Преглед изворни кода

merge from the expermental2 branch

Michael Vogt пре 14 година
родитељ
комит
443f5e8a32
100 измењених фајлова са 6207 додато и 3131 уклоњено
  1. 4 0
      .bzr-builddeb/default.conf
  2. 2 0
      .bzrignore
  3. 4 2
      Makefile
  4. 6 2
      apt-inst/contrib/arfile.cc
  5. 6 2
      apt-inst/contrib/arfile.h
  6. 4 1
      apt-inst/contrib/extracttar.cc
  7. 9 4
      apt-inst/contrib/extracttar.h
  8. 0 26
      apt-inst/database.cc
  9. 0 52
      apt-inst/database.h
  10. 2 62
      apt-inst/deb/debfile.cc
  11. 6 7
      apt-inst/deb/debfile.h
  12. 0 490
      apt-inst/deb/dpkgdb.cc
  13. 0 50
      apt-inst/deb/dpkgdb.h
  14. 4 4
      apt-inst/dirstream.cc
  15. 3 0
      apt-inst/extract.cc
  16. 1 1
      apt-inst/extract.h
  17. 2 0
      apt-inst/filelist.cc
  18. 3 2
      apt-inst/filelist.h
  19. 4 5
      apt-inst/makefile
  20. 74 79
      apt-pkg/acquire-item.cc
  21. 163 122
      apt-pkg/acquire-item.h
  22. 8 1
      apt-pkg/acquire-method.cc
  23. 28 22
      apt-pkg/acquire-method.h
  24. 15 18
      apt-pkg/acquire-worker.cc
  25. 13 10
      apt-pkg/acquire-worker.h
  26. 19 14
      apt-pkg/acquire.cc
  27. 53 40
      apt-pkg/acquire.h
  28. 85 30
      apt-pkg/algorithms.cc
  29. 14 4
      apt-pkg/algorithms.h
  30. 102 20
      apt-pkg/aptconfiguration.cc
  31. 39 2
      apt-pkg/cachefile.cc
  32. 11 1
      apt-pkg/cachefile.h
  33. 3 1
      apt-pkg/cachefilter.cc
  34. 2 0
      apt-pkg/cachefilter.h
  35. 7 10
      apt-pkg/cacheiterators.h
  36. 212 182
      apt-pkg/cacheset.cc
  37. 452 183
      apt-pkg/cacheset.h
  38. 87 46
      apt-pkg/cdrom.cc
  39. 26 24
      apt-pkg/cdrom.h
  40. 17 11
      apt-pkg/clean.cc
  41. 5 2
      apt-pkg/clean.h
  42. 6 2
      apt-pkg/contrib/cdromutl.cc
  43. 7 5
      apt-pkg/contrib/cdromutl.h
  44. 4 1
      apt-pkg/contrib/cmndline.cc
  45. 4 2
      apt-pkg/contrib/cmndline.h
  46. 12 3
      apt-pkg/contrib/configuration.cc
  47. 24 22
      apt-pkg/contrib/configuration.h
  48. 3 1
      apt-pkg/contrib/crc-16.cc
  49. 1 1
      apt-pkg/contrib/crc-16.h
  50. 3 2
      apt-pkg/contrib/error.cc
  51. 702 101
      apt-pkg/contrib/fileutl.cc
  52. 105 43
      apt-pkg/contrib/fileutl.h
  53. 78 35
      apt-pkg/contrib/hashes.cc
  54. 23 11
      apt-pkg/contrib/hashes.h
  55. 50 0
      apt-pkg/contrib/hashsum.cc
  56. 118 0
      apt-pkg/contrib/hashsum_template.h
  57. 4 81
      apt-pkg/contrib/md5.cc
  58. 11 30
      apt-pkg/contrib/md5.h
  59. 34 14
      apt-pkg/contrib/mmap.cc
  60. 10 6
      apt-pkg/contrib/mmap.h
  61. 5 2
      apt-pkg/contrib/netrc.cc
  62. 7 1
      apt-pkg/contrib/netrc.h
  63. 16 23
      apt-pkg/contrib/progress.cc
  64. 16 15
      apt-pkg/contrib/progress.h
  65. 6 87
      apt-pkg/contrib/sha1.cc
  66. 8 28
      apt-pkg/contrib/sha1.h
  67. 103 0
      apt-pkg/contrib/sha2.h
  68. 0 424
      apt-pkg/contrib/sha256.cc
  69. 2 66
      apt-pkg/contrib/sha256.h
  70. 1076 0
      apt-pkg/contrib/sha2_internal.cc
  71. 188 0
      apt-pkg/contrib/sha2_internal.h
  72. 34 6
      apt-pkg/contrib/strutl.cc
  73. 55 52
      apt-pkg/contrib/strutl.h
  74. 16 21
      apt-pkg/deb/debindexfile.cc
  75. 53 35
      apt-pkg/deb/debindexfile.h
  76. 34 25
      apt-pkg/deb/deblistparser.cc
  77. 23 16
      apt-pkg/deb/deblistparser.h
  78. 46 31
      apt-pkg/deb/debmetaindex.cc
  79. 32 22
      apt-pkg/deb/debmetaindex.h
  80. 27 4
      apt-pkg/deb/debrecords.cc
  81. 25 13
      apt-pkg/deb/debrecords.h
  82. 30 19
      apt-pkg/deb/debsrcrecords.cc
  83. 16 14
      apt-pkg/deb/debsrcrecords.h
  84. 43 28
      apt-pkg/deb/debsystem.cc
  85. 8 7
      apt-pkg/deb/debsystem.h
  86. 3 3
      apt-pkg/deb/debversion.cc
  87. 1 29
      apt-pkg/deb/debversion.h
  88. 227 99
      apt-pkg/deb/dpkgpm.cc
  89. 14 17
      apt-pkg/deb/dpkgpm.h
  90. 153 129
      apt-pkg/depcache.cc
  91. 31 23
      apt-pkg/depcache.h
  92. 573 0
      apt-pkg/edsp.cc
  93. 230 0
      apt-pkg/edsp.h
  94. 78 0
      apt-pkg/edsp/edspindexfile.cc
  95. 31 0
      apt-pkg/edsp/edspindexfile.h
  96. 92 0
      apt-pkg/edsp/edsplistparser.cc
  97. 43 0
      apt-pkg/edsp/edsplistparser.h
  98. 127 0
      apt-pkg/edsp/edspsystem.cc
  99. 41 0
      apt-pkg/edsp/edspsystem.h
  100. 0 0
      apt-pkg/indexcopy.cc

+ 4 - 0
.bzr-builddeb/default.conf

@@ -1,2 +1,6 @@
 [BUILDDEB]
 [BUILDDEB]
 native = true
 native = true
+
+[HOOKS]
+pre-export = ./prepare-release pre-export
+post-build = ./prepare-release post-build

+ 2 - 0
.bzrignore

@@ -10,6 +10,8 @@ build/
 configure
 configure
 buildlib/config.sub
 buildlib/config.sub
 buildlib/config.guess
 buildlib/config.guess
+debian/libapt-pkg[0-9]*.install
+debian/libapt-inst[0-9]*.install
 
 
 # abichecker related files/dir
 # abichecker related files/dir
 abicheck/apt_build.xml
 abicheck/apt_build.xml

+ 4 - 2
Makefile

@@ -9,8 +9,8 @@ endif
 .PHONY: default
 .PHONY: default
 default: startup all
 default: startup all
 
 
-.PHONY: headers library clean veryclean all binary program doc test
-all headers library clean veryclean binary program doc dirs test:
+.PHONY: headers library clean veryclean all binary program doc test update-po
+startup all headers library clean veryclean binary program doc dirs test update-po:
 	$(MAKE) -C apt-pkg $@
 	$(MAKE) -C apt-pkg $@
 	$(MAKE) -C apt-inst $@
 	$(MAKE) -C apt-inst $@
 	$(MAKE) -C methods $@
 	$(MAKE) -C methods $@
@@ -21,6 +21,8 @@ all headers library clean veryclean binary program doc dirs test:
 	$(MAKE) -C po $@
 	$(MAKE) -C po $@
 	$(MAKE) -C test $@
 	$(MAKE) -C test $@
 
 
+update-po: startup
+
 # Some very common aliases
 # Some very common aliases
 .PHONY: maintainer-clean dist-clean distclean pristine sanity 
 .PHONY: maintainer-clean dist-clean distclean pristine sanity 
 maintainer-clean dist-clean distclean pristine sanity: veryclean
 maintainer-clean dist-clean distclean pristine sanity: veryclean

+ 6 - 2
apt-inst/contrib/arfile.cc

@@ -14,13 +14,17 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include<config.h>
+
 #include <apt-pkg/arfile.h>
 #include <apt-pkg/arfile.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 
 
 #include <stdlib.h>
 #include <stdlib.h>
-									/*}}}*/
+
 #include <apti18n.h>
 #include <apti18n.h>
+									/*}}}*/
 
 
 struct ARArchive::MemberHeader
 struct ARArchive::MemberHeader
 {
 {
@@ -112,7 +116,7 @@ bool ARArchive::LoadHeaders()
       {
       {
 	 unsigned int I = sizeof(Head.Name) - 1;
 	 unsigned int I = sizeof(Head.Name) - 1;
 	 for (; Head.Name[I] == ' ' || Head.Name[I] == '/'; I--);
 	 for (; Head.Name[I] == ' ' || Head.Name[I] == '/'; I--);
-	 Memb->Name = string(Head.Name,I+1);
+	 Memb->Name = std::string(Head.Name,I+1);
       }
       }
 
 
       // Account for the AR header alignment 
       // Account for the AR header alignment 

+ 6 - 2
apt-inst/contrib/arfile.h

@@ -17,7 +17,11 @@
 
 
 
 
 #include <string>
 #include <string>
+#ifndef APT_8_CLEANER_HEADERS
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
+#endif
+
+class FileFd;
 
 
 class ARArchive
 class ARArchive
 {
 {
@@ -49,12 +53,12 @@ class ARArchive
 struct ARArchive::Member
 struct ARArchive::Member
 {
 {
    // Fields from the header
    // Fields from the header
-   string Name;
+   std::string Name;
    unsigned long MTime;
    unsigned long MTime;
    unsigned long UID;
    unsigned long UID;
    unsigned long GID;
    unsigned long GID;
    unsigned long Mode;
    unsigned long Mode;
-   unsigned long Size;
+   unsigned long long Size;
    
    
    // Location of the data.
    // Location of the data.
    unsigned long Start;
    unsigned long Start;

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

@@ -16,8 +16,10 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
-#include <apt-pkg/extracttar.h>
+#include<config.h>
 
 
+#include <apt-pkg/dirstream.h>
+#include <apt-pkg/extracttar.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
@@ -28,6 +30,7 @@
 #include <signal.h>
 #include <signal.h>
 #include <fcntl.h>
 #include <fcntl.h>
 #include <iostream>
 #include <iostream>
+
 #include <apti18n.h>
 #include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 
 

+ 9 - 4
apt-inst/contrib/extracttar.h

@@ -15,11 +15,16 @@
 #define PKGLIB_EXTRACTTAR_H
 #define PKGLIB_EXTRACTTAR_H
 
 
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
-#include <apt-pkg/dirstream.h>
 
 
-#include <algorithm>
+#include <string>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/dirstream.h>
+#include <algorithm>
 using std::min;
 using std::min;
+#endif
+
+class pkgDirStream;
 
 
 class ExtractTar
 class ExtractTar
 {
 {
@@ -38,7 +43,7 @@ class ExtractTar
    int GZPid;
    int GZPid;
    FileFd InFd;
    FileFd InFd;
    bool Eof;
    bool Eof;
-   string DecompressProg;
+   std::string DecompressProg;
    
    
    // Fork and reap gzip
    // Fork and reap gzip
    bool StartGzip();
    bool StartGzip();
@@ -48,7 +53,7 @@ class ExtractTar
 
 
    bool Go(pkgDirStream &Stream);
    bool Go(pkgDirStream &Stream);
    
    
-   ExtractTar(FileFd &Fd,unsigned long Max,string DecompressionProgram);
+   ExtractTar(FileFd &Fd,unsigned long Max,std::string DecompressionProgram);
    virtual ~ExtractTar();
    virtual ~ExtractTar();
 };
 };
 
 

+ 0 - 26
apt-inst/database.cc

@@ -1,26 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description								/*{{{*/
-// $Id: database.cc,v 1.2 2001/02/20 07:03:16 jgg Exp $
-/* ######################################################################
-
-   Data Base Abstraction
-   
-   ##################################################################### */
-									/*}}}*/
-// Include Files							/*{{{*/
-#include <apt-pkg/database.h>
-									/*}}}*/
-
-// DataBase::GetMetaTmp - Get the temp dir				/*{{{*/
-// ---------------------------------------------------------------------
-/* This re-initializes the meta temporary directory if it hasn't yet 
-   been inited for this cycle. The flag is the emptyness of MetaDir */
-bool pkgDataBase::GetMetaTmp(string &Dir)
-{
-   if (MetaDir.empty() == true)
-      if (InitMetaTmp(MetaDir) == false)
-	 return false;
-   Dir = MetaDir;
-   return true;
-}
-									/*}}}*/

+ 0 - 52
apt-inst/database.h

@@ -1,52 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description								/*{{{*/
-// $Id: database.h,v 1.2 2001/02/20 07:03:16 jgg Exp $
-/* ######################################################################
-
-   Data Base Abstraction
-   
-   This class provides a simple interface to an abstract notion of a 
-   database directory for storing state information about the system.
-
-   The 'Meta' information for a package is the control information and
-   setup scripts stored inside the archive. GetMetaTmp returns the name of
-   a directory that is used to store named files containing the control
-   information. 
-   
-   The File Listing is the database of installed files. It is loaded 
-   into the memory/persistent cache structure by the ReadFileList method.  
-   
-   ##################################################################### */
-									/*}}}*/
-#ifndef PKGLIB_DATABASE_H
-#define PKGLIB_DATABASE_H
-
-#include <apt-pkg/filelist.h>
-#include <apt-pkg/pkgcachegen.h>
-
-class pkgDataBase
-{
-   protected:
-   
-   pkgCacheGenerator *Cache;
-   pkgFLCache *FList;
-   string MetaDir;
-   virtual bool InitMetaTmp(string &Dir) = 0;
-   
-   public:
-
-   // Some manipulators for the cache and generator
-   inline pkgCache &GetCache() {return Cache->GetCache();};
-   inline pkgFLCache &GetFLCache() {return *FList;};
-   inline pkgCacheGenerator &GetGenerator() {return *Cache;};
-   
-   bool GetMetaTmp(string &Dir);
-   virtual bool ReadyFileList(OpProgress &Progress) = 0;
-   virtual bool ReadyPkgCache(OpProgress &Progress) = 0;
-   virtual bool LoadChanges() = 0;
-
-   pkgDataBase() : Cache(0), FList(0) {};
-   virtual ~pkgDataBase() {delete Cache; delete FList;};
-};
-
-#endif

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

@@ -16,6 +16,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include<config.h>
+
 #include <apt-pkg/debfile.h>
 #include <apt-pkg/debfile.h>
 #include <apt-pkg/extracttar.h>
 #include <apt-pkg/extracttar.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
@@ -87,42 +89,6 @@ const ARArchive::Member *debDebFile::GotoMember(const char *Name)
    return Member;
    return Member;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// DebFile::ExtractControl - Extract Control information		/*{{{*/
-// ---------------------------------------------------------------------
-/* Extract the control information into the Database's temporary 
-   directory. */
-bool debDebFile::ExtractControl(pkgDataBase &DB)
-{
-   // Get the archive member and positition the file
-   const ARArchive::Member *Member = GotoMember("control.tar.gz");
-   if (Member == 0)
-      return false;
-      
-   // Prepare Tar
-   ControlExtract Extract;
-   ExtractTar Tar(File,Member->Size,"gzip");
-   if (_error->PendingError() == true)
-      return false;
-   
-   // Get into the temporary directory
-   string Cwd = SafeGetCWD();
-   string Tmp;
-   if (DB.GetMetaTmp(Tmp) == false)
-      return false;
-   if (chdir(Tmp.c_str()) != 0)
-      return _error->Errno("chdir",_("Couldn't change to %s"),Tmp.c_str());
-   
-   // Do extraction
-   if (Tar.Go(Extract) == false)
-      return false;
-   
-   // Switch out of the tmp directory.
-   if (chdir(Cwd.c_str()) != 0)
-      chdir("/");
-   
-   return true;
-}
-									/*}}}*/
 // DebFile::ExtractArchive - Extract the archive data itself		/*{{{*/
 // DebFile::ExtractArchive - Extract the archive data itself		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Simple wrapper around tar.. */
 /* Simple wrapper around tar.. */
@@ -164,32 +130,6 @@ bool debDebFile::ExtractArchive(pkgDirStream &Stream)
    return Tar.Go(Stream);
    return Tar.Go(Stream);
 }
 }
 									/*}}}*/
 									/*}}}*/
-// DebFile::MergeControl - Merge the control information		/*{{{*/
-// ---------------------------------------------------------------------
-/* This reads the extracted control file into the cache and returns the
-   version that was parsed. All this really does is select the correct
-   parser and correct file to parse. */
-pkgCache::VerIterator debDebFile::MergeControl(pkgDataBase &DB)
-{
-   // Open the control file
-   string Tmp;
-   if (DB.GetMetaTmp(Tmp) == false)
-      return pkgCache::VerIterator(DB.GetCache());
-   FileFd Fd(Tmp + "control",FileFd::ReadOnly);
-   if (_error->PendingError() == true)
-      return pkgCache::VerIterator(DB.GetCache());
-   
-   // Parse it
-   debListParser Parse(&Fd);
-   pkgCache::VerIterator Ver(DB.GetCache());
-   if (DB.GetGenerator().MergeList(Parse,&Ver) == false)
-      return pkgCache::VerIterator(DB.GetCache());
-   
-   if (Ver.end() == true)
-      _error->Error(_("Failed to locate a valid control file"));
-   return Ver;
-}
-									/*}}}*/
 
 
 // DebFile::ControlExtract::DoItem - Control Tar Extraction		/*{{{*/
 // DebFile::ControlExtract::DoItem - Control Tar Extraction		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------

+ 6 - 7
apt-inst/deb/debfile.h

@@ -25,9 +25,11 @@
 
 
 
 
 #include <apt-pkg/arfile.h>
 #include <apt-pkg/arfile.h>
-#include <apt-pkg/database.h>
 #include <apt-pkg/dirstream.h>
 #include <apt-pkg/dirstream.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/tagfile.h>
+#include <apt-pkg/pkgcache.h>
+
+class FileFd;
 
 
 class debDebFile
 class debDebFile
 {
 {
@@ -39,13 +41,10 @@ class debDebFile
    bool CheckMember(const char *Name);
    bool CheckMember(const char *Name);
    
    
    public:
    public:
-
    class ControlExtract;
    class ControlExtract;
    class MemControlExtract;
    class MemControlExtract;
-   
-   bool ExtractControl(pkgDataBase &DB);
+
    bool ExtractArchive(pkgDirStream &Stream);
    bool ExtractArchive(pkgDirStream &Stream);
-   pkgCache::VerIterator MergeControl(pkgDataBase &DB);
    const ARArchive::Member *GotoMember(const char *Name);
    const ARArchive::Member *GotoMember(const char *Name);
    inline FileFd &GetFile() {return File;};
    inline FileFd &GetFile() {return File;};
    
    
@@ -68,7 +67,7 @@ class debDebFile::MemControlExtract : public pkgDirStream
    char *Control;
    char *Control;
    pkgTagSection Section;
    pkgTagSection Section;
    unsigned long Length;
    unsigned long Length;
-   string Member;
+   std::string Member;
    
    
    // Members from DirStream
    // Members from DirStream
    virtual bool DoItem(Item &Itm,int &Fd);
    virtual bool DoItem(Item &Itm,int &Fd);
@@ -81,7 +80,7 @@ class debDebFile::MemControlExtract : public pkgDirStream
    bool TakeControl(const void *Data,unsigned long Size);
    bool TakeControl(const void *Data,unsigned long Size);
       
       
    MemControlExtract() : IsControl(false), Control(0), Length(0), Member("control") {};
    MemControlExtract() : IsControl(false), Control(0), Length(0), Member("control") {};
-   MemControlExtract(string Member) : IsControl(false), Control(0), Length(0), Member(Member) {};
+   MemControlExtract(std::string Member) : IsControl(false), Control(0), Length(0), Member(Member) {};
    ~MemControlExtract() {delete [] Control;};   
    ~MemControlExtract() {delete [] Control;};   
 };
 };
 									/*}}}*/
 									/*}}}*/

+ 0 - 490
apt-inst/deb/dpkgdb.cc

@@ -1,490 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description								/*{{{*/
-// $Id: dpkgdb.cc,v 1.7.2.1 2004/01/16 18:58:50 mdz Exp $
-/* ######################################################################
-
-   DPKGv1 Database Implemenation
-   
-   This class provides parsers and other implementations for the DPKGv1
-   database. It reads the diversion file, the list files and the status
-   file to build both the list of currently installed files and the 
-   currently installed package list.
-   
-   ##################################################################### */
-									/*}}}*/
-// Include Files							/*{{{*/
-#include <apt-pkg/dpkgdb.h>
-#include <apt-pkg/configuration.h>
-#include <apt-pkg/error.h>
-#include <apt-pkg/progress.h>
-#include <apt-pkg/tagfile.h>
-#include <apt-pkg/strutl.h>
-
-#include <stdio.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <iostream>
-#include <apti18n.h>
-									/*}}}*/
-using namespace std;
-
-// EraseDir - Erase A Directory						/*{{{*/
-// ---------------------------------------------------------------------
-/* This is necessary to create a new empty sub directory. The caller should
-   invoke mkdir after this with the proper permissions and check for 
-   error. Maybe stick this in fileutils */
-static bool EraseDir(const char *Dir)
-{
-   // First we try a simple RM
-   if (rmdir(Dir) == 0 ||
-       errno == ENOENT)
-      return true;
-   
-   // A file? Easy enough..
-   if (errno == ENOTDIR)
-   {
-      if (unlink(Dir) != 0)
-	 return _error->Errno("unlink",_("Failed to remove %s"),Dir);
-      return true;
-   }
-   
-   // Should not happen
-   if (errno != ENOTEMPTY)
-      return _error->Errno("rmdir",_("Failed to remove %s"),Dir);
-   
-   // Purge it using rm
-   pid_t Pid = ExecFork();
-
-   // Spawn the subprocess
-   if (Pid == 0)
-   {
-      execlp(_config->Find("Dir::Bin::rm","/bin/rm").c_str(),
-	     "rm","-rf","--",Dir,(char *)NULL);
-      _exit(100);
-   }
-   return ExecWait(Pid,_config->Find("dir::bin::rm","/bin/rm").c_str());
-}
-									/*}}}*/
-// DpkgDB::debDpkgDB - Constructor					/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-debDpkgDB::debDpkgDB() : CacheMap(0), FileMap(0)
-{
-   AdminDir = flNotFile(_config->Find("Dir::State::status"));   
-   DiverInode = 0;
-   DiverTime = 0;
-}
-									/*}}}*/
-// DpkgDB::~debDpkgDB - Destructor					/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-debDpkgDB::~debDpkgDB()
-{
-   delete Cache;
-   Cache = 0;
-   delete CacheMap;
-   CacheMap = 0;
-   
-   delete FList;
-   FList = 0;
-   delete FileMap;
-   FileMap = 0;
-}
-									/*}}}*/
-// DpkgDB::InitMetaTmp - Get the temp dir for meta information		/*{{{*/
-// ---------------------------------------------------------------------
-/* This creats+empties the meta temporary directory /var/lib/dpkg/tmp.ci
-   Only one package at a time can be using the returned meta directory. */
-bool debDpkgDB::InitMetaTmp(string &Dir)
-{
-   string Tmp = AdminDir + "tmp.ci/";
-   if (EraseDir(Tmp.c_str()) == false)
-      return _error->Error(_("Unable to create %s"),Tmp.c_str());
-   if (mkdir(Tmp.c_str(),0755) != 0)
-      return _error->Errno("mkdir",_("Unable to create %s"),Tmp.c_str());
-   
-   // Verify it is on the same filesystem as the main info directory
-   dev_t Dev;
-   struct stat St;
-   if (stat((AdminDir + "info").c_str(),&St) != 0)
-      return _error->Errno("stat",_("Failed to stat %sinfo"),AdminDir.c_str());
-   Dev = St.st_dev;
-   if (stat(Tmp.c_str(),&St) != 0)
-      return _error->Errno("stat",_("Failed to stat %s"),Tmp.c_str());
-   if (Dev != St.st_dev)
-      return _error->Error(_("The info and temp directories need to be on the same filesystem"));
-   
-   // Done
-   Dir = Tmp;
-   return true;
-}
-									/*}}}*/
-// DpkgDB::ReadyPkgCache - Prepare the cache with the current status	/*{{{*/
-// ---------------------------------------------------------------------
-/* This reads in the status file into an empty cache. This really needs 
-   to be somehow unified with the high level APT notion of the Database
-   directory, but there is no clear way on how to do that yet. */
-bool debDpkgDB::ReadyPkgCache(OpProgress &Progress)
-{
-   if (Cache != 0)
-   {  
-      Progress.OverallProgress(1,1,1,_("Reading package lists"));      
-      return true;
-   }
-   
-   if (CacheMap != 0)
-   {
-      delete CacheMap;
-      CacheMap = 0;
-   }
-   
-   if (pkgCacheGenerator::MakeOnlyStatusCache(&Progress,&CacheMap) == false)
-      return false;
-   Cache->DropProgress();
-   
-   return true;
-}
-									/*}}}*/
-// DpkgDB::ReadFList - Read the File Listings in 			/*{{{*/
-// ---------------------------------------------------------------------
-/* This reads the file listing in from the state directory. This is a 
-   performance critical routine, as it needs to parse about 50k lines of
-   text spread over a hundred or more files. For an initial cold start
-   most of the time is spent in reading file inodes and so on, not 
-   actually parsing. */
-bool debDpkgDB::ReadFList(OpProgress &Progress)
-{
-   // Count the number of packages we need to read information for
-   unsigned long Total = 0;
-   pkgCache &Cache = this->Cache->GetCache();
-   for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
-   {
-      // Only not installed packages have no files.
-      if (I->CurrentState == pkgCache::State::NotInstalled)
-	 continue;
-      Total++;
-   }
-
-   /* Switch into the admin dir, this prevents useless lookups for the 
-      path components */
-   string Cwd = SafeGetCWD();
-   if (chdir((AdminDir + "info/").c_str()) != 0)
-      return _error->Errno("chdir",_("Failed to change to the admin dir %sinfo"),AdminDir.c_str());
-   
-   // Allocate a buffer. Anything larger than this buffer will be mmaped
-   unsigned long BufSize = 32*1024;
-   char *Buffer = new char[BufSize];
-
-   // Begin Loading them
-   unsigned long Count = 0;
-   char Name[300];
-   for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
-   {
-      /* Only not installed packages have no files. ConfFile packages have
-         file lists but we don't want to read them in */
-      if (I->CurrentState == pkgCache::State::NotInstalled ||
-	  I->CurrentState == pkgCache::State::ConfigFiles)
-	 continue;
-
-      // Fetch a package handle to associate with the file
-      pkgFLCache::PkgIterator FlPkg = FList->GetPkg(I.Name(),0,true);
-      if (FlPkg.end() == true)
-      {
-	 _error->Error(_("Internal error getting a package name"));
-	 break;
-      }
-      
-      Progress.OverallProgress(Count,Total,1,_("Reading file listing"));
-     
-      // Open the list file
-      snprintf(Name,sizeof(Name),"%s.list",I.Name());
-      int Fd = open(Name,O_RDONLY);
-      
-      /* Okay this is very strange and bad.. Best thing is to bail and
-         instruct the user to look into it. */
-      struct stat Stat;
-      if (Fd == -1 || fstat(Fd,&Stat) != 0)
-      {
-	 _error->Errno("open",_("Failed to open the list file '%sinfo/%s'. If you "
-		       "cannot restore this file then make it empty "
-		       "and immediately re-install the same version of the package!"),
-		       AdminDir.c_str(),Name);
-	 break;
-      }
-      
-      // Set File to be a memory buffer containing the whole file
-      char *File;
-      if ((unsigned)Stat.st_size < BufSize)
-      {
-	 if (read(Fd,Buffer,Stat.st_size) != Stat.st_size)
-	 {
-	    _error->Errno("read",_("Failed reading the list file %sinfo/%s"),
-			  AdminDir.c_str(),Name);
-	    close(Fd);
-	    break;
-	 }
-	 File = Buffer;
-      }
-      else
-      {
-	 // Use mmap
-	 File = (char *)mmap(0,Stat.st_size,PROT_READ,MAP_PRIVATE,Fd,0);
-	 if (File == (char *)(-1))
-	 {
-	    _error->Errno("mmap",_("Failed reading the list file %sinfo/%s"),
-			  AdminDir.c_str(),Name);
-	    close(Fd);
-	    break;
-	 }	    
-      }
-      
-      // Parse it
-      const char *Start = File;
-      const char *End = File;
-      const char *Finish = File + Stat.st_size;
-      for (; End < Finish; End++)
-      {
-	 // Not an end of line
-	 if (*End != '\n' && End + 1 < Finish)
-	    continue;
-
-	 // Skip blank lines
-	 if (End - Start > 1)
-	 {
-	    pkgFLCache::NodeIterator Node = FList->GetNode(Start,End,
- 					      FlPkg.Offset(),true,false);
-	    if (Node.end() == true)
-	    {
-	       _error->Error(_("Internal error getting a node"));
-	       break;
-	    }
-	 }
-	 
-	 // Skip past the end of line
-	 for (; *End == '\n' && End < Finish; End++);
-	 Start = End;
-      }      
-      
-      close(Fd);
-      if ((unsigned)Stat.st_size >= BufSize)
-	 munmap((caddr_t)File,Stat.st_size);
-      
-      // Failed
-      if (End < Finish)
-	 break;
-      
-      Count++;
-   }
-
-   delete [] Buffer;
-   if (chdir(Cwd.c_str()) != 0)
-      chdir("/");
-   
-   return !_error->PendingError();
-}
-									/*}}}*/
-// DpkgDB::ReadDiversions - Load the diversions file			/*{{{*/
-// ---------------------------------------------------------------------
-/* Read the diversion file in from disk. This is usually invoked by 
-   LoadChanges before performing an operation that uses the FLCache. */
-bool debDpkgDB::ReadDiversions()
-{
-   struct stat Stat;
-   if (stat((AdminDir + "diversions").c_str(),&Stat) != 0)
-      return true;
-   
-   if (_error->PendingError() == true)
-      return false;
-   
-   FILE *Fd = fopen((AdminDir + "diversions").c_str(),"r");
-   if (Fd == 0)
-      return _error->Errno("fopen",_("Failed to open the diversions file %sdiversions"),AdminDir.c_str());
-	
-   FList->BeginDiverLoad();
-   while (1)
-   {
-      char From[300];
-      char To[300];
-      char Package[100];
-   
-      // Read the three lines in
-      if (fgets(From,sizeof(From),Fd) == 0)
-	 break;
-      if (fgets(To,sizeof(To),Fd) == 0 ||
-	  fgets(Package,sizeof(Package),Fd) == 0)
-      {
-	 _error->Error(_("The diversion file is corrupted"));
-	 break;
-      }
-      
-      // Strip the \ns
-      unsigned long Len = strlen(From);
-      if (Len < 2 || From[Len-1] != '\n')
-	 _error->Error(_("Invalid line in the diversion file: %s"),From);
-      else
-	 From[Len-1] = 0;
-      Len = strlen(To);
-      if (Len < 2 || To[Len-1] != '\n')
-	 _error->Error(_("Invalid line in the diversion file: %s"),To);
-      else
-	 To[Len-1] = 0;     
-      Len = strlen(Package);
-      if (Len < 2 || Package[Len-1] != '\n')
-	 _error->Error(_("Invalid line in the diversion file: %s"),Package);
-      else
-	 Package[Len-1] = 0;
-      
-      // Make sure the lines were parsed OK
-      if (_error->PendingError() == true)
-	 break;
-      
-      // Fetch a package
-      if (strcmp(Package,":") == 0)
-	 Package[0] = 0;
-      pkgFLCache::PkgIterator FlPkg = FList->GetPkg(Package,0,true);
-      if (FlPkg.end() == true)
-      {
-	 _error->Error(_("Internal error getting a package name"));
-	 break;
-      }
-      
-      // Install the diversion
-      if (FList->AddDiversion(FlPkg,From,To) == false)
-      {
-	 _error->Error(_("Internal error adding a diversion"));
-	 break;
-      }
-   }
-   if (_error->PendingError() == false)
-      FList->FinishDiverLoad();
-   
-   DiverInode = Stat.st_ino;
-   DiverTime = Stat.st_mtime;
-   
-   fclose(Fd);
-   return !_error->PendingError();
-}
-									/*}}}*/
-// DpkgDB::ReadFileList - Read the file listing				/*{{{*/
-// ---------------------------------------------------------------------
-/* Read in the file listing. The file listing is created from three
-   sources, *.list, Conffile sections and the Diversion table. */
-bool debDpkgDB::ReadyFileList(OpProgress &Progress)
-{
-   if (Cache == 0)
-      return _error->Error(_("The pkg cache must be initialized first"));
-   if (FList != 0)
-   {
-      Progress.OverallProgress(1,1,1,_("Reading file listing"));
-      return true;
-   }
-   
-   // Create the cache and read in the file listing
-   FileMap = new DynamicMMap(MMap::Public);
-   FList = new pkgFLCache(*FileMap);
-   if (_error->PendingError() == true || 
-       ReadFList(Progress) == false ||
-       ReadConfFiles() == false || 
-       ReadDiversions() == false)
-   {
-      delete FList;
-      delete FileMap;
-      FileMap = 0;
-      FList = 0;
-      return false;
-   }
-      
-   cout << "Node: " << FList->HeaderP->NodeCount << ',' << FList->HeaderP->UniqNodes << endl;
-   cout << "Dir: " << FList->HeaderP->DirCount << endl;
-   cout << "Package: " << FList->HeaderP->PackageCount << endl;
-   cout << "HashSize: " << FList->HeaderP->HashSize << endl;
-   cout << "Size: " << FileMap->Size() << endl;
-   cout << endl;
-
-   return true;
-}
-									/*}}}*/
-// DpkgDB::ReadConfFiles - Read the conf file sections from the s-file	/*{{{*/
-// ---------------------------------------------------------------------
-/* Reading the conf files is done by reparsing the status file. This is
-   actually rather fast so it is no big deal. */
-bool debDpkgDB::ReadConfFiles()
-{
-   FileFd File(_config->FindFile("Dir::State::status"),FileFd::ReadOnly);
-   pkgTagFile Tags(&File);
-   if (_error->PendingError() == true)
-      return false;
-   
-   pkgTagSection Section;   
-   while (1)
-   {
-      // Skip to the next section
-      unsigned long Offset = Tags.Offset();
-      if (Tags.Step(Section) == false)
-	 break;
-	 
-      // Parse the line
-      const char *Start;
-      const char *Stop;
-      if (Section.Find("Conffiles",Start,Stop) == false)
-	 continue;
-
-      const char *PkgStart;
-      const char *PkgEnd;
-      if (Section.Find("Package",PkgStart,PkgEnd) == false)
-	 return _error->Error(_("Failed to find a Package: header, offset %lu"),Offset);
-
-      // Snag a package record for it
-      pkgFLCache::PkgIterator FlPkg = FList->GetPkg(PkgStart,PkgEnd,true);
-      if (FlPkg.end() == true)
-	 return _error->Error(_("Internal error getting a package name"));
-
-      // Parse the conf file lines
-      while (1)
-      {
-	 for (; isspace(*Start) != 0 && Start < Stop; Start++);
-	 if (Start == Stop)
-	    break;
-
-	 // Split it into words
-	 const char *End = Start;
-	 for (; isspace(*End) == 0 && End < Stop; End++);
-	 const char *StartMd5 = End;
-	 for (; isspace(*StartMd5) != 0 && StartMd5 < Stop; StartMd5++);
-	 const char *EndMd5 = StartMd5;
-	 for (; isspace(*EndMd5) == 0 && EndMd5 < Stop; EndMd5++);
-	 if (StartMd5 == EndMd5 || Start == End)
-	    return _error->Error(_("Bad ConfFile section in the status file. Offset %lu"),Offset);
-	 	 
-	 // Insert a new entry
-	 unsigned char MD5[16];
-	 if (Hex2Num(string(StartMd5,EndMd5-StartMd5),MD5,16) == false)
-	    return _error->Error(_("Error parsing MD5. Offset %lu"),Offset);
-
-	 if (FList->AddConfFile(Start,End,FlPkg,MD5) == false)
-	    return false;
-	 Start = EndMd5;
-      }      
-   }   
-   
-   return true;
-}
-									/*}}}*/
-// DpkgDB::LoadChanges - Read in any changed state files		/*{{{*/
-// ---------------------------------------------------------------------
-/* The only file in the dpkg system that can change while packages are
-   unpacking is the diversions file. */
-bool debDpkgDB::LoadChanges()
-{
-   struct stat Stat;
-   if (stat((AdminDir + "diversions").c_str(),&Stat) != 0)
-      return true;
-   if (DiverInode == Stat.st_ino && DiverTime == Stat.st_mtime)
-      return true;
-   return ReadDiversions();
-}
-									/*}}}*/

+ 0 - 50
apt-inst/deb/dpkgdb.h

@@ -1,50 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description								/*{{{*/
-// $Id: dpkgdb.h,v 1.2 2001/02/20 07:03:17 jgg Exp $
-/* ######################################################################
-
-   DPKGv1 Data Base Implemenation
-   
-   The DPKGv1 database is typically stored in /var/lib/dpkg/. For 
-   DPKGv1 the 'meta' information is the contents of the .deb control.tar.gz
-   member prepended by the package name. The meta information is unpacked
-   in its temporary directory and then migrated into the main list dir
-   at a checkpoint.
-   
-   Journaling is providing by syncronized file writes to the updates sub
-   directory.
-
-   ##################################################################### */
-									/*}}}*/
-#ifndef PKGLIB_DPKGDB_H
-#define PKGLIB_DPKGDB_H
-
-
-#include <apt-pkg/database.h>
-
-class debDpkgDB : public pkgDataBase
-{
-   protected:
-   
-   string AdminDir;
-   DynamicMMap *CacheMap;
-   DynamicMMap *FileMap;
-   unsigned long DiverInode;
-   signed long DiverTime;
-   
-   virtual bool InitMetaTmp(string &Dir);
-   bool ReadFList(OpProgress &Progress);
-   bool ReadDiversions();
-   bool ReadConfFiles();
-      
-   public:
-
-   virtual bool ReadyFileList(OpProgress &Progress);
-   virtual bool ReadyPkgCache(OpProgress &Progress);
-   virtual bool LoadChanges();
-   
-   debDpkgDB();
-   virtual ~debDpkgDB();
-};
-
-#endif

+ 4 - 4
apt-inst/dirstream.cc

@@ -11,6 +11,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include<config.h>
+
 #include <apt-pkg/dirstream.h>
 #include <apt-pkg/dirstream.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 
 
@@ -44,15 +46,13 @@ bool pkgDirStream::DoItem(Item &Itm,int &Fd)
 	 // fchmod deals with umask and fchown sets the ownership
 	 // fchmod deals with umask and fchown sets the ownership
 	 if (fchmod(iFd,Itm.Mode) != 0)
 	 if (fchmod(iFd,Itm.Mode) != 0)
 	 {
 	 {
-	    _error->Errno("fchmod",_("Failed to write file %s"), Itm.Name);
 	    close(iFd);
 	    close(iFd);
-	    return false;
+	    return _error->Errno("fchmod",_("Failed to write file %s"), Itm.Name);
 	 }
 	 }
 	 if (fchown(iFd,Itm.UID,Itm.GID) != 0 && errno != EPERM)
 	 if (fchown(iFd,Itm.UID,Itm.GID) != 0 && errno != EPERM)
 	 {
 	 {
-	    return _error->Errno("fchown",_("Failed to write file %s"), Itm.Name);
 	    close(iFd);
 	    close(iFd);
-	    return false;
+	    return _error->Errno("fchown",_("Failed to write file %s"), Itm.Name);
 	 }
 	 }
 	 Fd = iFd;
 	 Fd = iFd;
 	 return true;
 	 return true;

+ 3 - 0
apt-inst/extract.cc

@@ -44,9 +44,12 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include<config.h>
+
 #include <apt-pkg/extract.h>
 #include <apt-pkg/extract.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/debversion.h>
 #include <apt-pkg/debversion.h>
+#include <apt-pkg/fileutl.h>
 
 
 #include <sys/stat.h>
 #include <sys/stat.h>
 #include <stdio.h>
 #include <stdio.h>

+ 1 - 1
apt-inst/extract.h

@@ -33,7 +33,7 @@ class pkgExtract : public pkgDirStream
    
    
    bool HandleOverwrites(pkgFLCache::NodeIterator Nde,
    bool HandleOverwrites(pkgFLCache::NodeIterator Nde,
 			 bool DiverCheck = false);
 			 bool DiverCheck = false);
-   bool CheckDirReplace(string Dir,unsigned int Depth = 0);
+   bool CheckDirReplace(std::string Dir,unsigned int Depth = 0);
    
    
    public:
    public:
    
    

+ 2 - 0
apt-inst/filelist.cc

@@ -32,6 +32,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include<config.h>
+
 #include <apt-pkg/filelist.h>
 #include <apt-pkg/filelist.h>
 #include <apt-pkg/mmap.h>
 #include <apt-pkg/mmap.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>

+ 3 - 2
apt-inst/filelist.h

@@ -28,9 +28,10 @@
 #ifndef PKGLIB_FILELIST_H
 #ifndef PKGLIB_FILELIST_H
 #define PKGLIB_FILELIST_H
 #define PKGLIB_FILELIST_H
 
 
+#include <apt-pkg/mmap.h>
 
 
 #include <cstring>
 #include <cstring>
-#include <apt-pkg/mmap.h>
+#include <string>
 
 
 class pkgFLCache
 class pkgFLCache
 {
 {
@@ -48,7 +49,7 @@ class pkgFLCache
    class DiverIterator;
    class DiverIterator;
    
    
    protected:
    protected:
-   string CacheFile;
+   std::string CacheFile;
    DynamicMMap &Map;
    DynamicMMap &Map;
    map_ptrloc LastTreeLookup;
    map_ptrloc LastTreeLookup;
    unsigned long LastLookupSize;
    unsigned long LastLookupSize;

+ 4 - 5
apt-inst/makefile

@@ -14,7 +14,7 @@ include ../buildlib/libversion.mak
 
 
 # The library name
 # The library name
 LIBRARY=apt-inst
 LIBRARY=apt-inst
-MAJOR=1.2
+MAJOR=1.5
 MINOR=0
 MINOR=0
 SLIBS=$(PTHREADLIB) -lapt-pkg
 SLIBS=$(PTHREADLIB) -lapt-pkg
 APT_DOMAIN:=libapt-inst$(MAJOR)
 APT_DOMAIN:=libapt-inst$(MAJOR)
@@ -23,12 +23,11 @@ APT_DOMAIN:=libapt-inst$(MAJOR)
 SOURCE = contrib/extracttar.cc contrib/arfile.cc
 SOURCE = contrib/extracttar.cc contrib/arfile.cc
 
 
 # Source code for the main library
 # Source code for the main library
-SOURCE+= filelist.cc database.cc dirstream.cc extract.cc \
-         deb/dpkgdb.cc deb/debfile.cc
+SOURCE+= filelist.cc dirstream.cc extract.cc deb/debfile.cc
 
 
 # Public header files
 # Public header files
-HEADERS = extracttar.h arfile.h filelist.h database.h extract.h \
-          dpkgdb.h dirstream.h debfile.h
+HEADERS = extracttar.h arfile.h filelist.h extract.h \
+          dirstream.h debfile.h
 
 
 HEADERS := $(addprefix apt-pkg/,$(HEADERS))
 HEADERS := $(addprefix apt-pkg/,$(HEADERS))
 include $(LIBRARY_H)
 include $(LIBRARY_H)

+ 74 - 79
apt-pkg/acquire-item.cc

@@ -13,6 +13,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/aptconfiguration.h>
@@ -23,9 +25,9 @@
 #include <apt-pkg/md5.h>
 #include <apt-pkg/md5.h>
 #include <apt-pkg/sha1.h>
 #include <apt-pkg/sha1.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/tagfile.h>
+#include <apt-pkg/indexrecords.h>
+#include <apt-pkg/metaindex.h>
 
 
-#include <apti18n.h>
-    
 #include <sys/stat.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <unistd.h>
 #include <errno.h>
 #include <errno.h>
@@ -33,6 +35,8 @@
 #include <sstream>
 #include <sstream>
 #include <stdio.h>
 #include <stdio.h>
 #include <ctime>
 #include <ctime>
+
+#include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 
 
 using namespace std;
 using namespace std;
@@ -94,7 +98,7 @@ void pkgAcquire::Item::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Stash status and the file size. Note that setting Complete means 
 /* Stash status and the file size. Note that setting Complete means 
    sub-phases of the acquire process such as decompresion are operating */
    sub-phases of the acquire process such as decompresion are operating */
-void pkgAcquire::Item::Start(string /*Message*/,unsigned long Size)
+void pkgAcquire::Item::Start(string /*Message*/,unsigned long long Size)
 {
 {
    Status = StatFetching;
    Status = StatFetching;
    if (FileSize == 0 && Complete == false)
    if (FileSize == 0 && Complete == false)
@@ -104,7 +108,7 @@ void pkgAcquire::Item::Start(string /*Message*/,unsigned long Size)
 // Acquire::Item::Done - Item downloaded OK				/*{{{*/
 // Acquire::Item::Done - Item downloaded OK				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-void pkgAcquire::Item::Done(string Message,unsigned long Size,string Hash,
+void pkgAcquire::Item::Done(string Message,unsigned long long Size,string Hash,
 			    pkgAcquire::MethodConfig *Cnf)
 			    pkgAcquire::MethodConfig *Cnf)
 {
 {
    // We just downloaded something..
    // We just downloaded something..
@@ -185,14 +189,14 @@ void pkgAcquire::Item::ReportMirrorFailure(string FailCode)
 									/*}}}*/
 									/*}}}*/
 // AcqSubIndex::AcqSubIndex - Constructor				/*{{{*/
 // AcqSubIndex::AcqSubIndex - Constructor				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
-/* Get the Index file first and see if there are languages available
- * If so, create a pkgAcqIndexTrans for the found language(s).
- */
+/* Get a sub-index file based on checksums from a 'master' file and
+   possibly query additional files */
 pkgAcqSubIndex::pkgAcqSubIndex(pkgAcquire *Owner, string const &URI,
 pkgAcqSubIndex::pkgAcqSubIndex(pkgAcquire *Owner, string const &URI,
 				 string const &URIDesc, string const &ShortDesc,
 				 string const &URIDesc, string const &ShortDesc,
 				 HashString const &ExpectedHash)
 				 HashString const &ExpectedHash)
    : Item(Owner), ExpectedHash(ExpectedHash)
    : Item(Owner), ExpectedHash(ExpectedHash)
 {
 {
+   /* XXX: Beware: Currently this class does nothing (of value) anymore ! */
    Debug = _config->FindB("Debug::pkgAcquire::SubIndex",false);
    Debug = _config->FindB("Debug::pkgAcquire::SubIndex",false);
 
 
    DestFile = _config->FindDir("Dir::State::lists") + "partial/";
    DestFile = _config->FindDir("Dir::State::lists") + "partial/";
@@ -232,20 +236,10 @@ void pkgAcqSubIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)	/*{{{*
    Status = StatDone;
    Status = StatDone;
    Dequeue();
    Dequeue();
 
 
-   // No good Index is provided, so try guessing
-   std::vector<std::string> langs = APT::Configuration::getLanguages(true);
-   for (std::vector<std::string>::const_iterator l = langs.begin();
-	l != langs.end(); ++l)
-   {
-      if (*l == "none") continue;
-      string const file = "Translation-" + *l;
-      new pkgAcqIndexTrans(Owner, Desc.URI.substr(0, Desc.URI.rfind('/')+1).append(file),
-		Desc.Description.erase(Desc.Description.rfind(' ')+1).append(file),
-		file);
-   }
+   // No good Index is provided
 }
 }
 									/*}}}*/
 									/*}}}*/
-void pkgAcqSubIndex::Done(string Message,unsigned long Size,string Md5Hash,	/*{{{*/
+void pkgAcqSubIndex::Done(string Message,unsigned long long Size,string Md5Hash,	/*{{{*/
 			   pkgAcquire::MethodConfig *Cnf)
 			   pkgAcquire::MethodConfig *Cnf)
 {
 {
    if(Debug)
    if(Debug)
@@ -301,38 +295,7 @@ bool pkgAcqSubIndex::ParseIndex(string const &IndexFile)		/*{{{*/
    indexRecords SubIndexParser;
    indexRecords SubIndexParser;
    if (FileExists(IndexFile) == false || SubIndexParser.Load(IndexFile) == false)
    if (FileExists(IndexFile) == false || SubIndexParser.Load(IndexFile) == false)
       return false;
       return false;
-
-   std::vector<std::string> lang = APT::Configuration::getLanguages(true);
-   for (std::vector<std::string>::const_iterator l = lang.begin();
-	l != lang.end(); ++l)
-   {
-      if (*l == "none")
-	 continue;
-
-      string file = "Translation-" + *l;
-      indexRecords::checkSum const *Record = SubIndexParser.Lookup(file);
-      HashString expected;
-      if (Record == NULL)
-      {
-	 // FIXME: the Index file provided by debian currently only includes bz2 records
-	 Record = SubIndexParser.Lookup(file + ".bz2");
-	 if (Record == NULL)
-	    continue;
-      }
-      else
-      {
-	 expected = Record->Hash;
-	 if (expected.empty() == true)
-	    continue;
-      }
-
-      IndexTarget target;
-      target.Description = Desc.Description.erase(Desc.Description.rfind(' ')+1).append(file);
-      target.MetaKey = file;
-      target.ShortDesc = file;
-      target.URI = Desc.URI.substr(0, Desc.URI.rfind('/')+1).append(file);
-      new pkgAcqIndexTrans(Owner, &target, expected, &SubIndexParser);
-   }
+   // so something with the downloaded index
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -434,7 +397,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)		/*{{{*/
 
 
       FileFd fd(CurrentPackagesFile, FileFd::ReadOnly);
       FileFd fd(CurrentPackagesFile, FileFd::ReadOnly);
       SHA1Summation SHA1;
       SHA1Summation SHA1;
-      SHA1.AddFD(fd.Fd(), fd.Size());
+      SHA1.AddFD(fd);
       string const local_sha1 = SHA1.Result();
       string const local_sha1 = SHA1.Result();
 
 
       if(local_sha1 == ServerSha1) 
       if(local_sha1 == ServerSha1) 
@@ -544,7 +507,7 @@ void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)	/*{{{
    Dequeue();
    Dequeue();
 }
 }
 									/*}}}*/
 									/*}}}*/
-void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash,	/*{{{*/
+void pkgAcqDiffIndex::Done(string Message,unsigned long long Size,string Md5Hash,	/*{{{*/
 			   pkgAcquire::MethodConfig *Cnf)
 			   pkgAcquire::MethodConfig *Cnf)
 {
 {
    if(Debug)
    if(Debug)
@@ -665,7 +628,7 @@ bool pkgAcqIndexDiffs::QueueNextDiff()					/*{{{*/
 
 
    FileFd fd(FinalFile, FileFd::ReadOnly);
    FileFd fd(FinalFile, FileFd::ReadOnly);
    SHA1Summation SHA1;
    SHA1Summation SHA1;
-   SHA1.AddFD(fd.Fd(), fd.Size());
+   SHA1.AddFD(fd);
    string local_sha1 = string(SHA1.Result());
    string local_sha1 = string(SHA1.Result());
    if(Debug)
    if(Debug)
       std::clog << "QueueNextDiff: " 
       std::clog << "QueueNextDiff: " 
@@ -710,7 +673,7 @@ bool pkgAcqIndexDiffs::QueueNextDiff()					/*{{{*/
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,	/*{{{*/
+void pkgAcqIndexDiffs::Done(string Message,unsigned long long Size,string Md5Hash,	/*{{{*/
 			    pkgAcquire::MethodConfig *Cnf)
 			    pkgAcquire::MethodConfig *Cnf)
 {
 {
    if(Debug)
    if(Debug)
@@ -808,6 +771,13 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner, IndexTarget const *Target,
    if (CompressionExtension.empty() == false)
    if (CompressionExtension.empty() == false)
       CompressionExtension.erase(CompressionExtension.end()-1);
       CompressionExtension.erase(CompressionExtension.end()-1);
 
 
+   // only verify non-optional targets, see acquire-item.h for a FIXME
+   // to make this more flexible
+   if (Target->IsOptional())
+     Verify = false;
+   else
+     Verify = true;
+
    Init(Target->URI, Target->Description, Target->ShortDesc);
    Init(Target->URI, Target->Description, Target->ShortDesc);
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -881,7 +851,7 @@ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)	/*{{{*/
    to the uncompressed version of the file. If this is so the file
    to the uncompressed version of the file. If this is so the file
    is copied into the partial directory. In all other cases the file
    is copied into the partial directory. In all other cases the file
    is decompressed with a gzip uri. */
    is decompressed with a gzip uri. */
-void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash,
+void pkgAcqIndex::Done(string Message,unsigned long long Size,string Hash,
 		       pkgAcquire::MethodConfig *Cfg)
 		       pkgAcquire::MethodConfig *Cfg)
 {
 {
    Item::Done(Message,Size,Hash,Cfg);
    Item::Done(Message,Size,Hash,Cfg);
@@ -905,6 +875,7 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash,
 
 
       /* Verify the index file for correctness (all indexes must
       /* Verify the index file for correctness (all indexes must
        * have a Package field) (LP: #346386) (Closes: #627642) */
        * have a Package field) (LP: #346386) (Closes: #627642) */
+      if (Verify == true)
       {
       {
 	 FileFd fd(DestFile, FileFd::ReadOnly);
 	 FileFd fd(DestFile, FileFd::ReadOnly);
 	 pkgTagSection sec;
 	 pkgTagSection sec;
@@ -1123,7 +1094,7 @@ string pkgAcqMetaSig::Custom600Headers()
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 }
 }
 
 
-void pkgAcqMetaSig::Done(string Message,unsigned long Size,string MD5,
+void pkgAcqMetaSig::Done(string Message,unsigned long long Size,string MD5,
 			 pkgAcquire::MethodConfig *Cfg)
 			 pkgAcquire::MethodConfig *Cfg)
 {
 {
    Item::Done(Message,Size,MD5,Cfg);
    Item::Done(Message,Size,MD5,Cfg);
@@ -1232,7 +1203,7 @@ string pkgAcqMetaIndex::Custom600Headers()
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 }
 }
 									/*}}}*/
 									/*}}}*/
-void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash,	/*{{{*/
+void pkgAcqMetaIndex::Done(string Message,unsigned long long Size,string Hash,	/*{{{*/
 			   pkgAcquire::MethodConfig *Cfg)
 			   pkgAcquire::MethodConfig *Cfg)
 {
 {
    Item::Done(Message,Size,Hash,Cfg);
    Item::Done(Message,Size,Hash,Cfg);
@@ -1373,6 +1344,18 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)				/*{{{*/
       return;
       return;
    }
    }
 #endif
 #endif
+   bool transInRelease = false;
+   {
+      std::vector<std::string> const keys = MetaIndexParser->MetaKeys();
+      for (std::vector<std::string>::const_iterator k = keys.begin(); k != keys.end(); ++k)
+	 // FIXME: Feels wrong to check for hardcoded string here, but what should we do else…
+	 if (k->find("Translation-") != std::string::npos)
+	 {
+	    transInRelease = true;
+	    break;
+	 }
+   }
+
    for (vector <struct IndexTarget*>::const_iterator Target = IndexTargets->begin();
    for (vector <struct IndexTarget*>::const_iterator Target = IndexTargets->begin();
         Target != IndexTargets->end();
         Target != IndexTargets->end();
         ++Target)
         ++Target)
@@ -1410,8 +1393,15 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)				/*{{{*/
 	 if ((*Target)->IsSubIndex() == true)
 	 if ((*Target)->IsSubIndex() == true)
 	    new pkgAcqSubIndex(Owner, (*Target)->URI, (*Target)->Description,
 	    new pkgAcqSubIndex(Owner, (*Target)->URI, (*Target)->Description,
 				(*Target)->ShortDesc, ExpectedIndexHash);
 				(*Target)->ShortDesc, ExpectedIndexHash);
-	 else
-	    new pkgAcqIndexTrans(Owner, *Target, ExpectedIndexHash, MetaIndexParser);
+	 else if (transInRelease == false || MetaIndexParser->Exists((*Target)->MetaKey) == true)
+	 {
+	    if (_config->FindB("Acquire::PDiffs",true) == true && transInRelease == true &&
+		MetaIndexParser->Exists(string((*Target)->MetaKey).append(".diff/Index")) == true)
+	       new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description,
+				   (*Target)->ShortDesc, ExpectedIndexHash);
+	    else
+	       new pkgAcqIndexTrans(Owner, *Target, ExpectedIndexHash, MetaIndexParser);
+	 }
 	 continue;
 	 continue;
       }
       }
 
 
@@ -1738,6 +1728,8 @@ bool pkgAcqArchive::QueueNext()
       string PkgFile = Parse.FileName();
       string PkgFile = Parse.FileName();
       if (ForceHash.empty() == false)
       if (ForceHash.empty() == false)
       {
       {
+	 if(stringcasecmp(ForceHash, "sha512") == 0)
+	    ExpectedHash = HashString("SHA512", Parse.SHA512Hash());
 	 if(stringcasecmp(ForceHash, "sha256") == 0)
 	 if(stringcasecmp(ForceHash, "sha256") == 0)
 	    ExpectedHash = HashString("SHA256", Parse.SHA256Hash());
 	    ExpectedHash = HashString("SHA256", Parse.SHA256Hash());
 	 else if (stringcasecmp(ForceHash, "sha1") == 0)
 	 else if (stringcasecmp(ForceHash, "sha1") == 0)
@@ -1748,7 +1740,9 @@ bool pkgAcqArchive::QueueNext()
       else
       else
       {
       {
 	 string Hash;
 	 string Hash;
-	 if ((Hash = Parse.SHA256Hash()).empty() == false)
+	 if ((Hash = Parse.SHA512Hash()).empty() == false)
+	    ExpectedHash = HashString("SHA512", Hash);
+	 else if ((Hash = Parse.SHA256Hash()).empty() == false)
 	    ExpectedHash = HashString("SHA256", Hash);
 	    ExpectedHash = HashString("SHA256", Hash);
 	 else if ((Hash = Parse.SHA1Hash()).empty() == false)
 	 else if ((Hash = Parse.SHA1Hash()).empty() == false)
 	    ExpectedHash = HashString("SHA1", Hash);
 	    ExpectedHash = HashString("SHA1", Hash);
@@ -1772,7 +1766,7 @@ bool pkgAcqArchive::QueueNext()
       if (stat(FinalFile.c_str(),&Buf) == 0)
       if (stat(FinalFile.c_str(),&Buf) == 0)
       {
       {
 	 // Make sure the size matches
 	 // Make sure the size matches
-	 if ((unsigned)Buf.st_size == Version->Size)
+	 if ((unsigned long long)Buf.st_size == Version->Size)
 	 {
 	 {
 	    Complete = true;
 	    Complete = true;
 	    Local = true;
 	    Local = true;
@@ -1791,7 +1785,7 @@ bool pkgAcqArchive::QueueNext()
       if (stat(FinalFile.c_str(),&Buf) == 0)
       if (stat(FinalFile.c_str(),&Buf) == 0)
       {
       {
 	 // Make sure the size matches
 	 // Make sure the size matches
-	 if ((unsigned)Buf.st_size == Version->Size)
+	 if ((unsigned long long)Buf.st_size == Version->Size)
 	 {
 	 {
 	    Complete = true;
 	    Complete = true;
 	    Local = true;
 	    Local = true;
@@ -1811,12 +1805,23 @@ bool pkgAcqArchive::QueueNext()
       if (stat(DestFile.c_str(),&Buf) == 0)
       if (stat(DestFile.c_str(),&Buf) == 0)
       {
       {
 	 // Hmm, the partial file is too big, erase it
 	 // Hmm, the partial file is too big, erase it
-	 if ((unsigned)Buf.st_size > Version->Size)
+	 if ((unsigned long long)Buf.st_size > Version->Size)
 	    unlink(DestFile.c_str());
 	    unlink(DestFile.c_str());
 	 else
 	 else
 	    PartialSize = Buf.st_size;
 	    PartialSize = Buf.st_size;
       }
       }
-      
+
+      // Disables download of archives - useful if no real installation follows,
+      // e.g. if we are just interested in proposed installation order
+      if (_config->FindB("Debug::pkgAcqArchive::NoQueue", false) == true)
+      {
+	 Complete = true;
+	 Local = true;
+	 Status = StatDone;
+	 StoreFilename = DestFile = FinalFile;
+	 return true;
+      }
+
       // Create the item
       // Create the item
       Local = false;
       Local = false;
       Desc.URI = Index->ArchiveURI(PkgFile);
       Desc.URI = Index->ArchiveURI(PkgFile);
@@ -1834,7 +1839,7 @@ bool pkgAcqArchive::QueueNext()
 // AcqArchive::Done - Finished fetching					/*{{{*/
 // AcqArchive::Done - Finished fetching					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-void pkgAcqArchive::Done(string Message,unsigned long Size,string CalcHash,
+void pkgAcqArchive::Done(string Message,unsigned long long Size,string CalcHash,
 			 pkgAcquire::MethodConfig *Cfg)
 			 pkgAcquire::MethodConfig *Cfg)
 {
 {
    Item::Done(Message,Size,CalcHash,Cfg);
    Item::Done(Message,Size,CalcHash,Cfg);
@@ -1945,7 +1950,7 @@ void pkgAcqArchive::Finished()
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* The file is added to the queue */
 /* The file is added to the queue */
 pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string Hash,
 pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string Hash,
-		       unsigned long Size,string Dsc,string ShortDesc,
+		       unsigned long long Size,string Dsc,string ShortDesc,
 		       const string &DestDir, const string &DestFilename,
 		       const string &DestDir, const string &DestFilename,
                        bool IsIndexFile) :
                        bool IsIndexFile) :
                        Item(Owner), ExpectedHash(Hash), IsIndexFile(IsIndexFile)
                        Item(Owner), ExpectedHash(Hash), IsIndexFile(IsIndexFile)
@@ -1973,7 +1978,7 @@ pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string Hash,
    if (stat(DestFile.c_str(),&Buf) == 0)
    if (stat(DestFile.c_str(),&Buf) == 0)
    {
    {
       // Hmm, the partial file is too big, erase it
       // Hmm, the partial file is too big, erase it
-      if ((unsigned)Buf.st_size > Size)
+      if ((unsigned long long)Buf.st_size > Size)
 	 unlink(DestFile.c_str());
 	 unlink(DestFile.c_str());
       else
       else
 	 PartialSize = Buf.st_size;
 	 PartialSize = Buf.st_size;
@@ -1985,7 +1990,7 @@ pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string Hash,
 // AcqFile::Done - Item downloaded OK					/*{{{*/
 // AcqFile::Done - Item downloaded OK					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-void pkgAcqFile::Done(string Message,unsigned long Size,string CalcHash,
+void pkgAcqFile::Done(string Message,unsigned long long Size,string CalcHash,
 		      pkgAcquire::MethodConfig *Cnf)
 		      pkgAcquire::MethodConfig *Cnf)
 {
 {
    Item::Done(Message,Size,CalcHash,Cnf);
    Item::Done(Message,Size,CalcHash,Cnf);
@@ -2073,13 +2078,3 @@ string pkgAcqFile::Custom600Headers()
    return "";
    return "";
 }
 }
 									/*}}}*/
 									/*}}}*/
-bool IndexTarget::IsOptional() const {
-   if (strncmp(ShortDesc.c_str(), "Translation", 11) != 0)
-      return false;
-   return true;
-}
-bool IndexTarget::IsSubIndex() const {
-   if (ShortDesc != "TranslationIndex")
-      return false;
-   return true;
-}

+ 163 - 122
apt-pkg/acquire-item.h

@@ -21,13 +21,17 @@
 #define PKGLIB_ACQUIRE_ITEM_H
 #define PKGLIB_ACQUIRE_ITEM_H
 
 
 #include <apt-pkg/acquire.h>
 #include <apt-pkg/acquire.h>
+#include <apt-pkg/hashes.h>
+#include <apt-pkg/weakptr.h>
+#include <apt-pkg/pkgcache.h>
+
+#ifndef APT_8_CLEANER_HEADERS
 #include <apt-pkg/indexfile.h>
 #include <apt-pkg/indexfile.h>
 #include <apt-pkg/vendor.h>
 #include <apt-pkg/vendor.h>
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/pkgrecords.h>
 #include <apt-pkg/pkgrecords.h>
 #include <apt-pkg/indexrecords.h>
 #include <apt-pkg/indexrecords.h>
-#include <apt-pkg/hashes.h>
-#include <apt-pkg/weakptr.h>
+#endif
 
 
 /** \addtogroup acquire
 /** \addtogroup acquire
  *  @{
  *  @{
@@ -35,6 +39,10 @@
  *  \file acquire-item.h
  *  \file acquire-item.h
  */
  */
 
 
+class indexRecords;
+class pkgRecords;
+class pkgSourceList;
+
 /** \brief Represents the process by which a pkgAcquire object should	{{{
 /** \brief Represents the process by which a pkgAcquire object should	{{{
  *  retrieve a file or a collection of files.
  *  retrieve a file or a collection of files.
  *
  *
@@ -74,7 +82,7 @@ class pkgAcquire::Item : public WeakPointable
     *  \param To The new name of #From.  If #To exists it will be
     *  \param To The new name of #From.  If #To exists it will be
     *  overwritten.
     *  overwritten.
     */
     */
-   void Rename(string From,string To);
+   void Rename(std::string From,std::string To);
    
    
    public:
    public:
 
 
@@ -109,7 +117,7 @@ class pkgAcquire::Item : public WeakPointable
    /** \brief Contains a textual description of the error encountered
    /** \brief Contains a textual description of the error encountered
     *  if #Status is #StatError or #StatAuthError.
     *  if #Status is #StatError or #StatAuthError.
     */
     */
-   string ErrorText;
+   std::string ErrorText;
 
 
    /** \brief The size of the object to fetch. */
    /** \brief The size of the object to fetch. */
    unsigned long long FileSize;
    unsigned long long FileSize;
@@ -143,7 +151,7 @@ class pkgAcquire::Item : public WeakPointable
     *  download progress indicator's overall statistics.
     *  download progress indicator's overall statistics.
     */
     */
    bool Local;
    bool Local;
-   string UsedMirror;
+   std::string UsedMirror;
 
 
    /** \brief The number of fetch queues into which this item has been
    /** \brief The number of fetch queues into which this item has been
     *  inserted.
     *  inserted.
@@ -158,7 +166,7 @@ class pkgAcquire::Item : public WeakPointable
    /** \brief The name of the file into which the retrieved object
    /** \brief The name of the file into which the retrieved object
     *  will be written.
     *  will be written.
     */
     */
-   string DestFile;
+   std::string DestFile;
 
 
    /** \brief Invoked by the acquire worker when the object couldn't
    /** \brief Invoked by the acquire worker when the object couldn't
     *  be fetched.
     *  be fetched.
@@ -173,7 +181,7 @@ class pkgAcquire::Item : public WeakPointable
     *
     *
     *  \sa pkgAcqMethod
     *  \sa pkgAcqMethod
     */
     */
-   virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
+   virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf);
 
 
    /** \brief Invoked by the acquire worker when the object was
    /** \brief Invoked by the acquire worker when the object was
     *  fetched successfully.
     *  fetched successfully.
@@ -194,7 +202,7 @@ class pkgAcquire::Item : public WeakPointable
     *
     *
     *  \sa pkgAcqMethod
     *  \sa pkgAcqMethod
     */
     */
-   virtual void Done(string Message,unsigned long Size,string Hash,
+   virtual void Done(std::string Message,unsigned long long Size,std::string Hash,
 		     pkgAcquire::MethodConfig *Cnf);
 		     pkgAcquire::MethodConfig *Cnf);
 
 
    /** \brief Invoked when the worker starts to fetch this object.
    /** \brief Invoked when the worker starts to fetch this object.
@@ -206,7 +214,7 @@ class pkgAcquire::Item : public WeakPointable
     *
     *
     *  \sa pkgAcqMethod
     *  \sa pkgAcqMethod
     */
     */
-   virtual void Start(string Message,unsigned long Size);
+   virtual void Start(std::string Message,unsigned long long Size);
 
 
    /** \brief Custom headers to be sent to the fetch process.
    /** \brief Custom headers to be sent to the fetch process.
     *
     *
@@ -216,18 +224,18 @@ class pkgAcquire::Item : public WeakPointable
     *  line, so they should (if nonempty) have a leading newline and
     *  line, so they should (if nonempty) have a leading newline and
     *  no trailing newline.
     *  no trailing newline.
     */
     */
-   virtual string Custom600Headers() {return string();};
+   virtual std::string Custom600Headers() {return std::string();};
 
 
    /** \brief A "descriptive" URI-like string.
    /** \brief A "descriptive" URI-like string.
     *
     *
     *  \return a URI that should be used to describe what is being fetched.
     *  \return a URI that should be used to describe what is being fetched.
     */
     */
-   virtual string DescURI() = 0;
+   virtual std::string DescURI() = 0;
    /** \brief Short item description.
    /** \brief Short item description.
     *
     *
     *  \return a brief description of the object being fetched.
     *  \return a brief description of the object being fetched.
     */
     */
-   virtual string ShortDesc() {return DescURI();}
+   virtual std::string ShortDesc() {return DescURI();}
 
 
    /** \brief Invoked by the worker when the download is completely done. */
    /** \brief Invoked by the worker when the download is completely done. */
    virtual void Finished() {};
    virtual void Finished() {};
@@ -237,7 +245,7 @@ class pkgAcquire::Item : public WeakPointable
     *  \return the HashSum of this object, if applicable; otherwise, an
     *  \return the HashSum of this object, if applicable; otherwise, an
     *  empty string.
     *  empty string.
     */
     */
-   virtual string HashSum() {return string();};
+   virtual std::string HashSum() {return std::string();};
 
 
    /** \return the acquire process with which this item is associated. */
    /** \return the acquire process with which this item is associated. */
    pkgAcquire *GetOwner() {return Owner;};
    pkgAcquire *GetOwner() {return Owner;};
@@ -253,7 +261,7 @@ class pkgAcquire::Item : public WeakPointable
     * 
     * 
     *  \param FailCode A short failure string that is send
     *  \param FailCode A short failure string that is send
     */
     */
-   void ReportMirrorFailure(string FailCode);
+   void ReportMirrorFailure(std::string FailCode);
 
 
 
 
    /** \brief Initialize an item.
    /** \brief Initialize an item.
@@ -278,10 +286,10 @@ class pkgAcquire::Item : public WeakPointable
 /** \brief Information about an index patch (aka diff). */		/*{{{*/
 /** \brief Information about an index patch (aka diff). */		/*{{{*/
 struct DiffInfo {
 struct DiffInfo {
    /** The filename of the diff. */
    /** The filename of the diff. */
-   string file;
+   std::string file;
 
 
    /** The sha1 hash of the diff. */
    /** The sha1 hash of the diff. */
-   string sha1;
+   std::string sha1;
 
 
    /** The size of the diff. */
    /** The size of the diff. */
    unsigned long size;
    unsigned long size;
@@ -308,12 +316,12 @@ class pkgAcqSubIndex : public pkgAcquire::Item
 
 
  public:
  public:
    // Specialized action members
    // Specialized action members
-   virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
-   virtual void Done(string Message,unsigned long Size,string Md5Hash,
+   virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf);
+   virtual void Done(std::string Message,unsigned long long Size,std::string Md5Hash,
 		     pkgAcquire::MethodConfig *Cnf);
 		     pkgAcquire::MethodConfig *Cnf);
-   virtual string DescURI() {return Desc.URI;};
-   virtual string Custom600Headers();
-   virtual bool ParseIndex(string const &IndexFile);
+   virtual std::string DescURI() {return Desc.URI;};
+   virtual std::string Custom600Headers();
+   virtual bool ParseIndex(std::string const &IndexFile);
 
 
    /** \brief Create a new pkgAcqSubIndex.
    /** \brief Create a new pkgAcqSubIndex.
     *
     *
@@ -327,8 +335,8 @@ class pkgAcqSubIndex : public pkgAcquire::Item
     *
     *
     *  \param ExpectedHash The list file's MD5 signature.
     *  \param ExpectedHash The list file's MD5 signature.
     */
     */
-   pkgAcqSubIndex(pkgAcquire *Owner, string const &URI,string const &URIDesc,
-		   string const &ShortDesc, HashString const &ExpectedHash);
+   pkgAcqSubIndex(pkgAcquire *Owner, std::string const &URI,std::string const &URIDesc,
+		   std::string const &ShortDesc, HashString const &ExpectedHash);
 };
 };
 									/*}}}*/
 									/*}}}*/
 /** \brief An item that is responsible for fetching an index file of	{{{
 /** \brief An item that is responsible for fetching an index file of	{{{
@@ -352,7 +360,7 @@ class pkgAcqDiffIndex : public pkgAcquire::Item
    /** \brief The URI of the index file to recreate at our end (either
    /** \brief The URI of the index file to recreate at our end (either
     *  by downloading it or by applying partial patches).
     *  by downloading it or by applying partial patches).
     */
     */
-   string RealURI;
+   std::string RealURI;
 
 
    /** \brief The Hash that the real index file should have after
    /** \brief The Hash that the real index file should have after
     *  all patches have been applied.
     *  all patches have been applied.
@@ -362,20 +370,20 @@ class pkgAcqDiffIndex : public pkgAcquire::Item
    /** \brief The index file which will be patched to generate the new
    /** \brief The index file which will be patched to generate the new
     *  file.
     *  file.
     */
     */
-   string CurrentPackagesFile;
+   std::string CurrentPackagesFile;
 
 
    /** \brief A description of the Packages file (stored in
    /** \brief A description of the Packages file (stored in
     *  pkgAcquire::ItemDesc::Description).
     *  pkgAcquire::ItemDesc::Description).
     */
     */
-   string Description;
+   std::string Description;
 
 
  public:
  public:
    // Specialized action members
    // Specialized action members
-   virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
-   virtual void Done(string Message,unsigned long Size,string Md5Hash,
+   virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf);
+   virtual void Done(std::string Message,unsigned long long Size,std::string Md5Hash,
 		     pkgAcquire::MethodConfig *Cnf);
 		     pkgAcquire::MethodConfig *Cnf);
-   virtual string DescURI() {return RealURI + "Index";};
-   virtual string Custom600Headers();
+   virtual std::string DescURI() {return RealURI + "Index";};
+   virtual std::string Custom600Headers();
 
 
    /** \brief Parse the Index file for a set of Packages diffs.
    /** \brief Parse the Index file for a set of Packages diffs.
     *
     *
@@ -387,7 +395,7 @@ class pkgAcqDiffIndex : public pkgAcquire::Item
     *  \return \b true if the Index file was successfully parsed, \b
     *  \return \b true if the Index file was successfully parsed, \b
     *  false otherwise.
     *  false otherwise.
     */
     */
-   bool ParseDiffIndex(string IndexDiffFile);
+   bool ParseDiffIndex(std::string IndexDiffFile);
    
    
 
 
    /** \brief Create a new pkgAcqDiffIndex.
    /** \brief Create a new pkgAcqDiffIndex.
@@ -402,8 +410,8 @@ class pkgAcqDiffIndex : public pkgAcquire::Item
     *
     *
     *  \param ExpectedHash The list file's MD5 signature.
     *  \param ExpectedHash The list file's MD5 signature.
     */
     */
-   pkgAcqDiffIndex(pkgAcquire *Owner,string URI,string URIDesc,
-		   string ShortDesc, HashString ExpectedHash);
+   pkgAcqDiffIndex(pkgAcquire *Owner,std::string URI,std::string URIDesc,
+		   std::string ShortDesc, HashString ExpectedHash);
 };
 };
 									/*}}}*/
 									/*}}}*/
 /** \brief An item that is responsible for fetching all the patches	{{{
 /** \brief An item that is responsible for fetching all the patches	{{{
@@ -460,7 +468,7 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
    /** \brief The URI of the package index file that is being
    /** \brief The URI of the package index file that is being
     *  reconstructed.
     *  reconstructed.
     */
     */
-   string RealURI;
+   std::string RealURI;
 
 
    /** \brief The HashSum of the package index file that is being
    /** \brief The HashSum of the package index file that is being
     *  reconstructed.
     *  reconstructed.
@@ -468,7 +476,7 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
    HashString ExpectedHash;
    HashString ExpectedHash;
 
 
    /** A description of the file being downloaded. */
    /** A description of the file being downloaded. */
-   string Description;
+   std::string Description;
 
 
    /** The patches that remain to be downloaded, including the patch
    /** The patches that remain to be downloaded, including the patch
     *  being downloaded right now.  This list should be ordered so
     *  being downloaded right now.  This list should be ordered so
@@ -478,10 +486,10 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
     *  dictionary instead of relying on ordering and stripping them
     *  dictionary instead of relying on ordering and stripping them
     *  off the front?
     *  off the front?
     */
     */
-   vector<DiffInfo> available_patches;
+   std::vector<DiffInfo> available_patches;
 
 
    /** Stop applying patches when reaching that sha1 */
    /** Stop applying patches when reaching that sha1 */
-   string ServerSha1;
+   std::string ServerSha1;
 
 
    /** The current status of this patch. */
    /** The current status of this patch. */
    enum DiffState
    enum DiffState
@@ -506,11 +514,11 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
     *  This method will fall back to downloading the whole index file
     *  This method will fall back to downloading the whole index file
     *  outright; its arguments are ignored.
     *  outright; its arguments are ignored.
     */
     */
-   virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
+   virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf);
 
 
-   virtual void Done(string Message,unsigned long Size,string Md5Hash,
+   virtual void Done(std::string Message,unsigned long long Size,std::string Md5Hash,
 		     pkgAcquire::MethodConfig *Cnf);
 		     pkgAcquire::MethodConfig *Cnf);
-   virtual string DescURI() {return RealURI + "Index";};
+   virtual std::string DescURI() {return RealURI + "Index";};
 
 
    /** \brief Create an index diff item.
    /** \brief Create an index diff item.
     *
     *
@@ -534,10 +542,10 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
     *  should be ordered so that each diff appears before any diff
     *  should be ordered so that each diff appears before any diff
     *  that depends on it.
     *  that depends on it.
     */
     */
-   pkgAcqIndexDiffs(pkgAcquire *Owner,string URI,string URIDesc,
-		    string ShortDesc, HashString ExpectedHash,
-		    string ServerSha1,
-		    vector<DiffInfo> diffs=vector<DiffInfo>());
+   pkgAcqIndexDiffs(pkgAcquire *Owner,std::string URI,std::string URIDesc,
+		    std::string ShortDesc, HashString ExpectedHash,
+		    std::string ServerSha1,
+		    std::vector<DiffInfo> diffs=std::vector<DiffInfo>());
 };
 };
 									/*}}}*/
 									/*}}}*/
 /** \brief An acquire item that is responsible for fetching an index	{{{
 /** \brief An acquire item that is responsible for fetching an index	{{{
@@ -559,6 +567,16 @@ class pkgAcqIndex : public pkgAcquire::Item
     */
     */
    bool Erase;
    bool Erase;
 
 
+   /** \brief Verify for correctness by checking if a "Package"
+    *         tag is found in the index. This can be set to
+    *         false for optional index targets
+    *       
+    */
+   // FIXME: instead of a bool it should use a verify string that will
+   //        then be used in the pkgAcqIndex::Done method to ensure that
+   //        the downloaded file contains the expected tag
+   bool Verify;
+
    /** \brief The download request that is currently being
    /** \brief The download request that is currently being
     *   processed.
     *   processed.
     */
     */
@@ -567,7 +585,7 @@ class pkgAcqIndex : public pkgAcquire::Item
    /** \brief The object that is actually being fetched (minus any
    /** \brief The object that is actually being fetched (minus any
     *  compression-related extensions).
     *  compression-related extensions).
     */
     */
-   string RealURI;
+   std::string RealURI;
 
 
    /** \brief The expected hashsum of the decompressed index file. */
    /** \brief The expected hashsum of the decompressed index file. */
    HashString ExpectedHash;
    HashString ExpectedHash;
@@ -575,17 +593,17 @@ class pkgAcqIndex : public pkgAcquire::Item
    /** \brief The compression-related file extensions that are being
    /** \brief The compression-related file extensions that are being
     *  added to the downloaded file one by one if first fails (e.g., "gz bz2").
     *  added to the downloaded file one by one if first fails (e.g., "gz bz2").
     */
     */
-   string CompressionExtension;
+   std::string CompressionExtension;
 
 
    public:
    public:
    
    
    // Specialized action members
    // Specialized action members
-   virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
-   virtual void Done(string Message,unsigned long Size,string Md5Hash,
+   virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf);
+   virtual void Done(std::string Message,unsigned long long Size,std::string Md5Hash,
 		     pkgAcquire::MethodConfig *Cnf);
 		     pkgAcquire::MethodConfig *Cnf);
-   virtual string Custom600Headers();
-   virtual string DescURI() {return Desc.URI;};
-   virtual string HashSum() {return ExpectedHash.toStr(); };
+   virtual std::string Custom600Headers();
+   virtual std::string DescURI() {return Desc.URI;};
+   virtual std::string HashSum() {return ExpectedHash.toStr(); };
 
 
    /** \brief Create a pkgAcqIndex.
    /** \brief Create a pkgAcqIndex.
     *
     *
@@ -606,12 +624,12 @@ class pkgAcqIndex : public pkgAcquire::Item
     *  default is ".lzma" or ".bz2" (if the needed binaries are present)
     *  default is ".lzma" or ".bz2" (if the needed binaries are present)
     *  fallback is ".gz" or none.
     *  fallback is ".gz" or none.
     */
     */
-   pkgAcqIndex(pkgAcquire *Owner,string URI,string URIDesc,
-	       string ShortDesc, HashString ExpectedHash, 
-	       string compressExt="");
+   pkgAcqIndex(pkgAcquire *Owner,std::string URI,std::string URIDesc,
+	       std::string ShortDesc, HashString ExpectedHash, 
+	       std::string compressExt="");
    pkgAcqIndex(pkgAcquire *Owner, struct IndexTarget const * const Target,
    pkgAcqIndex(pkgAcquire *Owner, struct IndexTarget const * const Target,
 			 HashString const &ExpectedHash, indexRecords const *MetaIndexParser);
 			 HashString const &ExpectedHash, indexRecords const *MetaIndexParser);
-   void Init(string const &URI, string const &URIDesc, string const &ShortDesc);
+   void Init(std::string const &URI, std::string const &URIDesc, std::string const &ShortDesc);
 };
 };
 									/*}}}*/
 									/*}}}*/
 /** \brief An acquire item that is responsible for fetching a		{{{
 /** \brief An acquire item that is responsible for fetching a		{{{
@@ -625,8 +643,8 @@ class pkgAcqIndexTrans : public pkgAcqIndex
 {
 {
    public:
    public:
   
   
-   virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
-   virtual string Custom600Headers();
+   virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf);
+   virtual std::string Custom600Headers();
 
 
    /** \brief Create a pkgAcqIndexTrans.
    /** \brief Create a pkgAcqIndexTrans.
     *
     *
@@ -639,37 +657,60 @@ class pkgAcqIndexTrans : public pkgAcqIndex
     *
     *
     *  \param ShortDesc A brief description of this index file.
     *  \param ShortDesc A brief description of this index file.
     */
     */
-   pkgAcqIndexTrans(pkgAcquire *Owner,string URI,string URIDesc,
-		    string ShortDesc);
+   pkgAcqIndexTrans(pkgAcquire *Owner,std::string URI,std::string URIDesc,
+		    std::string ShortDesc);
    pkgAcqIndexTrans(pkgAcquire *Owner, struct IndexTarget const * const Target,
    pkgAcqIndexTrans(pkgAcquire *Owner, struct IndexTarget const * const Target,
 		    HashString const &ExpectedHash, indexRecords const *MetaIndexParser);
 		    HashString const &ExpectedHash, indexRecords const *MetaIndexParser);
 };
 };
 									/*}}}*/
 									/*}}}*/
 /** \brief Information about an index file. */				/*{{{*/
 /** \brief Information about an index file. */				/*{{{*/
-struct IndexTarget
+class IndexTarget
 {
 {
+ public:
    /** \brief A URI from which the index file can be downloaded. */
    /** \brief A URI from which the index file can be downloaded. */
-   string URI;
+   std::string URI;
 
 
    /** \brief A description of the index file. */
    /** \brief A description of the index file. */
-   string Description;
+   std::string Description;
 
 
    /** \brief A shorter description of the index file. */
    /** \brief A shorter description of the index file. */
-   string ShortDesc;
+   std::string ShortDesc;
 
 
    /** \brief The key by which this index file should be
    /** \brief The key by which this index file should be
     *  looked up within the meta signature file.
     *  looked up within the meta signature file.
     */
     */
-   string MetaKey;
-
-   //FIXME: We should use virtual methods here instead…
-   bool IsOptional() const;
-   bool IsSubIndex() const;
+   std::string MetaKey;
+
+   virtual bool IsOptional() const {
+      return false;
+   }
+   virtual bool IsSubIndex() const {
+      return false;
+   }
 };
 };
 									/*}}}*/
 									/*}}}*/
 /** \brief Information about an optional index file. */			/*{{{*/
 /** \brief Information about an optional index file. */			/*{{{*/
-struct OptionalIndexTarget : public IndexTarget
+class OptionalIndexTarget : public IndexTarget
+{
+   virtual bool IsOptional() const {
+      return true;
+   }
+};
+									/*}}}*/
+/** \brief Information about an subindex index file. */			/*{{{*/
+class SubIndexTarget : public IndexTarget
+{
+   virtual bool IsSubIndex() const {
+      return true;
+   }
+};
+									/*}}}*/
+/** \brief Information about an subindex index file. */			/*{{{*/
+class OptionalSubIndexTarget : public OptionalIndexTarget
 {
 {
+   virtual bool IsSubIndex() const {
+      return true;
+   }
 };
 };
 									/*}}}*/
 									/*}}}*/
 
 
@@ -685,7 +726,7 @@ class pkgAcqMetaSig : public pkgAcquire::Item
 {
 {
    protected:
    protected:
    /** \brief The last good signature file */
    /** \brief The last good signature file */
-   string LastGoodSig;
+   std::string LastGoodSig;
 
 
    /** \brief The fetch request that is currently being processed. */
    /** \brief The fetch request that is currently being processed. */
    pkgAcquire::ItemDesc Desc;
    pkgAcquire::ItemDesc Desc;
@@ -694,20 +735,20 @@ class pkgAcqMetaSig : public pkgAcquire::Item
     *  never modified; it is used to determine the file that is being
     *  never modified; it is used to determine the file that is being
     *  downloaded.
     *  downloaded.
     */
     */
-   string RealURI;
+   std::string RealURI;
 
 
    /** \brief The URI of the meta-index file to be fetched after the signature. */
    /** \brief The URI of the meta-index file to be fetched after the signature. */
-   string MetaIndexURI;
+   std::string MetaIndexURI;
 
 
    /** \brief A "URI-style" description of the meta-index file to be
    /** \brief A "URI-style" description of the meta-index file to be
     *  fetched after the signature.
     *  fetched after the signature.
     */
     */
-   string MetaIndexURIDesc;
+   std::string MetaIndexURIDesc;
 
 
    /** \brief A brief description of the meta-index file to be fetched
    /** \brief A brief description of the meta-index file to be fetched
     *  after the signature.
     *  after the signature.
     */
     */
-   string MetaIndexShortDesc;
+   std::string MetaIndexShortDesc;
 
 
    /** \brief A package-system-specific parser for the meta-index file. */
    /** \brief A package-system-specific parser for the meta-index file. */
    indexRecords* MetaIndexParser;
    indexRecords* MetaIndexParser;
@@ -717,21 +758,21 @@ class pkgAcqMetaSig : public pkgAcquire::Item
     *
     *
     *  \todo Why a list of pointers instead of a list of structs?
     *  \todo Why a list of pointers instead of a list of structs?
     */
     */
-   const vector<struct IndexTarget*>* IndexTargets;
+   const std::vector<struct IndexTarget*>* IndexTargets;
 
 
    public:
    public:
    
    
    // Specialized action members
    // Specialized action members
-   virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
-   virtual void Done(string Message,unsigned long Size,string Md5Hash,
+   virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf);
+   virtual void Done(std::string Message,unsigned long long Size,std::string Md5Hash,
 		     pkgAcquire::MethodConfig *Cnf);
 		     pkgAcquire::MethodConfig *Cnf);
-   virtual string Custom600Headers();
-   virtual string DescURI() {return RealURI; };
+   virtual std::string Custom600Headers();
+   virtual std::string DescURI() {return RealURI; };
 
 
    /** \brief Create a new pkgAcqMetaSig. */
    /** \brief Create a new pkgAcqMetaSig. */
-   pkgAcqMetaSig(pkgAcquire *Owner,string URI,string URIDesc, string ShortDesc,
-		 string MetaIndexURI, string MetaIndexURIDesc, string MetaIndexShortDesc,
-		 const vector<struct IndexTarget*>* IndexTargets,
+   pkgAcqMetaSig(pkgAcquire *Owner,std::string URI,std::string URIDesc, std::string ShortDesc,
+		 std::string MetaIndexURI, std::string MetaIndexURIDesc, std::string MetaIndexShortDesc,
+		 const std::vector<struct IndexTarget*>* IndexTargets,
 		 indexRecords* MetaIndexParser);
 		 indexRecords* MetaIndexParser);
 };
 };
 									/*}}}*/
 									/*}}}*/
@@ -754,17 +795,17 @@ class pkgAcqMetaIndex : public pkgAcquire::Item
    /** \brief The URI that is actually being downloaded; never
    /** \brief The URI that is actually being downloaded; never
     *  modified by pkgAcqMetaIndex.
     *  modified by pkgAcqMetaIndex.
     */
     */
-   string RealURI;
+   std::string RealURI;
 
 
    /** \brief The file in which the signature for this index was stored.
    /** \brief The file in which the signature for this index was stored.
     *
     *
     *  If empty, the signature and the md5sums of the individual
     *  If empty, the signature and the md5sums of the individual
     *  indices will not be checked.
     *  indices will not be checked.
     */
     */
-   string SigFile;
+   std::string SigFile;
 
 
    /** \brief The index files to download. */
    /** \brief The index files to download. */
-   const vector<struct IndexTarget*>* IndexTargets;
+   const std::vector<struct IndexTarget*>* IndexTargets;
 
 
    /** \brief The parser for the meta-index file. */
    /** \brief The parser for the meta-index file. */
    indexRecords* MetaIndexParser;
    indexRecords* MetaIndexParser;
@@ -780,7 +821,7 @@ class pkgAcqMetaIndex : public pkgAcquire::Item
     *
     *
     *  \return \b true if no fatal errors were encountered.
     *  \return \b true if no fatal errors were encountered.
     */
     */
-   bool VerifyVendor(string Message);
+   bool VerifyVendor(std::string Message);
 
 
    /** \brief Called when a file is finished being retrieved.
    /** \brief Called when a file is finished being retrieved.
     *
     *
@@ -791,7 +832,7 @@ class pkgAcqMetaIndex : public pkgAcquire::Item
     *  \param Message The message block received from the fetch
     *  \param Message The message block received from the fetch
     *  subprocess.
     *  subprocess.
     */
     */
-   void RetrievalDone(string Message);
+   void RetrievalDone(std::string Message);
 
 
    /** \brief Called when authentication succeeded.
    /** \brief Called when authentication succeeded.
     *
     *
@@ -802,7 +843,7 @@ class pkgAcqMetaIndex : public pkgAcquire::Item
     *  \param Message The message block received from the fetch
     *  \param Message The message block received from the fetch
     *  subprocess.
     *  subprocess.
     */
     */
-   void AuthDone(string Message);
+   void AuthDone(std::string Message);
 
 
    /** \brief Starts downloading the individual index files.
    /** \brief Starts downloading the individual index files.
     *
     *
@@ -817,17 +858,17 @@ class pkgAcqMetaIndex : public pkgAcquire::Item
    public:
    public:
    
    
    // Specialized action members
    // Specialized action members
-   virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
-   virtual void Done(string Message,unsigned long Size, string Hash,
+   virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf);
+   virtual void Done(std::string Message,unsigned long long Size, std::string Hash,
 		     pkgAcquire::MethodConfig *Cnf);
 		     pkgAcquire::MethodConfig *Cnf);
-   virtual string Custom600Headers();
-   virtual string DescURI() {return RealURI; };
+   virtual std::string Custom600Headers();
+   virtual std::string DescURI() {return RealURI; };
 
 
    /** \brief Create a new pkgAcqMetaIndex. */
    /** \brief Create a new pkgAcqMetaIndex. */
    pkgAcqMetaIndex(pkgAcquire *Owner,
    pkgAcqMetaIndex(pkgAcquire *Owner,
-		   string URI,string URIDesc, string ShortDesc,
-		   string SigFile,
-		   const vector<struct IndexTarget*>* IndexTargets,
+		   std::string URI,std::string URIDesc, std::string ShortDesc,
+		   std::string SigFile,
+		   const std::vector<struct IndexTarget*>* IndexTargets,
 		   indexRecords* MetaIndexParser);
 		   indexRecords* MetaIndexParser);
 };
 };
 									/*}}}*/
 									/*}}}*/
@@ -835,33 +876,33 @@ class pkgAcqMetaIndex : public pkgAcquire::Item
 class pkgAcqMetaClearSig : public pkgAcqMetaIndex
 class pkgAcqMetaClearSig : public pkgAcqMetaIndex
 {
 {
    /** \brief The URI of the meta-index file for the detached signature */
    /** \brief The URI of the meta-index file for the detached signature */
-   string MetaIndexURI;
+   std::string MetaIndexURI;
 
 
    /** \brief A "URI-style" description of the meta-index file */
    /** \brief A "URI-style" description of the meta-index file */
-   string MetaIndexURIDesc;
+   std::string MetaIndexURIDesc;
 
 
    /** \brief A brief description of the meta-index file */
    /** \brief A brief description of the meta-index file */
-   string MetaIndexShortDesc;
+   std::string MetaIndexShortDesc;
 
 
    /** \brief The URI of the detached meta-signature file if the clearsigned one failed. */
    /** \brief The URI of the detached meta-signature file if the clearsigned one failed. */
-   string MetaSigURI;
+   std::string MetaSigURI;
 
 
    /** \brief A "URI-style" description of the meta-signature file */
    /** \brief A "URI-style" description of the meta-signature file */
-   string MetaSigURIDesc;
+   std::string MetaSigURIDesc;
 
 
    /** \brief A brief description of the meta-signature file */
    /** \brief A brief description of the meta-signature file */
-   string MetaSigShortDesc;
+   std::string MetaSigShortDesc;
 
 
 public:
 public:
-   void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
-   virtual string Custom600Headers();
+   void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf);
+   virtual std::string Custom600Headers();
 
 
    /** \brief Create a new pkgAcqMetaClearSig. */
    /** \brief Create a new pkgAcqMetaClearSig. */
    pkgAcqMetaClearSig(pkgAcquire *Owner,
    pkgAcqMetaClearSig(pkgAcquire *Owner,
-		string const &URI, string const &URIDesc, string const &ShortDesc,
-		string const &MetaIndexURI, string const &MetaIndexURIDesc, string const &MetaIndexShortDesc,
-		string const &MetaSigURI, string const &MetaSigURIDesc, string const &MetaSigShortDesc,
-		const vector<struct IndexTarget*>* IndexTargets,
+		std::string const &URI, std::string const &URIDesc, std::string const &ShortDesc,
+		std::string const &MetaIndexURI, std::string const &MetaIndexURIDesc, std::string const &MetaIndexShortDesc,
+		std::string const &MetaSigURI, std::string const &MetaSigURIDesc, std::string const &MetaSigShortDesc,
+		const std::vector<struct IndexTarget*>* IndexTargets,
 		indexRecords* MetaIndexParser);
 		indexRecords* MetaIndexParser);
 };
 };
 									/*}}}*/
 									/*}}}*/
@@ -895,7 +936,7 @@ class pkgAcqArchive : public pkgAcquire::Item
    /** \brief A location in which the actual filename of the package
    /** \brief A location in which the actual filename of the package
     *  should be stored.
     *  should be stored.
     */
     */
-   string &StoreFilename;
+   std::string &StoreFilename;
 
 
    /** \brief The next file for this version to try to download. */
    /** \brief The next file for this version to try to download. */
    pkgCache::VerFileIterator Vf;
    pkgCache::VerFileIterator Vf;
@@ -917,13 +958,13 @@ class pkgAcqArchive : public pkgAcquire::Item
    
    
    public:
    public:
    
    
-   virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
-   virtual void Done(string Message,unsigned long Size,string Hash,
+   virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf);
+   virtual void Done(std::string Message,unsigned long long Size,std::string Hash,
 		     pkgAcquire::MethodConfig *Cnf);
 		     pkgAcquire::MethodConfig *Cnf);
-   virtual string DescURI() {return Desc.URI;};
-   virtual string ShortDesc() {return Desc.ShortDesc;};
+   virtual std::string DescURI() {return Desc.URI;};
+   virtual std::string ShortDesc() {return Desc.ShortDesc;};
    virtual void Finished();
    virtual void Finished();
-   virtual string HashSum() {return ExpectedHash.toStr(); };
+   virtual std::string HashSum() {return ExpectedHash.toStr(); };
    virtual bool IsTrusted();
    virtual bool IsTrusted();
    
    
    /** \brief Create a new pkgAcqArchive.
    /** \brief Create a new pkgAcqArchive.
@@ -946,7 +987,7 @@ class pkgAcqArchive : public pkgAcquire::Item
     */
     */
    pkgAcqArchive(pkgAcquire *Owner,pkgSourceList *Sources,
    pkgAcqArchive(pkgAcquire *Owner,pkgSourceList *Sources,
 		 pkgRecords *Recs,pkgCache::VerIterator const &Version,
 		 pkgRecords *Recs,pkgCache::VerIterator const &Version,
-		 string &StoreFilename);
+		 std::string &StoreFilename);
 };
 };
 									/*}}}*/
 									/*}}}*/
 /** \brief Retrieve an arbitrary file to the current directory.		{{{
 /** \brief Retrieve an arbitrary file to the current directory.		{{{
@@ -974,12 +1015,12 @@ class pkgAcqFile : public pkgAcquire::Item
    public:
    public:
    
    
    // Specialized action members
    // Specialized action members
-   virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
-   virtual void Done(string Message,unsigned long Size,string CalcHash,
+   virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf);
+   virtual void Done(std::string Message,unsigned long long Size,std::string CalcHash,
 		     pkgAcquire::MethodConfig *Cnf);
 		     pkgAcquire::MethodConfig *Cnf);
-   virtual string DescURI() {return Desc.URI;};
-   virtual string HashSum() {return ExpectedHash.toStr(); };
-   virtual string Custom600Headers();
+   virtual std::string DescURI() {return Desc.URI;};
+   virtual std::string HashSum() {return ExpectedHash.toStr(); };
+   virtual std::string Custom600Headers();
 
 
    /** \brief Create a new pkgAcqFile object.
    /** \brief Create a new pkgAcqFile object.
     *
     *
@@ -1012,9 +1053,9 @@ class pkgAcqFile : public pkgAcquire::Item
     * is the absolute name to which the file should be downloaded.
     * is the absolute name to which the file should be downloaded.
     */
     */
 
 
-   pkgAcqFile(pkgAcquire *Owner, string URI, string Hash, unsigned long Size,
-	      string Desc, string ShortDesc,
-	      const string &DestDir="", const string &DestFilename="",
+   pkgAcqFile(pkgAcquire *Owner, std::string URI, std::string Hash, unsigned long long Size,
+	      std::string Desc, std::string ShortDesc,
+	      const std::string &DestDir="", const std::string &DestFilename="",
 	      bool IsIndexFile=false);
 	      bool IsIndexFile=false);
 };
 };
 									/*}}}*/
 									/*}}}*/

+ 8 - 1
apt-pkg/acquire-method.cc

@@ -15,6 +15,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/acquire-method.h>
 #include <apt-pkg/acquire-method.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
@@ -166,6 +168,8 @@ void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt)
       std::cout << "SHA1-Hash: " << Res.SHA1Sum << "\n";
       std::cout << "SHA1-Hash: " << Res.SHA1Sum << "\n";
    if (Res.SHA256Sum.empty() == false)
    if (Res.SHA256Sum.empty() == false)
       std::cout << "SHA256-Hash: " << Res.SHA256Sum << "\n";
       std::cout << "SHA256-Hash: " << Res.SHA256Sum << "\n";
+   if (Res.SHA512Sum.empty() == false)
+      std::cout << "SHA512-Hash: " << Res.SHA512Sum << "\n";
    if (UsedMirror.empty() == false)
    if (UsedMirror.empty() == false)
       std::cout << "UsedMirror: " << UsedMirror << "\n";
       std::cout << "UsedMirror: " << UsedMirror << "\n";
    if (Res.GPGVOutput.empty() == false)
    if (Res.GPGVOutput.empty() == false)
@@ -199,7 +203,9 @@ void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt)
 	 std::cout << "Alt-SHA1-Hash: " << Alt->SHA1Sum << "\n";
 	 std::cout << "Alt-SHA1-Hash: " << Alt->SHA1Sum << "\n";
       if (Alt->SHA256Sum.empty() == false)
       if (Alt->SHA256Sum.empty() == false)
 	 std::cout << "Alt-SHA256-Hash: " << Alt->SHA256Sum << "\n";
 	 std::cout << "Alt-SHA256-Hash: " << Alt->SHA256Sum << "\n";
-
+      if (Alt->SHA512Sum.empty() == false)
+         std::cout << "Alt-SHA512-Hash: " << Alt->SHA512Sum << "\n";
+     
       if (Alt->IMSHit == true)
       if (Alt->IMSHit == true)
 	 std::cout << "Alt-IMS-Hit: true\n";
 	 std::cout << "Alt-IMS-Hit: true\n";
    }
    }
@@ -456,5 +462,6 @@ void pkgAcqMethod::FetchResult::TakeHashes(Hashes &Hash)
    MD5Sum = Hash.MD5.Result();
    MD5Sum = Hash.MD5.Result();
    SHA1Sum = Hash.SHA1.Result();
    SHA1Sum = Hash.SHA1.Result();
    SHA256Sum = Hash.SHA256.Result();
    SHA256Sum = Hash.SHA256.Result();
+   SHA512Sum = Hash.SHA512.Result();
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 28 - 22
apt-pkg/acquire-method.h

@@ -20,10 +20,15 @@
 #ifndef PKGLIB_ACQUIRE_METHOD_H
 #ifndef PKGLIB_ACQUIRE_METHOD_H
 #define PKGLIB_ACQUIRE_METHOD_H
 #define PKGLIB_ACQUIRE_METHOD_H
 
 
+#include <stdarg.h>
+
+#include <string>
+#include <vector>
+
+#ifndef APT_8_CLEANER_HEADERS
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
-
-#include <stdarg.h>
+#endif
 
 
 class Hashes;
 class Hashes;
 class pkgAcqMethod
 class pkgAcqMethod
@@ -34,8 +39,8 @@ class pkgAcqMethod
    {
    {
       FetchItem *Next;
       FetchItem *Next;
 
 
-      string Uri;
-      string DestFile;
+      std::string Uri;
+      std::string DestFile;
       time_t LastModified;
       time_t LastModified;
       bool IndexFile;
       bool IndexFile;
       bool FailIgnore;
       bool FailIgnore;
@@ -43,40 +48,41 @@ class pkgAcqMethod
    
    
    struct FetchResult
    struct FetchResult
    {
    {
-      string MD5Sum;
-      string SHA1Sum;
-      string SHA256Sum;
-      vector<string> GPGVOutput;
+      std::string MD5Sum;
+      std::string SHA1Sum;
+      std::string SHA256Sum;
+      std::string SHA512Sum;
+      std::vector<std::string> GPGVOutput;
       time_t LastModified;
       time_t LastModified;
       bool IMSHit;
       bool IMSHit;
-      string Filename;
-      unsigned long Size;
-      unsigned long ResumePoint;
+      std::string Filename;
+      unsigned long long Size;
+      unsigned long long ResumePoint;
       
       
       void TakeHashes(Hashes &Hash);
       void TakeHashes(Hashes &Hash);
       FetchResult();
       FetchResult();
    };
    };
 
 
    // State
    // State
-   vector<string> Messages;
+   std::vector<std::string> Messages;
    FetchItem *Queue;
    FetchItem *Queue;
    FetchItem *QueueBack;
    FetchItem *QueueBack;
-   string FailReason;
-   string UsedMirror;
-   string IP;
+   std::string FailReason;
+   std::string UsedMirror;
+   std::string IP;
    
    
    // Handlers for messages
    // Handlers for messages
-   virtual bool Configuration(string Message);
+   virtual bool Configuration(std::string Message);
    virtual bool Fetch(FetchItem * /*Item*/) {return true;};
    virtual bool Fetch(FetchItem * /*Item*/) {return true;};
    
    
    // Outgoing messages
    // Outgoing messages
    void Fail(bool Transient = false);
    void Fail(bool Transient = false);
-   inline void Fail(const char *Why, bool Transient = false) {Fail(string(Why),Transient);};
-   virtual void Fail(string Why, bool Transient = false);
+   inline void Fail(const char *Why, bool Transient = false) {Fail(std::string(Why),Transient);};
+   virtual void Fail(std::string Why, bool Transient = false);
    virtual void URIStart(FetchResult &Res);
    virtual void URIStart(FetchResult &Res);
    virtual void URIDone(FetchResult &Res,FetchResult *Alt = 0);
    virtual void URIDone(FetchResult &Res,FetchResult *Alt = 0);
 
 
-   bool MediaFail(string Required,string Drive);
+   bool MediaFail(std::string Required,std::string Drive);
    virtual void Exit() {};
    virtual void Exit() {};
 
 
    void PrintStatus(char const * const header, const char* Format, va_list &args) const;
    void PrintStatus(char const * const header, const char* Format, va_list &args) const;
@@ -90,11 +96,11 @@ class pkgAcqMethod
    void Log(const char *Format,...);
    void Log(const char *Format,...);
    void Status(const char *Format,...);
    void Status(const char *Format,...);
    
    
-   void Redirect(const string &NewURI);
+   void Redirect(const std::string &NewURI);
  
  
    int Run(bool Single = false);
    int Run(bool Single = false);
-   inline void SetFailReason(string Msg) {FailReason = Msg;};
-   inline void SetIP(string aIP) {IP = aIP;};
+   inline void SetFailReason(std::string Msg) {FailReason = Msg;};
+   inline void SetIP(std::string aIP) {IP = aIP;};
    
    
    pkgAcqMethod(const char *Ver,unsigned long Flags = 0);
    pkgAcqMethod(const char *Ver,unsigned long Flags = 0);
    virtual ~pkgAcqMethod() {};
    virtual ~pkgAcqMethod() {};

+ 15 - 18
apt-pkg/acquire-worker.cc

@@ -12,6 +12,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/acquire-worker.h>
 #include <apt-pkg/acquire-worker.h>
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
@@ -19,18 +21,18 @@
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 
 
-#include <apti18n.h>
-
 #include <iostream>
 #include <iostream>
 #include <sstream>
 #include <sstream>
 #include <fstream>
 #include <fstream>
-    
+
 #include <sys/stat.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <fcntl.h>
 #include <signal.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdio.h>
 #include <errno.h>
 #include <errno.h>
+
+#include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 
 
 using namespace std;
 using namespace std;
@@ -256,9 +258,9 @@ bool pkgAcquire::Worker::RunMessages()
 	    
 	    
 	    CurrentItem = Itm;
 	    CurrentItem = Itm;
 	    CurrentSize = 0;
 	    CurrentSize = 0;
-	    TotalSize = atoi(LookupTag(Message,"Size","0").c_str());
-	    ResumePoint = atoi(LookupTag(Message,"Resume-Point","0").c_str());
-	    Itm->Owner->Start(Message,atoi(LookupTag(Message,"Size","0").c_str()));
+	    TotalSize = strtoull(LookupTag(Message,"Size","0").c_str(), NULL, 10);
+	    ResumePoint = strtoull(LookupTag(Message,"Resume-Point","0").c_str(), NULL, 10);
+	    Itm->Owner->Start(Message,strtoull(LookupTag(Message,"Size","0").c_str(), NULL, 10));
 
 
 	    // Display update before completion
 	    // Display update before completion
 	    if (Log != 0 && Log->MorePulses == true)
 	    if (Log != 0 && Log->MorePulses == true)
@@ -287,9 +289,9 @@ bool pkgAcquire::Worker::RunMessages()
 	       Log->Pulse(Owner->GetOwner());
 	       Log->Pulse(Owner->GetOwner());
 	    
 	    
 	    OwnerQ->ItemDone(Itm);
 	    OwnerQ->ItemDone(Itm);
-	    unsigned long const ServerSize = atol(LookupTag(Message,"Size","0").c_str());
+	    unsigned long long const ServerSize = strtoull(LookupTag(Message,"Size","0").c_str(), NULL, 10);
 	    if (TotalSize != 0 && ServerSize != TotalSize)
 	    if (TotalSize != 0 && ServerSize != TotalSize)
-	       _error->Warning("Size of file %s is not what the server reported %s %lu",
+	       _error->Warning("Size of file %s is not what the server reported %s %llu",
 			       Owner->DestFile.c_str(), LookupTag(Message,"Size","0").c_str(),TotalSize);
 			       Owner->DestFile.c_str(), LookupTag(Message,"Size","0").c_str(),TotalSize);
 
 
 	    // see if there is a hash to verify
 	    // see if there is a hash to verify
@@ -429,7 +431,9 @@ bool pkgAcquire::Worker::MediaChange(string Message)
 	     << Drive  << ":"     // drive
 	     << Drive  << ":"     // drive
 	     << msg.str()         // l10n message
 	     << msg.str()         // l10n message
 	     << endl;
 	     << endl;
-      write(status_fd, status.str().c_str(), status.str().size());
+
+      std::string const dlstatus = status.str();
+      FileFd::Write(status_fd, dlstatus.c_str(), dlstatus.size());
    }
    }
 
 
    if (Log == 0 || Log->MediaChange(LookupTag(Message,"Media"),
    if (Log == 0 || Log->MediaChange(LookupTag(Message,"Media"),
@@ -528,17 +532,10 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
 /* */
 /* */
 bool pkgAcquire::Worker::OutFdReady()
 bool pkgAcquire::Worker::OutFdReady()
 {
 {
-   int Res;
-   do
-   {
-      Res = write(OutFd,OutQueue.c_str(),OutQueue.length());
-   }
-   while (Res < 0 && errno == EINTR);
-   
-   if (Res <= 0)
+   if (FileFd::Write(OutFd,OutQueue.c_str(),OutQueue.length()) == false)
       return MethodFailure();
       return MethodFailure();
    
    
-   OutQueue.erase(0,Res);
+   OutQueue.clear();
    if (OutQueue.empty() == true)
    if (OutQueue.empty() == true)
       OutReady = false;
       OutReady = false;
    
    

+ 13 - 10
apt-pkg/acquire-worker.h

@@ -44,6 +44,9 @@
  */
  */
 class pkgAcquire::Worker : public WeakPointable
 class pkgAcquire::Worker : public WeakPointable
 {
 {
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+  
    friend class pkgAcquire;
    friend class pkgAcquire;
    
    
    protected:
    protected:
@@ -76,7 +79,7 @@ class pkgAcquire::Worker : public WeakPointable
     *
     *
     *  \todo Doesn't this duplicate Config->Access?
     *  \todo Doesn't this duplicate Config->Access?
     */
     */
-   string Access;
+   std::string Access;
 
 
    /** \brief The PID of the subprocess. */
    /** \brief The PID of the subprocess. */
    pid_t Process;
    pid_t Process;
@@ -115,13 +118,13 @@ class pkgAcquire::Worker : public WeakPointable
    /** \brief The raw text values of messages received from the
    /** \brief The raw text values of messages received from the
     *  worker, in sequence.
     *  worker, in sequence.
     */
     */
-   vector<string> MessageQueue;
+   std::vector<std::string> MessageQueue;
 
 
    /** \brief Buffers pending writes to the subprocess.
    /** \brief Buffers pending writes to the subprocess.
     *
     *
     *  \todo Wouldn't a std::dequeue be more appropriate?
     *  \todo Wouldn't a std::dequeue be more appropriate?
     */
     */
-   string OutQueue;
+   std::string OutQueue;
    
    
    /** \brief Common code for the constructor.
    /** \brief Common code for the constructor.
     *
     *
@@ -180,7 +183,7 @@ class pkgAcquire::Worker : public WeakPointable
     *
     *
     *  \return \b true.
     *  \return \b true.
     */
     */
-   bool Capabilities(string Message);
+   bool Capabilities(std::string Message);
 
 
    /** \brief Send a 601 Configuration message (containing the APT
    /** \brief Send a 601 Configuration message (containing the APT
     *  configuration) to the subprocess.
     *  configuration) to the subprocess.
@@ -211,7 +214,7 @@ class pkgAcquire::Worker : public WeakPointable
     *  603 Media Changed, with the Failed field set to \b true if the
     *  603 Media Changed, with the Failed field set to \b true if the
     *  user cancelled the media change).
     *  user cancelled the media change).
     */
     */
-   bool MediaChange(string Message);
+   bool MediaChange(std::string Message);
    
    
    /** \brief Invoked when the worked process dies unexpectedly.
    /** \brief Invoked when the worked process dies unexpectedly.
     *
     *
@@ -239,22 +242,22 @@ class pkgAcquire::Worker : public WeakPointable
    /** \brief The most recent status string received from the
    /** \brief The most recent status string received from the
     *  subprocess.
     *  subprocess.
     */
     */
-   string Status;
+   std::string Status;
 
 
    /** \brief How many bytes of the file have been downloaded.  Zero
    /** \brief How many bytes of the file have been downloaded.  Zero
     *  if the current progress of the file cannot be determined.
     *  if the current progress of the file cannot be determined.
     */
     */
-   unsigned long CurrentSize;
+   unsigned long long CurrentSize;
 
 
    /** \brief The total number of bytes to be downloaded.  Zero if the
    /** \brief The total number of bytes to be downloaded.  Zero if the
     *  total size of the final is unknown.
     *  total size of the final is unknown.
     */
     */
-   unsigned long TotalSize;
+   unsigned long long TotalSize;
 
 
    /** \brief How much of the file was already downloaded prior to
    /** \brief How much of the file was already downloaded prior to
     *  starting this worker.
     *  starting this worker.
     */
     */
-   unsigned long ResumePoint;
+   unsigned long long ResumePoint;
    
    
    /** \brief Tell the subprocess to download the given item.
    /** \brief Tell the subprocess to download the given item.
     *
     *
@@ -314,7 +317,7 @@ class pkgAcquire::Worker : public WeakPointable
     *  Closes the file descriptors; if MethodConfig::NeedsCleanup is
     *  Closes the file descriptors; if MethodConfig::NeedsCleanup is
     *  \b false, also rudely interrupts the worker with a SIGINT.
     *  \b false, also rudely interrupts the worker with a SIGINT.
     */
     */
-   ~Worker();
+   virtual ~Worker();
 };
 };
 
 
 /** @} */
 /** @} */

+ 19 - 14
apt-pkg/acquire.cc

@@ -13,6 +13,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/acquire.h>
 #include <apt-pkg/acquire.h>
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/acquire-worker.h>
 #include <apt-pkg/acquire-worker.h>
@@ -21,8 +23,6 @@
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
 
 
-#include <apti18n.h>
-
 #include <iostream>
 #include <iostream>
 #include <sstream>
 #include <sstream>
 #include <stdio.h>
 #include <stdio.h>
@@ -30,6 +30,8 @@
 #include <dirent.h>
 #include <dirent.h>
 #include <sys/time.h>
 #include <sys/time.h>
 #include <errno.h>
 #include <errno.h>
+
+#include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 
 
 using namespace std;
 using namespace std;
@@ -37,9 +39,9 @@ using namespace std;
 // Acquire::pkgAcquire - Constructor					/*{{{*/
 // Acquire::pkgAcquire - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* We grab some runtime state from the configuration space */
 /* We grab some runtime state from the configuration space */
-pkgAcquire::pkgAcquire() : Queues(0), Workers(0), Configs(0), Log(NULL), ToFetch(0),
+pkgAcquire::pkgAcquire() : LockFD(-1), Queues(0), Workers(0), Configs(0), Log(NULL), ToFetch(0),
 			   Debug(_config->FindB("Debug::pkgAcquire",false)),
 			   Debug(_config->FindB("Debug::pkgAcquire",false)),
-			   Running(false), LockFD(-1)
+			   Running(false)
 {
 {
    string const Mode = _config->Find("Acquire::Queue-Mode","host");
    string const Mode = _config->Find("Acquire::Queue-Mode","host");
    if (strcasecmp(Mode.c_str(),"host") == 0)
    if (strcasecmp(Mode.c_str(),"host") == 0)
@@ -47,10 +49,10 @@ pkgAcquire::pkgAcquire() : Queues(0), Workers(0), Configs(0), Log(NULL), ToFetch
    if (strcasecmp(Mode.c_str(),"access") == 0)
    if (strcasecmp(Mode.c_str(),"access") == 0)
       QueueMode = QueueAccess;
       QueueMode = QueueAccess;
 }
 }
-pkgAcquire::pkgAcquire(pkgAcquireStatus *Progress) : Queues(0), Workers(0),
+pkgAcquire::pkgAcquire(pkgAcquireStatus *Progress) :  LockFD(-1), Queues(0), Workers(0),
 			   Configs(0), Log(Progress), ToFetch(0),
 			   Configs(0), Log(Progress), ToFetch(0),
 			   Debug(_config->FindB("Debug::pkgAcquire",false)),
 			   Debug(_config->FindB("Debug::pkgAcquire",false)),
-			   Running(false), LockFD(-1)
+			   Running(false)
 {
 {
    string const Mode = _config->Find("Acquire::Queue-Mode","host");
    string const Mode = _config->Find("Acquire::Queue-Mode","host");
    if (strcasecmp(Mode.c_str(),"host") == 0)
    if (strcasecmp(Mode.c_str(),"host") == 0)
@@ -764,7 +766,7 @@ void pkgAcquire::Queue::Bump()
 // AcquireStatus::pkgAcquireStatus - Constructor			/*{{{*/
 // AcquireStatus::pkgAcquireStatus - Constructor			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-pkgAcquireStatus::pkgAcquireStatus() : Update(true), MorePulses(false)
+pkgAcquireStatus::pkgAcquireStatus() : d(NULL), Update(true), MorePulses(false)
 {
 {
    Start();
    Start();
 }
 }
@@ -803,7 +805,7 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
    }
    }
    
    
    // Compute the current completion
    // Compute the current completion
-   unsigned long ResumeSize = 0;
+   unsigned long long ResumeSize = 0;
    for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0;
    for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0;
 	I = Owner->WorkerStep(I))
 	I = Owner->WorkerStep(I))
       if (I->CurrentItem != 0 && I->CurrentItem->Owner->Complete == false)
       if (I->CurrentItem != 0 && I->CurrentItem->Owner->Complete == false)
@@ -842,7 +844,7 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
       else
       else
 	 CurrentCPS = ((CurrentBytes - ResumeSize) - LastBytes)/Delta;
 	 CurrentCPS = ((CurrentBytes - ResumeSize) - LastBytes)/Delta;
       LastBytes = CurrentBytes - ResumeSize;
       LastBytes = CurrentBytes - ResumeSize;
-      ElapsedTime = (unsigned long)Delta;
+      ElapsedTime = (unsigned long long)Delta;
       Time = NewTime;
       Time = NewTime;
    }
    }
 
 
@@ -853,8 +855,9 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
 
 
       char msg[200];
       char msg[200];
       long i = CurrentItems < TotalItems ? CurrentItems + 1 : CurrentItems;
       long i = CurrentItems < TotalItems ? CurrentItems + 1 : CurrentItems;
-      unsigned long ETA =
-	 (unsigned long)((TotalBytes - CurrentBytes) / CurrentCPS);
+      unsigned long long ETA = 0;
+      if(CurrentCPS > 0)
+         ETA = (TotalBytes - CurrentBytes) / CurrentCPS;
 
 
       // only show the ETA if it makes sense
       // only show the ETA if it makes sense
       if (ETA > 0 && ETA < 172800 /* two days */ )
       if (ETA > 0 && ETA < 172800 /* two days */ )
@@ -869,7 +872,9 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
 	     << ":"  << (CurrentBytes/float(TotalBytes)*100.0) 
 	     << ":"  << (CurrentBytes/float(TotalBytes)*100.0) 
 	     << ":" << msg 
 	     << ":" << msg 
 	     << endl;
 	     << endl;
-      write(fd, status.str().c_str(), status.str().size());
+
+      std::string const dlstatus = status.str();
+      FileFd::Write(fd, dlstatus.c_str(), dlstatus.size());
    }
    }
 
 
    return true;
    return true;
@@ -910,13 +915,13 @@ void pkgAcquireStatus::Stop()
    else
    else
       CurrentCPS = FetchedBytes/Delta;
       CurrentCPS = FetchedBytes/Delta;
    LastBytes = CurrentBytes;
    LastBytes = CurrentBytes;
-   ElapsedTime = (unsigned int)Delta;
+   ElapsedTime = (unsigned long long)Delta;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // AcquireStatus::Fetched - Called when a byte set has been fetched	/*{{{*/
 // AcquireStatus::Fetched - Called when a byte set has been fetched	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This is used to get accurate final transfer rate reporting. */
 /* This is used to get accurate final transfer rate reporting. */
-void pkgAcquireStatus::Fetched(unsigned long Size,unsigned long Resume)
+void pkgAcquireStatus::Fetched(unsigned long long Size,unsigned long long Resume)
 {   
 {   
    FetchedBytes += Size - Resume;
    FetchedBytes += Size - Resume;
 }
 }

+ 53 - 40
apt-pkg/acquire.h

@@ -72,13 +72,14 @@
 #include <vector>
 #include <vector>
 #include <string>
 #include <string>
 
 
-using std::vector;
-using std::string;
-
-
 #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.					{{{
@@ -91,6 +92,12 @@ class pkgAcquireStatus;
  */
  */
 class pkgAcquire
 class pkgAcquire
 {   
 {   
+   private:
+   /** \brief FD of the Lock file we acquire in Setup (if any) */
+   int LockFD;
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+
    public:
    public:
    
    
    class Item;
    class Item;
@@ -101,8 +108,8 @@ class pkgAcquire
    friend class Item;
    friend class Item;
    friend class Queue;
    friend class Queue;
 
 
-   typedef vector<Item *>::iterator ItemIterator;
-   typedef vector<Item *>::const_iterator ItemCIterator;
+   typedef std::vector<Item *>::iterator ItemIterator;
+   typedef std::vector<Item *>::const_iterator ItemCIterator;
 
 
    protected:
    protected:
    
    
@@ -111,7 +118,7 @@ class pkgAcquire
     *  This is built monotonically as items are created and only
     *  This is built monotonically as items are created and only
     *  emptied when the download shuts down.
     *  emptied when the download shuts down.
     */
     */
-   vector<Item *> Items;
+   std::vector<Item *> Items;
    
    
    /** \brief The head of the list of active queues.
    /** \brief The head of the list of active queues.
     *
     *
@@ -142,12 +149,7 @@ class pkgAcquire
    /** \brief The progress indicator for this download. */
    /** \brief The progress indicator for this download. */
    pkgAcquireStatus *Log;
    pkgAcquireStatus *Log;
 
 
-   /** \brief The total size of the files which are to be fetched.
-    *
-    *  This is not necessarily the total number of bytes to download
-    *  when, e.g., download resumption and list updates via patches
-    *  are taken into account.
-    */
+   /** \brief The number of files which are to be fetched. */
    unsigned long ToFetch;
    unsigned long ToFetch;
 
 
    // Configurable parameters for the scheduler
    // Configurable parameters for the scheduler
@@ -201,7 +203,7 @@ class pkgAcquire
     *  \return the string-name of the queue in which a fetch request
     *  \return the string-name of the queue in which a fetch request
     *  for the given URI should be placed.
     *  for the given URI should be placed.
     */
     */
-   string QueueName(string URI,MethodConfig const *&Config);
+   std::string QueueName(std::string URI,MethodConfig const *&Config);
 
 
    /** \brief Build up the set of file descriptors upon which select() should
    /** \brief Build up the set of file descriptors upon which select() should
     *  block.
     *  block.
@@ -247,7 +249,7 @@ class pkgAcquire
     *
     *
     *  \return the method whose name is Access, or \b NULL if no such method exists.
     *  \return the method whose name is Access, or \b NULL if no such method exists.
     */
     */
-   MethodConfig *GetConfig(string Access);
+   MethodConfig *GetConfig(std::string Access);
 
 
    /** \brief Provides information on how a download terminated. */
    /** \brief Provides information on how a download terminated. */
    enum RunResult {
    enum RunResult {
@@ -318,7 +320,7 @@ class pkgAcquire
     *
     *
     *  \return \b true if the directory exists and is readable.
     *  \return \b true if the directory exists and is readable.
     */
     */
-   bool Clean(string Dir);
+   bool Clean(std::string Dir);
 
 
    /** \return the total size in bytes of all the items included in
    /** \return the total size in bytes of all the items included in
     *  this download.
     *  this download.
@@ -346,7 +348,7 @@ class pkgAcquire
     *  only one Acquire class is in action at the time or an empty string
     *  only one Acquire class is in action at the time or an empty string
     *  if no lock file should be used.
     *  if no lock file should be used.
     */
     */
-   bool Setup(pkgAcquireStatus *Progress = NULL, string const &Lock = "");
+   bool Setup(pkgAcquireStatus *Progress = NULL, std::string const &Lock = "");
 
 
    void SetLog(pkgAcquireStatus *Progress) { Log = Progress; }
    void SetLog(pkgAcquireStatus *Progress) { Log = Progress; }
 
 
@@ -361,9 +363,6 @@ class pkgAcquire
     */
     */
    virtual ~pkgAcquire();
    virtual ~pkgAcquire();
 
 
-   private:
-   /** \brief FD of the Lock file we acquire in Setup (if any) */
-   int LockFD;
 };
 };
 
 
 /** \brief Represents a single download source from which an item
 /** \brief Represents a single download source from which an item
@@ -374,11 +373,11 @@ class pkgAcquire
 struct pkgAcquire::ItemDesc : public WeakPointable
 struct pkgAcquire::ItemDesc : public WeakPointable
 {
 {
    /** \brief The URI from which to download this item. */
    /** \brief The URI from which to download this item. */
-   string URI;
+   std::string URI;
    /** brief A description of this item. */
    /** brief A description of this item. */
-   string Description;
+   std::string Description;
    /** brief A shorter description of this item. */
    /** brief A shorter description of this item. */
-   string ShortDesc;
+   std::string ShortDesc;
    /** brief The underlying item which is to be downloaded. */
    /** brief The underlying item which is to be downloaded. */
    Item *Owner;
    Item *Owner;
 };
 };
@@ -393,6 +392,9 @@ class pkgAcquire::Queue
    friend class pkgAcquire::UriIterator;
    friend class pkgAcquire::UriIterator;
    friend class pkgAcquire::Worker;
    friend class pkgAcquire::Worker;
 
 
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+
    /** \brief The next queue in the pkgAcquire object's list of queues. */
    /** \brief The next queue in the pkgAcquire object's list of queues. */
    Queue *Next;
    Queue *Next;
    
    
@@ -419,7 +421,7 @@ class pkgAcquire::Queue
    };
    };
    
    
    /** \brief The name of this queue. */
    /** \brief The name of this queue. */
-   string Name;
+   std::string Name;
 
 
    /** \brief The head of the list of items contained in this queue.
    /** \brief The head of the list of items contained in this queue.
     *
     *
@@ -474,13 +476,13 @@ class pkgAcquire::Queue
     *  \return the first item in the queue whose URI is #URI and that
     *  \return the first item in the queue whose URI is #URI and that
     *  is being downloaded by #Owner.
     *  is being downloaded by #Owner.
     */
     */
-   QItem *FindItem(string URI,pkgAcquire::Worker *Owner);
+   QItem *FindItem(std::string URI,pkgAcquire::Worker *Owner);
 
 
    /** Presumably this should start downloading an item?
    /** Presumably this should start downloading an item?
     *
     *
     *  \todo Unimplemented.  Implement it or remove?
     *  \todo Unimplemented.  Implement it or remove?
     */
     */
-   bool ItemStart(QItem *Itm,unsigned long Size);
+   bool ItemStart(QItem *Itm,unsigned long long Size);
 
 
    /** \brief Remove the given item from this queue and set its state
    /** \brief Remove the given item from this queue and set its state
     *  to pkgAcquire::Item::StatDone.
     *  to pkgAcquire::Item::StatDone.
@@ -537,17 +539,20 @@ class pkgAcquire::Queue
     *  \param Name The name of the new queue.
     *  \param Name The name of the new queue.
     *  \param Owner The download process that owns the new queue.
     *  \param Owner The download process that owns the new queue.
     */
     */
-   Queue(string Name,pkgAcquire *Owner);
+   Queue(std::string Name,pkgAcquire *Owner);
 
 
    /** Shut down all the worker processes associated with this queue
    /** Shut down all the worker processes associated with this queue
     *  and empty the queue.
     *  and empty the queue.
     */
     */
-   ~Queue();
+   virtual ~Queue();
 };
 };
 									/*}}}*/
 									/*}}}*/
 /** \brief Iterates over all the URIs being fetched by a pkgAcquire object.	{{{*/
 /** \brief Iterates over all the URIs being fetched by a pkgAcquire object.	{{{*/
 class pkgAcquire::UriIterator
 class pkgAcquire::UriIterator
 {
 {
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+
    /** The next queue to iterate over. */
    /** The next queue to iterate over. */
    pkgAcquire::Queue *CurQ;
    pkgAcquire::Queue *CurQ;
    /** The item that we currently point at. */
    /** The item that we currently point at. */
@@ -583,11 +588,15 @@ class pkgAcquire::UriIterator
 	 CurQ = CurQ->Next;
 	 CurQ = CurQ->Next;
       }
       }
    }   
    }   
+   virtual ~UriIterator() {};
 };
 };
 									/*}}}*/
 									/*}}}*/
 /** \brief Information about the properties of a single acquire method.	{{{*/
 /** \brief Information about the properties of a single acquire method.	{{{*/
 struct pkgAcquire::MethodConfig
 struct pkgAcquire::MethodConfig
 {
 {
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+   
    /** \brief The next link on the acquire method list.
    /** \brief The next link on the acquire method list.
     *
     *
     *  \todo Why not an STL container?
     *  \todo Why not an STL container?
@@ -595,10 +604,10 @@ struct pkgAcquire::MethodConfig
    MethodConfig *Next;
    MethodConfig *Next;
    
    
    /** \brief The name of this acquire method (e.g., http). */
    /** \brief The name of this acquire method (e.g., http). */
-   string Access;
+   std::string Access;
 
 
    /** \brief The implementation version of this acquire method. */
    /** \brief The implementation version of this acquire method. */
-   string Version;
+   std::string Version;
 
 
    /** \brief If \b true, only one download queue should be created for this
    /** \brief If \b true, only one download queue should be created for this
     *  method.
     *  method.
@@ -636,16 +645,20 @@ struct pkgAcquire::MethodConfig
     *  appropriate.
     *  appropriate.
     */
     */
    MethodConfig();
    MethodConfig();
+
+   /* \brief Destructor, empty currently */
+   virtual ~MethodConfig() {};
 };
 };
 									/*}}}*/
 									/*}}}*/
 /** \brief A monitor object for downloads controlled by the pkgAcquire class.	{{{
 /** \brief A monitor object for downloads controlled by the pkgAcquire class.	{{{
  *
  *
  *  \todo Why protected members?
  *  \todo Why protected members?
- *
- *  \todo Should the double members be uint64_t?
  */
  */
 class pkgAcquireStatus
 class pkgAcquireStatus
 {
 {
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+
    protected:
    protected:
    
    
    /** \brief The last time at which this monitor object was updated. */
    /** \brief The last time at which this monitor object was updated. */
@@ -657,34 +670,34 @@ class pkgAcquireStatus
    /** \brief The number of bytes fetched as of the previous call to
    /** \brief The number of bytes fetched as of the previous call to
     *  pkgAcquireStatus::Pulse, including local items.
     *  pkgAcquireStatus::Pulse, including local items.
     */
     */
-   double LastBytes;
+   unsigned long long LastBytes;
 
 
    /** \brief The current rate of download as of the most recent call
    /** \brief The current rate of download as of the most recent call
     *  to pkgAcquireStatus::Pulse, in bytes per second.
     *  to pkgAcquireStatus::Pulse, in bytes per second.
     */
     */
-   double CurrentCPS;
+   unsigned long long CurrentCPS;
 
 
    /** \brief The number of bytes fetched as of the most recent call
    /** \brief The number of bytes fetched as of the most recent call
     *  to pkgAcquireStatus::Pulse, including local items.
     *  to pkgAcquireStatus::Pulse, including local items.
     */
     */
-   double CurrentBytes;
+   unsigned long long CurrentBytes;
 
 
    /** \brief The total number of bytes that need to be fetched.
    /** \brief The total number of bytes that need to be fetched.
     *
     *
     *  \warning This member is inaccurate, as new items might be
     *  \warning This member is inaccurate, as new items might be
     *  enqueued while the download is in progress!
     *  enqueued while the download is in progress!
     */
     */
-   double TotalBytes;
+   unsigned long long TotalBytes;
 
 
    /** \brief The total number of bytes accounted for by items that
    /** \brief The total number of bytes accounted for by items that
     *  were successfully fetched.
     *  were successfully fetched.
     */
     */
-   double FetchedBytes;
+   unsigned long long FetchedBytes;
 
 
    /** \brief The amount of time that has elapsed since the download
    /** \brief The amount of time that has elapsed since the download
     *   started.
     *   started.
     */
     */
-   unsigned long ElapsedTime;
+   unsigned long long ElapsedTime;
 
 
    /** \brief The total number of items that need to be fetched.
    /** \brief The total number of items that need to be fetched.
     *
     *
@@ -717,7 +730,7 @@ class pkgAcquireStatus
     *
     *
     *  \param ResumePoint How much of the file was already fetched.
     *  \param ResumePoint How much of the file was already fetched.
     */
     */
-   virtual void Fetched(unsigned long Size,unsigned long ResumePoint);
+   virtual void Fetched(unsigned long long Size,unsigned long long ResumePoint);
    
    
    /** \brief Invoked when the user should be prompted to change the
    /** \brief Invoked when the user should be prompted to change the
     *         inserted removable media.
     *         inserted removable media.
@@ -736,7 +749,7 @@ class pkgAcquireStatus
     *  \todo This is a horrible blocking monster; it should be CPSed
     *  \todo This is a horrible blocking monster; it should be CPSed
     *  with prejudice.
     *  with prejudice.
     */
     */
-   virtual bool MediaChange(string Media,string Drive) = 0;
+   virtual bool MediaChange(std::string Media,std::string Drive) = 0;
    
    
    /** \brief Invoked when an item is confirmed to be up-to-date.
    /** \brief Invoked when an item is confirmed to be up-to-date.
 
 

+ 85 - 30
apt-pkg/algorithms.cc

@@ -14,18 +14,26 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/algorithms.h>
 #include <apt-pkg/algorithms.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/version.h>
 #include <apt-pkg/version.h>
 #include <apt-pkg/sptr.h>
 #include <apt-pkg/sptr.h>
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/acquire-item.h>
-    
-#include <apti18n.h>
+#include <apt-pkg/edsp.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/progress.h>
+
 #include <sys/types.h>
 #include <sys/types.h>
 #include <cstdlib>
 #include <cstdlib>
 #include <algorithm>
 #include <algorithm>
 #include <iostream>
 #include <iostream>
+#include <stdio.h>
+
+#include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 using namespace std;
 using namespace std;
 
 
@@ -327,6 +335,12 @@ bool pkgFixBroken(pkgDepCache &Cache)
  */
  */
 bool pkgDistUpgrade(pkgDepCache &Cache)
 bool pkgDistUpgrade(pkgDepCache &Cache)
 {
 {
+   std::string const solver = _config->Find("APT::Solver", "internal");
+   if (solver != "internal") {
+      OpTextProgress Prog(*_config);
+      return EDSP::ResolveExternal(solver.c_str(), Cache, false, true, false, &Prog);
+   }
+
    pkgDepCache::ActionGroup group(Cache);
    pkgDepCache::ActionGroup group(Cache);
 
 
    /* Upgrade all installed packages first without autoinst to help the resolver
    /* Upgrade all installed packages first without autoinst to help the resolver
@@ -379,6 +393,12 @@ bool pkgDistUpgrade(pkgDepCache &Cache)
    to install packages not marked for install */
    to install packages not marked for install */
 bool pkgAllUpgrade(pkgDepCache &Cache)
 bool pkgAllUpgrade(pkgDepCache &Cache)
 {
 {
+   std::string const solver = _config->Find("APT::Solver", "internal");
+   if (solver != "internal") {
+      OpTextProgress Prog(*_config);
+      return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog);
+   }
+
    pkgDepCache::ActionGroup group(Cache);
    pkgDepCache::ActionGroup group(Cache);
 
 
    pkgProblemResolver Fix(&Cache);
    pkgProblemResolver Fix(&Cache);
@@ -451,11 +471,11 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache)
 // ProblemResolver::pkgProblemResolver - Constructor			/*{{{*/
 // ProblemResolver::pkgProblemResolver - Constructor			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-pkgProblemResolver::pkgProblemResolver(pkgDepCache *pCache) : Cache(*pCache)
+pkgProblemResolver::pkgProblemResolver(pkgDepCache *pCache) : d(NULL), Cache(*pCache)
 {
 {
    // Allocate memory
    // Allocate memory
    unsigned long Size = Cache.Head().PackageCount;
    unsigned long Size = Cache.Head().PackageCount;
-   Scores = new signed short[Size];
+   Scores = new int[Size];
    Flags = new unsigned char[Size];
    Flags = new unsigned char[Size];
    memset(Flags,0,sizeof(*Flags)*Size);
    memset(Flags,0,sizeof(*Flags)*Size);
    
    
@@ -495,20 +515,20 @@ void pkgProblemResolver::MakeScores()
    memset(Scores,0,sizeof(*Scores)*Size);
    memset(Scores,0,sizeof(*Scores)*Size);
 
 
    // Important Required Standard Optional Extra
    // Important Required Standard Optional Extra
-   signed short PrioMap[] = {
+   int PrioMap[] = {
       0,
       0,
-      (signed short) _config->FindI("pkgProblemResolver::Scores::Important",3),
-      (signed short) _config->FindI("pkgProblemResolver::Scores::Required",2),
-      (signed short) _config->FindI("pkgProblemResolver::Scores::Standard",1),
-      (signed short) _config->FindI("pkgProblemResolver::Scores::Optional",-1),
-      (signed short) _config->FindI("pkgProblemResolver::Scores::Extra",-2)
+      _config->FindI("pkgProblemResolver::Scores::Important",3),
+      _config->FindI("pkgProblemResolver::Scores::Required",2),
+      _config->FindI("pkgProblemResolver::Scores::Standard",1),
+      _config->FindI("pkgProblemResolver::Scores::Optional",-1),
+      _config->FindI("pkgProblemResolver::Scores::Extra",-2)
    };
    };
-   signed short PrioEssentials = _config->FindI("pkgProblemResolver::Scores::Essentials",100);
-   signed short PrioInstalledAndNotObsolete = _config->FindI("pkgProblemResolver::Scores::NotObsolete",1);
-   signed short PrioDepends = _config->FindI("pkgProblemResolver::Scores::Depends",1);
-   signed short PrioRecommends = _config->FindI("pkgProblemResolver::Scores::Recommends",1);
-   signed short AddProtected = _config->FindI("pkgProblemResolver::Scores::AddProtected",10000);
-   signed short AddEssential = _config->FindI("pkgProblemResolver::Scores::AddEssential",5000);
+   int PrioEssentials = _config->FindI("pkgProblemResolver::Scores::Essentials",100);
+   int PrioInstalledAndNotObsolete = _config->FindI("pkgProblemResolver::Scores::NotObsolete",1);
+   int PrioDepends = _config->FindI("pkgProblemResolver::Scores::Depends",1);
+   int PrioRecommends = _config->FindI("pkgProblemResolver::Scores::Recommends",1);
+   int AddProtected = _config->FindI("pkgProblemResolver::Scores::AddProtected",10000);
+   int AddEssential = _config->FindI("pkgProblemResolver::Scores::AddEssential",5000);
 
 
    if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
    if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
       clog << "Settings used to calculate pkgProblemResolver::Scores::" << endl
       clog << "Settings used to calculate pkgProblemResolver::Scores::" << endl
@@ -530,13 +550,14 @@ void pkgProblemResolver::MakeScores()
       if (Cache[I].InstallVer == 0)
       if (Cache[I].InstallVer == 0)
 	 continue;
 	 continue;
       
       
-      signed short &Score = Scores[I->ID];
+      int &Score = Scores[I->ID];
       
       
       /* This is arbitrary, it should be high enough to elevate an
       /* This is arbitrary, it should be high enough to elevate an
          essantial package above most other packages but low enough
          essantial package above most other packages but low enough
 	 to allow an obsolete essential packages to be removed by
 	 to allow an obsolete essential packages to be removed by
 	 a conflicts on a powerfull normal package (ie libc6) */
 	 a conflicts on a powerfull normal package (ie libc6) */
-      if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
+      if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential
+	  || (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
 	 Score += PrioEssentials;
 	 Score += PrioEssentials;
 
 
       // We transform the priority
       // We transform the priority
@@ -568,7 +589,7 @@ void pkgProblemResolver::MakeScores()
    }   
    }   
    
    
    // Copy the scores to advoid additive looping
    // Copy the scores to advoid additive looping
-   SPtrArray<signed short> OldScores = new signed short[Size];
+   SPtrArray<int> OldScores = new int[Size];
    memcpy(OldScores,Scores,sizeof(*Scores)*Size);
    memcpy(OldScores,Scores,sizeof(*Scores)*Size);
       
       
    /* Now we cause 1 level of dependency inheritance, that is we add the 
    /* Now we cause 1 level of dependency inheritance, that is we add the 
@@ -611,7 +632,8 @@ void pkgProblemResolver::MakeScores()
    {
    {
       if ((Flags[I->ID] & Protected) != 0)
       if ((Flags[I->ID] & Protected) != 0)
 	 Scores[I->ID] += AddProtected;
 	 Scores[I->ID] += AddProtected;
-      if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
+      if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential ||
+          (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
 	 Scores[I->ID] += AddEssential;
 	 Scores[I->ID] += AddEssential;
    }
    }
 }
 }
@@ -725,7 +747,20 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// ProblemResolver::Resolve - Run the resolution pass			/*{{{*/
+// ProblemResolver::Resolve - calls a resolver to fix the situation	/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool pkgProblemResolver::Resolve(bool BrokenFix)
+{
+   std::string const solver = _config->Find("APT::Solver", "internal");
+   if (solver != "internal") {
+      OpTextProgress Prog(*_config);
+      return EDSP::ResolveExternal(solver.c_str(), Cache, false, false, false, &Prog);
+   }
+   return ResolveInternal(BrokenFix);
+}
+									/*}}}*/
+// ProblemResolver::ResolveInternal - Run the resolution pass		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This routines works by calculating a score for each package. The score
 /* This routines works by calculating a score for each package. The score
    is derived by considering the package's priority and all reverse 
    is derived by considering the package's priority and all reverse 
@@ -739,12 +774,10 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
  
  
    The BrokenFix flag enables a mode where the algorithm tries to 
    The BrokenFix flag enables a mode where the algorithm tries to 
    upgrade packages to advoid problems. */
    upgrade packages to advoid problems. */
-bool pkgProblemResolver::Resolve(bool BrokenFix)
+bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
 {
 {
    pkgDepCache::ActionGroup group(Cache);
    pkgDepCache::ActionGroup group(Cache);
 
 
-   unsigned long Size = Cache.Head().PackageCount;
-
    // Record which packages are marked for install
    // Record which packages are marked for install
    bool Again = false;
    bool Again = false;
    do
    do
@@ -774,7 +807,9 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
       clog << "Starting" << endl;
       clog << "Starting" << endl;
    
    
    MakeScores();
    MakeScores();
-   
+
+   unsigned long const Size = Cache.Head().PackageCount;
+
    /* We have to order the packages so that the broken fixing pass 
    /* We have to order the packages so that the broken fixing pass 
       operates from highest score to lowest. This prevents problems when
       operates from highest score to lowest. This prevents problems when
       high score packages cause the removal of lower score packages that
       high score packages cause the removal of lower score packages that
@@ -1065,8 +1100,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 		  LEnd->Dep = End;
 		  LEnd->Dep = End;
 		  LEnd++;
 		  LEnd++;
 		  
 		  
-		  if (Start->Type != pkgCache::Dep::Conflicts &&
-		      Start->Type != pkgCache::Dep::Obsoletes)
+		  if (Start.IsNegative() == false)
 		     break;
 		     break;
 	       }
 	       }
 	    }
 	    }
@@ -1176,7 +1210,6 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // ProblemResolver::BreaksInstOrPolicy - Check if the given pkg is broken/*{{{*/
 // ProblemResolver::BreaksInstOrPolicy - Check if the given pkg is broken/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This checks if the given package is broken either by a hard dependency
 /* This checks if the given package is broken either by a hard dependency
@@ -1207,13 +1240,28 @@ bool pkgProblemResolver::InstOrNewPolicyBroken(pkgCache::PkgIterator I)
 
 
    return false;
    return false;
 }
 }
-
+									/*}}}*/
 // ProblemResolver::ResolveByKeep - Resolve problems using keep		/*{{{*/
 // ProblemResolver::ResolveByKeep - Resolve problems using keep		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This is the work horse of the soft upgrade routine. It is very gental 
 /* This is the work horse of the soft upgrade routine. It is very gental 
    in that it does not install or remove any packages. It is assumed that the
    in that it does not install or remove any packages. It is assumed that the
    system was non-broken previously. */
    system was non-broken previously. */
 bool pkgProblemResolver::ResolveByKeep()
 bool pkgProblemResolver::ResolveByKeep()
+{
+   std::string const solver = _config->Find("APT::Solver", "internal");
+   if (solver != "internal") {
+      OpTextProgress Prog(*_config);
+      return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog);
+   }
+   return ResolveByKeepInternal();
+}
+									/*}}}*/
+// ProblemResolver::ResolveByKeepInternal - Resolve problems using keep	/*{{{*/
+// ---------------------------------------------------------------------
+/* This is the work horse of the soft upgrade routine. It is very gental
+   in that it does not install or remove any packages. It is assumed that the
+   system was non-broken previously. */
+bool pkgProblemResolver::ResolveByKeepInternal()
 {
 {
    pkgDepCache::ActionGroup group(Cache);
    pkgDepCache::ActionGroup group(Cache);
 
 
@@ -1384,6 +1432,13 @@ static int PrioComp(const void *A,const void *B)
    if ((L.ParentPkg()->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential &&
    if ((L.ParentPkg()->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential &&
        (R.ParentPkg()->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
        (R.ParentPkg()->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
      return -1;
      return -1;
+
+   if ((L.ParentPkg()->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important &&
+       (R.ParentPkg()->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important)
+     return 1;
+   if ((L.ParentPkg()->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important &&
+       (R.ParentPkg()->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
+     return -1;
    
    
    if (L->Priority != R->Priority)
    if (L->Priority != R->Priority)
       return R->Priority - L->Priority;
       return R->Priority - L->Priority;
@@ -1398,7 +1453,7 @@ void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List)
    qsort(List,Count,sizeof(*List),PrioComp);
    qsort(List,Count,sizeof(*List),PrioComp);
 }
 }
 									/*}}}*/
 									/*}}}*/
-// CacheFile::ListUpdate - update the cache files                    	/*{{{*/
+// ListUpdate - update the cache files					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This is a simple wrapper to update the cache. it will fetch stuff
 /* This is a simple wrapper to update the cache. it will fetch stuff
  * from the network (or any other sources defined in sources.list)
  * from the network (or any other sources defined in sources.list)

+ 14 - 4
apt-pkg/algorithms.h

@@ -33,11 +33,15 @@
 
 
 #include <apt-pkg/packagemanager.h>
 #include <apt-pkg/packagemanager.h>
 #include <apt-pkg/depcache.h>
 #include <apt-pkg/depcache.h>
-#include <apt-pkg/acquire.h>
 
 
 #include <iostream>
 #include <iostream>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/acquire.h>
 using std::ostream;
 using std::ostream;
+#endif
+
+class pkgAcquireStatus;
 
 
 class pkgSimulate : public pkgPackageManager				/*{{{*/
 class pkgSimulate : public pkgPackageManager				/*{{{*/
 {
 {
@@ -63,13 +67,13 @@ class pkgSimulate : public pkgPackageManager				/*{{{*/
    pkgDepCache::ActionGroup group;
    pkgDepCache::ActionGroup group;
    
    
    // The Actuall installation implementation
    // The Actuall installation implementation
-   virtual bool Install(PkgIterator Pkg,string File);
+   virtual bool Install(PkgIterator Pkg,std::string File);
    virtual bool Configure(PkgIterator Pkg);
    virtual bool Configure(PkgIterator Pkg);
    virtual bool Remove(PkgIterator Pkg,bool Purge);
    virtual bool Remove(PkgIterator Pkg,bool Purge);
 
 
 private:
 private:
    void ShortBreaks();
    void ShortBreaks();
-   void Describe(PkgIterator iPkg,ostream &out,bool Current,bool Candidate);
+   void Describe(PkgIterator iPkg,std::ostream &out,bool Current,bool Candidate);
    
    
    public:
    public:
 
 
@@ -78,6 +82,9 @@ private:
 									/*}}}*/
 									/*}}}*/
 class pkgProblemResolver						/*{{{*/
 class pkgProblemResolver						/*{{{*/
 {
 {
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+
    pkgDepCache &Cache;
    pkgDepCache &Cache;
    typedef pkgCache::PkgIterator PkgIterator;
    typedef pkgCache::PkgIterator PkgIterator;
    typedef pkgCache::VerIterator VerIterator;
    typedef pkgCache::VerIterator VerIterator;
@@ -89,7 +96,7 @@ class pkgProblemResolver						/*{{{*/
    enum Flags {Protected = (1 << 0), PreInstalled = (1 << 1),
    enum Flags {Protected = (1 << 0), PreInstalled = (1 << 1),
                Upgradable = (1 << 2), ReInstateTried = (1 << 3),
                Upgradable = (1 << 2), ReInstateTried = (1 << 3),
                ToRemove = (1 << 4)};
                ToRemove = (1 << 4)};
-   signed short *Scores;
+   int *Scores;
    unsigned char *Flags;
    unsigned char *Flags;
    bool Debug;
    bool Debug;
    
    
@@ -105,6 +112,9 @@ class pkgProblemResolver						/*{{{*/
 
 
    void MakeScores();
    void MakeScores();
    bool DoUpgrade(pkgCache::PkgIterator Pkg);
    bool DoUpgrade(pkgCache::PkgIterator Pkg);
+
+   bool ResolveInternal(bool const BrokenFix = false);
+   bool ResolveByKeepInternal();
    
    
    protected:
    protected:
    bool InstOrNewPolicyBroken(pkgCache::PkgIterator Pkg);
    bool InstOrNewPolicyBroken(pkgCache::PkgIterator Pkg);

+ 102 - 20
apt-pkg/aptconfiguration.cc

@@ -8,6 +8,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
@@ -18,6 +20,7 @@
 #include <sys/types.h>
 #include <sys/types.h>
 #include <dirent.h>
 #include <dirent.h>
 #include <stdio.h>
 #include <stdio.h>
+#include <fcntl.h>
 
 
 #include <algorithm>
 #include <algorithm>
 #include <string>
 #include <string>
@@ -57,10 +60,10 @@ const Configuration::getCompressionTypes(bool const &Cached) {
 		if ((*o).empty() == true)
 		if ((*o).empty() == true)
 			continue;
 			continue;
 		// ignore types we have no method ready to use
 		// ignore types we have no method ready to use
-		if (_config->Exists(string("Acquire::CompressionTypes::").append(*o)) == false)
+		if (_config->Exists(std::string("Acquire::CompressionTypes::").append(*o)) == false)
 			continue;
 			continue;
 		// ignore types we have no app ready to use
 		// ignore types we have no app ready to use
-		string const appsetting = string("Dir::Bin::").append(*o);
+		std::string const appsetting = std::string("Dir::Bin::").append(*o);
 		if (_config->Exists(appsetting) == true) {
 		if (_config->Exists(appsetting) == true) {
 			std::string const app = _config->FindFile(appsetting.c_str(), "");
 			std::string const app = _config->FindFile(appsetting.c_str(), "");
 			if (app.empty() == false && FileExists(app) == false)
 			if (app.empty() == false && FileExists(app) == false)
@@ -81,7 +84,7 @@ const Configuration::getCompressionTypes(bool const &Cached) {
 		if (std::find(types.begin(),types.end(),Types->Tag) != types.end())
 		if (std::find(types.begin(),types.end(),Types->Tag) != types.end())
 			continue;
 			continue;
 		// ignore types we have no app ready to use
 		// ignore types we have no app ready to use
-		string const appsetting = string("Dir::Bin::").append(Types->Value);
+		std::string const appsetting = std::string("Dir::Bin::").append(Types->Value);
 		if (appsetting.empty() == false && _config->Exists(appsetting) == true) {
 		if (appsetting.empty() == false && _config->Exists(appsetting) == true) {
 			std::string const app = _config->FindFile(appsetting.c_str(), "");
 			std::string const app = _config->FindFile(appsetting.c_str(), "");
 			if (app.empty() == false && FileExists(app) == false)
 			if (app.empty() == false && FileExists(app) == false)
@@ -93,7 +96,7 @@ const Configuration::getCompressionTypes(bool const &Cached) {
 	// add the special "uncompressed" type
 	// add the special "uncompressed" type
 	if (std::find(types.begin(), types.end(), "uncompressed") == types.end())
 	if (std::find(types.begin(), types.end(), "uncompressed") == types.end())
 	{
 	{
-		string const uncompr = _config->FindFile("Dir::Bin::uncompressed", "");
+		std::string const uncompr = _config->FindFile("Dir::Bin::uncompressed", "");
 		if (uncompr.empty() == true || FileExists(uncompr) == true)
 		if (uncompr.empty() == true || FileExists(uncompr) == true)
 			types.push_back("uncompressed");
 			types.push_back("uncompressed");
 	}
 	}
@@ -326,29 +329,79 @@ std::vector<std::string> const Configuration::getArchitectures(bool const &Cache
 	// FIXME: It is a bit unclean to have debian specific code here…
 	// FIXME: It is a bit unclean to have debian specific code here…
 	if (archs.empty() == true) {
 	if (archs.empty() == true) {
 		archs.push_back(arch);
 		archs.push_back(arch);
-		string dpkgcall = _config->Find("Dir::Bin::dpkg", "dpkg");
-		std::vector<string> const dpkgoptions = _config->FindVector("DPkg::options");
-		for (std::vector<string>::const_iterator o = dpkgoptions.begin();
-		     o != dpkgoptions.end(); ++o)
-			dpkgcall.append(" ").append(*o);
-		dpkgcall.append(" --print-foreign-architectures 2> /dev/null");
-		FILE *dpkg = popen(dpkgcall.c_str(), "r");
+
+		// Generate the base argument list for dpkg
+		std::vector<const char *> Args;
+		string Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
+		{
+			string const dpkgChrootDir = _config->FindDir("DPkg::Chroot-Directory", "/");
+			size_t dpkgChrootLen = dpkgChrootDir.length();
+			if (dpkgChrootDir != "/" && Tmp.find(dpkgChrootDir) == 0) {
+				if (dpkgChrootDir[dpkgChrootLen - 1] == '/')
+					--dpkgChrootLen;
+				Tmp = Tmp.substr(dpkgChrootLen);
+			}
+		}
+		Args.push_back(Tmp.c_str());
+
+		// Stick in any custom dpkg options
+		::Configuration::Item const *Opts = _config->Tree("DPkg::Options");
+		if (Opts != 0) {
+			Opts = Opts->Child;
+			for (; Opts != 0; Opts = Opts->Next)
+			{
+				if (Opts->Value.empty() == true)
+					continue;
+				Args.push_back(Opts->Value.c_str());
+			}
+		}
+
+		Args.push_back("--print-foreign-architectures");
+		Args.push_back(NULL);
+
+		int external[2] = {-1, -1};
+		if (pipe(external) != 0)
+		{
+			_error->WarningE("getArchitecture", "Can't create IPC pipe for dpkg --print-foreign-architectures");
+			return archs;
+		}
+
+		pid_t dpkgMultiArch = ExecFork();
+		if (dpkgMultiArch == 0) {
+			close(external[0]);
+			std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory");
+			if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0)
+				_error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --print-foreign-architectures", chrootDir.c_str());
+			int const nullfd = open("/dev/null", O_RDONLY);
+			dup2(nullfd, STDIN_FILENO);
+			dup2(external[1], STDOUT_FILENO);
+			dup2(nullfd, STDERR_FILENO);
+			execvp(Args[0], (char**) &Args[0]);
+			_error->WarningE("getArchitecture", "Can't detect foreign architectures supported by dpkg!");
+			_exit(100);
+		}
+		close(external[1]);
+
+		FILE *dpkg = fdopen(external[0], "r");
 		char buf[1024];
 		char buf[1024];
 		if(dpkg != NULL) {
 		if(dpkg != NULL) {
-			if (fgets(buf, sizeof(buf), dpkg) != NULL) {
+			while (fgets(buf, sizeof(buf), dpkg) != NULL) {
 				char* arch = strtok(buf, " ");
 				char* arch = strtok(buf, " ");
 				while (arch != NULL) {
 				while (arch != NULL) {
 					for (; isspace(*arch) != 0; ++arch);
 					for (; isspace(*arch) != 0; ++arch);
 					if (arch[0] != '\0') {
 					if (arch[0] != '\0') {
 						char const* archend = arch;
 						char const* archend = arch;
 						for (; isspace(*archend) == 0 && *archend != '\0'; ++archend);
 						for (; isspace(*archend) == 0 && *archend != '\0'; ++archend);
-						archs.push_back(string(arch, (archend - arch)));
+						string a(arch, (archend - arch));
+						if (std::find(archs.begin(), archs.end(), a) == archs.end())
+							archs.push_back(a);
 					}
 					}
 					arch = strtok(NULL, " ");
 					arch = strtok(NULL, " ");
 				}
 				}
 			}
 			}
-			pclose(dpkg);
+			fclose(dpkg);
 		}
 		}
+		ExecWait(dpkgMultiArch, "dpkg --print-foreign-architectures", true);
 		return archs;
 		return archs;
 	}
 	}
 
 
@@ -379,9 +432,30 @@ bool const Configuration::checkArchitecture(std::string const &Arch) {
 // setDefaultConfigurationForCompressors				/*{{{*/
 // setDefaultConfigurationForCompressors				/*{{{*/
 void Configuration::setDefaultConfigurationForCompressors() {
 void Configuration::setDefaultConfigurationForCompressors() {
 	// Set default application paths to check for optional compression types
 	// Set default application paths to check for optional compression types
-	_config->CndSet("Dir::Bin::lzma", "/usr/bin/lzma");
-	_config->CndSet("Dir::Bin::xz", "/usr/bin/xz");
 	_config->CndSet("Dir::Bin::bzip2", "/bin/bzip2");
 	_config->CndSet("Dir::Bin::bzip2", "/bin/bzip2");
+	_config->CndSet("Dir::Bin::xz", "/usr/bin/xz");
+	if (FileExists(_config->FindFile("Dir::Bin::xz")) == true) {
+		_config->Clear("Dir::Bin::lzma");
+		_config->Set("APT::Compressor::lzma::Binary", "xz");
+		if (_config->Exists("APT::Compressor::lzma::CompressArg") == false) {
+			_config->Set("APT::Compressor::lzma::CompressArg::", "--format=lzma");
+			_config->Set("APT::Compressor::lzma::CompressArg::", "-9");
+		}
+		if (_config->Exists("APT::Compressor::lzma::UncompressArg") == false) {
+			_config->Set("APT::Compressor::lzma::UncompressArg::", "--format=lzma");
+			_config->Set("APT::Compressor::lzma::UncompressArg::", "-d");
+		}
+	} else {
+		_config->CndSet("Dir::Bin::lzma", "/usr/bin/lzma");
+		if (_config->Exists("APT::Compressor::lzma::CompressArg") == false) {
+			_config->Set("APT::Compressor::lzma::CompressArg::", "--suffix=");
+			_config->Set("APT::Compressor::lzma::CompressArg::", "-9");
+		}
+		if (_config->Exists("APT::Compressor::lzma::UncompressArg") == false) {
+			_config->Set("APT::Compressor::lzma::UncompressArg::", "--suffix=");
+			_config->Set("APT::Compressor::lzma::UncompressArg::", "-d");
+		}
+	}
 }
 }
 									/*}}}*/
 									/*}}}*/
 // getCompressors - Return Vector of usbale compressors			/*{{{*/
 // getCompressors - Return Vector of usbale compressors			/*{{{*/
@@ -403,12 +477,20 @@ const Configuration::getCompressors(bool const Cached) {
 	compressors.push_back(Compressor(".", "", "", "", "", 1));
 	compressors.push_back(Compressor(".", "", "", "", "", 1));
 	if (_config->Exists("Dir::Bin::gzip") == false || FileExists(_config->FindFile("Dir::Bin::gzip")) == true)
 	if (_config->Exists("Dir::Bin::gzip") == false || FileExists(_config->FindFile("Dir::Bin::gzip")) == true)
 		compressors.push_back(Compressor("gzip",".gz","gzip","-9n","-d",2));
 		compressors.push_back(Compressor("gzip",".gz","gzip","-9n","-d",2));
+#ifdef HAVE_ZLIB
+	else
+		compressors.push_back(Compressor("gzip",".gz","false", "", "", 2));
+#endif
 	if (_config->Exists("Dir::Bin::bzip2") == false || FileExists(_config->FindFile("Dir::Bin::bzip2")) == true)
 	if (_config->Exists("Dir::Bin::bzip2") == false || FileExists(_config->FindFile("Dir::Bin::bzip2")) == true)
 		compressors.push_back(Compressor("bzip2",".bz2","bzip2","-9","-d",3));
 		compressors.push_back(Compressor("bzip2",".bz2","bzip2","-9","-d",3));
-	if (_config->Exists("Dir::Bin::lzma") == false || FileExists(_config->FindFile("Dir::Bin::lzma")) == true)
-		compressors.push_back(Compressor("lzma",".lzma","lzma","-9","-d",4));
+#ifdef HAVE_BZ2
+	else
+		compressors.push_back(Compressor("bzip2",".bz2","false", "", "", 3));
+#endif
 	if (_config->Exists("Dir::Bin::xz") == false || FileExists(_config->FindFile("Dir::Bin::xz")) == true)
 	if (_config->Exists("Dir::Bin::xz") == false || FileExists(_config->FindFile("Dir::Bin::xz")) == true)
-		compressors.push_back(Compressor("xz",".xz","xz","-6","-d",5));
+		compressors.push_back(Compressor("xz",".xz","xz","-6","-d",4));
+	if (_config->Exists("Dir::Bin::lzma") == false || FileExists(_config->FindFile("Dir::Bin::lzma")) == true)
+		compressors.push_back(Compressor("lzma",".lzma","lzma","-9","-d",5));
 
 
 	std::vector<std::string> const comp = _config->FindVector("APT::Compressor");
 	std::vector<std::string> const comp = _config->FindVector("APT::Compressor");
 	for (std::vector<std::string>::const_iterator c = comp.begin();
 	for (std::vector<std::string>::const_iterator c = comp.begin();
@@ -441,7 +523,7 @@ Configuration::Compressor::Compressor(char const *name, char const *extension,
 				      char const *binary,
 				      char const *binary,
 				      char const *compressArg, char const *uncompressArg,
 				      char const *compressArg, char const *uncompressArg,
 				      unsigned short const cost) {
 				      unsigned short const cost) {
-	std::string const config = string("APT:Compressor::").append(name).append("::");
+	std::string const config = std::string("APT::Compressor::").append(name).append("::");
 	Name = _config->Find(std::string(config).append("Name"), name);
 	Name = _config->Find(std::string(config).append("Name"), name);
 	Extension = _config->Find(std::string(config).append("Extension"), extension);
 	Extension = _config->Find(std::string(config).append("Extension"), extension);
 	Binary = _config->Find(std::string(config).append("Binary"), binary);
 	Binary = _config->Find(std::string(config).append("Binary"), binary);

+ 39 - 2
apt-pkg/cachefile.cc

@@ -12,6 +12,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/cachefile.h>
 #include <apt-pkg/cachefile.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/sourcelist.h>
@@ -21,13 +23,14 @@
 #include <apt-pkg/pkgsystem.h>
 #include <apt-pkg/pkgsystem.h>
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
-    
+#include <apt-pkg/progress.h>
+
 #include <apti18n.h>
 #include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 // CacheFile::CacheFile - Constructor					/*{{{*/
 // CacheFile::CacheFile - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-pkgCacheFile::pkgCacheFile() : Map(NULL), Cache(NULL), DCache(NULL),
+pkgCacheFile::pkgCacheFile() : d(NULL), Map(NULL), Cache(NULL), DCache(NULL),
 				SrcList(NULL), Policy(NULL)
 				SrcList(NULL), Policy(NULL)
 {
 {
 }
 }
@@ -175,6 +178,40 @@ void pkgCacheFile::RemoveCaches()
       unlink(pkgcache.c_str());
       unlink(pkgcache.c_str());
    if (srcpkgcache.empty() == false && RealFileExists(srcpkgcache) == true)
    if (srcpkgcache.empty() == false && RealFileExists(srcpkgcache) == true)
       unlink(srcpkgcache.c_str());
       unlink(srcpkgcache.c_str());
+   if (pkgcache.empty() == false)
+   {
+      std::string cachedir = flNotFile(pkgcache);
+      std::string cachefile = flNotDir(pkgcache);
+      if (cachedir.empty() != true && cachefile.empty() != true && DirectoryExists(cachedir) == true)
+      {
+	 cachefile.append(".");
+	 std::vector<std::string> caches = GetListOfFilesInDir(cachedir, false);
+	 for (std::vector<std::string>::const_iterator file = caches.begin(); file != caches.end(); ++file)
+	 {
+	    std::string nuke = flNotDir(*file);
+	    if (strncmp(cachefile.c_str(), nuke.c_str(), cachefile.length()) != 0)
+	       continue;
+	    unlink(file->c_str());
+	 }
+      }
+   }
+
+   if (srcpkgcache.empty() == true)
+      return;
+
+   std::string cachedir = flNotFile(srcpkgcache);
+   std::string cachefile = flNotDir(srcpkgcache);
+   if (cachedir.empty() == true || cachefile.empty() == true || DirectoryExists(cachedir) == false)
+      return;
+   cachefile.append(".");
+   std::vector<std::string> caches = GetListOfFilesInDir(cachedir, false);
+   for (std::vector<std::string>::const_iterator file = caches.begin(); file != caches.end(); ++file)
+   {
+      std::string nuke = flNotDir(*file);
+      if (strncmp(cachefile.c_str(), nuke.c_str(), cachefile.length()) != 0)
+	 continue;
+      unlink(file->c_str());
+   }
 }
 }
 									/*}}}*/
 									/*}}}*/
 // CacheFile::Close - close the cache files				/*{{{*/
 // CacheFile::Close - close the cache files				/*{{{*/

+ 11 - 1
apt-pkg/cachefile.h

@@ -17,14 +17,24 @@
 #ifndef PKGLIB_CACHEFILE_H
 #ifndef PKGLIB_CACHEFILE_H
 #define PKGLIB_CACHEFILE_H
 #define PKGLIB_CACHEFILE_H
 
 
-
 #include <apt-pkg/depcache.h>
 #include <apt-pkg/depcache.h>
+#include <apt-pkg/macros.h>
+
+#ifndef APT_8_CLEANER_HEADERS
 #include <apt-pkg/acquire.h>
 #include <apt-pkg/acquire.h>
 #include <apt-pkg/policy.h>
 #include <apt-pkg/policy.h>
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/sourcelist.h>
+#endif
+
+class pkgPolicy;
+class pkgSourceList;
+class OpProgress;
 
 
 class pkgCacheFile
 class pkgCacheFile
 {
 {
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+
    protected:
    protected:
    
    
    MMap *Map;
    MMap *Map;

+ 3 - 1
apt-pkg/cachefilter.cc

@@ -4,6 +4,8 @@
     Collection of functor classes */
     Collection of functor classes */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/cachefilter.h>
 #include <apt-pkg/cachefilter.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
@@ -16,7 +18,7 @@
 									/*}}}*/
 									/*}}}*/
 namespace APT {
 namespace APT {
 namespace CacheFilter {
 namespace CacheFilter {
-PackageNameMatchesRegEx::PackageNameMatchesRegEx(std::string const &Pattern) {/*{{{*/
+PackageNameMatchesRegEx::PackageNameMatchesRegEx(std::string const &Pattern) : d(NULL) {/*{{{*/
 	pattern = new regex_t;
 	pattern = new regex_t;
 	int const Res = regcomp(pattern, Pattern.c_str(), REG_EXTENDED | REG_ICASE | REG_NOSUB);
 	int const Res = regcomp(pattern, Pattern.c_str(), REG_EXTENDED | REG_ICASE | REG_NOSUB);
 	if (Res == 0)
 	if (Res == 0)

+ 2 - 0
apt-pkg/cachefilter.h

@@ -16,6 +16,8 @@ namespace APT {
 namespace CacheFilter {
 namespace CacheFilter {
 // PackageNameMatchesRegEx						/*{{{*/
 // PackageNameMatchesRegEx						/*{{{*/
 class PackageNameMatchesRegEx {
 class PackageNameMatchesRegEx {
+         /** \brief dpointer placeholder (for later in case we need it) */
+         void *d;
 	regex_t* pattern;
 	regex_t* pattern;
 public:
 public:
 	PackageNameMatchesRegEx(std::string const &Pattern);
 	PackageNameMatchesRegEx(std::string const &Pattern);

+ 7 - 10
apt-pkg/cacheiterators.h

@@ -32,6 +32,7 @@
 #include<iterator>
 #include<iterator>
 
 
 #include<string.h>
 #include<string.h>
+
 // abstract Iterator template						/*{{{*/
 // abstract Iterator template						/*{{{*/
 /* This template provides the very basic iterator methods we
 /* This template provides the very basic iterator methods we
    need to have for doing some walk-over-the-cache magic */
    need to have for doing some walk-over-the-cache magic */
@@ -111,7 +112,7 @@ class pkgCache::GrpIterator: public Iterator<Group, GrpIterator> {
 
 
 	inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;};
 	inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;};
 	inline PkgIterator PackageList() const;
 	inline PkgIterator PackageList() const;
-	PkgIterator FindPkg(string Arch = "any") const;
+	PkgIterator FindPkg(std::string Arch = "any") const;
 	/** \brief find the package with the "best" architecture
 	/** \brief find the package with the "best" architecture
 
 
 	    The best architecture is either the "native" or the first
 	    The best architecture is either the "native" or the first
@@ -206,15 +207,10 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
 	inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;};
 	inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;};
 	inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;};
 	inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;};
 	inline const char *Arch() const {
 	inline const char *Arch() const {
-		if (S->MultiArch == pkgCache::Version::All ||
-		    S->MultiArch == pkgCache::Version::AllForeign ||
-		    S->MultiArch == pkgCache::Version::AllAllowed)
+		if ((S->MultiArch & pkgCache::Version::All) == pkgCache::Version::All)
 			return "all";
 			return "all";
 		return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch;
 		return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch;
 	};
 	};
-	__deprecated inline const char *Arch(bool const pseudo) const {
-		return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch;
-	};
 	inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);};
 	inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);};
 
 
 	inline DescIterator DescriptionList() const;
 	inline DescIterator DescriptionList() const;
@@ -224,10 +220,9 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
 	inline VerFileIterator FileList() const;
 	inline VerFileIterator FileList() const;
 	bool Downloadable() const;
 	bool Downloadable() const;
 	inline const char *PriorityType() const {return Owner->Priority(S->Priority);};
 	inline const char *PriorityType() const {return Owner->Priority(S->Priority);};
-	string RelStr() const;
+	std::string RelStr() const;
 
 
 	bool Automatic() const;
 	bool Automatic() const;
-	__deprecated bool Pseudo() const;
 	VerFileIterator NewestFile() const;
 	VerFileIterator NewestFile() const;
 
 
 	inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Iterator<Version, VerIterator>(Owner, Trg) {
 	inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Iterator<Version, VerIterator>(Owner, Trg) {
@@ -288,6 +283,8 @@ class pkgCache::DepIterator : public Iterator<Dependency, DepIterator> {
 	inline bool Reverse() const {return Type == DepRev;};
 	inline bool Reverse() const {return Type == DepRev;};
 	bool IsCritical() const;
 	bool IsCritical() const;
 	bool IsNegative() const;
 	bool IsNegative() const;
+	bool IsIgnorable(PrvIterator const &Prv) const;
+	bool IsIgnorable(PkgIterator const &Pkg) const;
 	void GlobOr(DepIterator &Start,DepIterator &End);
 	void GlobOr(DepIterator &Start,DepIterator &End);
 	Version **AllTargets() const;
 	Version **AllTargets() const;
 	bool SmartTargetPkg(PkgIterator &Result) const;
 	bool SmartTargetPkg(PkgIterator &Result) const;
@@ -371,7 +368,7 @@ class pkgCache::PkgFileIterator : public Iterator<PackageFile, PkgFileIterator>
 	inline const char *IndexType() const {return S->IndexType == 0?0:Owner->StrP + S->IndexType;};
 	inline const char *IndexType() const {return S->IndexType == 0?0:Owner->StrP + S->IndexType;};
 
 
 	bool IsOk();
 	bool IsOk();
-	string RelStr();
+	std::string RelStr();
 
 
 	// Constructors
 	// Constructors
 	inline PkgFileIterator() : Iterator<PackageFile, PkgFileIterator>() {};
 	inline PkgFileIterator() : Iterator<PackageFile, PkgFileIterator>() {};

+ 212 - 182
apt-pkg/cacheset.cc

@@ -9,22 +9,27 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/aptconfiguration.h>
+#include <apt-pkg/cachefile.h>
 #include <apt-pkg/cachefilter.h>
 #include <apt-pkg/cachefilter.h>
 #include <apt-pkg/cacheset.h>
 #include <apt-pkg/cacheset.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/versionmatch.h>
 #include <apt-pkg/versionmatch.h>
-
-#include <apti18n.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/policy.h>
 
 
 #include <vector>
 #include <vector>
 
 
 #include <regex.h>
 #include <regex.h>
+
+#include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 namespace APT {
 namespace APT {
 // FromTask - Return all packages in the cache from a specific task	/*{{{*/
 // FromTask - Return all packages in the cache from a specific task	/*{{{*/
-PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
+bool PackageContainerInterface::FromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
 	size_t const archfound = pattern.find_last_of(':');
 	size_t const archfound = pattern.find_last_of(':');
 	std::string arch = "native";
 	std::string arch = "native";
 	if (archfound != std::string::npos) {
 	if (archfound != std::string::npos) {
@@ -33,13 +38,16 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheS
 	}
 	}
 
 
 	if (pattern[pattern.length() -1] != '^')
 	if (pattern[pattern.length() -1] != '^')
-		return APT::PackageSet(TASK);
+		return false;
 	pattern.erase(pattern.length()-1);
 	pattern.erase(pattern.length()-1);
 
 
 	if (unlikely(Cache.GetPkgCache() == 0 || Cache.GetDepCache() == 0))
 	if (unlikely(Cache.GetPkgCache() == 0 || Cache.GetDepCache() == 0))
-		return APT::PackageSet(TASK);
+		return false;
+
+	bool const wasEmpty = pci->empty();
+	if (wasEmpty == true)
+		pci->setConstructor(TASK);
 
 
-	PackageSet pkgset(TASK);
 	// get the records
 	// get the records
 	pkgRecords Recs(Cache);
 	pkgRecords Recs(Cache);
 
 
@@ -49,9 +57,10 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheS
 	snprintf(S, sizeof(S), "^Task:.*[, ]%s([, ]|$)", pattern.c_str());
 	snprintf(S, sizeof(S), "^Task:.*[, ]%s([, ]|$)", pattern.c_str());
 	if(regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE) != 0) {
 	if(regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE) != 0) {
 		_error->Error("Failed to compile task regexp");
 		_error->Error("Failed to compile task regexp");
-		return pkgset;
+		return false;
 	}
 	}
 
 
+	bool found = false;
 	for (pkgCache::GrpIterator Grp = Cache->GrpBegin(); Grp.end() == false; ++Grp) {
 	for (pkgCache::GrpIterator Grp = Cache->GrpBegin(); Grp.end() == false; ++Grp) {
 		pkgCache::PkgIterator Pkg = Grp.FindPkg(arch);
 		pkgCache::PkgIterator Pkg = Grp.FindPkg(arch);
 		if (Pkg.end() == true)
 		if (Pkg.end() == true)
@@ -70,22 +79,33 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheS
 		if (regexec(&Pattern, buf, 0, 0, 0) != 0)
 		if (regexec(&Pattern, buf, 0, 0, 0) != 0)
 			continue;
 			continue;
 
 
-		pkgset.insert(Pkg);
+		pci->insert(Pkg);
+		helper.showTaskSelection(Pkg, pattern);
+		found = true;
 	}
 	}
 	regfree(&Pattern);
 	regfree(&Pattern);
 
 
-	if (pkgset.empty() == true)
-		return helper.canNotFindTask(Cache, pattern);
+	if (found == false) {
+		helper.canNotFindTask(pci, Cache, pattern);
+		pci->setConstructor(UNKNOWN);
+		return false;
+	}
+
+	if (wasEmpty == false && pci->getConstructor() != UNKNOWN)
+		pci->setConstructor(UNKNOWN);
 
 
-	helper.showTaskSelection(pkgset, pattern);
-	return pkgset;
+	return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // FromRegEx - Return all packages in the cache matching a pattern	/*{{{*/
 // FromRegEx - Return all packages in the cache matching a pattern	/*{{{*/
-PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
+bool PackageContainerInterface::FromRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
 	static const char * const isregex = ".?+*|[^$";
 	static const char * const isregex = ".?+*|[^$";
 	if (pattern.find_first_of(isregex) == std::string::npos)
 	if (pattern.find_first_of(isregex) == std::string::npos)
-		return PackageSet(REGEX);
+		return false;
+
+	bool const wasEmpty = pci->empty();
+	if (wasEmpty == true)
+		pci->setConstructor(REGEX);
 
 
 	size_t archfound = pattern.find_last_of(':');
 	size_t archfound = pattern.find_last_of(':');
 	std::string arch = "native";
 	std::string arch = "native";
@@ -98,11 +118,11 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, Cache
 	}
 	}
 
 
 	if (unlikely(Cache.GetPkgCache() == 0))
 	if (unlikely(Cache.GetPkgCache() == 0))
-		return PackageSet(REGEX);
+		return false;
 
 
 	APT::CacheFilter::PackageNameMatchesRegEx regexfilter(pattern);
 	APT::CacheFilter::PackageNameMatchesRegEx regexfilter(pattern);
 
 
-	PackageSet pkgset(REGEX);
+	bool found = false;
 	for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp) {
 	for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp) {
 		if (regexfilter(Grp) == false)
 		if (regexfilter(Grp) == false)
 			continue;
 			continue;
@@ -118,18 +138,25 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, Cache
 				continue;
 				continue;
 		}
 		}
 
 
-		pkgset.insert(Pkg);
+		pci->insert(Pkg);
+		helper.showRegExSelection(Pkg, pattern);
+		found = true;
+	}
+
+	if (found == false) {
+		helper.canNotFindRegEx(pci, Cache, pattern);
+		pci->setConstructor(UNKNOWN);
+		return false;
 	}
 	}
 
 
-	if (pkgset.empty() == true)
-		return helper.canNotFindRegEx(Cache, pattern);
+	if (wasEmpty == false && pci->getConstructor() != UNKNOWN)
+		pci->setConstructor(UNKNOWN);
 
 
-	helper.showRegExSelection(pkgset, pattern);
-	return pkgset;
+	return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // FromName - Returns the package defined  by this string		/*{{{*/
 // FromName - Returns the package defined  by this string		/*{{{*/
-pkgCache::PkgIterator PackageSet::FromName(pkgCacheFile &Cache,
+pkgCache::PkgIterator PackageContainerInterface::FromName(pkgCacheFile &Cache,
 			std::string const &str, CacheSetHelper &helper) {
 			std::string const &str, CacheSetHelper &helper) {
 	std::string pkg = str;
 	std::string pkg = str;
 	size_t archfound = pkg.find_last_of(':');
 	size_t archfound = pkg.find_last_of(':');
@@ -155,167 +182,155 @@ pkgCache::PkgIterator PackageSet::FromName(pkgCacheFile &Cache,
 	return Pkg;
 	return Pkg;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
-std::map<unsigned short, PackageSet> PackageSet::GroupedFromCommandLine(
-		pkgCacheFile &Cache, const char **cmdline,
-		std::list<PackageSet::Modifier> const &mods,
-		unsigned short const &fallback, CacheSetHelper &helper) {
-	std::map<unsigned short, PackageSet> pkgsets;
-	for (const char **I = cmdline; *I != 0; ++I) {
-		unsigned short modID = fallback;
-		std::string str = *I;
-		bool modifierPresent = false;
-		for (std::list<PackageSet::Modifier>::const_iterator mod = mods.begin();
-		     mod != mods.end(); ++mod) {
-			size_t const alength = strlen(mod->Alias);
-			switch(mod->Pos) {
-			case PackageSet::Modifier::POSTFIX:
-				if (str.compare(str.length() - alength, alength,
-						mod->Alias, 0, alength) != 0)
-					continue;
-				str.erase(str.length() - alength);
-				modID = mod->ID;
-				break;
-			case PackageSet::Modifier::PREFIX:
-				continue;
-			case PackageSet::Modifier::NONE:
-				continue;
-			}
-			modifierPresent = true;
-			break;
-		}
-		if (modifierPresent == true) {
-			bool const errors = helper.showErrors(false);
-			pkgCache::PkgIterator Pkg = FromName(Cache, *I, helper);
-			helper.showErrors(errors);
-			if (Pkg.end() == false) {
-				pkgsets[fallback].insert(Pkg);
-				continue;
-			}
-		}
-		pkgsets[modID].insert(PackageSet::FromString(Cache, str, helper));
-	}
-	return pkgsets;
-}
-									/*}}}*/
-// FromCommandLine - Return all packages specified on commandline	/*{{{*/
-PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper) {
-	PackageSet pkgset;
-	for (const char **I = cmdline; *I != 0; ++I) {
-		PackageSet pset = FromString(Cache, *I, helper);
-		pkgset.insert(pset.begin(), pset.end());
-	}
-	return pkgset;
-}
-									/*}}}*/
 // FromString - Return all packages matching a specific string		/*{{{*/
 // FromString - Return all packages matching a specific string		/*{{{*/
-PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, CacheSetHelper &helper) {
+bool PackageContainerInterface::FromString(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &str, CacheSetHelper &helper) {
+	bool found = true;
 	_error->PushToStack();
 	_error->PushToStack();
 
 
-	PackageSet pkgset;
 	pkgCache::PkgIterator Pkg = FromName(Cache, str, helper);
 	pkgCache::PkgIterator Pkg = FromName(Cache, str, helper);
 	if (Pkg.end() == false)
 	if (Pkg.end() == false)
-		pkgset.insert(Pkg);
-	else {
-		pkgset = FromTask(Cache, str, helper);
-		if (pkgset.empty() == true) {
-			pkgset = FromRegEx(Cache, str, helper);
-			if (pkgset.empty() == true)
-				pkgset = helper.canNotFindPackage(Cache, str);
-		}
+		pci->insert(Pkg);
+	else if (FromTask(pci, Cache, str, helper) == false &&
+		 FromRegEx(pci, Cache, str, helper) == false)
+	{
+		helper.canNotFindPackage(pci, Cache, str);
+		found = false;
 	}
 	}
 
 
-	if (pkgset.empty() == false)
+	if (found == true)
 		_error->RevertToStack();
 		_error->RevertToStack();
 	else
 	else
 		_error->MergeWithStack();
 		_error->MergeWithStack();
-	return pkgset;
+	return found;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
-std::map<unsigned short, VersionSet> VersionSet::GroupedFromCommandLine(
-		pkgCacheFile &Cache, const char **cmdline,
-		std::list<VersionSet::Modifier> const &mods,
-		unsigned short const &fallback, CacheSetHelper &helper) {
-	std::map<unsigned short, VersionSet> versets;
-	for (const char **I = cmdline; *I != 0; ++I) {
-		unsigned short modID = fallback;
-		VersionSet::Version select = VersionSet::NEWEST;
-		std::string str = *I;
-		bool modifierPresent = false;
-		for (std::list<VersionSet::Modifier>::const_iterator mod = mods.begin();
-		     mod != mods.end(); ++mod) {
-			if (modID == fallback && mod->ID == fallback)
-				select = mod->SelectVersion;
-			size_t const alength = strlen(mod->Alias);
-			switch(mod->Pos) {
-			case VersionSet::Modifier::POSTFIX:
-				if (str.compare(str.length() - alength, alength,
-						mod->Alias, 0, alength) != 0)
-					continue;
-				str.erase(str.length() - alength);
-				modID = mod->ID;
-				select = mod->SelectVersion;
-				break;
-			case VersionSet::Modifier::PREFIX:
-				continue;
-			case VersionSet::Modifier::NONE:
+// FromCommandLine - Return all packages specified on commandline	/*{{{*/
+bool PackageContainerInterface::FromCommandLine(PackageContainerInterface * const pci, pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper) {
+	bool found = false;
+	for (const char **I = cmdline; *I != 0; ++I)
+		found |= PackageContainerInterface::FromString(pci, Cache, *I, helper);
+	return found;
+}
+									/*}}}*/
+// FromModifierCommandLine - helper doing the work for PKG:GroupedFromCommandLine	/*{{{*/
+bool PackageContainerInterface::FromModifierCommandLine(unsigned short &modID, PackageContainerInterface * const pci,
+							pkgCacheFile &Cache, const char * cmdline,
+							std::list<Modifier> const &mods, CacheSetHelper &helper) {
+	std::string str = cmdline;
+	bool modifierPresent = false;
+	for (std::list<Modifier>::const_iterator mod = mods.begin();
+	     mod != mods.end(); ++mod) {
+		size_t const alength = strlen(mod->Alias);
+		switch(mod->Pos) {
+		case Modifier::POSTFIX:
+			if (str.compare(str.length() - alength, alength,
+					mod->Alias, 0, alength) != 0)
 				continue;
 				continue;
-			}
-			modifierPresent = true;
+			str.erase(str.length() - alength);
+			modID = mod->ID;
 			break;
 			break;
+		case Modifier::PREFIX:
+			continue;
+		case Modifier::NONE:
+			continue;
 		}
 		}
-
-		if (modifierPresent == true) {
-			bool const errors = helper.showErrors(false);
-			VersionSet const vset = VersionSet::FromString(Cache, std::string(*I), select, helper, true);
-			helper.showErrors(errors);
-			if (vset.empty() == false) {
-				versets[fallback].insert(vset);
+		modifierPresent = true;
+		break;
+	}
+	if (modifierPresent == true) {
+		bool const errors = helper.showErrors(false);
+		pkgCache::PkgIterator Pkg = FromName(Cache, cmdline, helper);
+		helper.showErrors(errors);
+		if (Pkg.end() == false) {
+			pci->insert(Pkg);
+			return true;
+		}
+	}
+	return FromString(pci, Cache, str, helper);
+}
+									/*}}}*/
+// FromModifierCommandLine - helper doing the work for VER:GroupedFromCommandLine	/*{{{*/
+bool VersionContainerInterface::FromModifierCommandLine(unsigned short &modID,
+							VersionContainerInterface * const vci,
+							pkgCacheFile &Cache, const char * cmdline,
+							std::list<Modifier> const &mods,
+							CacheSetHelper &helper) {
+	Version select = NEWEST;
+	std::string str = cmdline;
+	bool modifierPresent = false;
+	unsigned short fallback = modID;
+	for (std::list<Modifier>::const_iterator mod = mods.begin();
+	     mod != mods.end(); ++mod) {
+		if (modID == fallback && mod->ID == fallback)
+			select = mod->SelectVersion;
+		size_t const alength = strlen(mod->Alias);
+		switch(mod->Pos) {
+		case Modifier::POSTFIX:
+			if (str.compare(str.length() - alength, alength,
+					mod->Alias, 0, alength) != 0)
 				continue;
 				continue;
-			}
+			str.erase(str.length() - alength);
+			modID = mod->ID;
+			select = mod->SelectVersion;
+			break;
+		case Modifier::PREFIX:
+			continue;
+		case Modifier::NONE:
+			continue;
 		}
 		}
-		versets[modID].insert(VersionSet::FromString(Cache, str, select , helper));
+		modifierPresent = true;
+		break;
 	}
 	}
-	return versets;
+
+	if (modifierPresent == true) {
+		bool const errors = helper.showErrors(false);
+		bool const found = VersionContainerInterface::FromString(vci, Cache, cmdline, select, helper, true);
+		helper.showErrors(errors);
+		if (found == true)
+			return true;
+	}
+	return FromString(vci, Cache, str, select, helper);
 }
 }
 									/*}}}*/
 									/*}}}*/
 // FromCommandLine - Return all versions specified on commandline	/*{{{*/
 // FromCommandLine - Return all versions specified on commandline	/*{{{*/
-APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
-		APT::VersionSet::Version const &fallback, CacheSetHelper &helper) {
-	VersionSet verset;
+bool VersionContainerInterface::FromCommandLine(VersionContainerInterface * const vci,
+						pkgCacheFile &Cache, const char **cmdline,
+						Version const &fallback, CacheSetHelper &helper) {
+	bool found = false;
 	for (const char **I = cmdline; *I != 0; ++I)
 	for (const char **I = cmdline; *I != 0; ++I)
-		verset.insert(VersionSet::FromString(Cache, *I, fallback, helper));
-	return verset;
+		found |= VersionContainerInterface::FromString(vci, Cache, *I, fallback, helper);
+	return found;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // FromString - Returns all versions spedcified by a string		/*{{{*/
 // FromString - Returns all versions spedcified by a string		/*{{{*/
-APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg,
-		APT::VersionSet::Version const &fallback, CacheSetHelper &helper,
-		bool const &onlyFromName) {
+bool VersionContainerInterface::FromString(VersionContainerInterface * const vci,
+					   pkgCacheFile &Cache, std::string pkg,
+					   Version const &fallback, CacheSetHelper &helper,
+					   bool const onlyFromName) {
 	std::string ver;
 	std::string ver;
 	bool verIsRel = false;
 	bool verIsRel = false;
 	size_t const vertag = pkg.find_last_of("/=");
 	size_t const vertag = pkg.find_last_of("/=");
-	if (vertag != string::npos) {
+	if (vertag != std::string::npos) {
 		ver = pkg.substr(vertag+1);
 		ver = pkg.substr(vertag+1);
 		verIsRel = (pkg[vertag] == '/');
 		verIsRel = (pkg[vertag] == '/');
 		pkg.erase(vertag);
 		pkg.erase(vertag);
 	}
 	}
 	PackageSet pkgset;
 	PackageSet pkgset;
 	if (onlyFromName == false)
 	if (onlyFromName == false)
-		pkgset = PackageSet::FromString(Cache, pkg, helper);
+		PackageContainerInterface::FromString(&pkgset, Cache, pkg, helper);
 	else {
 	else {
-		pkgset.insert(PackageSet::FromName(Cache, pkg, helper));
+		pkgset.insert(PackageContainerInterface::FromName(Cache, pkg, helper));
 	}
 	}
 
 
-	VersionSet verset;
 	bool errors = true;
 	bool errors = true;
 	if (pkgset.getConstructor() != PackageSet::UNKNOWN)
 	if (pkgset.getConstructor() != PackageSet::UNKNOWN)
 		errors = helper.showErrors(false);
 		errors = helper.showErrors(false);
+
+	bool found = false;
 	for (PackageSet::const_iterator P = pkgset.begin();
 	for (PackageSet::const_iterator P = pkgset.begin();
 	     P != pkgset.end(); ++P) {
 	     P != pkgset.end(); ++P) {
-		if (vertag == string::npos) {
-			verset.insert(VersionSet::FromPackage(Cache, P, fallback, helper));
+		if (vertag == std::string::npos) {
+			found |= VersionContainerInterface::FromPackage(vci, Cache, P, fallback, helper);
 			continue;
 			continue;
 		}
 		}
 		pkgCache::VerIterator V;
 		pkgCache::VerIterator V;
@@ -345,75 +360,78 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg,
 		if (V.end() == true)
 		if (V.end() == true)
 			continue;
 			continue;
 		helper.showSelectedVersion(P, V, ver, verIsRel);
 		helper.showSelectedVersion(P, V, ver, verIsRel);
-		verset.insert(V);
+		vci->insert(V);
+		found = true;
 	}
 	}
 	if (pkgset.getConstructor() != PackageSet::UNKNOWN)
 	if (pkgset.getConstructor() != PackageSet::UNKNOWN)
 		helper.showErrors(errors);
 		helper.showErrors(errors);
-	return verset;
+	return found;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // FromPackage - versions from package based on fallback		/*{{{*/
 // FromPackage - versions from package based on fallback		/*{{{*/
-VersionSet VersionSet::FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
-		VersionSet::Version const &fallback, CacheSetHelper &helper) {
-	VersionSet verset;
+bool VersionContainerInterface::FromPackage(VersionContainerInterface * const vci,
+					    pkgCacheFile &Cache,
+					    pkgCache::PkgIterator const &P,
+					    Version const &fallback,
+					    CacheSetHelper &helper) {
 	pkgCache::VerIterator V;
 	pkgCache::VerIterator V;
 	bool showErrors;
 	bool showErrors;
+	bool found = false;
 	switch(fallback) {
 	switch(fallback) {
-	case VersionSet::ALL:
+	case ALL:
 		if (P->VersionList != 0)
 		if (P->VersionList != 0)
 			for (V = P.VersionList(); V.end() != true; ++V)
 			for (V = P.VersionList(); V.end() != true; ++V)
-				verset.insert(V);
+				found |= vci->insert(V);
 		else
 		else
-			verset.insert(helper.canNotFindAllVer(Cache, P));
+			helper.canNotFindAllVer(vci, Cache, P);
 		break;
 		break;
-	case VersionSet::CANDANDINST:
-		verset.insert(getInstalledVer(Cache, P, helper));
-		verset.insert(getCandidateVer(Cache, P, helper));
+	case CANDANDINST:
+		found |= vci->insert(getInstalledVer(Cache, P, helper));
+		found |= vci->insert(getCandidateVer(Cache, P, helper));
 		break;
 		break;
-	case VersionSet::CANDIDATE:
-		verset.insert(getCandidateVer(Cache, P, helper));
+	case CANDIDATE:
+		found |= vci->insert(getCandidateVer(Cache, P, helper));
 		break;
 		break;
-	case VersionSet::INSTALLED:
-		verset.insert(getInstalledVer(Cache, P, helper));
+	case INSTALLED:
+		found |= vci->insert(getInstalledVer(Cache, P, helper));
 		break;
 		break;
-	case VersionSet::CANDINST:
+	case CANDINST:
 		showErrors = helper.showErrors(false);
 		showErrors = helper.showErrors(false);
 		V = getCandidateVer(Cache, P, helper);
 		V = getCandidateVer(Cache, P, helper);
 		if (V.end() == true)
 		if (V.end() == true)
 			V = getInstalledVer(Cache, P, helper);
 			V = getInstalledVer(Cache, P, helper);
 		helper.showErrors(showErrors);
 		helper.showErrors(showErrors);
 		if (V.end() == false)
 		if (V.end() == false)
-			verset.insert(V);
+			found |= vci->insert(V);
 		else
 		else
-			verset.insert(helper.canNotFindInstCandVer(Cache, P));
+			helper.canNotFindInstCandVer(vci, Cache, P);
 		break;
 		break;
-	case VersionSet::INSTCAND:
+	case INSTCAND:
 		showErrors = helper.showErrors(false);
 		showErrors = helper.showErrors(false);
 		V = getInstalledVer(Cache, P, helper);
 		V = getInstalledVer(Cache, P, helper);
 		if (V.end() == true)
 		if (V.end() == true)
 			V = getCandidateVer(Cache, P, helper);
 			V = getCandidateVer(Cache, P, helper);
 		helper.showErrors(showErrors);
 		helper.showErrors(showErrors);
 		if (V.end() == false)
 		if (V.end() == false)
-			verset.insert(V);
+			found |= vci->insert(V);
 		else
 		else
-			verset.insert(helper.canNotFindInstCandVer(Cache, P));
+			helper.canNotFindInstCandVer(vci, Cache, P);
 		break;
 		break;
-	case VersionSet::NEWEST:
+	case NEWEST:
 		if (P->VersionList != 0)
 		if (P->VersionList != 0)
-			verset.insert(P.VersionList());
+			found |= vci->insert(P.VersionList());
 		else
 		else
-			verset.insert(helper.canNotFindNewestVer(Cache, P));
+			helper.canNotFindNewestVer(Cache, P);
 		break;
 		break;
 	}
 	}
-	return verset;
+	return found;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // getCandidateVer - Returns the candidate version of the given package	/*{{{*/
 // getCandidateVer - Returns the candidate version of the given package	/*{{{*/
-pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache,
+pkgCache::VerIterator VersionContainerInterface::getCandidateVer(pkgCacheFile &Cache,
 		pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) {
 		pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) {
 	pkgCache::VerIterator Cand;
 	pkgCache::VerIterator Cand;
-	if (Cache.IsPolicyBuilt() == true || Cache.IsDepCacheBuilt() == false)
-	{
+	if (Cache.IsPolicyBuilt() == true || Cache.IsDepCacheBuilt() == false) {
 		if (unlikely(Cache.GetPolicy() == 0))
 		if (unlikely(Cache.GetPolicy() == 0))
 			return pkgCache::VerIterator(Cache);
 			return pkgCache::VerIterator(Cache);
 		Cand = Cache.GetPolicy()->GetCandidateVer(Pkg);
 		Cand = Cache.GetPolicy()->GetCandidateVer(Pkg);
@@ -426,13 +444,14 @@ pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache,
 }
 }
 									/*}}}*/
 									/*}}}*/
 // getInstalledVer - Returns the installed version of the given package	/*{{{*/
 // getInstalledVer - Returns the installed version of the given package	/*{{{*/
-pkgCache::VerIterator VersionSet::getInstalledVer(pkgCacheFile &Cache,
+pkgCache::VerIterator VersionContainerInterface::getInstalledVer(pkgCacheFile &Cache,
 		pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) {
 		pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) {
 	if (Pkg->CurrentVer == 0)
 	if (Pkg->CurrentVer == 0)
 		return helper.canNotFindInstalledVer(Cache, Pkg);
 		return helper.canNotFindInstalledVer(Cache, Pkg);
 	return Pkg.CurrentVer();
 	return Pkg.CurrentVer();
 }
 }
 									/*}}}*/
 									/*}}}*/
+
 // canNotFindPkgName - handle the case no package has this name		/*{{{*/
 // canNotFindPkgName - handle the case no package has this name		/*{{{*/
 pkgCache::PkgIterator CacheSetHelper::canNotFindPkgName(pkgCacheFile &Cache,
 pkgCache::PkgIterator CacheSetHelper::canNotFindPkgName(pkgCacheFile &Cache,
 			std::string const &str) {
 			std::string const &str) {
@@ -442,46 +461,40 @@ pkgCache::PkgIterator CacheSetHelper::canNotFindPkgName(pkgCacheFile &Cache,
 }
 }
 									/*}}}*/
 									/*}}}*/
 // canNotFindTask - handle the case no package is found for a task	/*{{{*/
 // canNotFindTask - handle the case no package is found for a task	/*{{{*/
-PackageSet CacheSetHelper::canNotFindTask(pkgCacheFile &Cache, std::string pattern) {
+void CacheSetHelper::canNotFindTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern) {
 	if (ShowError == true)
 	if (ShowError == true)
 		_error->Insert(ErrorType, _("Couldn't find task '%s'"), pattern.c_str());
 		_error->Insert(ErrorType, _("Couldn't find task '%s'"), pattern.c_str());
-	return PackageSet();
 }
 }
 									/*}}}*/
 									/*}}}*/
 // canNotFindRegEx - handle the case no package is found by a regex	/*{{{*/
 // canNotFindRegEx - handle the case no package is found by a regex	/*{{{*/
-PackageSet CacheSetHelper::canNotFindRegEx(pkgCacheFile &Cache, std::string pattern) {
+void CacheSetHelper::canNotFindRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern) {
 	if (ShowError == true)
 	if (ShowError == true)
 		_error->Insert(ErrorType, _("Couldn't find any package by regex '%s'"), pattern.c_str());
 		_error->Insert(ErrorType, _("Couldn't find any package by regex '%s'"), pattern.c_str());
-	return PackageSet();
 }
 }
 									/*}}}*/
 									/*}}}*/
 // canNotFindPackage - handle the case no package is found from a string/*{{{*/
 // canNotFindPackage - handle the case no package is found from a string/*{{{*/
-PackageSet CacheSetHelper::canNotFindPackage(pkgCacheFile &Cache, std::string const &str) {
-	return PackageSet();
+void CacheSetHelper::canNotFindPackage(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &str) {
 }
 }
 									/*}}}*/
 									/*}}}*/
 // canNotFindAllVer							/*{{{*/
 // canNotFindAllVer							/*{{{*/
-VersionSet CacheSetHelper::canNotFindAllVer(pkgCacheFile &Cache,
+void CacheSetHelper::canNotFindAllVer(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 		pkgCache::PkgIterator const &Pkg) {
 		pkgCache::PkgIterator const &Pkg) {
 	if (ShowError == true)
 	if (ShowError == true)
 		_error->Insert(ErrorType, _("Can't select versions from package '%s' as it is purely virtual"), Pkg.FullName(true).c_str());
 		_error->Insert(ErrorType, _("Can't select versions from package '%s' as it is purely virtual"), Pkg.FullName(true).c_str());
-	return VersionSet();
 }
 }
 									/*}}}*/
 									/*}}}*/
 // canNotFindInstCandVer						/*{{{*/
 // canNotFindInstCandVer						/*{{{*/
-VersionSet CacheSetHelper::canNotFindInstCandVer(pkgCacheFile &Cache,
+void CacheSetHelper::canNotFindInstCandVer(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 		pkgCache::PkgIterator const &Pkg) {
 		pkgCache::PkgIterator const &Pkg) {
 	if (ShowError == true)
 	if (ShowError == true)
 		_error->Insert(ErrorType, _("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg.FullName(true).c_str());
 		_error->Insert(ErrorType, _("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg.FullName(true).c_str());
-	return VersionSet();
 }
 }
 									/*}}}*/
 									/*}}}*/
 // canNotFindInstCandVer						/*{{{*/
 // canNotFindInstCandVer						/*{{{*/
-VersionSet CacheSetHelper::canNotFindCandInstVer(pkgCacheFile &Cache,
+void CacheSetHelper::canNotFindCandInstVer(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 		pkgCache::PkgIterator const &Pkg) {
 		pkgCache::PkgIterator const &Pkg) {
 	if (ShowError == true)
 	if (ShowError == true)
 		_error->Insert(ErrorType, _("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg.FullName(true).c_str());
 		_error->Insert(ErrorType, _("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg.FullName(true).c_str());
-	return VersionSet();
 }
 }
 									/*}}}*/
 									/*}}}*/
 // canNotFindNewestVer							/*{{{*/
 // canNotFindNewestVer							/*{{{*/
@@ -508,4 +521,21 @@ pkgCache::VerIterator CacheSetHelper::canNotFindInstalledVer(pkgCacheFile &Cache
 	return pkgCache::VerIterator(Cache, 0);
 	return pkgCache::VerIterator(Cache, 0);
 }
 }
 									/*}}}*/
 									/*}}}*/
+// showTaskSelection							/*{{{*/
+void CacheSetHelper::showTaskSelection(pkgCache::PkgIterator const &pkg,
+				       std::string const &pattern) {
+}
+									/*}}}*/
+// showRegExSelection							/*{{{*/
+void CacheSetHelper::showRegExSelection(pkgCache::PkgIterator const &pkg,
+					std::string const &pattern) {
+}
+									/*}}}*/
+// showSelectedVersion							/*{{{*/
+void CacheSetHelper::showSelectedVersion(pkgCache::PkgIterator const &Pkg,
+					 pkgCache::VerIterator const Ver,
+					 std::string const &ver,
+					 bool const verIsRel) {
+}
+									/*}}}*/
 }
 }

+ 452 - 183
apt-pkg/cacheset.h

@@ -14,14 +14,24 @@
 #include <list>
 #include <list>
 #include <map>
 #include <map>
 #include <set>
 #include <set>
+#include <list>
 #include <string>
 #include <string>
+#include <iterator>
 
 
-#include <apt-pkg/cachefile.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;
+
 namespace APT {
 namespace APT {
-class PackageSet;
-class VersionSet;
+class PackageContainerInterface;
+class VersionContainerInterface;
+
 class CacheSetHelper {							/*{{{*/
 class CacheSetHelper {							/*{{{*/
 /** \class APT::CacheSetHelper
 /** \class APT::CacheSetHelper
     Simple base class with a lot of virtual methods which can be overridden
     Simple base class with a lot of virtual methods which can be overridden
@@ -32,25 +42,28 @@ class CacheSetHelper {							/*{{{*/
     printed out.
     printed out.
 */
 */
 public:									/*{{{*/
 public:									/*{{{*/
-	CacheSetHelper(bool const &ShowError = true,
+	CacheSetHelper(bool const ShowError = true,
 		GlobalError::MsgType ErrorType = GlobalError::ERROR) :
 		GlobalError::MsgType ErrorType = GlobalError::ERROR) :
 			ShowError(ShowError), ErrorType(ErrorType) {};
 			ShowError(ShowError), ErrorType(ErrorType) {};
 	virtual ~CacheSetHelper() {};
 	virtual ~CacheSetHelper() {};
 
 
-	virtual void showTaskSelection(PackageSet const &pkgset, string const &pattern) {};
-	virtual void showRegExSelection(PackageSet const &pkgset, string const &pattern) {};
+	virtual void showTaskSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern);
+	virtual void showRegExSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern);
 	virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
 	virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
-				 string const &ver, bool const &verIsRel) {};
+				 std::string const &ver, bool const verIsRel);
 
 
-	virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str);
-	virtual PackageSet canNotFindTask(pkgCacheFile &Cache, std::string pattern);
-	virtual PackageSet canNotFindRegEx(pkgCacheFile &Cache, std::string pattern);
-	virtual PackageSet canNotFindPackage(pkgCacheFile &Cache, std::string const &str);
-	virtual VersionSet canNotFindAllVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg);
-	virtual VersionSet canNotFindInstCandVer(pkgCacheFile &Cache,
+	virtual void canNotFindTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
+	virtual void canNotFindRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
+	virtual void canNotFindPackage(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &str);
+
+	virtual void canNotFindAllVer(VersionContainerInterface * const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg);
+	virtual void canNotFindInstCandVer(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 				pkgCache::PkgIterator const &Pkg);
 				pkgCache::PkgIterator const &Pkg);
-	virtual VersionSet canNotFindCandInstVer(pkgCacheFile &Cache,
+	virtual void canNotFindCandInstVer(VersionContainerInterface * const vci,
+				pkgCacheFile &Cache,
 				pkgCache::PkgIterator const &Pkg);
 				pkgCache::PkgIterator const &Pkg);
+
+	virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str);
 	virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache,
 	virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache,
 				pkgCache::PkgIterator const &Pkg);
 				pkgCache::PkgIterator const &Pkg);
 	virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache,
 	virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache,
@@ -59,7 +72,7 @@ public:									/*{{{*/
 				pkgCache::PkgIterator const &Pkg);
 				pkgCache::PkgIterator const &Pkg);
 
 
 	bool showErrors() const { return ShowError; };
 	bool showErrors() const { return ShowError; };
-	bool showErrors(bool const &newValue) { if (ShowError == newValue) return ShowError; else return ((ShowError = newValue) == false); };
+	bool showErrors(bool const newValue) { if (ShowError == newValue) return ShowError; else return ((ShowError = newValue) == false); };
 	GlobalError::MsgType errorType() const { return ErrorType; };
 	GlobalError::MsgType errorType() const { return ErrorType; };
 	GlobalError::MsgType errorType(GlobalError::MsgType const &newValue)
 	GlobalError::MsgType errorType(GlobalError::MsgType const &newValue)
 	{
 	{
@@ -76,53 +89,138 @@ protected:
 	bool ShowError;
 	bool ShowError;
 	GlobalError::MsgType ErrorType;
 	GlobalError::MsgType ErrorType;
 };									/*}}}*/
 };									/*}}}*/
-class PackageSet : public std::set<pkgCache::PkgIterator> {		/*{{{*/
-/** \class APT::PackageSet
-
-    Simple wrapper around a std::set to provide a similar interface to
-    a set of packages as to the complete set of all packages in the
-    pkgCache. */
-public:									/*{{{*/
-	/** \brief smell like a pkgCache::PkgIterator */
-	class const_iterator : public std::set<pkgCache::PkgIterator>::const_iterator {/*{{{*/
+class PackageContainerInterface {					/*{{{*/
+/** \class PackageContainerInterface
+
+ * Interface ensuring that all operations can be executed on the yet to
+ * define concrete PackageContainer - access to all methods is possible,
+ * but in general the wrappers provided by the PackageContainer template
+ * are nicer to use.
+
+ * This class mostly protects use from the need to write all implementation
+ * of the methods working on containers in the template */
+public:
+	class const_iterator {						/*{{{*/
 	public:
 	public:
-		const_iterator(std::set<pkgCache::PkgIterator>::const_iterator x) :
-			 std::set<pkgCache::PkgIterator>::const_iterator(x) {}
-
-		operator pkgCache::PkgIterator(void) { return **this; }
-
-		inline const char *Name() const {return (**this).Name(); }
-		inline std::string FullName(bool const &Pretty) const { return (**this).FullName(Pretty); }
-		inline std::string FullName() const { return (**this).FullName(); }
-		inline const char *Section() const {return (**this).Section(); }
-		inline bool Purge() const {return (**this).Purge(); }
-		inline const char *Arch() const {return (**this).Arch(); }
-		inline pkgCache::GrpIterator Group() const { return (**this).Group(); }
-		inline pkgCache::VerIterator VersionList() const { return (**this).VersionList(); }
-		inline pkgCache::VerIterator CurrentVer() const { return (**this).CurrentVer(); }
-		inline pkgCache::DepIterator RevDependsList() const { return (**this).RevDependsList(); }
-		inline pkgCache::PrvIterator ProvidesList() const { return (**this).ProvidesList(); }
-		inline pkgCache::PkgIterator::OkState State() const { return (**this).State(); }
-		inline const char *CandVersion() const { return (**this).CandVersion(); }
-		inline const char *CurVersion() const { return (**this).CurVersion(); }
-		inline pkgCache *Cache() const { return (**this).Cache(); };
-		inline unsigned long Index() const {return (**this).Index();};
+		virtual pkgCache::PkgIterator getPkg() const = 0;
+		operator pkgCache::PkgIterator(void) const { return getPkg(); }
+
+		inline const char *Name() const {return getPkg().Name(); }
+		inline std::string FullName(bool const Pretty) const { return getPkg().FullName(Pretty); }
+		inline std::string FullName() const { return getPkg().FullName(); }
+		inline const char *Section() const {return getPkg().Section(); }
+		inline bool Purge() const {return getPkg().Purge(); }
+		inline const char *Arch() const {return getPkg().Arch(); }
+		inline pkgCache::GrpIterator Group() const { return getPkg().Group(); }
+		inline pkgCache::VerIterator VersionList() const { return getPkg().VersionList(); }
+		inline pkgCache::VerIterator CurrentVer() const { return getPkg().CurrentVer(); }
+		inline pkgCache::DepIterator RevDependsList() const { return getPkg().RevDependsList(); }
+		inline pkgCache::PrvIterator ProvidesList() const { return getPkg().ProvidesList(); }
+		inline pkgCache::PkgIterator::OkState State() const { return getPkg().State(); }
+		inline const char *CandVersion() const { return getPkg().CandVersion(); }
+		inline const char *CurVersion() const { return getPkg().CurVersion(); }
+		inline pkgCache *Cache() const { return getPkg().Cache(); };
+		inline unsigned long Index() const {return getPkg().Index();};
 		// we have only valid iterators here
 		// we have only valid iterators here
 		inline bool end() const { return false; };
 		inline bool end() const { return false; };
 
 
-		friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, (*i)); }
+		inline pkgCache::Package const * operator->() const {return &*getPkg();};
+	};
+									/*}}}*/
+
+	virtual bool insert(pkgCache::PkgIterator const &P) = 0;
+	virtual bool empty() const = 0;
+	virtual void clear() = 0;
 
 
-		inline pkgCache::Package const * operator->() const {
-			return &***this;
-		};
+	enum Constructor { UNKNOWN, REGEX, TASK };
+	virtual void setConstructor(Constructor const &con) = 0;
+	virtual Constructor getConstructor() const = 0;
+
+	static bool FromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
+	static bool FromRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
+	static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper);
+	static bool FromString(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper);
+	static bool FromCommandLine(PackageContainerInterface * const pci, pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper);
+
+	struct Modifier {
+		enum Position { NONE, PREFIX, POSTFIX };
+		unsigned short ID;
+		const char * const Alias;
+		Position Pos;
+		Modifier (unsigned short const &id, const char * const alias, Position const &pos) : ID(id), Alias(alias), Pos(pos) {};
+	};
+
+	static bool FromModifierCommandLine(unsigned short &modID, PackageContainerInterface * const pci,
+					    pkgCacheFile &Cache, const char * cmdline,
+					    std::list<Modifier> const &mods, CacheSetHelper &helper);
+};
+									/*}}}*/
+template<class Container> class PackageContainer : public PackageContainerInterface {/*{{{*/
+/** \class APT::PackageContainer
+
+    Simple wrapper around a container class like std::set to provide a similar
+    interface to a set of packages as to the complete set of all packages in the
+    pkgCache. */
+	Container _cont;
+public:									/*{{{*/
+	/** \brief smell like a pkgCache::PkgIterator */
+	class const_iterator : public PackageContainerInterface::const_iterator,/*{{{*/
+			       public std::iterator<std::forward_iterator_tag, typename Container::const_iterator> {
+		typename Container::const_iterator _iter;
+	public:
+		const_iterator(typename Container::const_iterator i) : _iter(i) {}
+		pkgCache::PkgIterator getPkg(void) const { return *_iter; }
+		inline pkgCache::PkgIterator operator*(void) const { return *_iter; };
+		operator typename Container::const_iterator(void) const { return _iter; }
+		inline const_iterator& operator++() { ++_iter; return *this; }
+		inline const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; }
+		inline bool operator!=(const_iterator const &i) const { return _iter != i._iter; };
+		inline bool operator==(const_iterator const &i) const { return _iter == i._iter; };
+		friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, *i); }
+	};
+	class iterator : public PackageContainerInterface::const_iterator,
+			 public std::iterator<std::forward_iterator_tag, typename Container::iterator> {
+		typename Container::iterator _iter;
+	public:
+		iterator(typename Container::iterator i) : _iter(i) {}
+		pkgCache::PkgIterator getPkg(void) const { return *_iter; }
+		inline pkgCache::PkgIterator operator*(void) const { return *_iter; };
+		operator typename Container::iterator(void) const { return _iter; }
+		operator typename PackageContainer<Container>::const_iterator() { return PackageContainer<Container>::const_iterator(_iter); }
+		inline iterator& operator++() { ++_iter; return *this; }
+		inline iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
+		inline bool operator!=(iterator const &i) const { return _iter != i._iter; };
+		inline bool operator==(iterator const &i) const { return _iter == i._iter; };
+		inline iterator& operator=(iterator const &i) { _iter = i._iter; return *this; };
+		inline iterator& operator=(typename Container::iterator const &i) { _iter = i; return *this; };
+		friend std::ostream& operator<<(std::ostream& out, iterator i) { return operator<<(out, *i); }
 	};
 	};
-	// 103. set::iterator is required to be modifiable, but this allows modification of keys
-	typedef APT::PackageSet::const_iterator iterator;
 									/*}}}*/
 									/*}}}*/
 
 
-	using std::set<pkgCache::PkgIterator>::insert;
-	inline void insert(pkgCache::PkgIterator const &P) { if (P.end() == false) std::set<pkgCache::PkgIterator>::insert(P); };
-	inline void insert(PackageSet const &pkgset) { insert(pkgset.begin(), pkgset.end()); };
+	bool insert(pkgCache::PkgIterator const &P) { if (P.end() == true) return false; _cont.insert(P); return true; };
+	template<class Cont> void insert(PackageContainer<Cont> const &pkgcont) { _cont.insert((typename Cont::const_iterator)pkgcont.begin(), (typename Cont::const_iterator)pkgcont.end()); };
+	void insert(const_iterator begin, const_iterator end) { _cont.insert(begin, end); };
+
+	bool empty() const { return _cont.empty(); };
+	void clear() { return _cont.clear(); };
+	//FIXME: on ABI break, replace the first with the second without bool
+	void erase(iterator position) { _cont.erase((typename Container::iterator)position); };
+	iterator& erase(iterator &position, bool) { return position = _cont.erase((typename Container::iterator)position); };
+	size_t erase(const pkgCache::PkgIterator x) { return _cont.erase(x); };
+	void erase(iterator first, iterator last) { _cont.erase(first, last); };
+	size_t size() const { return _cont.size(); };
+
+	const_iterator begin() const { return const_iterator(_cont.begin()); };
+	const_iterator end() const { return const_iterator(_cont.end()); };
+	iterator begin() { return iterator(_cont.begin()); };
+	iterator end() { return iterator(_cont.end()); };
+	const_iterator find(pkgCache::PkgIterator const &P) const { return const_iterator(_cont.find(P)); };
+
+	void setConstructor(Constructor const &by) { ConstructedBy = by; };
+	Constructor getConstructor() const { return ConstructedBy; };
+
+	PackageContainer() : ConstructedBy(UNKNOWN) {};
+	PackageContainer(Constructor const &by) : ConstructedBy(by) {};
 
 
 	/** \brief returns all packages in the cache who belong to the given task
 	/** \brief returns all packages in the cache who belong to the given task
 
 
@@ -132,8 +230,12 @@ public:									/*{{{*/
 	    \param Cache the packages are in
 	    \param Cache the packages are in
 	    \param pattern name of the task
 	    \param pattern name of the task
 	    \param helper responsible for error and message handling */
 	    \param helper responsible for error and message handling */
-	static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
-	static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string const &pattern) {
+	static PackageContainer FromTask(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
+		PackageContainer cont(TASK);
+		PackageContainerInterface::FromTask(&cont, Cache, pattern, helper);
+		return cont;
+	}
+	static PackageContainer FromTask(pkgCacheFile &Cache, std::string const &pattern) {
 		CacheSetHelper helper;
 		CacheSetHelper helper;
 		return FromTask(Cache, pattern, helper);
 		return FromTask(Cache, pattern, helper);
 	}
 	}
@@ -146,32 +248,43 @@ public:									/*{{{*/
 	    \param Cache the packages are in
 	    \param Cache the packages are in
 	    \param pattern regular expression for package names
 	    \param pattern regular expression for package names
 	    \param helper responsible for error and message handling */
 	    \param helper responsible for error and message handling */
-	static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
-	static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string const &pattern) {
+	static PackageContainer FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
+		PackageContainer cont(REGEX);
+		PackageContainerInterface::FromRegEx(&cont, Cache, pattern, helper);
+		return cont;
+	}
+
+	static PackageContainer FromRegEx(pkgCacheFile &Cache, std::string const &pattern) {
 		CacheSetHelper helper;
 		CacheSetHelper helper;
 		return FromRegEx(Cache, pattern, helper);
 		return FromRegEx(Cache, pattern, helper);
 	}
 	}
 
 
-	/** \brief returns all packages specified by a string
+	/** \brief returns a package specified by a string
 
 
-	    \param Cache the packages are in
-	    \param string String the package name(s) should be extracted from
+	    \param Cache the package is in
+	    \param pattern String the package name should be extracted from
 	    \param helper responsible for error and message handling */
 	    \param helper responsible for error and message handling */
-	static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper);
-	static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string) {
+	static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
+		return PackageContainerInterface::FromName(Cache, pattern, helper);
+	}
+	static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern) {
 		CacheSetHelper helper;
 		CacheSetHelper helper;
-		return FromString(Cache, string, helper);
+		return PackageContainerInterface::FromName(Cache, pattern, helper);
 	}
 	}
 
 
-	/** \brief returns a package specified by a string
+	/** \brief returns all packages specified by a string
 
 
-	    \param Cache the package is in
-	    \param string String the package name should be extracted from
+	    \param Cache the packages are in
+	    \param pattern String the package name(s) should be extracted from
 	    \param helper responsible for error and message handling */
 	    \param helper responsible for error and message handling */
-	static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper);
-	static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string) {
+	static PackageContainer FromString(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
+		PackageContainer cont;
+		PackageContainerInterface::FromString(&cont, Cache, pattern, helper);
+		return cont;
+	}
+	static PackageContainer FromString(pkgCacheFile &Cache, std::string const &pattern) {
 		CacheSetHelper helper;
 		CacheSetHelper helper;
-		return FromName(Cache, string, helper);
+		return FromString(Cache, pattern, helper);
 	}
 	}
 
 
 	/** \brief returns all packages specified on the commandline
 	/** \brief returns all packages specified on the commandline
@@ -181,20 +294,16 @@ public:									/*{{{*/
 	    \param Cache the packages are in
 	    \param Cache the packages are in
 	    \param cmdline Command line the package names should be extracted from
 	    \param cmdline Command line the package names should be extracted from
 	    \param helper responsible for error and message handling */
 	    \param helper responsible for error and message handling */
-	static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper);
-	static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
+	static PackageContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper) {
+		PackageContainer cont;
+		PackageContainerInterface::FromCommandLine(&cont, Cache, cmdline, helper);
+		return cont;
+	}
+	static PackageContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
 		CacheSetHelper helper;
 		CacheSetHelper helper;
 		return FromCommandLine(Cache, cmdline, helper);
 		return FromCommandLine(Cache, cmdline, helper);
 	}
 	}
 
 
-	struct Modifier {
-		enum Position { NONE, PREFIX, POSTFIX };
-		unsigned short ID;
-		const char * const Alias;
-		Position Pos;
-		Modifier (unsigned short const &id, const char * const alias, Position const &pos) : ID(id), Alias(alias), Pos(pos) {};
-	};
-
 	/** \brief group packages by a action modifiers
 	/** \brief group packages by a action modifiers
 
 
 	    At some point it is needed to get from the same commandline
 	    At some point it is needed to get from the same commandline
@@ -206,78 +315,93 @@ public:									/*{{{*/
 	    \param mods list of modifiers the method should accept
 	    \param mods list of modifiers the method should accept
 	    \param fallback the default modifier group for a package
 	    \param fallback the default modifier group for a package
 	    \param helper responsible for error and message handling */
 	    \param helper responsible for error and message handling */
-	static std::map<unsigned short, PackageSet> GroupedFromCommandLine(
-		pkgCacheFile &Cache, const char **cmdline,
-		std::list<PackageSet::Modifier> const &mods,
-		unsigned short const &fallback, CacheSetHelper &helper);
-	static std::map<unsigned short, PackageSet> GroupedFromCommandLine(
-		pkgCacheFile &Cache, const char **cmdline,
-		std::list<PackageSet::Modifier> const &mods,
-		unsigned short const &fallback) {
+	static std::map<unsigned short, PackageContainer> GroupedFromCommandLine(
+										 pkgCacheFile &Cache,
+										 const char **cmdline,
+										 std::list<Modifier> const &mods,
+										 unsigned short const &fallback,
+										 CacheSetHelper &helper) {
+		std::map<unsigned short, PackageContainer> pkgsets;
+		for (const char **I = cmdline; *I != 0; ++I) {
+			unsigned short modID = fallback;
+			PackageContainer pkgset;
+			PackageContainerInterface::FromModifierCommandLine(modID, &pkgset, Cache, *I, mods, helper);
+			pkgsets[modID].insert(pkgset);
+		}
+		return pkgsets;
+	}
+	static std::map<unsigned short, PackageContainer> GroupedFromCommandLine(
+										 pkgCacheFile &Cache,
+										 const char **cmdline,
+										 std::list<Modifier> const &mods,
+										 unsigned short const &fallback) {
 		CacheSetHelper helper;
 		CacheSetHelper helper;
 		return GroupedFromCommandLine(Cache, cmdline,
 		return GroupedFromCommandLine(Cache, cmdline,
 				mods, fallback, helper);
 				mods, fallback, helper);
 	}
 	}
-
-	enum Constructor { UNKNOWN, REGEX, TASK };
-	Constructor getConstructor() const { return ConstructedBy; };
-
-	PackageSet() : ConstructedBy(UNKNOWN) {};
-	PackageSet(Constructor const &by) : ConstructedBy(by) {};
 									/*}}}*/
 									/*}}}*/
 private:								/*{{{*/
 private:								/*{{{*/
 	Constructor ConstructedBy;
 	Constructor ConstructedBy;
 									/*}}}*/
 									/*}}}*/
 };									/*}}}*/
 };									/*}}}*/
-class VersionSet : public std::set<pkgCache::VerIterator> {		/*{{{*/
-/** \class APT::VersionSet
 
 
-    Simple wrapper around a std::set to provide a similar interface to
-    a set of versions as to the complete set of all versions in the
-    pkgCache. */
-public:									/*{{{*/
+template<> template<class Cont> void PackageContainer<std::list<pkgCache::PkgIterator> >::insert(PackageContainer<Cont> const &pkgcont) {
+	for (typename PackageContainer<Cont>::const_iterator p = pkgcont.begin(); p != pkgcont.end(); ++p)
+		_cont.push_back(*p);
+};
+// these two are 'inline' as otherwise the linker has problems with seeing these untemplated
+// specializations again and again - but we need to see them, so that library users can use them
+template<> inline bool PackageContainer<std::list<pkgCache::PkgIterator> >::insert(pkgCache::PkgIterator const &P) {
+	if (P.end() == true)
+		return false;
+	_cont.push_back(P);
+	return true;
+};
+template<> inline void PackageContainer<std::list<pkgCache::PkgIterator> >::insert(const_iterator begin, const_iterator end) {
+	for (const_iterator p = begin; p != end; ++p)
+		_cont.push_back(*p);
+};
+typedef PackageContainer<std::set<pkgCache::PkgIterator> > PackageSet;
+typedef PackageContainer<std::list<pkgCache::PkgIterator> > PackageList;
+
+class VersionContainerInterface {					/*{{{*/
+/** \class APT::VersionContainerInterface
+
+    Same as APT::PackageContainerInterface, just for Versions */
+public:
 	/** \brief smell like a pkgCache::VerIterator */
 	/** \brief smell like a pkgCache::VerIterator */
-	class const_iterator : public std::set<pkgCache::VerIterator>::const_iterator {/*{{{*/
+	class const_iterator {						/*{{{*/
 	public:
 	public:
-		const_iterator(std::set<pkgCache::VerIterator>::const_iterator x) :
-			 std::set<pkgCache::VerIterator>::const_iterator(x) {}
-
-		operator pkgCache::VerIterator(void) { return **this; }
-
-		inline pkgCache *Cache() const { return (**this).Cache(); };
-		inline unsigned long Index() const {return (**this).Index();};
+		virtual pkgCache::VerIterator getVer() const = 0;
+		operator pkgCache::VerIterator(void) { return getVer(); }
+
+		inline pkgCache *Cache() const { return getVer().Cache(); };
+		inline unsigned long Index() const {return getVer().Index();};
+		inline int CompareVer(const pkgCache::VerIterator &B) const { return getVer().CompareVer(B); };
+		inline const char *VerStr() const { return getVer().VerStr(); };
+		inline const char *Section() const { return getVer().Section(); };
+		inline const char *Arch() const { return getVer().Arch(); };
+		inline pkgCache::PkgIterator ParentPkg() const { return getVer().ParentPkg(); };
+		inline pkgCache::DescIterator DescriptionList() const { return getVer().DescriptionList(); };
+		inline pkgCache::DescIterator TranslatedDescription() const { return getVer().TranslatedDescription(); };
+		inline pkgCache::DepIterator DependsList() const { return getVer().DependsList(); };
+		inline pkgCache::PrvIterator ProvidesList() const { return getVer().ProvidesList(); };
+		inline pkgCache::VerFileIterator FileList() const { return getVer().FileList(); };
+		inline bool Downloadable() const { return getVer().Downloadable(); };
+		inline const char *PriorityType() const { return getVer().PriorityType(); };
+		inline std::string RelStr() const { return getVer().RelStr(); };
+		inline bool Automatic() const { return getVer().Automatic(); };
+		inline pkgCache::VerFileIterator NewestFile() const { return getVer().NewestFile(); };
 		// we have only valid iterators here
 		// we have only valid iterators here
 		inline bool end() const { return false; };
 		inline bool end() const { return false; };
 
 
-		inline pkgCache::Version const * operator->() const {
-			return &***this;
-		};
-
-		inline int CompareVer(const pkgCache::VerIterator &B) const { return (**this).CompareVer(B); };
-		inline const char *VerStr() const { return (**this).VerStr(); };
-		inline const char *Section() const { return (**this).Section(); };
-		inline const char *Arch() const { return (**this).Arch(); };
-		__deprecated inline const char *Arch(bool const pseudo) const { return (**this).Arch(); };
-		inline pkgCache::PkgIterator ParentPkg() const { return (**this).ParentPkg(); };
-		inline pkgCache::DescIterator DescriptionList() const { return (**this).DescriptionList(); };
-		inline pkgCache::DescIterator TranslatedDescription() const { return (**this).TranslatedDescription(); };
-		inline pkgCache::DepIterator DependsList() const { return (**this).DependsList(); };
-		inline pkgCache::PrvIterator ProvidesList() const { return (**this).ProvidesList(); };
-		inline pkgCache::VerFileIterator FileList() const { return (**this).FileList(); };
-		inline bool Downloadable() const { return (**this).Downloadable(); };
-		inline const char *PriorityType() const { return (**this).PriorityType(); };
-		inline string RelStr() const { return (**this).RelStr(); };
-		inline bool Automatic() const { return (**this).Automatic(); };
-		__deprecated inline bool Pseudo() const { return false; };
-		inline pkgCache::VerFileIterator NewestFile() const { return (**this).NewestFile(); };
+		inline pkgCache::Version const * operator->() const { return &*getVer(); };
 	};
 	};
 									/*}}}*/
 									/*}}}*/
-	// 103. set::iterator is required to be modifiable, but this allows modification of keys
-	typedef APT::VersionSet::const_iterator iterator;
 
 
-	using std::set<pkgCache::VerIterator>::insert;
-	inline void insert(pkgCache::VerIterator const &V) { if (V.end() == false) std::set<pkgCache::VerIterator>::insert(V); };
-	inline void insert(VersionSet const &verset) { insert(verset.begin(), verset.end()); };
+	virtual bool insert(pkgCache::VerIterator const &V) = 0;
+	virtual bool empty() const = 0;
+	virtual void clear() = 0;
 
 
 	/** \brief specifies which version(s) will be returned if non is given */
 	/** \brief specifies which version(s) will be returned if non is given */
 	enum Version {
 	enum Version {
@@ -297,6 +421,120 @@ public:									/*{{{*/
 		NEWEST
 		NEWEST
 	};
 	};
 
 
+	struct Modifier {
+		enum Position { NONE, PREFIX, POSTFIX };
+		unsigned short ID;
+		const char * const Alias;
+		Position Pos;
+		Version SelectVersion;
+		Modifier (unsigned short const &id, const char * const alias, Position const &pos,
+			  Version const &select) : ID(id), Alias(alias), Pos(pos),
+			 SelectVersion(select) {};
+	};
+
+	static bool FromCommandLine(VersionContainerInterface * const vci, pkgCacheFile &Cache,
+				    const char **cmdline, Version const &fallback,
+				    CacheSetHelper &helper);
+
+	static bool FromString(VersionContainerInterface * const vci, pkgCacheFile &Cache,
+			       std::string pkg, Version const &fallback, CacheSetHelper &helper,
+			       bool const onlyFromName = false);
+
+	static bool FromPackage(VersionContainerInterface * const vci, pkgCacheFile &Cache,
+				pkgCache::PkgIterator const &P, Version const &fallback,
+				CacheSetHelper &helper);
+
+	static bool FromModifierCommandLine(unsigned short &modID,
+					    VersionContainerInterface * const vci,
+					    pkgCacheFile &Cache, const char * cmdline,
+					    std::list<Modifier> const &mods,
+					    CacheSetHelper &helper);
+
+
+	static bool FromDependency(VersionContainerInterface * const vci,
+				   pkgCacheFile &Cache,
+				   pkgCache::DepIterator const &D,
+				   Version const &selector,
+				   CacheSetHelper &helper);
+
+protected:								/*{{{*/
+
+	/** \brief returns the candidate version of the package
+
+	    \param Cache to be used to query for information
+	    \param Pkg we want the candidate version from this package */
+	static pkgCache::VerIterator getCandidateVer(pkgCacheFile &Cache,
+		pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper);
+
+	/** \brief returns the installed version of the package
+
+	    \param Cache to be used to query for information
+	    \param Pkg we want the installed version from this package */
+	static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache,
+		pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper);
+									/*}}}*/
+};
+									/*}}}*/
+template<class Container> class VersionContainer : public VersionContainerInterface {/*{{{*/
+/** \class APT::VersionContainer
+
+    Simple wrapper around a container class like std::set to provide a similar
+    interface to a set of versions as to the complete set of all versions in the
+    pkgCache. */
+	Container _cont;
+public:									/*{{{*/
+	/** \brief smell like a pkgCache::VerIterator */
+	class const_iterator : public VersionContainerInterface::const_iterator,
+			       public std::iterator<std::forward_iterator_tag, typename Container::const_iterator> {/*{{{*/
+		typename Container::const_iterator _iter;
+	public:
+		const_iterator(typename Container::const_iterator i) : _iter(i) {}
+		pkgCache::VerIterator getVer(void) const { return *_iter; }
+		inline pkgCache::VerIterator operator*(void) const { return *_iter; };
+		operator typename Container::const_iterator(void) const { return _iter; }
+		inline const_iterator& operator++() { ++_iter; return *this; }
+		inline const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; }
+		inline bool operator!=(const_iterator const &i) const { return _iter != i._iter; };
+		inline bool operator==(const_iterator const &i) const { return _iter == i._iter; };
+		friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, *i); }
+	};
+	class iterator : public VersionContainerInterface::const_iterator,
+			 public std::iterator<std::forward_iterator_tag, typename Container::iterator> {
+		typename Container::iterator _iter;
+	public:
+		iterator(typename Container::iterator i) : _iter(i) {}
+		pkgCache::VerIterator getVer(void) const { return *_iter; }
+		inline pkgCache::VerIterator operator*(void) const { return *_iter; };
+		operator typename Container::iterator(void) const { return _iter; }
+		operator typename VersionContainer<Container>::const_iterator() { return VersionContainer<Container>::const_iterator(_iter); }
+		inline iterator& operator++() { ++_iter; return *this; }
+		inline iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
+		inline bool operator!=(iterator const &i) const { return _iter != i._iter; };
+		inline bool operator==(iterator const &i) const { return _iter == i._iter; };
+		inline iterator& operator=(iterator const &i) { _iter = i._iter; return *this; };
+		inline iterator& operator=(typename Container::iterator const &i) { _iter = i; return *this; };
+		friend std::ostream& operator<<(std::ostream& out, iterator i) { return operator<<(out, *i); }
+	};
+									/*}}}*/
+
+	bool insert(pkgCache::VerIterator const &V) { if (V.end() == true) return false; _cont.insert(V); return true; };
+	template<class Cont> void insert(VersionContainer<Cont> const &vercont) { _cont.insert((typename Cont::const_iterator)vercont.begin(), (typename Cont::const_iterator)vercont.end()); };
+	void insert(const_iterator begin, const_iterator end) { _cont.insert(begin, end); };
+	bool empty() const { return _cont.empty(); };
+	void clear() { return _cont.clear(); };
+	//FIXME: on ABI break, replace the first with the second without bool
+	void erase(iterator position) { _cont.erase((typename Container::iterator)position); };
+	iterator& erase(iterator &position, bool) { return position = _cont.erase((typename Container::iterator)position); };
+	size_t erase(const pkgCache::VerIterator x) { return _cont.erase(x); };
+	void erase(iterator first, iterator last) { _cont.erase(first, last); };
+	size_t size() const { return _cont.size(); };
+
+	const_iterator begin() const { return const_iterator(_cont.begin()); };
+	const_iterator end() const { return const_iterator(_cont.end()); };
+	iterator begin() { return iterator(_cont.begin()); };
+	iterator end() { return iterator(_cont.end()); };
+	const_iterator find(pkgCache::VerIterator const &V) const { return const_iterator(_cont.find(V)); };
+
 	/** \brief returns all versions specified on the commandline
 	/** \brief returns all versions specified on the commandline
 
 
 	    Get all versions from the commandline, uses given default version if
 	    Get all versions from the commandline, uses given default version if
@@ -304,26 +542,34 @@ public:									/*{{{*/
 	    \param Cache the packages and versions are in
 	    \param Cache the packages and versions are in
 	    \param cmdline Command line the versions should be extracted from
 	    \param cmdline Command line the versions should be extracted from
 	    \param helper responsible for error and message handling */
 	    \param helper responsible for error and message handling */
-	static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
-			APT::VersionSet::Version const &fallback, CacheSetHelper &helper);
-	static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
-			APT::VersionSet::Version const &fallback) {
+	static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
+			Version const &fallback, CacheSetHelper &helper) {
+		VersionContainer vercon;
+		VersionContainerInterface::FromCommandLine(&vercon, Cache, cmdline, fallback, helper);
+		return vercon;
+	}
+	static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
+			Version const &fallback) {
 		CacheSetHelper helper;
 		CacheSetHelper helper;
 		return FromCommandLine(Cache, cmdline, fallback, helper);
 		return FromCommandLine(Cache, cmdline, fallback, helper);
 	}
 	}
-	static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
+	static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
 		return FromCommandLine(Cache, cmdline, CANDINST);
 		return FromCommandLine(Cache, cmdline, CANDINST);
 	}
 	}
 
 
-	static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg,
-			APT::VersionSet::Version const &fallback, CacheSetHelper &helper,
-			bool const &onlyFromName = false);
-	static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg,
-			APT::VersionSet::Version const &fallback) {
+	static VersionContainer FromString(pkgCacheFile &Cache, std::string const &pkg,
+			Version const &fallback, CacheSetHelper &helper,
+			bool const onlyFromName = false) {
+		VersionContainer vercon;
+		VersionContainerInterface::FromString(&vercon, Cache, pkg, fallback, helper);
+		return vercon;
+	}
+	static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg,
+			Version const &fallback) {
 		CacheSetHelper helper;
 		CacheSetHelper helper;
 		return FromString(Cache, pkg, fallback, helper);
 		return FromString(Cache, pkg, fallback, helper);
 	}
 	}
-	static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg) {
+	static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg) {
 		return FromString(Cache, pkg, CANDINST);
 		return FromString(Cache, pkg, CANDINST);
 	}
 	}
 
 
@@ -333,57 +579,80 @@ public:									/*{{{*/
 	    \param P the package in question
 	    \param P the package in question
 	    \param fallback the version(s) you want to get
 	    \param fallback the version(s) you want to get
 	    \param helper the helper used for display and error handling */
 	    \param helper the helper used for display and error handling */
-	static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
-		VersionSet::Version const &fallback, CacheSetHelper &helper);
-	static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
-			APT::VersionSet::Version const &fallback) {
+	static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
+		Version const &fallback, CacheSetHelper &helper) {
+		VersionContainer vercon;
+		VersionContainerInterface::FromPackage(&vercon, Cache, P, fallback, helper);
+		return vercon;
+	}
+	static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
+					    Version const &fallback) {
 		CacheSetHelper helper;
 		CacheSetHelper helper;
 		return FromPackage(Cache, P, fallback, helper);
 		return FromPackage(Cache, P, fallback, helper);
 	}
 	}
-	static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) {
-		return FromPackage(Cache, P, CANDINST);
+	static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) {
+		return FromPackage(Cache, P, CANDIDATE);
 	}
 	}
 
 
-	struct Modifier {
-		enum Position { NONE, PREFIX, POSTFIX };
-		unsigned short ID;
-		const char * const Alias;
-		Position Pos;
-		VersionSet::Version SelectVersion;
-		Modifier (unsigned short const &id, const char * const alias, Position const &pos,
-			  VersionSet::Version const &select) : ID(id), Alias(alias), Pos(pos),
-			 SelectVersion(select) {};
-	};
+	static std::map<unsigned short, VersionContainer> GroupedFromCommandLine(
+										 pkgCacheFile &Cache,
+										 const char **cmdline,
+										 std::list<Modifier> const &mods,
+										 unsigned short const fallback,
+										 CacheSetHelper &helper) {
+		std::map<unsigned short, VersionContainer> versets;
+		for (const char **I = cmdline; *I != 0; ++I) {
+			unsigned short modID = fallback;
+			VersionContainer verset;
+			VersionContainerInterface::FromModifierCommandLine(modID, &verset, Cache, *I, mods, helper);
+			versets[modID].insert(verset);
+		}
+		return versets;
 
 
-	static std::map<unsigned short, VersionSet> GroupedFromCommandLine(
-		pkgCacheFile &Cache, const char **cmdline,
-		std::list<VersionSet::Modifier> const &mods,
-		unsigned short const &fallback, CacheSetHelper &helper);
-	static std::map<unsigned short, VersionSet> GroupedFromCommandLine(
+	}
+	static std::map<unsigned short, VersionContainer> GroupedFromCommandLine(
 		pkgCacheFile &Cache, const char **cmdline,
 		pkgCacheFile &Cache, const char **cmdline,
-		std::list<VersionSet::Modifier> const &mods,
-		unsigned short const &fallback) {
+		std::list<Modifier> const &mods,
+		unsigned short const fallback) {
 		CacheSetHelper helper;
 		CacheSetHelper helper;
 		return GroupedFromCommandLine(Cache, cmdline,
 		return GroupedFromCommandLine(Cache, cmdline,
 				mods, fallback, helper);
 				mods, fallback, helper);
 	}
 	}
-									/*}}}*/
-protected:								/*{{{*/
 
 
-	/** \brief returns the candidate version of the package
-
-	    \param Cache to be used to query for information
-	    \param Pkg we want the candidate version from this package */
-	static pkgCache::VerIterator getCandidateVer(pkgCacheFile &Cache,
-		pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper);
-
-	/** \brief returns the installed version of the package
-
-	    \param Cache to be used to query for information
-	    \param Pkg we want the installed version from this package */
-	static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache,
-		pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper);
+	static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D,
+					       Version const &selector, CacheSetHelper &helper) {
+		VersionContainer vercon;
+		VersionContainerInterface::FromDependency(&vercon, Cache, D, selector, helper);
+		return vercon;
+	}
+	static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D,
+					       Version const &selector) {
+		CacheSetHelper helper;
+		return FromPackage(Cache, D, selector, helper);
+	}
+	static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D) {
+		return FromPackage(Cache, D, CANDIDATE);
+	}
 									/*}}}*/
 									/*}}}*/
 };									/*}}}*/
 };									/*}}}*/
+
+template<> template<class Cont> void VersionContainer<std::list<pkgCache::VerIterator> >::insert(VersionContainer<Cont> const &vercont) {
+	for (typename VersionContainer<Cont>::const_iterator v = vercont.begin(); v != vercont.end(); ++v)
+		_cont.push_back(*v);
+};
+// these two are 'inline' as otherwise the linker has problems with seeing these untemplated
+// specializations again and again - but we need to see them, so that library users can use them
+template<> inline bool VersionContainer<std::list<pkgCache::VerIterator> >::insert(pkgCache::VerIterator const &V) {
+	if (V.end() == true)
+		return false;
+	_cont.push_back(V);
+	return true;
+};
+template<> inline void VersionContainer<std::list<pkgCache::VerIterator> >::insert(const_iterator begin, const_iterator end) {
+	for (const_iterator v = begin; v != end; ++v)
+		_cont.push_back(*v);
+};
+typedef VersionContainer<std::set<pkgCache::VerIterator> > VersionSet;
+typedef VersionContainer<std::list<pkgCache::VerIterator> > VersionList;
 }
 }
 #endif
 #endif

+ 87 - 46
apt-pkg/cdrom.cc

@@ -1,5 +1,6 @@
 /*
 /*
  */
  */
+#include<config.h>
 
 
 #include<apt-pkg/init.h>
 #include<apt-pkg/init.h>
 #include<apt-pkg/error.h>
 #include<apt-pkg/error.h>
@@ -7,11 +8,11 @@
 #include<apt-pkg/strutl.h>
 #include<apt-pkg/strutl.h>
 #include<apt-pkg/cdrom.h>
 #include<apt-pkg/cdrom.h>
 #include<apt-pkg/aptconfiguration.h>
 #include<apt-pkg/aptconfiguration.h>
+#include<apt-pkg/configuration.h>
+#include<apt-pkg/fileutl.h>
 
 
 #include<sstream>
 #include<sstream>
 #include<fstream>
 #include<fstream>
-#include<config.h>
-#include<apti18n.h>
 #include <sys/stat.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <fcntl.h>
 #include <dirent.h>
 #include <dirent.h>
@@ -22,6 +23,8 @@
 
 
 #include "indexcopy.h"
 #include "indexcopy.h"
 
 
+#include<apti18n.h>
+
 using namespace std;
 using namespace std;
 
 
 // FindPackages - Find the package files on the CDROM			/*{{{*/
 // FindPackages - Find the package files on the CDROM			/*{{{*/
@@ -55,66 +58,91 @@ 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);
    }
    }
+
    /* 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 */
-   if (stat("Packages",&Buf) == 0 || stat("Packages.gz",&Buf) == 0)
+   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);
       List.push_back(CD);
-      
+
       // Continue down if thorough is given
       // Continue down if thorough is given
       if (_config->FindB("APT::CDROM::Thorough",false) == false)
       if (_config->FindB("APT::CDROM::Thorough",false) == false)
 	 return true;
 	 return true;
+      break;
    }
    }
-   if (stat("Sources.gz",&Buf) == 0 || stat("Sources",&Buf) == 0)
+   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);
       SList.push_back(CD);
-      
+
       // Continue down if thorough is given
       // Continue down if thorough is given
       if (_config->FindB("APT::CDROM::Thorough",false) == false)
       if (_config->FindB("APT::CDROM::Thorough",false) == false)
 	 return true;
 	 return true;
+      break;
    }
    }
 
 
-   // see if we find translatin indexes
-   if (stat("i18n",&Buf) == 0)
+   // 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;
-	    if(file.substr(file.size()-3,file.size()) == ".gz")
-	       file = file.substr(0,file.size()-3);
-	    TransList.push_back(CD+"i18n/"+ file);
+	    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());
@@ -249,30 +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;
-      if (stat((List[I] + Name).c_str(),&Buf) != 0 &&
-	  stat((List[I] + Name + ".gz").c_str(),&Buf) != 0)
-	 _error->Errno("stat","Failed to stat %s%s",List[I].c_str(),
-		       Name);
-      Inodes[I] = Buf.st_ino;
-   }
-   
-   if (_error->PendingError() == true) {
-      delete[] Inodes;
-      return false;
+      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 = std::string(List[I]).append(Name).append(c->Extension);
+         if (stat(filename.c_str(), &Buf) != 0)
+	    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;
+      }
    }
    }
-   
+
    // 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
@@ -298,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		/*{{{*/
@@ -389,7 +430,8 @@ bool pkgCdrom::WriteDatabase(Configuration &Cnf)
 
 
    Out.close();
    Out.close();
    
    
-   link(DFile.c_str(),string(DFile + '~').c_str());
+   if (FileExists(DFile) == true && link(DFile.c_str(),string(DFile + '~').c_str()) != 0)
+      return _error->Errno("link", "Failed to link %s to %s~", DFile.c_str(), DFile.c_str());
    if (rename(NewFile.c_str(),DFile.c_str()) != 0)
    if (rename(NewFile.c_str(),DFile.c_str()) != 0)
       return _error->Errno("rename","Failed to rename %s.new to %s",
       return _error->Errno("rename","Failed to rename %s.new to %s",
 			   DFile.c_str(),DFile.c_str());
 			   DFile.c_str(),DFile.c_str());
@@ -656,7 +698,8 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
       return false;
       return false;
    }
    }
 
 
-   chdir(StartDir.c_str());
+   if (chdir(StartDir.c_str()) != 0)
+      return _error->Errno("chdir","Unable to change to %s", StartDir.c_str());
 
 
    if (_config->FindB("Debug::aptcdrom",false) == true)
    if (_config->FindB("Debug::aptcdrom",false) == true)
    {
    {
@@ -677,7 +720,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("");
@@ -874,9 +923,7 @@ pkgUdevCdromDevices::Dlopen()                     		        /*{{{*/
    libudev_handle = h;
    libudev_handle = h;
    udev_new = (udev* (*)(void)) dlsym(h, "udev_new");
    udev_new = (udev* (*)(void)) dlsym(h, "udev_new");
    udev_enumerate_add_match_property = (int (*)(udev_enumerate*, const char*, const char*))dlsym(h, "udev_enumerate_add_match_property");
    udev_enumerate_add_match_property = (int (*)(udev_enumerate*, const char*, const char*))dlsym(h, "udev_enumerate_add_match_property");
-#if 0 // FIXME: uncomment on next ABI break
    udev_enumerate_add_match_sysattr = (int (*)(udev_enumerate*, const char*, const char*))dlsym(h, "udev_enumerate_add_match_sysattr");
    udev_enumerate_add_match_sysattr = (int (*)(udev_enumerate*, const char*, const char*))dlsym(h, "udev_enumerate_add_match_sysattr");
-#endif
    udev_enumerate_scan_devices = (int (*)(udev_enumerate*))dlsym(h, "udev_enumerate_scan_devices");
    udev_enumerate_scan_devices = (int (*)(udev_enumerate*))dlsym(h, "udev_enumerate_scan_devices");
    udev_enumerate_get_list_entry = (udev_list_entry* (*)(udev_enumerate*))dlsym(h, "udev_enumerate_get_list_entry");
    udev_enumerate_get_list_entry = (udev_list_entry* (*)(udev_enumerate*))dlsym(h, "udev_enumerate_get_list_entry");
    udev_device_new_from_syspath = (udev_device* (*)(udev*, const char*))dlsym(h, "udev_device_new_from_syspath");
    udev_device_new_from_syspath = (udev_device* (*)(udev*, const char*))dlsym(h, "udev_device_new_from_syspath");
@@ -890,10 +937,8 @@ pkgUdevCdromDevices::Dlopen()                     		        /*{{{*/
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
                                                                         /*{{{*/
                                                                         /*{{{*/
-// compatiblity only with the old API/ABI, can be removed on the next
-// ABI break
+// convenience interface, this will just call ScanForRemovable
 vector<CdromDevice>
 vector<CdromDevice>
 pkgUdevCdromDevices::Scan()
 pkgUdevCdromDevices::Scan()
 { 
 { 
@@ -918,10 +963,6 @@ pkgUdevCdromDevices::ScanForRemovable(bool CdromOnly)
    if (CdromOnly)
    if (CdromOnly)
       udev_enumerate_add_match_property(enumerate, "ID_CDROM", "1");
       udev_enumerate_add_match_property(enumerate, "ID_CDROM", "1");
    else {
    else {
-#if 1 // FIXME: remove the next two lines on the next ABI break
-      int (*udev_enumerate_add_match_sysattr)(struct udev_enumerate *udev_enumerate, const char *property, const char *value);
-      udev_enumerate_add_match_sysattr = (int (*)(udev_enumerate*, const char*, const char*))dlsym(libudev_handle, "udev_enumerate_add_match_sysattr");
-#endif
       udev_enumerate_add_match_sysattr(enumerate, "removable", "1");
       udev_enumerate_add_match_sysattr(enumerate, "removable", "1");
    }
    }
 
 

+ 26 - 24
apt-pkg/cdrom.h

@@ -1,12 +1,16 @@
 #ifndef PKGLIB_CDROM_H
 #ifndef PKGLIB_CDROM_H
 #define PKGLIB_CDROM_H
 #define PKGLIB_CDROM_H
 
 
-#include<apt-pkg/init.h>
 #include<string>
 #include<string>
 #include<vector>
 #include<vector>
 
 
-
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/init.h>
 using namespace std;
 using namespace std;
+#endif
+
+class Configuration;
+class OpProgress;
 
 
 class pkgCdromStatus							/*{{{*/
 class pkgCdromStatus							/*{{{*/
 {
 {
@@ -20,12 +24,12 @@ class pkgCdromStatus							/*{{{*/
    // total steps
    // total steps
    virtual void SetTotal(int total) { totalSteps = total; };
    virtual void SetTotal(int total) { totalSteps = total; };
    // update steps, will be called regularly as a "pulse"
    // update steps, will be called regularly as a "pulse"
-   virtual void Update(string text="", int current=0) = 0;
+   virtual void Update(std::string text="", int current=0) = 0;
    
    
    // ask for cdrom insert
    // ask for cdrom insert
    virtual bool ChangeCdrom() = 0;
    virtual bool ChangeCdrom() = 0;
    // ask for cdrom name
    // ask for cdrom name
-   virtual bool AskCdromName(string &Name) = 0;
+   virtual bool AskCdromName(std::string &Name) = 0;
    // Progress indicator for the Index rewriter
    // Progress indicator for the Index rewriter
    virtual OpProgress* GetOpProgress() {return NULL; };
    virtual OpProgress* GetOpProgress() {return NULL; };
 };
 };
@@ -47,22 +51,22 @@ class pkgCdrom								/*{{{*/
    };
    };
 
 
 
 
-   bool FindPackages(string CD,
-		     vector<string> &List,
-		     vector<string> &SList, 
-		     vector<string> &SigList,
-		     vector<string> &TransList,
-		     string &InfoDir, pkgCdromStatus *log,
+   bool FindPackages(std::string CD,
+		     std::vector<std::string> &List,
+		     std::vector<std::string> &SList, 
+		     std::vector<std::string> &SigList,
+		     std::vector<std::string> &TransList,
+		     std::string &InfoDir, pkgCdromStatus *log,
 		     unsigned int Depth = 0);
 		     unsigned int Depth = 0);
-   bool DropBinaryArch(vector<string> &List);
-   bool DropRepeats(vector<string> &List,const char *Name);
-   void ReduceSourcelist(string CD,vector<string> &List);
+   bool DropBinaryArch(std::vector<std::string> &List);
+   bool DropRepeats(std::vector<std::string> &List,const char *Name);
+   void ReduceSourcelist(std::string CD,std::vector<std::string> &List);
    bool WriteDatabase(Configuration &Cnf);
    bool WriteDatabase(Configuration &Cnf);
-   bool WriteSourceList(string Name,vector<string> &List,bool Source);
-   int Score(string Path);
+   bool WriteSourceList(std::string Name,std::vector<std::string> &List,bool Source);
+   int Score(std::string Path);
 
 
  public:
  public:
-   bool Ident(string &ident, pkgCdromStatus *log);
+   bool Ident(std::string &ident, pkgCdromStatus *log);
    bool Add(pkgCdromStatus *log);
    bool Add(pkgCdromStatus *log);
 };
 };
 									/*}}}*/
 									/*}}}*/
@@ -71,9 +75,9 @@ class pkgCdrom								/*{{{*/
 // class that uses libudev to find cdrom/removable devices dynamically
 // class that uses libudev to find cdrom/removable devices dynamically
 struct CdromDevice							/*{{{*/
 struct CdromDevice							/*{{{*/
 {
 {
-   string DeviceName;
+   std::string DeviceName;
    bool Mounted;
    bool Mounted;
-   string MountPath;
+   std::string MountPath;
 };
 };
 									/*}}}*/
 									/*}}}*/
 class pkgUdevCdromDevices						/*{{{*/
 class pkgUdevCdromDevices						/*{{{*/
@@ -92,9 +96,7 @@ class pkgUdevCdromDevices						/*{{{*/
    struct udev_enumerate *(*udev_enumerate_new) (struct udev *udev);
    struct udev_enumerate *(*udev_enumerate_new) (struct udev *udev);
    struct udev_list_entry *(*udev_list_entry_get_next)(struct udev_list_entry *list_entry);
    struct udev_list_entry *(*udev_list_entry_get_next)(struct udev_list_entry *list_entry);
    const char* (*udev_device_get_property_value)(struct udev_device *udev_device, const char *key);
    const char* (*udev_device_get_property_value)(struct udev_device *udev_device, const char *key);
-#if 0 // FIXME: uncomment on next ABI break
    int (*udev_enumerate_add_match_sysattr)(struct udev_enumerate *udev_enumerate, const char *property, const char *value);
    int (*udev_enumerate_add_match_sysattr)(struct udev_enumerate *udev_enumerate, const char *property, const char *value);
-#endif 
    // end libudev dlopen
    // end libudev dlopen
    
    
  public:
  public:
@@ -104,11 +106,11 @@ class pkgUdevCdromDevices						/*{{{*/
    // try to open 
    // try to open 
    bool Dlopen();
    bool Dlopen();
 
 
-   // this is the new interface
-   vector<CdromDevice> ScanForRemovable(bool CdromOnly);
-   // FIXME: compat with the old interface/API/ABI only
-   vector<CdromDevice> Scan();
+   // convenience interface, this will just call ScanForRemovable
+   // with "APT::cdrom::CdromOnly"
+   std::vector<CdromDevice> Scan();
 
 
+   std::vector<CdromDevice> ScanForRemovable(bool CdromOnly);
 };
 };
 									/*}}}*/
 									/*}}}*/
 
 

+ 17 - 11
apt-pkg/clean.cc

@@ -8,23 +8,26 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Includes								/*{{{*/
 // Includes								/*{{{*/
+#include<config.h>
+
 #include <apt-pkg/clean.h>
 #include <apt-pkg/clean.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/aptconfiguration.h>
-
-#include <apti18n.h>    
+#include <apt-pkg/fileutl.h>
 
 
 #include <dirent.h>
 #include <dirent.h>
 #include <sys/stat.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <unistd.h>
+
+#include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 // ArchiveCleaner::Go - Perform smart cleanup of the archive		/*{{{*/
 // ArchiveCleaner::Go - Perform smart cleanup of the archive		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Scan the directory for files to erase, we check the version information
 /* Scan the directory for files to erase, we check the version information
    against our database to see if it is interesting */
    against our database to see if it is interesting */
-bool pkgArchiveCleaner::Go(string Dir,pkgCache &Cache)
+bool pkgArchiveCleaner::Go(std::string Dir,pkgCache &Cache)
 {
 {
    bool CleanInstalled = _config->FindB("APT::Clean-Installed",true);
    bool CleanInstalled = _config->FindB("APT::Clean-Installed",true);
       
       
@@ -32,7 +35,7 @@ bool pkgArchiveCleaner::Go(string Dir,pkgCache &Cache)
    if (D == 0)
    if (D == 0)
       return _error->Errno("opendir",_("Unable to read %s"),Dir.c_str());
       return _error->Errno("opendir",_("Unable to read %s"),Dir.c_str());
 
 
-   string StartDir = SafeGetCWD();
+   std::string StartDir = SafeGetCWD();
    if (chdir(Dir.c_str()) != 0)
    if (chdir(Dir.c_str()) != 0)
    {
    {
       closedir(D);
       closedir(D);
@@ -51,9 +54,11 @@ bool pkgArchiveCleaner::Go(string Dir,pkgCache &Cache)
       struct stat St;
       struct stat St;
       if (stat(Dir->d_name,&St) != 0)
       if (stat(Dir->d_name,&St) != 0)
       {
       {
-	 chdir(StartDir.c_str());
+	 _error->Errno("stat",_("Unable to stat %s."),Dir->d_name);
 	 closedir(D);
 	 closedir(D);
-	 return _error->Errno("stat",_("Unable to stat %s."),Dir->d_name);
+	 if (chdir(StartDir.c_str()) != 0)
+	    return _error->Errno("chdir", _("Unable to change to %s"), StartDir.c_str());
+	 return false;
       }
       }
       
       
       // Grab the package name
       // Grab the package name
@@ -61,21 +66,21 @@ bool pkgArchiveCleaner::Go(string Dir,pkgCache &Cache)
       for (; *I != 0 && *I != '_';I++);
       for (; *I != 0 && *I != '_';I++);
       if (*I != '_')
       if (*I != '_')
 	 continue;
 	 continue;
-      string Pkg = DeQuoteString(string(Dir->d_name,I-Dir->d_name));
+      std::string Pkg = DeQuoteString(std::string(Dir->d_name,I-Dir->d_name));
 
 
       // Grab the version
       // Grab the version
       const char *Start = I + 1;
       const char *Start = I + 1;
       for (I = Start; *I != 0 && *I != '_';I++);
       for (I = Start; *I != 0 && *I != '_';I++);
       if (*I != '_')
       if (*I != '_')
 	 continue;
 	 continue;
-      string Ver = DeQuoteString(string(Start,I-Start));
+      std::string Ver = DeQuoteString(std::string(Start,I-Start));
   
   
       // Grab the arch
       // Grab the arch
       Start = I + 1;
       Start = I + 1;
       for (I = Start; *I != 0 && *I != '.' ;I++);
       for (I = Start; *I != 0 && *I != '.' ;I++);
       if (*I != '.')
       if (*I != '.')
 	 continue;
 	 continue;
-      string const Arch = DeQuoteString(string(Start,I-Start));
+      std::string const Arch = DeQuoteString(std::string(Start,I-Start));
       
       
       if (APT::Configuration::checkArchitecture(Arch) == false)
       if (APT::Configuration::checkArchitecture(Arch) == false)
 	 continue;
 	 continue;
@@ -112,8 +117,9 @@ bool pkgArchiveCleaner::Go(string Dir,pkgCache &Cache)
       Erase(Dir->d_name,Pkg,Ver,St);
       Erase(Dir->d_name,Pkg,Ver,St);
    };
    };
    
    
-   chdir(StartDir.c_str());
    closedir(D);
    closedir(D);
-   return true;   
+   if (chdir(StartDir.c_str()) != 0)
+      return _error->Errno("chdir", _("Unable to change to %s"), StartDir.c_str());
+   return true;
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 5 - 2
apt-pkg/clean.h

@@ -15,13 +15,16 @@
 
 
 class pkgArchiveCleaner
 class pkgArchiveCleaner
 {
 {
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+
    protected:
    protected:
    
    
-   virtual void Erase(const char * /*File*/,string /*Pkg*/,string /*Ver*/,struct stat & /*St*/) {};
+   virtual void Erase(const char * /*File*/,std::string /*Pkg*/,std::string /*Ver*/,struct stat & /*St*/) {};
 
 
    public:   
    public:   
    
    
-   bool Go(string Dir,pkgCache &Cache);
+   bool Go(std::string Dir,pkgCache &Cache);
    virtual ~pkgArchiveCleaner() {};
    virtual ~pkgArchiveCleaner() {};
 };
 };
 
 

+ 6 - 2
apt-pkg/contrib/cdromutl.cc

@@ -10,6 +10,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include<config.h>
+
 #include <apt-pkg/cdromutl.h>
 #include <apt-pkg/cdromutl.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/md5.h>
 #include <apt-pkg/md5.h>
@@ -17,8 +19,6 @@
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 
 
-#include <apti18n.h>
-    
 #include <sys/wait.h>
 #include <sys/wait.h>
 #include <sys/statvfs.h>
 #include <sys/statvfs.h>
 #include <dirent.h>
 #include <dirent.h>
@@ -26,8 +26,12 @@
 #include <sys/stat.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <stdio.h>
+
+#include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 
 
+using std::string;
+
 // IsMounted - Returns true if the mount point is mounted		/*{{{*/
 // IsMounted - Returns true if the mount point is mounted		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This is a simple algorithm that should always work, we stat the mount point
 /* This is a simple algorithm that should always work, we stat the mount point

+ 7 - 5
apt-pkg/contrib/cdromutl.h

@@ -12,13 +12,15 @@
 
 
 #include <string>
 #include <string>
 
 
+#ifndef APT_8_CLEANER_HEADERS
 using std::string;
 using std::string;
+#endif
 
 
 // mount cdrom, DeviceName (e.g. /dev/sr0) is optional
 // mount cdrom, DeviceName (e.g. /dev/sr0) is optional
-bool MountCdrom(string Path, string DeviceName="");
-bool UnmountCdrom(string Path);
-bool IdentCdrom(string CD,string &Res,unsigned int Version = 2);
-bool IsMounted(string &Path);
-string FindMountPointForDevice(const char *device);
+bool MountCdrom(std::string Path, std::string DeviceName="");
+bool UnmountCdrom(std::string Path);
+bool IdentCdrom(std::string CD,std::string &Res,unsigned int Version = 2);
+bool IsMounted(std::string &Path);
+std::string FindMountPointForDevice(const char *device);
 
 
 #endif
 #endif

+ 4 - 1
apt-pkg/contrib/cmndline.cc

@@ -11,11 +11,14 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include files							/*{{{*/
 // Include files							/*{{{*/
+#include<config.h>
+
+#include <apt-pkg/configuration.h>
 #include <apt-pkg/cmndline.h>
 #include <apt-pkg/cmndline.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 
 
-#include <apti18n.h>    
+#include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 using namespace std;
 using namespace std;
 
 

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

@@ -44,9 +44,11 @@
 #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>
 #include <apt-pkg/configuration.h>
+#endif
+
+class Configuration;
 
 
 class CommandLine
 class CommandLine
 {
 {

+ 12 - 3
apt-pkg/contrib/configuration.cc

@@ -15,16 +15,19 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include files							/*{{{*/
 // Include files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
-#include <apti18n.h>
 
 
 #include <vector>
 #include <vector>
 #include <fstream>
 #include <fstream>
 #include <iostream>
 #include <iostream>
 
 
+#include <apti18n.h>
+
 using namespace std;
 using namespace std;
 									/*}}}*/
 									/*}}}*/
 
 
@@ -182,8 +185,14 @@ string Configuration::FindFile(const char *Name,const char *Default) const
    }
    }
    
    
    string val = Itm->Value;
    string val = Itm->Value;
-   while (Itm->Parent != 0 && Itm->Parent->Value.empty() == false)
-   {	 
+   while (Itm->Parent != 0)
+   {
+      if (Itm->Parent->Value.empty() == true)
+      {
+	 Itm = Itm->Parent;
+	 continue;
+      }
+
       // Absolute
       // Absolute
       if (val.length() >= 1 && val[0] == '/')
       if (val.length() >= 1 && val[0] == '/')
          break;
          break;

+ 24 - 22
apt-pkg/contrib/configuration.h

@@ -34,7 +34,9 @@
 #include <vector>
 #include <vector>
 #include <iostream>
 #include <iostream>
 
 
+#ifndef APT_8_CLEANER_HEADERS
 using std::string;
 using std::string;
+#endif
 
 
 class Configuration
 class Configuration
 {
 {
@@ -42,13 +44,13 @@ class Configuration
    
    
    struct Item
    struct Item
    {
    {
-      string Value;
-      string Tag;
+      std::string Value;
+      std::string Tag;
       Item *Parent;
       Item *Parent;
       Item *Child;
       Item *Child;
       Item *Next;
       Item *Next;
       
       
-      string FullTag(const Item *Stop = 0) const;
+      std::string FullTag(const Item *Stop = 0) const;
       
       
       Item() : Parent(0), Child(0), Next(0) {};
       Item() : Parent(0), Child(0), Next(0) {};
    };
    };
@@ -67,35 +69,35 @@ class Configuration
    
    
    public:
    public:
 
 
-   string Find(const char *Name,const char *Default = 0) const;
-   string Find(string const &Name,const char *Default = 0) const {return Find(Name.c_str(),Default);};
-   string Find(string const &Name, string const &Default) const {return Find(Name.c_str(),Default.c_str());};
-   string FindFile(const char *Name,const char *Default = 0) const;
-   string FindDir(const char *Name,const char *Default = 0) const;
-   std::vector<string> FindVector(const char *Name) const;
-   std::vector<string> FindVector(string const &Name) const { return FindVector(Name.c_str()); };
+   std::string Find(const char *Name,const char *Default = 0) const;
+   std::string Find(std::string const &Name,const char *Default = 0) const {return Find(Name.c_str(),Default);};
+   std::string Find(std::string const &Name, std::string const &Default) const {return Find(Name.c_str(),Default.c_str());};
+   std::string FindFile(const char *Name,const char *Default = 0) const;
+   std::string FindDir(const char *Name,const char *Default = 0) const;
+   std::vector<std::string> FindVector(const char *Name) const;
+   std::vector<std::string> FindVector(std::string const &Name) const { return FindVector(Name.c_str()); };
    int FindI(const char *Name,int const &Default = 0) const;
    int FindI(const char *Name,int const &Default = 0) const;
-   int FindI(string const &Name,int const &Default = 0) const {return FindI(Name.c_str(),Default);};
+   int FindI(std::string const &Name,int const &Default = 0) const {return FindI(Name.c_str(),Default);};
    bool FindB(const char *Name,bool const &Default = false) const;
    bool FindB(const char *Name,bool const &Default = false) const;
-   bool FindB(string const &Name,bool const &Default = false) const {return FindB(Name.c_str(),Default);};
-   string FindAny(const char *Name,const char *Default = 0) const;
+   bool FindB(std::string const &Name,bool const &Default = false) const {return FindB(Name.c_str(),Default);};
+   std::string FindAny(const char *Name,const char *Default = 0) const;
 	      
 	      
-   inline void Set(const string &Name,const string &Value) {Set(Name.c_str(),Value);};
-   void CndSet(const char *Name,const string &Value);
+   inline void Set(const std::string &Name,const std::string &Value) {Set(Name.c_str(),Value);};
+   void CndSet(const char *Name,const std::string &Value);
    void CndSet(const char *Name,const int Value);
    void CndSet(const char *Name,const int Value);
-   void Set(const char *Name,const string &Value);
+   void Set(const char *Name,const std::string &Value);
    void Set(const char *Name,const int &Value);
    void Set(const char *Name,const int &Value);
    
    
-   inline bool Exists(const string &Name) const {return Exists(Name.c_str());};
+   inline bool Exists(const std::string &Name) const {return Exists(Name.c_str());};
    bool Exists(const char *Name) const;
    bool Exists(const char *Name) const;
    bool ExistsAny(const char *Name) const;
    bool ExistsAny(const char *Name) const;
 
 
    // clear a whole tree
    // clear a whole tree
-   void Clear(const string &Name);
+   void Clear(const std::string &Name);
 
 
    // remove a certain value from a list (e.g. the list of "APT::Keep-Fds")
    // remove a certain value from a list (e.g. the list of "APT::Keep-Fds")
-   void Clear(string const &List, string const &Value);
-   void Clear(string const &List, int const &Value);
+   void Clear(std::string const &List, std::string const &Value);
+   void Clear(std::string const &List, int const &Value);
 
 
    inline const Item *Tree(const char *Name) const {return Lookup(Name);};
    inline const Item *Tree(const char *Name) const {return Lookup(Name);};
 
 
@@ -127,11 +129,11 @@ class Configuration
 
 
 extern Configuration *_config;
 extern Configuration *_config;
 
 
-bool ReadConfigFile(Configuration &Conf,const string &FName,
+bool ReadConfigFile(Configuration &Conf,const std::string &FName,
 		    bool const &AsSectional = false,
 		    bool const &AsSectional = false,
 		    unsigned const &Depth = 0);
 		    unsigned const &Depth = 0);
 
 
-bool ReadConfigDir(Configuration &Conf,const string &Dir,
+bool ReadConfigDir(Configuration &Conf,const std::string &Dir,
 		   bool const &AsSectional = false,
 		   bool const &AsSectional = false,
 		   unsigned const &Depth = 0);
 		   unsigned const &Depth = 0);
 
 

+ 3 - 1
apt-pkg/contrib/crc-16.cc

@@ -15,6 +15,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/crc-16.h>
 #include <apt-pkg/crc-16.h>
 									/*}}}*/
 									/*}}}*/
 
 
@@ -63,7 +65,7 @@ static unsigned short const crc16_table[256] =
 /* Recompute the FCS with one more character appended. */
 /* Recompute the FCS with one more character appended. */
 #define CalcFCS(fcs, c) (((fcs) >> 8) ^ crc16_table[((fcs) ^ (c)) & 0xff])
 #define CalcFCS(fcs, c) (((fcs) >> 8) ^ crc16_table[((fcs) ^ (c)) & 0xff])
 unsigned short AddCRC16(unsigned short fcs, void const *Buf,
 unsigned short AddCRC16(unsigned short fcs, void const *Buf,
-			unsigned long len) 
+			unsigned long long len)
 {
 {
    unsigned char const *buf = (unsigned char const *)Buf;
    unsigned char const *buf = (unsigned char const *)Buf;
    while (len--)
    while (len--)

+ 1 - 1
apt-pkg/contrib/crc-16.h

@@ -12,6 +12,6 @@
 
 
 #define INIT_FCS  0xffff
 #define INIT_FCS  0xffff
 unsigned short AddCRC16(unsigned short fcs, void const *buf,
 unsigned short AddCRC16(unsigned short fcs, void const *buf,
-			unsigned long len);
+			unsigned long long len);
 
 
 #endif
 #endif

+ 3 - 2
apt-pkg/contrib/error.cc

@@ -13,6 +13,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 
 
 #include <iostream>
 #include <iostream>
@@ -24,8 +26,7 @@
 #include <string>
 #include <string>
 #include <cstring>
 #include <cstring>
 
 
-#include "config.h"
-   									/*}}}*/
+									/*}}}*/
 
 
 // Global Error Object							/*{{{*/
 // Global Error Object							/*{{{*/
 /* If the implementation supports posix threads then the accessor function
 /* If the implementation supports posix threads then the accessor function

Разлика између датотеке није приказан због своје велике величине
+ 702 - 101
apt-pkg/contrib/fileutl.cc


+ 105 - 43
apt-pkg/contrib/fileutl.h

@@ -22,82 +22,143 @@
 #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
 
 
-using std::string;
-
+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;
-   string FileName;
-   string TemporaryFileName;
-   gzFile gz;
+   std::string FileName;
+   std::string TemporaryFileName;
 
 
    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 Size,bool AllowEof)
+   inline bool Read(void *To,unsigned long long Size,bool AllowEof)
    {
    {
-      unsigned long Jnk;
+      unsigned long long Jnk;
       if (AllowEof)
       if (AllowEof)
 	 return Read(To,Size,&Jnk);
 	 return Read(To,Size,&Jnk);
       return Read(To,Size);
       return Read(To,Size);
    }   
    }   
-   bool Read(void *To,unsigned long Size,unsigned long *Actual = 0);
-   bool Write(const void *From,unsigned long Size);
-   bool Seek(unsigned long To);
-   bool Skip(unsigned long To);
-   bool Truncate(unsigned long To);
-   unsigned long Tell();
-   unsigned long Size();
-   unsigned long FileSize();
-   bool Open(string FileName,OpenMode Mode,unsigned long Perms = 0666);
-   bool OpenDescriptor(int Fd, OpenMode Mode, bool AutoClose=false);
+   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 static Write(int Fd, const void *From, unsigned long long Size);
+   bool Seek(unsigned long long To);
+   bool Skip(unsigned long long To);
+   bool Truncate(unsigned long long To);
+   unsigned long long Tell();
+   unsigned long long Size();
+   unsigned long long FileSize();
+   time_t ModificationTime();
+
+   /* 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.
+      This shouldn't happen all to often for the indexes, but deb's might be…
+      And as the auto-conversation converts a 'unsigned long *' to a 'bool'
+      instead of 'unsigned long long *' we need to provide this explicitely -
+      otherwise applications magically start to fail… */
+   __deprecated bool Read(void *To,unsigned long long Size,unsigned long *Actual)
+   {
+	unsigned long long R;
+	bool const T = Read(To, Size, &R);
+	*Actual = R;
+	return T;
+   }
+
+   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 gzFile gzFd() {return gz;};
+   inline void Fd(int fd) { OpenDescriptor(fd, ReadWrite);};
+   __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 string &Name() {return FileName;};
+   inline bool IsCompressed() {return (Flags & Compressed) == Compressed;};
+   inline std::string &Name() {return FileName;};
    
    
-   FileFd(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, 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,Perms);
+      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);
 bool CopyFile(FileFd &From,FileFd &To);
 bool CopyFile(FileFd &From,FileFd &To);
-int GetLock(string File,bool Errors = true);
-bool FileExists(string File);
-bool RealFileExists(string File);
-bool DirectoryExists(string const &Path) __attrib_const;
-bool CreateDirectory(string const &Parent, string const &Path);
-time_t GetModificationTime(string const &Path);
+int GetLock(std::string File,bool Errors = true);
+bool FileExists(std::string File);
+bool RealFileExists(std::string File);
+bool DirectoryExists(std::string const &Path) __attrib_const;
+bool CreateDirectory(std::string const &Parent, std::string const &Path);
+time_t GetModificationTime(std::string const &Path);
 
 
 /** \brief Ensure the existence of the given Path
 /** \brief Ensure the existence of the given Path
  *
  *
@@ -105,13 +166,14 @@ time_t GetModificationTime(string const &Path);
  *  /apt/ will be removed before CreateDirectory call.
  *  /apt/ will be removed before CreateDirectory call.
  *  \param Path which should exist after (successful) call
  *  \param Path which should exist after (successful) call
  */
  */
-bool CreateAPTDirectoryIfNeeded(string const &Parent, string const &Path);
+bool CreateAPTDirectoryIfNeeded(std::string const &Parent, std::string const &Path);
 
 
-std::vector<string> GetListOfFilesInDir(string const &Dir, string const &Ext,
+std::vector<std::string> GetListOfFilesInDir(std::string const &Dir, std::string const &Ext,
 					bool const &SortList, bool const &AllowNoExt=false);
 					bool const &SortList, bool const &AllowNoExt=false);
-std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> const &Ext,
+std::vector<std::string> GetListOfFilesInDir(std::string const &Dir, std::vector<std::string> const &Ext,
 					bool const &SortList);
 					bool const &SortList);
-string SafeGetCWD();
+std::vector<std::string> GetListOfFilesInDir(std::string const &Dir, bool SortList);
+std::string SafeGetCWD();
 void SetCloseExec(int Fd,bool Close);
 void SetCloseExec(int Fd,bool Close);
 void SetNonBlock(int Fd,bool Block);
 void SetNonBlock(int Fd,bool Block);
 bool WaitFd(int Fd,bool write = false,unsigned long timeout = 0);
 bool WaitFd(int Fd,bool write = false,unsigned long timeout = 0);
@@ -119,10 +181,10 @@ pid_t ExecFork();
 bool ExecWait(pid_t Pid,const char *Name,bool Reap = false);
 bool ExecWait(pid_t Pid,const char *Name,bool Reap = false);
 
 
 // File string manipulators
 // File string manipulators
-string flNotDir(string File);
-string flNotFile(string File);
-string flNoLink(string File);
-string flExtension(string File);
-string flCombine(string Dir,string File);
+std::string flNotDir(std::string File);
+std::string flNotFile(std::string File);
+std::string flNoLink(std::string File);
+std::string flExtension(std::string File);
+std::string flCombine(std::string Dir,std::string File);
 
 
 #endif
 #endif

+ 78 - 35
apt-pkg/contrib/hashes.cc

@@ -11,39 +11,41 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/hashes.h>
 #include <apt-pkg/hashes.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/macros.h>
 #include <apt-pkg/macros.h>
 
 
-#include <unistd.h>    
+#include <unistd.h>
 #include <string>
 #include <string>
 #include <iostream>
 #include <iostream>
 									/*}}}*/
 									/*}}}*/
 
 
 const char* HashString::_SupportedHashes[] = 
 const char* HashString::_SupportedHashes[] = 
 {
 {
-   "SHA256", "SHA1", "MD5Sum", NULL
+   "SHA512", "SHA256", "SHA1", "MD5Sum", NULL
 };
 };
 
 
 HashString::HashString()
 HashString::HashString()
 {
 {
 }
 }
 
 
-HashString::HashString(string Type, string Hash) : Type(Type), Hash(Hash)
+HashString::HashString(std::string Type, std::string Hash) : Type(Type), Hash(Hash)
 {
 {
 }
 }
 
 
-HashString::HashString(string StringedHash)				/*{{{*/
+HashString::HashString(std::string StringedHash)			/*{{{*/
 {
 {
    // legacy: md5sum without "MD5Sum:" prefix
    // legacy: md5sum without "MD5Sum:" prefix
-   if (StringedHash.find(":") == string::npos && StringedHash.size() == 32)
+   if (StringedHash.find(":") == std::string::npos && StringedHash.size() == 32)
    {
    {
       Type = "MD5Sum";
       Type = "MD5Sum";
       Hash = StringedHash;
       Hash = StringedHash;
       return;
       return;
    }
    }
-   string::size_type pos = StringedHash.find(":");
+   std::string::size_type pos = StringedHash.find(":");
    Type = StringedHash.substr(0,pos);
    Type = StringedHash.substr(0,pos);
    Hash = StringedHash.substr(pos+1, StringedHash.size() - pos);
    Hash = StringedHash.substr(pos+1, StringedHash.size() - pos);
 
 
@@ -51,29 +53,34 @@ HashString::HashString(string StringedHash)				/*{{{*/
       std::clog << "HashString(string): " << Type << " : " << Hash << std::endl;
       std::clog << "HashString(string): " << Type << " : " << Hash << std::endl;
 }
 }
 									/*}}}*/
 									/*}}}*/
-bool HashString::VerifyFile(string filename) const			/*{{{*/
+bool HashString::VerifyFile(std::string filename) const			/*{{{*/
 {
 {
-   FileFd fd;
-   MD5Summation MD5;
-   SHA1Summation SHA1;
-   SHA256Summation SHA256;
-   string fileHash;
+   std::string fileHash;
 
 
    FileFd Fd(filename, FileFd::ReadOnly);
    FileFd Fd(filename, FileFd::ReadOnly);
-   if(Type == "MD5Sum") 
+   if(Type == "MD5Sum")
    {
    {
-      MD5.AddFD(Fd.Fd(), Fd.Size());
-      fileHash = (string)MD5.Result();
-   } 
+      MD5Summation MD5;
+      MD5.AddFD(Fd);
+      fileHash = (std::string)MD5.Result();
+   }
    else if (Type == "SHA1")
    else if (Type == "SHA1")
    {
    {
-      SHA1.AddFD(Fd.Fd(), Fd.Size());
-      fileHash = (string)SHA1.Result();
-   } 
-   else if (Type == "SHA256") 
+      SHA1Summation SHA1;
+      SHA1.AddFD(Fd);
+      fileHash = (std::string)SHA1.Result();
+   }
+   else if (Type == "SHA256")
    {
    {
-      SHA256.AddFD(Fd.Fd(), Fd.Size());
-      fileHash = (string)SHA256.Result();
+      SHA256Summation SHA256;
+      SHA256.AddFD(Fd);
+      fileHash = (std::string)SHA256.Result();
+   }
+   else if (Type == "SHA512")
+   {
+      SHA512Summation SHA512;
+      SHA512.AddFD(Fd);
+      fileHash = (std::string)SHA512.Result();
    }
    }
    Fd.Close();
    Fd.Close();
 
 
@@ -93,34 +100,70 @@ bool HashString::empty() const
    return (Type.empty() || Hash.empty());
    return (Type.empty() || Hash.empty());
 }
 }
 
 
-string HashString::toStr() const
+std::string HashString::toStr() const
 {
 {
-   return Type+string(":")+Hash;
+   return Type + std::string(":") + Hash;
 }
 }
 
 
 // Hashes::AddFD - Add the contents of the FD				/*{{{*/
 // Hashes::AddFD - Add the contents of the FD				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-bool Hashes::AddFD(int Fd,unsigned long Size)
+bool Hashes::AddFD(int const Fd,unsigned long long Size, bool const addMD5,
+		   bool const addSHA1, bool const addSHA256, bool const addSHA512)
 {
 {
    unsigned char Buf[64*64];
    unsigned char Buf[64*64];
-   int Res = 0;
+   ssize_t Res = 0;
    int ToEOF = (Size == 0);
    int ToEOF = (Size == 0);
    while (Size != 0 || ToEOF)
    while (Size != 0 || ToEOF)
    {
    {
-      unsigned n = sizeof(Buf);
-      if (!ToEOF) n = min(Size,(unsigned long)n);
+      unsigned long long n = sizeof(Buf);
+      if (!ToEOF) n = std::min(Size, n);
       Res = read(Fd,Buf,n);
       Res = read(Fd,Buf,n);
-      if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read
-         return false;
+      if (Res < 0 || (!ToEOF && Res != (ssize_t) n)) // error, or short read
+	 return false;
       if (ToEOF && Res == 0) // EOF
       if (ToEOF && Res == 0) // EOF
-         break;
+	 break;
       Size -= Res;
       Size -= Res;
-      MD5.Add(Buf,Res);
-      SHA1.Add(Buf,Res);
-      SHA256.Add(Buf,Res);
+      if (addMD5 == true)
+	 MD5.Add(Buf,Res);
+      if (addSHA1 == true)
+	 SHA1.Add(Buf,Res);
+      if (addSHA256 == true)
+	 SHA256.Add(Buf,Res);
+      if (addSHA512 == true)
+	 SHA512.Add(Buf,Res);
+   }
+   return true;
+}
+bool Hashes::AddFD(FileFd &Fd,unsigned long long Size, bool const addMD5,
+		   bool const addSHA1, bool const addSHA256, bool const addSHA512)
+{
+   unsigned char Buf[64*64];
+   bool const ToEOF = (Size == 0);
+   while (Size != 0 || ToEOF)
+   {
+      unsigned long long n = sizeof(Buf);
+      if (!ToEOF) n = std::min(Size, n);
+      unsigned long long a = 0;
+      if (Fd.Read(Buf, n, &a) == false) // error
+	 return false;
+      if (ToEOF == false)
+      {
+	 if (a != n) // short read
+	    return false;
+      }
+      else if (a == 0) // EOF
+	 break;
+      Size -= a;
+      if (addMD5 == true)
+	 MD5.Add(Buf, a);
+      if (addSHA1 == true)
+	 SHA1.Add(Buf, a);
+      if (addSHA256 == true)
+	 SHA256.Add(Buf, a);
+      if (addSHA512 == true)
+	 SHA512.Add(Buf, a);
    }
    }
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-

+ 23 - 11
apt-pkg/contrib/hashes.h

@@ -16,37 +16,41 @@
 
 
 #include <apt-pkg/md5.h>
 #include <apt-pkg/md5.h>
 #include <apt-pkg/sha1.h>
 #include <apt-pkg/sha1.h>
-#include <apt-pkg/sha256.h>
+#include <apt-pkg/sha2.h>
+#include <apt-pkg/fileutl.h>
 
 
 #include <algorithm>
 #include <algorithm>
 #include <vector>
 #include <vector>
 #include <cstring>
 #include <cstring>
 
 
+
+#ifndef APT_8_CLEANER_HEADERS
 using std::min;
 using std::min;
 using std::vector;
 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
 {
 {
  protected:
  protected:
-   string Type;
-   string Hash;
+   std::string Type;
+   std::string Hash;
    static const char * _SupportedHashes[10];
    static const char * _SupportedHashes[10];
 
 
  public:
  public:
-   HashString(string Type, string Hash);
-   HashString(string StringedHashString);  // init from str as "type:hash"
+   HashString(std::string Type, std::string Hash);
+   HashString(std::string StringedHashString);  // init from str as "type:hash"
    HashString();
    HashString();
 
 
    // get hash type used
    // get hash type used
-   string HashType() { return Type; };
+   std::string HashType() { return Type; };
 
 
    // verify the given filename against the currently loaded hash
    // verify the given filename against the currently loaded hash
-   bool VerifyFile(string filename) const;
+   bool VerifyFile(std::string filename) const;
 
 
    // helper
    // helper
-   string toStr() const;                    // convert to str as "type:hash"
+   std::string toStr() const;                    // convert to str as "type:hash"
    bool empty() const;
    bool empty() const;
 
 
    // return the list of hashes we support
    // return the list of hashes we support
@@ -60,13 +64,21 @@ class Hashes
    MD5Summation MD5;
    MD5Summation MD5;
    SHA1Summation SHA1;
    SHA1Summation SHA1;
    SHA256Summation SHA256;
    SHA256Summation SHA256;
+   SHA512Summation SHA512;
    
    
-   inline bool Add(const unsigned char *Data,unsigned long Size)
+   inline bool Add(const unsigned char *Data,unsigned long long Size)
    {
    {
-      return MD5.Add(Data,Size) && SHA1.Add(Data,Size) && SHA256.Add(Data,Size);
+      return MD5.Add(Data,Size) && SHA1.Add(Data,Size) && SHA256.Add(Data,Size) && SHA512.Add(Data,Size);
    };
    };
    inline bool Add(const char *Data) {return Add((unsigned char *)Data,strlen(Data));};
    inline bool Add(const char *Data) {return Add((unsigned char *)Data,strlen(Data));};
-   bool AddFD(int Fd,unsigned long Size);
+   inline bool AddFD(int const Fd,unsigned long long Size = 0)
+   { return AddFD(Fd, Size, true, true, true, true); };
+   bool AddFD(int const Fd, unsigned long long Size, bool const addMD5,
+	      bool const addSHA1, bool const addSHA256, bool const addSHA512);
+   inline bool AddFD(FileFd &Fd,unsigned long long Size = 0)
+   { return AddFD(Fd, Size, true, true, true, true); };
+   bool AddFD(FileFd &Fd, unsigned long long Size, bool const addMD5,
+	      bool const addSHA1, bool const addSHA256, bool const addSHA512);
    inline bool Add(const unsigned char *Beg,const unsigned char *End) 
    inline bool Add(const unsigned char *Beg,const unsigned char *End) 
                   {return Add(Beg,End-Beg);};
                   {return Add(Beg,End-Beg);};
 };
 };

+ 50 - 0
apt-pkg/contrib/hashsum.cc

@@ -0,0 +1,50 @@
+// Cryptographic API Base
+#include <config.h>
+
+#include <unistd.h>
+#include "hashsum_template.h"
+
+// Summation::AddFD - Add content of file into the checksum		/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool SummationImplementation::AddFD(int const Fd, unsigned long long Size) {
+   unsigned char Buf[64 * 64];
+   ssize_t Res = 0;
+   int ToEOF = (Size == 0);
+   while (Size != 0 || ToEOF)
+   {
+      unsigned long long n = sizeof(Buf);
+      if (!ToEOF) n = std::min(Size, n);
+      Res = read(Fd, Buf, n);
+      if (Res < 0 || (!ToEOF && Res != (ssize_t) n)) // error, or short read
+	 return false;
+      if (ToEOF && Res == 0) // EOF
+	 break;
+      Size -= Res;
+      Add(Buf,Res);
+   }
+   return true;
+}
+bool SummationImplementation::AddFD(FileFd &Fd, unsigned long long Size) {
+   unsigned char Buf[64 * 64];
+   bool ToEOF = (Size == 0);
+   while (Size != 0 || ToEOF)
+   {
+      unsigned long long n = sizeof(Buf);
+      if (!ToEOF) n = std::min(Size, n);
+      unsigned long long a = 0;
+      if (Fd.Read(Buf, n, &a) == false) // error
+	 return false;
+      if (ToEOF == false)
+      {
+	 if (a != n) // short read
+	    return false;
+      }
+      else if (a == 0) // EOF
+	 break;
+      Size -= a;
+      Add(Buf, a);
+   }
+   return true;
+}
+									/*}}}*/

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

@@ -0,0 +1,118 @@
+// -*- mode: cpp; mode: fold -*-
+// Description                                                          /*{{{*/
+// $Id: hashsum_template.h,v 1.3 2001/05/07 05:05:47 jgg Exp $
+/* ######################################################################
+
+   HashSumValueTemplate - Generic Storage for a hash value
+   
+   ##################################################################### */
+                                                                        /*}}}*/
+#ifndef APTPKG_HASHSUM_TEMPLATE_H
+#define APTPKG_HASHSUM_TEMPLATE_H
+
+#include <apt-pkg/fileutl.h>
+
+#include <string>
+#include <cstring>
+#include <algorithm>
+#include <stdint.h>
+
+#include <apt-pkg/strutl.h>
+
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+using std::min;
+#endif
+
+template<int N>
+class HashSumValue
+{
+   unsigned char Sum[N/8];
+   
+   public:
+
+   // Accessors
+   bool operator ==(const HashSumValue &rhs) const
+   {
+      return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0;
+   };
+   bool operator !=(const HashSumValue &rhs) const
+   {
+      return memcmp(Sum,rhs.Sum,sizeof(Sum)) != 0;
+   };
+
+   std::string Value() const
+   {
+      char Conv[16] =
+      { '0','1','2','3','4','5','6','7','8','9','a','b',
+        'c','d','e','f'
+      };
+      char Result[((N/8)*2)+1];
+      Result[(N/8)*2] = 0;
+      
+      // Convert each char into two letters
+      int J = 0;
+      int I = 0;
+      for (; I != (N/8)*2; J++,I += 2)
+      {
+         Result[I] = Conv[Sum[J] >> 4];
+         Result[I + 1] = Conv[Sum[J] & 0xF];
+      }
+      return std::string(Result);
+   };
+   
+   inline void Value(unsigned char S[N/8])
+   {
+      for (int I = 0; I != sizeof(Sum); I++) 
+         S[I] = Sum[I];
+   };
+
+   inline operator std::string() const 
+   {
+      return Value();
+   };
+
+   bool Set(std::string Str) 
+   {
+      return Hex2Num(Str,Sum,sizeof(Sum));
+   };
+
+   inline void Set(unsigned char S[N/8]) 
+   {
+      for (int I = 0; I != sizeof(Sum); I++) 
+         Sum[I] = S[I];
+   };
+
+   HashSumValue(std::string Str) 
+   {
+         memset(Sum,0,sizeof(Sum));
+         Set(Str);
+   }
+   HashSumValue()
+   {
+      memset(Sum,0,sizeof(Sum));
+   }
+};
+
+class SummationImplementation
+{
+   public:
+   virtual bool Add(const unsigned char *inbuf, unsigned long long inlen) = 0;
+   inline bool Add(const char *inbuf, unsigned long long const inlen)
+   { return Add((unsigned char *)inbuf, inlen); };
+
+   inline bool Add(const unsigned char *Data)
+   { return Add(Data, strlen((const char *)Data)); };
+   inline bool Add(const char *Data)
+   { return Add((const unsigned char *)Data, strlen((const char *)Data)); };
+
+   inline bool Add(const unsigned char *Beg, const unsigned char *End)
+   { return Add(Beg, End - Beg); };
+   inline bool Add(const char *Beg, const char *End)
+   { return Add((const unsigned char *)Beg, End - Beg); };
+
+   bool AddFD(int Fd, unsigned long long Size = 0);
+   bool AddFD(FileFd &Fd, unsigned long long Size = 0);
+};
+
+#endif

+ 4 - 81
apt-pkg/contrib/md5.cc

@@ -35,6 +35,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/md5.h>
 #include <apt-pkg/md5.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/macros.h>
 #include <apt-pkg/macros.h>
@@ -43,7 +45,6 @@
 #include <unistd.h>
 #include <unistd.h>
 #include <netinet/in.h>                          // For htonl
 #include <netinet/in.h>                          // For htonl
 #include <inttypes.h>
 #include <inttypes.h>
-#include <config.h>
 									/*}}}*/
 									/*}}}*/
 
 
 // byteSwap - Swap bytes in a buffer					/*{{{*/
 // byteSwap - Swap bytes in a buffer					/*{{{*/
@@ -165,61 +166,6 @@ static void MD5Transform(uint32_t buf[4], uint32_t const in[16])
    buf[3] += d;
    buf[3] += d;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// MD5SumValue::MD5SumValue - Constructs the summation from a string	/*{{{*/
-// ---------------------------------------------------------------------
-/* The string form of a MD5 is a 32 character hex number */
-MD5SumValue::MD5SumValue(string Str)
-{
-   memset(Sum,0,sizeof(Sum));
-   Set(Str);
-}
-									/*}}}*/
-// MD5SumValue::MD5SumValue - Default constructor			/*{{{*/
-// ---------------------------------------------------------------------
-/* Sets the value to 0 */
-MD5SumValue::MD5SumValue()
-{
-   memset(Sum,0,sizeof(Sum));
-}
-									/*}}}*/
-// MD5SumValue::Set - Set the sum from a string				/*{{{*/
-// ---------------------------------------------------------------------
-/* Converts the hex string into a set of chars */
-bool MD5SumValue::Set(string Str)
-{
-   return Hex2Num(Str,Sum,sizeof(Sum));
-}
-									/*}}}*/
-// MD5SumValue::Value - Convert the number into a string		/*{{{*/
-// ---------------------------------------------------------------------
-/* Converts the set of chars into a hex string in lower case */
-string MD5SumValue::Value() const
-{
-   char Conv[16] = {'0','1','2','3','4','5','6','7','8','9','a','b',
-                    'c','d','e','f'};
-   char Result[33];
-   Result[32] = 0;
-   
-   // Convert each char into two letters
-   int J = 0;
-   int I = 0;
-   for (; I != 32; J++, I += 2)
-   {
-      Result[I] = Conv[Sum[J] >> 4];
-      Result[I + 1] = Conv[Sum[J] & 0xF];
-   } 
-
-   return string(Result);
-}
-									/*}}}*/
-// MD5SumValue::operator == - Comparitor				/*{{{*/
-// ---------------------------------------------------------------------
-/* Call memcmp on the buffer */
-bool MD5SumValue::operator ==(const MD5SumValue &rhs) const
-{
-   return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0;
-}
-									/*}}}*/
 // MD5Summation::MD5Summation - Initialize the summer			/*{{{*/
 // MD5Summation::MD5Summation - Initialize the summer			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This assigns the deep magic initial values */
 /* This assigns the deep magic initial values */
@@ -241,7 +187,7 @@ MD5Summation::MD5Summation()
 // MD5Summation::Add - 'Add' a data set to the hash			/*{{{*/
 // MD5Summation::Add - 'Add' a data set to the hash			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-bool MD5Summation::Add(const unsigned char *data,unsigned long len)
+bool MD5Summation::Add(const unsigned char *data,unsigned long long len)
 {
 {
    if (Done == true)
    if (Done == true)
       return false;
       return false;
@@ -286,29 +232,6 @@ bool MD5Summation::Add(const unsigned char *data,unsigned long len)
    return true;   
    return true;   
 }
 }
 									/*}}}*/
 									/*}}}*/
-// MD5Summation::AddFD - Add the contents of a FD to the hash		/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool MD5Summation::AddFD(int Fd,unsigned long Size)
-{
-   unsigned char Buf[64*64];
-   int Res = 0;
-   int ToEOF = (Size == 0);
-   while (Size != 0 || ToEOF)
-   {
-      unsigned n = sizeof(Buf);
-      if (!ToEOF) n = min(Size,(unsigned long)n);
-      Res = read(Fd,Buf,n);
-      if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read
-         return false;
-      if (ToEOF && Res == 0) // EOF
-         break;
-      Size -= Res;
-      Add(Buf,Res);
-   }
-   return true;
-}
-									/*}}}*/
 // MD5Summation::Result - Returns the value of the sum			/*{{{*/
 // MD5Summation::Result - Returns the value of the sum			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Because this must add in the last bytes of the series it prevents anyone
 /* Because this must add in the last bytes of the series it prevents anyone
@@ -353,7 +276,7 @@ MD5SumValue MD5Summation::Result()
    }
    }
    
    
    MD5SumValue V;
    MD5SumValue V;
-   memcpy(V.Sum,buf,16);
+   V.Set((unsigned char *)buf);
    return V;
    return V;
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 11 - 30
apt-pkg/contrib/md5.h

@@ -29,48 +29,29 @@
 #include <algorithm>
 #include <algorithm>
 #include <stdint.h>
 #include <stdint.h>
 
 
+#include "hashsum_template.h"
+
+#ifndef APT_8_CLEANER_HEADERS
 using std::string;
 using std::string;
 using std::min;
 using std::min;
+#endif
 
 
-class MD5Summation;
-
-class MD5SumValue
-{
-   friend class MD5Summation;
-   unsigned char Sum[4*4];
-   
-   public:
-
-   // Accessors
-   bool operator ==(const MD5SumValue &rhs) const; 
-   string Value() const;
-   inline void Value(unsigned char S[16]) 
-         {for (int I = 0; I != sizeof(Sum); I++) S[I] = Sum[I];};
-   inline operator string() const {return Value();};
-   bool Set(string Str);
-   inline void Set(unsigned char S[16]) 
-         {for (int I = 0; I != sizeof(Sum); I++) Sum[I] = S[I];};
-
-   MD5SumValue(string Str);
-   MD5SumValue();
-};
+typedef HashSumValue<128> MD5SumValue;
 
 
-class MD5Summation
+class MD5Summation : public SummationImplementation
 {
 {
    uint32_t Buf[4];
    uint32_t Buf[4];
    unsigned char Bytes[2*4];
    unsigned char Bytes[2*4];
    unsigned char In[16*4];
    unsigned char In[16*4];
    bool Done;
    bool Done;
-   
+
    public:
    public:
 
 
-   bool Add(const unsigned char *Data,unsigned long Size);
-   inline bool Add(const char *Data) {return Add((unsigned char *)Data,strlen(Data));};
-   bool AddFD(int Fd,unsigned long Size);
-   inline bool Add(const unsigned char *Beg,const unsigned char *End) 
-                  {return Add(Beg,End-Beg);};
+   bool Add(const unsigned char *inbuf, unsigned long long inlen);
+   using SummationImplementation::Add;
+
    MD5SumValue Result();
    MD5SumValue Result();
-   
+
    MD5Summation();
    MD5Summation();
 };
 };
 
 

+ 34 - 14
apt-pkg/contrib/mmap.cc

@@ -17,10 +17,11 @@
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
 #define _BSD_SOURCE
 #define _BSD_SOURCE
+#include <config.h>
+
 #include <apt-pkg/mmap.h>
 #include <apt-pkg/mmap.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
-
-#include <apti18n.h>
+#include <apt-pkg/fileutl.h>
 
 
 #include <sys/mman.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/stat.h>
@@ -28,9 +29,10 @@
 #include <fcntl.h>
 #include <fcntl.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <errno.h>
-
 #include <cstring>
 #include <cstring>
-   									/*}}}*/
+
+#include <apti18n.h>
+									/*}}}*/
 
 
 // MMap::MMap - Constructor						/*{{{*/
 // MMap::MMap - Constructor						/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
@@ -64,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;
@@ -75,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 _error->Error("Compressed file %s can't be read into mmap", Fd.Name().c_str());
+      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)
@@ -84,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());
@@ -94,7 +114,7 @@ bool MMap::Map(FileFd &Fd)
 	    return false;
 	    return false;
       }
       }
       else
       else
-	 return _error->Errno("mmap",_("Couldn't make mmap of %lu bytes"),
+	 return _error->Errno("mmap",_("Couldn't make mmap of %llu bytes"),
 	                      iSize);
 	                      iSize);
      }
      }
 
 
@@ -165,7 +185,7 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop)
       return true;
       return true;
    
    
 #ifdef _POSIX_SYNCHRONIZED_IO
 #ifdef _POSIX_SYNCHRONIZED_IO
-   unsigned long PSize = sysconf(_SC_PAGESIZE);
+   unsigned long long PSize = sysconf(_SC_PAGESIZE);
    if ((Flags & ReadOnly) != ReadOnly)
    if ((Flags & ReadOnly) != ReadOnly)
    {
    {
       if (SyncToFd != 0)
       if (SyncToFd != 0)
@@ -176,7 +196,7 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop)
       }
       }
       else
       else
       {
       {
-	 if (msync((char *)Base+(int)(Start/PSize)*PSize,Stop - Start,MS_SYNC) < 0)
+	 if (msync((char *)Base+(unsigned long long)(Start/PSize)*PSize,Stop - Start,MS_SYNC) < 0)
 	    return _error->Errno("msync", _("Unable to synchronize mmap"));
 	    return _error->Errno("msync", _("Unable to synchronize mmap"));
       }
       }
    }
    }
@@ -196,7 +216,7 @@ DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long const &Work
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
       return;
       return;
    
    
-   unsigned long EndOfFile = Fd->Size();
+   unsigned long long EndOfFile = Fd->Size();
    if (EndOfFile > WorkSpace)
    if (EndOfFile > WorkSpace)
       WorkSpace = EndOfFile;
       WorkSpace = EndOfFile;
    else if(WorkSpace > 0)
    else if(WorkSpace > 0)
@@ -284,7 +304,7 @@ DynamicMMap::~DynamicMMap()
       return;
       return;
    }
    }
    
    
-   unsigned long EndOfFile = iSize;
+   unsigned long long EndOfFile = iSize;
    iSize = WorkSpace;
    iSize = WorkSpace;
    Close(false);
    Close(false);
    if(ftruncate(Fd->Fd(),EndOfFile) < 0)
    if(ftruncate(Fd->Fd(),EndOfFile) < 0)
@@ -294,9 +314,9 @@ DynamicMMap::~DynamicMMap()
 // DynamicMMap::RawAllocate - Allocate a raw chunk of unaligned space	/*{{{*/
 // DynamicMMap::RawAllocate - Allocate a raw chunk of unaligned space	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This allocates a block of memory aligned to the given size */
 /* This allocates a block of memory aligned to the given size */
-unsigned long DynamicMMap::RawAllocate(unsigned long Size,unsigned long Aln)
+unsigned long DynamicMMap::RawAllocate(unsigned long long Size,unsigned long Aln)
 {
 {
-   unsigned long Result = iSize;
+   unsigned long long Result = iSize;
    if (Aln != 0)
    if (Aln != 0)
       Result += Aln - (iSize%Aln);
       Result += Aln - (iSize%Aln);
 
 
@@ -411,7 +431,7 @@ bool DynamicMMap::Grow() {
 	if (GrowFactor <= 0)
 	if (GrowFactor <= 0)
 		return _error->Error(_("Unable to increase size of the MMap as automatic growing is disabled by user."));
 		return _error->Error(_("Unable to increase size of the MMap as automatic growing is disabled by user."));
 
 
-	unsigned long const newSize = WorkSpace + GrowFactor;
+	unsigned long long const newSize = WorkSpace + GrowFactor;
 
 
 	if(Fd != 0) {
 	if(Fd != 0) {
 		Fd->Seek(newSize - 1);
 		Fd->Seek(newSize - 1);

+ 10 - 6
apt-pkg/contrib/mmap.h

@@ -27,9 +27,13 @@
 
 
 
 
 #include <string>
 #include <string>
-#include <apt-pkg/fileutl.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/fileutl.h>
 using std::string;
 using std::string;
+#endif
+
+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
    types are too small. Where ever possible 'unsigned long' should be used
    types are too small. Where ever possible 'unsigned long' should be used
@@ -41,7 +45,7 @@ class MMap
    protected:
    protected:
    
    
    unsigned long Flags;
    unsigned long Flags;
-   unsigned long iSize;
+   unsigned long long iSize;
    void *Base;
    void *Base;
 
 
    // In case mmap can not be used, we keep a dup of the file
    // In case mmap can not be used, we keep a dup of the file
@@ -60,8 +64,8 @@ class MMap
    // Simple accessors
    // Simple accessors
    inline operator void *() {return Base;};
    inline operator void *() {return Base;};
    inline void *Data() {return Base;}; 
    inline void *Data() {return Base;}; 
-   inline unsigned long Size() {return iSize;};
-   inline void AddSize(unsigned long const size) {iSize += size;};
+   inline unsigned long long Size() {return iSize;};
+   inline void AddSize(unsigned long long const size) {iSize += size;};
    inline bool validData() const { return Base != (void *)-1 && Base != 0; };
    inline bool validData() const { return Base != (void *)-1 && Base != 0; };
    
    
    // File manipulators
    // File manipulators
@@ -99,10 +103,10 @@ class DynamicMMap : public MMap
    public:
    public:
 
 
    // Allocation
    // Allocation
-   unsigned long RawAllocate(unsigned long Size,unsigned long Aln = 0);
+   unsigned long RawAllocate(unsigned long long Size,unsigned long Aln = 0);
    unsigned long Allocate(unsigned long ItemSize);
    unsigned long Allocate(unsigned long ItemSize);
    unsigned long WriteString(const char *String,unsigned long Len = (unsigned long)-1);
    unsigned long WriteString(const char *String,unsigned long Len = (unsigned long)-1);
-   inline unsigned long WriteString(const string &S) {return WriteString(S.c_str(),S.length());};
+   inline unsigned long WriteString(const std::string &S) {return WriteString(S.c_str(),S.length());};
    void UsePools(Pool &P,unsigned int Count) {Pools = &P; PoolCount = Count;};
    void UsePools(Pool &P,unsigned int Count) {Pools = &P; PoolCount = Count;};
    
    
    DynamicMMap(FileFd &F,unsigned long Flags,unsigned long const &WorkSpace = 2*1024*1024,
    DynamicMMap(FileFd &F,unsigned long Flags,unsigned long const &WorkSpace = 2*1024*1024,

+ 5 - 2
apt-pkg/contrib/netrc.cc

@@ -11,9 +11,12 @@
 
 
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
+#include <config.h>
 
 
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
+#include <apt-pkg/strutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
+
 #include <iostream>
 #include <iostream>
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
@@ -23,6 +26,7 @@
 
 
 #include "netrc.h"
 #include "netrc.h"
 
 
+using std::string;
 
 
 /* Get user and password from .netrc when given a machine name */
 /* Get user and password from .netrc when given a machine name */
 
 
@@ -64,8 +68,7 @@ int parsenetrc (char *host, char *login, char *password, char *netrcfile = NULL)
     if (!home)
     if (!home)
       return -1;
       return -1;
 
 
-    asprintf (&netrcfile, "%s%s%s", home, DIR_CHAR, NETRC);
-    if(!netrcfile)
+    if (asprintf (&netrcfile, "%s%s%s", home, DIR_CHAR, NETRC) == -1 || netrcfile == NULL)
       return -1;
       return -1;
     else
     else
       netrc_alloc = true;
       netrc_alloc = true;

+ 7 - 1
apt-pkg/contrib/netrc.h

@@ -14,16 +14,22 @@
 #ifndef NETRC_H
 #ifndef NETRC_H
 #define NETRC_H
 #define NETRC_H
 
 
+#include <string>
+
+#ifndef APT_8_CLEANER_HEADERS
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
+#endif
 
 
 #define DOT_CHAR "."
 #define DOT_CHAR "."
 #define DIR_CHAR "/"
 #define DIR_CHAR "/"
 
 
+class URI;
+
 // Assume: password[0]=0, host[0] != 0.
 // Assume: password[0]=0, host[0] != 0.
 // If login[0] = 0, search for login and password within a machine section
 // If login[0] = 0, search for login and password within a machine section
 // in the netrc.
 // in the netrc.
 // If login[0] != 0, search for password within machine and login.
 // If login[0] != 0, search for password within machine and login.
 int parsenetrc (char *host, char *login, char *password, char *filename);
 int parsenetrc (char *host, char *login, char *password, char *filename);
 
 
-void maybe_add_auth (URI &Uri, string NetRCFile);
+void maybe_add_auth (URI &Uri, std::string NetRCFile);
 #endif
 #endif

+ 16 - 23
apt-pkg/contrib/progress.cc

@@ -8,15 +8,17 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/progress.h>
 #include <apt-pkg/progress.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 
 
-#include <apti18n.h>
-
 #include <iostream>
 #include <iostream>
 #include <stdio.h>
 #include <stdio.h>
 #include <cstring>
 #include <cstring>
+
+#include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 
 
 using namespace std;
 using namespace std;
@@ -35,7 +37,7 @@ OpProgress::OpProgress() : Current(0), Total(0), Size(0), SubTotal(1),
 /* Current is the Base Overall progress in units of Total. Cur is the sub
 /* Current is the Base Overall progress in units of Total. Cur is the sub
    progress in units of SubTotal. Size is a scaling factor that says what
    progress in units of SubTotal. Size is a scaling factor that says what
    percent of Total SubTotal is. */
    percent of Total SubTotal is. */
-void OpProgress::Progress(unsigned long Cur)
+void OpProgress::Progress(unsigned long long Cur)
 {
 {
    if (Total == 0 || Size == 0 || SubTotal == 0)
    if (Total == 0 || Size == 0 || SubTotal == 0)
       Percent = 0;
       Percent = 0;
@@ -47,8 +49,8 @@ void OpProgress::Progress(unsigned long Cur)
 // OpProgress::OverallProgress - Set the overall progress		/*{{{*/
 // OpProgress::OverallProgress - Set the overall progress		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-void OpProgress::OverallProgress(unsigned long Current, unsigned long Total,
-	  			 unsigned long Size,const string &Op)
+void OpProgress::OverallProgress(unsigned long long Current, unsigned long long Total,
+	  			 unsigned long long Size,const string &Op)
 {
 {
    this->Current = Current;
    this->Current = Current;
    this->Total = Total;
    this->Total = Total;
@@ -65,27 +67,18 @@ void OpProgress::OverallProgress(unsigned long Current, unsigned long Total,
 // OpProgress::SubProgress - Set the sub progress state			/*{{{*/
 // OpProgress::SubProgress - Set the sub progress state			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-void OpProgress::SubProgress(unsigned long SubTotal,const string &Op)
-{
-   this->SubTotal = SubTotal;
-   SubOp = Op;
-   if (Total == 0)
-      Percent = 0;
-   else
-      Percent = Current*100.0/Total;
-   Update();
-}
-									/*}}}*/
-// OpProgress::SubProgress - Set the sub progress state			/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void OpProgress::SubProgress(unsigned long SubTotal)
+void OpProgress::SubProgress(unsigned long long SubTotal,const string &Op,
+			     float const Percent)
 {
 {
    this->SubTotal = SubTotal;
    this->SubTotal = SubTotal;
-   if (Total == 0)
-      Percent = 0;
+   if (Op.empty() == false)
+      SubOp = Op;
+   if (Total == 0 || Percent == 0)
+      this->Percent = 0;
+   else if (Percent != -1)
+      this->Percent = this->Current += (Size*Percent)/SubTotal;
    else
    else
-      Percent = Current*100.0/Total;
+      this->Percent = Current*100.0/Total;
    Update();
    Update();
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 16 - 15
apt-pkg/contrib/progress.h

@@ -25,26 +25,28 @@
 #include <string>
 #include <string>
 #include <sys/time.h>
 #include <sys/time.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
 using std::string;
 using std::string;
+#endif
 
 
 class Configuration;
 class Configuration;
 class OpProgress
 class OpProgress
 {
 {
-   unsigned long Current;
-   unsigned long Total;
-   unsigned long Size;
-   unsigned long SubTotal;
+   unsigned long long Current;
+   unsigned long long Total;
+   unsigned long long Size;
+   unsigned long long SubTotal;
    float LastPercent;
    float LastPercent;
    
    
    // Change reduction code
    // Change reduction code
    struct timeval LastTime;
    struct timeval LastTime;
-   string LastOp;
-   string LastSubOp;
+   std::string LastOp;
+   std::string LastSubOp;
    
    
    protected:
    protected:
    
    
-   string Op;
-   string SubOp;
+   std::string Op;
+   std::string SubOp;
    float Percent;
    float Percent;
    
    
    bool MajorChange;
    bool MajorChange;
@@ -54,11 +56,10 @@ class OpProgress
    
    
    public:
    public:
    
    
-   void Progress(unsigned long Current);
-   void SubProgress(unsigned long SubTotal);
-   void SubProgress(unsigned long SubTotal,const string &Op);
-   void OverallProgress(unsigned long Current,unsigned long Total,
-			unsigned long Size,const string &Op);
+   void Progress(unsigned long long Current);
+   void SubProgress(unsigned long long SubTotal, const std::string &Op = "", float const Percent = -1);
+   void OverallProgress(unsigned long long Current,unsigned long long Total,
+			unsigned long long Size,const std::string &Op);
    virtual void Done() {};
    virtual void Done() {};
    
    
    OpProgress();
    OpProgress();
@@ -68,8 +69,8 @@ class OpProgress
 class OpTextProgress : public OpProgress
 class OpTextProgress : public OpProgress
 {
 {
    protected:
    protected:
-   
-   string OldOp;
+
+   std::string OldOp;
    bool NoUpdate;
    bool NoUpdate;
    bool NoDisplay;
    bool NoDisplay;
    unsigned long LastLen;
    unsigned long LastLen;

+ 6 - 87
apt-pkg/contrib/sha1.cc

@@ -29,6 +29,8 @@
  */
  */
 									/*}}} */
 									/*}}} */
 // Include Files                                                        /*{{{*/
 // Include Files                                                        /*{{{*/
+#include <config.h>
+
 #include <apt-pkg/sha1.h>
 #include <apt-pkg/sha1.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/macros.h>
 #include <apt-pkg/macros.h>
@@ -36,7 +38,6 @@
 #include <string.h>
 #include <string.h>
 #include <unistd.h>
 #include <unistd.h>
 #include <inttypes.h>
 #include <inttypes.h>
-#include <config.h>
 									/*}}}*/
 									/*}}}*/
 
 
 // SHA1Transform - Alters an existing SHA-1 hash			/*{{{*/
 // SHA1Transform - Alters an existing SHA-1 hash			/*{{{*/
@@ -177,67 +178,6 @@ static void SHA1Transform(uint32_t state[5],uint8_t const buffer[64])
 }
 }
 									/*}}}*/
 									/*}}}*/
 
 
-// SHA1SumValue::SHA1SumValue - Constructs the summation from a string  /*{{{*/
-// ---------------------------------------------------------------------
-/* The string form of a SHA1 is a 40 character hex number */
-SHA1SumValue::SHA1SumValue(string Str)
-{
-   memset(Sum,0,sizeof(Sum));
-   Set(Str);
-}
-
-									/*}}} */
-// SHA1SumValue::SHA1SumValue - Default constructor                     /*{{{*/
-// ---------------------------------------------------------------------
-/* Sets the value to 0 */
-SHA1SumValue::SHA1SumValue()
-{
-   memset(Sum,0,sizeof(Sum));
-}
-
-									/*}}} */
-// SHA1SumValue::Set - Set the sum from a string                        /*{{{*/
-// ---------------------------------------------------------------------
-/* Converts the hex string into a set of chars */
-bool SHA1SumValue::Set(string Str)
-{
-   return Hex2Num(Str,Sum,sizeof(Sum));
-}
-
-									/*}}} */
-// SHA1SumValue::Value - Convert the number into a string               /*{{{*/
-// ---------------------------------------------------------------------
-/* Converts the set of chars into a hex string in lower case */
-string SHA1SumValue::Value() const
-{
-   char Conv[16] =
-      { '0','1','2','3','4','5','6','7','8','9','a','b',
-      'c','d','e','f'
-   };
-   char Result[41];
-   Result[40] = 0;
-
-   // Convert each char into two letters
-   int J = 0;
-   int I = 0;
-   for (; I != 40; J++,I += 2)
-   {
-      Result[I] = Conv[Sum[J] >> 4];
-      Result[I + 1] = Conv[Sum[J] & 0xF];
-   }
-
-   return string(Result);
-}
-
-									/*}}} */
-// SHA1SumValue::operator == - Comparator                               /*{{{*/
-// ---------------------------------------------------------------------
-/* Call memcmp on the buffer */
-bool SHA1SumValue::operator == (const SHA1SumValue & rhs) const
-{
-   return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0;
-}
-									/*}}}*/
 // SHA1Summation::SHA1Summation - Constructor                           /*{{{*/
 // SHA1Summation::SHA1Summation - Constructor                           /*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -289,18 +229,20 @@ SHA1SumValue SHA1Summation::Result()
 
 
    // Transfer over the result
    // Transfer over the result
    SHA1SumValue Value;
    SHA1SumValue Value;
+   unsigned char res[20];
    for (unsigned i = 0; i < 20; i++)
    for (unsigned i = 0; i < 20; i++)
    {
    {
-      Value.Sum[i] = (unsigned char)
+      res[i] = (unsigned char)
 	 ((state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
 	 ((state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
    }
    }
+   Value.Set(res);
    return Value;
    return Value;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // SHA1Summation::Add - Adds content of buffer into the checksum        /*{{{*/
 // SHA1Summation::Add - Adds content of buffer into the checksum        /*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* May not be called after Result() is called */
 /* May not be called after Result() is called */
-bool SHA1Summation::Add(const unsigned char *data,unsigned long len)
+bool SHA1Summation::Add(const unsigned char *data,unsigned long long len)
 {
 {
    if (Done)
    if (Done)
       return false;
       return false;
@@ -331,26 +273,3 @@ bool SHA1Summation::Add(const unsigned char *data,unsigned long len)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// SHA1Summation::AddFD - Add content of file into the checksum         /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool SHA1Summation::AddFD(int Fd,unsigned long Size)
-{
-   unsigned char Buf[64 * 64];
-   int Res = 0;
-   int ToEOF = (Size == 0);
-   while (Size != 0 || ToEOF)
-   {
-      unsigned n = sizeof(Buf);
-      if (!ToEOF) n = min(Size,(unsigned long)n);
-      Res = read(Fd,Buf,n);
-      if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read
-	 return false;
-      if (ToEOF && Res == 0) // EOF
-         break;
-      Size -= Res;
-      Add(Buf,Res);
-   }
-   return true;
-}
-									/*}}}*/

+ 8 - 28
apt-pkg/contrib/sha1.h

@@ -18,33 +18,16 @@
 #include <cstring>
 #include <cstring>
 #include <algorithm>
 #include <algorithm>
 
 
+#include "hashsum_template.h"
+
+#ifndef APT_8_CLEANER_HEADERS
 using std::string;
 using std::string;
 using std::min;
 using std::min;
+#endif
 
 
-class SHA1Summation;
-
-class SHA1SumValue
-{
-   friend class SHA1Summation;
-   unsigned char Sum[20];
-   
-   public:
-
-   // Accessors
-   bool operator ==(const SHA1SumValue &rhs) const; 
-   string Value() const;
-   inline void Value(unsigned char S[20])
-         {for (int I = 0; I != sizeof(Sum); I++) S[I] = Sum[I];};
-   inline operator string() const {return Value();};
-   bool Set(string Str);
-   inline void Set(unsigned char S[20]) 
-         {for (int I = 0; I != sizeof(Sum); I++) Sum[I] = S[I];};
-
-   SHA1SumValue(string Str);
-   SHA1SumValue();
-};
+typedef  HashSumValue<160> SHA1SumValue;
 
 
-class SHA1Summation
+class SHA1Summation : public SummationImplementation
 {
 {
    /* assumes 64-bit alignment just in case */
    /* assumes 64-bit alignment just in case */
    unsigned char Buffer[64] __attribute__((aligned(8)));
    unsigned char Buffer[64] __attribute__((aligned(8)));
@@ -53,12 +36,9 @@ class SHA1Summation
    bool Done;
    bool Done;
    
    
    public:
    public:
+   bool Add(const unsigned char *inbuf, unsigned long long inlen);
+   using SummationImplementation::Add;
 
 
-   bool Add(const unsigned char *inbuf,unsigned long inlen);
-   inline bool Add(const char *Data) {return Add((unsigned char *)Data,strlen(Data));};
-   bool AddFD(int Fd,unsigned long Size);
-   inline bool Add(const unsigned char *Beg,const unsigned char *End) 
-                  {return Add(Beg,End-Beg);};
    SHA1SumValue Result();
    SHA1SumValue Result();
    
    
    SHA1Summation();
    SHA1Summation();

+ 103 - 0
apt-pkg/contrib/sha2.h

@@ -0,0 +1,103 @@
+// -*- mode: cpp; mode: fold -*-
+// Description                                                          /*{{{*/
+// $Id: sha512.h,v 1.3 2001/05/07 05:05:47 jgg Exp $
+/* ######################################################################
+
+   SHA{512,256}SumValue - Storage for a SHA-{512,256} hash.
+   SHA{512,256}Summation - SHA-{512,256} Secure Hash Algorithm.
+   
+   This is a C++ interface to a set of SHA{512,256}Sum functions, that mirrors
+   the equivalent MD5 & SHA1 classes. 
+
+   ##################################################################### */
+                                                                        /*}}}*/
+#ifndef APTPKG_SHA2_H
+#define APTPKG_SHA2_H
+
+#include <string>
+#include <cstring>
+#include <algorithm>
+#include <stdint.h>
+
+#include "sha2_internal.h"
+#include "hashsum_template.h"
+
+typedef HashSumValue<512> SHA512SumValue;
+typedef HashSumValue<256> SHA256SumValue;
+
+class SHA2SummationBase : public SummationImplementation
+{
+ protected:
+   bool Done;
+ public:
+   bool Add(const unsigned char *inbuf, unsigned long long len) = 0;
+
+   void Result();
+};
+
+class SHA256Summation : public SHA2SummationBase
+{
+   SHA256_CTX ctx;
+   unsigned char Sum[32];
+
+   public:
+   bool Add(const unsigned char *inbuf, unsigned long long len)
+   {
+      if (Done) 
+         return false;
+      SHA256_Update(&ctx, inbuf, len);
+      return true;
+   };
+   using SummationImplementation::Add;
+
+   SHA256SumValue Result()
+   {
+      if (!Done) {
+         SHA256_Final(Sum, &ctx);
+         Done = true;
+      }
+      SHA256SumValue res;
+      res.Set(Sum);
+      return res;
+   };
+   SHA256Summation() 
+   {
+      SHA256_Init(&ctx);
+      Done = false;
+   };
+};
+
+class SHA512Summation : public SHA2SummationBase
+{
+   SHA512_CTX ctx;
+   unsigned char Sum[64];
+
+   public:
+   bool Add(const unsigned char *inbuf, unsigned long long len)
+   {
+      if (Done) 
+         return false;
+      SHA512_Update(&ctx, inbuf, len);
+      return true;
+   };
+   using SummationImplementation::Add;
+
+   SHA512SumValue Result()
+   {
+      if (!Done) {
+         SHA512_Final(Sum, &ctx);
+         Done = true;
+      }
+      SHA512SumValue res;
+      res.Set(Sum);
+      return res;
+   };
+   SHA512Summation()
+   {
+      SHA512_Init(&ctx);
+      Done = false;
+   };
+};
+
+
+#endif

+ 0 - 424
apt-pkg/contrib/sha256.cc

@@ -1,424 +0,0 @@
-/*
- * Cryptographic API.							{{{
- *
- * SHA-256, as specified in
- * http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf
- *
- * SHA-256 code by Jean-Luc Cooke <jlcooke@certainkey.com>.
- *
- * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
- * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *
- * Ported from the Linux kernel to Apt by Anthony Towns <ajt@debian.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option) 
- * any later version.
- *
- */									/*}}}*/
-
-#ifdef __GNUG__
-#pragma implementation "apt-pkg/sha256.h"
-#endif
-
-
-#define SHA256_DIGEST_SIZE      32
-#define SHA256_HMAC_BLOCK_SIZE  64
-
-#define ror32(value,bits) (((value) >> (bits)) | ((value) << (32 - (bits))))
-
-#include <apt-pkg/sha256.h>
-#include <apt-pkg/strutl.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <arpa/inet.h>
-
-typedef uint32_t u32;
-typedef uint8_t  u8;
-
-static inline u32 Ch(u32 x, u32 y, u32 z)
-{
-        return z ^ (x & (y ^ z));
-}
-
-static inline u32 Maj(u32 x, u32 y, u32 z)
-{
-        return (x & y) | (z & (x | y));
-}
-
-#define e0(x)       (ror32(x, 2) ^ ror32(x,13) ^ ror32(x,22))
-#define e1(x)       (ror32(x, 6) ^ ror32(x,11) ^ ror32(x,25))
-#define s0(x)       (ror32(x, 7) ^ ror32(x,18) ^ (x >> 3))
-#define s1(x)       (ror32(x,17) ^ ror32(x,19) ^ (x >> 10))
-
-#define H0         0x6a09e667
-#define H1         0xbb67ae85
-#define H2         0x3c6ef372
-#define H3         0xa54ff53a
-#define H4         0x510e527f
-#define H5         0x9b05688c
-#define H6         0x1f83d9ab
-#define H7         0x5be0cd19
-
-static inline void LOAD_OP(int I, u32 *W, const u8 *input)		/*{{{*/
-{
-	W[I] = (  ((u32) input[I * 4 + 0] << 24)
-		| ((u32) input[I * 4 + 1] << 16)
-		| ((u32) input[I * 4 + 2] << 8)
-		| ((u32) input[I * 4 + 3]));
-}
-									/*}}}*/
-static inline void BLEND_OP(int I, u32 *W)
-{
-        W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
-}
-
-static void sha256_transform(u32 *state, const u8 *input)		/*{{{*/
-{
-        u32 a, b, c, d, e, f, g, h, t1, t2;
-        u32 W[64];
-        int i;
-
-        /* load the input */
-        for (i = 0; i < 16; i++)
-                LOAD_OP(i, W, input);
-
-        /* now blend */
-        for (i = 16; i < 64; i++)
-                BLEND_OP(i, W);
-    
-        /* load the state into our registers */
-        a=state[0];  b=state[1];  c=state[2];  d=state[3];
-        e=state[4];  f=state[5];  g=state[6];  h=state[7];
-
-        /* now iterate */
-        t1 = h + e1(e) + Ch(e,f,g) + 0x428a2f98 + W[ 0];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0x71374491 + W[ 1];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0xb5c0fbcf + W[ 2];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0xe9b5dba5 + W[ 3];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0x3956c25b + W[ 4];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0x59f111f1 + W[ 5];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0x923f82a4 + W[ 6];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0xab1c5ed5 + W[ 7];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        t1 = h + e1(e) + Ch(e,f,g) + 0xd807aa98 + W[ 8];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0x12835b01 + W[ 9];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0x243185be + W[10];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0x550c7dc3 + W[11];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0x72be5d74 + W[12];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0x80deb1fe + W[13];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0x9bdc06a7 + W[14];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0xc19bf174 + W[15];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        t1 = h + e1(e) + Ch(e,f,g) + 0xe49b69c1 + W[16];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0xefbe4786 + W[17];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0x0fc19dc6 + W[18];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0x240ca1cc + W[19];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0x2de92c6f + W[20];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0x4a7484aa + W[21];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0x5cb0a9dc + W[22];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0x76f988da + W[23];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        t1 = h + e1(e) + Ch(e,f,g) + 0x983e5152 + W[24];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0xa831c66d + W[25];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0xb00327c8 + W[26];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0xbf597fc7 + W[27];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0xc6e00bf3 + W[28];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0xd5a79147 + W[29];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0x06ca6351 + W[30];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0x14292967 + W[31];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        t1 = h + e1(e) + Ch(e,f,g) + 0x27b70a85 + W[32];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0x2e1b2138 + W[33];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0x4d2c6dfc + W[34];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0x53380d13 + W[35];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0x650a7354 + W[36];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0x766a0abb + W[37];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0x81c2c92e + W[38];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0x92722c85 + W[39];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        t1 = h + e1(e) + Ch(e,f,g) + 0xa2bfe8a1 + W[40];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0xa81a664b + W[41];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0xc24b8b70 + W[42];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0xc76c51a3 + W[43];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0xd192e819 + W[44];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0xd6990624 + W[45];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0xf40e3585 + W[46];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0x106aa070 + W[47];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        t1 = h + e1(e) + Ch(e,f,g) + 0x19a4c116 + W[48];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0x1e376c08 + W[49];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0x2748774c + W[50];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0x34b0bcb5 + W[51];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0x391c0cb3 + W[52];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0x4ed8aa4a + W[53];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0x5b9cca4f + W[54];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0x682e6ff3 + W[55];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        t1 = h + e1(e) + Ch(e,f,g) + 0x748f82ee + W[56];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0x78a5636f + W[57];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0x84c87814 + W[58];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0x8cc70208 + W[59];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0x90befffa + W[60];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0xa4506ceb + W[61];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0xbef9a3f7 + W[62];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0xc67178f2 + W[63];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        state[0] += a; state[1] += b; state[2] += c; state[3] += d;
-        state[4] += e; state[5] += f; state[6] += g; state[7] += h;
-
-        /* clear any sensitive info... */
-        a = b = c = d = e = f = g = h = t1 = t2 = 0;
-        memset(W, 0, 64 * sizeof(u32));
-}
-									/*}}}*/
-SHA256Summation::SHA256Summation()					/*{{{*/
-{
-        Sum.state[0] = H0;
-        Sum.state[1] = H1;
-        Sum.state[2] = H2;
-        Sum.state[3] = H3;
-        Sum.state[4] = H4;
-        Sum.state[5] = H5;
-        Sum.state[6] = H6;
-        Sum.state[7] = H7;
-        Sum.count[0] = Sum.count[1] = 0;
-        memset(Sum.buf, 0, sizeof(Sum.buf));
-        Done = false;
-}
-									/*}}}*/
-bool SHA256Summation::Add(const u8 *data, unsigned long len)		/*{{{*/
-{
-        struct sha256_ctx *sctx = &Sum;
-        unsigned int i, index, part_len;
-
-        if (Done) return false;
-
-        /* Compute number of bytes mod 128 */
-        index = (unsigned int)((sctx->count[0] >> 3) & 0x3f);
-
-        /* Update number of bits */
-        if ((sctx->count[0] += (len << 3)) < (len << 3)) {
-                sctx->count[1]++;
-                sctx->count[1] += (len >> 29);
-        }
-
-        part_len = 64 - index;
-
-        /* Transform as many times as possible. */
-        if (len >= part_len) {
-                memcpy(&sctx->buf[index], data, part_len);
-                sha256_transform(sctx->state, sctx->buf);
-
-                for (i = part_len; i + 63 < len; i += 64)
-                        sha256_transform(sctx->state, &data[i]);
-                index = 0;
-        } else {
-                i = 0;
-        }
-
-        /* Buffer remaining input */
-        memcpy(&sctx->buf[index], &data[i], len-i);
-
-        return true;
-}
-									/*}}}*/
-SHA256SumValue SHA256Summation::Result()				/*{{{*/
-{
-   struct sha256_ctx *sctx = &Sum;
-   if (!Done) {
-        u8 bits[8];
-        unsigned int index, pad_len, t;
-        static const u8 padding[64] = { 0x80, };
-
-        /* Save number of bits */
-        t = sctx->count[0];
-        bits[7] = t; t >>= 8;
-        bits[6] = t; t >>= 8;
-        bits[5] = t; t >>= 8;
-        bits[4] = t;
-        t = sctx->count[1];
-        bits[3] = t; t >>= 8;
-        bits[2] = t; t >>= 8;
-        bits[1] = t; t >>= 8;
-        bits[0] = t;
-
-        /* Pad out to 56 mod 64. */
-        index = (sctx->count[0] >> 3) & 0x3f;
-        pad_len = (index < 56) ? (56 - index) : ((64+56) - index);
-        Add(padding, pad_len);
-
-        /* Append length (before padding) */
-        Add(bits, 8);
-   }
-
-   Done = true;
-
-   /* Store state in digest */
-
-   SHA256SumValue res;
-   u8 *out = res.Sum;
-
-   int i, j;
-   unsigned int t;
-   for (i = j = 0; i < 8; i++, j += 4) {
-      t = sctx->state[i];
-      out[j+3] = t; t >>= 8;
-      out[j+2] = t; t >>= 8;
-      out[j+1] = t; t >>= 8;
-      out[j  ] = t;
-   }
-
-   return res;
-}
-									/*}}}*/
-// SHA256SumValue::SHA256SumValue - Constructs the sum from a string   /*{{{*/
-// ---------------------------------------------------------------------
-/* The string form of a SHA256 is a 64 character hex number */
-SHA256SumValue::SHA256SumValue(string Str)
-{
-   memset(Sum,0,sizeof(Sum));
-   Set(Str);
-}
-                                                                       /*}}}*/
-// SHA256SumValue::SHA256SumValue - Default constructor                /*{{{*/
-// ---------------------------------------------------------------------
-/* Sets the value to 0 */
-SHA256SumValue::SHA256SumValue()
-{
-   memset(Sum,0,sizeof(Sum));
-}
-                                                                       /*}}}*/
-// SHA256SumValue::Set - Set the sum from a string                     /*{{{*/
-// ---------------------------------------------------------------------
-/* Converts the hex string into a set of chars */
-bool SHA256SumValue::Set(string Str)
-{
-   return Hex2Num(Str,Sum,sizeof(Sum));
-}
-                                                                       /*}}}*/
-// SHA256SumValue::Value - Convert the number into a string            /*{{{*/
-// ---------------------------------------------------------------------
-/* Converts the set of chars into a hex string in lower case */
-string SHA256SumValue::Value() const
-{
-   char Conv[16] =
-      { '0','1','2','3','4','5','6','7','8','9','a','b',
-      'c','d','e','f'
-   };
-   char Result[65];
-   Result[64] = 0;
-
-   // Convert each char into two letters
-   int J = 0;
-   int I = 0;
-   for (; I != 64; J++,I += 2)
-   {
-      Result[I] = Conv[Sum[J] >> 4];
-      Result[I + 1] = Conv[Sum[J] & 0xF];
-   }
-
-   return string(Result);
-}
-									/*}}}*/
-// SHA256SumValue::operator == - Comparator                            /*{{{*/
-// ---------------------------------------------------------------------
-/* Call memcmp on the buffer */
-bool SHA256SumValue::operator == (const SHA256SumValue & rhs) const
-{
-   return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0;
-}
-                                                                       /*}}}*/
-// SHA256Summation::AddFD - Add content of file into the checksum      /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool SHA256Summation::AddFD(int Fd,unsigned long Size)
-{
-   unsigned char Buf[64 * 64];
-   int Res = 0;
-   int ToEOF = (Size == 0);
-   while (Size != 0 || ToEOF)
-   {
-      unsigned n = sizeof(Buf);
-      if (!ToEOF) n = min(Size,(unsigned long)n);
-      Res = read(Fd,Buf,n);
-      if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read
-         return false;
-      if (ToEOF && Res == 0) // EOF
-         break;
-      Size -= Res;
-      Add(Buf,Res);
-   }
-   return true;
-}
-                                                                       /*}}}*/
-

+ 2 - 66
apt-pkg/contrib/sha256.h

@@ -1,72 +1,8 @@
-// -*- mode: cpp; mode: fold -*-
-// Description                                                          /*{{{*/
-// $Id: sha1.h,v 1.3 2001/05/07 05:05:47 jgg Exp $
-/* ######################################################################
-
-   SHA256SumValue - Storage for a SHA-256 hash.
-   SHA256Summation - SHA-256 Secure Hash Algorithm.
-   
-   This is a C++ interface to a set of SHA256Sum functions, that mirrors
-   the equivalent MD5 & SHA1 classes. 
-
-   ##################################################################### */
-                                                                        /*}}}*/
 #ifndef APTPKG_SHA256_H
 #ifndef APTPKG_SHA256_H
 #define APTPKG_SHA256_H
 #define APTPKG_SHA256_H
 
 
-#include <string>
-#include <cstring>
-#include <algorithm>
-#include <stdint.h>
-
-using std::string;
-using std::min;
-
-class SHA256Summation;
-
-class SHA256SumValue
-{
-   friend class SHA256Summation;
-   unsigned char Sum[32];
-   
-   public:
-
-   // Accessors
-   bool operator ==(const SHA256SumValue &rhs) const; 
-   string Value() const;
-   inline void Value(unsigned char S[32])
-         {for (int I = 0; I != sizeof(Sum); I++) S[I] = Sum[I];};
-   inline operator string() const {return Value();};
-   bool Set(string Str);
-   inline void Set(unsigned char S[32]) 
-         {for (int I = 0; I != sizeof(Sum); I++) Sum[I] = S[I];};
-
-   SHA256SumValue(string Str);
-   SHA256SumValue();
-};
-
-struct sha256_ctx {
-    uint32_t count[2];
-    uint32_t state[8];
-    uint8_t buf[128];
-};
-
-class SHA256Summation
-{
-   struct sha256_ctx Sum;
-
-   bool Done;
-
-   public:
+#include "sha2.h"
 
 
-   bool Add(const unsigned char *inbuf,unsigned long inlen);
-   inline bool Add(const char *Data) {return Add((unsigned char *)Data,strlen(Data));};
-   bool AddFD(int Fd,unsigned long Size);
-   inline bool Add(const unsigned char *Beg,const unsigned char *End) 
-                  {return Add(Beg,End-Beg);};
-   SHA256SumValue Result();
-   
-   SHA256Summation();
-};
+#warning "This header is deprecated, please include sha2.h instead"
 
 
 #endif
 #endif

Разлика између датотеке није приказан због своје велике величине
+ 1076 - 0
apt-pkg/contrib/sha2_internal.cc


+ 188 - 0
apt-pkg/contrib/sha2_internal.h

@@ -0,0 +1,188 @@
+/*
+ * FILE:	sha2.h
+ * AUTHOR:	Aaron D. Gifford - http://www.aarongifford.com/
+ * 
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
+ */
+
+#ifndef __SHA2_H__
+#define __SHA2_H__
+
+/*
+ * Import u_intXX_t size_t type definitions from system headers.  You
+ * may need to change this, or define these things yourself in this
+ * file.
+ */
+#include <sys/types.h>
+
+#ifdef SHA2_USE_INTTYPES_H
+
+#include <inttypes.h>
+
+#endif /* SHA2_USE_INTTYPES_H */
+
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+#define SHA256_BLOCK_LENGTH		64
+#define SHA256_DIGEST_LENGTH		32
+#define SHA256_DIGEST_STRING_LENGTH	(SHA256_DIGEST_LENGTH * 2 + 1)
+#define SHA384_BLOCK_LENGTH		128
+#define SHA384_DIGEST_LENGTH		48
+#define SHA384_DIGEST_STRING_LENGTH	(SHA384_DIGEST_LENGTH * 2 + 1)
+#define SHA512_BLOCK_LENGTH		128
+#define SHA512_DIGEST_LENGTH		64
+#define SHA512_DIGEST_STRING_LENGTH	(SHA512_DIGEST_LENGTH * 2 + 1)
+
+
+/*** SHA-256/384/512 Context Structures *******************************/
+/* NOTE: If your architecture does not define either u_intXX_t types or
+ * uintXX_t (from inttypes.h), you may need to define things by hand
+ * for your system:
+ */
+#if 0
+typedef unsigned char u_int8_t;		/* 1-byte  (8-bits)  */
+typedef unsigned int u_int32_t;		/* 4-bytes (32-bits) */
+typedef unsigned long long u_int64_t;	/* 8-bytes (64-bits) */
+#endif
+/*
+ * Most BSD systems already define u_intXX_t types, as does Linux.
+ * Some systems, however, like Compaq's Tru64 Unix instead can use
+ * uintXX_t types defined by very recent ANSI C standards and included
+ * in the file:
+ *
+ *   #include <inttypes.h>
+ *
+ * If you choose to use <inttypes.h> then please define: 
+ *
+ *   #define SHA2_USE_INTTYPES_H
+ *
+ * Or on the command line during compile:
+ *
+ *   cc -DSHA2_USE_INTTYPES_H ...
+ */
+#ifdef SHA2_USE_INTTYPES_H
+
+typedef struct _SHA256_CTX {
+	uint32_t	state[8];
+	uint64_t	bitcount;
+	uint8_t	buffer[SHA256_BLOCK_LENGTH];
+} SHA256_CTX;
+typedef struct _SHA512_CTX {
+	uint64_t	state[8];
+	uint64_t	bitcount[2];
+	uint8_t	buffer[SHA512_BLOCK_LENGTH];
+} SHA512_CTX;
+
+#else /* SHA2_USE_INTTYPES_H */
+
+typedef struct _SHA256_CTX {
+	u_int32_t	state[8];
+	u_int64_t	bitcount;
+	u_int8_t	buffer[SHA256_BLOCK_LENGTH];
+} SHA256_CTX;
+typedef struct _SHA512_CTX {
+	u_int64_t	state[8];
+	u_int64_t	bitcount[2];
+	u_int8_t	buffer[SHA512_BLOCK_LENGTH];
+} SHA512_CTX;
+
+#endif /* SHA2_USE_INTTYPES_H */
+
+typedef SHA512_CTX SHA384_CTX;
+
+
+/*** SHA-256/384/512 Function Prototypes ******************************/
+#ifndef NOPROTO
+#ifdef SHA2_USE_INTTYPES_H
+
+void SHA256_Init(SHA256_CTX *);
+void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t);
+void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
+char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
+char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
+
+void SHA384_Init(SHA384_CTX*);
+void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t);
+void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
+char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
+char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
+
+void SHA512_Init(SHA512_CTX*);
+void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t);
+void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
+char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
+char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
+
+#else /* SHA2_USE_INTTYPES_H */
+
+void SHA256_Init(SHA256_CTX *);
+void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t);
+void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
+char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
+char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
+
+void SHA384_Init(SHA384_CTX*);
+void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t);
+void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
+char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
+char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
+
+void SHA512_Init(SHA512_CTX*);
+void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t);
+void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
+char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
+char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
+
+#endif /* SHA2_USE_INTTYPES_H */
+
+#else /* NOPROTO */
+
+void SHA256_Init();
+void SHA256_Update();
+void SHA256_Final();
+char* SHA256_End();
+char* SHA256_Data();
+
+void SHA384_Init();
+void SHA384_Update();
+void SHA384_Final();
+char* SHA384_End();
+char* SHA384_Data();
+
+void SHA512_Init();
+void SHA512_Update();
+void SHA512_Final();
+char* SHA512_End();
+char* SHA512_Data();
+
+#endif /* NOPROTO */
+
+#endif /* __SHA2_H__ */
+

+ 34 - 6
apt-pkg/contrib/strutl.cc

@@ -15,12 +15,12 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Includes								/*{{{*/
 // Includes								/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 
 
-#include <apti18n.h>
-    
 #include <ctype.h>
 #include <ctype.h>
 #include <string.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdio.h>
@@ -31,7 +31,7 @@
 #include <stdarg.h>
 #include <stdarg.h>
 #include <iconv.h>
 #include <iconv.h>
 
 
-#include "config.h"
+#include <apti18n.h>
 
 
 using namespace std;
 using namespace std;
 									/*}}}*/
 									/*}}}*/
@@ -910,17 +910,17 @@ bool StrToTime(const string &Val,time_t &Result)
 
 
    // Handle RFC 1123 time
    // Handle RFC 1123 time
    Month[0] = 0;
    Month[0] = 0;
-   if (sscanf(I," %d %3s %d %d:%d:%d GMT",&Tm.tm_mday,Month,&Tm.tm_year,
+   if (sscanf(I," %2d %3s %4d %2d:%2d:%2d GMT",&Tm.tm_mday,Month,&Tm.tm_year,
 	      &Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec) != 6)
 	      &Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec) != 6)
    {
    {
       // Handle RFC 1036 time
       // Handle RFC 1036 time
-      if (sscanf(I," %d-%3s-%d %d:%d:%d GMT",&Tm.tm_mday,Month,
+      if (sscanf(I," %2d-%3s-%3d %2d:%2d:%2d GMT",&Tm.tm_mday,Month,
 		 &Tm.tm_year,&Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec) == 6)
 		 &Tm.tm_year,&Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec) == 6)
 	 Tm.tm_year += 1900;
 	 Tm.tm_year += 1900;
       else
       else
       {
       {
 	 // asctime format
 	 // asctime format
-	 if (sscanf(I," %3s %d %d:%d:%d %d",Month,&Tm.tm_mday,
+	 if (sscanf(I," %3s %2d %2d:%2d:%2d %4d",Month,&Tm.tm_mday,
 		    &Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec,&Tm.tm_year) != 6)
 		    &Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec,&Tm.tm_year) != 6)
 	 {
 	 {
 	    // 'ftp' time
 	    // 'ftp' time
@@ -969,6 +969,34 @@ bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// StrToNum - Convert a fixed length string to a number			/*{{{*/
+// ---------------------------------------------------------------------
+/* This is used in decoding the crazy fixed length string headers in 
+   tar and ar files. */
+bool StrToNum(const char *Str,unsigned long long &Res,unsigned Len,unsigned Base)
+{
+   char S[30];
+   if (Len >= sizeof(S))
+      return false;
+   memcpy(S,Str,Len);
+   S[Len] = 0;
+   
+   // All spaces is a zero
+   Res = 0;
+   unsigned I;
+   for (I = 0; S[I] == ' '; I++);
+   if (S[I] == 0)
+      return true;
+   
+   char *End;
+   Res = strtoull(S,&End,Base);
+   if (End == S)
+      return false;
+   
+   return true;
+}
+									/*}}}*/
+
 // Base256ToNum - Convert a fixed length binary to a number             /*{{{*/
 // Base256ToNum - Convert a fixed length binary to a number             /*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This is used in decoding the 256bit encoded fixed length fields in
 /* This is used in decoding the 256bit encoded fixed length fields in

+ 55 - 52
apt-pkg/contrib/strutl.h

@@ -27,59 +27,62 @@
 
 
 #include "macros.h"
 #include "macros.h"
 
 
+#ifndef APT_8_CLEANER_HEADERS
 using std::string;
 using std::string;
 using std::vector;
 using std::vector;
 using std::ostream;
 using std::ostream;
+#endif
 
 
-bool UTF8ToCodeset(const char *codeset, const string &orig, 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);
-bool ParseQuoteWord(const char *&String,string &Res);
-bool ParseCWord(const char *&String,string &Res);
-string QuoteString(const string &Str,const char *Bad);
-string DeQuoteString(const string &Str);
-string DeQuoteString(string::const_iterator const &begin, string::const_iterator const &end);
+bool ParseQuoteWord(const char *&String,std::string &Res);
+bool ParseCWord(const char *&String,std::string &Res);
+std::string QuoteString(const std::string &Str,const char *Bad);
+std::string DeQuoteString(const std::string &Str);
+std::string DeQuoteString(std::string::const_iterator const &begin, std::string::const_iterator const &end);
 
 
 // unescape (\0XX and \xXX) from a string
 // unescape (\0XX and \xXX) from a string
-string DeEscapeString(const string &input);
-
-string SizeToStr(double Bytes);
-string TimeToStr(unsigned long Sec);
-string Base64Encode(const string &Str);
-string OutputInDepth(const unsigned long Depth, const char* Separator="  ");
-string URItoFileName(const string &URI);
-string TimeRFC1123(time_t Date);
+std::string DeEscapeString(const std::string &input);
+
+std::string SizeToStr(double Bytes);
+std::string TimeToStr(unsigned long Sec);
+std::string Base64Encode(const std::string &Str);
+std::string OutputInDepth(const unsigned long Depth, const char* Separator="  ");
+std::string URItoFileName(const std::string &URI);
+std::string TimeRFC1123(time_t Date);
 bool RFC1123StrToTime(const char* const str,time_t &time) __must_check;
 bool RFC1123StrToTime(const char* const str,time_t &time) __must_check;
 bool FTPMDTMStrToTime(const char* const str,time_t &time) __must_check;
 bool FTPMDTMStrToTime(const char* const str,time_t &time) __must_check;
-__deprecated bool StrToTime(const string &Val,time_t &Result);
-string LookupTag(const string &Message,const char *Tag,const char *Default = 0);
-int StringToBool(const string &Text,int Default = -1);
-bool ReadMessages(int Fd, vector<string> &List);
+__deprecated bool StrToTime(const std::string &Val,time_t &Result);
+std::string LookupTag(const std::string &Message,const char *Tag,const char *Default = 0);
+int StringToBool(const std::string &Text,int Default = -1);
+bool ReadMessages(int Fd, std::vector<std::string> &List);
 bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base = 0);
 bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base = 0);
+bool StrToNum(const char *Str,unsigned long long &Res,unsigned Len,unsigned Base = 0);
 bool Base256ToNum(const char *Str,unsigned long &Res,unsigned int Len);
 bool Base256ToNum(const char *Str,unsigned long &Res,unsigned int Len);
-bool Hex2Num(const string &Str,unsigned char *Num,unsigned int Length);
+bool Hex2Num(const std::string &Str,unsigned char *Num,unsigned int Length);
 bool TokSplitString(char Tok,char *Input,char **List,
 bool TokSplitString(char Tok,char *Input,char **List,
 		    unsigned long ListMax);
 		    unsigned long ListMax);
-vector<string> VectorizeString(string const &haystack, char const &split) __attrib_const;
-void ioprintf(ostream &out,const char *format,...) __like_printf(2);
-void strprintf(string &out,const char *format,...) __like_printf(2);
+std::vector<std::string> VectorizeString(std::string const &haystack, char const &split) __attrib_const;
+void ioprintf(std::ostream &out,const char *format,...) __like_printf(2);
+void strprintf(std::string &out,const char *format,...) __like_printf(2);
 char *safe_snprintf(char *Buffer,char *End,const char *Format,...) __like_printf(3);
 char *safe_snprintf(char *Buffer,char *End,const char *Format,...) __like_printf(3);
-bool CheckDomainList(const string &Host, const string &List);
+bool CheckDomainList(const std::string &Host, const std::string &List);
 int tolower_ascii(int const c) __attrib_const __hot;
 int tolower_ascii(int const c) __attrib_const __hot;
-string StripEpoch(const string &VerStr);
+std::string StripEpoch(const std::string &VerStr);
 
 
 #define APT_MKSTRCMP(name,func) \
 #define APT_MKSTRCMP(name,func) \
 inline int name(const char *A,const char *B) {return func(A,A+strlen(A),B,B+strlen(B));}; \
 inline int name(const char *A,const char *B) {return func(A,A+strlen(A),B,B+strlen(B));}; \
 inline int name(const char *A,const char *AEnd,const char *B) {return func(A,AEnd,B,B+strlen(B));}; \
 inline int name(const char *A,const char *AEnd,const char *B) {return func(A,AEnd,B,B+strlen(B));}; \
-inline int name(const string& A,const char *B) {return func(A.c_str(),A.c_str()+A.length(),B,B+strlen(B));}; \
-inline int name(const string& A,const string& B) {return func(A.c_str(),A.c_str()+A.length(),B.c_str(),B.c_str()+B.length());}; \
-inline int name(const string& A,const char *B,const char *BEnd) {return func(A.c_str(),A.c_str()+A.length(),B,BEnd);};
+inline int name(const std::string& A,const char *B) {return func(A.c_str(),A.c_str()+A.length(),B,B+strlen(B));}; \
+inline int name(const std::string& A,const std::string& B) {return func(A.c_str(),A.c_str()+A.length(),B.c_str(),B.c_str()+B.length());}; \
+inline int name(const std::string& A,const char *B,const char *BEnd) {return func(A.c_str(),A.c_str()+A.length(),B,BEnd);};
 
 
 #define APT_MKSTRCMP2(name,func) \
 #define APT_MKSTRCMP2(name,func) \
 inline int name(const char *A,const char *AEnd,const char *B) {return func(A,AEnd,B,B+strlen(B));}; \
 inline int name(const char *A,const char *AEnd,const char *B) {return func(A,AEnd,B,B+strlen(B));}; \
-inline int name(const string& A,const char *B) {return func(A.begin(),A.end(),B,B+strlen(B));}; \
-inline int name(const string& A,const string& B) {return func(A.begin(),A.end(),B.begin(),B.end());}; \
-inline int name(const string& A,const char *B,const char *BEnd) {return func(A.begin(),A.end(),B,BEnd);};
+inline int name(const std::string& A,const char *B) {return func(A.begin(),A.end(),B,B+strlen(B));}; \
+inline int name(const std::string& A,const std::string& B) {return func(A.begin(),A.end(),B.begin(),B.end());}; \
+inline int name(const std::string& A,const char *B,const char *BEnd) {return func(A.begin(),A.end(),B,BEnd);};
 
 
 int stringcmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
 int stringcmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
 int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
 int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
@@ -88,17 +91,17 @@ int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd)
    case the definition of string::const_iterator is not the same as
    case the definition of string::const_iterator is not the same as
    const char * and we need these extra functions */
    const char * and we need these extra functions */
 #if __GNUC__ >= 3
 #if __GNUC__ >= 3
-int stringcmp(string::const_iterator A,string::const_iterator AEnd,
+int stringcmp(std::string::const_iterator A,std::string::const_iterator AEnd,
 	      const char *B,const char *BEnd);
 	      const char *B,const char *BEnd);
-int stringcmp(string::const_iterator A,string::const_iterator AEnd,
-	      string::const_iterator B,string::const_iterator BEnd);
-int stringcasecmp(string::const_iterator A,string::const_iterator AEnd,
+int stringcmp(std::string::const_iterator A,std::string::const_iterator AEnd,
+	      std::string::const_iterator B,std::string::const_iterator BEnd);
+int stringcasecmp(std::string::const_iterator A,std::string::const_iterator AEnd,
 		  const char *B,const char *BEnd);
 		  const char *B,const char *BEnd);
-int stringcasecmp(string::const_iterator A,string::const_iterator AEnd,
-                  string::const_iterator B,string::const_iterator BEnd);
+int stringcasecmp(std::string::const_iterator A,std::string::const_iterator AEnd,
+                  std::string::const_iterator B,std::string::const_iterator BEnd);
 
 
-inline int stringcmp(string::const_iterator A,string::const_iterator Aend,const char *B) {return stringcmp(A,Aend,B,B+strlen(B));};
-inline int stringcasecmp(string::const_iterator A,string::const_iterator Aend,const char *B) {return stringcasecmp(A,Aend,B,B+strlen(B));};
+inline int stringcmp(std::string::const_iterator A,std::string::const_iterator Aend,const char *B) {return stringcmp(A,Aend,B,B+strlen(B));};
+inline int stringcasecmp(std::string::const_iterator A,std::string::const_iterator Aend,const char *B) {return stringcasecmp(A,Aend,B,B+strlen(B));};
 #endif
 #endif
 
 
 APT_MKSTRCMP2(stringcmp,stringcmp);
 APT_MKSTRCMP2(stringcmp,stringcmp);
@@ -108,34 +111,34 @@ inline const char *DeNull(const char *s) {return (s == 0?"(null)":s);};
 
 
 class URI
 class URI
 {
 {
-   void CopyFrom(const string &From);
+   void CopyFrom(const std::string &From);
 		 
 		 
    public:
    public:
    
    
-   string Access;
-   string User;
-   string Password;
-   string Host;
-   string Path;
+   std::string Access;
+   std::string User;
+   std::string Password;
+   std::string Host;
+   std::string Path;
    unsigned int Port;
    unsigned int Port;
    
    
-   operator string();
-   inline void operator =(const string &From) {CopyFrom(From);};
+   operator std::string();
+   inline void operator =(const std::string &From) {CopyFrom(From);};
    inline bool empty() {return Access.empty();};
    inline bool empty() {return Access.empty();};
-   static string SiteOnly(const string &URI);
-   static string NoUserPassword(const string &URI);
+   static std::string SiteOnly(const std::string &URI);
+   static std::string NoUserPassword(const std::string &URI);
    
    
-   URI(string Path) {CopyFrom(Path);};
+   URI(std::string Path) {CopyFrom(Path);};
    URI() : Port(0) {};
    URI() : Port(0) {};
 };
 };
 
 
 struct SubstVar
 struct SubstVar
 {
 {
    const char *Subst;
    const char *Subst;
-   const string *Contents;
+   const std::string *Contents;
 };
 };
-string SubstVar(string Str,const struct SubstVar *Vars);
-string SubstVar(const string &Str,const string &Subst,const string &Contents);
+std::string SubstVar(std::string Str,const struct SubstVar *Vars);
+std::string SubstVar(const std::string &Str,const std::string &Subst,const std::string &Contents);
 
 
 struct RxChoiceList
 struct RxChoiceList
 {
 {

+ 16 - 21
apt-pkg/deb/debindexfile.cc

@@ -9,6 +9,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/debindexfile.h>
 #include <apt-pkg/debindexfile.h>
 #include <apt-pkg/debsrcrecords.h>
 #include <apt-pkg/debsrcrecords.h>
 #include <apt-pkg/deblistparser.h>
 #include <apt-pkg/deblistparser.h>
@@ -24,6 +26,8 @@
 #include <sys/stat.h>
 #include <sys/stat.h>
 									/*}}}*/
 									/*}}}*/
 
 
+using std::string;
+
 // SourcesIndex::debSourcesIndex - Constructor				/*{{{*/
 // SourcesIndex::debSourcesIndex - Constructor				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -157,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();
 
 
@@ -286,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();
 
 
@@ -303,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)
@@ -317,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());
@@ -487,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();
 
 
@@ -507,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;
@@ -519,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());
@@ -588,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);
@@ -602,11 +600,8 @@ bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 
 
    // 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("now");
    CFile->Archive = Gen.WriteUniqString("now");
    
    
    if (Gen.MergeList(Parser) == false)
    if (Gen.MergeList(Parser) == false)

+ 53 - 35
apt-pkg/deb/debindexfile.h

@@ -22,46 +22,55 @@
 
 
 class debStatusIndex : public pkgIndexFile
 class debStatusIndex : public pkgIndexFile
 {
 {
-   string File;
-   
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+
+   protected:
+   std::string File;
+
    public:
    public:
 
 
    virtual const Type *GetType() const;
    virtual const Type *GetType() const;
    
    
    // Interface for acquire
    // Interface for acquire
-   virtual string Describe(bool Short) const {return File;};
+   virtual std::string Describe(bool Short) const {return File;};
    
    
    // Interface for the Cache Generator
    // Interface for the Cache Generator
    virtual bool Exists() const;
    virtual bool Exists() const;
    virtual bool HasPackages() const {return true;};
    virtual bool HasPackages() const {return true;};
    virtual unsigned long Size() const;
    virtual unsigned long Size() const;
    virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const;
    virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const;
+   bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog, unsigned long const Flag) const;
    virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const;
    virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const;
 
 
-   debStatusIndex(string File);
+   debStatusIndex(std::string File);
+   virtual ~debStatusIndex() {};
 };
 };
     
     
 class debPackagesIndex : public pkgIndexFile
 class debPackagesIndex : public pkgIndexFile
 {
 {
-   string URI;
-   string Dist;
-   string Section;
-   string Architecture;
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
 
 
-   string Info(const char *Type) const;
-   string IndexFile(const char *Type) const;
-   string IndexURI(const char *Type) const;
+   std::string URI;
+   std::string Dist;
+   std::string Section;
+   std::string Architecture;
+
+   std::string Info(const char *Type) const;
+   std::string IndexFile(const char *Type) const;
+   std::string IndexURI(const char *Type) const;
    
    
    public:
    public:
    
    
    virtual const Type *GetType() const;
    virtual const Type *GetType() const;
 
 
    // Stuff for accessing files on remote items
    // Stuff for accessing files on remote items
-   virtual string ArchiveInfo(pkgCache::VerIterator Ver) const;
-   virtual string ArchiveURI(string File) const {return URI + File;};
+   virtual std::string ArchiveInfo(pkgCache::VerIterator Ver) const;
+   virtual std::string ArchiveURI(std::string File) const {return URI + File;};
    
    
    // Interface for acquire
    // Interface for acquire
-   virtual string Describe(bool Short) const;   
+   virtual std::string Describe(bool Short) const;   
    
    
    // Interface for the Cache Generator
    // Interface for the Cache Generator
    virtual bool Exists() const;
    virtual bool Exists() const;
@@ -70,29 +79,33 @@ class debPackagesIndex : public pkgIndexFile
    virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const;
    virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const;
    virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const;
    virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const;
 
 
-   debPackagesIndex(string const &URI, string const &Dist, string const &Section,
-			bool const &Trusted, string const &Arch = "native");
+   debPackagesIndex(std::string const &URI, std::string const &Dist, std::string const &Section,
+			bool const &Trusted, std::string const &Arch = "native");
+   virtual ~debPackagesIndex() {};
 };
 };
 
 
 class debTranslationsIndex : public pkgIndexFile
 class debTranslationsIndex : public pkgIndexFile
 {
 {
-   string URI;
-   string Dist;
-   string Section;
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+
+   std::string URI;
+   std::string Dist;
+   std::string Section;
    const char * const Language;
    const char * const Language;
    
    
-   string Info(const char *Type) const;
-   string IndexFile(const char *Type) const;
-   string IndexURI(const char *Type) const;
+   std::string Info(const char *Type) const;
+   std::string IndexFile(const char *Type) const;
+   std::string IndexURI(const char *Type) const;
 
 
-   inline string TranslationFile() const {return string("Translation-").append(Language);};
+   inline std::string TranslationFile() const {return std::string("Translation-").append(Language);};
 
 
    public:
    public:
    
    
    virtual const Type *GetType() const;
    virtual const Type *GetType() const;
 
 
    // Interface for acquire
    // Interface for acquire
-   virtual string Describe(bool Short) const;   
+   virtual std::string Describe(bool Short) const;   
    virtual bool GetIndexes(pkgAcquire *Owner) const;
    virtual bool GetIndexes(pkgAcquire *Owner) const;
    
    
    // Interface for the Cache Generator
    // Interface for the Cache Generator
@@ -102,30 +115,34 @@ class debTranslationsIndex : public pkgIndexFile
    virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const;
    virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const;
    virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const;
    virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const;
 
 
-   debTranslationsIndex(string URI,string Dist,string Section, char const * const Language);
+   debTranslationsIndex(std::string URI,std::string Dist,std::string Section, char const * const Language);
+   virtual ~debTranslationsIndex() {};
 };
 };
 
 
 class debSourcesIndex : public pkgIndexFile
 class debSourcesIndex : public pkgIndexFile
 {
 {
-   string URI;
-   string Dist;
-   string Section;
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+
+   std::string URI;
+   std::string Dist;
+   std::string Section;
 
 
-   string Info(const char *Type) const;
-   string IndexFile(const char *Type) const;
-   string IndexURI(const char *Type) const;
+   std::string Info(const char *Type) const;
+   std::string IndexFile(const char *Type) const;
+   std::string IndexURI(const char *Type) const;
    
    
    public:
    public:
 
 
    virtual const Type *GetType() const;
    virtual const Type *GetType() const;
 
 
    // Stuff for accessing files on remote items
    // Stuff for accessing files on remote items
-   virtual string SourceInfo(pkgSrcRecords::Parser const &Record,
+   virtual std::string SourceInfo(pkgSrcRecords::Parser const &Record,
 			     pkgSrcRecords::File const &File) const;
 			     pkgSrcRecords::File const &File) const;
-   virtual string ArchiveURI(string File) const {return URI + File;};
+   virtual std::string ArchiveURI(std::string File) const {return URI + File;};
    
    
    // Interface for acquire
    // Interface for acquire
-   virtual string Describe(bool Short) const;   
+   virtual std::string Describe(bool Short) const;   
 
 
    // Interface for the record parsers
    // Interface for the record parsers
    virtual pkgSrcRecords::Parser *CreateSrcParser() const;
    virtual pkgSrcRecords::Parser *CreateSrcParser() const;
@@ -135,7 +152,8 @@ class debSourcesIndex : public pkgIndexFile
    virtual bool HasPackages() const {return false;};
    virtual bool HasPackages() const {return false;};
    virtual unsigned long Size() const;
    virtual unsigned long Size() const;
    
    
-   debSourcesIndex(string URI,string Dist,string Section,bool Trusted);
+   debSourcesIndex(std::string URI,std::string Dist,std::string Section,bool Trusted);
+   virtual ~debSourcesIndex() {};
 };
 };
 
 
 #endif
 #endif

+ 34 - 25
apt-pkg/deb/deblistparser.cc

@@ -10,11 +10,14 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/deblistparser.h>
 #include <apt-pkg/deblistparser.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
 #include <apt-pkg/crc-16.h>
 #include <apt-pkg/crc-16.h>
 #include <apt-pkg/md5.h>
 #include <apt-pkg/md5.h>
 #include <apt-pkg/macros.h>
 #include <apt-pkg/macros.h>
@@ -23,6 +26,8 @@
 #include <ctype.h>
 #include <ctype.h>
 									/*}}}*/
 									/*}}}*/
 
 
+using std::string;
+
 static debListParser::WordList PrioList[] = {{"important",pkgCache::State::Important},
 static debListParser::WordList PrioList[] = {{"important",pkgCache::State::Important},
                        {"required",pkgCache::State::Required},
                        {"required",pkgCache::State::Required},
                        {"standard",pkgCache::State::Standard},
                        {"standard",pkgCache::State::Standard},
@@ -69,10 +74,7 @@ string debListParser::Package() {
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This will return the Architecture of the package this section describes */
 /* This will return the Architecture of the package this section describes */
 string debListParser::Architecture() {
 string debListParser::Architecture() {
-   std::string const Arch = Section.FindS("Architecture");
-   if (Arch.empty() == true)
-      return _config->Find("APT::Architecture");
-   return Arch;
+   return Section.FindS("Architecture");
 }
 }
 									/*}}}*/
 									/*}}}*/
 // ListParser::ArchitectureAll						/*{{{*/
 // ListParser::ArchitectureAll						/*{{{*/
@@ -128,12 +130,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver)
    }
    }
 
 
    if (ArchitectureAll() == true)
    if (ArchitectureAll() == true)
-      switch (Ver->MultiArch)
-      {
-	 case pkgCache::Version::Foreign: Ver->MultiArch = pkgCache::Version::AllForeign; break;
-	 case pkgCache::Version::Allowed: Ver->MultiArch = pkgCache::Version::AllAllowed; break;
-	 default: Ver->MultiArch = pkgCache::Version::All;
-      }
+      Ver->MultiArch |= pkgCache::Version::All;
 
 
    // Archive Size
    // Archive Size
    Ver->Size = Section.FindULL("Size");
    Ver->Size = Section.FindULL("Size");
@@ -252,7 +249,7 @@ bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg,
       return false;
       return false;
 
 
    if (strcmp(Pkg.Name(),"apt") == 0)
    if (strcmp(Pkg.Name(),"apt") == 0)
-      Pkg->Flags |= pkgCache::Flag::Important;
+      Pkg->Flags |= pkgCache::Flag::Essential | pkgCache::Flag::Important;
    
    
    if (ParseStatus(Pkg,Ver) == false)
    if (ParseStatus(Pkg,Ver) == false)
       return false;
       return false;
@@ -678,6 +675,9 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
 	    return _error->Error("Problem parsing Provides line");
 	    return _error->Error("Problem parsing Provides line");
 	 if (Op != pkgCache::Dep::NoOp) {
 	 if (Op != pkgCache::Dep::NoOp) {
 	    _error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str());
 	    _error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str());
+	 } else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) {
+	    if (NewProvidesAllArch(Ver, Package, Version) == false)
+	       return false;
 	 } else {
 	 } else {
 	    if (NewProvides(Ver, Package, Arch, Version) == false)
 	    if (NewProvides(Ver, Package, Arch, Version) == false)
 	       return false;
 	       return false;
@@ -690,12 +690,12 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
 
 
    if (MultiArchEnabled == false)
    if (MultiArchEnabled == false)
       return true;
       return true;
-   else if (Ver->MultiArch == pkgCache::Version::Allowed || Ver->MultiArch == pkgCache::Version::AllAllowed)
+   else if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
    {
    {
       string const Package = string(Ver.ParentPkg().Name()).append(":").append("any");
       string const Package = string(Ver.ParentPkg().Name()).append(":").append("any");
       return NewProvidesAllArch(Ver, Package, Ver.VerStr());
       return NewProvidesAllArch(Ver, Package, Ver.VerStr());
    }
    }
-   else if (Ver->MultiArch == pkgCache::Version::Foreign || Ver->MultiArch == pkgCache::Version::AllForeign)
+   else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign)
       return NewProvidesAllArch(Ver, Ver.ParentPkg().Name(), Ver.VerStr());
       return NewProvidesAllArch(Ver, Ver.ParentPkg().Name(), Ver.VerStr());
 
 
    return true;
    return true;
@@ -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;
@@ -816,16 +817,16 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
       ++lineEnd;
       ++lineEnd;
 
 
       // which datastorage need to be updated
       // which datastorage need to be updated
-      map_ptrloc* writeTo = NULL;
+      enum { Suite, Component, Version, Origin, Codename, Label, None } writeTo = None;
       if (buffer[0] == ' ')
       if (buffer[0] == ' ')
 	 ;
 	 ;
-      #define APT_PARSER_WRITETO(X, Y) else if (strncmp(Y, buffer, len) == 0) writeTo = &X;
-      APT_PARSER_WRITETO(FileI->Archive, "Suite")
-      APT_PARSER_WRITETO(FileI->Component, "Component")
-      APT_PARSER_WRITETO(FileI->Version, "Version")
-      APT_PARSER_WRITETO(FileI->Origin, "Origin")
-      APT_PARSER_WRITETO(FileI->Codename, "Codename")
-      APT_PARSER_WRITETO(FileI->Label, "Label")
+      #define APT_PARSER_WRITETO(X) else if (strncmp(#X, buffer, len) == 0) writeTo = X;
+      APT_PARSER_WRITETO(Suite)
+      APT_PARSER_WRITETO(Component)
+      APT_PARSER_WRITETO(Version)
+      APT_PARSER_WRITETO(Origin)
+      APT_PARSER_WRITETO(Codename)
+      APT_PARSER_WRITETO(Label)
       #undef APT_PARSER_WRITETO
       #undef APT_PARSER_WRITETO
       #define APT_PARSER_FLAGIT(X) else if (strncmp(#X, buffer, len) == 0) \
       #define APT_PARSER_FLAGIT(X) else if (strncmp(#X, buffer, len) == 0) \
 	 pkgTagSection::FindFlag(FileI->Flags, pkgCache::Flag:: X, dataStart, lineEnd);
 	 pkgTagSection::FindFlag(FileI->Flags, pkgCache::Flag:: X, dataStart, lineEnd);
@@ -835,19 +836,19 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
 
 
       // load all data from the line and save it
       // load all data from the line and save it
       string data;
       string data;
-      if (writeTo != NULL)
+      if (writeTo != None)
 	 data.append(dataStart, dataEnd);
 	 data.append(dataStart, dataEnd);
       if (sizeof(buffer) - 1 == (dataEnd - buffer))
       if (sizeof(buffer) - 1 == (dataEnd - buffer))
       {
       {
 	 while (fgets(buffer, sizeof(buffer), release) != NULL)
 	 while (fgets(buffer, sizeof(buffer), release) != NULL)
 	 {
 	 {
-	    if (writeTo != NULL)
+	    if (writeTo != None)
 	       data.append(buffer);
 	       data.append(buffer);
 	    if (strlen(buffer) != sizeof(buffer) - 1)
 	    if (strlen(buffer) != sizeof(buffer) - 1)
 	       break;
 	       break;
 	 }
 	 }
       }
       }
-      if (writeTo != NULL)
+      if (writeTo != None)
       {
       {
 	 // remove spaces and stuff from the end of the data line
 	 // remove spaces and stuff from the end of the data line
 	 for (std::string::reverse_iterator s = data.rbegin();
 	 for (std::string::reverse_iterator s = data.rbegin();
@@ -857,7 +858,15 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
 	       break;
 	       break;
 	    *s = '\0';
 	    *s = '\0';
 	 }
 	 }
-	 *writeTo = WriteUniqString(data);
+	 switch (writeTo) {
+	 case Suite: FileI->Archive = WriteUniqString(data); break;
+	 case Component: FileI->Component = WriteUniqString(data); break;
+	 case Version: FileI->Version = WriteUniqString(data); break;
+	 case Origin: FileI->Origin = WriteUniqString(data); break;
+	 case Codename: FileI->Codename = WriteUniqString(data); break;
+	 case Label: FileI->Label = WriteUniqString(data); break;
+	 case None: break;
+	 }
       }
       }
    }
    }
    fclose(release);
    fclose(release);

+ 23 - 16
apt-pkg/deb/deblistparser.h

@@ -12,9 +12,12 @@
 #define PKGLIB_DEBLISTPARSER_H
 #define PKGLIB_DEBLISTPARSER_H
 
 
 #include <apt-pkg/pkgcachegen.h>
 #include <apt-pkg/pkgcachegen.h>
-#include <apt-pkg/indexfile.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:
@@ -25,36 +28,39 @@ class debListParser : public pkgCacheGenerator::ListParser
       const char *Str;
       const char *Str;
       unsigned char Val;
       unsigned char Val;
    };
    };
-   
+
    private:
    private:
-   
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+
+   protected:
    pkgTagFile Tags;
    pkgTagFile Tags;
    pkgTagSection Section;
    pkgTagSection Section;
    unsigned long iOffset;
    unsigned long iOffset;
-   string Arch;
+   std::string Arch;
    std::vector<std::string> Architectures;
    std::vector<std::string> Architectures;
    bool MultiArchEnabled;
    bool MultiArchEnabled;
 
 
    unsigned long UniqFindTagWrite(const char *Tag);
    unsigned long UniqFindTagWrite(const char *Tag);
-   bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver);
+   virtual bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver);
    bool ParseDepends(pkgCache::VerIterator &Ver,const char *Tag,
    bool ParseDepends(pkgCache::VerIterator &Ver,const char *Tag,
 		     unsigned int Type);
 		     unsigned int Type);
    bool ParseProvides(pkgCache::VerIterator &Ver);
    bool ParseProvides(pkgCache::VerIterator &Ver);
-   bool NewProvidesAllArch(pkgCache::VerIterator &Ver, string const &Package, string const &Version);
-   static bool GrabWord(string Word,WordList *List,unsigned char &Out);
+   bool NewProvidesAllArch(pkgCache::VerIterator &Ver, std::string const &Package, std::string const &Version);
+   static bool GrabWord(std::string Word,WordList *List,unsigned char &Out);
    
    
    public:
    public:
 
 
-   static unsigned char GetPrio(string Str);
+   static unsigned char GetPrio(std::string Str);
       
       
    // These all operate against the current section
    // These all operate against the current section
-   virtual string Package();
-   virtual string Architecture();
+   virtual std::string Package();
+   virtual std::string Architecture();
    virtual bool ArchitectureAll();
    virtual bool ArchitectureAll();
-   virtual string Version();
+   virtual std::string Version();
    virtual bool NewVersion(pkgCache::VerIterator &Ver);
    virtual bool NewVersion(pkgCache::VerIterator &Ver);
-   virtual string Description();
-   virtual string DescriptionLanguage();
+   virtual std::string Description();
+   virtual std::string DescriptionLanguage();
    virtual MD5SumValue Description_md5();
    virtual MD5SumValue Description_md5();
    virtual unsigned short VersionHash();
    virtual unsigned short VersionHash();
    virtual bool UsePackage(pkgCache::PkgIterator &Pkg,
    virtual bool UsePackage(pkgCache::PkgIterator &Pkg,
@@ -65,15 +71,16 @@ class debListParser : public pkgCacheGenerator::ListParser
    virtual bool Step();
    virtual bool Step();
    
    
    bool LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,FileFd &File,
    bool LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,FileFd &File,
-			string section);
+			std::string section);
    
    
    static const char *ParseDepends(const char *Start,const char *Stop,
    static const char *ParseDepends(const char *Start,const char *Stop,
-			    string &Package,string &Ver,unsigned int &Op,
+			    std::string &Package,std::string &Ver,unsigned int &Op,
 			    bool const &ParseArchFlags = false,
 			    bool const &ParseArchFlags = false,
 			    bool const &StripMultiArch = true);
 			    bool const &StripMultiArch = true);
    static const char *ConvertRelation(const char *I,unsigned int &Op);
    static const char *ConvertRelation(const char *I,unsigned int &Op);
 
 
-   debListParser(FileFd *File, string const &Arch = "");
+   debListParser(FileFd *File, std::string const &Arch = "");
+   virtual ~debListParser() {};
 };
 };
 
 
 #endif
 #endif

+ 46 - 31
apt-pkg/deb/debmetaindex.cc

@@ -1,11 +1,15 @@
 // ijones, walters
 // ijones, walters
+#include <config.h>
 
 
 #include <apt-pkg/debmetaindex.h>
 #include <apt-pkg/debmetaindex.h>
 #include <apt-pkg/debindexfile.h>
 #include <apt-pkg/debindexfile.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/aptconfiguration.h>
+#include <apt-pkg/indexrecords.h>
+#include <apt-pkg/sourcelist.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 
 
 #include <set>
 #include <set>
@@ -124,7 +128,7 @@ string debReleaseIndex::TranslationIndexURISuffix(const char *Type, const string
 {
 {
    string Res ="";
    string Res ="";
    if (Dist[Dist.size() - 1] != '/')
    if (Dist[Dist.size() - 1] != '/')
-      Res += Section + "/i18n/";
+      Res += Section + "/i18n/Translation-";
    return Res + Type;
    return Res + Type;
 }
 }
 
 
@@ -143,11 +147,13 @@ string debReleaseIndex::TranslationIndexURI(const char *Type, const string &Sect
       return URI + "dists/" + Dist + "/" + TranslationIndexURISuffix(Type, Section);
       return URI + "dists/" + Dist + "/" + TranslationIndexURISuffix(Type, Section);
 }
 }
 
 
-debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist) {
-	this->URI = URI;
-	this->Dist = Dist;
-	this->Indexes = NULL;
-	this->Type = "deb";
+debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist) :
+					metaIndex(URI, Dist, "deb"), Trusted(CHECK_TRUST)
+{}
+
+debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist, bool const Trusted) :
+					metaIndex(URI, Dist, "deb") {
+	SetTrusted(Trusted);
 }
 }
 
 
 debReleaseIndex::~debReleaseIndex() {
 debReleaseIndex::~debReleaseIndex() {
@@ -204,31 +210,17 @@ vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
 	if (lang.empty() == true)
 	if (lang.empty() == true)
 		return IndexTargets;
 		return IndexTargets;
 
 
-	// get the Translations:
-	// - if its a dists-style repository get the i18n/Index first
-	// - if its flat try to acquire files by guessing
-	if (Dist[Dist.size() - 1] == '/') {
-		for (std::set<std::string>::const_iterator s = sections.begin();
-		     s != sections.end(); ++s) {
-			for (std::vector<std::string>::const_iterator l = lang.begin();
-			     l != lang.end(); ++l) {
-				IndexTarget * Target = new OptionalIndexTarget();
-				Target->ShortDesc = "Translation-" + *l;
-				Target->MetaKey = TranslationIndexURISuffix(l->c_str(), *s);
-				Target->URI = TranslationIndexURI(l->c_str(), *s);
-				Target->Description = Info (Target->ShortDesc.c_str(), *s);
-				IndexTargets->push_back(Target);
-			}
-		}
-	} else {
-		for (std::set<std::string>::const_iterator s = sections.begin();
-		     s != sections.end(); ++s) {
+	// get the Translation-* files, later we will skip download of non-existent if we have an index
+	for (std::set<std::string>::const_iterator s = sections.begin();
+	     s != sections.end(); ++s) {
+		for (std::vector<std::string>::const_iterator l = lang.begin();
+		     l != lang.end(); ++l) {
 			IndexTarget * Target = new OptionalIndexTarget();
 			IndexTarget * Target = new OptionalIndexTarget();
-			Target->ShortDesc = "TranslationIndex";
-			Target->MetaKey = TranslationIndexURISuffix("Index", *s);
-			Target->URI = TranslationIndexURI("Index", *s);
+			Target->ShortDesc = "Translation-" + *l;
+			Target->MetaKey = TranslationIndexURISuffix(l->c_str(), *s);
+			Target->URI = TranslationIndexURI(l->c_str(), *s);
 			Target->Description = Info (Target->ShortDesc.c_str(), *s);
 			Target->Description = Info (Target->ShortDesc.c_str(), *s);
-			IndexTargets->push_back (Target);
+			IndexTargets->push_back(Target);
 		}
 		}
 	}
 	}
 
 
@@ -256,8 +248,22 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const
 	return true;
 	return true;
 }
 }
 
 
+void debReleaseIndex::SetTrusted(bool const Trusted)
+{
+	if (Trusted == true)
+		this->Trusted = ALWAYS_TRUSTED;
+	else
+		this->Trusted = NEVER_TRUSTED;
+}
+
 bool debReleaseIndex::IsTrusted() const
 bool debReleaseIndex::IsTrusted() const
 {
 {
+   if (Trusted == ALWAYS_TRUSTED)
+      return true;
+   else if (Trusted == NEVER_TRUSTED)
+      return false;
+
+
    if(_config->FindB("APT::Authentication::TrustCDROM", false))
    if(_config->FindB("APT::Authentication::TrustCDROM", false))
       if(URI.substr(0,strlen("cdrom:")) == "cdrom:")
       if(URI.substr(0,strlen("cdrom:")) == "cdrom:")
 	 return true;
 	 return true;
@@ -353,6 +359,7 @@ class debSLTypeDebian : public pkgSourceList::Type
       vector<string> const Archs =
       vector<string> const Archs =
 		(arch != Options.end()) ? VectorizeString(arch->second, ',') :
 		(arch != Options.end()) ? VectorizeString(arch->second, ',') :
 				APT::Configuration::getArchitectures();
 				APT::Configuration::getArchitectures();
+      map<string, string>::const_iterator const trusted = Options.find("trusted");
 
 
       for (vector<metaIndex *>::const_iterator I = List.begin();
       for (vector<metaIndex *>::const_iterator I = List.begin();
 	   I != List.end(); ++I)
 	   I != List.end(); ++I)
@@ -362,6 +369,9 @@ class debSLTypeDebian : public pkgSourceList::Type
 	    continue;
 	    continue;
 
 
 	 debReleaseIndex *Deb = (debReleaseIndex *) (*I);
 	 debReleaseIndex *Deb = (debReleaseIndex *) (*I);
+	 if (trusted != Options.end())
+	    Deb->SetTrusted(StringToBool(trusted->second, false));
+
 	 /* This check insures that there will be only one Release file
 	 /* This check insures that there will be only one Release file
 	    queued for all the Packages files and Sources files it
 	    queued for all the Packages files and Sources files it
 	    corresponds to. */
 	    corresponds to. */
@@ -379,9 +389,14 @@ class debSLTypeDebian : public pkgSourceList::Type
 	    return true;
 	    return true;
 	 }
 	 }
       }
       }
+
       // No currently created Release file indexes this entry, so we create a new one.
       // No currently created Release file indexes this entry, so we create a new one.
-      // XXX determine whether this release is trusted or not
-      debReleaseIndex *Deb = new debReleaseIndex(URI, Dist);
+      debReleaseIndex *Deb;
+      if (trusted != Options.end())
+	 Deb = new debReleaseIndex(URI, Dist, StringToBool(trusted->second, false));
+      else
+	 Deb = new debReleaseIndex(URI, Dist);
+
       if (IsSrc == true)
       if (IsSrc == true)
 	 Deb->PushSectionEntry ("source", new debReleaseIndex::debSectionEntry(Section, IsSrc));
 	 Deb->PushSectionEntry ("source", new debReleaseIndex::debSectionEntry(Section, IsSrc));
       else
       else

+ 32 - 22
apt-pkg/deb/debmetaindex.h

@@ -3,9 +3,14 @@
 #define PKGLIB_DEBMETAINDEX_H
 #define PKGLIB_DEBMETAINDEX_H
 
 
 #include <apt-pkg/metaindex.h>
 #include <apt-pkg/metaindex.h>
-#include <apt-pkg/sourcelist.h>
 
 
 #include <map>
 #include <map>
+#include <string>
+#include <vector>
+
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/sourcelist.h>
+#endif
 
 
 class debReleaseIndex : public metaIndex {
 class debReleaseIndex : public metaIndex {
    public:
    public:
@@ -13,38 +18,43 @@ class debReleaseIndex : public metaIndex {
    class debSectionEntry
    class debSectionEntry
    {
    {
       public:
       public:
-      debSectionEntry (string const &Section, bool const &IsSrc);
-      string const Section;
+      debSectionEntry (std::string const &Section, bool const &IsSrc);
+      std::string const Section;
       bool const IsSrc;
       bool const IsSrc;
    };
    };
 
 
    private:
    private:
-   std::map<string, vector<debSectionEntry const*> > ArchEntries;
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+   std::map<std::string, std::vector<debSectionEntry const*> > ArchEntries;
+   enum { ALWAYS_TRUSTED, NEVER_TRUSTED, CHECK_TRUST } Trusted;
 
 
    public:
    public:
 
 
-   debReleaseIndex(string const &URI, string const &Dist);
-   ~debReleaseIndex();
+   debReleaseIndex(std::string const &URI, std::string const &Dist);
+   debReleaseIndex(std::string const &URI, std::string const &Dist, bool const Trusted);
+   virtual ~debReleaseIndex();
 
 
-   virtual string ArchiveURI(string const &File) const {return URI + File;};
+   virtual std::string ArchiveURI(std::string const &File) const {return URI + File;};
    virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const;
    virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const;
-   vector <struct IndexTarget *>* ComputeIndexTargets() const;
-   string Info(const char *Type, string const &Section, string const &Arch="") const;
-   string MetaIndexInfo(const char *Type) const;
-   string MetaIndexFile(const char *Types) const;
-   string MetaIndexURI(const char *Type) const;
-   string IndexURI(const char *Type, string const &Section, string const &Arch="native") const;
-   string IndexURISuffix(const char *Type, string const &Section, string const &Arch="native") const;
-   string SourceIndexURI(const char *Type, const string &Section) const;
-   string SourceIndexURISuffix(const char *Type, const string &Section) const;
-   string TranslationIndexURI(const char *Type, const string &Section) const;
-   string TranslationIndexURISuffix(const char *Type, const string &Section) const;
-   virtual vector <pkgIndexFile *> *GetIndexFiles();
-
+   std::vector <struct IndexTarget *>* ComputeIndexTargets() const;
+   std::string Info(const char *Type, std::string const &Section, std::string const &Arch="") const;
+   std::string MetaIndexInfo(const char *Type) const;
+   std::string MetaIndexFile(const char *Types) const;
+   std::string MetaIndexURI(const char *Type) const;
+   std::string IndexURI(const char *Type, std::string const &Section, std::string const &Arch="native") const;
+   std::string IndexURISuffix(const char *Type, std::string const &Section, std::string const &Arch="native") const;
+   std::string SourceIndexURI(const char *Type, const std::string &Section) const;
+   std::string SourceIndexURISuffix(const char *Type, const std::string &Section) const;
+   std::string TranslationIndexURI(const char *Type, const std::string &Section) const;
+   std::string TranslationIndexURISuffix(const char *Type, const std::string &Section) const;
+   virtual std::vector <pkgIndexFile *> *GetIndexFiles();
+
+   void SetTrusted(bool const Trusted);
    virtual bool IsTrusted() const;
    virtual bool IsTrusted() const;
 
 
-   void PushSectionEntry(vector<string> const &Archs, const debSectionEntry *Entry);
-   void PushSectionEntry(string const &Arch, const debSectionEntry *Entry);
+   void PushSectionEntry(std::vector<std::string> const &Archs, const debSectionEntry *Entry);
+   void PushSectionEntry(std::string const &Arch, const debSectionEntry *Entry);
    void PushSectionEntry(const debSectionEntry *Entry);
    void PushSectionEntry(const debSectionEntry *Entry);
 };
 };
 
 

+ 27 - 4
apt-pkg/deb/debrecords.cc

@@ -8,18 +8,24 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/debrecords.h>
 #include <apt-pkg/debrecords.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/aptconfiguration.h>
+#include <apt-pkg/fileutl.h>
+
 #include <langinfo.h>
 #include <langinfo.h>
 									/*}}}*/
 									/*}}}*/
 
 
+using std::string;
+
 // RecordParser::debRecordParser - Constructor				/*{{{*/
 // RecordParser::debRecordParser - Constructor				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
 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)
 {
 {
@@ -77,7 +83,7 @@ string debRecordParser::SHA1Hash()
    return Section.FindS("SHA1");
    return Section.FindS("SHA1");
 }
 }
 									/*}}}*/
 									/*}}}*/
-// RecordParser::SHA1Hash - Return the archive hash			/*{{{*/
+// RecordParser::SHA256Hash - Return the archive hash			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
 string debRecordParser::SHA256Hash()
 string debRecordParser::SHA256Hash()
@@ -85,6 +91,14 @@ string debRecordParser::SHA256Hash()
    return Section.FindS("SHA256");
    return Section.FindS("SHA256");
 }
 }
 									/*}}}*/
 									/*}}}*/
+// RecordParser::SHA512Hash - Return the archive hash			/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string debRecordParser::SHA512Hash()
+{
+   return Section.FindS("SHA512");
+}
+									/*}}}*/
 // RecordParser::Maintainer - Return the maintainer email		/*{{{*/
 // RecordParser::Maintainer - Return the maintainer email		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -93,6 +107,15 @@ string debRecordParser::Maintainer()
    return Section.FindS("Maintainer");
    return Section.FindS("Maintainer");
 }
 }
 									/*}}}*/
 									/*}}}*/
+// RecordParser::RecordField - Return the value of an arbitrary field       /*{{*/
+// ---------------------------------------------------------------------
+/* */
+string debRecordParser::RecordField(const char *fieldName)
+{
+   return Section.FindS(fieldName);
+}
+
+                                                                        /*}}}*/
 // RecordParser::ShortDesc - Return a 1 line description		/*{{{*/
 // RecordParser::ShortDesc - Return a 1 line description		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -116,8 +139,8 @@ string debRecordParser::LongDesc()
      orig = Section.FindS("Description").c_str();
      orig = Section.FindS("Description").c_str();
   else
   else
   {
   {
-     vector<string> const lang = APT::Configuration::getLanguages();
-     for (vector<string>::const_iterator l = lang.begin();
+     std::vector<string> const lang = APT::Configuration::getLanguages();
+     for (std::vector<string>::const_iterator l = lang.begin();
 	  orig.empty() && l != lang.end(); ++l)
 	  orig.empty() && l != lang.end(); ++l)
 	orig = Section.FindS(string("Description-").append(*l).c_str());
 	orig = Section.FindS(string("Description-").append(*l).c_str());
   }
   }

+ 25 - 13
apt-pkg/deb/debrecords.h

@@ -15,11 +15,18 @@
 #define PKGLIB_DEBRECORDS_H
 #define PKGLIB_DEBRECORDS_H
 
 
 #include <apt-pkg/pkgrecords.h>
 #include <apt-pkg/pkgrecords.h>
-#include <apt-pkg/indexfile.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/tagfile.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) */
+   void *d;
+
    FileFd File;
    FileFd File;
    pkgTagFile Tags;
    pkgTagFile Tags;
    pkgTagSection Section;
    pkgTagSection Section;
@@ -32,23 +39,28 @@ class debRecordParser : public pkgRecords::Parser
    public:
    public:
 
 
    // These refer to the archive file for the Version
    // These refer to the archive file for the Version
-   virtual string FileName();
-   virtual string MD5Hash();
-   virtual string SHA1Hash();
-   virtual string SHA256Hash();
-   virtual string SourcePkg();
-   virtual string SourceVer();
+   virtual std::string FileName();
+   virtual std::string MD5Hash();
+   virtual std::string SHA1Hash();
+   virtual std::string SHA256Hash();
+   virtual std::string SHA512Hash();
+   virtual std::string SourcePkg();
+   virtual std::string SourceVer();
    
    
    // These are some general stats about the package
    // These are some general stats about the package
-   virtual string Maintainer();
-   virtual string ShortDesc();
-   virtual string LongDesc();
-   virtual string Name();
-   virtual string Homepage();
+   virtual std::string Maintainer();
+   virtual std::string ShortDesc();
+   virtual std::string LongDesc();
+   virtual std::string Name();
+   virtual std::string Homepage();
+
+   // An arbitrary custom field
+   virtual std::string RecordField(const char *fieldName);
 
 
    virtual void GetRec(const char *&Start,const char *&Stop);
    virtual void GetRec(const char *&Start,const char *&Stop);
    
    
-   debRecordParser(string FileName,pkgCache &Cache);
+   debRecordParser(std::string FileName,pkgCache &Cache);
+   virtual ~debRecordParser() {};
 };
 };
 
 
 #endif
 #endif

+ 30 - 19
apt-pkg/deb/debsrcrecords.cc

@@ -9,6 +9,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/deblistparser.h>
 #include <apt-pkg/deblistparser.h>
 #include <apt-pkg/debsrcrecords.h>
 #include <apt-pkg/debsrcrecords.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
@@ -19,6 +21,8 @@
 using std::max;
 using std::max;
 									/*}}}*/
 									/*}}}*/
 
 
+using std::string;
+
 // SrcRecordParser::Binaries - Return the binaries field		/*{{{*/
 // SrcRecordParser::Binaries - Return the binaries field		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This member parses the binaries field into a pair of class arrays and
 /* This member parses the binaries field into a pair of class arrays and
@@ -28,25 +32,32 @@ using std::max;
    used during scanning to find the right package */
    used during scanning to find the right package */
 const char **debSrcRecordParser::Binaries()
 const char **debSrcRecordParser::Binaries()
 {
 {
-   // This should use Start/Stop too, it is supposed to be efficient after all.
-   string Bins = Sect.FindS("Binary");
-   if (Bins.empty() == true || Bins.length() >= 102400)
-      return 0;
-   
-   if (Bins.length() >= BufSize)
-   {
-      delete [] Buffer;
-      // allocate new size based on buffer (but never smaller than 4000)
-      BufSize = max((unsigned int)4000, max((unsigned int)Bins.length()+1,2*BufSize));
-      Buffer = new char[BufSize];
-   }
+   const char *Start, *End;
+   if (Sect.Find("Binary", Start, End) == false)
+      return NULL;
+   for (; isspace(*Start) != 0; ++Start);
+   if (Start >= End)
+      return NULL;
+
+   StaticBinList.clear();
+   free(Buffer);
+   Buffer = strndup(Start, End - Start);
 
 
-   strcpy(Buffer,Bins.c_str());
-   if (TokSplitString(',',Buffer,StaticBinList,
-		      sizeof(StaticBinList)/sizeof(StaticBinList[0])) == false)
-      return 0;
+   char* bin = Buffer;
+   do {
+      char* binStartNext = strchrnul(bin, ',');
+      char* binEnd = binStartNext - 1;
+      for (; isspace(*binEnd) != 0; --binEnd)
+	 binEnd = '\0';
+      StaticBinList.push_back(bin);
+      if (*binStartNext != ',')
+	 break;
+      *binStartNext = '\0';
+      for (bin = binStartNext + 1; isspace(*bin) != 0; ++bin);
+   } while (*bin != '\0');
+   StaticBinList.push_back(NULL);
 
 
-   return (const char **)StaticBinList;
+   return (const char **) &StaticBinList[0];
 }
 }
 									/*}}}*/
 									/*}}}*/
 // SrcRecordParser::BuildDepends - Return the Build-Depends information	/*{{{*/
 // SrcRecordParser::BuildDepends - Return the Build-Depends information	/*{{{*/
@@ -55,7 +66,7 @@ const char **debSrcRecordParser::Binaries()
    package/version records representing the build dependency. The returned 
    package/version records representing the build dependency. The returned 
    array need not be freed and will be reused by the next call to this 
    array need not be freed and will be reused by the next call to this 
    function */
    function */
-bool debSrcRecordParser::BuildDepends(vector<pkgSrcRecords::Parser::BuildDepRec> &BuildDeps,
+bool debSrcRecordParser::BuildDepends(std::vector<pkgSrcRecords::Parser::BuildDepRec> &BuildDeps,
 					bool const &ArchOnly, bool const &StripMultiArch)
 					bool const &ArchOnly, bool const &StripMultiArch)
 {
 {
    unsigned int I;
    unsigned int I;
@@ -100,7 +111,7 @@ bool debSrcRecordParser::BuildDepends(vector<pkgSrcRecords::Parser::BuildDepRec>
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This parses the list of files and returns it, each file is required to have
 /* This parses the list of files and returns it, each file is required to have
    a complete source package */
    a complete source package */
-bool debSrcRecordParser::Files(vector<pkgSrcRecords::File> &List)
+bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List)
 {
 {
    List.erase(List.begin(),List.end());
    List.erase(List.begin(),List.end());
    
    

+ 16 - 14
apt-pkg/deb/debsrcrecords.h

@@ -18,13 +18,15 @@
 
 
 class debSrcRecordParser : public pkgSrcRecords::Parser
 class debSrcRecordParser : public pkgSrcRecords::Parser
 {
 {
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+
    FileFd Fd;
    FileFd Fd;
    pkgTagFile Tags;
    pkgTagFile Tags;
    pkgTagSection Sect;
    pkgTagSection Sect;
-   char *StaticBinList[400];
+   std::vector<const char*> StaticBinList;
    unsigned long iOffset;
    unsigned long iOffset;
    char *Buffer;
    char *Buffer;
-   unsigned int BufSize;
    
    
    public:
    public:
 
 
@@ -32,25 +34,25 @@ class debSrcRecordParser : public pkgSrcRecords::Parser
    virtual bool Step() {iOffset = Tags.Offset(); return Tags.Step(Sect);};
    virtual bool Step() {iOffset = Tags.Offset(); return Tags.Step(Sect);};
    virtual bool Jump(unsigned long const &Off) {iOffset = Off; return Tags.Jump(Sect,Off);};
    virtual bool Jump(unsigned long const &Off) {iOffset = Off; return Tags.Jump(Sect,Off);};
 
 
-   virtual string Package() const {return Sect.FindS("Package");};
-   virtual string Version() const {return Sect.FindS("Version");};
-   virtual string Maintainer() const {return Sect.FindS("Maintainer");};
-   virtual string Section() const {return Sect.FindS("Section");};
+   virtual std::string Package() const {return Sect.FindS("Package");};
+   virtual std::string Version() const {return Sect.FindS("Version");};
+   virtual std::string Maintainer() const {return Sect.FindS("Maintainer");};
+   virtual std::string Section() const {return Sect.FindS("Section");};
    virtual const char **Binaries();
    virtual const char **Binaries();
-   virtual bool BuildDepends(vector<BuildDepRec> &BuildDeps, bool const &ArchOnly, bool const &StripMultiArch = true);
+   virtual bool BuildDepends(std::vector<BuildDepRec> &BuildDeps, bool const &ArchOnly, bool const &StripMultiArch = true);
    virtual unsigned long Offset() {return iOffset;};
    virtual unsigned long Offset() {return iOffset;};
-   virtual string AsStr() 
+   virtual std::string AsStr() 
    {
    {
       const char *Start=0,*Stop=0;
       const char *Start=0,*Stop=0;
       Sect.GetSection(Start,Stop);
       Sect.GetSection(Start,Stop);
-      return string(Start,Stop);
+      return std::string(Start,Stop);
    };
    };
-   virtual bool Files(vector<pkgSrcRecords::File> &F);
+   virtual bool Files(std::vector<pkgSrcRecords::File> &F);
 
 
-   debSrcRecordParser(string const &File,pkgIndexFile const *Index) 
-      : Parser(Index), Fd(File,FileFd::ReadOnlyGzip), Tags(&Fd,102400), 
-        Buffer(0), BufSize(0) {}
-   ~debSrcRecordParser();
+   debSrcRecordParser(std::string const &File,pkgIndexFile const *Index) 
+      : Parser(Index), Fd(File,FileFd::ReadOnly, FileFd::Extension), Tags(&Fd,102400), 
+        Buffer(NULL) {}
+   virtual ~debSrcRecordParser();
 };
 };
 
 
 #endif
 #endif

+ 43 - 28
apt-pkg/deb/debsystem.cc

@@ -10,6 +10,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/debsystem.h>
 #include <apt-pkg/debsystem.h>
 #include <apt-pkg/debversion.h>
 #include <apt-pkg/debversion.h>
 #include <apt-pkg/debindexfile.h>
 #include <apt-pkg/debindexfile.h>
@@ -17,24 +19,36 @@
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
-#include <apti18n.h>
 #include <sys/types.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <unistd.h>
 #include <dirent.h>
 #include <dirent.h>
 #include <errno.h>
 #include <errno.h>
+
+#include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 
 
+using std::string;
+
 debSystem debSys;
 debSystem debSys;
 
 
+class debSystemPrivate {
+public:
+   debSystemPrivate() : LockFD(-1), LockCount(0), StatusFile(0)
+   {
+   }
+   // For locking support
+   int LockFD;
+   unsigned LockCount;
+   
+   debStatusIndex *StatusFile;
+};
+
 // System::debSystem - Constructor					/*{{{*/
 // System::debSystem - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
 debSystem::debSystem()
 debSystem::debSystem()
 {
 {
-   LockFD = -1;
-   LockCount = 0;
-   StatusFile = 0;
-   
+   d = new debSystemPrivate();
    Label = "Debian dpkg interface";
    Label = "Debian dpkg interface";
    VS = &debVS;
    VS = &debVS;
 }
 }
@@ -44,7 +58,8 @@ debSystem::debSystem()
 /* */
 /* */
 debSystem::~debSystem()
 debSystem::~debSystem()
 {
 {
-   delete StatusFile;
+   delete d->StatusFile;
+   delete d;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // System::Lock - Get the lock						/*{{{*/
 // System::Lock - Get the lock						/*{{{*/
@@ -54,16 +69,16 @@ debSystem::~debSystem()
 bool debSystem::Lock()
 bool debSystem::Lock()
 {
 {
    // Disable file locking
    // Disable file locking
-   if (_config->FindB("Debug::NoLocking",false) == true || LockCount > 1)
+   if (_config->FindB("Debug::NoLocking",false) == true || d->LockCount > 1)
    {
    {
-      LockCount++;
+      d->LockCount++;
       return true;
       return true;
    }
    }
 
 
    // Create the lockfile
    // Create the lockfile
    string AdminDir = flNotFile(_config->Find("Dir::State::status"));
    string AdminDir = flNotFile(_config->Find("Dir::State::status"));
-   LockFD = GetLock(AdminDir + "lock");
-   if (LockFD == -1)
+   d->LockFD = GetLock(AdminDir + "lock");
+   if (d->LockFD == -1)
    {
    {
       if (errno == EACCES || errno == EAGAIN)
       if (errno == EACCES || errno == EAGAIN)
 	 return _error->Error(_("Unable to lock the administration directory (%s), "
 	 return _error->Error(_("Unable to lock the administration directory (%s), "
@@ -76,8 +91,8 @@ bool debSystem::Lock()
    // See if we need to abort with a dirty journal
    // See if we need to abort with a dirty journal
    if (CheckUpdates() == true)
    if (CheckUpdates() == true)
    {
    {
-      close(LockFD);
-      LockFD = -1;
+      close(d->LockFD);
+      d->LockFD = -1;
       const char *cmd;
       const char *cmd;
       if (getenv("SUDO_USER") != NULL)
       if (getenv("SUDO_USER") != NULL)
 	 cmd = "sudo dpkg --configure -a";
 	 cmd = "sudo dpkg --configure -a";
@@ -89,7 +104,7 @@ bool debSystem::Lock()
                              "run '%s' to correct the problem. "), cmd);
                              "run '%s' to correct the problem. "), cmd);
    }
    }
 
 
-	 LockCount++;
+	 d->LockCount++;
       
       
    return true;
    return true;
 }
 }
@@ -99,15 +114,15 @@ bool debSystem::Lock()
 /* */
 /* */
 bool debSystem::UnLock(bool NoErrors)
 bool debSystem::UnLock(bool NoErrors)
 {
 {
-   if (LockCount == 0 && NoErrors == true)
+   if (d->LockCount == 0 && NoErrors == true)
       return false;
       return false;
    
    
-   if (LockCount < 1)
+   if (d->LockCount < 1)
       return _error->Error(_("Not locked"));
       return _error->Error(_("Not locked"));
-   if (--LockCount == 0)
+   if (--d->LockCount == 0)
    {
    {
-      close(LockFD);
-      LockCount = 0;
+      close(d->LockFD);
+      d->LockCount = 0;
    }
    }
    
    
    return true;
    return true;
@@ -168,9 +183,9 @@ bool debSystem::Initialize(Configuration &Cnf)
    Cnf.CndSet("Dir::State::status","/var/lib/dpkg/status");
    Cnf.CndSet("Dir::State::status","/var/lib/dpkg/status");
    Cnf.CndSet("Dir::Bin::dpkg","/usr/bin/dpkg");
    Cnf.CndSet("Dir::Bin::dpkg","/usr/bin/dpkg");
 
 
-   if (StatusFile) {
-     delete StatusFile;
-     StatusFile = 0;
+   if (d->StatusFile) {
+     delete d->StatusFile;
+     d->StatusFile = 0;
    }
    }
 
 
    return true;
    return true;
@@ -206,11 +221,11 @@ signed debSystem::Score(Configuration const &Cnf)
 // System::AddStatusFiles - Register the status files			/*{{{*/
 // System::AddStatusFiles - Register the status files			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-bool debSystem::AddStatusFiles(vector<pkgIndexFile *> &List)
+bool debSystem::AddStatusFiles(std::vector<pkgIndexFile *> &List)
 {
 {
-   if (StatusFile == 0)
-      StatusFile = new debStatusIndex(_config->FindFile("Dir::State::status"));
-   List.push_back(StatusFile);
+   if (d->StatusFile == 0)
+      d->StatusFile = new debStatusIndex(_config->FindFile("Dir::State::status"));
+   List.push_back(d->StatusFile);
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -220,11 +235,11 @@ bool debSystem::AddStatusFiles(vector<pkgIndexFile *> &List)
 bool debSystem::FindIndex(pkgCache::PkgFileIterator File,
 bool debSystem::FindIndex(pkgCache::PkgFileIterator File,
 			  pkgIndexFile *&Found) const
 			  pkgIndexFile *&Found) const
 {
 {
-   if (StatusFile == 0)
+   if (d->StatusFile == 0)
       return false;
       return false;
-   if (StatusFile->FindInCache(*File.Cache()) == File)
+   if (d->StatusFile->FindInCache(*File.Cache()) == File)
    {
    {
-      Found = StatusFile;
+      Found = d->StatusFile;
       return true;
       return true;
    }
    }
    
    

+ 8 - 7
apt-pkg/deb/debsystem.h

@@ -11,17 +11,18 @@
 #define PKGLIB_DEBSYSTEM_H
 #define PKGLIB_DEBSYSTEM_H
 
 
 #include <apt-pkg/pkgsystem.h>
 #include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/pkgcache.h>
 
 
+class debSystemPrivate;
 class debStatusIndex;
 class debStatusIndex;
+class pkgDepCache;
+
 class debSystem : public pkgSystem
 class debSystem : public pkgSystem
 {
 {
-   // For locking support
-   int LockFD;
-   unsigned LockCount;
+   // private d-pointer
+   debSystemPrivate *d;
    bool CheckUpdates();
    bool CheckUpdates();
-   
-   debStatusIndex *StatusFile;
-   
+
    public:
    public:
 
 
    virtual bool Lock();
    virtual bool Lock();
@@ -35,7 +36,7 @@ class debSystem : public pkgSystem
 			  pkgIndexFile *&Found) const;
 			  pkgIndexFile *&Found) const;
 
 
    debSystem();
    debSystem();
-   ~debSystem();
+   virtual ~debSystem();
 };
 };
 
 
 extern debSystem debSys;
 extern debSystem debSys;

+ 3 - 3
apt-pkg/deb/debversion.cc

@@ -10,7 +10,7 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
-#define APT_COMPATIBILITY 986
+#include <config.h>
 
 
 #include <apt-pkg/debversion.h>
 #include <apt-pkg/debversion.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
@@ -257,7 +257,7 @@ bool debVersioningSystem::CheckDep(const char *PkgVer,
 // debVS::UpstreamVersion - Return the upstream version string		/*{{{*/
 // debVS::UpstreamVersion - Return the upstream version string		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This strips all the debian specific information from the version number */
 /* This strips all the debian specific information from the version number */
-string debVersioningSystem::UpstreamVersion(const char *Ver)
+std::string debVersioningSystem::UpstreamVersion(const char *Ver)
 {
 {
    // Strip off the bit before the first colon
    // Strip off the bit before the first colon
    const char *I = Ver;
    const char *I = Ver;
@@ -272,6 +272,6 @@ string debVersioningSystem::UpstreamVersion(const char *Ver)
       if (*I == '-')
       if (*I == '-')
 	 Last = I - Ver;
 	 Last = I - Ver;
    
    
-   return string(Ver,Last);
+   return std::string(Ver,Last);
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 1 - 29
apt-pkg/deb/debversion.h

@@ -32,39 +32,11 @@ class debVersioningSystem : public pkgVersioningSystem
    {
    {
       return DoCmpVersion(A,Aend,B,Bend);
       return DoCmpVersion(A,Aend,B,Bend);
    }   
    }   
-   virtual string UpstreamVersion(const char *A);
+   virtual std::string UpstreamVersion(const char *A);
 
 
    debVersioningSystem();
    debVersioningSystem();
 };
 };
 
 
 extern debVersioningSystem debVS;
 extern debVersioningSystem debVS;
 
 
-#ifdef APT_COMPATIBILITY
-#if APT_COMPATIBILITY != 986
-#warning "Using APT_COMPATIBILITY"
-#endif
-
-inline int pkgVersionCompare(const char *A, const char *B)
-{
-   return debVS.CmpVersion(A,B);
-}
-inline int pkgVersionCompare(const char *A, const char *AEnd, 
-			     const char *B, const char *BEnd)
-{
-   return debVS.DoCmpVersion(A,AEnd,B,BEnd);
-}
-inline int pkgVersionCompare(string A,string B)
-{
-   return debVS.CmpVersion(A,B);
-}
-inline bool pkgCheckDep(const char *DepVer,const char *PkgVer,int Op)
-{
-   return debVS.CheckDep(PkgVer,Op,DepVer);
-}
-inline string pkgBaseVersion(const char *Ver)
-{
-   return debVS.UpstreamVersion(Ver);
-}
-#endif
-
 #endif
 #endif

+ 227 - 99
apt-pkg/deb/dpkgpm.cc

@@ -8,6 +8,8 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Includes								/*{{{*/
 // Includes								/*{{{*/
+#include <config.h>
+
 #include <apt-pkg/dpkgpm.h>
 #include <apt-pkg/dpkgpm.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
@@ -16,6 +18,7 @@
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/cachefile.h>
 #include <apt-pkg/cachefile.h>
+#include <apt-pkg/packagemanager.h>
 
 
 #include <unistd.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdlib.h>
@@ -40,12 +43,28 @@
 #include <sys/ioctl.h>
 #include <sys/ioctl.h>
 #include <pty.h>
 #include <pty.h>
 
 
-#include <config.h>
 #include <apti18n.h>
 #include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 
 
 using namespace std;
 using namespace std;
 
 
+class pkgDPkgPMPrivate 
+{
+public:
+   pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0),
+			term_out(NULL), history_out(NULL)
+   {
+      dpkgbuf[0] = '\0';
+   }
+   bool stdin_is_dev_null;
+   // the buffer we use for the dpkg status-fd reading
+   char dpkgbuf[1024];
+   int dpkgbuf_pos;
+   FILE *term_out;
+   FILE *history_out;
+   string dpkg_error;
+};
+
 namespace
 namespace
 {
 {
   // Maps the dpkg "processing" info to human readable names.  Entry 0
   // Maps the dpkg "processing" info to human readable names.  Entry 0
@@ -91,7 +110,7 @@ ionice(int PID)
 {
 {
    if (!FileExists("/usr/bin/ionice"))
    if (!FileExists("/usr/bin/ionice"))
       return false;
       return false;
-   pid_t Process = ExecFork();      
+   pid_t Process = ExecFork();
    if (Process == 0)
    if (Process == 0)
    {
    {
       char buf[32];
       char buf[32];
@@ -106,13 +125,52 @@ ionice(int PID)
    return ExecWait(Process, "ionice");
    return ExecWait(Process, "ionice");
 }
 }
 
 
+// dpkgChrootDirectory - chrooting for dpkg if needed			/*{{{*/
+static void dpkgChrootDirectory()
+{
+   std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory");
+   if (chrootDir == "/")
+      return;
+   std::cerr << "Chrooting into " << chrootDir << std::endl;
+   if (chroot(chrootDir.c_str()) != 0)
+      _exit(100);
+}
+									/*}}}*/
+
+
+// FindNowVersion - Helper to find a Version in "now" state	/*{{{*/
+// ---------------------------------------------------------------------
+/* This is helpful when a package is no longer installed but has residual 
+ * config files
+ */
+static 
+pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg)
+{
+   pkgCache::VerIterator Ver;
+   for (Ver = Pkg.VersionList(); Ver.end() == false; Ver++)
+   {
+      pkgCache::VerFileIterator Vf = Ver.FileList();
+      pkgCache::PkgFileIterator F = Vf.File();
+      for (F = Vf.File(); F.end() == false; F++)
+      {
+         if (F && F.Archive())
+         {
+            if (strcmp(F.Archive(), "now")) 
+               return Ver;
+         }
+      }
+   }
+   return Ver;
+}
+									/*}}}*/
+
 // DPkgPM::pkgDPkgPM - Constructor					/*{{{*/
 // DPkgPM::pkgDPkgPM - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
 pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) 
 pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) 
-   : pkgPackageManager(Cache), dpkgbuf_pos(0),
-     term_out(NULL), history_out(NULL), PackagesDone(0), PackagesTotal(0)
+   : pkgPackageManager(Cache), PackagesDone(0), PackagesTotal(0)
 {
 {
+   d = new pkgDPkgPMPrivate();
 }
 }
 									/*}}}*/
 									/*}}}*/
 // DPkgPM::pkgDPkgPM - Destructor					/*{{{*/
 // DPkgPM::pkgDPkgPM - Destructor					/*{{{*/
@@ -120,6 +178,7 @@ pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache)
 /* */
 /* */
 pkgDPkgPM::~pkgDPkgPM()
 pkgDPkgPM::~pkgDPkgPM()
 {
 {
+   delete d;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // DPkgPM::Install - Install a package					/*{{{*/
 // DPkgPM::Install - Install a package					/*{{{*/
@@ -310,15 +369,7 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
 	 SetCloseExec(STDIN_FILENO,false);      
 	 SetCloseExec(STDIN_FILENO,false);      
 	 SetCloseExec(STDERR_FILENO,false);
 	 SetCloseExec(STDERR_FILENO,false);
 
 
-	 if (_config->FindDir("DPkg::Chroot-Directory","/") != "/") 
-	 {
-	    std::cerr << "Chrooting into " 
-		      << _config->FindDir("DPkg::Chroot-Directory") 
-		      << std::endl;
-	    if (chroot(_config->FindDir("DPkg::Chroot-Directory","/").c_str()) != 0)
-	       _exit(100);
-	 }
-
+	 dpkgChrootDirectory();
 	 const char *Args[4];
 	 const char *Args[4];
 	 Args[0] = "/bin/sh";
 	 Args[0] = "/bin/sh";
 	 Args[1] = "-c";
 	 Args[1] = "-c";
@@ -374,9 +425,9 @@ void pkgDPkgPM::DoStdin(int master)
    unsigned char input_buf[256] = {0,}; 
    unsigned char input_buf[256] = {0,}; 
    ssize_t len = read(0, input_buf, sizeof(input_buf));
    ssize_t len = read(0, input_buf, sizeof(input_buf));
    if (len)
    if (len)
-      write(master, input_buf, len);
+      FileFd::Write(master, input_buf, len);
    else
    else
-      stdin_is_dev_null = true;
+      d->stdin_is_dev_null = true;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // DPkgPM::DoTerminalPty - Read the terminal pty and write log		/*{{{*/
 // DPkgPM::DoTerminalPty - Read the terminal pty and write log		/*{{{*/
@@ -400,9 +451,9 @@ void pkgDPkgPM::DoTerminalPty(int master)
    }  
    }  
    if(len <= 0) 
    if(len <= 0) 
       return;
       return;
-   write(1, term_buf, len);
-   if(term_out)
-      fwrite(term_buf, len, sizeof(char), term_out);
+   FileFd::Write(1, term_buf, len);
+   if(d->term_out)
+      fwrite(term_buf, len, sizeof(char), d->term_out);
 }
 }
 									/*}}}*/
 									/*}}}*/
 // DPkgPM::ProcessDpkgStatusBuf                                        	/*{{{*/
 // DPkgPM::ProcessDpkgStatusBuf                                        	/*{{{*/
@@ -475,7 +526,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
 	     << ":" << s
 	     << ":" << s
 	     << endl;
 	     << endl;
       if(OutStatusFd > 0)
       if(OutStatusFd > 0)
-	 write(OutStatusFd, status.str().c_str(), status.str().size());
+	 FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size());
       if (Debug == true)
       if (Debug == true)
 	 std::clog << "send: '" << status.str() << "'" << endl;
 	 std::clog << "send: '" << status.str() << "'" << endl;
 
 
@@ -499,7 +550,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
 	     << ":" << list[3]
 	     << ":" << list[3]
 	     << endl;
 	     << endl;
       if(OutStatusFd > 0)
       if(OutStatusFd > 0)
-	 write(OutStatusFd, status.str().c_str(), status.str().size());
+	 FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size());
       if (Debug == true)
       if (Debug == true)
 	 std::clog << "send: '" << status.str() << "'" << endl;
 	 std::clog << "send: '" << status.str() << "'" << endl;
       pkgFailures++;
       pkgFailures++;
@@ -513,7 +564,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
 	     << ":" << list[3]
 	     << ":" << list[3]
 	     << endl;
 	     << endl;
       if(OutStatusFd > 0)
       if(OutStatusFd > 0)
-	 write(OutStatusFd, status.str().c_str(), status.str().size());
+	 FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size());
       if (Debug == true)
       if (Debug == true)
 	 std::clog << "send: '" << status.str() << "'" << endl;
 	 std::clog << "send: '" << status.str() << "'" << endl;
       return;
       return;
@@ -541,7 +592,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
 	     << ":" << s
 	     << ":" << s
 	     << endl;
 	     << endl;
       if(OutStatusFd > 0)
       if(OutStatusFd > 0)
-	 write(OutStatusFd, status.str().c_str(), status.str().size());
+	 FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size());
       if (Debug == true)
       if (Debug == true)
 	 std::clog << "send: '" << status.str() << "'" << endl;
 	 std::clog << "send: '" << status.str() << "'" << endl;
    }
    }
@@ -606,14 +657,14 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd)
    char *p, *q;
    char *p, *q;
    int len;
    int len;
 
 
-   len=read(statusfd, &dpkgbuf[dpkgbuf_pos], sizeof(dpkgbuf)-dpkgbuf_pos);
-   dpkgbuf_pos += len;
+   len=read(statusfd, &d->dpkgbuf[d->dpkgbuf_pos], sizeof(d->dpkgbuf)-d->dpkgbuf_pos);
+   d->dpkgbuf_pos += len;
    if(len <= 0)
    if(len <= 0)
       return;
       return;
 
 
    // process line by line if we have a buffer
    // process line by line if we have a buffer
-   p = q = dpkgbuf;
-   while((q=(char*)memchr(p, '\n', dpkgbuf+dpkgbuf_pos-p)) != NULL)
+   p = q = d->dpkgbuf;
+   while((q=(char*)memchr(p, '\n', d->dpkgbuf+d->dpkgbuf_pos-p)) != NULL)
    {
    {
       *q = 0;
       *q = 0;
       ProcessDpkgStatusLine(OutStatusFd, p);
       ProcessDpkgStatusLine(OutStatusFd, p);
@@ -621,8 +672,8 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd)
    }
    }
 
 
    // now move the unprocessed bits (after the final \n that is now a 0x0) 
    // now move the unprocessed bits (after the final \n that is now a 0x0) 
-   // to the start and update dpkgbuf_pos
-   p = (char*)memrchr(dpkgbuf, 0, dpkgbuf_pos);
+   // to the start and update d->dpkgbuf_pos
+   p = (char*)memrchr(d->dpkgbuf, 0, d->dpkgbuf_pos);
    if(p == NULL)
    if(p == NULL)
       return;
       return;
 
 
@@ -630,8 +681,8 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd)
    p++;
    p++;
 
 
    // move the unprocessed tail to the start and update pos
    // move the unprocessed tail to the start and update pos
-   memmove(dpkgbuf, p, p-dpkgbuf);
-   dpkgbuf_pos = dpkgbuf+dpkgbuf_pos-p;
+   memmove(d->dpkgbuf, p, p-d->dpkgbuf);
+   d->dpkgbuf_pos = d->dpkgbuf+d->dpkgbuf_pos-p;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // DPkgPM::WriteHistoryTag						/*{{{*/
 // DPkgPM::WriteHistoryTag						/*{{{*/
@@ -643,7 +694,7 @@ void pkgDPkgPM::WriteHistoryTag(string const &tag, string value)
    // poor mans rstrip(", ")
    // poor mans rstrip(", ")
    if (value[length-2] == ',' && value[length-1] == ' ')
    if (value[length-2] == ',' && value[length-1] == ' ')
       value.erase(length - 2, 2);
       value.erase(length - 2, 2);
-   fprintf(history_out, "%s: %s\n", tag.c_str(), value.c_str());
+   fprintf(d->history_out, "%s: %s\n", tag.c_str(), value.c_str());
 }									/*}}}*/
 }									/*}}}*/
 // DPkgPM::OpenLog							/*{{{*/
 // DPkgPM::OpenLog							/*{{{*/
 bool pkgDPkgPM::OpenLog()
 bool pkgDPkgPM::OpenLog()
@@ -664,11 +715,11 @@ bool pkgDPkgPM::OpenLog()
 				   _config->Find("Dir::Log::Terminal"));
 				   _config->Find("Dir::Log::Terminal"));
    if (!logfile_name.empty())
    if (!logfile_name.empty())
    {
    {
-      term_out = fopen(logfile_name.c_str(),"a");
-      if (term_out == NULL)
+      d->term_out = fopen(logfile_name.c_str(),"a");
+      if (d->term_out == NULL)
 	 return _error->WarningE("OpenLog", _("Could not open file '%s'"), logfile_name.c_str());
 	 return _error->WarningE("OpenLog", _("Could not open file '%s'"), logfile_name.c_str());
-      setvbuf(term_out, NULL, _IONBF, 0);
-      SetCloseExec(fileno(term_out), true);
+      setvbuf(d->term_out, NULL, _IONBF, 0);
+      SetCloseExec(fileno(d->term_out), true);
       struct passwd *pw;
       struct passwd *pw;
       struct group *gr;
       struct group *gr;
       pw = getpwnam("root");
       pw = getpwnam("root");
@@ -676,7 +727,7 @@ bool pkgDPkgPM::OpenLog()
       if (pw != NULL && gr != NULL)
       if (pw != NULL && gr != NULL)
 	  chown(logfile_name.c_str(), pw->pw_uid, gr->gr_gid);
 	  chown(logfile_name.c_str(), pw->pw_uid, gr->gr_gid);
       chmod(logfile_name.c_str(), 0644);
       chmod(logfile_name.c_str(), 0644);
-      fprintf(term_out, "\nLog started: %s\n", timestr);
+      fprintf(d->term_out, "\nLog started: %s\n", timestr);
    }
    }
 
 
    // write your history
    // write your history
@@ -684,11 +735,11 @@ bool pkgDPkgPM::OpenLog()
 				   _config->Find("Dir::Log::History"));
 				   _config->Find("Dir::Log::History"));
    if (!history_name.empty())
    if (!history_name.empty())
    {
    {
-      history_out = fopen(history_name.c_str(),"a");
-      if (history_out == NULL)
+      d->history_out = fopen(history_name.c_str(),"a");
+      if (d->history_out == NULL)
 	 return _error->WarningE("OpenLog", _("Could not open file '%s'"), history_name.c_str());
 	 return _error->WarningE("OpenLog", _("Could not open file '%s'"), history_name.c_str());
       chmod(history_name.c_str(), 0644);
       chmod(history_name.c_str(), 0644);
-      fprintf(history_out, "\nStart-Date: %s\n", timestr);
+      fprintf(d->history_out, "\nStart-Date: %s\n", timestr);
       string remove, purge, install, reinstall, upgrade, downgrade;
       string remove, purge, install, reinstall, upgrade, downgrade;
       for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
       for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
       {
       {
@@ -729,7 +780,7 @@ bool pkgDPkgPM::OpenLog()
       WriteHistoryTag("Downgrade",downgrade);
       WriteHistoryTag("Downgrade",downgrade);
       WriteHistoryTag("Remove",remove);
       WriteHistoryTag("Remove",remove);
       WriteHistoryTag("Purge",purge);
       WriteHistoryTag("Purge",purge);
-      fflush(history_out);
+      fflush(d->history_out);
    }
    }
    
    
    return true;
    return true;
@@ -743,16 +794,16 @@ bool pkgDPkgPM::CloseLog()
    struct tm *tmp = localtime(&t);
    struct tm *tmp = localtime(&t);
    strftime(timestr, sizeof(timestr), "%F  %T", tmp);
    strftime(timestr, sizeof(timestr), "%F  %T", tmp);
 
 
-   if(term_out)
+   if(d->term_out)
    {
    {
-      fprintf(term_out, "Log ended: ");
-      fprintf(term_out, "%s", timestr);
-      fprintf(term_out, "\n");
-      fclose(term_out);
+      fprintf(d->term_out, "Log ended: ");
+      fprintf(d->term_out, "%s", timestr);
+      fprintf(d->term_out, "\n");
+      fclose(d->term_out);
    }
    }
-   term_out = NULL;
+   d->term_out = NULL;
 
 
-   if(history_out)
+   if(d->history_out)
    {
    {
       if (disappearedPkgs.empty() == false)
       if (disappearedPkgs.empty() == false)
       {
       {
@@ -769,12 +820,12 @@ bool pkgDPkgPM::CloseLog()
 	 }
 	 }
 	 WriteHistoryTag("Disappeared", disappear);
 	 WriteHistoryTag("Disappeared", disappear);
       }
       }
-      if (dpkg_error.empty() == false)
-	 fprintf(history_out, "Error: %s\n", dpkg_error.c_str());
-      fprintf(history_out, "End-Date: %s\n", timestr);
-      fclose(history_out);
+      if (d->dpkg_error.empty() == false)
+	 fprintf(d->history_out, "Error: %s\n", d->dpkg_error.c_str());
+      fprintf(d->history_out, "End-Date: %s\n", timestr);
+      fclose(d->history_out);
    }
    }
-   history_out = NULL;
+   d->history_out = NULL;
 
 
    return true;
    return true;
 }
 }
@@ -811,6 +862,58 @@ static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds,
 */
 */
 bool pkgDPkgPM::Go(int OutStatusFd)
 bool pkgDPkgPM::Go(int OutStatusFd)
 {
 {
+   pkgPackageManager::SigINTStop = false;
+
+   // Generate the base argument list for dpkg
+   std::vector<const char *> Args;
+   unsigned long StartSize = 0;
+   string Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
+   {
+      string const dpkgChrootDir = _config->FindDir("DPkg::Chroot-Directory", "/");
+      size_t dpkgChrootLen = dpkgChrootDir.length();
+      if (dpkgChrootDir != "/" && Tmp.find(dpkgChrootDir) == 0)
+      {
+	 if (dpkgChrootDir[dpkgChrootLen - 1] == '/')
+	    --dpkgChrootLen;
+	 Tmp = Tmp.substr(dpkgChrootLen);
+      }
+   }
+   Args.push_back(Tmp.c_str());
+   StartSize += Tmp.length();
+
+   // Stick in any custom dpkg options
+   Configuration::Item const *Opts = _config->Tree("DPkg::Options");
+   if (Opts != 0)
+   {
+      Opts = Opts->Child;
+      for (; Opts != 0; Opts = Opts->Next)
+      {
+	 if (Opts->Value.empty() == true)
+	    continue;
+	 Args.push_back(Opts->Value.c_str());
+	 StartSize += Opts->Value.length();
+      }
+   }
+
+   size_t const BaseArgs = Args.size();
+   // we need to detect if we can qualify packages with the architecture or not
+   Args.push_back("--assert-multi-arch");
+   Args.push_back(NULL);
+
+   pid_t dpkgAssertMultiArch = ExecFork();
+   if (dpkgAssertMultiArch == 0)
+   {
+      dpkgChrootDirectory();
+      // redirect everything to the ultimate sink as we only need the exit-status
+      int const nullfd = open("/dev/null", O_RDONLY);
+      dup2(nullfd, STDIN_FILENO);
+      dup2(nullfd, STDOUT_FILENO);
+      dup2(nullfd, STDERR_FILENO);
+      execvp(Args[0], (char**) &Args[0]);
+      _error->WarningE("dpkgGo", "Can't detect if dpkg supports multi-arch!");
+      _exit(2);
+   }
+
    fd_set rfds;
    fd_set rfds;
    struct timespec tv;
    struct timespec tv;
    sigset_t sigmask;
    sigset_t sigmask;
@@ -882,32 +985,25 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       }
       }
    }
    }
 
 
-   stdin_is_dev_null = false;
+   d->stdin_is_dev_null = false;
 
 
    // create log
    // create log
    OpenLog();
    OpenLog();
 
 
-   // Generate the base argument list for dpkg
-   std::vector<const char *> Args;
-   unsigned long StartSize = 0;
-   string const Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
-   Args.push_back(Tmp.c_str());
-   StartSize += Tmp.length();
-
-   // Stick in any custom dpkg options
-   Configuration::Item const *Opts = _config->Tree("DPkg::Options");
-   if (Opts != 0)
+   bool dpkgMultiArch = false;
+   if (dpkgAssertMultiArch > 0)
    {
    {
-      Opts = Opts->Child;
-      for (; Opts != 0; Opts = Opts->Next)
+      int Status = 0;
+      while (waitpid(dpkgAssertMultiArch, &Status, 0) != dpkgAssertMultiArch)
       {
       {
-	 if (Opts->Value.empty() == true)
+	 if (errno == EINTR)
 	    continue;
 	    continue;
-	 Args.push_back(Opts->Value.c_str());
-	 StartSize += Opts->Value.length();
+	 _error->WarningE("dpkgGo", _("Waited for %s but it wasn't there"), "dpkg --assert-multi-arch");
+	 break;
       }
       }
+      if (WIFEXITED(Status) == true && WEXITSTATUS(Status) == 0)
+	 dpkgMultiArch = true;
    }
    }
-   size_t const BaseArgs = Args.size();
 
 
    // this loop is runs once per operation
    // this loop is runs once per operation
    for (vector<Item>::const_iterator I = List.begin(); I != List.end();)
    for (vector<Item>::const_iterator I = List.begin(); I != List.end();)
@@ -943,20 +1039,24 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       // the argument list is split in a way that A depends on B
       // the argument list is split in a way that A depends on B
       // and they are in the same "--configure A B" run
       // and they are in the same "--configure A B" run
       // - with the split they may now be configured in different
       // - with the split they may now be configured in different
-      //   runs 
+      //   runs, using Immediate-Configure-All can help prevent this.
       if (J - I > (signed)MaxArgs)
       if (J - I > (signed)MaxArgs)
       {
       {
 	 J = I + MaxArgs;
 	 J = I + MaxArgs;
-	 Args.reserve(MaxArgs + 10);
+	 unsigned long const size = MaxArgs + 10;
+	 Args.reserve(size);
+	 Packages.reserve(size);
       }
       }
       else
       else
       {
       {
-	 Args.reserve((J - I) + 10);
+	 unsigned long const size = (J - I) + 10;
+	 Args.reserve(size);
+	 Packages.reserve(size);
       }
       }
 
 
-      
       int fd[2];
       int fd[2];
-      pipe(fd);
+      if (pipe(fd) != 0)
+	 return _error->Errno("pipe","Failed to create IPC pipe to dpkg");
 
 
 #define ADDARG(X) Args.push_back(X); Size += strlen(X)
 #define ADDARG(X) Args.push_back(X); Size += strlen(X)
 #define ADDARGC(X) Args.push_back(X); Size += sizeof(X) - 1
 #define ADDARGC(X) Args.push_back(X); Size += sizeof(X) - 1
@@ -965,6 +1065,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       char status_fd_buf[20];
       char status_fd_buf[20];
       snprintf(status_fd_buf,sizeof(status_fd_buf),"%i", fd[1]);
       snprintf(status_fd_buf,sizeof(status_fd_buf),"%i", fd[1]);
       ADDARG(status_fd_buf);
       ADDARG(status_fd_buf);
+      unsigned long const Op = I->Op;
 
 
       switch (I->Op)
       switch (I->Op)
       {
       {
@@ -1028,14 +1129,29 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	       continue;
 	       continue;
 	    if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end())
 	    if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end())
 	       continue;
 	       continue;
-	    if (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all"))
+	    // We keep this here to allow "smooth" transitions from e.g. multiarch dpkg/ubuntu to dpkg/debian
+	    if (dpkgMultiArch == false && (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all")))
 	    {
 	    {
 	       char const * const name = I->Pkg.Name();
 	       char const * const name = I->Pkg.Name();
 	       ADDARG(name);
 	       ADDARG(name);
 	    }
 	    }
 	    else
 	    else
 	    {
 	    {
-	       char * const fullname = strdup(I->Pkg.FullName(false).c_str());
+	       pkgCache::VerIterator PkgVer;
+	       std::string name = I->Pkg.Name();
+	       if (Op == Item::Remove || Op == Item::Purge) 
+               {
+		  PkgVer = I->Pkg.CurrentVer();
+                  if(PkgVer.end() == true)
+                     PkgVer = FindNowVersion(I->Pkg);
+               }
+	       else
+		  PkgVer = Cache[I->Pkg].InstVerIter(Cache);
+               if (PkgVer.end() == false)
+                  name.append(":").append(PkgVer.Arch());
+               else
+                  _error->Warning("Can not find PkgVer for '%s'", name.c_str());
+	       char * const fullname = strdup(name.c_str());
 	       Packages.push_back(fullname);
 	       Packages.push_back(fullname);
 	       ADDARG(fullname);
 	       ADDARG(fullname);
 	    }
 	    }
@@ -1067,8 +1183,13 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	 it to all processes in the group. Since dpkg ignores the signal 
 	 it to all processes in the group. Since dpkg ignores the signal 
 	 it doesn't die but we do! So we must also ignore it */
 	 it doesn't die but we do! So we must also ignore it */
       sighandler_t old_SIGQUIT = signal(SIGQUIT,SIG_IGN);
       sighandler_t old_SIGQUIT = signal(SIGQUIT,SIG_IGN);
-      sighandler_t old_SIGINT = signal(SIGINT,SIG_IGN);
-
+      sighandler_t old_SIGINT = signal(SIGINT,SigINT);
+      
+      // Check here for any SIGINT
+      if (pkgPackageManager::SigINTStop && (Op == Item::Remove || Op == Item::Purge || Op == Item::Install)) 
+         break;
+      
+      
       // ignore SIGHUP as well (debian #463030)
       // ignore SIGHUP as well (debian #463030)
       sighandler_t old_SIGHUP = signal(SIGHUP,SIG_IGN);
       sighandler_t old_SIGHUP = signal(SIGHUP,SIG_IGN);
 
 
@@ -1087,8 +1208,8 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	    const char *s = _("Can not write log, openpty() "
 	    const char *s = _("Can not write log, openpty() "
 	                      "failed (/dev/pts not mounted?)\n");
 	                      "failed (/dev/pts not mounted?)\n");
 	    fprintf(stderr, "%s",s);
 	    fprintf(stderr, "%s",s);
-            if(term_out)
-              fprintf(term_out, "%s",s);
+            if(d->term_out)
+              fprintf(d->term_out, "%s",s);
 	    master = slave = -1;
 	    master = slave = -1;
 	 }  else {
 	 }  else {
 	    struct termios rtt;
 	    struct termios rtt;
@@ -1106,7 +1227,6 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	    sigprocmask(SIG_SETMASK, &original_sigmask, 0);
 	    sigprocmask(SIG_SETMASK, &original_sigmask, 0);
 	 }
 	 }
       }
       }
-
        // Fork dpkg
        // Fork dpkg
       pid_t Child;
       pid_t Child;
       _config->Set("APT::Keep-Fds::",fd[1]);
       _config->Set("APT::Keep-Fds::",fd[1]);
@@ -1117,7 +1237,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 		<< (PackagesDone/float(PackagesTotal)*100.0) 
 		<< (PackagesDone/float(PackagesTotal)*100.0) 
 		<< ":" << _("Running dpkg")
 		<< ":" << _("Running dpkg")
 		<< endl;
 		<< endl;
-	 write(OutStatusFd, status.str().c_str(), status.str().size());
+	 FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size());
       }
       }
       Child = ExecFork();
       Child = ExecFork();
             
             
@@ -1136,14 +1256,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	 }
 	 }
 	 close(fd[0]); // close the read end of the pipe
 	 close(fd[0]); // close the read end of the pipe
 
 
-	 if (_config->FindDir("DPkg::Chroot-Directory","/") != "/") 
-	 {
-	    std::cerr << "Chrooting into " 
-		      << _config->FindDir("DPkg::Chroot-Directory") 
-		      << std::endl;
-	    if (chroot(_config->FindDir("DPkg::Chroot-Directory","/").c_str()) != 0)
-	       _exit(100);
-	 }
+	 dpkgChrootDirectory();
 
 
 	 if (chdir(_config->FindDir("DPkg::Run-Directory","/").c_str()) != 0)
 	 if (chdir(_config->FindDir("DPkg::Run-Directory","/").c_str()) != 0)
 	    _exit(100);
 	    _exit(100);
@@ -1213,13 +1326,14 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	    // Restore sig int/quit
 	    // Restore sig int/quit
 	    signal(SIGQUIT,old_SIGQUIT);
 	    signal(SIGQUIT,old_SIGQUIT);
 	    signal(SIGINT,old_SIGINT);
 	    signal(SIGINT,old_SIGINT);
+
 	    signal(SIGHUP,old_SIGHUP);
 	    signal(SIGHUP,old_SIGHUP);
 	    return _error->Errno("waitpid","Couldn't wait for subprocess");
 	    return _error->Errno("waitpid","Couldn't wait for subprocess");
 	 }
 	 }
 
 
 	 // wait for input or output here
 	 // wait for input or output here
 	 FD_ZERO(&rfds);
 	 FD_ZERO(&rfds);
-	 if (master >= 0 && !stdin_is_dev_null)
+	 if (master >= 0 && !d->stdin_is_dev_null)
 	    FD_SET(0, &rfds); 
 	    FD_SET(0, &rfds); 
 	 FD_SET(_dpkgin, &rfds);
 	 FD_SET(_dpkgin, &rfds);
 	 if(master >= 0)
 	 if(master >= 0)
@@ -1253,6 +1367,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       // Restore sig int/quit
       // Restore sig int/quit
       signal(SIGQUIT,old_SIGQUIT);
       signal(SIGQUIT,old_SIGQUIT);
       signal(SIGINT,old_SIGINT);
       signal(SIGINT,old_SIGINT);
+      
       signal(SIGHUP,old_SIGHUP);
       signal(SIGHUP,old_SIGHUP);
 
 
       if(master >= 0) 
       if(master >= 0) 
@@ -1273,14 +1388,14 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	    RunScripts("DPkg::Post-Invoke");
 	    RunScripts("DPkg::Post-Invoke");
 
 
 	 if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV) 
 	 if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV) 
-	    strprintf(dpkg_error, "Sub-process %s received a segmentation fault.",Args[0]);
+	    strprintf(d->dpkg_error, "Sub-process %s received a segmentation fault.",Args[0]);
 	 else if (WIFEXITED(Status) != 0)
 	 else if (WIFEXITED(Status) != 0)
-	    strprintf(dpkg_error, "Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status));
+	    strprintf(d->dpkg_error, "Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status));
 	 else 
 	 else 
-	    strprintf(dpkg_error, "Sub-process %s exited unexpectedly",Args[0]);
+	    strprintf(d->dpkg_error, "Sub-process %s exited unexpectedly",Args[0]);
 
 
-	 if(dpkg_error.size() > 0)
-	    _error->Error("%s", dpkg_error.c_str());
+	 if(d->dpkg_error.size() > 0)
+	    _error->Error("%s", d->dpkg_error.c_str());
 
 
 	 if(stopOnError) 
 	 if(stopOnError) 
 	 {
 	 {
@@ -1290,6 +1405,9 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       }      
       }      
    }
    }
    CloseLog();
    CloseLog();
+   
+   if (pkgPackageManager::SigINTStop)
+       _error->Warning(_("Operation was interrupted before it could finish"));
 
 
    if (RunScripts("DPkg::Post-Invoke") == false)
    if (RunScripts("DPkg::Post-Invoke") == false)
       return false;
       return false;
@@ -1314,6 +1432,10 @@ bool pkgDPkgPM::Go(int OutStatusFd)
    Cache.writeStateFile(NULL);
    Cache.writeStateFile(NULL);
    return true;
    return true;
 }
 }
+
+void SigINT(int sig) {
+   pkgPackageManager::SigINTStop = true;
+}
 									/*}}}*/
 									/*}}}*/
 // pkgDpkgPM::Reset - Dump the contents of the command list		/*{{{*/
 // pkgDpkgPM::Reset - Dump the contents of the command list		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
@@ -1328,6 +1450,12 @@ void pkgDPkgPM::Reset()
 /* */
 /* */
 void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) 
 void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) 
 {
 {
+   // If apport doesn't exist or isn't installed do nothing
+   // This e.g. prevents messages in 'universes' without apport
+   pkgCache::PkgIterator apportPkg = Cache.FindPkg("apport");
+   if (apportPkg.end() == true || apportPkg->CurrentVer == 0)
+      return;
+
    string pkgname, reportfile, srcpkgname, pkgver, arch;
    string pkgname, reportfile, srcpkgname, pkgver, arch;
    string::size_type pos;
    string::size_type pos;
    FILE *report;
    FILE *report;
@@ -1415,7 +1543,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
 	 if(strstr(strbuf,"Package:") == strbuf)
 	 if(strstr(strbuf,"Package:") == strbuf)
 	 {
 	 {
 	    char pkgname[255], version[255];
 	    char pkgname[255], version[255];
-	    if(sscanf(strbuf, "Package: %s %s", pkgname, version) == 2)
+	    if(sscanf(strbuf, "Package: %254s %254s", pkgname, version) == 2)
 	       if(strcmp(pkgver.c_str(), version) == 0)
 	       if(strcmp(pkgver.c_str(), version) == 0)
 	       {
 	       {
 		  fclose(report);
 		  fclose(report);
@@ -1444,8 +1572,8 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
    fprintf(report, "ErrorMessage:\n %s\n", errormsg);
    fprintf(report, "ErrorMessage:\n %s\n", errormsg);
 
 
    // ensure that the log is flushed
    // ensure that the log is flushed
-   if(term_out)
-      fflush(term_out);
+   if(d->term_out)
+      fflush(d->term_out);
 
 
    // attach terminal log it if we have it
    // attach terminal log it if we have it
    string logfile_name = _config->FindFile("Dir::Log::Terminal");
    string logfile_name = _config->FindFile("Dir::Log::Terminal");

+ 14 - 17
apt-pkg/deb/dpkgpm.h

@@ -15,22 +15,17 @@
 #include <map>
 #include <map>
 #include <stdio.h>
 #include <stdio.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
 using std::vector;
 using std::vector;
 using std::map;
 using std::map;
+#endif
 
 
+class pkgDPkgPMPrivate;
 
 
 class pkgDPkgPM : public pkgPackageManager
 class pkgDPkgPM : public pkgPackageManager
 {
 {
    private:
    private:
-
-   bool stdin_is_dev_null;
-
-   // the buffer we use for the dpkg status-fd reading
-   char dpkgbuf[1024];
-   int dpkgbuf_pos;
-   FILE *term_out;
-   FILE *history_out;
-   string dpkg_error;
+   pkgDPkgPMPrivate *d;
 
 
    /** \brief record the disappear action and handle accordingly
    /** \brief record the disappear action and handle accordingly
 
 
@@ -45,7 +40,7 @@ class pkgDPkgPM : public pkgPackageManager
       needs to declare a Replaces on the disappeared package.
       needs to declare a Replaces on the disappeared package.
       \param pkgname Name of the package that disappeared
       \param pkgname Name of the package that disappeared
    */
    */
-   void handleDisappearAction(string const &pkgname);
+   void handleDisappearAction(std::string const &pkgname);
 
 
    protected:
    protected:
    int pkgFailures;
    int pkgFailures;
@@ -60,11 +55,11 @@ class pkgDPkgPM : public pkgPackageManager
    // the dpkg states that the pkg will run through, the string is 
    // the dpkg states that the pkg will run through, the string is 
    // the package, the vector contains the dpkg states that the package
    // the package, the vector contains the dpkg states that the package
    // will go through
    // will go through
-   map<string,vector<struct DpkgState> > PackageOps;
+   std::map<std::string,std::vector<struct DpkgState> > PackageOps;
    // the dpkg states that are already done; the string is the package
    // the dpkg states that are already done; the string is the package
    // the int is the state that is already done (e.g. a package that is
    // the int is the state that is already done (e.g. a package that is
    // going to be install is already in state "half-installed")
    // going to be install is already in state "half-installed")
-   map<string,unsigned int> PackageOpsDone;
+   std::map<std::string,unsigned int> PackageOpsDone;
 
 
    // progress reporting
    // progress reporting
    unsigned int PackagesDone;
    unsigned int PackagesDone;
@@ -73,19 +68,19 @@ class pkgDPkgPM : public pkgPackageManager
    struct Item
    struct Item
    {
    {
       enum Ops {Install, Configure, Remove, Purge, ConfigurePending, TriggersPending} Op;
       enum Ops {Install, Configure, Remove, Purge, ConfigurePending, TriggersPending} Op;
-      string File;
+      std::string File;
       PkgIterator Pkg;
       PkgIterator Pkg;
-      Item(Ops Op,PkgIterator Pkg,string File = "") : Op(Op),
+      Item(Ops Op,PkgIterator Pkg,std::string File = "") : Op(Op),
             File(File), Pkg(Pkg) {};
             File(File), Pkg(Pkg) {};
       Item() {};
       Item() {};
       
       
    };
    };
-   vector<Item> List;
+   std::vector<Item> List;
 
 
    // Helpers
    // Helpers
    bool RunScriptsWithPkgs(const char *Cnf);
    bool RunScriptsWithPkgs(const char *Cnf);
    bool SendV2Pkgs(FILE *F);
    bool SendV2Pkgs(FILE *F);
-   void WriteHistoryTag(string const &tag, string value);
+   void WriteHistoryTag(std::string const &tag, std::string value);
 
 
    // apport integration
    // apport integration
    void WriteApportReport(const char *pkgpath, const char *errormsg);
    void WriteApportReport(const char *pkgpath, const char *errormsg);
@@ -101,7 +96,7 @@ class pkgDPkgPM : public pkgPackageManager
    void ProcessDpkgStatusLine(int OutStatusFd, char *line);
    void ProcessDpkgStatusLine(int OutStatusFd, char *line);
 
 
    // The Actuall installation implementation
    // The Actuall installation implementation
-   virtual bool Install(PkgIterator Pkg,string File);
+   virtual bool Install(PkgIterator Pkg,std::string File);
    virtual bool Configure(PkgIterator Pkg);
    virtual bool Configure(PkgIterator Pkg);
    virtual bool Remove(PkgIterator Pkg,bool Purge = false);
    virtual bool Remove(PkgIterator Pkg,bool Purge = false);
    virtual bool Go(int StatusFd=-1);
    virtual bool Go(int StatusFd=-1);
@@ -113,4 +108,6 @@ class pkgDPkgPM : public pkgPackageManager
    virtual ~pkgDPkgPM();
    virtual ~pkgDPkgPM();
 };
 };
 
 
+void SigINT(int sig);
+
 #endif
 #endif

+ 153 - 129
apt-pkg/depcache.cc

@@ -8,28 +8,35 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
+#include<config.h>
+
 #include <apt-pkg/depcache.h>
 #include <apt-pkg/depcache.h>
 #include <apt-pkg/version.h>
 #include <apt-pkg/version.h>
 #include <apt-pkg/versionmatch.h>
 #include <apt-pkg/versionmatch.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/sptr.h>
 #include <apt-pkg/sptr.h>
 #include <apt-pkg/algorithms.h>
 #include <apt-pkg/algorithms.h>
-
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/pkgsystem.h>
 #include <apt-pkg/pkgsystem.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/tagfile.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/cacheset.h>
 
 
+#include <algorithm>
 #include <iostream>
 #include <iostream>
-#include <sstream>    
+#include <sstream>
 #include <set>
 #include <set>
 
 
 #include <sys/stat.h>
 #include <sys/stat.h>
 
 
-#include <apti18n.h>    
+#include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
+
+using std::string;
+
 // helper for Install-Recommends-Sections and Never-MarkAuto-Sections	/*{{{*/
 // helper for Install-Recommends-Sections and Never-MarkAuto-Sections	/*{{{*/
 static bool 
 static bool 
 ConfigValueInSubTree(const char* SubTree, const char *needle)
 ConfigValueInSubTree(const char* SubTree, const char *needle)
@@ -169,14 +176,14 @@ bool pkgDepCache::readStateFile(OpProgress *Prog)			/*{{{*/
    string const state = _config->FindFile("Dir::State::extended_states");
    string const state = _config->FindFile("Dir::State::extended_states");
    if(RealFileExists(state)) {
    if(RealFileExists(state)) {
       state_file.Open(state, FileFd::ReadOnly);
       state_file.Open(state, FileFd::ReadOnly);
-      int const file_size = state_file.Size();
+      off_t const file_size = state_file.Size();
       if(Prog != NULL)
       if(Prog != NULL)
 	 Prog->OverallProgress(0, file_size, 1, 
 	 Prog->OverallProgress(0, file_size, 1, 
 			       _("Reading state information"));
 			       _("Reading state information"));
 
 
       pkgTagFile tagfile(&state_file);
       pkgTagFile tagfile(&state_file);
       pkgTagSection section;
       pkgTagSection section;
-      int amt = 0;
+      off_t amt = 0;
       bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
       bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
       while(tagfile.Step(section)) {
       while(tagfile.Step(section)) {
 	 string const pkgname = section.FindS("Package");
 	 string const pkgname = section.FindS("Package");
@@ -364,14 +371,11 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res)
    
    
    // Check the providing packages
    // Check the providing packages
    PrvIterator P = Dep.TargetPkg().ProvidesList();
    PrvIterator P = Dep.TargetPkg().ProvidesList();
-   PkgIterator Pkg = Dep.ParentPkg();
    for (; P.end() != true; ++P)
    for (; P.end() != true; ++P)
    {
    {
-      /* Provides may never be applied against the same package (or group)
-         if it is a conflicts. See the comment above. */
-      if (P.OwnerPkg()->Group == Pkg->Group && Dep.IsNegative() == true)
+      if (Dep.IsIgnorable(P) == true)
 	 continue;
 	 continue;
-      
+
       // Check if the provides is a hit
       // Check if the provides is a hit
       if (Type == NowVersion)
       if (Type == NowVersion)
       {
       {
@@ -406,60 +410,8 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res)
 									/*}}}*/
 									/*}}}*/
 // DepCache::AddSizes - Add the packages sizes to the counters		/*{{{*/
 // DepCache::AddSizes - Add the packages sizes to the counters		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
-/* Call with Mult = -1 to preform the inverse opration
-   The Mult increases the complexity of the calulations here and is unused -
-   or do we really have a usecase for removing the size of a package two
-   times? So let us replace it with a simple bool and be done with it… */
-__deprecated void pkgDepCache::AddSizes(const PkgIterator &Pkg,signed long Mult)
-{
-   StateCache &P = PkgState[Pkg->ID];
-   
-   if (Pkg->VersionList == 0)
-      return;
-   
-   if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && 
-       P.Keep() == true)
-      return;
-   
-   // Compute the size data
-   if (P.NewInstall() == true)
-   {
-      iUsrSize += (signed long long)(Mult*P.InstVerIter(*this)->InstalledSize);
-      iDownloadSize += (signed long long)(Mult*P.InstVerIter(*this)->Size);
-      return;
-   }
-   
-   // Upgrading
-   if (Pkg->CurrentVer != 0 && 
-       (P.InstallVer != (Version *)Pkg.CurrentVer() || 
-	(P.iFlags & ReInstall) == ReInstall) && P.InstallVer != 0)
-   {
-      iUsrSize += (signed long long)(Mult*((signed long long)P.InstVerIter(*this)->InstalledSize - 
-			(signed long long)Pkg.CurrentVer()->InstalledSize));
-      iDownloadSize += (signed long long)(Mult*P.InstVerIter(*this)->Size);
-      return;
-   }
-   
-   // Reinstall
-   if (Pkg.State() == pkgCache::PkgIterator::NeedsUnpack &&
-       P.Delete() == false)
-   {
-      iDownloadSize += (signed long long)(Mult*P.InstVerIter(*this)->Size);
-      return;
-   }
-   
-   // Removing
-   if (Pkg->CurrentVer != 0 && P.InstallVer == 0)
-   {
-      iUsrSize -= (signed long long)(Mult*Pkg.CurrentVer()->InstalledSize);
-      return;
-   }   
-}
-									/*}}}*/
-// DepCache::AddSizes - Add the packages sizes to the counters		/*{{{*/
-// ---------------------------------------------------------------------
 /* Call with Inverse = true to preform the inverse opration */
 /* Call with Inverse = true to preform the inverse opration */
-void pkgDepCache::AddSizes(const PkgIterator &Pkg, bool const &Inverse)
+void pkgDepCache::AddSizes(const PkgIterator &Pkg, bool const Inverse)
 {
 {
    StateCache &P = PkgState[Pkg->ID];
    StateCache &P = PkgState[Pkg->ID];
    
    
@@ -530,8 +482,9 @@ void pkgDepCache::AddSizes(const PkgIterator &Pkg, bool const &Inverse)
    calld Remove/Add itself. Remember, dependencies can be circular so
    calld Remove/Add itself. Remember, dependencies can be circular so
    while processing a dep for Pkg it is possible that Add/Remove
    while processing a dep for Pkg it is possible that Add/Remove
    will be called on Pkg */
    will be called on Pkg */
-void pkgDepCache::AddStates(const PkgIterator &Pkg,int Add)
+void pkgDepCache::AddStates(const PkgIterator &Pkg, bool const Invert)
 {
 {
+   signed char const Add = (Invert == false) ? 1 : -1;
    StateCache &State = PkgState[Pkg->ID];
    StateCache &State = PkgState[Pkg->ID];
    
    
    // The Package is broken (either minimal dep or policy dep)
    // The Package is broken (either minimal dep or policy dep)
@@ -806,17 +759,17 @@ void pkgDepCache::Update(PkgIterator const &Pkg)
 // DepCache::MarkKeep - Put the package in the keep state		/*{{{*/
 // DepCache::MarkKeep - Put the package in the keep state		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
+bool pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
                            unsigned long Depth)
                            unsigned long Depth)
 {
 {
    if (IsModeChangeOk(ModeKeep, Pkg, Depth, FromUser) == false)
    if (IsModeChangeOk(ModeKeep, Pkg, Depth, FromUser) == false)
-      return;
+      return false;
 
 
    /* Reject an attempt to keep a non-source broken installed package, those
    /* Reject an attempt to keep a non-source broken installed package, those
       must be upgraded */
       must be upgraded */
    if (Pkg.State() == PkgIterator::NeedsUnpack && 
    if (Pkg.State() == PkgIterator::NeedsUnpack && 
        Pkg.CurrentVer().Downloadable() == false)
        Pkg.CurrentVer().Downloadable() == false)
-      return;
+      return false;
 
 
    /* We changed the soft state all the time so the UI is a bit nicer
    /* We changed the soft state all the time so the UI is a bit nicer
       to use */
       to use */
@@ -824,7 +777,7 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
 
 
    // Check that it is not already kept
    // Check that it is not already kept
    if (P.Mode == ModeKeep)
    if (P.Mode == ModeKeep)
-      return;
+      return true;
 
 
    if (Soft == true)
    if (Soft == true)
       P.iFlags |= AutoKept;
       P.iFlags |= AutoKept;
@@ -857,31 +810,31 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
       P.InstallVer = Pkg.CurrentVer();
       P.InstallVer = Pkg.CurrentVer();
 
 
    AddStates(Pkg);
    AddStates(Pkg);
-
    Update(Pkg);
    Update(Pkg);
-
    AddSizes(Pkg);
    AddSizes(Pkg);
+
+   return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // DepCache::MarkDelete - Put the package in the delete state		/*{{{*/
 // DepCache::MarkDelete - Put the package in the delete state		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
+bool pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
                              unsigned long Depth, bool FromUser)
                              unsigned long Depth, bool FromUser)
 {
 {
    if (IsModeChangeOk(ModeDelete, Pkg, Depth, FromUser) == false)
    if (IsModeChangeOk(ModeDelete, Pkg, Depth, FromUser) == false)
-      return;
+      return false;
 
 
    StateCache &P = PkgState[Pkg->ID];
    StateCache &P = PkgState[Pkg->ID];
 
 
    // Check that it is not already marked for delete
    // Check that it is not already marked for delete
    if ((P.Mode == ModeDelete || P.InstallVer == 0) && 
    if ((P.Mode == ModeDelete || P.InstallVer == 0) && 
        (Pkg.Purge() == true || rPurge == false))
        (Pkg.Purge() == true || rPurge == false))
-      return;
+      return true;
 
 
    // check if we are allowed to remove the package
    // check if we are allowed to remove the package
    if (IsDeleteOk(Pkg,rPurge,Depth,FromUser) == false)
    if (IsDeleteOk(Pkg,rPurge,Depth,FromUser) == false)
-      return;
+      return false;
 
 
    P.iFlags &= ~(AutoKept | Purge);
    P.iFlags &= ~(AutoKept | Purge);
    if (rPurge == true)
    if (rPurge == true)
@@ -905,6 +858,7 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
    Update(Pkg);
    Update(Pkg);
    AddSizes(Pkg);
    AddSizes(Pkg);
 
 
+   return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // DepCache::IsDeleteOk - check if it is ok to remove this package	/*{{{*/
 // DepCache::IsDeleteOk - check if it is ok to remove this package	/*{{{*/
@@ -985,18 +939,70 @@ bool pkgDepCache::IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
 // DepCache::MarkInstall - Put the package in the install state		/*{{{*/
 // DepCache::MarkInstall - Put the package in the install state		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
+struct CompareProviders {
+   pkgCache::PkgIterator const Pkg;
+   CompareProviders(pkgCache::DepIterator const &Dep) : Pkg(Dep.TargetPkg()) {};
+   //bool operator() (APT::VersionList::iterator const &AV, APT::VersionList::iterator const &BV)
+   bool operator() (pkgCache::VerIterator const &AV, pkgCache::VerIterator const &BV)
+   {
+      pkgCache::PkgIterator const A = AV.ParentPkg();
+      pkgCache::PkgIterator const B = BV.ParentPkg();
+      // Prefer packages in the same group as the target; e.g. foo:i386, foo:amd64
+      if (A->Group != B->Group)
+      {
+	 if (A->Group == Pkg->Group && B->Group != Pkg->Group)
+	    return false;
+	 else if (B->Group == Pkg->Group && A->Group != Pkg->Group)
+	    return true;
+      }
+      // we like essentials
+      if ((A->Flags & pkgCache::Flag::Essential) != (B->Flags & pkgCache::Flag::Essential))
+      {
+	 if ((A->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
+	    return false;
+	 else if ((B->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
+	    return true;
+      }
+      if ((A->Flags & pkgCache::Flag::Important) != (B->Flags & pkgCache::Flag::Important))
+      {
+	 if ((A->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
+	    return false;
+	 else if ((B->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
+	    return true;
+      }
+      // higher priority seems like a good idea
+      if (AV->Priority != BV->Priority)
+	 return AV->Priority < BV->Priority;
+      // prefer native architecture
+      if (strcmp(A.Arch(), B.Arch()) != 0)
+      {
+	 if (strcmp(A.Arch(), A.Cache()->NativeArch()) == 0)
+	    return false;
+	 else if (strcmp(B.Arch(), B.Cache()->NativeArch()) == 0)
+	    return true;
+	 std::vector<std::string> archs = APT::Configuration::getArchitectures();
+	 for (std::vector<std::string>::const_iterator a = archs.begin(); a != archs.end(); ++a)
+	    if (*a == A.Arch())
+	       return false;
+	    else if (*a == B.Arch())
+	       return true;
+      }
+      // unable to decide…
+      return A->ID < B->ID;
+   }
+};
+bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 			      unsigned long Depth, bool FromUser,
 			      unsigned long Depth, bool FromUser,
 			      bool ForceImportantDeps)
 			      bool ForceImportantDeps)
 {
 {
    if (IsModeChangeOk(ModeInstall, Pkg, Depth, FromUser) == false)
    if (IsModeChangeOk(ModeInstall, Pkg, Depth, FromUser) == false)
-      return;
+      return false;
 
 
    StateCache &P = PkgState[Pkg->ID];
    StateCache &P = PkgState[Pkg->ID];
 
 
    // See if there is even any possible instalation candidate
    // See if there is even any possible instalation candidate
    if (P.CandidateVer == 0)
    if (P.CandidateVer == 0)
-      return;
+      return false;
 
 
    /* Check that it is not already marked for install and that it can be 
    /* Check that it is not already marked for install and that it can be 
       installed */
       installed */
@@ -1005,13 +1011,13 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 	P.CandidateVer == (Version *)Pkg.CurrentVer()))
 	P.CandidateVer == (Version *)Pkg.CurrentVer()))
    {
    {
       if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0)
       if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0)
-	 MarkKeep(Pkg, false, FromUser, Depth+1);
-      return;
+	 return MarkKeep(Pkg, false, FromUser, Depth+1);
+      return true;
    }
    }
 
 
    // check if we are allowed to install the package
    // check if we are allowed to install the package
    if (IsInstallOk(Pkg,AutoInst,Depth,FromUser) == false)
    if (IsInstallOk(Pkg,AutoInst,Depth,FromUser) == false)
-      return;
+      return false;
 
 
    ActionGroup group(*this);
    ActionGroup group(*this);
    P.iFlags &= ~AutoKept;
    P.iFlags &= ~AutoKept;
@@ -1046,8 +1052,8 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
    Update(Pkg);
    Update(Pkg);
    AddSizes(Pkg);
    AddSizes(Pkg);
 
 
-   if (AutoInst == false)
-      return;
+   if (AutoInst == false || _config->Find("APT::Solver", "internal") != "internal")
+      return true;
 
 
    if (DebugMarker == true)
    if (DebugMarker == true)
       std::clog << OutputInDepth(Depth) << "MarkInstall " << Pkg << " FU=" << FromUser << std::endl;
       std::clog << OutputInDepth(Depth) << "MarkInstall " << Pkg << " FU=" << FromUser << std::endl;
@@ -1091,7 +1097,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 	    continue;
 	    continue;
 	 // if the dependency was critical, we can't install it, so remove it again
 	 // if the dependency was critical, we can't install it, so remove it again
 	 MarkDelete(Pkg,false,Depth + 1, false);
 	 MarkDelete(Pkg,false,Depth + 1, false);
-	 return;
+	 return false;
       }
       }
 
 
       /* Check if any ImportantDep() (but not Critical) were added
       /* Check if any ImportantDep() (but not Critical) were added
@@ -1147,41 +1153,28 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 
 
       /* This bit is for processing the possibilty of an install/upgrade
       /* This bit is for processing the possibilty of an install/upgrade
          fixing the problem */
          fixing the problem */
-      SPtrArray<Version *> List = Start.AllTargets();
       if (Start->Type != Dep::DpkgBreaks &&
       if (Start->Type != Dep::DpkgBreaks &&
 	  (DepState[Start->ID] & DepCVer) == DepCVer)
 	  (DepState[Start->ID] & DepCVer) == DepCVer)
       {
       {
-	 // Right, find the best version to install..
-	 Version **Cur = List;
-	 PkgIterator P = Start.TargetPkg();
-	 PkgIterator InstPkg(*Cache,0);
-	 
-	 // See if there are direct matches (at the start of the list)
-	 for (; *Cur != 0 && (*Cur)->ParentPkg == P.Index(); Cur++)
+	 APT::VersionList verlist;
+	 pkgCache::VerIterator Cand = PkgState[Start.TargetPkg()->ID].CandidateVerIter(*this);
+	 if (Cand.end() == false && VS().CheckDep(Cand.VerStr(), Start->CompareOp, Start.TargetVer()) == true)
+	    verlist.insert(Cand);
+	 for (PrvIterator Prv = Start.TargetPkg().ProvidesList(); Prv.end() != true; ++Prv)
 	 {
 	 {
-	    PkgIterator Pkg(*Cache,Cache->PkgP + (*Cur)->ParentPkg);
-	    if (PkgState[Pkg->ID].CandidateVer != *Cur)
+	    pkgCache::VerIterator V = Prv.OwnerVer();
+	    pkgCache::VerIterator Cand = PkgState[Prv.OwnerPkg()->ID].CandidateVerIter(*this);
+	    if (Cand.end() == true || V != Cand ||
+		VS().CheckDep(Cand.VerStr(), Start->CompareOp, Start.TargetVer()) == false)
 	       continue;
 	       continue;
-	    InstPkg = Pkg;
-	    break;
+	    verlist.insert(Cand);
 	 }
 	 }
+	 CompareProviders comp(Start);
+	 APT::VersionList::iterator InstVer = std::max_element(verlist.begin(), verlist.end(), comp);
 
 
-	 // Select the highest priority providing package
-	 if (InstPkg.end() == true)
-	 {
-	    pkgPrioSortList(*Cache,Cur);
-	    for (; *Cur != 0; Cur++)
-	    {
-	       PkgIterator Pkg(*Cache,Cache->PkgP + (*Cur)->ParentPkg);
-	       if (PkgState[Pkg->ID].CandidateVer != *Cur)
-		  continue;
-	       InstPkg = Pkg;
-	       break;
-	    }
-	 }
-	 
-	 if (InstPkg.end() == false)
+	 if (InstVer != verlist.end())
 	 {
 	 {
+	    pkgCache::PkgIterator InstPkg = InstVer.ParentPkg();
 	    if(DebugAutoInstall == true)
 	    if(DebugAutoInstall == true)
 	       std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.Name()
 	       std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.Name()
 			 << " as " << Start.DepType() << " of " << Pkg.Name()
 			 << " as " << Start.DepType() << " of " << Pkg.Name()
@@ -1199,7 +1192,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
  	       // mark automatic dependency
  	       // mark automatic dependency
  	       MarkInstall(InstPkg,true,Depth + 1, false, ForceImportantDeps);
  	       MarkInstall(InstPkg,true,Depth + 1, false, ForceImportantDeps);
  	       // Set the autoflag, after MarkInstall because MarkInstall unsets it
  	       // Set the autoflag, after MarkInstall because MarkInstall unsets it
- 	       if (P->CurrentVer == 0)
+ 	       if (InstPkg->CurrentVer == 0)
  		  PkgState[InstPkg->ID].Flags |= Flag::Auto;
  		  PkgState[InstPkg->ID].Flags |= Flag::Auto;
  	    }
  	    }
 	 }
 	 }
@@ -1211,6 +1204,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
          upgrade the package. */
          upgrade the package. */
       if (Start.IsNegative() == true)
       if (Start.IsNegative() == true)
       {
       {
+	 SPtrArray<Version *> List = Start.AllTargets();
 	 for (Version **I = List; *I != 0; I++)
 	 for (Version **I = List; *I != 0; I++)
 	 {
 	 {
 	    VerIterator Ver(*this,*I);
 	    VerIterator Ver(*this,*I);
@@ -1222,14 +1216,17 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 	       continue;
 	       continue;
 
 
 	    if (PkgState[Pkg->ID].CandidateVer != *I &&
 	    if (PkgState[Pkg->ID].CandidateVer != *I &&
-	        Start->Type == Dep::DpkgBreaks)
-	       MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps);
-	    else
-	       MarkDelete(Pkg,false,Depth + 1, false);
+		Start->Type == Dep::DpkgBreaks &&
+		MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps) == true)
+	       continue;
+	    else if (MarkDelete(Pkg,false,Depth + 1, false) == false)
+	       break;
 	 }
 	 }
 	 continue;
 	 continue;
       }      
       }      
    }
    }
+
+   return Dep.end() == true;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // DepCache::IsInstallOk - check if it is ok to install this package	/*{{{*/
 // DepCache::IsInstallOk - check if it is ok to install this package	/*{{{*/
@@ -1250,25 +1247,42 @@ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To)
    if (unlikely(Pkg.end() == true))
    if (unlikely(Pkg.end() == true))
       return;
       return;
 
 
+   APT::PackageList pkglist;
+   if (Pkg->CurrentVer != 0 &&
+       (Pkg.CurrentVer()-> MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
+   {
+      pkgCache::GrpIterator Grp = Pkg.Group();
+      for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
+      {
+	 if (P->CurrentVer != 0)
+	    pkglist.insert(P);
+      }
+   }
+   else
+      pkglist.insert(Pkg);
+
    ActionGroup group(*this);
    ActionGroup group(*this);
 
 
-   RemoveSizes(Pkg);
-   RemoveStates(Pkg);
-   
-   StateCache &P = PkgState[Pkg->ID];
-   if (To == true)
-      P.iFlags |= ReInstall;
-   else
-      P.iFlags &= ~ReInstall;
-   
-   AddStates(Pkg);
-   AddSizes(Pkg);
+   for (APT::PackageList::const_iterator Pkg = pkglist.begin(); Pkg != pkglist.end(); ++Pkg)
+   {
+      RemoveSizes(Pkg);
+      RemoveStates(Pkg);
+
+      StateCache &P = PkgState[Pkg->ID];
+      if (To == true)
+	 P.iFlags |= ReInstall;
+      else
+	 P.iFlags &= ~ReInstall;
+
+      AddStates(Pkg);
+      AddSizes(Pkg);
+   }
 }
 }
 									/*}}}*/
 									/*}}}*/
 // DepCache::SetCandidateVersion - Change the candidate version		/*{{{*/
 // DepCache::SetCandidateVersion - Change the candidate version		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-void pkgDepCache::SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo)
+void pkgDepCache::SetCandidateVersion(VerIterator TargetVer)
 {
 {
    pkgCache::PkgIterator Pkg = TargetVer.ParentPkg();
    pkgCache::PkgIterator Pkg = TargetVer.ParentPkg();
    StateCache &P = PkgState[Pkg->ID];
    StateCache &P = PkgState[Pkg->ID];
@@ -1558,7 +1572,7 @@ bool pkgDepCache::Policy::IsImportantDep(DepIterator const &Dep)
       return true;
       return true;
    else if(Dep->Type == pkgCache::Dep::Recommends) 
    else if(Dep->Type == pkgCache::Dep::Recommends) 
    {
    {
-      if ( _config->FindB("APT::Install-Recommends", false))
+      if (InstallRecommends)
 	 return true;
 	 return true;
       // we suport a special mode to only install-recommends for certain
       // we suport a special mode to only install-recommends for certain
       // sections
       // sections
@@ -1569,11 +1583,17 @@ bool pkgDepCache::Policy::IsImportantDep(DepIterator const &Dep)
 	 return true;
 	 return true;
    }
    }
    else if(Dep->Type == pkgCache::Dep::Suggests)
    else if(Dep->Type == pkgCache::Dep::Suggests)
-     return _config->FindB("APT::Install-Suggests", false);
+      return InstallSuggests;
 
 
    return false;
    return false;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// Policy::GetPriority - Get the priority of the package pin		/*{{{*/
+signed short pkgDepCache::Policy::GetPriority(pkgCache::PkgIterator const &Pkg)
+{ return 0; };
+signed short pkgDepCache::Policy::GetPriority(pkgCache::PkgFileIterator const &File)
+{ return 0; };
+									/*}}}*/
 pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc()		/*{{{*/
 pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc()		/*{{{*/
 {
 {
   DefaultRootSetFunc *f = new DefaultRootSetFunc;
   DefaultRootSetFunc *f = new DefaultRootSetFunc;
@@ -1599,6 +1619,9 @@ bool pkgDepCache::MarkFollowsSuggests()
 // pkgDepCache::MarkRequired - the main mark algorithm			/*{{{*/
 // pkgDepCache::MarkRequired - the main mark algorithm			/*{{{*/
 bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
 bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
 {
 {
+   if (_config->Find("APT::Solver", "internal") != "internal")
+      return true;
+
    bool follow_recommends;
    bool follow_recommends;
    bool follow_suggests;
    bool follow_suggests;
    bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
    bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
@@ -1625,6 +1648,7 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
    {
    {
       if(!(PkgState[p->ID].Flags & Flag::Auto) ||
       if(!(PkgState[p->ID].Flags & Flag::Auto) ||
 	  (p->Flags & Flag::Essential) ||
 	  (p->Flags & Flag::Essential) ||
+	  (p->Flags & Flag::Important) ||
 	  userFunc.InRootSet(p) ||
 	  userFunc.InRootSet(p) ||
 	  // be nice even then a required package violates the policy (#583517)
 	  // be nice even then a required package violates the policy (#583517)
 	  // and do the full mark process also for required packages
 	  // and do the full mark process also for required packages

+ 31 - 23
apt-pkg/depcache.h

@@ -40,12 +40,18 @@
 
 
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
-#include <apt-pkg/progress.h>
-#include <apt-pkg/error.h>
 
 
 #include <vector>
 #include <vector>
 #include <memory>
 #include <memory>
 #include <set>
 #include <set>
+#include <list>
+
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/progress.h>
+#include <apt-pkg/error.h>
+#endif
+
+class OpProgress;
 
 
 class pkgDepCache : protected pkgCache::Namespace
 class pkgDepCache : protected pkgCache::Namespace
 {
 {
@@ -233,6 +239,7 @@ class pkgDepCache : protected pkgCache::Namespace
       inline bool Delete() const {return Mode == ModeDelete;};
       inline bool Delete() const {return Mode == ModeDelete;};
       inline bool Purge() const {return Delete() == true && (iFlags & pkgDepCache::Purge) == pkgDepCache::Purge; };
       inline bool Purge() const {return Delete() == true && (iFlags & pkgDepCache::Purge) == pkgDepCache::Purge; };
       inline bool Keep() const {return Mode == ModeKeep;};
       inline bool Keep() const {return Mode == ModeKeep;};
+      inline bool Protect() const {return (iFlags & Protected) == Protected;};
       inline bool Upgrade() const {return Status > 0 && Mode == ModeInstall;};
       inline bool Upgrade() const {return Status > 0 && Mode == ModeInstall;};
       inline bool Upgradable() const {return Status >= 1;};
       inline bool Upgradable() const {return Status >= 1;};
       inline bool Downgrade() const {return Status < 0 && Mode == ModeInstall;};
       inline bool Downgrade() const {return Status < 0 && Mode == ModeInstall;};
@@ -257,11 +264,21 @@ class pkgDepCache : protected pkgCache::Namespace
    class Policy
    class Policy
    {
    {
       public:
       public:
-      
+      Policy() {
+         InstallRecommends = _config->FindB("APT::Install-Recommends", false);
+         InstallSuggests = _config->FindB("APT::Install-Suggests", false);
+      }
+
       virtual VerIterator GetCandidateVer(PkgIterator const &Pkg);
       virtual VerIterator GetCandidateVer(PkgIterator const &Pkg);
       virtual bool IsImportantDep(DepIterator const &Dep);
       virtual bool IsImportantDep(DepIterator const &Dep);
-      
+      virtual signed short GetPriority(PkgIterator const &Pkg);
+      virtual signed short GetPriority(PkgFileIterator const &File);
+
       virtual ~Policy() {};
       virtual ~Policy() {};
+
+      private:
+      bool InstallRecommends;
+      bool InstallSuggests;
    };
    };
 
 
    private:
    private:
@@ -315,11 +332,10 @@ class pkgDepCache : protected pkgCache::Namespace
    void Update(PkgIterator const &P);
    void Update(PkgIterator const &P);
    
    
    // Count manipulators
    // Count manipulators
-   void AddSizes(const PkgIterator &Pkg, bool const &Invert = false);
+   void AddSizes(const PkgIterator &Pkg, bool const Invert = false);
    inline void RemoveSizes(const PkgIterator &Pkg) {AddSizes(Pkg, true);};
    inline void RemoveSizes(const PkgIterator &Pkg) {AddSizes(Pkg, true);};
-   void AddSizes(const PkgIterator &Pkg,signed long Mult) __deprecated;
-   void AddStates(const PkgIterator &Pkg,int Add = 1);
-   inline void RemoveStates(const PkgIterator &Pkg) {AddStates(Pkg,-1);};
+   void AddStates(const PkgIterator &Pkg, bool const Invert = false);
+   inline void RemoveStates(const PkgIterator &Pkg) {AddStates(Pkg,true);};
    
    
    public:
    public:
 
 
@@ -328,9 +344,9 @@ class pkgDepCache : protected pkgCache::Namespace
    inline Header &Head() {return *Cache->HeaderP;};
    inline Header &Head() {return *Cache->HeaderP;};
    inline GrpIterator GrpBegin() {return Cache->GrpBegin();};
    inline GrpIterator GrpBegin() {return Cache->GrpBegin();};
    inline PkgIterator PkgBegin() {return Cache->PkgBegin();};
    inline PkgIterator PkgBegin() {return Cache->PkgBegin();};
-   inline GrpIterator FindGrp(string const &Name) {return Cache->FindGrp(Name);};
-   inline PkgIterator FindPkg(string const &Name) {return Cache->FindPkg(Name);};
-   inline PkgIterator FindPkg(string const &Name, string const &Arch) {return Cache->FindPkg(Name, Arch);};
+   inline GrpIterator FindGrp(std::string const &Name) {return Cache->FindGrp(Name);};
+   inline PkgIterator FindPkg(std::string const &Name) {return Cache->FindPkg(Name);};
+   inline PkgIterator FindPkg(std::string const &Name, std::string const &Arch) {return Cache->FindPkg(Name, Arch);};
 
 
    inline pkgCache &GetCache() {return *Cache;};
    inline pkgCache &GetCache() {return *Cache;};
    inline pkgVersioningSystem &VS() {return *Cache->VS;};
    inline pkgVersioningSystem &VS() {return *Cache->VS;};
@@ -388,18 +404,17 @@ class pkgDepCache : protected pkgCache::Namespace
    /** \name State Manipulators
    /** \name State Manipulators
     */
     */
    // @{
    // @{
-   void MarkKeep(PkgIterator const &Pkg, bool Soft = false,
+   bool MarkKeep(PkgIterator const &Pkg, bool Soft = false,
 		 bool FromUser = true, unsigned long Depth = 0);
 		 bool FromUser = true, unsigned long Depth = 0);
-   void MarkDelete(PkgIterator const &Pkg, bool MarkPurge = false,
+   bool MarkDelete(PkgIterator const &Pkg, bool MarkPurge = false,
                    unsigned long Depth = 0, bool FromUser = true);
                    unsigned long Depth = 0, bool FromUser = true);
-   void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
+   bool MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
 		    unsigned long Depth = 0, bool FromUser = true,
 		    unsigned long Depth = 0, bool FromUser = true,
 		    bool ForceImportantDeps = false);
 		    bool ForceImportantDeps = false);
    void MarkProtected(PkgIterator const &Pkg) { PkgState[Pkg->ID].iFlags |= Protected; };
    void MarkProtected(PkgIterator const &Pkg) { PkgState[Pkg->ID].iFlags |= Protected; };
 
 
    void SetReInstall(PkgIterator const &Pkg,bool To);
    void SetReInstall(PkgIterator const &Pkg,bool To);
-   // FIXME: Remove the unused boolean parameter on abi break
-   void SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo = true);
+   void SetCandidateVersion(VerIterator TargetVer);
    bool SetCandidateRelease(pkgCache::VerIterator TargetVer,
    bool SetCandidateRelease(pkgCache::VerIterator TargetVer,
 				std::string const &TargetRel);
 				std::string const &TargetRel);
    /** Set the candidate version for dependencies too if needed.
    /** Set the candidate version for dependencies too if needed.
@@ -484,13 +499,6 @@ class pkgDepCache : protected pkgCache::Namespace
    virtual ~pkgDepCache();
    virtual ~pkgDepCache();
 
 
    private:
    private:
-   // Helper for Update(OpProgress) to remove pseudoinstalled arch all packages
-   // FIXME: they are private so shouldn't affect abi, but just in case…
-   __deprecated bool RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set<unsigned long> &recheck) { return true; };
-   __deprecated bool ReInstallPseudoForGroup(unsigned long const &Grp, std::set<unsigned long> &recheck) { return true; };
-   __deprecated bool ReInstallPseudoForGroup(pkgCache::PkgIterator const &P, std::set<unsigned long> &recheck) { return true; };
-
-
    bool IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
    bool IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
 			unsigned long const Depth, bool const FromUser);
 			unsigned long const Depth, bool const FromUser);
 };
 };

+ 573 - 0
apt-pkg/edsp.cc

@@ -0,0 +1,573 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+   Set of methods to help writing and reading everything needed for EDSP
+   ##################################################################### */
+									/*}}}*/
+// Include Files							/*{{{*/
+#include <config.h>
+
+#include <apt-pkg/edsp.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/policy.h>
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/progress.h>
+
+#include <limits>
+#include <stdio.h>
+
+#include <string>
+
+#include <apti18n.h>
+									/*}}}*/
+
+using std::string;
+
+// we could use pkgCache::DepType and ::Priority, but these would be localized strings…
+const char * const EDSP::PrioMap[] = {0, "important", "required", "standard",
+				      "optional", "extra"};
+const char * const EDSP::DepMap[] = {"", "Depends", "Pre-Depends", "Suggests",
+				     "Recommends" , "Conflicts", "Replaces",
+				     "Obsoletes", "Breaks", "Enhances"};
+
+// EDSP::WriteScenario - to the given file descriptor			/*{{{*/
+bool EDSP::WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress)
+{
+   if (Progress != NULL)
+      Progress->SubProgress(Cache.Head().VersionCount, _("Send scenario to solver"));
+   unsigned long p = 0;
+   for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg)
+      for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver, ++p)
+      {
+	 WriteScenarioVersion(Cache, output, Pkg, Ver);
+	 WriteScenarioDependency(Cache, output, Pkg, Ver);
+	 fprintf(output, "\n");
+	 if (Progress != NULL && p % 100 == 0)
+	    Progress->Progress(p);
+      }
+   return true;
+}
+									/*}}}*/
+// EDSP::WriteLimitedScenario - to the given file descriptor		/*{{{*/
+bool EDSP::WriteLimitedScenario(pkgDepCache &Cache, FILE* output,
+				APT::PackageSet const &pkgset,
+				OpProgress *Progress)
+{
+   if (Progress != NULL)
+      Progress->SubProgress(Cache.Head().VersionCount, _("Send scenario to solver"));
+   unsigned long p  = 0;
+   for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg, ++p)
+      for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver)
+      {
+	 WriteScenarioVersion(Cache, output, Pkg, Ver);
+	 WriteScenarioLimitedDependency(Cache, output, Pkg, Ver, pkgset);
+	 fprintf(output, "\n");
+	 if (Progress != NULL && p % 100 == 0)
+	    Progress->Progress(p);
+      }
+   if (Progress != NULL)
+      Progress->Done();
+   return true;
+}
+									/*}}}*/
+// EDSP::WriteScenarioVersion						/*{{{*/
+void EDSP::WriteScenarioVersion(pkgDepCache &Cache, FILE* output, pkgCache::PkgIterator const &Pkg,
+				pkgCache::VerIterator const &Ver)
+{
+   fprintf(output, "Package: %s\n", Pkg.Name());
+   fprintf(output, "Architecture: %s\n", Ver.Arch());
+   fprintf(output, "Version: %s\n", Ver.VerStr());
+   if (Pkg.CurrentVer() == Ver)
+      fprintf(output, "Installed: yes\n");
+   if (Pkg->SelectedState == pkgCache::State::Hold ||
+       (Cache[Pkg].Keep() == true && Cache[Pkg].Protect() == true))
+      fprintf(output, "Hold: yes\n");
+   fprintf(output, "APT-ID: %d\n", Ver->ID);
+   fprintf(output, "Priority: %s\n", PrioMap[Ver->Priority]);
+   if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
+      fprintf(output, "Essential: yes\n");
+   fprintf(output, "Section: %s\n", Ver.Section());
+   if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
+      fprintf(output, "Multi-Arch: allowed\n");
+   else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign)
+      fprintf(output, "Multi-Arch: foreign\n");
+   else if ((Ver->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
+      fprintf(output, "Multi-Arch: same\n");
+   signed short Pin = std::numeric_limits<signed short>::min();
+   for (pkgCache::VerFileIterator File = Ver.FileList(); File.end() == false; ++File) {
+      signed short const p = Cache.GetPolicy().GetPriority(File.File());
+      if (Pin < p)
+	 Pin = p;
+   }
+   fprintf(output, "APT-Pin: %d\n", Pin);
+   if (Cache.GetCandidateVer(Pkg) == Ver)
+      fprintf(output, "APT-Candidate: yes\n");
+   if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto)
+      fprintf(output, "APT-Automatic: yes\n");
+}
+									/*}}}*/
+// EDSP::WriteScenarioDependency					/*{{{*/
+void EDSP::WriteScenarioDependency(pkgDepCache &Cache, FILE* output, pkgCache::PkgIterator const &Pkg,
+				pkgCache::VerIterator const &Ver)
+{
+   std::string dependencies[pkgCache::Dep::Enhances + 1];
+   bool orGroup = false;
+   for (pkgCache::DepIterator Dep = Ver.DependsList(); Dep.end() == false; ++Dep)
+   {
+      // Ignore implicit dependencies for multiarch here
+      if (strcmp(Pkg.Arch(), Dep.TargetPkg().Arch()) != 0)
+	 continue;
+      if (orGroup == false)
+	 dependencies[Dep->Type].append(", ");
+      dependencies[Dep->Type].append(Dep.TargetPkg().Name());
+      if (Dep->Version != 0)
+	 dependencies[Dep->Type].append(" (").append(pkgCache::CompTypeDeb(Dep->CompareOp)).append(" ").append(Dep.TargetVer()).append(")");
+      if ((Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)
+      {
+	 dependencies[Dep->Type].append(" | ");
+	 orGroup = true;
+      }
+      else
+	 orGroup = false;
+   }
+   for (int i = 1; i < pkgCache::Dep::Enhances + 1; ++i)
+      if (dependencies[i].empty() == false)
+	 fprintf(output, "%s: %s\n", DepMap[i], dependencies[i].c_str()+2);
+   string provides;
+   for (pkgCache::PrvIterator Prv = Ver.ProvidesList(); Prv.end() == false; ++Prv)
+   {
+      // Ignore implicit provides for multiarch here
+      if (strcmp(Pkg.Arch(), Prv.ParentPkg().Arch()) != 0 || strcmp(Pkg.Name(),Prv.Name()) == 0)
+	 continue;
+      provides.append(", ").append(Prv.Name());
+   }
+   if (provides.empty() == false)
+      fprintf(output, "Provides: %s\n", provides.c_str()+2);
+}
+									/*}}}*/
+// EDSP::WriteScenarioLimitedDependency					/*{{{*/
+void EDSP::WriteScenarioLimitedDependency(pkgDepCache &Cache, FILE* output,
+					  pkgCache::PkgIterator const &Pkg,
+					  pkgCache::VerIterator const &Ver,
+					  APT::PackageSet const &pkgset)
+{
+   std::string dependencies[pkgCache::Dep::Enhances + 1];
+   bool orGroup = false;
+   for (pkgCache::DepIterator Dep = Ver.DependsList(); Dep.end() == false; ++Dep)
+   {
+      // Ignore implicit dependencies for multiarch here
+      if (strcmp(Pkg.Arch(), Dep.TargetPkg().Arch()) != 0)
+	 continue;
+      if (orGroup == false)
+      {
+	 if (pkgset.find(Dep.TargetPkg()) == pkgset.end())
+	    continue;
+	 dependencies[Dep->Type].append(", ");
+      }
+      else if (pkgset.find(Dep.TargetPkg()) == pkgset.end())
+      {
+	 if ((Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)
+	    continue;
+	 dependencies[Dep->Type].erase(dependencies[Dep->Type].end()-3, dependencies[Dep->Type].end());
+	 orGroup = false;
+	 continue;
+      }
+      dependencies[Dep->Type].append(Dep.TargetPkg().Name());
+      if (Dep->Version != 0)
+	 dependencies[Dep->Type].append(" (").append(pkgCache::CompTypeDeb(Dep->CompareOp)).append(" ").append(Dep.TargetVer()).append(")");
+      if ((Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)
+      {
+	 dependencies[Dep->Type].append(" | ");
+	 orGroup = true;
+      }
+      else
+	 orGroup = false;
+   }
+   for (int i = 1; i < pkgCache::Dep::Enhances + 1; ++i)
+      if (dependencies[i].empty() == false)
+	 fprintf(output, "%s: %s\n", DepMap[i], dependencies[i].c_str()+2);
+   string provides;
+   for (pkgCache::PrvIterator Prv = Ver.ProvidesList(); Prv.end() == false; ++Prv)
+   {
+      // Ignore implicit provides for multiarch here
+      if (strcmp(Pkg.Arch(), Prv.ParentPkg().Arch()) != 0 || strcmp(Pkg.Name(),Prv.Name()) == 0)
+	 continue;
+      if (pkgset.find(Prv.ParentPkg()) == pkgset.end())
+	 continue;
+      provides.append(", ").append(Prv.Name());
+   }
+   if (provides.empty() == false)
+      fprintf(output, "Provides: %s\n", provides.c_str()+2);
+}
+									/*}}}*/
+// EDSP::WriteRequest - to the given file descriptor			/*{{{*/
+bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade,
+			bool const DistUpgrade, bool const AutoRemove,
+			OpProgress *Progress)
+{
+   if (Progress != NULL)
+      Progress->SubProgress(Cache.Head().PackageCount, _("Send request to solver"));
+   unsigned long p = 0;
+   string del, inst;
+   for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg, ++p)
+   {
+      if (Progress != NULL && p % 100 == 0)
+         Progress->Progress(p);
+      string* req;
+      if (Cache[Pkg].Delete() == true)
+	 req = &del;
+      else if (Cache[Pkg].NewInstall() == true || Cache[Pkg].Upgrade() == true)
+	 req = &inst;
+      else
+	 continue;
+      req->append(" ").append(Pkg.FullName());
+   }
+   fprintf(output, "Request: EDSP 0.4\n");
+   if (del.empty() == false)
+      fprintf(output, "Remove: %s\n", del.c_str()+1);
+   if (inst.empty() == false)
+      fprintf(output, "Install: %s\n", inst.c_str()+1);
+   if (Upgrade == true)
+      fprintf(output, "Upgrade: yes\n");
+   if (DistUpgrade == true)
+      fprintf(output, "Dist-Upgrade: yes\n");
+   if (AutoRemove == true)
+      fprintf(output, "Autoremove: yes\n");
+   if (_config->FindB("APT::Solver::Strict-Pinning", true) == false)
+      fprintf(output, "Strict-Pinning: no\n");
+   string solverpref("APT::Solver::");
+   solverpref.append(_config->Find("APT::Solver", "internal")).append("::Preferences");
+   if (_config->Exists(solverpref) == true)
+      fprintf(output, "Preferences: %s\n", _config->Find(solverpref,"").c_str());
+   fprintf(output, "\n");
+
+   return true;
+}
+									/*}}}*/
+// EDSP::ReadResponse - from the given file descriptor			/*{{{*/
+bool EDSP::ReadResponse(int const input, pkgDepCache &Cache, OpProgress *Progress) {
+	/* We build an map id to mmap offset here
+	   In theory we could use the offset as ID, but then VersionCount
+	   couldn't be used to create other versionmappings anymore and it
+	   would be too easy for a (buggy) solver to segfault APT… */
+	unsigned long long const VersionCount = Cache.Head().VersionCount;
+	unsigned long VerIdx[VersionCount];
+	for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; ++P) {
+		for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V)
+			VerIdx[V->ID] = V.Index();
+		Cache[P].Marked = true;
+		Cache[P].Garbage = false;
+	}
+
+	FileFd in;
+	in.OpenDescriptor(input, FileFd::ReadOnly);
+	pkgTagFile response(&in, 100);
+	pkgTagSection section;
+
+	while (response.Step(section) == true) {
+		std::string type;
+		if (section.Exists("Install") == true)
+			type = "Install";
+		else if (section.Exists("Remove") == true)
+			type = "Remove";
+		else if (section.Exists("Progress") == true) {
+			if (Progress != NULL) {
+				string msg = section.FindS("Message");
+				if (msg.empty() == true)
+					msg = _("Prepare for receiving solution");
+				Progress->SubProgress(100, msg, section.FindI("Percentage", 0));
+			}
+			continue;
+		} else if (section.Exists("Error") == true) {
+			std::string msg = SubstVar(SubstVar(section.FindS("Message"), "\n .\n", "\n\n"), "\n ", "\n");
+			if (msg.empty() == true) {
+				msg = _("External solver failed without a proper error message");
+				_error->Error("%s", msg.c_str());
+			} else
+				_error->Error("External solver failed with: %s", msg.substr(0,msg.find('\n')).c_str());
+			if (Progress != NULL)
+				Progress->Done();
+			std::cerr << "The solver encountered an error of type: " << section.FindS("Error") << std::endl;
+			std::cerr << "The following information might help you to understand what is wrong:" << std::endl;
+			std::cerr << msg << std::endl << std::endl;
+			return false;
+		} else if (section.Exists("Autoremove") == true)
+			type = "Autoremove";
+		else
+			continue;
+
+		size_t const id = section.FindULL(type.c_str(), VersionCount);
+		if (id == VersionCount) {
+			_error->Warning("Unable to parse %s request with id value '%s'!", type.c_str(), section.FindS(type.c_str()).c_str());
+			continue;
+		} else if (id > Cache.Head().VersionCount) {
+			_error->Warning("ID value '%s' in %s request stanza is to high to refer to a known version!", section.FindS(type.c_str()).c_str(), type.c_str());
+			continue;
+		}
+
+		pkgCache::VerIterator Ver(Cache.GetCache(), Cache.GetCache().VerP + VerIdx[id]);
+		Cache.SetCandidateVersion(Ver);
+		if (type == "Install")
+			Cache.MarkInstall(Ver.ParentPkg(), false, 0, false);
+		else if (type == "Remove")
+			Cache.MarkDelete(Ver.ParentPkg(), false);
+		else if (type == "Autoremove") {
+			Cache[Ver.ParentPkg()].Marked = false;
+			Cache[Ver.ParentPkg()].Garbage = true;
+		}
+	}
+	return true;
+}
+									/*}}}*/
+// EDSP::ReadLine - first line from the given file descriptor		/*{{{*/
+// ---------------------------------------------------------------------
+/* Little helper method to read a complete line into a string. Similar to
+   fgets but we need to use the low-level read() here as otherwise the
+   listparser will be confused later on as mixing of fgets and read isn't
+   a supported action according to the manpages and results are undefined */
+bool EDSP::ReadLine(int const input, std::string &line) {
+	char one;
+	ssize_t data = 0;
+	line.erase();
+	line.reserve(100);
+	while ((data = read(input, &one, sizeof(one))) != -1) {
+		if (data != 1)
+			continue;
+		if (one == '\n')
+			return true;
+		if (one == '\r')
+			continue;
+		if (line.empty() == true && isblank(one) != 0)
+			continue;
+		line += one;
+	}
+	return false;
+}
+									/*}}}*/
+// EDSP::StringToBool - convert yes/no to bool				/*{{{*/
+// ---------------------------------------------------------------------
+/* we are not as lazy as we are in the global StringToBool as we really
+   only accept yes/no here - but we will ignore leading spaces */
+bool EDSP::StringToBool(char const *answer, bool const defValue) {
+   for (; isspace(*answer) != 0; ++answer);
+   if (strncasecmp(answer, "yes", 3) == 0)
+      return true;
+   else if (strncasecmp(answer, "no", 2) == 0)
+      return false;
+   else
+      _error->Warning("Value '%s' is not a boolean 'yes' or 'no'!", answer);
+   return defValue;
+}
+									/*}}}*/
+// EDSP::ReadRequest - first stanza from the given file descriptor	/*{{{*/
+bool EDSP::ReadRequest(int const input, std::list<std::string> &install,
+			std::list<std::string> &remove, bool &upgrade,
+			bool &distUpgrade, bool &autoRemove)
+{
+   install.clear();
+   remove.clear();
+   upgrade = false;
+   distUpgrade = false;
+   autoRemove = false;
+   std::string line;
+   while (ReadLine(input, line) == true)
+   {
+      // Skip empty lines before request
+      if (line.empty() == true)
+	 continue;
+      // The first Tag must be a request, so search for it
+      if (line.compare(0, 8, "Request:") != 0)
+	 continue;
+
+      while (ReadLine(input, line) == true)
+      {
+	 // empty lines are the end of the request
+	 if (line.empty() == true)
+	    return true;
+
+	 std::list<std::string> *request = NULL;
+	 if (line.compare(0, 8, "Install:") == 0)
+	 {
+	    line.erase(0, 8);
+	    request = &install;
+	 }
+	 else if (line.compare(0, 7, "Remove:") == 0)
+	 {
+	    line.erase(0, 7);
+	    request = &remove;
+	 }
+	 else if (line.compare(0, 8, "Upgrade:") == 0)
+	    upgrade = EDSP::StringToBool(line.c_str() + 9, false);
+	 else if (line.compare(0, 13, "Dist-Upgrade:") == 0)
+	    distUpgrade = EDSP::StringToBool(line.c_str() + 14, false);
+	 else if (line.compare(0, 11, "Autoremove:") == 0)
+	    autoRemove = EDSP::StringToBool(line.c_str() + 12, false);
+	 else
+	    _error->Warning("Unknown line in EDSP Request stanza: %s", line.c_str());
+
+	 if (request == NULL)
+	    continue;
+	 size_t end = line.length();
+	 do {
+	    size_t begin = line.rfind(' ');
+	    if (begin == std::string::npos)
+	    {
+	       request->push_back(line.substr(0, end));
+	       break;
+	    }
+	    else if (begin < end)
+	       request->push_back(line.substr(begin + 1, end));
+	    line.erase(begin);
+	    end = line.find_last_not_of(' ');
+	 } while (end != std::string::npos);
+      }
+   }
+   return false;
+}
+									/*}}}*/
+// EDSP::ApplyRequest - first stanza from the given file descriptor	/*{{{*/
+bool EDSP::ApplyRequest(std::list<std::string> const &install,
+			 std::list<std::string> const &remove,
+			 pkgDepCache &Cache)
+{
+	for (std::list<std::string>::const_iterator i = install.begin();
+	     i != install.end(); ++i) {
+		pkgCache::PkgIterator P = Cache.FindPkg(*i);
+		if (P.end() == true)
+			_error->Warning("Package %s is not known, so can't be installed", i->c_str());
+		else
+			Cache.MarkInstall(P, false);
+	}
+
+	for (std::list<std::string>::const_iterator i = remove.begin();
+	     i != remove.end(); ++i) {
+		pkgCache::PkgIterator P = Cache.FindPkg(*i);
+		if (P.end() == true)
+			_error->Warning("Package %s is not known, so can't be installed", i->c_str());
+		else
+			Cache.MarkDelete(P);
+	}
+	return true;
+}
+									/*}}}*/
+// EDSP::WriteSolution - to the given file descriptor			/*{{{*/
+bool EDSP::WriteSolution(pkgDepCache &Cache, FILE* output)
+{
+   bool const Debug = _config->FindB("Debug::EDSP::WriteSolution", false);
+   for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg)
+   {
+      if (Cache[Pkg].Delete() == true)
+      {
+	 fprintf(output, "Remove: %d\n", Pkg.CurrentVer()->ID);
+	 if (Debug == true)
+	    fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), Pkg.CurrentVer().VerStr());
+      }
+      else if (Cache[Pkg].NewInstall() == true || Cache[Pkg].Upgrade() == true)
+      {
+	 fprintf(output, "Install: %d\n", Cache.GetCandidateVer(Pkg)->ID);
+	 if (Debug == true)
+	    fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), Cache.GetCandidateVer(Pkg).VerStr());
+      }
+      else if (Cache[Pkg].Garbage == true)
+      {
+	 fprintf(output, "Autoremove: %d\n", Pkg.CurrentVer()->ID);
+	 if (Debug == true)
+	    fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), Pkg.CurrentVer().VerStr());
+	    fprintf(stderr, "Autoremove: %s\nVersion: %s\n", Pkg.FullName().c_str(), Pkg.CurrentVer().VerStr());
+      }
+      else
+	 continue;
+      fprintf(output, "\n");
+   }
+
+   return true;
+}
+									/*}}}*/
+// EDSP::WriteProgess - pulse to the given file descriptor		/*{{{*/
+bool EDSP::WriteProgress(unsigned short const percent, const char* const message, FILE* output) {
+	fprintf(output, "Progress: %s\n", TimeRFC1123(time(NULL)).c_str());
+	fprintf(output, "Percentage: %d\n", percent);
+	fprintf(output, "Message: %s\n\n", message);
+	fflush(output);
+	return true;
+}
+									/*}}}*/
+// EDSP::WriteError - format an error message to be send to file descriptor /*{{{*/
+bool EDSP::WriteError(char const * const uuid, std::string const &message, FILE* output) {
+	fprintf(output, "Error: %s\n", uuid);
+	fprintf(output, "Message: %s\n\n", SubstVar(SubstVar(message, "\n\n", "\n.\n"), "\n", "\n ").c_str());
+	return true;
+}
+									/*}}}*/
+// EDSP::ExecuteSolver - fork requested solver and setup ipc pipes	{{{*/
+bool EDSP::ExecuteSolver(const char* const solver, int *solver_in, int *solver_out) {
+	std::vector<std::string> const solverDirs = _config->FindVector("Dir::Bin::Solvers");
+	std::string file;
+	for (std::vector<std::string>::const_iterator dir = solverDirs.begin();
+	     dir != solverDirs.end(); ++dir) {
+		file = flCombine(*dir, solver);
+		if (RealFileExists(file.c_str()) == true)
+			break;
+		file.clear();
+	}
+
+	if (file.empty() == true)
+		return _error->Error("Can't call external solver '%s' as it is not in a configured directory!", solver);
+	int external[4] = {-1, -1, -1, -1};
+	if (pipe(external) != 0 || pipe(external + 2) != 0)
+		return _error->Errno("Resolve", "Can't create needed IPC pipes for EDSP");
+	for (int i = 0; i < 4; ++i)
+		SetCloseExec(external[i], true);
+
+	pid_t Solver = ExecFork();
+	if (Solver == 0) {
+		dup2(external[0], STDIN_FILENO);
+		dup2(external[3], STDOUT_FILENO);
+		const char* calling[2] = { file.c_str(), 0 };
+		execv(calling[0], (char**) calling);
+		std::cerr << "Failed to execute solver '" << solver << "'!" << std::endl;
+		_exit(100);
+	}
+	close(external[0]);
+	close(external[3]);
+
+	if (WaitFd(external[1], true, 5) == false)
+		return _error->Errno("Resolve", "Timed out while Waiting on availability of solver stdin");
+
+	*solver_in = external[1];
+	*solver_out = external[2];
+	return true;
+}
+									/*}}}*/
+// EDSP::ResolveExternal - resolve problems by asking external for help	{{{*/
+bool EDSP::ResolveExternal(const char* const solver, pkgDepCache &Cache,
+			 bool const upgrade, bool const distUpgrade,
+			 bool const autoRemove, OpProgress *Progress) {
+	int solver_in, solver_out;
+	if (EDSP::ExecuteSolver(solver, &solver_in, &solver_out) == false)
+		return false;
+
+	FILE* output = fdopen(solver_in, "w");
+	if (output == NULL)
+		return _error->Errno("Resolve", "fdopen on solver stdin failed");
+
+	if (Progress != NULL)
+		Progress->OverallProgress(0, 100, 5, _("Execute external solver"));
+	EDSP::WriteRequest(Cache, output, upgrade, distUpgrade, autoRemove, Progress);
+	if (Progress != NULL)
+		Progress->OverallProgress(5, 100, 20, _("Execute external solver"));
+	EDSP::WriteScenario(Cache, output, Progress);
+	fclose(output);
+
+	if (Progress != NULL)
+		Progress->OverallProgress(25, 100, 75, _("Execute external solver"));
+	if (EDSP::ReadResponse(solver_out, Cache, Progress) == false)
+		return false;
+
+	return true;
+}
+									/*}}}*/

+ 230 - 0
apt-pkg/edsp.h

@@ -0,0 +1,230 @@
+// -*- mode: cpp; mode: fold -*-
+/** Description \file edsp.h						{{{
+   ######################################################################
+   Set of methods to help writing and reading everything needed for EDSP
+   with the noteable exception of reading a scenario for conversion into
+   a Cache as this is handled by edsp interface for listparser and friends
+   ##################################################################### */
+									/*}}}*/
+#ifndef PKGLIB_EDSP_H
+#define PKGLIB_EDSP_H
+
+#include <apt-pkg/pkgcache.h>
+#include <apt-pkg/cacheset.h>
+
+#include <list>
+#include <string>
+
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/depcache.h>
+#include <apt-pkg/progress.h>
+#endif
+
+class pkgDepCache;
+class OpProgress;
+
+class EDSP								/*{{{*/
+{
+	// we could use pkgCache::DepType and ::Priority, but these would be localized strings…
+	static const char * const PrioMap[];
+	static const char * const DepMap[];
+
+	bool static ReadLine(int const input, std::string &line);
+	bool static StringToBool(char const *answer, bool const defValue);
+
+	void static WriteScenarioVersion(pkgDepCache &Cache, FILE* output,
+					 pkgCache::PkgIterator const &Pkg,
+					 pkgCache::VerIterator const &Ver);
+	void static WriteScenarioDependency(pkgDepCache &Cache, FILE* output,
+					    pkgCache::PkgIterator const &Pkg,
+					    pkgCache::VerIterator const &Ver);
+	void static WriteScenarioLimitedDependency(pkgDepCache &Cache, FILE* output,
+						   pkgCache::PkgIterator const &Pkg,
+						   pkgCache::VerIterator const &Ver,
+						   APT::PackageSet const &pkgset);
+public:
+	/** \brief creates the EDSP request stanza
+	 *
+	 *  In the EDSP protocol the first thing send to the resolver is a stanza
+	 *  encoding the request. This method will write this stanza by looking at
+	 *  the given Cache and requests the installation of all packages which were
+	 *  marked for installation in it (equally for remove).
+	 *
+	 *  \param Cache in which the request is encoded
+	 *  \param output is written to this "file"
+	 *  \param upgrade is true if it is an request like apt-get upgrade
+	 *  \param distUpgrade is true if it is a request like apt-get dist-upgrade
+	 *  \param autoRemove is true if removal of unneeded packages should be performed
+	 *  \param Progress is an instance to report progress to
+	 *
+	 *  \return true if request was composed successfully, otherwise false
+	 */
+	bool static WriteRequest(pkgDepCache &Cache, FILE* output,
+				 bool const upgrade = false,
+				 bool const distUpgrade = false,
+				 bool const autoRemove = false,
+				OpProgress *Progress = NULL);
+
+	/** \brief creates the scenario representing the package universe
+	 *
+	 *  After the request all known information about a package are send
+	 *  to the solver. The output looks similar to a Packages or status file
+	 *
+	 *  All packages and version included in this Cache are send, even if
+	 *  it doesn't make sense from an APT resolver point of view like versions
+	 *  with a negative pin to enable the solver to propose even that as a
+	 *  solution or at least to be able to give a hint what can be done to
+	 *  statisfy a request.
+	 *
+	 *  \param Cache is the known package universe
+	 *  \param output is written to this "file"
+	 *  \param Progress is an instance to report progress to
+	 *
+	 *  \return true if universe was composed successfully, otherwise false
+	 */
+	bool static WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress = NULL);
+
+	/** \brief creates a limited scenario representing the package universe
+	 *
+	 *  This method works similar to #WriteScenario as it works in the same
+	 *  way but doesn't send the complete universe to the solver but only
+	 *  packages included in the pkgset which will have only dependencies
+	 *  on packages which are in the given set. All other dependencies will
+	 *  be removed, so that this method can be used to create testcases
+	 *
+	 *  \param Cache is the known package universe
+	 *  \param output is written to this "file"
+	 *  \param pkgset is a set of packages the universe should be limited to
+	 *  \param Progress is an instance to report progress to
+	 *
+	 *  \return true if universe was composed successfully, otherwise false
+	 */
+	bool static WriteLimitedScenario(pkgDepCache &Cache, FILE* output,
+					 APT::PackageSet const &pkgset,
+					 OpProgress *Progress = NULL);
+
+	/** \brief waits and acts on the information returned from the solver
+	 *
+	 *  This method takes care of interpreting whatever the solver sends
+	 *  through the standard output like a solution, progress or an error.
+	 *  The main thread should handle his control over to this method to
+	 *  wait for the solver to finish the given task
+	 *
+	 *  \param input file descriptor with the response from the solver
+	 *  \param Cache the solution should be applied on if any
+	 *  \param Progress is an instance to report progress to
+	 *
+	 *  \return true if a solution is found and applied correctly, otherwise false
+	 */
+	bool static ReadResponse(int const input, pkgDepCache &Cache, OpProgress *Progress = NULL);
+
+	/** \brief search and read the request stanza for action later
+	 *
+	 *  This method while ignore the input up to the point it finds the
+	 *  Request: line as an indicator for the Request stanza.
+	 *  The request is stored in the parameters install and remove then,
+	 *  as the cache isn't build yet as the scenario follows the request.
+	 *
+	 *  \param input file descriptor with the edsp input for the solver
+	 *  \param[out] install is a list which gets populated with requested installs
+	 *  \param[out] remove is a list which gets populated with requested removals
+	 *  \param[out] upgrade is true if it is a request like apt-get upgrade
+	 *  \param[out] distUpgrade is true if it is a request like apt-get dist-upgrade
+	 *  \param[out] autoRemove is true if removal of uneeded packages should be performed
+	 *
+	 *  \return true if the request could be found and worked on, otherwise false
+	 */
+	bool static ReadRequest(int const input, std::list<std::string> &install,
+			std::list<std::string> &remove, bool &upgrade,
+			bool &distUpgrade, bool &autoRemove);
+
+	/** \brief takes the request lists and applies it on the cache
+	 *
+	 *  The lists as created by #ReadRequest will be used to find the
+	 *  packages in question and mark them for install/remove.
+	 *  No solving is done and no auto-install/-remove.
+	 *
+	 *  \param install is a list of packages to mark for installation
+	 *  \param remove is a list of packages to mark for removal
+	 *  \param Cache is there the markers should be set
+	 *
+	 *  \return false if the request couldn't be applied, true otherwise
+	 */
+	bool static ApplyRequest(std::list<std::string> const &install,
+				 std::list<std::string> const &remove,
+				 pkgDepCache &Cache);
+
+	/** \brief encodes the changes in the Cache as a EDSP solution
+	 *
+	 *  The markers in the Cache are observed and send to given
+	 *  file. The solution isn't checked for consistency or alike,
+	 *  so even broken solutions can be written successfully,
+	 *  but the front-end revicing it will properly fail then.
+	 *
+	 *  \param Cache which represents the solution
+	 *  \param output to write the stanzas forming the solution to
+	 *
+	 *  \return true if solution could be written, otherwise false
+	 */
+	bool static WriteSolution(pkgDepCache &Cache, FILE* output);
+
+	/** \brief sends a progress report
+	 *
+	 *  \param percent of the solving completed
+	 *  \param message the solver wants the user to see
+	 *  \param output the front-end listens for progress report
+	 */
+	bool static WriteProgress(unsigned short const percent, const char* const message, FILE* output);
+
+	/** \brief sends an error report
+	 *
+	 *  Solvers are expected to execute successfully even if
+	 *  they were unable to calculate a solution for a given task.
+	 *  Obviously they can't send a solution through, so this
+	 *  methods deals with formatting an error message correctly
+	 *  so that the front-ends can recieve and display it.
+	 *
+	 *  The first line of the message should be a short description
+	 *  of the error so it can be used for dialog titles or alike
+	 *
+	 *  \param uuid of this error message
+	 *  \param message is free form text to discribe the error
+	 *  \param output the front-end listens for error messages
+	 */
+	bool static WriteError(char const * const uuid, std::string const &message, FILE* output);
+
+
+	/** \brief executes the given solver and returns the pipe ends
+	 *
+	 *  The given solver is executed if it can be found in one of the
+	 *  configured directories and setup for it is performed.
+	 *
+	 *  \param solver to execute
+	 *  \param[out] solver_in will be the stdin of the solver
+	 *  \param[out] solver_out will be the stdout of the solver
+	 *
+	 *  \return true if the solver could be started and the pipes
+	 *  are set up correctly, otherwise false and the pipes are invalid
+	 */
+	bool static ExecuteSolver(const char* const solver, int *solver_in, int *solver_out);
+
+	/** \brief call an external resolver to handle the request
+	 *
+	 *  This method wraps all the methods above to call an external solver
+	 *
+	 *  \param solver to execute
+	 *  \param Cache with the problem and as universe to work in
+	 *  \param upgrade is true if it is a request like apt-get upgrade
+	 *  \param distUpgrade is true if it is a request like apt-get dist-upgrade
+	 *  \param autoRemove is true if unneeded packages should be removed
+	 *  \param Progress is an instance to report progress to
+	 *
+	 *  \return true if the solver has successfully solved the problem,
+	 *  otherwise false
+	 */
+	bool static ResolveExternal(const char* const solver, pkgDepCache &Cache,
+				    bool const upgrade, bool const distUpgrade,
+				    bool const autoRemove, OpProgress *Progress = NULL);
+};
+									/*}}}*/
+#endif

+ 78 - 0
apt-pkg/edsp/edspindexfile.cc

@@ -0,0 +1,78 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+   The scenario file is designed to work as an intermediate file between
+   APT and the resolver. Its on propose very similar to a dpkg status file
+   ##################################################################### */
+									/*}}}*/
+// Include Files							/*{{{*/
+#include <config.h>
+
+#include <apt-pkg/edspindexfile.h>
+#include <apt-pkg/edsplistparser.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/acquire-item.h>
+
+#include <sys/stat.h>
+									/*}}}*/
+
+// edspIndex::edspIndex - Constructor					/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+edspIndex::edspIndex(std::string File) : debStatusIndex(File)
+{
+}
+									/*}}}*/
+// StatusIndex::Merge - Load the index file into a cache		/*{{{*/
+bool edspIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
+{
+   FileFd Pkg;
+   if (File != "stdin")
+      Pkg.Open(File, FileFd::ReadOnly);
+   else
+      Pkg.OpenDescriptor(STDIN_FILENO, FileFd::ReadOnly);
+   if (_error->PendingError() == true)
+      return false;
+   edspListParser Parser(&Pkg);
+   if (_error->PendingError() == true)
+      return false;
+
+   if (Prog != NULL)
+      Prog->SubProgress(0,File);
+   if (Gen.SelectFile(File,std::string(),*this) == false)
+      return _error->Error("Problem with SelectFile %s",File.c_str());
+
+   // Store the IMS information
+   pkgCache::PkgFileIterator CFile = Gen.GetCurFile();
+   CFile->Size = Pkg.FileSize();
+   CFile->mtime = Pkg.ModificationTime();
+   CFile->Archive = Gen.WriteUniqString("edsp::scenario");
+
+   if (Gen.MergeList(Parser) == false)
+      return _error->Error("Problem with MergeList %s",File.c_str());
+   return true;
+}
+									/*}}}*/
+// Index File types for APT						/*{{{*/
+class edspIFType: public pkgIndexFile::Type
+{
+   public:
+   virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const
+   {
+      // we don't have a record parser for this type as the file is not presistent
+      return NULL;
+   };
+   edspIFType() {Label = "EDSP scenario file";};
+};
+static edspIFType _apt_Universe;
+
+const pkgIndexFile::Type *edspIndex::GetType() const
+{
+   return &_apt_Universe;
+}
+									/*}}}*/

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

@@ -0,0 +1,31 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+   The scenario file is designed to work as an intermediate file between
+   APT and the resolver. Its on propose very similar to a dpkg status file
+   ##################################################################### */
+									/*}}}*/
+#ifndef PKGLIB_EDSPINDEXFILE_H
+#define PKGLIB_EDSPINDEXFILE_H
+
+#include <apt-pkg/debindexfile.h>
+
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/indexfile.h>
+#endif
+
+class edspIndex : public debStatusIndex
+{
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+
+   public:
+
+   virtual const Type *GetType() const;
+
+   virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const;
+
+   edspIndex(std::string File);
+};
+
+#endif

+ 92 - 0
apt-pkg/edsp/edsplistparser.cc

@@ -0,0 +1,92 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+
+   Package Cache Generator - Generator for the cache structure.
+
+   This builds the cache structure from the abstract package list parser.
+
+   ##################################################################### */
+									/*}}}*/
+// Include Files							/*{{{*/
+#include <config.h>
+
+#include <apt-pkg/edsplistparser.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/md5.h>
+#include <apt-pkg/macros.h>
+									/*}}}*/
+
+// ListParser::edspListParser - Constructor				/*{{{*/
+edspListParser::edspListParser(FileFd *File, std::string const &Arch) : debListParser(File, Arch)
+{}
+									/*}}}*/
+// ListParser::NewVersion - Fill in the version structure		/*{{{*/
+bool edspListParser::NewVersion(pkgCache::VerIterator &Ver)
+{
+   Ver->ID = Section.FindI("APT-ID", Ver->ID);
+   return debListParser::NewVersion(Ver);
+}
+									/*}}}*/
+// ListParser::Description - Return the description string		/*{{{*/
+// ---------------------------------------------------------------------
+/* Sorry, no description for the resolvers… */
+std::string edspListParser::Description()
+{
+   return "";
+}
+std::string edspListParser::DescriptionLanguage()
+{
+   return "";
+}
+MD5SumValue edspListParser::Description_md5()
+{
+   return MD5SumValue("");
+}
+									/*}}}*/
+// ListParser::VersionHash - Compute a unique hash for this version	/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+unsigned short edspListParser::VersionHash()
+{
+   if (Section.Exists("APT-Hash") == true)
+      return Section.FindI("APT-Hash");
+   else if (Section.Exists("APT-ID") == true)
+      return Section.FindI("APT-ID");
+   return 0;
+}
+									/*}}}*/
+// ListParser::ParseStatus - Parse the status field			/*{{{*/
+// ---------------------------------------------------------------------
+/* The Status: line here is not a normal dpkg one but just one which tells
+   use if the package is installed or not, where missing means not. */
+bool edspListParser::ParseStatus(pkgCache::PkgIterator &Pkg,
+				pkgCache::VerIterator &Ver)
+{
+   unsigned long state = 0;
+   if (Section.FindFlag("Hold",state,pkgCache::State::Hold) == false)
+      return false;
+   if (state != 0)
+      Pkg->SelectedState = pkgCache::State::Hold;
+
+   state = 0;
+   if (Section.FindFlag("Installed",state,pkgCache::State::Installed) == false)
+      return false;
+   if (state != 0)
+   {
+      Pkg->CurrentState = pkgCache::State::Installed;
+      Pkg->CurrentVer = Ver.Index();
+   }
+
+   return true;
+}
+									/*}}}*/
+// ListParser::LoadReleaseInfo - Load the release information		/*{{{*/
+bool edspListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
+				    FileFd &File, std::string component)
+{
+   return true;
+}
+									/*}}}*/

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

@@ -0,0 +1,43 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+
+   EDSP Package List Parser - This implements the abstract parser
+   interface for the APT specific intermediate format which is passed
+   to external resolvers
+
+   ##################################################################### */
+									/*}}}*/
+#ifndef PKGLIB_EDSPLISTPARSER_H
+#define PKGLIB_EDSPLISTPARSER_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 edspListParser : public debListParser
+{
+   public:
+   virtual bool NewVersion(pkgCache::VerIterator &Ver);
+   virtual std::string Description();
+   virtual std::string DescriptionLanguage();
+   virtual MD5SumValue Description_md5();
+   virtual unsigned short VersionHash();
+
+   bool LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,FileFd &File,
+			std::string section);
+
+   edspListParser(FileFd *File, std::string const &Arch = "");
+
+   protected:
+   virtual bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver);
+
+};
+
+#endif

+ 127 - 0
apt-pkg/edsp/edspsystem.cc

@@ -0,0 +1,127 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+
+   This system provides the abstraction to use the scenario file as the
+   only source of package information to be able to feed the created file
+   back to APT for its own consumption (eat your own dogfood).
+
+   ##################################################################### */
+									/*}}}*/
+// Include Files							/*{{{*/
+#include <config.h>
+
+#include <apt-pkg/edspsystem.h>
+#include <apt-pkg/debversion.h>
+#include <apt-pkg/edspindexfile.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/fileutl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include <apti18n.h>
+									/*}}}*/
+
+edspSystem edspSys;
+
+// System::debSystem - Constructor					/*{{{*/
+edspSystem::edspSystem()
+{
+   StatusFile = 0;
+
+   Label = "Debian APT solver interface";
+   VS = &debVS;
+}
+									/*}}}*/
+// System::~debSystem - Destructor					/*{{{*/
+edspSystem::~edspSystem()
+{
+   delete StatusFile;
+}
+									/*}}}*/
+// System::Lock - Get the lock						/*{{{*/
+bool edspSystem::Lock()
+{
+   return true;
+}
+									/*}}}*/
+// System::UnLock - Drop a lock						/*{{{*/
+bool edspSystem::UnLock(bool NoErrors)
+{
+   return true;
+}
+									/*}}}*/
+// System::CreatePM - Create the underlying package manager		/*{{{*/
+// ---------------------------------------------------------------------
+/* we can't use edsp input as input for real installations - just a
+   simulation can work, but everything else will fail bigtime */
+pkgPackageManager *edspSystem::CreatePM(pkgDepCache *Cache) const
+{
+   return NULL;
+}
+									/*}}}*/
+// System::Initialize - Setup the configuration space..			/*{{{*/
+bool edspSystem::Initialize(Configuration &Cnf)
+{
+   Cnf.Set("Dir::State::extended_states", "/dev/null");
+   Cnf.Set("Dir::State::status","/dev/null");
+   Cnf.Set("Dir::State::lists","/dev/null");
+
+   Cnf.Set("Debug::NoLocking", "true");
+   Cnf.Set("APT::Get::Simulate", "true");
+
+   if (StatusFile) {
+     delete StatusFile;
+     StatusFile = 0;
+   }
+   return true;
+}
+									/*}}}*/
+// System::ArchiveSupported - Is a file format supported		/*{{{*/
+bool edspSystem::ArchiveSupported(const char *Type)
+{
+   return false;
+}
+									/*}}}*/
+// System::Score - Determine if we should use the edsp system		/*{{{*/
+signed edspSystem::Score(Configuration const &Cnf)
+{
+   if (Cnf.Find("edsp::scenario", "") == "stdin")
+      return 1000;
+   if (FileExists(Cnf.FindFile("edsp::scenario","")) == true)
+      return 1000;
+   return -1000;
+}
+									/*}}}*/
+// System::AddStatusFiles - Register the status files			/*{{{*/
+bool edspSystem::AddStatusFiles(std::vector<pkgIndexFile *> &List)
+{
+   if (StatusFile == 0)
+   {
+      if (_config->Find("edsp::scenario", "") == "stdin")
+	 StatusFile = new edspIndex("stdin");
+      else
+	 StatusFile = new edspIndex(_config->FindFile("edsp::scenario"));
+   }
+   List.push_back(StatusFile);
+   return true;
+}
+									/*}}}*/
+// System::FindIndex - Get an index file for status files		/*{{{*/
+bool edspSystem::FindIndex(pkgCache::PkgFileIterator File,
+			  pkgIndexFile *&Found) const
+{
+   if (StatusFile == 0)
+      return false;
+   if (StatusFile->FindInCache(*File.Cache()) == File)
+   {
+      Found = StatusFile;
+      return true;
+   }
+
+   return false;
+}
+									/*}}}*/

+ 41 - 0
apt-pkg/edsp/edspsystem.h

@@ -0,0 +1,41 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+// $Id: debsystem.h,v 1.4 2003/01/11 07:16:33 jgg Exp $
+/* ######################################################################
+
+   System - Debian version of the  System Class
+
+   ##################################################################### */
+									/*}}}*/
+#ifndef PKGLIB_EDSPSYSTEM_H
+#define PKGLIB_EDSPSYSTEM_H
+
+#include <apt-pkg/pkgsystem.h>
+
+class edspIndex;
+class edspSystem : public pkgSystem
+{
+   /** \brief dpointer placeholder (for later in case we need it) */
+   void *d;
+
+   edspIndex *StatusFile;
+
+   public:
+
+   virtual bool Lock();
+   virtual bool UnLock(bool NoErrors = false);
+   virtual pkgPackageManager *CreatePM(pkgDepCache *Cache) const;
+   virtual bool Initialize(Configuration &Cnf);
+   virtual bool ArchiveSupported(const char *Type);
+   virtual signed Score(Configuration const &Cnf);
+   virtual bool AddStatusFiles(std::vector<pkgIndexFile *> &List);
+   virtual bool FindIndex(pkgCache::PkgFileIterator File,
+			  pkgIndexFile *&Found) const;
+
+   edspSystem();
+   ~edspSystem();
+};
+
+extern edspSystem edspSys;
+
+#endif

+ 0 - 0
apt-pkg/indexcopy.cc


Неке датотеке нису приказане због велике количине промена