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

Merge remote-tracking branch 'donkult/debian/experimental' into debian/experimental

Michael Vogt пре 11 година
родитељ
комит
245dde9619
100 измењених фајлова са 5962 додато и 4412 уклоњено
  1. 5 0
      apt-inst/contrib/arfile.h
  2. 5 0
      apt-inst/contrib/extracttar.cc
  3. 10 1
      apt-inst/contrib/extracttar.h
  4. 8 0
      apt-inst/deb/debfile.cc
  5. 10 2
      apt-inst/deb/debfile.h
  6. 11 1
      apt-inst/dirstream.h
  7. 2174 1672
      apt-pkg/acquire-item.cc
  8. 442 426
      apt-pkg/acquire-item.h
  9. 15 10
      apt-pkg/acquire-method.cc
  10. 11 3
      apt-pkg/acquire-method.h
  11. 224 148
      apt-pkg/acquire-worker.cc
  12. 3 1
      apt-pkg/acquire-worker.h
  13. 139 24
      apt-pkg/acquire.cc
  14. 38 17
      apt-pkg/acquire.h
  15. 13 1
      apt-pkg/algorithms.cc
  16. 13 3
      apt-pkg/algorithms.h
  17. 10 11
      apt-pkg/aptconfiguration.h
  18. 0 1
      apt-pkg/cachefile.h
  19. 48 10
      apt-pkg/cacheiterators.h
  20. 26 39
      apt-pkg/cacheset.cc
  21. 45 99
      apt-pkg/cacheset.h
  22. 20 16
      apt-pkg/cdrom.cc
  23. 9 2
      apt-pkg/cdrom.h
  24. 2 1
      apt-pkg/clean.cc
  25. 2 0
      apt-pkg/clean.h
  26. 16 15
      apt-pkg/contrib/cdromutl.cc
  27. 3 0
      apt-pkg/contrib/cmndline.cc
  28. 1 0
      apt-pkg/contrib/cmndline.h
  29. 13 7
      apt-pkg/contrib/configuration.cc
  30. 3 2
      apt-pkg/contrib/configuration.h
  31. 21 1
      apt-pkg/contrib/fileutl.cc
  32. 12 1
      apt-pkg/contrib/fileutl.h
  33. 86 46
      apt-pkg/contrib/hashes.cc
  34. 37 11
      apt-pkg/contrib/hashes.h
  35. 18 1
      apt-pkg/contrib/macros.h
  36. 9 0
      apt-pkg/contrib/sha2_internal.cc
  37. 74 79
      apt-pkg/contrib/strutl.cc
  38. 2 1
      apt-pkg/contrib/strutl.h
  39. 98 427
      apt-pkg/deb/debindexfile.cc
  40. 28 75
      apt-pkg/deb/debindexfile.h
  41. 10 39
      apt-pkg/deb/deblistparser.cc
  42. 13 13
      apt-pkg/deb/deblistparser.h
  43. 333 269
      apt-pkg/deb/debmetaindex.cc
  44. 17 14
      apt-pkg/deb/debmetaindex.h
  45. 60 55
      apt-pkg/deb/debrecords.cc
  46. 33 17
      apt-pkg/deb/debrecords.h
  47. 36 22
      apt-pkg/deb/debsrcrecords.cc
  48. 4 5
      apt-pkg/deb/debsrcrecords.h
  49. 1 1
      apt-pkg/deb/debsystem.cc
  50. 0 1
      apt-pkg/deb/debversion.h
  51. 103 67
      apt-pkg/deb/dpkgpm.cc
  52. 37 40
      apt-pkg/depcache.cc
  53. 6 4
      apt-pkg/depcache.h
  54. 70 62
      apt-pkg/edsp.cc
  55. 13 29
      apt-pkg/edsp.h
  56. 6 5
      apt-pkg/edsp/edspindexfile.cc
  57. 2 1
      apt-pkg/edsp/edspindexfile.h
  58. 4 2
      apt-pkg/edsp/edsplistparser.cc
  59. 5 3
      apt-pkg/edsp/edsplistparser.h
  60. 2 2
      apt-pkg/edsp/edspsystem.cc
  61. 2 4
      apt-pkg/edsp/edspsystem.h
  62. 63 77
      apt-pkg/indexcopy.cc
  63. 23 7
      apt-pkg/indexcopy.h
  64. 126 6
      apt-pkg/indexfile.cc
  65. 73 7
      apt-pkg/indexfile.h
  66. 32 24
      apt-pkg/indexrecords.cc
  67. 9 12
      apt-pkg/indexrecords.h
  68. 24 2
      apt-pkg/init.cc
  69. 6 0
      apt-pkg/install-progress.cc
  70. 10 1
      apt-pkg/install-progress.h
  71. 57 0
      apt-pkg/metaindex.cc
  72. 14 20
      apt-pkg/metaindex.h
  73. 2 2
      apt-pkg/orderlist.h
  74. 39 13
      apt-pkg/packagemanager.cc
  75. 6 8
      apt-pkg/packagemanager.h
  76. 81 57
      apt-pkg/pkgcache.cc
  77. 151 26
      apt-pkg/pkgcache.h
  78. 200 66
      apt-pkg/pkgcachegen.cc
  79. 20 17
      apt-pkg/pkgcachegen.h
  80. 3 0
      apt-pkg/pkgrecords.cc
  81. 12 3
      apt-pkg/pkgrecords.h
  82. 2 0
      apt-pkg/pkgsystem.cc
  83. 3 2
      apt-pkg/pkgsystem.h
  84. 29 54
      apt-pkg/policy.cc
  85. 3 2
      apt-pkg/policy.h
  86. 1 1
      apt-pkg/sourcelist.cc
  87. 12 16
      apt-pkg/sourcelist.h
  88. 30 1
      apt-pkg/srcrecords.cc
  89. 9 11
      apt-pkg/srcrecords.h
  90. 109 0
      apt-pkg/tagfile-order.c
  91. 237 95
      apt-pkg/tagfile.cc
  92. 56 27
      apt-pkg/tagfile.h
  93. 18 10
      apt-pkg/upgrade.cc
  94. 9 4
      apt-pkg/upgrade.h
  95. 3 7
      apt-pkg/vendorlist.cc
  96. 3 0
      apt-pkg/version.cc
  97. 1 1
      apt-pkg/version.h
  98. 23 22
      apt-pkg/versionmatch.cc
  99. 2 2
      apt-pkg/versionmatch.h
  100. 0 0
      apt-private/acqprogress.cc

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

@@ -17,6 +17,7 @@
 
 
 
 
 #include <string>
 #include <string>
+#include <apt-pkg/macros.h>
 #ifndef APT_8_CLEANER_HEADERS
 #ifndef APT_8_CLEANER_HEADERS
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
 #endif
 #endif
@@ -61,7 +62,11 @@ struct ARArchive::Member
    unsigned long long Size;
    unsigned long long Size;
    
    
    // Location of the data.
    // Location of the data.
+#if APT_PKG_ABI >= 413
    unsigned long long Start;
    unsigned long long Start;
+#else
+   unsigned long Start;
+#endif
    Member *Next;
    Member *Next;
    
    
    Member() : Start(0), Next(0) {};
    Member() : Start(0), Next(0) {};

+ 5 - 0
apt-inst/contrib/extracttar.cc

@@ -60,8 +60,13 @@ struct ExtractTar::TarHeader
 // ExtractTar::ExtractTar - Constructor					/*{{{*/
 // ExtractTar::ExtractTar - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
+#if APT_PKG_ABI >= 413
 ExtractTar::ExtractTar(FileFd &Fd,unsigned long long Max,string DecompressionProgram)
 ExtractTar::ExtractTar(FileFd &Fd,unsigned long long Max,string DecompressionProgram)
 	: File(Fd), MaxInSize(Max), DecompressProg(DecompressionProgram)
 	: File(Fd), MaxInSize(Max), DecompressProg(DecompressionProgram)
+#else
+ExtractTar::ExtractTar(FileFd &Fd,unsigned long Max,string DecompressionProgram)
+	: File(Fd), MaxInSize(Max), DecompressProg(DecompressionProgram)
+#endif
 {
 {
    GZPid = -1;
    GZPid = -1;
    Eof = false;
    Eof = false;

+ 10 - 1
apt-inst/contrib/extracttar.h

@@ -15,6 +15,7 @@
 #define PKGLIB_EXTRACTTAR_H
 #define PKGLIB_EXTRACTTAR_H
 
 
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
+#include <apt-pkg/macros.h>
 
 
 #include <string>
 #include <string>
 
 
@@ -39,7 +40,11 @@ class ExtractTar
                   GNU_LongLink = 'K',GNU_LongName = 'L'};
                   GNU_LongLink = 'K',GNU_LongName = 'L'};
 
 
    FileFd &File;
    FileFd &File;
+#if APT_PKG_ABI >= 413
    unsigned long long MaxInSize;
    unsigned long long MaxInSize;
+#else
+   unsigned long MaxInSize;
+#endif
    int GZPid;
    int GZPid;
    FileFd InFd;
    FileFd InFd;
    bool Eof;
    bool Eof;
@@ -52,8 +57,12 @@ class ExtractTar
    public:
    public:
 
 
    bool Go(pkgDirStream &Stream);
    bool Go(pkgDirStream &Stream);
-   
+
+#if APT_PKG_ABI >= 413
    ExtractTar(FileFd &Fd,unsigned long long Max,std::string DecompressionProgram);
    ExtractTar(FileFd &Fd,unsigned long long Max,std::string DecompressionProgram);
+#else
+   ExtractTar(FileFd &Fd,unsigned long Max,std::string DecompressionProgram);
+#endif
    virtual ~ExtractTar();
    virtual ~ExtractTar();
 };
 };
 
 

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

@@ -203,7 +203,11 @@ bool debDebFile::MemControlExtract::DoItem(Item &Itm,int &Fd)
 /* Just memcopy the block from the tar extractor and put it in the right
 /* Just memcopy the block from the tar extractor and put it in the right
    place in the pre-allocated memory block. */
    place in the pre-allocated memory block. */
 bool debDebFile::MemControlExtract::Process(Item &/*Itm*/,const unsigned char *Data,
 bool debDebFile::MemControlExtract::Process(Item &/*Itm*/,const unsigned char *Data,
+#if APT_PKG_ABI >= 413
 			     unsigned long long Size,unsigned long long Pos)
 			     unsigned long long Size,unsigned long long Pos)
+#else
+			     unsigned long Size,unsigned long Pos)
+#endif
 {
 {
    memcpy(Control + Pos, Data,Size);
    memcpy(Control + Pos, Data,Size);
    return true;
    return true;
@@ -232,7 +236,11 @@ bool debDebFile::MemControlExtract::Read(debDebFile &Deb)
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* The given memory block is loaded into the parser and parsed as a control
 /* The given memory block is loaded into the parser and parsed as a control
    record. */
    record. */
+#if APT_PKG_ABI >= 413
 bool debDebFile::MemControlExtract::TakeControl(const void *Data,unsigned long long Size)
 bool debDebFile::MemControlExtract::TakeControl(const void *Data,unsigned long long Size)
+#else
+bool debDebFile::MemControlExtract::TakeControl(const void *Data,unsigned long Size)
+#endif
 {
 {
    delete [] Control;
    delete [] Control;
    Control = new char[Size+2];
    Control = new char[Size+2];

+ 10 - 2
apt-inst/deb/debfile.h

@@ -27,6 +27,7 @@
 #include <apt-pkg/arfile.h>
 #include <apt-pkg/arfile.h>
 #include <apt-pkg/dirstream.h>
 #include <apt-pkg/dirstream.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/tagfile.h>
+#include <apt-pkg/macros.h>
 
 
 #include <string>
 #include <string>
 
 
@@ -81,13 +82,20 @@ class debDebFile::MemControlExtract : public pkgDirStream
    // Members from DirStream
    // Members from DirStream
    virtual bool DoItem(Item &Itm,int &Fd);
    virtual bool DoItem(Item &Itm,int &Fd);
    virtual bool Process(Item &Itm,const unsigned char *Data,
    virtual bool Process(Item &Itm,const unsigned char *Data,
+#if APT_PKG_ABI >= 413
 			unsigned long long Size,unsigned long long Pos);
 			unsigned long long Size,unsigned long long Pos);
-   
+#else
+			unsigned long Size,unsigned long Pos);
+#endif
 
 
    // Helpers
    // Helpers
    bool Read(debDebFile &Deb);
    bool Read(debDebFile &Deb);
+#if APT_PKG_ABI >= 413
    bool TakeControl(const void *Data,unsigned long long Size);
    bool TakeControl(const void *Data,unsigned long long Size);
-      
+#else
+   bool TakeControl(const void *Data,unsigned long Size);
+#endif
+
    MemControlExtract() : IsControl(false), Control(0), Length(0), Member("control") {};
    MemControlExtract() : IsControl(false), Control(0), Length(0), Member("control") {};
    MemControlExtract(std::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;};   

+ 11 - 1
apt-inst/dirstream.h

@@ -25,6 +25,7 @@
 #ifndef PKGLIB_DIRSTREAM_H
 #ifndef PKGLIB_DIRSTREAM_H
 #define PKGLIB_DIRSTREAM_H
 #define PKGLIB_DIRSTREAM_H
 
 
+#include <apt-pkg/macros.h>
 
 
 class pkgDirStream
 class pkgDirStream
 { 
 { 
@@ -37,10 +38,15 @@ class pkgDirStream
 	           Directory, FIFO} Type;
 	           Directory, FIFO} Type;
       char *Name;
       char *Name;
       char *LinkTarget;
       char *LinkTarget;
+#if APT_PKG_ABI >= 413
       unsigned long long Size;
       unsigned long long Size;
+#endif
       unsigned long Mode;
       unsigned long Mode;
       unsigned long UID;
       unsigned long UID;
       unsigned long GID;
       unsigned long GID;
+#if APT_PKG_ABI < 413
+      unsigned long Size;
+#endif
       unsigned long MTime;
       unsigned long MTime;
       unsigned long Major;
       unsigned long Major;
       unsigned long Minor;
       unsigned long Minor;
@@ -49,9 +55,13 @@ class pkgDirStream
    virtual bool DoItem(Item &Itm,int &Fd);
    virtual bool DoItem(Item &Itm,int &Fd);
    virtual bool Fail(Item &Itm,int Fd);
    virtual bool Fail(Item &Itm,int Fd);
    virtual bool FinishedFile(Item &Itm,int Fd);
    virtual bool FinishedFile(Item &Itm,int Fd);
+#if APT_PKG_ABI >= 413
    virtual bool Process(Item &/*Itm*/,const unsigned char * /*Data*/,
    virtual bool Process(Item &/*Itm*/,const unsigned char * /*Data*/,
 			unsigned long long /*Size*/,unsigned long long /*Pos*/) {return true;};
 			unsigned long long /*Size*/,unsigned long long /*Pos*/) {return true;};
-      
+#else
+   virtual bool Process(Item &/*Itm*/,const unsigned char * /*Data*/,
+			unsigned long /*Size*/,unsigned long /*Pos*/) {return true;};
+#endif
    virtual ~pkgDirStream() {};   
    virtual ~pkgDirStream() {};   
 };
 };
 
 

Разлика између датотеке није приказан због своје велике величине
+ 2174 - 1672
apt-pkg/acquire-item.cc


Разлика између датотеке није приказан због своје велике величине
+ 442 - 426
apt-pkg/acquire-item.h


+ 15 - 10
apt-pkg/acquire-method.cc

@@ -376,7 +376,10 @@ int pkgAcqMethod::Run(bool Single)
 		  Tmp->ExpectedHashes.push_back(HashString(*t, hash));
 		  Tmp->ExpectedHashes.push_back(HashString(*t, hash));
 	    }
 	    }
             char *End;
             char *End;
-            Tmp->MaximumSize = strtoll(LookupTag(Message, "Maximum-Size", "0").c_str(), &End, 10);
+	    if (Tmp->ExpectedHashes.FileSize() > 0)
+	       Tmp->MaximumSize = Tmp->ExpectedHashes.FileSize();
+	    else
+	       Tmp->MaximumSize = strtoll(LookupTag(Message, "Maximum-Size", "0").c_str(), &End, 10);
 	    Tmp->Next = 0;
 	    Tmp->Next = 0;
 	    
 	    
 	    // Append it to the list
 	    // Append it to the list
@@ -385,14 +388,14 @@ int pkgAcqMethod::Run(bool Single)
 	    *I = Tmp;
 	    *I = Tmp;
 	    if (QueueBack == 0)
 	    if (QueueBack == 0)
 	       QueueBack = Tmp;
 	       QueueBack = Tmp;
-	    
+
 	    // Notify that this item is to be fetched.
 	    // Notify that this item is to be fetched.
-	    if (Fetch(Tmp) == false)
+	    if (URIAcquire(Message, Tmp) == false)
 	       Fail();
 	       Fail();
-	    
-	    break;					     
-	 }   
-      }      
+
+	    break;
+	 }
+      }
    }
    }
 
 
    Exit();
    Exit();
@@ -400,8 +403,6 @@ int pkgAcqMethod::Run(bool Single)
 }
 }
 									/*}}}*/
 									/*}}}*/
 // AcqMethod::PrintStatus - privately really send a log/status message	/*{{{*/
 // AcqMethod::PrintStatus - privately really send a log/status message	/*{{{*/
-// ---------------------------------------------------------------------
-/* */
 void pkgAcqMethod::PrintStatus(char const * const header, const char* Format,
 void pkgAcqMethod::PrintStatus(char const * const header, const char* Format,
 			       va_list &args) const
 			       va_list &args) const
 {
 {
@@ -477,5 +478,9 @@ void pkgAcqMethod::Dequeue() {						/*{{{*/
    delete Tmp;
    delete Tmp;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 pkgAcqMethod::~pkgAcqMethod() {}
 pkgAcqMethod::~pkgAcqMethod() {}
+
+pkgAcqMethod::FetchItem::FetchItem() {}
+pkgAcqMethod::FetchItem::~FetchItem() {}
+
+pkgAcqMethod::FetchResult::~FetchResult() {}

+ 11 - 3
apt-pkg/acquire-method.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: acquire-method.h,v 1.15.2.1 2003/12/24 23:09:17 mdz Exp $
 /* ######################################################################
 /* ######################################################################
 
 
    Acquire Method - Method helper class + functions
    Acquire Method - Method helper class + functions
@@ -53,6 +52,11 @@ class pkgAcqMethod
       // for when we know it or a arbitrary limit when we don't know the
       // for when we know it or a arbitrary limit when we don't know the
       // filesize (like a InRelease file)
       // filesize (like a InRelease file)
       unsigned long long MaximumSize;
       unsigned long long MaximumSize;
+
+      FetchItem();
+      virtual ~FetchItem();
+      private:
+      void *d;
    };
    };
    
    
    struct FetchResult
    struct FetchResult
@@ -67,6 +71,9 @@ class pkgAcqMethod
       
       
       void TakeHashes(class Hashes &Hash);
       void TakeHashes(class Hashes &Hash);
       FetchResult();
       FetchResult();
+      virtual ~FetchResult();
+      private:
+      void *d;
    };
    };
 
 
    // State
    // State
@@ -76,11 +83,12 @@ class pkgAcqMethod
    std::string FailReason;
    std::string FailReason;
    std::string UsedMirror;
    std::string UsedMirror;
    std::string IP;
    std::string IP;
-   
+
    // Handlers for messages
    // Handlers for messages
    virtual bool Configuration(std::string Message);
    virtual bool Configuration(std::string Message);
    virtual bool Fetch(FetchItem * /*Item*/) {return true;};
    virtual bool Fetch(FetchItem * /*Item*/) {return true;};
-   
+   virtual bool URIAcquire(std::string const &/*Message*/, FetchItem *Itm) { return Fetch(Itm); };
+
    // Outgoing messages
    // Outgoing messages
    void Fail(bool Transient = false);
    void Fail(bool Transient = false);
    inline void Fail(const char *Why, bool Transient = false) {Fail(std::string(Why),Transient);};
    inline void Fail(const char *Why, bool Transient = false) {Fail(std::string(Why),Transient);};

+ 224 - 148
apt-pkg/acquire-worker.cc

@@ -43,20 +43,6 @@
 
 
 using namespace std;
 using namespace std;
 
 
-static void ChangeOwnerAndPermissionOfFile(char const * const requester, char const * const file, char const * const user, char const * const group, mode_t const mode) /*{{{*/
-{
-   if (getuid() == 0 && strlen(user) != 0 && strlen(group) != 0) // if we aren't root, we can't chown, so don't try it
-   {
-      // ensure the file is owned by root and has good permissions
-      struct passwd const * const pw = getpwnam(user);
-      struct group const * const gr = getgrnam(group);
-      if (pw != NULL && gr != NULL && chown(file, pw->pw_uid, gr->gr_gid) != 0)
-	 _error->WarningE(requester, "chown to %s:%s of file %s failed", user, group, file);
-   }
-   if (chmod(file, mode) != 0)
-      _error->WarningE(requester, "chmod 0%o of file %s failed", mode, file);
-}
-									/*}}}*/
 // Worker::Worker - Constructor for Queue startup			/*{{{*/
 // Worker::Worker - Constructor for Queue startup			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -69,8 +55,8 @@ pkgAcquire::Worker::Worker(Queue *Q,MethodConfig *Cnf,
    CurrentItem = 0;
    CurrentItem = 0;
    TotalSize = 0;
    TotalSize = 0;
    CurrentSize = 0;
    CurrentSize = 0;
-   
-   Construct();   
+
+   Construct();
 }
 }
 									/*}}}*/
 									/*}}}*/
 // Worker::Worker - Constructor for method config startup		/*{{{*/
 // Worker::Worker - Constructor for method config startup		/*{{{*/
@@ -84,8 +70,8 @@ pkgAcquire::Worker::Worker(MethodConfig *Cnf)
    CurrentItem = 0;
    CurrentItem = 0;
    TotalSize = 0;
    TotalSize = 0;
    CurrentSize = 0;
    CurrentSize = 0;
-   
-   Construct();   
+
+   Construct();
 }
 }
 									/*}}}*/
 									/*}}}*/
 // Worker::Construct - Constructor helper				/*{{{*/
 // Worker::Construct - Constructor helper				/*{{{*/
@@ -150,7 +136,7 @@ bool pkgAcquire::Worker::Start()
    }
    }
    for (int I = 0; I != 4; I++)
    for (int I = 0; I != 4; I++)
       SetCloseExec(Pipes[I],true);
       SetCloseExec(Pipes[I],true);
-   
+
    // Fork off the process
    // Fork off the process
    Process = ExecFork();
    Process = ExecFork();
    if (Process == 0)
    if (Process == 0)
@@ -159,9 +145,9 @@ bool pkgAcquire::Worker::Start()
       dup2(Pipes[1],STDOUT_FILENO);
       dup2(Pipes[1],STDOUT_FILENO);
       dup2(Pipes[2],STDIN_FILENO);
       dup2(Pipes[2],STDIN_FILENO);
       SetCloseExec(STDOUT_FILENO,false);
       SetCloseExec(STDOUT_FILENO,false);
-      SetCloseExec(STDIN_FILENO,false);      
+      SetCloseExec(STDIN_FILENO,false);
       SetCloseExec(STDERR_FILENO,false);
       SetCloseExec(STDERR_FILENO,false);
-      
+
       const char *Args[2];
       const char *Args[2];
       Args[0] = Method.c_str();
       Args[0] = Method.c_str();
       Args[1] = 0;
       Args[1] = 0;
@@ -179,7 +165,7 @@ bool pkgAcquire::Worker::Start()
    close(Pipes[2]);
    close(Pipes[2]);
    OutReady = false;
    OutReady = false;
    InReady = true;
    InReady = true;
-   
+
    // Read the configuration data
    // Read the configuration data
    if (WaitFd(InFd) == false ||
    if (WaitFd(InFd) == false ||
        ReadMessages() == false)
        ReadMessages() == false)
@@ -188,7 +174,7 @@ bool pkgAcquire::Worker::Start()
    RunMessages();
    RunMessages();
    if (OwnerQ != 0)
    if (OwnerQ != 0)
       SendConfiguration();
       SendConfiguration();
-   
+
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -215,7 +201,7 @@ bool pkgAcquire::Worker::RunMessages()
 
 
       if (Debug == true)
       if (Debug == true)
 	 clog << " <- " << Access << ':' << QuoteString(Message,"\n") << endl;
 	 clog << " <- " << Access << ':' << QuoteString(Message,"\n") << endl;
-      
+
       // Fetch the message number
       // Fetch the message number
       char *End;
       char *End;
       int Number = strtol(Message.c_str(),&End,10);
       int Number = strtol(Message.c_str(),&End,10);
@@ -229,15 +215,15 @@ bool pkgAcquire::Worker::RunMessages()
 
 
       // update used mirror
       // update used mirror
       string UsedMirror = LookupTag(Message,"UsedMirror", "");
       string UsedMirror = LookupTag(Message,"UsedMirror", "");
-      if (!UsedMirror.empty() && 
+      if (!UsedMirror.empty() &&
           Itm && 
           Itm && 
-          Itm->Description.find(" ") != string::npos) 
+          Itm->Description.find(" ") != string::npos)
       {
       {
          Itm->Description.replace(0, Itm->Description.find(" "), UsedMirror);
          Itm->Description.replace(0, Itm->Description.find(" "), UsedMirror);
          // FIXME: will we need this as well?
          // FIXME: will we need this as well?
          //Itm->ShortDesc = UsedMirror;
          //Itm->ShortDesc = UsedMirror;
       }
       }
-      
+
       // Determine the message number and dispatch
       // Determine the message number and dispatch
       switch (Number)
       switch (Number)
       {
       {
@@ -246,18 +232,18 @@ bool pkgAcquire::Worker::RunMessages()
 	 if (Capabilities(Message) == false)
 	 if (Capabilities(Message) == false)
 	    return _error->Error("Unable to process Capabilities message from %s",Access.c_str());
 	    return _error->Error("Unable to process Capabilities message from %s",Access.c_str());
 	 break;
 	 break;
-	 
+
 	 // 101 Log
 	 // 101 Log
 	 case 101:
 	 case 101:
 	 if (Debug == true)
 	 if (Debug == true)
 	    clog << " <- (log) " << LookupTag(Message,"Message") << endl;
 	    clog << " <- (log) " << LookupTag(Message,"Message") << endl;
 	 break;
 	 break;
-	 
+
 	 // 102 Status
 	 // 102 Status
 	 case 102:
 	 case 102:
 	 Status = LookupTag(Message,"Message");
 	 Status = LookupTag(Message,"Message");
 	 break;
 	 break;
-	    
+
          // 103 Redirect
          // 103 Redirect
          case 103:
          case 103:
          {
          {
@@ -266,27 +252,36 @@ bool pkgAcquire::Worker::RunMessages()
                _error->Error("Method gave invalid 103 Redirect message");
                _error->Error("Method gave invalid 103 Redirect message");
                break;
                break;
             }
             }
- 
+
             string NewURI = LookupTag(Message,"New-URI",URI.c_str());
             string NewURI = LookupTag(Message,"New-URI",URI.c_str());
             Itm->URI = NewURI;
             Itm->URI = NewURI;
 
 
 	    ItemDone();
 	    ItemDone();
 
 
-	    pkgAcquire::Item *Owner = Itm->Owner;
-	    pkgAcquire::ItemDesc Desc = *Itm;
-
 	    // Change the status so that it can be dequeued
 	    // Change the status so that it can be dequeued
-	    Owner->Status = pkgAcquire::Item::StatIdle;
+	    for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
+	    {
+	       pkgAcquire::Item *Owner = *O;
+	       Owner->Status = pkgAcquire::Item::StatIdle;
+	    }
 	    // Mark the item as done (taking care of all queues)
 	    // Mark the item as done (taking care of all queues)
 	    // and then put it in the main queue again
 	    // and then put it in the main queue again
+	    std::vector<Item*> const ItmOwners = Itm->Owners;
 	    OwnerQ->ItemDone(Itm);
 	    OwnerQ->ItemDone(Itm);
-	    OwnerQ->Owner->Enqueue(Desc);
+	    Itm = NULL;
+	    for (pkgAcquire::Queue::QItem::owner_iterator O = ItmOwners.begin(); O != ItmOwners.end(); ++O)
+	    {
+	       pkgAcquire::Item *Owner = *O;
+	       pkgAcquire::ItemDesc desc = Owner->GetItemDesc();
+	       desc.URI = NewURI;
+	       OwnerQ->Owner->Enqueue(desc);
 
 
-	    if (Log != 0)
-	       Log->Done(Desc);
+	       if (Log != 0)
+		  Log->Done(Owner->GetItemDesc());
+	    }
             break;
             break;
          }
          }
-   
+
 	 // 200 URI Start
 	 // 200 URI Start
 	 case 200:
 	 case 200:
 	 {
 	 {
@@ -295,23 +290,27 @@ bool pkgAcquire::Worker::RunMessages()
 	       _error->Error("Method gave invalid 200 URI Start message");
 	       _error->Error("Method gave invalid 200 URI Start message");
 	       break;
 	       break;
 	    }
 	    }
-	    
+
 	    CurrentItem = Itm;
 	    CurrentItem = Itm;
 	    CurrentSize = 0;
 	    CurrentSize = 0;
 	    TotalSize = strtoull(LookupTag(Message,"Size","0").c_str(), NULL, 10);
 	    TotalSize = strtoull(LookupTag(Message,"Size","0").c_str(), NULL, 10);
 	    ResumePoint = strtoull(LookupTag(Message,"Resume-Point","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));
+	    for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
+	    {
+	       (*O)->Start(Message, TotalSize);
 
 
-	    // Display update before completion
-	    if (Log != 0 && Log->MorePulses == true)
-	       Log->Pulse(Itm->Owner->GetOwner());
-	    
-	    if (Log != 0)
-	       Log->Fetch(*Itm);
+	       // Display update before completion
+	       if (Log != 0)
+	       {
+		  if (Log->MorePulses == true)
+		     Log->Pulse((*O)->GetOwner());
+		  Log->Fetch((*O)->GetItemDesc());
+	       }
+	    }
 
 
 	    break;
 	    break;
 	 }
 	 }
-	 
+
 	 // 201 URI Done
 	 // 201 URI Done
 	 case 201:
 	 case 201:
 	 {
 	 {
@@ -320,72 +319,113 @@ bool pkgAcquire::Worker::RunMessages()
 	       _error->Error("Method gave invalid 201 URI Done message");
 	       _error->Error("Method gave invalid 201 URI Done message");
 	       break;
 	       break;
 	    }
 	    }
-	    
-	    pkgAcquire::Item *Owner = Itm->Owner;
-	    pkgAcquire::ItemDesc Desc = *Itm;
 
 
-	    if (RealFileExists(Owner->DestFile))
-	       ChangeOwnerAndPermissionOfFile("201::URIDone", Owner->DestFile.c_str(), "root", "root", 0644);
+	    PrepareFiles("201::URIDone", Itm);
 
 
 	    // Display update before completion
 	    // Display update before completion
 	    if (Log != 0 && Log->MorePulses == true)
 	    if (Log != 0 && Log->MorePulses == true)
-	       Log->Pulse(Owner->GetOwner());
-	    
-	    OwnerQ->ItemDone(Itm);
-	    unsigned long long const ServerSize = strtoull(LookupTag(Message,"Size","0").c_str(), NULL, 10);
-            bool isHit = StringToBool(LookupTag(Message,"IMS-Hit"),false) ||
-                         StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false);
-            // Using the https method the server might return 200, but the
-            // If-Modified-Since condition is not satsified, libcurl will
-            // discard the download. In this case, however, TotalSize will be
-            // set to the actual size of the file, while ServerSize will be set
-            // to 0. Therefore, if the item is marked as a hit and the
-            // downloaded size (ServerSize) is 0, we ignore TotalSize.
-	    if (TotalSize != 0 && (!isHit || ServerSize != 0) && ServerSize != TotalSize)
-	       _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);
-
-	    // see if there is a hash to verify
-	    HashStringList RecivedHashes;
-	    HashStringList expectedHashes = Owner->HashSums();
-	    for (HashStringList::const_iterator hs = expectedHashes.begin(); hs != expectedHashes.end(); ++hs)
-	    {
-	       std::string const tagname = hs->HashType() + "-Hash";
-	       std::string const hashsum = LookupTag(Message, tagname.c_str());
-	       if (hashsum.empty() == false)
-		  RecivedHashes.push_back(HashString(hs->HashType(), hashsum));
-	    }
+	       for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
+		  Log->Pulse((*O)->GetOwner());
 
 
-	    if(_config->FindB("Debug::pkgAcquire::Auth", false) == true)
+	    std::string const filename = LookupTag(Message, "Filename", Itm->Owner->DestFile.c_str());
+	    HashStringList ReceivedHashes;
 	    {
 	    {
-	       std::clog << "201 URI Done: " << Owner->DescURI() << endl
-		  << "RecivedHash:" << endl;
-	       for (HashStringList::const_iterator hs = RecivedHashes.begin(); hs != RecivedHashes.end(); ++hs)
-		  std::clog <<  "\t- " << hs->toStr() << std::endl;
-	       std::clog << "ExpectedHash:" << endl;
-	       for (HashStringList::const_iterator hs = expectedHashes.begin(); hs != expectedHashes.end(); ++hs)
-		  std::clog <<  "\t- " << hs->toStr() << std::endl;
-	       std::clog << endl;
+	       // see if we got hashes to verify
+	       for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type)
+	       {
+		  std::string const tagname = std::string(*type) + "-Hash";
+		  std::string const hashsum = LookupTag(Message, tagname.c_str());
+		  if (hashsum.empty() == false)
+		     ReceivedHashes.push_back(HashString(*type, hashsum));
+	       }
+	       // not all methods always sent Hashes our way
+	       if (ReceivedHashes.usable() == false)
+	       {
+		  HashStringList const ExpectedHashes = Itm->GetExpectedHashes();
+		  if (ExpectedHashes.usable() == true && RealFileExists(filename))
+		  {
+		     Hashes calc(ExpectedHashes);
+		     FileFd file(filename, FileFd::ReadOnly, FileFd::None);
+		     calc.AddFD(file);
+		     ReceivedHashes = calc.GetHashStringList();
+		  }
+	       }
 	    }
 	    }
-	    Owner->Done(Message, ServerSize, RecivedHashes, Config);
-	    ItemDone();
 
 
-	    // Log that we are done
-	    if (Log != 0)
+	    // only local files can refer other filenames and counting them as fetched would be unfair
+	    if (Log !=  NULL && filename != Itm->Owner->DestFile)
+	       Log->Fetched(ReceivedHashes.FileSize(),atoi(LookupTag(Message,"Resume-Point","0").c_str()));
+
+	    std::vector<Item*> const ItmOwners = Itm->Owners;
+	    OwnerQ->ItemDone(Itm);
+	    Itm = NULL;
+
+	    bool const isIMSHit = StringToBool(LookupTag(Message,"IMS-Hit"),false) ||
+	       StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false);
+	    for (pkgAcquire::Queue::QItem::owner_iterator O = ItmOwners.begin(); O != ItmOwners.end(); ++O)
 	    {
 	    {
-	       if (isHit)
+	       pkgAcquire::Item * const Owner = *O;
+	       HashStringList const ExpectedHashes = Owner->GetExpectedHashes();
+	       if(_config->FindB("Debug::pkgAcquire::Auth", false) == true)
+	       {
+		  std::clog << "201 URI Done: " << Owner->DescURI() << endl
+		     << "ReceivedHash:" << endl;
+		  for (HashStringList::const_iterator hs = ReceivedHashes.begin(); hs != ReceivedHashes.end(); ++hs)
+		     std::clog <<  "\t- " << hs->toStr() << std::endl;
+		  std::clog << "ExpectedHash:" << endl;
+		  for (HashStringList::const_iterator hs = ExpectedHashes.begin(); hs != ExpectedHashes.end(); ++hs)
+		     std::clog <<  "\t- " << hs->toStr() << std::endl;
+		  std::clog << endl;
+	       }
+
+	       // decide if what we got is what we expected
+	       bool consideredOkay = false;
+	       if (ExpectedHashes.usable())
+	       {
+		  if (ReceivedHashes.usable() == false)
+		  {
+		     /* IMS-Hits can't be checked here as we will have uncompressed file,
+			but the hashes for the compressed file. What we have was good through
+			so all we have to ensure later is that we are not stalled. */
+		     consideredOkay = isIMSHit;
+		  }
+		  else if (ReceivedHashes == ExpectedHashes)
+		     consideredOkay = true;
+		  else
+		     consideredOkay = false;
+
+	       }
+	       else if (Owner->HashesRequired() == true)
+		  consideredOkay = false;
+	       else
+		  consideredOkay = true;
+
+	       if (consideredOkay == true)
 	       {
 	       {
-		  /* Hide 'hits' for local only sources - we also manage to
-		     hide gets */
-		  if (Config->LocalOnly == false)
-		     Log->IMSHit(Desc);
-	       }	       
+		  Owner->Done(Message, ReceivedHashes, Config);
+
+		  // Log that we are done
+		  if (Log != 0)
+		  {
+		     if (isIMSHit)
+			Log->IMSHit(Owner->GetItemDesc());
+		     else
+			Log->Done(Owner->GetItemDesc());
+		  }
+	       }
 	       else
 	       else
-		  Log->Done(Desc);
+	       {
+		  Owner->Status = pkgAcquire::Item::StatAuthError;
+		  Owner->Failed(Message,Config);
+
+		  if (Log != 0)
+		     Log->Fail(Owner->GetItemDesc());
+	       }
 	    }
 	    }
+	    ItemDone();
 	    break;
 	    break;
-	 }	 
-	 
+	 }
+
 	 // 400 URI Failure
 	 // 400 URI Failure
 	 case 400:
 	 case 400:
 	 {
 	 {
@@ -396,44 +436,46 @@ bool pkgAcquire::Worker::RunMessages()
 	       break;
 	       break;
 	    }
 	    }
 
 
+	    PrepareFiles("400::URIFailure", Itm);
+
 	    // Display update before completion
 	    // Display update before completion
 	    if (Log != 0 && Log->MorePulses == true)
 	    if (Log != 0 && Log->MorePulses == true)
-	       Log->Pulse(Itm->Owner->GetOwner());
-
-	    pkgAcquire::Item *Owner = Itm->Owner;
-	    pkgAcquire::ItemDesc Desc = *Itm;
-
-	    if (RealFileExists(Owner->DestFile))
-	       ChangeOwnerAndPermissionOfFile("400::URIFailure", Owner->DestFile.c_str(), "root", "root", 0644);
+	       for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
+		  Log->Pulse((*O)->GetOwner());
 
 
+	    std::vector<Item*> const ItmOwners = Itm->Owners;
 	    OwnerQ->ItemDone(Itm);
 	    OwnerQ->ItemDone(Itm);
+	    Itm = NULL;
+
+	    for (pkgAcquire::Queue::QItem::owner_iterator O = ItmOwners.begin(); O != ItmOwners.end(); ++O)
+	    {
+	       // set some status
+	       if(LookupTag(Message,"FailReason") == "Timeout" ||
+		     LookupTag(Message,"FailReason") == "TmpResolveFailure" ||
+		     LookupTag(Message,"FailReason") == "ResolveFailure" ||
+		     LookupTag(Message,"FailReason") == "ConnectionRefused")
+		  (*O)->Status = pkgAcquire::Item::StatTransientNetworkError;
 
 
-	    // set some status
-	    if(LookupTag(Message,"FailReason") == "Timeout" || 
-	       LookupTag(Message,"FailReason") == "TmpResolveFailure" ||
-	       LookupTag(Message,"FailReason") == "ResolveFailure" ||
-	       LookupTag(Message,"FailReason") == "ConnectionRefused") 
-	       Owner->Status = pkgAcquire::Item::StatTransientNetworkError;
+	       (*O)->Failed(Message,Config);
 
 
-	    Owner->Failed(Message,Config);
+	       if (Log != 0)
+		  Log->Fail((*O)->GetItemDesc());
+	    }
 	    ItemDone();
 	    ItemDone();
 
 
-	    if (Log != 0)
-	       Log->Fail(Desc);
-
 	    break;
 	    break;
-	 }	 
-	 
+	 }
+
 	 // 401 General Failure
 	 // 401 General Failure
 	 case 401:
 	 case 401:
 	 _error->Error("Method %s General failure: %s",Access.c_str(),LookupTag(Message,"Message").c_str());
 	 _error->Error("Method %s General failure: %s",Access.c_str(),LookupTag(Message,"Message").c_str());
 	 break;
 	 break;
-	 
+
 	 // 403 Media Change
 	 // 403 Media Change
 	 case 403:
 	 case 403:
-	 MediaChange(Message); 
+	 MediaChange(Message);
 	 break;
 	 break;
-      }      
+      }
    }
    }
    return true;
    return true;
 }
 }
@@ -446,7 +488,7 @@ bool pkgAcquire::Worker::Capabilities(string Message)
 {
 {
    if (Config == 0)
    if (Config == 0)
       return true;
       return true;
-   
+
    Config->Version = LookupTag(Message,"Version");
    Config->Version = LookupTag(Message,"Version");
    Config->SingleInstance = StringToBool(LookupTag(Message,"Single-Instance"),false);
    Config->SingleInstance = StringToBool(LookupTag(Message,"Single-Instance"),false);
    Config->Pipeline = StringToBool(LookupTag(Message,"Pipeline"),false);
    Config->Pipeline = StringToBool(LookupTag(Message,"Pipeline"),false);
@@ -461,13 +503,13 @@ bool pkgAcquire::Worker::Capabilities(string Message)
       clog << "Configured access method " << Config->Access << endl;
       clog << "Configured access method " << Config->Access << endl;
       clog << "Version:" << Config->Version <<
       clog << "Version:" << Config->Version <<
 	      " SingleInstance:" << Config->SingleInstance <<
 	      " SingleInstance:" << Config->SingleInstance <<
-	      " Pipeline:" << Config->Pipeline << 
-	      " SendConfig:" << Config->SendConfig << 
-	      " LocalOnly: " << Config->LocalOnly << 
-	      " NeedsCleanup: " << Config->NeedsCleanup << 
+	      " Pipeline:" << Config->Pipeline <<
+	      " SendConfig:" << Config->SendConfig <<
+	      " LocalOnly: " << Config->LocalOnly <<
+	      " NeedsCleanup: " << Config->NeedsCleanup <<
 	      " Removable: " << Config->Removable << endl;
 	      " Removable: " << Config->Removable << endl;
    }
    }
-   
+
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -477,10 +519,10 @@ bool pkgAcquire::Worker::Capabilities(string Message)
 bool pkgAcquire::Worker::MediaChange(string Message)
 bool pkgAcquire::Worker::MediaChange(string Message)
 {
 {
    int status_fd = _config->FindI("APT::Status-Fd",-1);
    int status_fd = _config->FindI("APT::Status-Fd",-1);
-   if(status_fd > 0) 
+   if(status_fd > 0)
    {
    {
       string Media = LookupTag(Message,"Media");
       string Media = LookupTag(Message,"Media");
-      string Drive = LookupTag(Message,"Drive"); 
+      string Drive = LookupTag(Message,"Drive");
       ostringstream msg,status;
       ostringstream msg,status;
       ioprintf(msg,_("Please insert the disc labeled: "
       ioprintf(msg,_("Please insert the disc labeled: "
 		     "'%s' "
 		     "'%s' "
@@ -550,21 +592,29 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
 {
 {
    if (OutFd == -1)
    if (OutFd == -1)
       return false;
       return false;
-   
+
    string Message = "600 URI Acquire\n";
    string Message = "600 URI Acquire\n";
    Message.reserve(300);
    Message.reserve(300);
    Message += "URI: " + Item->URI;
    Message += "URI: " + Item->URI;
    Message += "\nFilename: " + Item->Owner->DestFile;
    Message += "\nFilename: " + Item->Owner->DestFile;
-   HashStringList const hsl = Item->Owner->HashSums();
+
+   HashStringList const hsl = Item->GetExpectedHashes();
    for (HashStringList::const_iterator hs = hsl.begin(); hs != hsl.end(); ++hs)
    for (HashStringList::const_iterator hs = hsl.begin(); hs != hsl.end(); ++hs)
       Message += "\nExpected-" + hs->HashType() + ": " + hs->HashValue();
       Message += "\nExpected-" + hs->HashType() + ": " + hs->HashValue();
-   if(Item->Owner->FileSize > 0)
+
+   if (hsl.FileSize() == 0)
    {
    {
-      string MaximumSize;
-      strprintf(MaximumSize, "%llu", Item->Owner->FileSize);
-      Message += "\nMaximum-Size: " + MaximumSize;
+      unsigned long long FileSize = Item->GetMaximumSize();
+      if(FileSize > 0)
+      {
+	 string MaximumSize;
+	 strprintf(MaximumSize, "%llu", FileSize);
+	 Message += "\nMaximum-Size: " + MaximumSize;
+      }
    }
    }
-   Message += Item->Owner->Custom600Headers();
+
+   Item->SyncDestinationFiles();
+   Message += Item->Custom600Headers();
    Message += "\n\n";
    Message += "\n\n";
 
 
    if (RealFileExists(Item->Owner->DestFile))
    if (RealFileExists(Item->Owner->DestFile))
@@ -578,7 +628,7 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
       clog << " -> " << Access << ':' << QuoteString(Message,"\n") << endl;
       clog << " -> " << Access << ':' << QuoteString(Message,"\n") << endl;
    OutQueue += Message;
    OutQueue += Message;
    OutReady = true;
    OutReady = true;
-   
+
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -600,7 +650,7 @@ bool pkgAcquire::Worker::OutFdReady()
    OutQueue.erase(0,Res);
    OutQueue.erase(0,Res);
    if (OutQueue.empty() == true)
    if (OutQueue.empty() == true)
       OutReady = false;
       OutReady = false;
-   
+
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -622,7 +672,7 @@ bool pkgAcquire::Worker::InFdReady()
 bool pkgAcquire::Worker::MethodFailure()
 bool pkgAcquire::Worker::MethodFailure()
 {
 {
    _error->Error("Method %s has died unexpectedly!",Access.c_str());
    _error->Error("Method %s has died unexpectedly!",Access.c_str());
-   
+
    // do not reap the child here to show meaningfull error to the user
    // do not reap the child here to show meaningfull error to the user
    ExecWait(Process,Access.c_str(),false);
    ExecWait(Process,Access.c_str(),false);
    Process = -1;
    Process = -1;
@@ -634,26 +684,22 @@ bool pkgAcquire::Worker::MethodFailure()
    InReady = false;
    InReady = false;
    OutQueue = string();
    OutQueue = string();
    MessageQueue.erase(MessageQueue.begin(),MessageQueue.end());
    MessageQueue.erase(MessageQueue.begin(),MessageQueue.end());
-   
+
    return false;
    return false;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// Worker::Pulse - Called periodically 					/*{{{*/
+// Worker::Pulse - Called periodically					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
 void pkgAcquire::Worker::Pulse()
 void pkgAcquire::Worker::Pulse()
 {
 {
    if (CurrentItem == 0)
    if (CurrentItem == 0)
       return;
       return;
- 
+
    struct stat Buf;
    struct stat Buf;
    if (stat(CurrentItem->Owner->DestFile.c_str(),&Buf) != 0)
    if (stat(CurrentItem->Owner->DestFile.c_str(),&Buf) != 0)
       return;
       return;
    CurrentSize = Buf.st_size;
    CurrentSize = Buf.st_size;
-   
-   // Hmm? Should not happen...
-   if (CurrentSize > TotalSize && TotalSize != 0)
-      TotalSize = CurrentSize;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // Worker::ItemDone - Called when the current item is finished		/*{{{*/
 // Worker::ItemDone - Called when the current item is finished		/*{{{*/
@@ -667,3 +713,33 @@ void pkgAcquire::Worker::ItemDone()
    Status = string();
    Status = string();
 }
 }
 									/*}}}*/
 									/*}}}*/
+void pkgAcquire::Worker::PrepareFiles(char const * const caller, pkgAcquire::Queue::QItem const * const Itm)/*{{{*/
+{
+   if (RealFileExists(Itm->Owner->DestFile))
+   {
+      ChangeOwnerAndPermissionOfFile(caller, Itm->Owner->DestFile.c_str(), "root", "root", 0644);
+      std::string const filename = Itm->Owner->DestFile;
+      for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
+      {
+	 pkgAcquire::Item const * const Owner = *O;
+	 if (Owner->DestFile == filename)
+	    continue;
+	 unlink(Owner->DestFile.c_str());
+	 if (link(filename.c_str(), Owner->DestFile.c_str()) != 0)
+	 {
+	    // diferent mounts can't happen for us as we download to lists/ by default,
+	    // but if the system is reused by others the locations can potentially be on
+	    // different disks, so use symlink as poor-men replacement.
+	    // FIXME: Real copying as last fallback, but that is costly, so offload to a method preferable
+	    if (symlink(filename.c_str(), Owner->DestFile.c_str()) != 0)
+	       _error->Error("Can't create (sym)link of file %s to %s", filename.c_str(), Owner->DestFile.c_str());
+	 }
+      }
+   }
+   else
+   {
+      for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
+	 unlink((*O)->DestFile.c_str());
+   }
+}
+									/*}}}*/

+ 3 - 1
apt-pkg/acquire-worker.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: acquire-worker.h,v 1.12 2001/02/20 07:03:17 jgg Exp $
 /* ######################################################################
 /* ######################################################################
 
 
    Acquire Worker - Worker process manager
    Acquire Worker - Worker process manager
@@ -326,6 +325,9 @@ class pkgAcquire::Worker : public WeakPointable
     *  \b false, also rudely interrupts the worker with a SIGINT.
     *  \b false, also rudely interrupts the worker with a SIGINT.
     */
     */
    virtual ~Worker();
    virtual ~Worker();
+
+private:
+   APT_HIDDEN void PrepareFiles(char const * const caller, pkgAcquire::Queue::QItem const * const Itm);
 };
 };
 
 
 /** @} */
 /** @} */

+ 139 - 24
apt-pkg/acquire.cc

@@ -23,6 +23,7 @@
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
 
 
+#include <algorithm>
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
 #include <iostream>
 #include <iostream>
@@ -92,8 +93,11 @@ void pkgAcquire::Initialize()
 static bool SetupAPTPartialDirectory(std::string const &grand, std::string const &parent)
 static bool SetupAPTPartialDirectory(std::string const &grand, std::string const &parent)
 {
 {
    std::string const partial = parent + "partial";
    std::string const partial = parent + "partial";
-   if (CreateAPTDirectoryIfNeeded(grand, partial) == false &&
-	 CreateAPTDirectoryIfNeeded(parent, partial) == false)
+   mode_t const mode = umask(S_IWGRP | S_IWOTH);
+   bool const creation_fail = (CreateAPTDirectoryIfNeeded(grand, partial) == false &&
+	 CreateAPTDirectoryIfNeeded(parent, partial) == false);
+   umask(mode);
+   if (creation_fail == true)
       return false;
       return false;
 
 
    std::string const SandboxUser = _config->Find("APT::Sandbox::User");
    std::string const SandboxUser = _config->Find("APT::Sandbox::User");
@@ -152,6 +156,8 @@ bool pkgAcquire::GetLock(std::string const &Lock)
       return true;
       return true;
 
 
    // Lock the directory this acquire object will work in
    // Lock the directory this acquire object will work in
+   if (LockFD != -1)
+      close(LockFD);
    LockFD = ::GetLock(flCombine(Lock, "lock"));
    LockFD = ::GetLock(flCombine(Lock, "lock"));
    if (LockFD == -1)
    if (LockFD == -1)
       return _error->Error(_("Unable to lock directory %s"), Lock.c_str());
       return _error->Error(_("Unable to lock directory %s"), Lock.c_str());
@@ -674,10 +680,14 @@ bool pkgAcquire::Queue::Enqueue(ItemDesc &Item)
 {
 {
    QItem **I = &Items;
    QItem **I = &Items;
    // move to the end of the queue and check for duplicates here
    // move to the end of the queue and check for duplicates here
+   HashStringList const hsl = Item.Owner->GetExpectedHashes();
    for (; *I != 0; I = &(*I)->Next)
    for (; *I != 0; I = &(*I)->Next)
-      if (Item.URI == (*I)->URI) 
+      if (Item.URI == (*I)->URI || hsl == (*I)->Owner->GetExpectedHashes())
       {
       {
-	 Item.Owner->Status = Item::StatDone;
+	 if (_config->FindB("Debug::pkgAcquire::Worker",false) == true)
+	    std::cerr << " @ Queue: Action combined for " << Item.URI << " and " << (*I)->URI << std::endl;
+	 (*I)->Owners.push_back(Item.Owner);
+	 Item.Owner->Status = (*I)->Owner->Status;
 	 return false;
 	 return false;
       }
       }
 
 
@@ -700,13 +710,13 @@ bool pkgAcquire::Queue::Dequeue(Item *Owner)
 {
 {
    if (Owner->Status == pkgAcquire::Item::StatFetching)
    if (Owner->Status == pkgAcquire::Item::StatFetching)
       return _error->Error("Tried to dequeue a fetching object");
       return _error->Error("Tried to dequeue a fetching object");
-       
+
    bool Res = false;
    bool Res = false;
-   
+
    QItem **I = &Items;
    QItem **I = &Items;
    for (; *I != 0;)
    for (; *I != 0;)
    {
    {
-      if ((*I)->Owner == Owner)
+      if (Owner == (*I)->Owner)
       {
       {
 	 QItem *Jnk= *I;
 	 QItem *Jnk= *I;
 	 *I = (*I)->Next;
 	 *I = (*I)->Next;
@@ -717,7 +727,7 @@ bool pkgAcquire::Queue::Dequeue(Item *Owner)
       else
       else
 	 I = &(*I)->Next;
 	 I = &(*I)->Next;
    }
    }
-   
+
    return Res;
    return Res;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -794,9 +804,12 @@ pkgAcquire::Queue::QItem *pkgAcquire::Queue::FindItem(string URI,pkgAcquire::Wor
 bool pkgAcquire::Queue::ItemDone(QItem *Itm)
 bool pkgAcquire::Queue::ItemDone(QItem *Itm)
 {
 {
    PipeDepth--;
    PipeDepth--;
-   if (Itm->Owner->Status == pkgAcquire::Item::StatFetching)
-      Itm->Owner->Status = pkgAcquire::Item::StatDone;
-   
+   for (QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
+   {
+      if ((*O)->Status == pkgAcquire::Item::StatFetching)
+	 (*O)->Status = pkgAcquire::Item::StatDone;
+   }
+
    if (Itm->Owner->QueueCounter <= 1)
    if (Itm->Owner->QueueCounter <= 1)
       Owner->Dequeue(Itm->Owner);
       Owner->Dequeue(Itm->Owner);
    else
    else
@@ -804,7 +817,7 @@ bool pkgAcquire::Queue::ItemDone(QItem *Itm)
       Dequeue(Itm->Owner);
       Dequeue(Itm->Owner);
       Owner->Bump();
       Owner->Bump();
    }
    }
-   
+
    return Cycle();
    return Cycle();
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -819,7 +832,7 @@ bool pkgAcquire::Queue::Cycle()
 
 
    if (PipeDepth < 0)
    if (PipeDepth < 0)
       return _error->Error("Pipedepth failure");
       return _error->Error("Pipedepth failure");
-			   
+
    // Look for a queable item
    // Look for a queable item
    QItem *I = Items;
    QItem *I = Items;
    while (PipeDepth < (signed)MaxPipeDepth)
    while (PipeDepth < (signed)MaxPipeDepth)
@@ -827,18 +840,19 @@ bool pkgAcquire::Queue::Cycle()
       for (; I != 0; I = I->Next)
       for (; I != 0; I = I->Next)
 	 if (I->Owner->Status == pkgAcquire::Item::StatIdle)
 	 if (I->Owner->Status == pkgAcquire::Item::StatIdle)
 	    break;
 	    break;
-      
+
       // Nothing to do, queue is idle.
       // Nothing to do, queue is idle.
       if (I == 0)
       if (I == 0)
 	 return true;
 	 return true;
-      
+
       I->Worker = Workers;
       I->Worker = Workers;
-      I->Owner->Status = pkgAcquire::Item::StatFetching;
+      for (QItem::owner_iterator O = I->Owners.begin(); O != I->Owners.end(); ++O)
+	 (*O)->Status = pkgAcquire::Item::StatFetching;
       PipeDepth++;
       PipeDepth++;
       if (Workers->QueueItem(I) == false)
       if (Workers->QueueItem(I) == false)
 	 return false;
 	 return false;
    }
    }
-   
+
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -850,10 +864,98 @@ void pkgAcquire::Queue::Bump()
    Cycle();
    Cycle();
 }
 }
 									/*}}}*/
 									/*}}}*/
+HashStringList pkgAcquire::Queue::QItem::GetExpectedHashes() const	/*{{{*/
+{
+   /* each Item can have multiple owners and each owner might have different
+      hashes, even if that is unlikely in practice and if so at least some
+      owners will later fail. There is one situation through which is not a
+      failure and still needs this handling: Two owners who expect the same
+      file, but one owner only knows the SHA1 while the other only knows SHA256. */
+   HashStringList superhsl;
+   for (pkgAcquire::Queue::QItem::owner_iterator O = Owners.begin(); O != Owners.end(); ++O)
+   {
+      HashStringList const hsl = (*O)->GetExpectedHashes();
+      if (hsl.usable() == false)
+	 continue;
+      if (superhsl.usable() == false)
+	 superhsl = hsl;
+      else
+      {
+	 // we merge both lists - if we find disagreement send no hashes
+	 HashStringList::const_iterator hs = hsl.begin();
+	 for (; hs != hsl.end(); ++hs)
+	    if (superhsl.push_back(*hs) == false)
+	       break;
+	 if (hs != hsl.end())
+	 {
+	    superhsl.clear();
+	    break;
+	 }
+      }
+   }
+   return superhsl;
+}
+									/*}}}*/
+APT_PURE unsigned long long pkgAcquire::Queue::QItem::GetMaximumSize() const	/*{{{*/
+{
+   unsigned long long Maximum = std::numeric_limits<unsigned long long>::max();
+   for (pkgAcquire::Queue::QItem::owner_iterator O = Owners.begin(); O != Owners.end(); ++O)
+   {
+      if ((*O)->FileSize == 0)
+	 continue;
+      Maximum = std::min(Maximum, (*O)->FileSize);
+   }
+   if (Maximum == std::numeric_limits<unsigned long long>::max())
+      return 0;
+   return Maximum;
+}
+									/*}}}*/
+void pkgAcquire::Queue::QItem::SyncDestinationFiles() const		/*{{{*/
+{
+   /* ensure that the first owner has the best partial file of all and
+      the rest have (potentially dangling) symlinks to it so that
+      everything (like progress reporting) finds it easily */
+   std::string superfile = Owner->DestFile;
+   off_t supersize = 0;
+   for (pkgAcquire::Queue::QItem::owner_iterator O = Owners.begin(); O != Owners.end(); ++O)
+   {
+      if ((*O)->DestFile == superfile)
+	 continue;
+      struct stat file;
+      if (lstat((*O)->DestFile.c_str(),&file) == 0)
+      {
+	 if ((file.st_mode & S_IFREG) == 0)
+	    unlink((*O)->DestFile.c_str());
+	 else if (supersize < file.st_size)
+	 {
+	    supersize = file.st_size;
+	    unlink(superfile.c_str());
+	    rename((*O)->DestFile.c_str(), superfile.c_str());
+	 }
+	 else
+	    unlink((*O)->DestFile.c_str());
+	 if (symlink(superfile.c_str(), (*O)->DestFile.c_str()) != 0)
+	 {
+	    ; // not a problem per-se and no real alternative
+	 }
+      }
+   }
+}
+									/*}}}*/
+std::string pkgAcquire::Queue::QItem::Custom600Headers() const		/*{{{*/
+{
+   /* The others are relatively easy to merge, but this one?
+      Lets not merge and see how far we can run with it…
+      Likely, nobody will ever notice as all the items will
+      be of the same class and hence generate the same headers. */
+   return Owner->Custom600Headers();
+}
+									/*}}}*/
+
 // AcquireStatus::pkgAcquireStatus - Constructor			/*{{{*/
 // AcquireStatus::pkgAcquireStatus - Constructor			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-pkgAcquireStatus::pkgAcquireStatus() : d(NULL), Percent(0), Update(true), MorePulses(false)
+pkgAcquireStatus::pkgAcquireStatus() : d(NULL), Percent(-1), Update(true), MorePulses(false)
 {
 {
    Start();
    Start();
 }
 }
@@ -909,9 +1011,9 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
       {
       {
 	 CurrentBytes += I->CurrentSize;
 	 CurrentBytes += I->CurrentSize;
 	 ResumeSize += I->ResumePoint;
 	 ResumeSize += I->ResumePoint;
-	 
+
 	 // Files with unknown size always have 100% completion
 	 // Files with unknown size always have 100% completion
-	 if (I->CurrentItem->Owner->FileSize == 0 && 
+	 if (I->CurrentItem->Owner->FileSize == 0 &&
 	     I->CurrentItem->Owner->Complete == false)
 	     I->CurrentItem->Owner->Complete == false)
 	    TotalBytes += I->CurrentSize;
 	    TotalBytes += I->CurrentSize;
       }
       }
@@ -952,13 +1054,17 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
       Time = NewTime;
       Time = NewTime;
    }
    }
 
 
+   double const OldPercent = Percent;
    // calculate the percentage, if we have too little data assume 1%
    // calculate the percentage, if we have too little data assume 1%
    if (TotalBytes > 0 && UnfetchedReleaseFiles)
    if (TotalBytes > 0 && UnfetchedReleaseFiles)
       Percent = 0;
       Percent = 0;
-   else 
+   else
       // use both files and bytes because bytes can be unreliable
       // use both files and bytes because bytes can be unreliable
-      Percent = (0.8 * (CurrentBytes/float(TotalBytes)*100.0) + 
+      Percent = (0.8 * (CurrentBytes/float(TotalBytes)*100.0) +
                  0.2 * (CurrentItems/float(TotalItems)*100.0));
                  0.2 * (CurrentItems/float(TotalItems)*100.0));
+   double const DiffPercent = Percent - OldPercent;
+   if (DiffPercent < 0.001 && _config->FindB("Acquire::Progress::Diffpercent", false) == true)
+      return true;
 
 
    int fd = _config->FindI("APT::Status-Fd",-1);
    int fd = _config->FindI("APT::Status-Fd",-1);
    if(fd > 0) 
    if(fd > 0) 
@@ -976,11 +1082,11 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
 	 snprintf(msg,sizeof(msg), _("Retrieving file %li of %li (%s remaining)"), i, TotalItems, TimeToStr(ETA).c_str());
 	 snprintf(msg,sizeof(msg), _("Retrieving file %li of %li (%s remaining)"), i, TotalItems, TimeToStr(ETA).c_str());
       else
       else
 	 snprintf(msg,sizeof(msg), _("Retrieving file %li of %li"), i, TotalItems);
 	 snprintf(msg,sizeof(msg), _("Retrieving file %li of %li"), i, TotalItems);
-	 
+
       // build the status str
       // build the status str
       status << "dlstatus:" << i
       status << "dlstatus:" << i
              << ":"  << std::setprecision(3) << Percent
              << ":"  << std::setprecision(3) << Percent
-             << ":" << msg 
+             << ":" << msg
              << endl;
              << endl;
 
 
       std::string const dlstatus = status.str();
       std::string const dlstatus = status.str();
@@ -1037,6 +1143,15 @@ void pkgAcquireStatus::Fetched(unsigned long long Size,unsigned long long Resume
 }
 }
 									/*}}}*/
 									/*}}}*/
 
 
+pkgAcquire::UriIterator::UriIterator(pkgAcquire::Queue *Q) : d(NULL), CurQ(Q), CurItem(0)
+{
+   while (CurItem == 0 && CurQ != 0)
+   {
+      CurItem = CurQ->Items;
+      CurQ = CurQ->Next;
+   }
+}
+
 APT_CONST pkgAcquire::UriIterator::~UriIterator() {}
 APT_CONST pkgAcquire::UriIterator::~UriIterator() {}
 APT_CONST pkgAcquire::MethodConfig::~MethodConfig() {}
 APT_CONST pkgAcquire::MethodConfig::~MethodConfig() {}
 APT_CONST pkgAcquireStatus::~pkgAcquireStatus() {}
 APT_CONST pkgAcquireStatus::~pkgAcquireStatus() {}

+ 38 - 17
apt-pkg/acquire.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: acquire.h,v 1.29.2.1 2003/12/24 23:09:17 mdz Exp $
 /* ######################################################################
 /* ######################################################################
 
 
    Acquire - File Acquiration
    Acquire - File Acquiration
@@ -68,9 +67,10 @@
 
 
 #include <apt-pkg/macros.h>
 #include <apt-pkg/macros.h>
 #include <apt-pkg/weakptr.h>
 #include <apt-pkg/weakptr.h>
+#include <apt-pkg/hashes.h>
 
 
-#include <vector>
 #include <string>
 #include <string>
+#include <vector>
 
 
 #include <stddef.h>
 #include <stddef.h>
 #include <sys/time.h>
 #include <sys/time.h>
@@ -111,6 +111,7 @@ class pkgAcquire
    struct MethodConfig;
    struct MethodConfig;
    struct ItemDesc;
    struct ItemDesc;
    friend class Item;
    friend class Item;
+   friend class pkgAcqMetaBase;
    friend class Queue;
    friend class Queue;
 
 
    typedef std::vector<Item *>::iterator ItemIterator;
    typedef std::vector<Item *>::iterator ItemIterator;
@@ -389,13 +390,13 @@ class pkgAcquire
  */
  */
 struct pkgAcquire::ItemDesc : public WeakPointable
 struct pkgAcquire::ItemDesc : public WeakPointable
 {
 {
-   /** \brief The URI from which to download this item. */
+   /** \brief URI from which to download this item. */
    std::string URI;
    std::string URI;
-   /** brief A description of this item. */
+   /** \brief description of this item. */
    std::string Description;
    std::string Description;
-   /** brief A shorter description of this item. */
+   /** \brief shorter description of this item. */
    std::string ShortDesc;
    std::string ShortDesc;
-   /** brief The underlying item which is to be downloaded. */
+   /** \brief underlying item which is to be downloaded. */
    Item *Owner;
    Item *Owner;
 };
 };
 									/*}}}*/
 									/*}}}*/
@@ -418,13 +419,26 @@ class pkgAcquire::Queue
    protected:
    protected:
 
 
    /** \brief A single item placed in this queue. */
    /** \brief A single item placed in this queue. */
-   struct QItem : pkgAcquire::ItemDesc
+   struct QItem : public WeakPointable
    {
    {
       /** \brief The next item in the queue. */
       /** \brief The next item in the queue. */
       QItem *Next;
       QItem *Next;
       /** \brief The worker associated with this item, if any. */
       /** \brief The worker associated with this item, if any. */
       pkgAcquire::Worker *Worker;
       pkgAcquire::Worker *Worker;
 
 
+      /** \brief The URI from which to download this item. */
+      std::string URI;
+      /** \brief A description of this item. */
+      std::string Description;
+      /** \brief A shorter description of this item. */
+      std::string ShortDesc;
+      /** \brief The underlying items interested in the download */
+      std::vector<Item*> Owners;
+      // both, backward compatibility and easy access as syncing is interal
+      Item * Owner;
+
+      typedef std::vector<Item*>::const_iterator owner_iterator;
+
       /** \brief Assign the ItemDesc portion of this QItem from
       /** \brief Assign the ItemDesc portion of this QItem from
        *  another ItemDesc
        *  another ItemDesc
        */
        */
@@ -433,10 +447,24 @@ class pkgAcquire::Queue
 	 URI = I.URI;
 	 URI = I.URI;
 	 Description = I.Description;
 	 Description = I.Description;
 	 ShortDesc = I.ShortDesc;
 	 ShortDesc = I.ShortDesc;
+	 Owners.clear();
+	 Owners.push_back(I.Owner);
 	 Owner = I.Owner;
 	 Owner = I.Owner;
       };
       };
+
+      /** @return the sum of all expected hashes by all owners */
+      HashStringList GetExpectedHashes() const;
+
+      /** @return smallest maximum size of all owners */
+      unsigned long long GetMaximumSize() const;
+
+      /** \brief get partial files in order */
+      void SyncDestinationFiles() const;
+
+      /** @return the custom headers to use for this item */
+      std::string Custom600Headers() const;
    };
    };
-   
+
    /** \brief The name of this queue. */
    /** \brief The name of this queue. */
    std::string Name;
    std::string Name;
 
 
@@ -589,7 +617,7 @@ class pkgAcquire::UriIterator
       }
       }
    };
    };
    
    
-   inline pkgAcquire::ItemDesc const *operator ->() const {return CurItem;};
+   inline pkgAcquire::Queue::QItem const *operator ->() const {return CurItem;};
    inline bool operator !=(UriIterator const &rhs) const {return rhs.CurQ != CurQ || rhs.CurItem != CurItem;};
    inline bool operator !=(UriIterator const &rhs) const {return rhs.CurQ != CurQ || rhs.CurItem != CurItem;};
    inline bool operator ==(UriIterator const &rhs) const {return rhs.CurQ == CurQ && rhs.CurItem == CurItem;};
    inline bool operator ==(UriIterator const &rhs) const {return rhs.CurQ == CurQ && rhs.CurItem == CurItem;};
    
    
@@ -597,14 +625,7 @@ class pkgAcquire::UriIterator
     *
     *
     *  \param Q The queue over which this UriIterator should iterate.
     *  \param Q The queue over which this UriIterator should iterate.
     */
     */
-   UriIterator(pkgAcquire::Queue *Q) : d(NULL), CurQ(Q), CurItem(0)
-   {
-      while (CurItem == 0 && CurQ != 0)
-      {
-	 CurItem = CurQ->Items;
-	 CurQ = CurQ->Next;
-      }
-   }   
+   UriIterator(pkgAcquire::Queue *Q);
    virtual ~UriIterator();
    virtual ~UriIterator();
 };
 };
 									/*}}}*/
 									/*}}}*/

+ 13 - 1
apt-pkg/algorithms.cc

@@ -468,7 +468,7 @@ void pkgProblemResolver::MakeScores()
 	 if (D->Version != 0)
 	 if (D->Version != 0)
 	 {
 	 {
 	    pkgCache::VerIterator const IV = Cache[T].InstVerIter(Cache);
 	    pkgCache::VerIterator const IV = Cache[T].InstVerIter(Cache);
-	    if (IV.end() == true || D.IsSatisfied(IV) != D.IsNegative())
+	    if (IV.end() == true || D.IsSatisfied(IV) == false)
 	       continue;
 	       continue;
 	 }
 	 }
 	 Scores[T->ID] += DepMap[D->Type];
 	 Scores[T->ID] += DepMap[D->Type];
@@ -640,6 +640,12 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
 // ProblemResolver::Resolve - calls a resolver to fix the situation	/*{{{*/
 // ProblemResolver::Resolve - calls a resolver to fix the situation	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
+#if APT_PKG_ABI < 413
+bool pkgProblemResolver::Resolve(bool BrokenFix)
+{
+   return Resolve(BrokenFix, NULL);
+}
+#endif
 bool pkgProblemResolver::Resolve(bool BrokenFix, OpProgress * const Progress)
 bool pkgProblemResolver::Resolve(bool BrokenFix, OpProgress * const Progress)
 {
 {
    std::string const solver = _config->Find("APT::Solver", "internal");
    std::string const solver = _config->Find("APT::Solver", "internal");
@@ -1138,6 +1144,12 @@ bool pkgProblemResolver::InstOrNewPolicyBroken(pkgCache::PkgIterator I)
 /* 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. */
+#if APT_PKG_ABI < 413
+bool pkgProblemResolver::ResolveByKeep()
+{
+   return ResolveByKeep(NULL);
+}
+#endif
 bool pkgProblemResolver::ResolveByKeep(OpProgress * const Progress)
 bool pkgProblemResolver::ResolveByKeep(OpProgress * const Progress)
 {
 {
    std::string const solver = _config->Find("APT::Solver", "internal");
    std::string const solver = _config->Find("APT::Solver", "internal");

+ 13 - 3
apt-pkg/algorithms.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: algorithms.h,v 1.10 2001/05/22 04:17:41 jgg Exp $
 /* ######################################################################
 /* ######################################################################
 
 
    Algorithms - A set of misc algorithms
    Algorithms - A set of misc algorithms
@@ -55,6 +54,7 @@ using std::ostream;
 
 
 class pkgSimulate : public pkgPackageManager				/*{{{*/
 class pkgSimulate : public pkgPackageManager				/*{{{*/
 {
 {
+   void *d;
    protected:
    protected:
 
 
    class Policy : public pkgDepCache::Policy
    class Policy : public pkgDepCache::Policy
@@ -88,7 +88,7 @@ private:
    public:
    public:
 
 
    pkgSimulate(pkgDepCache *Cache);
    pkgSimulate(pkgDepCache *Cache);
-   ~pkgSimulate();
+   virtual ~pkgSimulate();
 };
 };
 									/*}}}*/
 									/*}}}*/
 class pkgProblemResolver						/*{{{*/
 class pkgProblemResolver						/*{{{*/
@@ -138,15 +138,25 @@ class pkgProblemResolver						/*{{{*/
    inline void Clear(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] &= ~(Protected | ToRemove);};
    inline void Clear(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] &= ~(Protected | ToRemove);};
 
 
    // Try to intelligently resolve problems by installing and removing packages
    // Try to intelligently resolve problems by installing and removing packages
+#if APT_PKG_ABI >= 413
    bool Resolve(bool BrokenFix = false, OpProgress * const Progress = NULL);
    bool Resolve(bool BrokenFix = false, OpProgress * const Progress = NULL);
+#else
+   bool Resolve(bool BrokenFix = false);
+   bool Resolve(bool BrokenFix, OpProgress * const Progress);
+#endif
 
 
    // Try to resolve problems only by using keep
    // Try to resolve problems only by using keep
+#if APT_PKG_ABI >= 413
    bool ResolveByKeep(OpProgress * const Progress = NULL);
    bool ResolveByKeep(OpProgress * const Progress = NULL);
+#else
+   bool ResolveByKeep();
+   bool ResolveByKeep(OpProgress * const Progress);
+#endif
 
 
    APT_DEPRECATED void InstallProtect();
    APT_DEPRECATED void InstallProtect();
 
 
    pkgProblemResolver(pkgDepCache *Cache);
    pkgProblemResolver(pkgDepCache *Cache);
-   ~pkgProblemResolver();
+   virtual ~pkgProblemResolver();
 };
 };
 									/*}}}*/
 									/*}}}*/
 bool pkgApplyStatus(pkgDepCache &Cache);
 bool pkgApplyStatus(pkgDepCache &Cache);

+ 10 - 11
apt-pkg/aptconfiguration.h

@@ -16,8 +16,7 @@
 #include <limits>
 #include <limits>
 									/*}}}*/
 									/*}}}*/
 namespace APT {
 namespace APT {
-class Configuration {							/*{{{*/
-public:									/*{{{*/
+namespace Configuration {							/*{{{*/
 	/** \brief Returns a vector of usable Compression Types
 	/** \brief Returns a vector of usable Compression Types
 	 *
 	 *
 	 *  Files can be compressed in various ways to decrease the size of the
 	 *  Files can be compressed in various ways to decrease the size of the
@@ -39,7 +38,7 @@ public:									/*{{{*/
 	 *
 	 *
 	 *  \return a vector of the compression types in the preferred usage order
 	 *  \return a vector of the compression types in the preferred usage order
 	 */
 	 */
-	std::vector<std::string> static const getCompressionTypes(bool const &Cached = true);
+	std::vector<std::string> const getCompressionTypes(bool const &Cached = true);
 
 
 	/** \brief Returns a vector of Language Codes
 	/** \brief Returns a vector of Language Codes
 	 *
 	 *
@@ -64,7 +63,7 @@ public:									/*{{{*/
 	 *
 	 *
 	 *  \return a vector of (all) Language Codes in the preferred usage order
 	 *  \return a vector of (all) Language Codes in the preferred usage order
 	 */
 	 */
-	std::vector<std::string> static const getLanguages(bool const &All = false,
+	std::vector<std::string> const getLanguages(bool const &All = false,
 			bool const &Cached = true, char const ** const Locale = 0);
 			bool const &Cached = true, char const ** const Locale = 0);
 
 
 	/** \brief Are we interested in the given Language?
 	/** \brief Are we interested in the given Language?
@@ -73,7 +72,7 @@ public:									/*{{{*/
 	 *  \param All defines if we check against all codes or only against used codes
 	 *  \param All defines if we check against all codes or only against used codes
 	 *  \return true if we are interested, false otherwise
 	 *  \return true if we are interested, false otherwise
 	 */
 	 */
-	bool static checkLanguage(std::string Lang, bool const All = false);
+	bool checkLanguage(std::string Lang, bool const All = false);
 
 
 	/** \brief Returns a vector of Architectures we support
 	/** \brief Returns a vector of Architectures we support
 	 *
 	 *
@@ -82,14 +81,14 @@ public:									/*{{{*/
 	 *
 	 *
 	 *  \return a vector of Architectures in preferred order
 	 *  \return a vector of Architectures in preferred order
 	 */
 	 */
-	std::vector<std::string> static const getArchitectures(bool const &Cached = true);
+	std::vector<std::string> const getArchitectures(bool const &Cached = true);
 
 
 	/** \brief Are we interested in the given Architecture?
 	/** \brief Are we interested in the given Architecture?
 	 *
 	 *
 	 *  \param Arch we want to check
 	 *  \param Arch we want to check
 	 *  \return true if we are interested, false otherwise
 	 *  \return true if we are interested, false otherwise
 	 */
 	 */
-	bool static checkArchitecture(std::string const &Arch);
+	bool checkArchitecture(std::string const &Arch);
 
 
 	/** \brief Representation of supported compressors */
 	/** \brief Representation of supported compressors */
 	struct Compressor {
 	struct Compressor {
@@ -113,15 +112,15 @@ public:									/*{{{*/
 	 *
 	 *
 	 *  \return a vector of Compressors
 	 *  \return a vector of Compressors
 	 */
 	 */
-	std::vector<Compressor> static const getCompressors(bool const Cached = true);
+	std::vector<Compressor> const getCompressors(bool const Cached = true);
 
 
 	/** \brief Return a vector of extensions supported for data.tar's */
 	/** \brief Return a vector of extensions supported for data.tar's */
-	std::vector<std::string> static const getCompressorExtensions();
+	std::vector<std::string> const getCompressorExtensions();
 
 
 	/** \return Return a vector of enabled build profile specifications */
 	/** \return Return a vector of enabled build profile specifications */
-	std::vector<std::string> static const getBuildProfiles();
+	std::vector<std::string> const getBuildProfiles();
 	/** \return Return a comma-separated list of enabled build profile specifications */
 	/** \return Return a comma-separated list of enabled build profile specifications */
-	std::string static const getBuildProfilesString();
+	std::string const getBuildProfilesString();
 									/*}}}*/
 									/*}}}*/
 };
 };
 									/*}}}*/
 									/*}}}*/

+ 0 - 1
apt-pkg/cachefile.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: cachefile.h,v 1.5 2002/04/27 04:28:04 jgg Exp $
 /* ######################################################################
 /* ######################################################################
    
    
    CacheFile - Simple wrapper class for opening, generating and whatnot
    CacheFile - Simple wrapper class for opening, generating and whatnot

+ 48 - 10
apt-pkg/cacheiterators.h

@@ -161,10 +161,12 @@ class pkgCache::PkgIterator: public Iterator<Package, PkgIterator> {
 	// Accessors
 	// Accessors
 	inline const char *Name() const { return Group().Name(); }
 	inline const char *Name() const { return Group().Name(); }
 	// Versions have sections - and packages can have different versions with different sections
 	// Versions have sections - and packages can have different versions with different sections
-	// so this interface is broken by design. It used to return the section of the "first parsed
-	// package stanza", but as this can potentially be anything it now returns the section of the
-	// newest version instead (if any). aka: Run as fast as you can to Version.Section().
-	APT_DEPRECATED const char *Section() const;
+	// so this interface is broken by design. Run as fast as you can to Version.Section().
+	APT_DEPRECATED inline const char *Section() const {
+	   APT_IGNORE_DEPRECATED_PUSH
+	   return S->Section == 0?0:Owner->StrP + S->Section;
+	   APT_IGNORE_DEPRECATED_POP
+	}
 	inline bool Purge() const {return S->CurrentState == pkgCache::State::Purge ||
 	inline bool Purge() const {return S->CurrentState == pkgCache::State::Purge ||
 		(S->CurrentVer == 0 && S->CurrentState == pkgCache::State::NotInstalled);}
 		(S->CurrentVer == 0 && S->CurrentState == pkgCache::State::NotInstalled);}
 	inline const char *Arch() const {return S->Arch == 0?0:Owner->StrP + S->Arch;}
 	inline const char *Arch() const {return S->Arch == 0?0:Owner->StrP + S->Arch;}
@@ -215,12 +217,14 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
 	// Accessors
 	// Accessors
 	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;}
+#if APT_PKG_ABI >= 413
 	/** \brief source package name this version comes from
 	/** \brief source package name this version comes from
 	   Always contains the name, even if it is the same as the binary name */
 	   Always contains the name, even if it is the same as the binary name */
 	inline const char *SourcePkgName() const {return Owner->StrP + S->SourcePkgName;}
 	inline const char *SourcePkgName() const {return Owner->StrP + S->SourcePkgName;}
 	/** \brief source version this version comes from
 	/** \brief source version this version comes from
 	   Always contains the version string, even if it is the same as the binary version */
 	   Always contains the version string, even if it is the same as the binary version */
 	inline const char *SourceVerStr() const {return Owner->StrP + S->SourceVerStr;}
 	inline const char *SourceVerStr() const {return Owner->StrP + S->SourceVerStr;}
+#endif
 	inline const char *Arch() const {
 	inline const char *Arch() const {
 		if ((S->MultiArch & pkgCache::Version::All) == pkgCache::Version::All)
 		if ((S->MultiArch & pkgCache::Version::All) == pkgCache::Version::All)
 			return "all";
 			return "all";
@@ -363,27 +367,61 @@ class pkgCache::PrvIterator : public Iterator<Provides, PrvIterator> {
 	}
 	}
 };
 };
 									/*}}}*/
 									/*}}}*/
-// Package file								/*{{{*/
-class pkgCache::PkgFileIterator : public Iterator<PackageFile, PkgFileIterator> {
+// Release file								/*{{{*/
+class pkgCache::RlsFileIterator : public Iterator<ReleaseFile, RlsFileIterator> {
 	protected:
 	protected:
-	inline PackageFile* OwnerPointer() const {
-		return (Owner != 0) ? Owner->PkgFileP : 0;
+	inline ReleaseFile* OwnerPointer() const {
+		return (Owner != 0) ? Owner->RlsFileP : 0;
 	}
 	}
 
 
 	public:
 	public:
 	// Iteration
 	// Iteration
-	void operator ++(int) {if (S != Owner->PkgFileP) S = Owner->PkgFileP + S->NextFile;}
+	void operator ++(int) {if (S != Owner->RlsFileP) S = Owner->RlsFileP + S->NextFile;}
 	inline void operator ++() {operator ++(0);}
 	inline void operator ++() {operator ++(0);}
 
 
 	// Accessors
 	// Accessors
 	inline const char *FileName() const {return S->FileName == 0?0:Owner->StrP + S->FileName;}
 	inline const char *FileName() const {return S->FileName == 0?0:Owner->StrP + S->FileName;}
 	inline const char *Archive() const {return S->Archive == 0?0:Owner->StrP + S->Archive;}
 	inline const char *Archive() const {return S->Archive == 0?0:Owner->StrP + S->Archive;}
-	inline const char *Component() const {return S->Component == 0?0:Owner->StrP + S->Component;}
 	inline const char *Version() const {return S->Version == 0?0:Owner->StrP + S->Version;}
 	inline const char *Version() const {return S->Version == 0?0:Owner->StrP + S->Version;}
 	inline const char *Origin() const {return S->Origin == 0?0:Owner->StrP + S->Origin;}
 	inline const char *Origin() const {return S->Origin == 0?0:Owner->StrP + S->Origin;}
 	inline const char *Codename() const {return S->Codename ==0?0:Owner->StrP + S->Codename;}
 	inline const char *Codename() const {return S->Codename ==0?0:Owner->StrP + S->Codename;}
 	inline const char *Label() const {return S->Label == 0?0:Owner->StrP + S->Label;}
 	inline const char *Label() const {return S->Label == 0?0:Owner->StrP + S->Label;}
 	inline const char *Site() const {return S->Site == 0?0:Owner->StrP + S->Site;}
 	inline const char *Site() const {return S->Site == 0?0:Owner->StrP + S->Site;}
+	inline bool Flagged(pkgCache::Flag::ReleaseFileFlags const flag) const {return (S->Flags & flag) == flag; }
+
+	bool IsOk();
+	std::string RelStr();
+
+	// Constructors
+	inline RlsFileIterator() : Iterator<ReleaseFile, RlsFileIterator>() {}
+	inline RlsFileIterator(pkgCache &Owner) : Iterator<ReleaseFile, RlsFileIterator>(Owner, Owner.RlsFileP) {}
+	inline RlsFileIterator(pkgCache &Owner,ReleaseFile *Trg) : Iterator<ReleaseFile, RlsFileIterator>(Owner, Trg) {}
+};
+									/*}}}*/
+// Package file								/*{{{*/
+class pkgCache::PkgFileIterator : public Iterator<PackageFile, PkgFileIterator> {
+	protected:
+	inline PackageFile* OwnerPointer() const {
+		return (Owner != 0) ? Owner->PkgFileP : 0;
+	}
+
+	public:
+	// Iteration
+	void operator ++(int) {if (S != Owner->PkgFileP) S = Owner->PkgFileP + S->NextFile;}
+	inline void operator ++() {operator ++(0);}
+
+	// Accessors
+	inline const char *FileName() const {return S->FileName == 0?0:Owner->StrP + S->FileName;}
+	inline pkgCache::RlsFileIterator ReleaseFile() const {return RlsFileIterator(*Owner, Owner->RlsFileP + S->Release);}
+	inline const char *Archive() const {return S->Release == 0 ? Component() : ReleaseFile().Archive();}
+	inline const char *Version() const {return S->Release == 0 ? NULL : ReleaseFile().Version();}
+	inline const char *Origin() const {return S->Release == 0 ? NULL : ReleaseFile().Origin();}
+	inline const char *Codename() const {return S->Release == 0 ? NULL : ReleaseFile().Codename();}
+	inline const char *Label() const {return S->Release == 0 ? NULL : ReleaseFile().Label();}
+	inline const char *Site() const {return S->Release == 0 ? NULL : ReleaseFile().Site();}
+	inline bool Flagged(pkgCache::Flag::ReleaseFileFlags const flag) const {return S->Release== 0 ? false : ReleaseFile().Flagged(flag);}
+	inline bool Flagged(pkgCache::Flag::PkgFFlags const flag) const {return (S->Flags & flag) == flag;}
+	inline const char *Component() const {return S->Component == 0?0:Owner->StrP + S->Component;}
 	inline const char *Architecture() const {return S->Architecture == 0?0:Owner->StrP + S->Architecture;}
 	inline const char *Architecture() const {return S->Architecture == 0?0:Owner->StrP + S->Architecture;}
 	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;}
 
 

+ 26 - 39
apt-pkg/cacheset.cc

@@ -37,7 +37,6 @@
 #include <apti18n.h>
 #include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 namespace APT {
 namespace APT {
-
 // PackageFrom - selecting the appropriate method for package selection	/*{{{*/
 // PackageFrom - selecting the appropriate method for package selection	/*{{{*/
 bool CacheSetHelper::PackageFrom(enum PkgSelector const select, PackageContainerInterface * const pci,
 bool CacheSetHelper::PackageFrom(enum PkgSelector const select, PackageContainerInterface * const pci,
       pkgCacheFile &Cache, std::string const &pattern) {
       pkgCacheFile &Cache, std::string const &pattern) {
@@ -613,19 +612,14 @@ void CacheSetHelper::canNotFindPackage(enum PkgSelector const select,
       PackageContainerInterface * const pci, pkgCacheFile &Cache,
       PackageContainerInterface * const pci, pkgCacheFile &Cache,
       std::string const &pattern) {
       std::string const &pattern) {
 	switch (select) {
 	switch (select) {
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	case REGEX: canNotFindRegEx(pci, Cache, pattern); break;
 	case REGEX: canNotFindRegEx(pci, Cache, pattern); break;
 	case TASK: canNotFindTask(pci, Cache, pattern); break;
 	case TASK: canNotFindTask(pci, Cache, pattern); break;
 	case FNMATCH: canNotFindFnmatch(pci, Cache, pattern); break;
 	case FNMATCH: canNotFindFnmatch(pci, Cache, pattern); break;
 	case PACKAGENAME: canNotFindPackage(pci, Cache, pattern); break;
 	case PACKAGENAME: canNotFindPackage(pci, Cache, pattern); break;
 	case STRING: canNotFindPackage(pci, Cache, pattern); break;
 	case STRING: canNotFindPackage(pci, Cache, pattern); break;
 	case UNKNOWN: break;
 	case UNKNOWN: break;
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 	}
 	}
 }
 }
 // canNotFindTask - handle the case no package is found for a task	/*{{{*/
 // canNotFindTask - handle the case no package is found for a task	/*{{{*/
@@ -663,19 +657,14 @@ pkgCache::PkgIterator CacheSetHelper::canNotFindPkgName(pkgCacheFile &Cache,
 void CacheSetHelper::canNotFindVersion(enum VerSelector const select, VersionContainerInterface * const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg)
 void CacheSetHelper::canNotFindVersion(enum VerSelector const select, VersionContainerInterface * const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg)
 {
 {
 	switch (select) {
 	switch (select) {
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	case ALL: canNotFindAllVer(vci, Cache, Pkg); break;
 	case ALL: canNotFindAllVer(vci, Cache, Pkg); break;
 	case INSTCAND: canNotFindInstCandVer(vci, Cache, Pkg); break;
 	case INSTCAND: canNotFindInstCandVer(vci, Cache, Pkg); break;
 	case CANDINST: canNotFindCandInstVer(vci, Cache, Pkg); break;
 	case CANDINST: canNotFindCandInstVer(vci, Cache, Pkg); break;
 	case NEWEST: canNotFindNewestVer(Cache, Pkg); break;
 	case NEWEST: canNotFindNewestVer(Cache, Pkg); break;
 	case CANDIDATE: canNotFindCandidateVer(Cache, Pkg); break;
 	case CANDIDATE: canNotFindCandidateVer(Cache, Pkg); break;
 	case INSTALLED: canNotFindInstalledVer(Cache, Pkg); break;
 	case INSTALLED: canNotFindInstalledVer(Cache, Pkg); break;
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 	case CANDANDINST: canNotGetCandInstVer(Cache, Pkg); break;
 	case CANDANDINST: canNotGetCandInstVer(Cache, Pkg); break;
 	case RELEASE:
 	case RELEASE:
 	case VERSIONNUMBER:
 	case VERSIONNUMBER:
@@ -706,16 +695,11 @@ void CacheSetHelper::canNotFindCandInstVer(VersionContainerInterface * const /*v
 // canNotGetVersion - for package by selector				/*{{{*/
 // canNotGetVersion - for package by selector				/*{{{*/
 pkgCache::VerIterator CacheSetHelper::canNotGetVersion(enum VerSelector const select, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
 pkgCache::VerIterator CacheSetHelper::canNotGetVersion(enum VerSelector const select, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
 	switch (select) {
 	switch (select) {
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	case NEWEST: return canNotFindNewestVer(Cache, Pkg);
 	case NEWEST: return canNotFindNewestVer(Cache, Pkg);
 	case CANDIDATE: return canNotFindCandidateVer(Cache, Pkg);
 	case CANDIDATE: return canNotFindCandidateVer(Cache, Pkg);
 	case INSTALLED: return canNotFindInstalledVer(Cache, Pkg);
 	case INSTALLED: return canNotFindInstalledVer(Cache, Pkg);
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 	case CANDINST: return canNotGetCandInstVer(Cache, Pkg);
 	case CANDINST: return canNotGetCandInstVer(Cache, Pkg);
 	case INSTCAND: return canNotGetInstCandVer(Cache, Pkg);
 	case INSTCAND: return canNotGetInstCandVer(Cache, Pkg);
 	case ALL:
 	case ALL:
@@ -769,19 +753,14 @@ pkgCache::VerIterator CacheSetHelper::canNotGetCandInstVer(pkgCacheFile &Cache,
 									/*}}}*/
 									/*}}}*/
 									/*}}}*/
 									/*}}}*/
 // showPackageSelection - by selector and given pattern			/*{{{*/
 // showPackageSelection - by selector and given pattern			/*{{{*/
-APT_CONST void CacheSetHelper::showPackageSelection(pkgCache::PkgIterator const &pkg, enum PkgSelector const select,
+void CacheSetHelper::showPackageSelection(pkgCache::PkgIterator const &pkg, enum PkgSelector const select,
 				       std::string const &pattern) {
 				       std::string const &pattern) {
 	switch (select) {
 	switch (select) {
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	case REGEX: showRegExSelection(pkg, pattern); break;
 	case REGEX: showRegExSelection(pkg, pattern); break;
 	case TASK: showTaskSelection(pkg, pattern); break;
 	case TASK: showTaskSelection(pkg, pattern); break;
 	case FNMATCH: showFnmatchSelection(pkg, pattern); break;
 	case FNMATCH: showFnmatchSelection(pkg, pattern); break;
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 	case PACKAGENAME: /* no suprises here */ break;
 	case PACKAGENAME: /* no suprises here */ break;
 	case STRING: /* handled by the special cases */ break;
 	case STRING: /* handled by the special cases */ break;
 	case UNKNOWN: break;
 	case UNKNOWN: break;
@@ -804,23 +783,17 @@ APT_CONST void CacheSetHelper::showFnmatchSelection(pkgCache::PkgIterator const
 									/*}}}*/
 									/*}}}*/
 									/*}}}*/
 									/*}}}*/
 // showVersionSelection							/*{{{*/
 // showVersionSelection							/*{{{*/
-APT_CONST void CacheSetHelper::showVersionSelection(pkgCache::PkgIterator const &Pkg,
+void CacheSetHelper::showVersionSelection(pkgCache::PkgIterator const &Pkg,
       pkgCache::VerIterator const &Ver, enum VerSelector const select, std::string const &pattern) {
       pkgCache::VerIterator const &Ver, enum VerSelector const select, std::string const &pattern) {
 	switch (select) {
 	switch (select) {
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	case RELEASE:
 	case RELEASE:
 		showSelectedVersion(Pkg, Ver, pattern, true);
 		showSelectedVersion(Pkg, Ver, pattern, true);
 		break;
 		break;
 	case VERSIONNUMBER:
 	case VERSIONNUMBER:
 		showSelectedVersion(Pkg, Ver, pattern, false);
 		showSelectedVersion(Pkg, Ver, pattern, false);
 		break;
 		break;
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_POP
 	case NEWEST:
 	case NEWEST:
 	case CANDIDATE:
 	case CANDIDATE:
 	case INSTALLED:
 	case INSTALLED:
@@ -838,4 +811,18 @@ APT_CONST void CacheSetHelper::showSelectedVersion(pkgCache::PkgIterator const &
 					 bool const /*verIsRel*/) {
 					 bool const /*verIsRel*/) {
 }
 }
 									/*}}}*/
 									/*}}}*/
+
+CacheSetHelper::CacheSetHelper(bool const ShowError, GlobalError::MsgType ErrorType) :
+   ShowError(ShowError), ErrorType(ErrorType) {}
+CacheSetHelper::~CacheSetHelper() {}
+
+PackageContainerInterface::PackageContainerInterface() : ConstructedBy(CacheSetHelper::UNKNOWN) {}
+PackageContainerInterface::PackageContainerInterface(CacheSetHelper::PkgSelector const by) : ConstructedBy(by) {}
+PackageContainerInterface::~PackageContainerInterface() {}
+
+PackageUniverse::PackageUniverse(pkgCache * const Owner) : _cont(Owner) { }
+PackageUniverse::~PackageUniverse() {}
+
+VersionContainerInterface::VersionContainerInterface() {}
+VersionContainerInterface::~VersionContainerInterface() {}
 }
 }

+ 45 - 99
apt-pkg/cacheset.h

@@ -23,6 +23,7 @@
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/cacheiterators.h>
+#include <apt-pkg/macros.h>
 
 
 #ifndef APT_8_CLEANER_HEADERS
 #ifndef APT_8_CLEANER_HEADERS
 #include <apt-pkg/cachefile.h>
 #include <apt-pkg/cachefile.h>
@@ -49,9 +50,8 @@ class CacheSetHelper {							/*{{{*/
 */
 */
 public:									/*{{{*/
 public:									/*{{{*/
 	CacheSetHelper(bool const ShowError = true,
 	CacheSetHelper(bool const ShowError = true,
-		GlobalError::MsgType ErrorType = GlobalError::ERROR) :
-			ShowError(ShowError), ErrorType(ErrorType) {}
-	virtual ~CacheSetHelper() {}
+		GlobalError::MsgType ErrorType = GlobalError::ERROR);
+	virtual ~CacheSetHelper();
 
 
 	enum PkgSelector { UNKNOWN, REGEX, TASK, FNMATCH, PACKAGENAME, STRING };
 	enum PkgSelector { UNKNOWN, REGEX, TASK, FNMATCH, PACKAGENAME, STRING };
 
 
@@ -202,6 +202,8 @@ protected:
 	bool PackageFromFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
 	bool PackageFromFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
 	bool PackageFromPackageName(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
 	bool PackageFromPackageName(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
 	bool PackageFromString(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &pattern);
 	bool PackageFromString(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &pattern);
+private:
+	void *d;
 };									/*}}}*/
 };									/*}}}*/
 
 
 class PackageContainerInterface {					/*{{{*/
 class PackageContainerInterface {					/*{{{*/
@@ -224,14 +226,9 @@ public:
 		inline std::string FullName(bool const Pretty) const { return getPkg().FullName(Pretty); }
 		inline std::string FullName(bool const Pretty) const { return getPkg().FullName(Pretty); }
 		inline std::string FullName() const { return getPkg().FullName(); }
 		inline std::string FullName() const { return getPkg().FullName(); }
 		APT_DEPRECATED inline const char *Section() const {
 		APT_DEPRECATED inline const char *Section() const {
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
-	   return getPkg().Section();
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+		   APT_IGNORE_DEPRECATED_PUSH
+		      return getPkg().Section();
+		   APT_IGNORE_DEPRECATED_POP
 		}
 		}
 		inline bool Purge() const {return getPkg().Purge(); }
 		inline bool Purge() const {return getPkg().Purge(); }
 		inline const char *Arch() const {return getPkg().Arch(); }
 		inline const char *Arch() const {return getPkg().Arch(); }
@@ -261,19 +258,15 @@ public:
 		REGEX = CacheSetHelper::REGEX,
 		REGEX = CacheSetHelper::REGEX,
 		TASK = CacheSetHelper::TASK,
 		TASK = CacheSetHelper::TASK,
 		FNMATCH = CacheSetHelper::FNMATCH };
 		FNMATCH = CacheSetHelper::FNMATCH };
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	void setConstructor(Constructor const by) { ConstructedBy = (CacheSetHelper::PkgSelector)by; }
 	void setConstructor(Constructor const by) { ConstructedBy = (CacheSetHelper::PkgSelector)by; }
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 
 
 	void setConstructor(CacheSetHelper::PkgSelector const by) { ConstructedBy = by; }
 	void setConstructor(CacheSetHelper::PkgSelector const by) { ConstructedBy = by; }
 	CacheSetHelper::PkgSelector getConstructor() const { return ConstructedBy; }
 	CacheSetHelper::PkgSelector getConstructor() const { return ConstructedBy; }
-	PackageContainerInterface() : ConstructedBy(CacheSetHelper::UNKNOWN) {}
-	PackageContainerInterface(CacheSetHelper::PkgSelector const by) : ConstructedBy(by) {}
+	PackageContainerInterface();
+	PackageContainerInterface(CacheSetHelper::PkgSelector const by);
+	virtual ~PackageContainerInterface();
 
 
 	APT_DEPRECATED static bool FromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
 	APT_DEPRECATED static bool FromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
 	   return helper.PackageFrom(CacheSetHelper::TASK, pci, Cache, pattern); }
 	   return helper.PackageFrom(CacheSetHelper::TASK, pci, Cache, pattern); }
@@ -290,22 +283,18 @@ public:
 
 
 	APT_DEPRECATED typedef CacheSetHelper::PkgModifier Modifier;
 	APT_DEPRECATED typedef CacheSetHelper::PkgModifier Modifier;
 
 
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	APT_DEPRECATED static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
 	APT_DEPRECATED static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
 	   return helper.PackageFromName(Cache, pattern); }
 	   return helper.PackageFromName(Cache, pattern); }
 	APT_DEPRECATED static bool FromModifierCommandLine(unsigned short &modID, PackageContainerInterface * const pci,
 	APT_DEPRECATED static bool FromModifierCommandLine(unsigned short &modID, PackageContainerInterface * const pci,
 	      pkgCacheFile &Cache, const char * cmdline,
 	      pkgCacheFile &Cache, const char * cmdline,
 	      std::list<Modifier> const &mods, CacheSetHelper &helper) {
 	      std::list<Modifier> const &mods, CacheSetHelper &helper) {
 	   return helper.PackageFromModifierCommandLine(modID, pci, Cache, cmdline, mods); }
 	   return helper.PackageFromModifierCommandLine(modID, pci, Cache, cmdline, mods); }
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 
 
 private:
 private:
 	CacheSetHelper::PkgSelector ConstructedBy;
 	CacheSetHelper::PkgSelector ConstructedBy;
+	void *d;
 };
 };
 									/*}}}*/
 									/*}}}*/
 template<class Container> class PackageContainer : public PackageContainerInterface {/*{{{*/
 template<class Container> class PackageContainer : public PackageContainerInterface {/*{{{*/
@@ -369,16 +358,11 @@ public:									/*{{{*/
 	iterator end() { return iterator(_cont.end()); }
 	iterator end() { return iterator(_cont.end()); }
 	const_iterator find(pkgCache::PkgIterator const &P) const { return const_iterator(_cont.find(P)); }
 	const_iterator find(pkgCache::PkgIterator const &P) const { return const_iterator(_cont.find(P)); }
 
 
-	PackageContainer() : PackageContainerInterface() {}
+	PackageContainer() : PackageContainerInterface(CacheSetHelper::UNKNOWN) {}
 	PackageContainer(CacheSetHelper::PkgSelector const &by) : PackageContainerInterface(by) {}
 	PackageContainer(CacheSetHelper::PkgSelector const &by) : PackageContainerInterface(by) {}
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	APT_DEPRECATED PackageContainer(Constructor const &by) : PackageContainerInterface((CacheSetHelper::PkgSelector)by) {}
 	APT_DEPRECATED PackageContainer(Constructor const &by) : PackageContainerInterface((CacheSetHelper::PkgSelector)by) {}
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 
 
 	/** \brief sort all included versions with given comparer
 	/** \brief sort all included versions with given comparer
 
 
@@ -439,10 +423,7 @@ public:									/*{{{*/
 		return FromFnmatch(Cache, pattern, helper);
 		return FromFnmatch(Cache, pattern, helper);
 	}
 	}
 
 
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	/** \brief returns a package specified by a string
 	/** \brief returns a package specified by a string
 
 
 	    \param Cache the package is in
 	    \param Cache the package is in
@@ -455,9 +436,7 @@ public:									/*{{{*/
 		CacheSetHelper helper;
 		CacheSetHelper helper;
 		return FromName(Cache, pattern, helper);
 		return FromName(Cache, pattern, helper);
 	}
 	}
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 
 
 	/** \brief returns all packages specified by a string
 	/** \brief returns all packages specified by a string
 
 
@@ -576,6 +555,7 @@ template<> template<class Compare> inline bool PackageContainer<std::vector<pkgC
     private methods. */
     private methods. */
 class APT_HIDDEN PackageUniverse : public PackageContainerInterface {
 class APT_HIDDEN PackageUniverse : public PackageContainerInterface {
 	pkgCache * const _cont;
 	pkgCache * const _cont;
+	void *d;
 public:
 public:
 	typedef pkgCache::PkgIterator iterator;
 	typedef pkgCache::PkgIterator iterator;
 	typedef pkgCache::PkgIterator const_iterator;
 	typedef pkgCache::PkgIterator const_iterator;
@@ -588,7 +568,8 @@ public:
 	APT_PUBLIC iterator begin() { return _cont->PkgBegin(); }
 	APT_PUBLIC iterator begin() { return _cont->PkgBegin(); }
 	APT_PUBLIC iterator end() { return _cont->PkgEnd(); }
 	APT_PUBLIC iterator end() { return _cont->PkgEnd(); }
 
 
-	APT_PUBLIC PackageUniverse(pkgCache * const Owner) : _cont(Owner) { }
+	APT_PUBLIC PackageUniverse(pkgCache * const Owner);
+	APT_PUBLIC virtual ~PackageUniverse();
 
 
 private:
 private:
 	bool insert(pkgCache::PkgIterator const &) { return true; }
 	bool insert(pkgCache::PkgIterator const &) { return true; }
@@ -663,65 +644,45 @@ public:
 		Modifier (unsigned short const &id, const char * const alias, Position const &pos,
 		Modifier (unsigned short const &id, const char * const alias, Position const &pos,
 			  enum CacheSetHelper::VerSelector const select) : ID(id), Alias(alias), Pos(pos),
 			  enum CacheSetHelper::VerSelector const select) : ID(id), Alias(alias), Pos(pos),
 			 SelectVersion(select) {}
 			 SelectVersion(select) {}
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 		APT_DEPRECATED Modifier(unsigned short const &id, const char * const alias, Position const &pos,
 		APT_DEPRECATED Modifier(unsigned short const &id, const char * const alias, Position const &pos,
 			  Version const &select) : ID(id), Alias(alias), Pos(pos),
 			  Version const &select) : ID(id), Alias(alias), Pos(pos),
 			 SelectVersion((CacheSetHelper::VerSelector)select) {}
 			 SelectVersion((CacheSetHelper::VerSelector)select) {}
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 	};
 	};
 
 
 	static bool FromCommandLine(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 	static bool FromCommandLine(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 				    const char **cmdline, CacheSetHelper::VerSelector const fallback,
 				    const char **cmdline, CacheSetHelper::VerSelector const fallback,
 				    CacheSetHelper &helper);
 				    CacheSetHelper &helper);
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	APT_DEPRECATED static bool FromCommandLine(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 	APT_DEPRECATED static bool FromCommandLine(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 				    const char **cmdline, Version const &fallback,
 				    const char **cmdline, Version const &fallback,
 				    CacheSetHelper &helper) {
 				    CacheSetHelper &helper) {
 	   return FromCommandLine(vci, Cache, cmdline, (CacheSetHelper::VerSelector)fallback, helper);
 	   return FromCommandLine(vci, Cache, cmdline, (CacheSetHelper::VerSelector)fallback, helper);
 	}
 	}
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 
 
 	static bool FromString(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 	static bool FromString(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 			       std::string pkg, CacheSetHelper::VerSelector const fallback, CacheSetHelper &helper,
 			       std::string pkg, CacheSetHelper::VerSelector const fallback, CacheSetHelper &helper,
 			       bool const onlyFromName = false);
 			       bool const onlyFromName = false);
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	APT_DEPRECATED static bool FromString(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 	APT_DEPRECATED static bool FromString(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 			       std::string pkg, Version const &fallback, CacheSetHelper &helper,
 			       std::string pkg, Version const &fallback, CacheSetHelper &helper,
 			       bool const onlyFromName = false) {
 			       bool const onlyFromName = false) {
 	   return FromString(vci, Cache, pkg, (CacheSetHelper::VerSelector)fallback, helper, onlyFromName);
 	   return FromString(vci, Cache, pkg, (CacheSetHelper::VerSelector)fallback, helper, onlyFromName);
 	}
 	}
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 
 
 	static bool FromPackage(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 	static bool FromPackage(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 				pkgCache::PkgIterator const &P, CacheSetHelper::VerSelector const fallback,
 				pkgCache::PkgIterator const &P, CacheSetHelper::VerSelector const fallback,
 				CacheSetHelper &helper);
 				CacheSetHelper &helper);
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	APT_DEPRECATED static bool FromPackage(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 	APT_DEPRECATED static bool FromPackage(VersionContainerInterface * const vci, pkgCacheFile &Cache,
 				pkgCache::PkgIterator const &P, Version const &fallback,
 				pkgCache::PkgIterator const &P, Version const &fallback,
 				CacheSetHelper &helper) {
 				CacheSetHelper &helper) {
 	   return FromPackage(vci, Cache, P, (CacheSetHelper::VerSelector)fallback, helper);
 	   return FromPackage(vci, Cache, P, (CacheSetHelper::VerSelector)fallback, helper);
 	}
 	}
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 
 
 	static bool FromModifierCommandLine(unsigned short &modID,
 	static bool FromModifierCommandLine(unsigned short &modID,
 					    VersionContainerInterface * const vci,
 					    VersionContainerInterface * const vci,
@@ -735,10 +696,7 @@ public:
 				   pkgCache::DepIterator const &D,
 				   pkgCache::DepIterator const &D,
 				   CacheSetHelper::VerSelector const selector,
 				   CacheSetHelper::VerSelector const selector,
 				   CacheSetHelper &helper);
 				   CacheSetHelper &helper);
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	APT_DEPRECATED static bool FromDependency(VersionContainerInterface * const vci,
 	APT_DEPRECATED static bool FromDependency(VersionContainerInterface * const vci,
 				   pkgCacheFile &Cache,
 				   pkgCacheFile &Cache,
 				   pkgCache::DepIterator const &D,
 				   pkgCache::DepIterator const &D,
@@ -746,9 +704,12 @@ public:
 				   CacheSetHelper &helper) {
 				   CacheSetHelper &helper) {
 	   return FromDependency(vci, Cache, D, (CacheSetHelper::VerSelector)selector, helper);
 	   return FromDependency(vci, Cache, D, (CacheSetHelper::VerSelector)selector, helper);
 	}
 	}
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
+
+	VersionContainerInterface();
+	virtual ~VersionContainerInterface();
+private:
+	void *d;
 
 
 protected:								/*{{{*/
 protected:								/*{{{*/
 
 
@@ -879,10 +840,7 @@ public:									/*{{{*/
 	static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg) {
 	static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg) {
 		return FromString(Cache, pkg, CacheSetHelper::CANDINST);
 		return FromString(Cache, pkg, CacheSetHelper::CANDINST);
 	}
 	}
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
 	static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
 			Version const &fallback, CacheSetHelper &helper) {
 			Version const &fallback, CacheSetHelper &helper) {
 		VersionContainer vercon;
 		VersionContainer vercon;
@@ -906,9 +864,7 @@ public:									/*{{{*/
 		CacheSetHelper helper;
 		CacheSetHelper helper;
 		return FromString(Cache, pkg, (CacheSetHelper::VerSelector)fallback, helper);
 		return FromString(Cache, pkg, (CacheSetHelper::VerSelector)fallback, helper);
 	}
 	}
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 
 
 	/** \brief returns all versions specified for the package
 	/** \brief returns all versions specified for the package
 
 
@@ -927,10 +883,7 @@ public:									/*{{{*/
 		CacheSetHelper helper;
 		CacheSetHelper helper;
 		return FromPackage(Cache, P, fallback, helper);
 		return FromPackage(Cache, P, fallback, helper);
 	}
 	}
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
 	static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
 		Version const &fallback, CacheSetHelper &helper) {
 		Version const &fallback, CacheSetHelper &helper) {
 		VersionContainer vercon;
 		VersionContainer vercon;
@@ -942,9 +895,7 @@ public:									/*{{{*/
 		CacheSetHelper helper;
 		CacheSetHelper helper;
 		return FromPackage(Cache, P, (CacheSetHelper::VerSelector)fallback, helper);
 		return FromPackage(Cache, P, (CacheSetHelper::VerSelector)fallback, helper);
 	}
 	}
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 	static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) {
 	static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) {
 		return FromPackage(Cache, P, CacheSetHelper::CANDIDATE);
 		return FromPackage(Cache, P, CacheSetHelper::CANDIDATE);
 	}
 	}
@@ -985,10 +936,7 @@ public:									/*{{{*/
 		CacheSetHelper helper;
 		CacheSetHelper helper;
 		return FromPackage(Cache, D, selector, helper);
 		return FromPackage(Cache, D, selector, helper);
 	}
 	}
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 	static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D,
 	static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D,
 					       Version const &selector, CacheSetHelper &helper) {
 					       Version const &selector, CacheSetHelper &helper) {
 		VersionContainer vercon;
 		VersionContainer vercon;
@@ -1000,9 +948,7 @@ public:									/*{{{*/
 		CacheSetHelper helper;
 		CacheSetHelper helper;
 		return FromPackage(Cache, D, (CacheSetHelper::VerSelector)selector, helper);
 		return FromPackage(Cache, D, (CacheSetHelper::VerSelector)selector, helper);
 	}
 	}
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 	static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D) {
 	static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D) {
 		return FromPackage(Cache, D, CacheSetHelper::CANDIDATE);
 		return FromPackage(Cache, D, CacheSetHelper::CANDIDATE);
 	}
 	}

+ 20 - 16
apt-pkg/cdrom.cc

@@ -466,7 +466,7 @@ bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
    // Open the stream for reading
    // Open the stream for reading
    ifstream F((FileExists(File)?File.c_str():"/dev/null"),
    ifstream F((FileExists(File)?File.c_str():"/dev/null"),
 	      ios::in );
 	      ios::in );
-   if (!F != 0)
+   if (F.fail() == true)
       return _error->Errno("ifstream::ifstream","Opening %s",File.c_str());
       return _error->Errno("ifstream::ifstream","Opening %s",File.c_str());
 
 
    string NewFile = File + ".new";
    string NewFile = File + ".new";
@@ -477,7 +477,7 @@ bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
 			   "Failed to open %s.new",File.c_str());
 			   "Failed to open %s.new",File.c_str());
 
 
    // Create a short uri without the path
    // Create a short uri without the path
-   string ShortURI = "cdrom:[" + Name + "]/";   
+   string ShortURI = "cdrom:[" + Name + "]/";
    string ShortURI2 = "cdrom:" + Name + "/";     // For Compatibility
    string ShortURI2 = "cdrom:" + Name + "/";     // For Compatibility
 
 
    string Type;
    string Type;
@@ -485,12 +485,12 @@ bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
       Type = "deb-src";
       Type = "deb-src";
    else
    else
       Type = "deb";
       Type = "deb";
-   
+
    char Buffer[300];
    char Buffer[300];
    int CurLine = 0;
    int CurLine = 0;
    bool First = true;
    bool First = true;
    while (F.eof() == false)
    while (F.eof() == false)
-   {      
+   {
       F.getline(Buffer,sizeof(Buffer));
       F.getline(Buffer,sizeof(Buffer));
       CurLine++;
       CurLine++;
       if (F.fail() && !F.eof())
       if (F.fail() && !F.eof())
@@ -754,7 +754,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
 	  FileExists(InfoDir + "/info") == true)
 	  FileExists(InfoDir + "/info") == true)
       {
       {
 	 ifstream F((InfoDir + "/info").c_str());
 	 ifstream F((InfoDir + "/info").c_str());
-	 if (!F == 0)
+	 if (F.good() == true)
 	    getline(F,Name);
 	    getline(F,Name);
 
 
 	 if (Name.empty() == false)
 	 if (Name.empty() == false)
@@ -822,8 +822,11 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
    // check for existence and possibly create state directory for copying
    // check for existence and possibly create state directory for copying
    string const listDir = _config->FindDir("Dir::State::lists");
    string const listDir = _config->FindDir("Dir::State::lists");
    string const partialListDir = listDir + "partial/";
    string const partialListDir = listDir + "partial/";
-   if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::State"), partialListDir) == false &&
-       CreateAPTDirectoryIfNeeded(listDir, partialListDir) == false)
+   mode_t const mode = umask(S_IWGRP | S_IWOTH);
+   bool const creation_fail = (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::State"), partialListDir) == false &&
+	 CreateAPTDirectoryIfNeeded(listDir, partialListDir) == false);
+   umask(mode);
+   if (creation_fail == true)
    {
    {
       UnmountCDROM(CDROM, NULL);
       UnmountCDROM(CDROM, NULL);
       return _error->Errno("cdrom", _("List directory %spartial is missing."), listDir.c_str());
       return _error->Errno("cdrom", _("List directory %spartial is missing."), listDir.c_str());
@@ -924,8 +927,7 @@ pkgUdevCdromDevices::pkgUdevCdromDevices()				/*{{{*/
 }
 }
 									/*}}}*/
 									/*}}}*/
 
 
-bool
-pkgUdevCdromDevices::Dlopen()                     		        /*{{{*/
+bool pkgUdevCdromDevices::Dlopen()					/*{{{*/
 {
 {
    // alread open
    // alread open
    if(libudev_handle != NULL)
    if(libudev_handle != NULL)
@@ -954,18 +956,14 @@ pkgUdevCdromDevices::Dlopen()                     		        /*{{{*/
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-                                                                        /*{{{*/
-// convenience interface, this will just call ScanForRemovable
-vector<CdromDevice>
-pkgUdevCdromDevices::Scan()
+// convenience interface, this will just call ScanForRemovable		/*{{{*/
+vector<CdromDevice> pkgUdevCdromDevices::Scan()
 {
 {
    bool CdromOnly = _config->FindB("APT::cdrom::CdromOnly", true);
    bool CdromOnly = _config->FindB("APT::cdrom::CdromOnly", true);
    return ScanForRemovable(CdromOnly);
    return ScanForRemovable(CdromOnly);
 }
 }
 									/*}}}*/
 									/*}}}*/
-                                                                        /*{{{*/
-vector<CdromDevice>
-pkgUdevCdromDevices::ScanForRemovable(bool CdromOnly)
+vector<CdromDevice> pkgUdevCdromDevices::ScanForRemovable(bool CdromOnly)/*{{{*/
 {
 {
    vector<CdromDevice> cdrom_devices;
    vector<CdromDevice> cdrom_devices;
    struct udev_enumerate *enumerate;
    struct udev_enumerate *enumerate;
@@ -1024,3 +1022,9 @@ pkgUdevCdromDevices::~pkgUdevCdromDevices()                             /*{{{*/
       dlclose(libudev_handle);
       dlclose(libudev_handle);
 }
 }
 									/*}}}*/
 									/*}}}*/
+
+pkgCdromStatus::pkgCdromStatus() : totalSteps(0) {}
+pkgCdromStatus::~pkgCdromStatus() {}
+
+pkgCdrom::pkgCdrom() {}
+pkgCdrom::~pkgCdrom() {}

+ 9 - 2
apt-pkg/cdrom.h

@@ -18,12 +18,13 @@ class OpProgress;
 
 
 class pkgCdromStatus							/*{{{*/
 class pkgCdromStatus							/*{{{*/
 {
 {
+   void *d;
  protected:
  protected:
    int totalSteps;
    int totalSteps;
 
 
  public:
  public:
-   pkgCdromStatus() : totalSteps(0) {};
-   virtual ~pkgCdromStatus() {};
+   pkgCdromStatus();
+   virtual ~pkgCdromStatus();
 
 
    // total steps
    // total steps
    virtual void SetTotal(int total) { totalSteps = total; };
    virtual void SetTotal(int total) { totalSteps = total; };
@@ -74,7 +75,12 @@ class pkgCdrom								/*{{{*/
    bool Ident(std::string &ident, pkgCdromStatus *log);
    bool Ident(std::string &ident, pkgCdromStatus *log);
    bool Add(pkgCdromStatus *log);
    bool Add(pkgCdromStatus *log);
 
 
+   pkgCdrom();
+   virtual ~pkgCdrom();
+
  private:
  private:
+   void *d;
+
    APT_HIDDEN bool MountAndIdentCDROM(Configuration &Database, std::string &CDROM,
    APT_HIDDEN bool MountAndIdentCDROM(Configuration &Database, std::string &CDROM,
 	 std::string &ident, pkgCdromStatus * const log, bool const interactive);
 	 std::string &ident, pkgCdromStatus * const log, bool const interactive);
    APT_HIDDEN bool UnmountCDROM(std::string const &CDROM, pkgCdromStatus * const log);
    APT_HIDDEN bool UnmountCDROM(std::string const &CDROM, pkgCdromStatus * const log);
@@ -92,6 +98,7 @@ struct CdromDevice							/*{{{*/
 									/*}}}*/
 									/*}}}*/
 class pkgUdevCdromDevices						/*{{{*/
 class pkgUdevCdromDevices						/*{{{*/
 {
 {
+   void *d;
  protected:
  protected:
    // libudev dlopen structure
    // libudev dlopen structure
    void *libudev_handle;
    void *libudev_handle;

+ 2 - 1
apt-pkg/clean.cc

@@ -106,7 +106,7 @@ bool pkgArchiveCleaner::Go(std::string Dir,pkgCache &Cache)
 		 J.end() == false; ++J)
 		 J.end() == false; ++J)
 	    {
 	    {
 	       if (CleanInstalled == true &&
 	       if (CleanInstalled == true &&
-		   (J.File()->Flags & pkgCache::Flag::NotSource) != 0)
+		   J.File().Flagged(pkgCache::Flag::NotSource))
 		  continue;
 		  continue;
 	       IsFetchable = true;
 	       IsFetchable = true;
 	       break;
 	       break;
@@ -132,4 +132,5 @@ bool pkgArchiveCleaner::Go(std::string Dir,pkgCache &Cache)
 }
 }
 									/*}}}*/
 									/*}}}*/
 
 
+pkgArchiveCleaner::pkgArchiveCleaner() {}
 APT_CONST pkgArchiveCleaner::~pkgArchiveCleaner() {}
 APT_CONST pkgArchiveCleaner::~pkgArchiveCleaner() {}

+ 2 - 0
apt-pkg/clean.h

@@ -30,6 +30,8 @@ class pkgArchiveCleaner
    public:
    public:
 
 
    bool Go(std::string Dir,pkgCache &Cache);
    bool Go(std::string Dir,pkgCache &Cache);
+
+   pkgArchiveCleaner();
    virtual ~pkgArchiveCleaner();
    virtual ~pkgArchiveCleaner();
 };
 };
 
 

+ 16 - 15
apt-pkg/contrib/cdromutl.cc

@@ -207,7 +207,6 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version)
    /* Run over the directory, we assume that the reader order will never
    /* Run over the directory, we assume that the reader order will never
       change as the media is read-only. In theory if the kernel did
       change as the media is read-only. In theory if the kernel did
       some sort of wacked caching this might not be true.. */
       some sort of wacked caching this might not be true.. */
-   char S[300];
    for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D))
    for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D))
    {
    {
       // Skip some files..
       // Skip some files..
@@ -215,30 +214,32 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version)
 	  strcmp(Dir->d_name,"..") == 0)
 	  strcmp(Dir->d_name,"..") == 0)
 	 continue;
 	 continue;
 
 
+      std::string S;
       if (Version <= 1)
       if (Version <= 1)
       {
       {
-	 sprintf(S,"%lu",(unsigned long)Dir->d_ino);
+	 strprintf(S, "%lu", (unsigned long)Dir->d_ino);
       }
       }
       else
       else
       {
       {
 	 struct stat Buf;
 	 struct stat Buf;
 	 if (stat(Dir->d_name,&Buf) != 0)
 	 if (stat(Dir->d_name,&Buf) != 0)
 	    continue;
 	    continue;
-	 sprintf(S,"%lu",(unsigned long)Buf.st_mtime);
+	 strprintf(S, "%lu", (unsigned long)Buf.st_mtime);
       }
       }
-      
-      Hash.Add(S);
+
+      Hash.Add(S.c_str());
       Hash.Add(Dir->d_name);
       Hash.Add(Dir->d_name);
    };
    };
-   
+
    if (chdir(StartDir.c_str()) != 0) {
    if (chdir(StartDir.c_str()) != 0) {
       _error->Errno("chdir",_("Unable to change to %s"),StartDir.c_str());
       _error->Errno("chdir",_("Unable to change to %s"),StartDir.c_str());
       closedir(D);
       closedir(D);
       return false;
       return false;
    }
    }
    closedir(D);
    closedir(D);
-   
+
    // Some stats from the fsys
    // Some stats from the fsys
+   std::string S;
    if (_config->FindB("Debug::identcdrom",false) == false)
    if (_config->FindB("Debug::identcdrom",false) == false)
    {
    {
       struct statvfs Buf;
       struct statvfs Buf;
@@ -248,19 +249,19 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version)
       // We use a kilobyte block size to advoid overflow
       // We use a kilobyte block size to advoid overflow
       if (writable_media)
       if (writable_media)
       {
       {
-         sprintf(S,"%lu",(long)(Buf.f_blocks*(Buf.f_bsize/1024)));
+         strprintf(S, "%lu", (unsigned long)(Buf.f_blocks*(Buf.f_bsize/1024)));
       } else {
       } else {
-         sprintf(S,"%lu %lu",(long)(Buf.f_blocks*(Buf.f_bsize/1024)),
-                 (long)(Buf.f_bfree*(Buf.f_bsize/1024)));
+         strprintf(S, "%lu %lu", (unsigned long)(Buf.f_blocks*(Buf.f_bsize/1024)),
+                 (unsigned long)(Buf.f_bfree*(Buf.f_bsize/1024)));
       }
       }
-      Hash.Add(S);
-      sprintf(S,"-%u",Version);
+      Hash.Add(S.c_str());
+      strprintf(S, "-%u", Version);
    }
    }
    else
    else
-      sprintf(S,"-%u.debug",Version);
-   
+      strprintf(S, "-%u.debug", Version);
+
    Res = Hash.Result().Value() + S;
    Res = Hash.Result().Value() + S;
-   return true;   
+   return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // FindMountPointForDevice - Find mountpoint for the given device	/*{{{*/
 // FindMountPointForDevice - Find mountpoint for the given device	/*{{{*/

+ 3 - 0
apt-pkg/contrib/cmndline.cc

@@ -33,6 +33,9 @@ using namespace std;
 CommandLine::CommandLine(Args *AList,Configuration *Conf) : ArgList(AList), 
 CommandLine::CommandLine(Args *AList,Configuration *Conf) : ArgList(AList), 
                                  Conf(Conf), FileList(0)
                                  Conf(Conf), FileList(0)
 {
 {
+}
+CommandLine::CommandLine() : ArgList(NULL), Conf(NULL), FileList(0)
+{
 }
 }
 									/*}}}*/
 									/*}}}*/
 // CommandLine::~CommandLine - Destructor				/*{{{*/
 // CommandLine::~CommandLine - Destructor				/*{{{*/

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

@@ -91,6 +91,7 @@ class CommandLine
    static CommandLine::Args MakeArgs(char ShortOpt, char const *LongOpt,
    static CommandLine::Args MakeArgs(char ShortOpt, char const *LongOpt,
 	 char const *ConfName, unsigned long Flags) APT_CONST;
 	 char const *ConfName, unsigned long Flags) APT_CONST;
 
 
+   CommandLine();
    CommandLine(Args *AList,Configuration *Conf);
    CommandLine(Args *AList,Configuration *Conf);
    ~CommandLine();
    ~CommandLine();
 };
 };

+ 13 - 7
apt-pkg/contrib/configuration.cc

@@ -253,7 +253,13 @@ string Configuration::FindDir(const char *Name,const char *Default) const
 // Configuration::FindVector - Find a vector of values			/*{{{*/
 // Configuration::FindVector - Find a vector of values			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Returns a vector of config values under the given item */
 /* Returns a vector of config values under the given item */
-vector<string> Configuration::FindVector(const char *Name, std::string const &Default) const
+#if APT_PKG_ABI < 413
+vector<string> Configuration::FindVector(const char *Name) const
+{
+   return FindVector(Name, "");
+}
+#endif
+vector<string> Configuration::FindVector(const char *Name, std::string const &Default, bool const Keys) const
 {
 {
    vector<string> Vec;
    vector<string> Vec;
    const Item *Top = Lookup(Name);
    const Item *Top = Lookup(Name);
@@ -266,7 +272,7 @@ vector<string> Configuration::FindVector(const char *Name, std::string const &De
    Item *I = Top->Child;
    Item *I = Top->Child;
    while(I != NULL)
    while(I != NULL)
    {
    {
-      Vec.push_back(I->Value);
+      Vec.push_back(Keys ? I->Tag : I->Value);
       I = I->Next;
       I = I->Next;
    }
    }
    if (Vec.empty() == true)
    if (Vec.empty() == true)
@@ -623,19 +629,19 @@ string Configuration::Item::FullTag(const Item *Stop) const
    tag/value. AsSectional enables Sectional parsing.*/
    tag/value. AsSectional enables Sectional parsing.*/
 bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectional,
 bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectional,
 		    unsigned const &Depth)
 		    unsigned const &Depth)
-{   
+{
    // Open the stream for reading
    // Open the stream for reading
-   ifstream F(FName.c_str(),ios::in); 
-   if (!F != 0)
+   ifstream F(FName.c_str(),ios::in);
+   if (F.fail() == true)
       return _error->Errno("ifstream::ifstream",_("Opening configuration file %s"),FName.c_str());
       return _error->Errno("ifstream::ifstream",_("Opening configuration file %s"),FName.c_str());
 
 
    string LineBuffer;
    string LineBuffer;
    string Stack[100];
    string Stack[100];
    unsigned int StackPos = 0;
    unsigned int StackPos = 0;
-   
+
    // Parser state
    // Parser state
    string ParentTag;
    string ParentTag;
-   
+
    int CurLine = 0;
    int CurLine = 0;
    bool InComment = false;
    bool InComment = false;
    while (F.eof() == false)
    while (F.eof() == false)

+ 3 - 2
apt-pkg/contrib/configuration.h

@@ -84,8 +84,9 @@ class Configuration
     *
     *
     * \param Name of the parent node
     * \param Name of the parent node
     * \param Default list of values separated by commas */
     * \param Default list of values separated by commas */
-   std::vector<std::string> FindVector(const char *Name, std::string const &Default = "") const;
-   std::vector<std::string> FindVector(std::string const &Name, std::string const &Default = "") const { return FindVector(Name.c_str(), Default); };
+   std::vector<std::string> FindVector(const char *Name, std::string const &Default = "", bool const Keys = false) const;
+   std::vector<std::string> FindVector(std::string const &Name, std::string const &Default = "", bool const Keys = false) const { return FindVector(Name.c_str(), Default, Keys); };
+
    int FindI(const char *Name,int const &Default = 0) const;
    int FindI(const char *Name,int const &Default = 0) const;
    int FindI(std::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;

+ 21 - 1
apt-pkg/contrib/fileutl.cc

@@ -800,8 +800,9 @@ pid_t ExecFork(std::set<int> KeepFDs)
       signal(SIGCONT,SIG_DFL);
       signal(SIGCONT,SIG_DFL);
       signal(SIGTSTP,SIG_DFL);
       signal(SIGTSTP,SIG_DFL);
 
 
+      long ScOpenMax = sysconf(_SC_OPEN_MAX);
       // Close all of our FDs - just in case
       // Close all of our FDs - just in case
-      for (int K = 3; K != sysconf(_SC_OPEN_MAX); K++)
+      for (int K = 3; K != ScOpenMax; K++)
       {
       {
 	 if(KeepFDs.find(K) == KeepFDs.end())
 	 if(KeepFDs.find(K) == KeepFDs.end())
 	    fcntl(K,F_SETFD,FD_CLOEXEC);
 	    fcntl(K,F_SETFD,FD_CLOEXEC);
@@ -874,6 +875,25 @@ bool StartsWithGPGClearTextSignature(string const &FileName)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// ChangeOwnerAndPermissionOfFile - set file attributes to requested values /*{{{*/
+bool ChangeOwnerAndPermissionOfFile(char const * const requester, char const * const file, char const * const user, char const * const group, mode_t const mode)
+{
+   if (strcmp(file, "/dev/null") == 0)
+      return true;
+   bool Res = true;
+   if (getuid() == 0 && strlen(user) != 0 && strlen(group) != 0) // if we aren't root, we can't chown, so don't try it
+   {
+      // ensure the file is owned by root and has good permissions
+      struct passwd const * const pw = getpwnam(user);
+      struct group const * const gr = getgrnam(group);
+      if (pw != NULL && gr != NULL && chown(file, pw->pw_uid, gr->gr_gid) != 0)
+	 Res &= _error->WarningE(requester, "chown to %s:%s of file %s failed", user, group, file);
+   }
+   if (chmod(file, mode) != 0)
+      Res &= _error->WarningE(requester, "chmod 0%o of file %s failed", mode, file);
+   return Res;
+}
+									/*}}}*/
 
 
 class FileFdPrivate {							/*{{{*/
 class FileFdPrivate {							/*{{{*/
 	public:
 	public:

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

@@ -195,10 +195,21 @@ pid_t ExecFork(std::set<int> keep_fds);
 void MergeKeepFdsFromConfiguration(std::set<int> &keep_fds);
 void MergeKeepFdsFromConfiguration(std::set<int> &keep_fds);
 bool ExecWait(pid_t Pid,const char *Name,bool Reap = false);
 bool ExecWait(pid_t Pid,const char *Name,bool Reap = false);
 
 
-
 // check if the given file starts with a PGP cleartext signature
 // check if the given file starts with a PGP cleartext signature
 bool StartsWithGPGClearTextSignature(std::string const &FileName);
 bool StartsWithGPGClearTextSignature(std::string const &FileName);
 
 
+/** change file attributes to requested known good values
+ *
+ * The method skips the user:group setting if not root.
+ *
+ * @param requester is printed as functionname in error cases
+ * @param file is the file to be modified
+ * @param user is the (new) owner of the file, e.g. _apt
+ * @param group is the (new) group owning the file, e.g. root
+ * @param mode is the access mode of the file, e.g. 0644
+ */
+bool ChangeOwnerAndPermissionOfFile(char const * const requester, char const * const file, char const * const user, char const * const group, mode_t const mode);
+
 /**
 /**
  * \brief Drop privileges
  * \brief Drop privileges
  *
  *

+ 86 - 46
apt-pkg/contrib/hashes.cc

@@ -23,6 +23,7 @@
 #include <stddef.h>
 #include <stddef.h>
 #include <algorithm>
 #include <algorithm>
 #include <unistd.h>
 #include <unistd.h>
+#include <stdlib.h>
 #include <string>
 #include <string>
 #include <iostream>
 #include <iostream>
 									/*}}}*/
 									/*}}}*/
@@ -178,6 +179,22 @@ HashString const * HashStringList::find(char const * const type) const /*{{{*/
    return NULL;
    return NULL;
 }
 }
 									/*}}}*/
 									/*}}}*/
+unsigned long long HashStringList::FileSize() const			/*{{{*/
+{
+   HashString const * const hsf = find("Checksum-FileSize");
+   if (hsf == NULL)
+      return 0;
+   std::string const hv = hsf->HashValue();
+   return strtoull(hv.c_str(), NULL, 10);
+}
+									/*}}}*/
+bool HashStringList::FileSize(unsigned long long const Size)		/*{{{*/
+{
+   std::string size;
+   strprintf(size, "%llu", Size);
+   return push_back(HashString("Checksum-FileSize", size));
+}
+									/*}}}*/
 bool HashStringList::supported(char const * const type)			/*{{{*/
 bool HashStringList::supported(char const * const type)			/*{{{*/
 {
 {
    for (char const * const * t = HashString::SupportedHashes(); *t != NULL; ++t)
    for (char const * const * t = HashString::SupportedHashes(); *t != NULL; ++t)
@@ -204,15 +221,22 @@ bool HashStringList::push_back(const HashString &hashString)		/*{{{*/
 									/*}}}*/
 									/*}}}*/
 bool HashStringList::VerifyFile(std::string filename) const		/*{{{*/
 bool HashStringList::VerifyFile(std::string filename) const		/*{{{*/
 {
 {
-   if (list.empty() == true)
-      return false;
-   HashString const * const hs = find(NULL);
-   if (hs == NULL || hs->VerifyFile(filename) == false)
+   if (usable() == false)
       return false;
       return false;
+
+   Hashes hashes(*this);
+   FileFd file(filename, FileFd::ReadOnly);
    HashString const * const hsf = find("Checksum-FileSize");
    HashString const * const hsf = find("Checksum-FileSize");
-   if (hsf != NULL && hsf->VerifyFile(filename) == false)
-      return false;
-   return true;
+   if (hsf != NULL)
+   {
+      std::string fileSize;
+      strprintf(fileSize, "%llu", file.FileSize());
+      if (hsf->HashValue() != fileSize)
+	 return false;
+   }
+   hashes.AddFD(file);
+   HashStringList const hsl = hashes.GetHashStringList();
+   return hsl == *this;
 }
 }
 									/*}}}*/
 									/*}}}*/
 bool HashStringList::operator==(HashStringList const &other) const	/*{{{*/
 bool HashStringList::operator==(HashStringList const &other) const	/*{{{*/
@@ -250,33 +274,34 @@ bool HashStringList::operator!=(HashStringList const &other) const
 class PrivateHashes {
 class PrivateHashes {
 public:
 public:
    unsigned long long FileSize;
    unsigned long long FileSize;
+   unsigned int CalcHashes;
 
 
-   PrivateHashes() : FileSize(0) {}
+   PrivateHashes(unsigned int const CalcHashes) : FileSize(0), CalcHashes(CalcHashes) {}
 };
 };
 									/*}}}*/
 									/*}}}*/
 // Hashes::Add* - Add the contents of data or FD			/*{{{*/
 // Hashes::Add* - Add the contents of data or FD			/*{{{*/
-bool Hashes::Add(const unsigned char * const Data,unsigned long long const Size, unsigned int const Hashes)
+bool Hashes::Add(const unsigned char * const Data, unsigned long long const Size)
 {
 {
    bool Res = true;
    bool Res = true;
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
-   if ((Hashes & MD5SUM) == MD5SUM)
+APT_IGNORE_DEPRECATED_PUSH
+   if ((d->CalcHashes & MD5SUM) == MD5SUM)
       Res &= MD5.Add(Data, Size);
       Res &= MD5.Add(Data, Size);
-   if ((Hashes & SHA1SUM) == SHA1SUM)
+   if ((d->CalcHashes & SHA1SUM) == SHA1SUM)
       Res &= SHA1.Add(Data, Size);
       Res &= SHA1.Add(Data, Size);
-   if ((Hashes & SHA256SUM) == SHA256SUM)
+   if ((d->CalcHashes & SHA256SUM) == SHA256SUM)
       Res &= SHA256.Add(Data, Size);
       Res &= SHA256.Add(Data, Size);
-   if ((Hashes & SHA512SUM) == SHA512SUM)
+   if ((d->CalcHashes & SHA512SUM) == SHA512SUM)
       Res &= SHA512.Add(Data, Size);
       Res &= SHA512.Add(Data, Size);
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
    d->FileSize += Size;
    d->FileSize += Size;
    return Res;
    return Res;
 }
 }
-bool Hashes::AddFD(int const Fd,unsigned long long Size, unsigned int const Hashes)
+bool Hashes::Add(const unsigned char * const Data, unsigned long long const Size, unsigned int const Hashes)
+{
+   d->CalcHashes = Hashes;
+   return Add(Data, Size);
+}
+bool Hashes::AddFD(int const Fd,unsigned long long Size)
 {
 {
    unsigned char Buf[64*64];
    unsigned char Buf[64*64];
    bool const ToEOF = (Size == UntilEOF);
    bool const ToEOF = (Size == UntilEOF);
@@ -290,12 +315,17 @@ bool Hashes::AddFD(int const Fd,unsigned long long Size, unsigned int const Hash
       if (ToEOF && Res == 0) // EOF
       if (ToEOF && Res == 0) // EOF
 	 break;
 	 break;
       Size -= Res;
       Size -= Res;
-      if (Add(Buf, Res, Hashes) == false)
+      if (Add(Buf, Res) == false)
 	 return false;
 	 return false;
    }
    }
    return true;
    return true;
 }
 }
-bool Hashes::AddFD(FileFd &Fd,unsigned long long Size, unsigned int const Hashes)
+bool Hashes::AddFD(int const Fd,unsigned long long Size, unsigned int const Hashes)
+{
+   d->CalcHashes = Hashes;
+   return AddFD(Fd, Size);
+}
+bool Hashes::AddFD(FileFd &Fd,unsigned long long Size)
 {
 {
    unsigned char Buf[64*64];
    unsigned char Buf[64*64];
    bool const ToEOF = (Size == 0);
    bool const ToEOF = (Size == 0);
@@ -314,37 +344,47 @@ bool Hashes::AddFD(FileFd &Fd,unsigned long long Size, unsigned int const Hashes
       else if (a == 0) // EOF
       else if (a == 0) // EOF
 	 break;
 	 break;
       Size -= a;
       Size -= a;
-      if (Add(Buf, a, Hashes) == false)
+      if (Add(Buf, a) == false)
 	 return false;
 	 return false;
    }
    }
    return true;
    return true;
+}
+bool Hashes::AddFD(FileFd &Fd,unsigned long long Size, unsigned int const Hashes)
+{
+   d->CalcHashes = Hashes;
+   return AddFD(Fd, Size);
 }
 }
 									/*}}}*/
 									/*}}}*/
 HashStringList Hashes::GetHashStringList()
 HashStringList Hashes::GetHashStringList()
 {
 {
    HashStringList hashes;
    HashStringList hashes;
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
-   hashes.push_back(HashString("MD5Sum", MD5.Result().Value()));
-   hashes.push_back(HashString("SHA1", SHA1.Result().Value()));
-   hashes.push_back(HashString("SHA256", SHA256.Result().Value()));
-   hashes.push_back(HashString("SHA512", SHA512.Result().Value()));
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
-   std::string SizeStr;
-   strprintf(SizeStr, "%llu", d->FileSize);
-   hashes.push_back(HashString("Checksum-FileSize", SizeStr));
+APT_IGNORE_DEPRECATED_PUSH
+   if ((d->CalcHashes & MD5SUM) == MD5SUM)
+      hashes.push_back(HashString("MD5Sum", MD5.Result().Value()));
+   if ((d->CalcHashes & SHA1SUM) == SHA1SUM)
+      hashes.push_back(HashString("SHA1", SHA1.Result().Value()));
+   if ((d->CalcHashes & SHA256SUM) == SHA256SUM)
+      hashes.push_back(HashString("SHA256", SHA256.Result().Value()));
+   if ((d->CalcHashes & SHA512SUM) == SHA512SUM)
+      hashes.push_back(HashString("SHA512", SHA512.Result().Value()));
+APT_IGNORE_DEPRECATED_POP
+   hashes.FileSize(d->FileSize);
    return hashes;
    return hashes;
 }
 }
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
-Hashes::Hashes() { d = new PrivateHashes(); }
+APT_IGNORE_DEPRECATED_PUSH
+Hashes::Hashes() { d = new PrivateHashes(~0); }
+Hashes::Hashes(unsigned int const Hashes) { d = new PrivateHashes(Hashes); }
+Hashes::Hashes(HashStringList const &Hashes) {
+   unsigned int calcHashes = Hashes.usable() ? 0 : ~0;
+   if (Hashes.find("MD5Sum") != NULL)
+      calcHashes |= MD5SUM;
+   if (Hashes.find("SHA1") != NULL)
+      calcHashes |= SHA1SUM;
+   if (Hashes.find("SHA256") != NULL)
+      calcHashes |= SHA256SUM;
+   if (Hashes.find("SHA512") != NULL)
+      calcHashes |= SHA512SUM;
+   d = new PrivateHashes(calcHashes);
+}
 Hashes::~Hashes() { delete d; }
 Hashes::~Hashes() { delete d; }
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP

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

@@ -55,6 +55,8 @@ class HashString
    // get hash type used
    // get hash type used
    std::string HashType() const { return Type; };
    std::string HashType() const { return Type; };
    std::string HashValue() const { return Hash; };
    std::string HashValue() const { return Hash; };
+   APT_DEPRECATED std::string HashType() { return Type; };
+   APT_DEPRECATED std::string HashValue() { return Hash; };
 
 
    // verify the given filename against the currently loaded hash
    // verify the given filename against the currently loaded hash
    bool VerifyFile(std::string filename) const;
    bool VerifyFile(std::string filename) const;
@@ -85,6 +87,22 @@ class HashStringList
     */
     */
    HashString const * find(char const * const type) const;
    HashString const * find(char const * const type) const;
    HashString const * find(std::string const &type) const { return find(type.c_str()); }
    HashString const * find(std::string const &type) const { return find(type.c_str()); }
+
+   /** finds the filesize hash and returns it as number
+    *
+    * @return beware: if the size isn't known we return \b 0 here,
+    * just like we would do for an empty file. If that is a problem
+    * for you have to get the size manually out of the list.
+    */
+   unsigned long long FileSize() const;
+
+   /** sets the filesize hash
+    *
+    * @param Size of the file
+    * @return @see #push_back
+    */
+   bool FileSize(unsigned long long const Size);
+
    /** check if the given hash type is supported
    /** check if the given hash type is supported
     *
     *
     * @param type to check
     * @param type to check
@@ -176,7 +194,8 @@ class Hashes
 
 
    static const int UntilEOF = 0;
    static const int UntilEOF = 0;
 
 
-   bool Add(const unsigned char * const Data, unsigned long long const Size, unsigned int const Hashes = ~0);
+   bool Add(const unsigned char * const Data, unsigned long long const Size);
+   APT_DEPRECATED bool Add(const unsigned char * const Data, unsigned long long const Size, unsigned int const Hashes);
    inline bool Add(const char * const Data)
    inline bool Add(const char * const Data)
    {return Add((unsigned char const * const)Data,strlen(Data));};
    {return Add((unsigned char const * const)Data,strlen(Data));};
    inline bool Add(const unsigned char * const Beg,const unsigned char * const End)
    inline bool Add(const unsigned char * const Beg,const unsigned char * const End)
@@ -184,20 +203,26 @@ class Hashes
 
 
    enum SupportedHashes { MD5SUM = (1 << 0), SHA1SUM = (1 << 1), SHA256SUM = (1 << 2),
    enum SupportedHashes { MD5SUM = (1 << 0), SHA1SUM = (1 << 1), SHA256SUM = (1 << 2),
       SHA512SUM = (1 << 3) };
       SHA512SUM = (1 << 3) };
-   bool AddFD(int const Fd,unsigned long long Size = 0, unsigned int const Hashes = ~0);
-   bool AddFD(FileFd &Fd,unsigned long long Size = 0, unsigned int const Hashes = ~0);
+   bool AddFD(int const Fd,unsigned long long Size = 0);
+   APT_DEPRECATED bool AddFD(int const Fd,unsigned long long Size, unsigned int const Hashes);
+   bool AddFD(FileFd &Fd,unsigned long long Size = 0);
+   APT_DEPRECATED bool AddFD(FileFd &Fd,unsigned long long Size, unsigned int const Hashes);
 
 
    HashStringList GetHashStringList();
    HashStringList GetHashStringList();
 
 
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
+   /** create a Hashes object to calculate all supported hashes
+    *
+    * If ALL is too much, you can limit which Hashes are calculated
+    * with the following other constructors which mention explicitly
+    * which hashes to generate. */
    Hashes();
    Hashes();
+   /** @param Hashes bitflag composed of #SupportedHashes */
+   Hashes(unsigned int const Hashes);
+   /** @param Hashes is a list of hashes */
+   Hashes(HashStringList const &Hashes);
    virtual ~Hashes();
    virtual ~Hashes();
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 
 
    private:
    private:
    APT_HIDDEN APT_CONST inline unsigned int boolsToFlag(bool const addMD5, bool const addSHA1, bool const addSHA256, bool const addSHA512)
    APT_HIDDEN APT_CONST inline unsigned int boolsToFlag(bool const addMD5, bool const addSHA1, bool const addSHA256, bool const addSHA512)
@@ -211,15 +236,16 @@ class Hashes
    }
    }
 
 
    public:
    public:
+APT_IGNORE_DEPRECATED_PUSH
    APT_DEPRECATED bool AddFD(int const Fd, unsigned long long Size, bool const addMD5,
    APT_DEPRECATED bool AddFD(int const Fd, unsigned long long Size, bool const addMD5,
 	 bool const addSHA1, bool const addSHA256, bool const addSHA512) {
 	 bool const addSHA1, bool const addSHA256, bool const addSHA512) {
       return AddFD(Fd, Size, boolsToFlag(addMD5, addSHA1, addSHA256, addSHA512));
       return AddFD(Fd, Size, boolsToFlag(addMD5, addSHA1, addSHA256, addSHA512));
    };
    };
-
    APT_DEPRECATED bool AddFD(FileFd &Fd, unsigned long long Size, bool const addMD5,
    APT_DEPRECATED bool AddFD(FileFd &Fd, unsigned long long Size, bool const addMD5,
 	 bool const addSHA1, bool const addSHA256, bool const addSHA512) {
 	 bool const addSHA1, bool const addSHA256, bool const addSHA512) {
       return AddFD(Fd, Size, boolsToFlag(addMD5, addSHA1, addSHA256, addSHA512));
       return AddFD(Fd, Size, boolsToFlag(addMD5, addSHA1, addSHA256, addSHA512));
    };
    };
+APT_IGNORE_DEPRECATED_POP
 };
 };
 
 
 #endif
 #endif

+ 18 - 1
apt-pkg/contrib/macros.h

@@ -89,7 +89,7 @@
 	#define APT_MUSTCHECK		__attribute__((warn_unused_result))
 	#define APT_MUSTCHECK		__attribute__((warn_unused_result))
 #else
 #else
 	#define APT_NONNULL(...)
 	#define APT_NONNULL(...)
-	#define APT_REQRET
+	#define APT_MUSTCHECK
 #endif
 #endif
 
 
 #if APT_GCC_VERSION >= 0x0400
 #if APT_GCC_VERSION >= 0x0400
@@ -132,6 +132,22 @@
 #endif
 #endif
 #endif
 #endif
 
 
+#if __GNUC__ >= 4
+	#define APT_IGNORE_DEPRECATED_PUSH \
+		_Pragma("GCC diagnostic push") \
+		_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+	#define APT_IGNORE_DEPRECATED_POP \
+		_Pragma("GCC diagnostic pop")
+	#define APT_IGNORE_DEPRECATED(XXX) \
+		APT_IGNORE_DEPRECATED_PUSH \
+		XXX \
+		APT_IGNORE_DEPRECATED_POP
+#else
+	#define APT_IGNORE_DEPRECATED_PUSH
+	#define APT_IGNORE_DEPRECATED_POP
+	#define APT_IGNORE_DEPRECATED(XXX) XXX
+#endif
+
 // These lines are extracted by the makefiles and the buildsystem
 // These lines are extracted by the makefiles and the buildsystem
 // Increasing MAJOR or MINOR results in the need of recompiling all
 // Increasing MAJOR or MINOR results in the need of recompiling all
 // reverse-dependencies of libapt-pkg against the new SONAME.
 // reverse-dependencies of libapt-pkg against the new SONAME.
@@ -140,5 +156,6 @@
 #define APT_PKG_MAJOR 4
 #define APT_PKG_MAJOR 4
 #define APT_PKG_MINOR 15
 #define APT_PKG_MINOR 15
 #define APT_PKG_RELEASE 0
 #define APT_PKG_RELEASE 0
+#define APT_PKG_ABI ((APT_PKG_MAJOR * 100) + APT_PKG_MINOR)
 
 
 #endif
 #endif

+ 9 - 0
apt-pkg/contrib/sha2_internal.cc

@@ -129,6 +129,14 @@ typedef u_int64_t sha2_word64;	/* Exactly 8 bytes */
 
 
 /*** ENDIAN REVERSAL MACROS *******************************************/
 /*** ENDIAN REVERSAL MACROS *******************************************/
 #if BYTE_ORDER == LITTLE_ENDIAN
 #if BYTE_ORDER == LITTLE_ENDIAN
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+#define REVERSE32(w,x)	{ \
+	(x) = __builtin_bswap32(w); \
+}
+#define REVERSE64(w,x)	{ \
+	(x) = __builtin_bswap64(w); \
+}
+#else
 #define REVERSE32(w,x)	{ \
 #define REVERSE32(w,x)	{ \
 	sha2_word32 tmp = (w); \
 	sha2_word32 tmp = (w); \
 	tmp = (tmp >> 16) | (tmp << 16); \
 	tmp = (tmp >> 16) | (tmp << 16); \
@@ -142,6 +150,7 @@ typedef u_int64_t sha2_word64;	/* Exactly 8 bytes */
 	(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
 	(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
 	      ((tmp & 0x0000ffff0000ffffULL) << 16); \
 	      ((tmp & 0x0000ffff0000ffffULL) << 16); \
 }
 }
+#endif
 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
 
 
 /*
 /*

+ 74 - 79
apt-pkg/contrib/strutl.cc

@@ -324,21 +324,19 @@ bool ParseCWord(const char *&String,string &Res)
 /* */
 /* */
 string QuoteString(const string &Str, const char *Bad)
 string QuoteString(const string &Str, const char *Bad)
 {
 {
-   string Res;
+   std::stringstream Res;
    for (string::const_iterator I = Str.begin(); I != Str.end(); ++I)
    for (string::const_iterator I = Str.begin(); I != Str.end(); ++I)
    {
    {
-      if (strchr(Bad,*I) != 0 || isprint(*I) == 0 || 
+      if (strchr(Bad,*I) != 0 || isprint(*I) == 0 ||
 	  *I == 0x25 || // percent '%' char
 	  *I == 0x25 || // percent '%' char
 	  *I <= 0x20 || *I >= 0x7F) // control chars
 	  *I <= 0x20 || *I >= 0x7F) // control chars
       {
       {
-	 char Buf[10];
-	 sprintf(Buf,"%%%02x",(int)*I);
-	 Res += Buf;
+	 ioprintf(Res,"%%%02x",(int)*I);
       }
       }
       else
       else
-	 Res += *I;
+	 Res << *I;
    }
    }
-   return Res;
+   return Res.str();
 }
 }
 									/*}}}*/
 									/*}}}*/
 // DeQuoteString - Convert a string from quoted from                    /*{{{*/
 // DeQuoteString - Convert a string from quoted from                    /*{{{*/
@@ -379,13 +377,12 @@ string DeQuoteString(string::const_iterator const &begin,
    YottaBytes (E24) */
    YottaBytes (E24) */
 string SizeToStr(double Size)
 string SizeToStr(double Size)
 {
 {
-   char S[300];
    double ASize;
    double ASize;
    if (Size >= 0)
    if (Size >= 0)
       ASize = Size;
       ASize = Size;
    else
    else
       ASize = -1*Size;
       ASize = -1*Size;
-   
+
    /* bytes, KiloBytes, MegaBytes, GigaBytes, TeraBytes, PetaBytes, 
    /* bytes, KiloBytes, MegaBytes, GigaBytes, TeraBytes, PetaBytes, 
       ExaBytes, ZettaBytes, YottaBytes */
       ExaBytes, ZettaBytes, YottaBytes */
    char Ext[] = {'\0','k','M','G','T','P','E','Z','Y'};
    char Ext[] = {'\0','k','M','G','T','P','E','Z','Y'};
@@ -394,20 +391,21 @@ string SizeToStr(double Size)
    {
    {
       if (ASize < 100 && I != 0)
       if (ASize < 100 && I != 0)
       {
       {
-         sprintf(S,"%'.1f %c",ASize,Ext[I]);
-	 break;
+	 std::string S;
+	 strprintf(S, "%'.1f %c", ASize, Ext[I]);
+	 return S;
       }
       }
-      
+
       if (ASize < 10000)
       if (ASize < 10000)
       {
       {
-         sprintf(S,"%'.0f %c",ASize,Ext[I]);
-	 break;
+	 std::string S;
+	 strprintf(S, "%'.0f %c", ASize, Ext[I]);
+	 return S;
       }
       }
       ASize /= 1000.0;
       ASize /= 1000.0;
       I++;
       I++;
    }
    }
-   
-   return S;
+   return "";
 }
 }
 									/*}}}*/
 									/*}}}*/
 // TimeToStr - Convert the time into a string				/*{{{*/
 // TimeToStr - Convert the time into a string				/*{{{*/
@@ -415,36 +413,27 @@ string SizeToStr(double Size)
 /* Converts a number of seconds to a hms format */
 /* Converts a number of seconds to a hms format */
 string TimeToStr(unsigned long Sec)
 string TimeToStr(unsigned long Sec)
 {
 {
-   char S[300];
-   
-   while (1)
+   std::string S;
+   if (Sec > 60*60*24)
    {
    {
-      if (Sec > 60*60*24)
-      {
-	 //d means days, h means hours, min means minutes, s means seconds
-	 sprintf(S,_("%lid %lih %limin %lis"),Sec/60/60/24,(Sec/60/60) % 24,(Sec/60) % 60,Sec % 60);
-	 break;
-      }
-      
-      if (Sec > 60*60)
-      {
-	 //h means hours, min means minutes, s means seconds
-	 sprintf(S,_("%lih %limin %lis"),Sec/60/60,(Sec/60) % 60,Sec % 60);
-	 break;
-      }
-      
-      if (Sec > 60)
-      {
-	 //min means minutes, s means seconds
-	 sprintf(S,_("%limin %lis"),Sec/60,Sec % 60);
-	 break;
-      }
-
-      //s means seconds
-      sprintf(S,_("%lis"),Sec);
-      break;
+      //TRANSLATOR: d means days, h means hours, min means minutes, s means seconds
+      strprintf(S,_("%lid %lih %limin %lis"),Sec/60/60/24,(Sec/60/60) % 24,(Sec/60) % 60,Sec % 60);
+   }
+   else if (Sec > 60*60)
+   {
+      //TRANSLATOR: h means hours, min means minutes, s means seconds
+      strprintf(S,_("%lih %limin %lis"),Sec/60/60,(Sec/60) % 60,Sec % 60);
+   }
+   else if (Sec > 60)
+   {
+      //TRANSLATOR: min means minutes, s means seconds
+      strprintf(S,_("%limin %lis"),Sec/60,Sec % 60);
+   }
+   else
+   {
+      //TRANSLATOR: s means seconds
+      strprintf(S,_("%lis"),Sec);
    }
    }
-   
    return S;
    return S;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -1319,10 +1308,12 @@ void ioprintf(ostream &out,const char *format,...)
    va_list args;
    va_list args;
    ssize_t size = 400;
    ssize_t size = 400;
    while (true) {
    while (true) {
+      bool ret = false;
       va_start(args,format);
       va_start(args,format);
-      if (iovprintf(out, format, args, size) == true)
-	 return;
+      ret = iovprintf(out, format, args, size);
       va_end(args);
       va_end(args);
+      if (ret == true)
+	 return;
    }
    }
 }
 }
 void strprintf(string &out,const char *format,...)
 void strprintf(string &out,const char *format,...)
@@ -1331,10 +1322,12 @@ void strprintf(string &out,const char *format,...)
    ssize_t size = 400;
    ssize_t size = 400;
    std::ostringstream outstr;
    std::ostringstream outstr;
    while (true) {
    while (true) {
+      bool ret = false;
       va_start(args,format);
       va_start(args,format);
-      if (iovprintf(outstr, format, args, size) == true)
-	 break;
+      ret = iovprintf(outstr, format, args, size);
       va_end(args);
       va_end(args);
+      if (ret == true)
+	 break;
    }
    }
    out = outstr.str();
    out = outstr.str();
 }
 }
@@ -1419,7 +1412,7 @@ size_t strv_length(const char **str_array)
       ;
       ;
    return i;
    return i;
 }
 }
-
+									/*}}}*/
 // DeEscapeString - unescape (\0XX and \xXX) from a string		/*{{{*/
 // DeEscapeString - unescape (\0XX and \xXX) from a string		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -1601,56 +1594,49 @@ void URI::CopyFrom(const string &U)
 /* */
 /* */
 URI::operator string()
 URI::operator string()
 {
 {
-   string Res;
-   
+   std::stringstream Res;
+
    if (Access.empty() == false)
    if (Access.empty() == false)
-      Res = Access + ':';
-   
+      Res << Access << ':';
+
    if (Host.empty() == false)
    if (Host.empty() == false)
-   {	 
+   {
       if (Access.empty() == false)
       if (Access.empty() == false)
-	 Res += "//";
-          
+	 Res << "//";
+
       if (User.empty() == false)
       if (User.empty() == false)
       {
       {
 	 // FIXME: Technically userinfo is permitted even less
 	 // FIXME: Technically userinfo is permitted even less
 	 // characters than these, but this is not conveniently
 	 // characters than these, but this is not conveniently
 	 // expressed with a blacklist.
 	 // expressed with a blacklist.
-	 Res += QuoteString(User, ":/?#[]@");
+	 Res << QuoteString(User, ":/?#[]@");
 	 if (Password.empty() == false)
 	 if (Password.empty() == false)
-	    Res += ":" + QuoteString(Password, ":/?#[]@");
-	 Res += "@";
+	    Res << ":" << QuoteString(Password, ":/?#[]@");
+	 Res << "@";
       }
       }
-      
+
       // Add RFC 2732 escaping characters
       // Add RFC 2732 escaping characters
-      if (Access.empty() == false &&
-	  (Host.find('/') != string::npos || Host.find(':') != string::npos))
-	 Res += '[' + Host + ']';
+      if (Access.empty() == false && Host.find_first_of("/:") != string::npos)
+	 Res << '[' << Host << ']';
       else
       else
-	 Res += Host;
-      
+	 Res << Host;
+
       if (Port != 0)
       if (Port != 0)
-      {
-	 char S[30];
-	 sprintf(S,":%u",Port);
-	 Res += S;
-      }	 
+	 Res << ':' << Port;
    }
    }
-   
+
    if (Path.empty() == false)
    if (Path.empty() == false)
    {
    {
       if (Path[0] != '/')
       if (Path[0] != '/')
-	 Res += "/" + Path;
+	 Res << "/" << Path;
       else
       else
-	 Res += Path;
+	 Res << Path;
    }
    }
-   
-   return Res;
+
+   return Res.str();
 }
 }
 									/*}}}*/
 									/*}}}*/
 // URI::SiteOnly - Return the schema and site for the URI		/*{{{*/
 // URI::SiteOnly - Return the schema and site for the URI		/*{{{*/
-// ---------------------------------------------------------------------
-/* */
 string URI::SiteOnly(const string &URI)
 string URI::SiteOnly(const string &URI)
 {
 {
    ::URI U(URI);
    ::URI U(URI);
@@ -1660,9 +1646,18 @@ string URI::SiteOnly(const string &URI)
    return U;
    return U;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// URI::ArchiveOnly - Return the schema, site and cleaned path for the URI /*{{{*/
+string URI::ArchiveOnly(const string &URI)
+{
+   ::URI U(URI);
+   U.User.clear();
+   U.Password.clear();
+   if (U.Path.empty() == false && U.Path[U.Path.length() - 1] == '/')
+      U.Path.erase(U.Path.length() - 1);
+   return U;
+}
+									/*}}}*/
 // URI::NoUserPassword - Return the schema, site and path for the URI	/*{{{*/
 // URI::NoUserPassword - Return the schema, site and path for the URI	/*{{{*/
-// ---------------------------------------------------------------------
-/* */
 string URI::NoUserPassword(const string &URI)
 string URI::NoUserPassword(const string &URI)
 {
 {
    ::URI U(URI);
    ::URI U(URI);

+ 2 - 1
apt-pkg/contrib/strutl.h

@@ -81,7 +81,7 @@ bool TokSplitString(char Tok,char *Input,char **List,
 		    unsigned long ListMax);
 		    unsigned long ListMax);
 
 
 // split a given string by a char
 // split a given string by a char
-std::vector<std::string> VectorizeString(std::string const &haystack, char const &split) APT_CONST;
+std::vector<std::string> VectorizeString(std::string const &haystack, char const &split) APT_PURE;
 
 
 /* \brief Return a vector of strings from string "input" where "sep"
 /* \brief Return a vector of strings from string "input" where "sep"
  * is used as the delimiter string.
  * is used as the delimiter string.
@@ -167,6 +167,7 @@ class URI
    inline void operator =(const std::string &From) {CopyFrom(From);}
    inline void operator =(const std::string &From) {CopyFrom(From);}
    inline bool empty() {return Access.empty();};
    inline bool empty() {return Access.empty();};
    static std::string SiteOnly(const std::string &URI);
    static std::string SiteOnly(const std::string &URI);
+   static std::string ArchiveOnly(const std::string &URI);
    static std::string NoUserPassword(const std::string &URI);
    static std::string NoUserPassword(const std::string &URI);
    
    
    URI(std::string Path) {CopyFrom(Path);}
    URI(std::string Path) {CopyFrom(Path);}

+ 98 - 427
apt-pkg/deb/debindexfile.cc

@@ -34,6 +34,7 @@
 
 
 #include <stdio.h>
 #include <stdio.h>
 #include <iostream>
 #include <iostream>
+#include <sstream>
 #include <string>
 #include <string>
 #include <sys/stat.h>
 #include <sys/stat.h>
 									/*}}}*/
 									/*}}}*/
@@ -43,8 +44,8 @@ using std::string;
 // SourcesIndex::debSourcesIndex - Constructor				/*{{{*/
 // SourcesIndex::debSourcesIndex - Constructor				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-debSourcesIndex::debSourcesIndex(string URI,string Dist,string Section,bool Trusted) :
-     pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section)
+debSourcesIndex::debSourcesIndex(IndexTarget const &Target,bool const Trusted) :
+     pkgIndexTargetFile(Target, Trusted)
 {
 {
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -55,16 +56,9 @@ debSourcesIndex::debSourcesIndex(string URI,string Dist,string Section,bool Trus
 string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record,
 string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record,
 				   pkgSrcRecords::File const &File) const
 				   pkgSrcRecords::File const &File) const
 {
 {
-   string Res;
-   Res = ::URI::NoUserPassword(URI) + ' ';
-   if (Dist[Dist.size() - 1] == '/')
-   {
-      if (Dist != "/")
-	 Res += Dist;
-   }      
-   else
-      Res += Dist + '/' + Section;
-   
+   string Res = Target.Description;
+   Res.erase(Target.Description.rfind(' '));
+
    Res += " ";
    Res += " ";
    Res += Record.Package();
    Res += Record.Package();
    Res += " ";
    Res += " ";
@@ -79,129 +73,19 @@ string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record,
 /* */
 /* */
 pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const
 pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const
 {
 {
-   string SourcesURI = _config->FindDir("Dir::State::lists") + 
-      URItoFileName(IndexURI("Sources"));
-
-   std::vector<std::string> types = APT::Configuration::getCompressionTypes();
-   for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
-   {
-      string p;
-      p = SourcesURI + '.' + *t;
-      if (FileExists(p))
-         return new debSrcRecordParser(p, this);
-   }
+   string const SourcesURI = IndexFileName();
    if (FileExists(SourcesURI))
    if (FileExists(SourcesURI))
       return new debSrcRecordParser(SourcesURI, this);
       return new debSrcRecordParser(SourcesURI, this);
    return NULL;
    return NULL;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// SourcesIndex::Describe - Give a descriptive path to the index	/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debSourcesIndex::Describe(bool Short) const
-{
-   char S[300];
-   if (Short == true)
-      snprintf(S,sizeof(S),"%s",Info("Sources").c_str());
-   else
-      snprintf(S,sizeof(S),"%s (%s)",Info("Sources").c_str(),
-	       IndexFile("Sources").c_str());
-   
-   return S;
-}
-									/*}}}*/
-// SourcesIndex::Info - One liner describing the index URI		/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debSourcesIndex::Info(const char *Type) const
-{
-   string Info = ::URI::NoUserPassword(URI) + ' ';
-   if (Dist[Dist.size() - 1] == '/')
-   {
-      if (Dist != "/")
-	 Info += Dist;
-   }
-   else
-      Info += Dist + '/' + Section;   
-   Info += " ";
-   Info += Type;
-   return Info;
-}
-									/*}}}*/
-// SourcesIndex::Index* - Return the URI to the index files		/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debSourcesIndex::IndexFile(const char *Type) const
-{
-   string s = URItoFileName(IndexURI(Type));
-
-   std::vector<std::string> types = APT::Configuration::getCompressionTypes();
-   for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
-   {
-      string p = s + '.' + *t;
-      if (FileExists(p))
-         return p;
-   }
-   return s;
-}
-
-string debSourcesIndex::IndexURI(const char *Type) const
-{
-   string Res;
-   if (Dist[Dist.size() - 1] == '/')
-   {
-      if (Dist != "/")
-	 Res = URI + Dist;
-      else 
-	 Res = URI;
-   }
-   else
-      Res = URI + "dists/" + Dist + '/' + Section +
-      "/source/";
-   
-   Res += Type;
-   return Res;
-}
-									/*}}}*/
-// SourcesIndex::Exists - Check if the index is available		/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool debSourcesIndex::Exists() const
-{
-   return FileExists(IndexFile("Sources"));
-}
-									/*}}}*/
-// SourcesIndex::Size - Return the size of the index			/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-unsigned long debSourcesIndex::Size() const
-{
-   unsigned long size = 0;
-
-   /* we need to ignore errors here; if the lists are absent, just return 0 */
-   _error->PushToStack();
-
-   FileFd f(IndexFile("Sources"), FileFd::ReadOnly, FileFd::Extension);
-   if (!f.Failed())
-      size = f.Size();
-
-   if (_error->PendingError() == true)
-       size = 0;
-   _error->RevertToStack();
-
-   return size;
-}
-									/*}}}*/
 
 
 // PackagesIndex::debPackagesIndex - Contructor				/*{{{*/
 // PackagesIndex::debPackagesIndex - Contructor				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-debPackagesIndex::debPackagesIndex(string const &URI, string const &Dist, string const &Section,
-					bool const &Trusted, string const &Arch) :
-                  pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section), Architecture(Arch)
+debPackagesIndex::debPackagesIndex(IndexTarget const &Target, bool const Trusted) :
+                  pkgIndexTargetFile(Target, Trusted)
 {
 {
-	if (Architecture == "native")
-		Architecture = _config->Find("APT::Architecture");
 }
 }
 									/*}}}*/
 									/*}}}*/
 // PackagesIndex::ArchiveInfo - Short version of the archive url	/*{{{*/
 // PackagesIndex::ArchiveInfo - Short version of the archive url	/*{{{*/
@@ -209,137 +93,42 @@ debPackagesIndex::debPackagesIndex(string const &URI, string const &Dist, string
 /* This is a shorter version that is designed to be < 60 chars or so */
 /* This is a shorter version that is designed to be < 60 chars or so */
 string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const
 string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const
 {
 {
-   string Res = ::URI::NoUserPassword(URI) + ' ';
-   if (Dist[Dist.size() - 1] == '/')
-   {
-      if (Dist != "/")
-	 Res += Dist;
-   }
-   else
-      Res += Dist + '/' + Section;
-   
+   std::string const Dist = Target.Option(IndexTarget::RELEASE);
+   string Res = Target.Option(IndexTarget::SITE) + " " + Dist;
+   std::string const Component = Target.Option(IndexTarget::COMPONENT);
+   if (Component.empty() == false)
+      Res += "/" + Component;
+
    Res += " ";
    Res += " ";
    Res += Ver.ParentPkg().Name();
    Res += Ver.ParentPkg().Name();
    Res += " ";
    Res += " ";
-   if (Dist[Dist.size() - 1] != '/')
+   if (Dist.empty() == false && Dist[Dist.size() - 1] != '/')
       Res.append(Ver.Arch()).append(" ");
       Res.append(Ver.Arch()).append(" ");
    Res += Ver.VerStr();
    Res += Ver.VerStr();
    return Res;
    return Res;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// PackagesIndex::Describe - Give a descriptive path to the index	/*{{{*/
-// ---------------------------------------------------------------------
-/* This should help the user find the index in the sources.list and
-   in the filesystem for problem solving */
-string debPackagesIndex::Describe(bool Short) const
-{   
-   char S[300];
-   if (Short == true)
-      snprintf(S,sizeof(S),"%s",Info("Packages").c_str());
-   else
-      snprintf(S,sizeof(S),"%s (%s)",Info("Packages").c_str(),
-	       IndexFile("Packages").c_str());
-   return S;
-}
-									/*}}}*/
-// PackagesIndex::Info - One liner describing the index URI		/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debPackagesIndex::Info(const char *Type) const 
-{
-   string Info = ::URI::NoUserPassword(URI) + ' ';
-   if (Dist[Dist.size() - 1] == '/')
-   {
-      if (Dist != "/")
-	 Info += Dist;
-   }
-   else
-      Info += Dist + '/' + Section;   
-   Info += " ";
-   if (Dist[Dist.size() - 1] != '/')
-      Info += Architecture + " ";
-   Info += Type;
-   return Info;
-}
-									/*}}}*/
-// PackagesIndex::Index* - Return the URI to the index files		/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debPackagesIndex::IndexFile(const char *Type) const
-{
-   string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type));
-
-   std::vector<std::string> types = APT::Configuration::getCompressionTypes();
-   for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
-   {
-      string p = s + '.' + *t;
-      if (FileExists(p))
-         return p;
-   }
-   return s;
-}
-string debPackagesIndex::IndexURI(const char *Type) const
-{
-   string Res;
-   if (Dist[Dist.size() - 1] == '/')
-   {
-      if (Dist != "/")
-	 Res = URI + Dist;
-      else 
-	 Res = URI;
-   }
-   else
-      Res = URI + "dists/" + Dist + '/' + Section +
-      "/binary-" + Architecture + '/';
-   
-   Res += Type;
-   return Res;
-}
-									/*}}}*/
-// PackagesIndex::Exists - Check if the index is available		/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool debPackagesIndex::Exists() const
-{
-   return FileExists(IndexFile("Packages"));
-}
-									/*}}}*/
-// PackagesIndex::Size - Return the size of the index			/*{{{*/
-// ---------------------------------------------------------------------
-/* This is really only used for progress reporting. */
-unsigned long debPackagesIndex::Size() const
-{
-   unsigned long size = 0;
-
-   /* we need to ignore errors here; if the lists are absent, just return 0 */
-   _error->PushToStack();
-
-   FileFd f(IndexFile("Packages"), FileFd::ReadOnly, FileFd::Extension);
-   if (!f.Failed())
-      size = f.Size();
-
-   if (_error->PendingError() == true)
-       size = 0;
-   _error->RevertToStack();
-
-   return size;
-}
-									/*}}}*/
 // PackagesIndex::Merge - Load the index file into a cache		/*{{{*/
 // PackagesIndex::Merge - Load the index file into a cache		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
 bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 {
 {
-   string PackageFile = IndexFile("Packages");
+   string const PackageFile = IndexFileName();
    FileFd Pkg(PackageFile,FileFd::ReadOnly, FileFd::Extension);
    FileFd Pkg(PackageFile,FileFd::ReadOnly, FileFd::Extension);
-   debListParser Parser(&Pkg, Architecture);
+   debListParser Parser(&Pkg, Target.Option(IndexTarget::ARCHITECTURE));
 
 
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
       return _error->Error("Problem opening %s",PackageFile.c_str());
       return _error->Error("Problem opening %s",PackageFile.c_str());
    if (Prog != NULL)
    if (Prog != NULL)
-      Prog->SubProgress(0,Info("Packages"));
+      Prog->SubProgress(0, Target.Description);
+
+
+   std::string const URI = Target.Option(IndexTarget::REPO_URI);
+   std::string Dist = Target.Option(IndexTarget::RELEASE);
+   if (Dist.empty())
+      Dist = "/";
    ::URI Tmp(URI);
    ::URI Tmp(URI);
-   if (Gen.SelectFile(PackageFile,Tmp.Host,*this) == false)
+   if (Gen.SelectFile(PackageFile, *this, Target.Option(IndexTarget::ARCHITECTURE), Target.Option(IndexTarget::COMPONENT)) == false)
       return _error->Error("Problem with SelectFile %s",PackageFile.c_str());
       return _error->Error("Problem with SelectFile %s",PackageFile.c_str());
 
 
    // Store the IMS information
    // Store the IMS information
@@ -347,31 +136,10 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
    pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(File);
    pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(File);
    File->Size = Pkg.FileSize();
    File->Size = Pkg.FileSize();
    File->mtime = Pkg.ModificationTime();
    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());
 
 
-   // Check the release file
-   string ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("InRelease");
-   bool releaseExists = false;
-   if (FileExists(ReleaseFile) == true)
-      releaseExists = true;
-   else
-      ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("Release");
-
-   if (releaseExists == true || FileExists(ReleaseFile) == true)
-   {
-      FileFd Rel;
-      // Beware: The 'Release' file might be clearsigned in case the
-      // signature for an 'InRelease' file couldn't be checked
-      if (OpenMaybeClearSignedFile(ReleaseFile, Rel) == false)
-	 return false;
-
-      if (_error->PendingError() == true)
-	 return false;
-      Parser.LoadReleaseInfo(File,Rel,Section);
-   }
-   
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -380,7 +148,7 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 /* */
 /* */
 pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const
 pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const
 {
 {
-   string FileName = IndexFile("Packages");
+   string const FileName = IndexFileName();
    pkgCache::PkgFileIterator File = Cache.FileBegin();
    pkgCache::PkgFileIterator File = Cache.FileBegin();
    for (; File.end() == false; ++File)
    for (; File.end() == false; ++File)
    {
    {
@@ -410,113 +178,13 @@ pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const
 									/*}}}*/
 									/*}}}*/
 
 
 // TranslationsIndex::debTranslationsIndex - Contructor			/*{{{*/
 // TranslationsIndex::debTranslationsIndex - Contructor			/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section,
-						char const * const Translation) :
-			pkgIndexFile(true), URI(URI), Dist(Dist), Section(Section),
-				Language(Translation)
+debTranslationsIndex::debTranslationsIndex(IndexTarget const &Target) :
+			pkgIndexTargetFile(Target, true)
 {}
 {}
 									/*}}}*/
 									/*}}}*/
-// TranslationIndex::Trans* - Return the URI to the translation files	/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debTranslationsIndex::IndexFile(const char *Type) const
-{
-   string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type));
-
-   std::vector<std::string> types = APT::Configuration::getCompressionTypes();
-   for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
-   {
-      string p = s + '.' + *t;
-      if (FileExists(p))
-         return p;
-   }
-   return s;
-}
-string debTranslationsIndex::IndexURI(const char *Type) const
-{
-   string Res;
-   if (Dist[Dist.size() - 1] == '/')
-   {
-      if (Dist != "/")
-	 Res = URI + Dist;
-      else 
-	 Res = URI;
-   }
-   else
-      Res = URI + "dists/" + Dist + '/' + Section +
-      "/i18n/Translation-";
-   
-   Res += Type;
-   return Res;
-}
-									/*}}}*/
-// TranslationsIndex::Describe - Give a descriptive path to the index	/*{{{*/
-// ---------------------------------------------------------------------
-/* This should help the user find the index in the sources.list and
-   in the filesystem for problem solving */
-string debTranslationsIndex::Describe(bool Short) const
-{   
-   char S[300];
-   if (Short == true)
-      snprintf(S,sizeof(S),"%s",Info(TranslationFile().c_str()).c_str());
-   else
-      snprintf(S,sizeof(S),"%s (%s)",Info(TranslationFile().c_str()).c_str(),
-	       IndexFile(Language).c_str());
-   return S;
-}
-									/*}}}*/
-// TranslationsIndex::Info - One liner describing the index URI		/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debTranslationsIndex::Info(const char *Type) const 
-{
-   string Info = ::URI::NoUserPassword(URI) + ' ';
-   if (Dist[Dist.size() - 1] == '/')
-   {
-      if (Dist != "/")
-	 Info += Dist;
-   }
-   else
-      Info += Dist + '/' + Section;   
-   Info += " ";
-   Info += Type;
-   return Info;
-}
-									/*}}}*/
 bool debTranslationsIndex::HasPackages() const				/*{{{*/
 bool debTranslationsIndex::HasPackages() const				/*{{{*/
 {
 {
-   return FileExists(IndexFile(Language));
-}
-									/*}}}*/
-// TranslationsIndex::Exists - Check if the index is available		/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool debTranslationsIndex::Exists() const
-{
-   return FileExists(IndexFile(Language));
-}
-									/*}}}*/
-// TranslationsIndex::Size - Return the size of the index		/*{{{*/
-// ---------------------------------------------------------------------
-/* This is really only used for progress reporting. */
-unsigned long debTranslationsIndex::Size() const
-{
-   unsigned long size = 0;
-
-   /* we need to ignore errors here; if the lists are absent, just return 0 */
-   _error->PushToStack();
-
-   FileFd f(IndexFile(Language), FileFd::ReadOnly, FileFd::Extension);
-   if (!f.Failed())
-      size = f.Size();
-
-   if (_error->PendingError() == true)
-       size = 0;
-   _error->RevertToStack();
-
-   return size;
+   return Exists();
 }
 }
 									/*}}}*/
 									/*}}}*/
 // TranslationsIndex::Merge - Load the index file into a cache		/*{{{*/
 // TranslationsIndex::Merge - Load the index file into a cache		/*{{{*/
@@ -525,24 +193,24 @@ unsigned long debTranslationsIndex::Size() const
 bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 {
 {
    // Check the translation file, if in use
    // Check the translation file, if in use
-   string TranslationFile = IndexFile(Language);
+   string const TranslationFile = IndexFileName();
    if (FileExists(TranslationFile))
    if (FileExists(TranslationFile))
    {
    {
      FileFd Trans(TranslationFile,FileFd::ReadOnly, FileFd::Extension);
      FileFd Trans(TranslationFile,FileFd::ReadOnly, FileFd::Extension);
      debTranslationsParser TransParser(&Trans);
      debTranslationsParser TransParser(&Trans);
      if (_error->PendingError() == true)
      if (_error->PendingError() == true)
        return false;
        return false;
-     
+
      if (Prog != NULL)
      if (Prog != NULL)
-	Prog->SubProgress(0, Info(TranslationFile.c_str()));
-     if (Gen.SelectFile(TranslationFile,string(),*this) == false)
+	Prog->SubProgress(0, Target.Description);
+     if (Gen.SelectFile(TranslationFile, *this, "", Target.Option(IndexTarget::COMPONENT), pkgCache::Flag::NotSource | pkgCache::Flag::NoPackages) == false)
        return _error->Error("Problem with SelectFile %s",TranslationFile.c_str());
        return _error->Error("Problem with SelectFile %s",TranslationFile.c_str());
 
 
      // Store the IMS information
      // Store the IMS information
      pkgCache::PkgFileIterator TransFile = Gen.GetCurFile();
      pkgCache::PkgFileIterator TransFile = Gen.GetCurFile();
      TransFile->Size = Trans.FileSize();
      TransFile->Size = Trans.FileSize();
      TransFile->mtime = Trans.ModificationTime();
      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());
    }
    }
@@ -555,8 +223,8 @@ bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 /* */
 /* */
 pkgCache::PkgFileIterator debTranslationsIndex::FindInCache(pkgCache &Cache) const
 pkgCache::PkgFileIterator debTranslationsIndex::FindInCache(pkgCache &Cache) const
 {
 {
-   string FileName = IndexFile(Language);
-   
+   string FileName = IndexFileName();
+
    pkgCache::PkgFileIterator File = Cache.FileBegin();
    pkgCache::PkgFileIterator File = Cache.FileBegin();
    for (; File.end() == false; ++File)
    for (; File.end() == false; ++File)
    {
    {
@@ -579,10 +247,11 @@ pkgCache::PkgFileIterator debTranslationsIndex::FindInCache(pkgCache &Cache) con
 	 return pkgCache::PkgFileIterator(Cache);
 	 return pkgCache::PkgFileIterator(Cache);
       }
       }
       return File;
       return File;
-   }   
+   }
    return File;
    return File;
 }
 }
 									/*}}}*/
 									/*}}}*/
+
 // StatusIndex::debStatusIndex - Constructor				/*{{{*/
 // StatusIndex::debStatusIndex - Constructor				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -615,18 +284,17 @@ bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 
 
    if (Prog != NULL)
    if (Prog != NULL)
       Prog->SubProgress(0,File);
       Prog->SubProgress(0,File);
-   if (Gen.SelectFile(File,string(),*this,pkgCache::Flag::NotSource) == false)
+   if (Gen.SelectFile(File, *this, "", "now", pkgCache::Flag::NotSource) == false)
       return _error->Error("Problem with SelectFile %s",File.c_str());
       return _error->Error("Problem with SelectFile %s",File.c_str());
 
 
    // Store the IMS information
    // Store the IMS information
    pkgCache::PkgFileIterator CFile = Gen.GetCurFile();
    pkgCache::PkgFileIterator CFile = Gen.GetCurFile();
+   pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(CFile);
    CFile->Size = Pkg.FileSize();
    CFile->Size = Pkg.FileSize();
    CFile->mtime = Pkg.ModificationTime();
    CFile->mtime = Pkg.ModificationTime();
-   map_stringitem_t const storage = Gen.StoreString(pkgCacheGenerator::MIXED, "now");
-   CFile->Archive = storage;
-   
+
    if (Gen.MergeList(Parser) == false)
    if (Gen.MergeList(Parser) == false)
-      return _error->Error("Problem with MergeList %s",File.c_str());   
+      return _error->Error("Problem with MergeList %s",File.c_str());
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -671,8 +339,7 @@ APT_CONST bool debStatusIndex::Exists() const
 }
 }
 									/*}}}*/
 									/*}}}*/
 
 
-// debDebPkgFile - Single .deb file                           		/*{{{*/
-// ---------------------------------------------------------------------
+// debDebPkgFile - Single .deb file					/*{{{*/
 debDebPkgFileIndex::debDebPkgFileIndex(std::string DebFile)
 debDebPkgFileIndex::debDebPkgFileIndex(std::string DebFile)
    : pkgIndexFile(true), DebFile(DebFile)
    : pkgIndexFile(true), DebFile(DebFile)
 {
 {
@@ -688,64 +355,67 @@ bool debDebPkgFileIndex::Exists() const
 {
 {
    return FileExists(DebFile);
    return FileExists(DebFile);
 }
 }
-bool debDebPkgFileIndex::Merge(pkgCacheGenerator& Gen, OpProgress* Prog) const
+bool debDebPkgFileIndex::GetContent(std::ostream &content, std::string const &debfile)
 {
 {
-   if(Prog)
-      Prog->SubProgress(0, "Reading deb file");
-
-   // get the control data out of the deb file vid dpkg -I
-   // ... can I haz libdpkg?
-   Configuration::Item const *Opts = _config->Tree("DPkg::Options");
-   std::string dpkg = _config->Find("Dir::Bin::dpkg","dpkg");
+   // get the control data out of the deb file via dpkg-deb -I
+   std::string dpkg = _config->Find("Dir::Bin::dpkg","dpkg-deb");
    std::vector<const char *> Args;
    std::vector<const char *> Args;
    Args.push_back(dpkg.c_str());
    Args.push_back(dpkg.c_str());
-   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("-I");
    Args.push_back("-I");
-   Args.push_back(DebFile.c_str());
+   Args.push_back(debfile.c_str());
    Args.push_back("control");
    Args.push_back("control");
    Args.push_back(NULL);
    Args.push_back(NULL);
    FileFd PipeFd;
    FileFd PipeFd;
    pid_t Child;
    pid_t Child;
    if(Popen((const char**)&Args[0], PipeFd, Child, FileFd::ReadOnly) == false)
    if(Popen((const char**)&Args[0], PipeFd, Child, FileFd::ReadOnly) == false)
       return _error->Error("Popen failed");
       return _error->Error("Popen failed");
-   // FIXME: static buffer
-   char buf[8*1024];
-   unsigned long long n = 0;
-   if(PipeFd.Read(buf, sizeof(buf)-1, &n) == false)
-      return _error->Errno("read", "Failed to read dpkg pipe");
+
+   char buffer[1024];
+   do {
+      unsigned long long actual = 0;
+      if (PipeFd.Read(buffer, sizeof(buffer)-1, &actual) == false)
+	 return _error->Errno("read", "Failed to read dpkg pipe");
+      if (actual == 0)
+	 break;
+      buffer[actual] = '\0';
+      content << buffer;
+   } while(true);
    ExecWait(Child, "Popen");
    ExecWait(Child, "Popen");
 
 
-   // now write the control data to a tempfile
+   content << "Filename: " << debfile << "\n";
+   struct stat Buf;
+   if (stat(debfile.c_str(), &Buf) != 0)
+      return false;
+   content << "Size: " << Buf.st_size << "\n";
+
+   return true;
+}
+bool debDebPkgFileIndex::Merge(pkgCacheGenerator& Gen, OpProgress* Prog) const
+{
+   if(Prog)
+      Prog->SubProgress(0, "Reading deb file");
+
+   // write the control data to a tempfile
    SPtr<FileFd> DebControl = GetTempFile("deb-file-" + flNotDir(DebFile));
    SPtr<FileFd> DebControl = GetTempFile("deb-file-" + flNotDir(DebFile));
    if(DebControl == NULL)
    if(DebControl == NULL)
       return false;
       return false;
-   DebControl->Write(buf, n);
-   // append size of the file
-   FileFd Fd(DebFile, FileFd::ReadOnly);
-   string Size;
-   strprintf(Size, "Size: %llu\n", Fd.Size());
-   DebControl->Write(Size.c_str(), Size.size());
-   // and rewind for the listparser
+   std::ostringstream content;
+   if (GetContent(content, DebFile) == false)
+      return false;
+   std::string const contentstr = content.str();
+   DebControl->Write(contentstr.c_str(), contentstr.length());
+   // rewind for the listparser
    DebControl->Seek(0);
    DebControl->Seek(0);
 
 
    // and give it to the list parser
    // and give it to the list parser
    debDebFileParser Parser(DebControl, DebFile);
    debDebFileParser Parser(DebControl, DebFile);
-   if(Gen.SelectFile(DebFile, "local", *this) == false)
+   if(Gen.SelectFile(DebFile, *this, "", "now", pkgCache::Flag::LocalSource) == false)
       return _error->Error("Problem with SelectFile %s", DebFile.c_str());
       return _error->Error("Problem with SelectFile %s", DebFile.c_str());
 
 
    pkgCache::PkgFileIterator File = Gen.GetCurFile();
    pkgCache::PkgFileIterator File = Gen.GetCurFile();
    File->Size = DebControl->Size();
    File->Size = DebControl->Size();
    File->mtime = DebControl->ModificationTime();
    File->mtime = DebControl->ModificationTime();
-   
+
    if (Gen.MergeList(Parser) == false)
    if (Gen.MergeList(Parser) == false)
       return _error->Error("Problem with MergeLister for %s", DebFile.c_str());
       return _error->Error("Problem with MergeLister for %s", DebFile.c_str());
 
 
@@ -802,13 +472,13 @@ pkgSrcRecords::Parser *debDscFileIndex::CreateSrcParser() const
 }
 }
 									/*}}}*/
 									/*}}}*/
 // Index File types for Debian						/*{{{*/
 // Index File types for Debian						/*{{{*/
-class debIFTypeSrc : public pkgIndexFile::Type
+class APT_HIDDEN debIFTypeSrc : public pkgIndexFile::Type
 {
 {
    public:
    public:
    
    
    debIFTypeSrc() {Label = "Debian Source Index";};
    debIFTypeSrc() {Label = "Debian Source Index";};
 };
 };
-class debIFTypePkg : public pkgIndexFile::Type
+class APT_HIDDEN debIFTypePkg : public pkgIndexFile::Type
 {
 {
    public:
    public:
    
    
@@ -818,12 +488,12 @@ class debIFTypePkg : public pkgIndexFile::Type
    };
    };
    debIFTypePkg() {Label = "Debian Package Index";};
    debIFTypePkg() {Label = "Debian Package Index";};
 };
 };
-class debIFTypeTrans : public debIFTypePkg
+class APT_HIDDEN debIFTypeTrans : public debIFTypePkg
 {
 {
    public:
    public:
    debIFTypeTrans() {Label = "Debian Translation Index";};
    debIFTypeTrans() {Label = "Debian Translation Index";};
 };
 };
-class debIFTypeStatus : public pkgIndexFile::Type
+class APT_HIDDEN debIFTypeStatus : public pkgIndexFile::Type
 {
 {
    public:
    public:
    
    
@@ -833,16 +503,16 @@ class debIFTypeStatus : public pkgIndexFile::Type
    };
    };
    debIFTypeStatus() {Label = "Debian dpkg status file";};
    debIFTypeStatus() {Label = "Debian dpkg status file";};
 };
 };
-class debIFTypeDebPkgFile : public pkgIndexFile::Type
+class APT_HIDDEN debIFTypeDebPkgFile : public pkgIndexFile::Type
 {
 {
    public:
    public:
    virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const 
    virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const 
    {
    {
-      return new debDebFileRecordParser(File.FileName(),*File.Cache());
+      return new debDebFileRecordParser(File.FileName());
    };
    };
    debIFTypeDebPkgFile() {Label = "deb Package file";};
    debIFTypeDebPkgFile() {Label = "deb Package file";};
 };
 };
-class debIFTypeDscFile : public pkgIndexFile::Type
+class APT_HIDDEN debIFTypeDscFile : public pkgIndexFile::Type
 {
 {
    public:
    public:
    virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string DscFile) const
    virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string DscFile) const
@@ -851,7 +521,7 @@ class debIFTypeDscFile : public pkgIndexFile::Type
    };
    };
    debIFTypeDscFile() {Label = "dsc File Source Index";};
    debIFTypeDscFile() {Label = "dsc File Source Index";};
 };
 };
-class debIFTypeDebianSourceDir : public pkgIndexFile::Type
+class APT_HIDDEN debIFTypeDebianSourceDir : public pkgIndexFile::Type
 {
 {
    public:
    public:
    virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string SourceDir) const
    virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string SourceDir) const
@@ -861,14 +531,14 @@ class debIFTypeDebianSourceDir : public pkgIndexFile::Type
    debIFTypeDebianSourceDir() {Label = "debian/control File Source Index";};
    debIFTypeDebianSourceDir() {Label = "debian/control File Source Index";};
 };
 };
 
 
-static debIFTypeSrc _apt_Src;
-static debIFTypePkg _apt_Pkg;
-static debIFTypeTrans _apt_Trans;
-static debIFTypeStatus _apt_Status;
-static debIFTypeDebPkgFile _apt_DebPkgFile;
+APT_HIDDEN debIFTypeSrc _apt_Src;
+APT_HIDDEN debIFTypePkg _apt_Pkg;
+APT_HIDDEN debIFTypeTrans _apt_Trans;
+APT_HIDDEN debIFTypeStatus _apt_Status;
+APT_HIDDEN debIFTypeDebPkgFile _apt_DebPkgFile;
 // file based pseudo indexes
 // file based pseudo indexes
-static debIFTypeDscFile _apt_DscFile;
-static debIFTypeDebianSourceDir _apt_DebianSourceDir;
+APT_HIDDEN debIFTypeDscFile _apt_DscFile;
+APT_HIDDEN debIFTypeDebianSourceDir _apt_DebianSourceDir;
 
 
 const pkgIndexFile::Type *debSourcesIndex::GetType() const
 const pkgIndexFile::Type *debSourcesIndex::GetType() const
 {
 {
@@ -906,3 +576,4 @@ debTranslationsIndex::~debTranslationsIndex() {}
 debSourcesIndex::~debSourcesIndex() {}
 debSourcesIndex::~debSourcesIndex() {}
 
 
 debDebPkgFileIndex::~debDebPkgFileIndex() {}
 debDebPkgFileIndex::~debDebPkgFileIndex() {}
+debDscFileIndex::~debDscFileIndex() {}

+ 28 - 75
apt-pkg/deb/debindexfile.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: debindexfile.h,v 1.3.2.1 2003/12/24 23:09:17 mdz Exp $
 /* ######################################################################
 /* ######################################################################
 
 
    Debian Index Files
    Debian Index Files
@@ -28,117 +27,68 @@ class pkgAcquire;
 class pkgCacheGenerator;
 class pkgCacheGenerator;
 
 
 
 
-class debStatusIndex : public pkgIndexFile
+class APT_HIDDEN debStatusIndex : public pkgIndexFile
 {
 {
-   /** \brief dpointer placeholder (for later in case we need it) */
    void *d;
    void *d;
-
    protected:
    protected:
    std::string File;
    std::string File;
 
 
    public:
    public:
 
 
    virtual const Type *GetType() const APT_CONST;
    virtual const Type *GetType() const APT_CONST;
-   
+
    // Interface for acquire
    // Interface for acquire
    virtual std::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(std::string File);
    debStatusIndex(std::string File);
    virtual ~debStatusIndex();
    virtual ~debStatusIndex();
 };
 };
-    
-class debPackagesIndex : public pkgIndexFile
+
+class APT_HIDDEN debPackagesIndex : public pkgIndexTargetFile
 {
 {
-   /** \brief dpointer placeholder (for later in case we need it) */
    void *d;
    void *d;
-
-   std::string URI;
-   std::string Dist;
-   std::string Section;
-   std::string Architecture;
-
-   APT_HIDDEN std::string Info(const char *Type) const;
-   APT_HIDDEN std::string IndexFile(const char *Type) const;
-   APT_HIDDEN std::string IndexURI(const char *Type) const;
-
    public:
    public:
-   
+
    virtual const Type *GetType() const APT_CONST;
    virtual const Type *GetType() const APT_CONST;
 
 
    // Stuff for accessing files on remote items
    // Stuff for accessing files on remote items
    virtual std::string ArchiveInfo(pkgCache::VerIterator Ver) const;
    virtual std::string ArchiveInfo(pkgCache::VerIterator Ver) const;
-   virtual std::string ArchiveURI(std::string File) const {return URI + File;};
-   
-   // Interface for acquire
-   virtual std::string Describe(bool Short) const;   
-   
+
    // Interface for the Cache Generator
    // Interface for the Cache Generator
-   virtual bool Exists() const;
    virtual bool HasPackages() const {return true;};
    virtual bool HasPackages() const {return true;};
-   virtual unsigned long Size() const;
    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(std::string const &URI, std::string const &Dist, std::string const &Section,
-			bool const &Trusted, std::string const &Arch = "native");
+   debPackagesIndex(IndexTarget const &Target, bool const Trusted);
    virtual ~debPackagesIndex();
    virtual ~debPackagesIndex();
 };
 };
 
 
-class debTranslationsIndex : public pkgIndexFile
+class APT_HIDDEN debTranslationsIndex : public pkgIndexTargetFile
 {
 {
-   /** \brief dpointer placeholder (for later in case we need it) */
    void *d;
    void *d;
-
-   std::string URI;
-   std::string Dist;
-   std::string Section;
-   const char * const Language;
-   
-   APT_HIDDEN std::string Info(const char *Type) const;
-   APT_HIDDEN std::string IndexFile(const char *Type) const;
-   APT_HIDDEN std::string IndexURI(const char *Type) const;
-
-   APT_HIDDEN std::string TranslationFile() const {return std::string("Translation-").append(Language);};
-
    public:
    public:
-   
+
    virtual const Type *GetType() const APT_CONST;
    virtual const Type *GetType() const APT_CONST;
 
 
-   // Interface for acquire
-   virtual std::string Describe(bool Short) const;   
-   
    // Interface for the Cache Generator
    // Interface for the Cache Generator
-   virtual bool Exists() const;
    virtual bool HasPackages() const;
    virtual bool HasPackages() const;
-   virtual unsigned long Size() const;
    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(std::string URI,std::string Dist,std::string Section, char const * const Language);
+   debTranslationsIndex(IndexTarget const &Target);
    virtual ~debTranslationsIndex();
    virtual ~debTranslationsIndex();
 };
 };
 
 
-class debSourcesIndex : public pkgIndexFile
+class APT_HIDDEN debSourcesIndex : public pkgIndexTargetFile
 {
 {
-   /** \brief dpointer placeholder (for later in case we need it) */
    void *d;
    void *d;
-
-   std::string URI;
-   std::string Dist;
-   std::string Section;
-
-   APT_HIDDEN std::string Info(const char *Type) const;
-   APT_HIDDEN std::string IndexFile(const char *Type) const;
-   APT_HIDDEN std::string IndexURI(const char *Type) const;
-
    public:
    public:
 
 
    virtual const Type *GetType() const APT_CONST;
    virtual const Type *GetType() const APT_CONST;
@@ -146,24 +96,18 @@ class debSourcesIndex : public pkgIndexFile
    // Stuff for accessing files on remote items
    // Stuff for accessing files on remote items
    virtual std::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 std::string ArchiveURI(std::string File) const {return URI + File;};
-   
-   // Interface for acquire
-   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;
-   
+
    // Interface for the Cache Generator
    // Interface for the Cache Generator
-   virtual bool Exists() const;
    virtual bool HasPackages() const {return false;};
    virtual bool HasPackages() const {return false;};
-   virtual unsigned long Size() const;
-   
-   debSourcesIndex(std::string URI,std::string Dist,std::string Section,bool Trusted);
+
+   debSourcesIndex(IndexTarget const &Target, bool const Trusted);
    virtual ~debSourcesIndex();
    virtual ~debSourcesIndex();
 };
 };
 
 
-class debDebPkgFileIndex : public pkgIndexFile
+class APT_HIDDEN debDebPkgFileIndex : public pkgIndexFile
 {
 {
  private:
  private:
    void *d;
    void *d;
@@ -177,6 +121,14 @@ class debDebPkgFileIndex : public pkgIndexFile
       return DebFile;
       return DebFile;
    }
    }
 
 
+   /** get the control (file) content of the deb file
+    *
+    * @param[out] content of the control file
+    * @param debfile is the filename of the .deb-file
+    * @return \b true if successful, otherwise \b false.
+    */
+   static bool GetContent(std::ostream &content, std::string const &debfile);
+
    // Interface for the Cache Generator
    // Interface for the Cache Generator
    virtual bool Exists() const;
    virtual bool Exists() const;
    virtual bool HasPackages() const {
    virtual bool HasPackages() const {
@@ -193,9 +145,10 @@ class debDebPkgFileIndex : public pkgIndexFile
    virtual ~debDebPkgFileIndex();
    virtual ~debDebPkgFileIndex();
 };
 };
 
 
-class debDscFileIndex : public pkgIndexFile
+class APT_HIDDEN debDscFileIndex : public pkgIndexFile
 {
 {
  private:
  private:
+   void *d;
    std::string DscFile;
    std::string DscFile;
  public:
  public:
    virtual const Type *GetType() const APT_CONST;
    virtual const Type *GetType() const APT_CONST;
@@ -208,10 +161,10 @@ class debDscFileIndex : public pkgIndexFile
    };
    };
 
 
    debDscFileIndex(std::string &DscFile);
    debDscFileIndex(std::string &DscFile);
-   virtual ~debDscFileIndex() {};
+   virtual ~debDscFileIndex();
 };
 };
 
 
-class debDebianSourceDirIndex : public debDscFileIndex
+class APT_HIDDEN debDebianSourceDirIndex : public debDscFileIndex
 {
 {
  public:
  public:
    virtual const Type *GetType() const APT_CONST;
    virtual const Type *GetType() const APT_CONST;

+ 10 - 39
apt-pkg/deb/deblistparser.cc

@@ -141,6 +141,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver)
       map_stringitem_t const idx = StoreString(pkgCacheGenerator::SECTION, Start, Stop - Start);
       map_stringitem_t const idx = StoreString(pkgCacheGenerator::SECTION, Start, Stop - Start);
       Ver->Section = idx;
       Ver->Section = idx;
    }
    }
+#if APT_PKG_ABI >= 413
    // Parse the source package name
    // Parse the source package name
    pkgCache::GrpIterator const G = Ver.ParentPkg().Group();
    pkgCache::GrpIterator const G = Ver.ParentPkg().Group();
    Ver->SourcePkgName = G->Name;
    Ver->SourcePkgName = G->Name;
@@ -192,6 +193,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver)
 	 }
 	 }
       }
       }
    }
    }
+#endif
 
 
    Ver->MultiArch = ParseMultiArch(true);
    Ver->MultiArch = ParseMultiArch(true);
    // Archive Size
    // Archive Size
@@ -804,7 +806,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
 	 if (NewDepends(Ver,Package,"none",Version,Op,Type) == false)
 	 if (NewDepends(Ver,Package,"none",Version,Op,Type) == false)
 	    return false;
 	    return false;
       }
       }
-      else if (MultiArchEnabled == true && found != string::npos &&
+      else if (found != string::npos &&
 	       strcmp(Package.c_str() + found, ":any") != 0)
 	       strcmp(Package.c_str() + found, ":any") != 0)
       {
       {
 	 string Arch = Package.substr(found+1, string::npos);
 	 string Arch = Package.substr(found+1, string::npos);
@@ -851,10 +853,16 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
       while (1)
       while (1)
       {
       {
 	 Start = ParseDepends(Start,Stop,Package,Version,Op);
 	 Start = ParseDepends(Start,Stop,Package,Version,Op);
+	 const size_t archfound = Package.rfind(':');
 	 if (Start == 0)
 	 if (Start == 0)
 	    return _error->Error("Problem parsing Provides line");
 	    return _error->Error("Problem parsing Provides line");
 	 if (Op != pkgCache::Dep::NoOp && Op != pkgCache::Dep::Equals) {
 	 if (Op != pkgCache::Dep::NoOp && Op != pkgCache::Dep::Equals) {
 	    _error->Warning("Ignoring Provides line with non-equal DepCompareOp for package %s", Package.c_str());
 	    _error->Warning("Ignoring Provides line with non-equal DepCompareOp for package %s", Package.c_str());
+	 } else if (archfound != string::npos) {
+	    string OtherArch = Package.substr(archfound+1, string::npos);
+	    Package = Package.substr(0, archfound);
+	    if (NewProvides(Ver, Package, OtherArch, Version) == false)
+	       return false;
 	 } else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) {
 	 } else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) {
 	    if (NewProvidesAllArch(Ver, Package, Version) == false)
 	    if (NewProvidesAllArch(Ver, Package, Version) == false)
 	       return false;
 	       return false;
@@ -943,43 +951,6 @@ bool debListParser::Step()
    return false;
    return false;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// ListParser::LoadReleaseInfo - Load the release information		/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
-				    FileFd &File, string component)
-{
-   // apt-secure does no longer download individual (per-section) Release
-   // file. to provide Component pinning we use the section name now
-   map_stringitem_t const storage = StoreString(pkgCacheGenerator::MIXED, component);
-   FileI->Component = storage;
-
-   pkgTagFile TagFile(&File, File.Size());
-   pkgTagSection Section;
-   if (_error->PendingError() == true || TagFile.Step(Section) == false)
-      return false;
-
-   std::string data;
-   #define APT_INRELEASE(TYPE, TAG, STORE) \
-   data = Section.FindS(TAG); \
-   if (data.empty() == false) \
-   { \
-      map_stringitem_t const storage = StoreString(pkgCacheGenerator::TYPE, data); \
-      STORE = storage; \
-   }
-   APT_INRELEASE(MIXED, "Suite", FileI->Archive)
-   APT_INRELEASE(MIXED, "Component", FileI->Component)
-   APT_INRELEASE(VERSIONNUMBER, "Version", FileI->Version)
-   APT_INRELEASE(MIXED, "Origin", FileI->Origin)
-   APT_INRELEASE(MIXED, "Codename", FileI->Codename)
-   APT_INRELEASE(MIXED, "Label", FileI->Label)
-   #undef APT_INRELEASE
-   Section.FindFlag("NotAutomatic", FileI->Flags, pkgCache::Flag::NotAutomatic);
-   Section.FindFlag("ButAutomaticUpgrades", FileI->Flags, pkgCache::Flag::ButAutomaticUpgrades);
-
-   return !_error->PendingError();
-}
-									/*}}}*/
 // ListParser::GetPrio - Convert the priority from a string		/*{{{*/
 // ListParser::GetPrio - Convert the priority from a string		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -992,7 +963,7 @@ unsigned char debListParser::GetPrio(string Str)
    return Out;
    return Out;
 }
 }
 									/*}}}*/
 									/*}}}*/
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+#if APT_PKG_ABI >= 413
 bool debListParser::SameVersion(unsigned short const Hash,		/*{{{*/
 bool debListParser::SameVersion(unsigned short const Hash,		/*{{{*/
       pkgCache::VerIterator const &Ver)
       pkgCache::VerIterator const &Ver)
 {
 {

+ 13 - 13
apt-pkg/deb/deblistparser.h

@@ -26,7 +26,7 @@
 
 
 class FileFd;
 class FileFd;
 
 
-class debListParser : public pkgCacheGenerator::ListParser
+class APT_HIDDEN debListParser : public pkgCacheGenerator::ListParser
 {
 {
    public:
    public:
 
 
@@ -59,7 +59,7 @@ class debListParser : public pkgCacheGenerator::ListParser
 
 
    public:
    public:
 
 
-   static unsigned char GetPrio(std::string Str);
+   APT_PUBLIC static unsigned char GetPrio(std::string Str);
       
       
    // These all operate against the current section
    // These all operate against the current section
    virtual std::string Package();
    virtual std::string Package();
@@ -71,7 +71,7 @@ class debListParser : public pkgCacheGenerator::ListParser
    virtual std::vector<std::string> AvailableDescriptionLanguages();
    virtual std::vector<std::string> AvailableDescriptionLanguages();
    virtual MD5SumValue Description_md5();
    virtual MD5SumValue Description_md5();
    virtual unsigned short VersionHash();
    virtual unsigned short VersionHash();
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+#if APT_PKG_ABI >= 413
    virtual bool SameVersion(unsigned short const Hash, pkgCache::VerIterator const &Ver);
    virtual bool SameVersion(unsigned short const Hash, pkgCache::VerIterator const &Ver);
 #endif
 #endif
    virtual bool UsePackage(pkgCache::PkgIterator &Pkg,
    virtual bool UsePackage(pkgCache::PkgIterator &Pkg,
@@ -80,30 +80,30 @@ class debListParser : public pkgCacheGenerator::ListParser
    virtual map_filesize_t Size() {return Section.size();};
    virtual map_filesize_t Size() {return Section.size();};
 
 
    virtual bool Step();
    virtual bool Step();
-   
-   bool LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,FileFd &File,
-			std::string section);
 
 
-   static const char *ParseDepends(const char *Start,const char *Stop,
+   bool LoadReleaseInfo(pkgCache::RlsFileIterator &FileI,FileFd &File,
+			std::string const &section);
+
+   APT_PUBLIC static const char *ParseDepends(const char *Start,const char *Stop,
 	 std::string &Package,std::string &Ver,unsigned int &Op);
 	 std::string &Package,std::string &Ver,unsigned int &Op);
-   static const char *ParseDepends(const char *Start,const char *Stop,
+   APT_PUBLIC static const char *ParseDepends(const char *Start,const char *Stop,
 	 std::string &Package,std::string &Ver,unsigned int &Op,
 	 std::string &Package,std::string &Ver,unsigned int &Op,
 	 bool const &ParseArchFlags);
 	 bool const &ParseArchFlags);
-   static const char *ParseDepends(const char *Start,const char *Stop,
+   APT_PUBLIC static const char *ParseDepends(const char *Start,const char *Stop,
 	 std::string &Package,std::string &Ver,unsigned int &Op,
 	 std::string &Package,std::string &Ver,unsigned int &Op,
 	 bool const &ParseArchFlags, bool const &StripMultiArch);
 	 bool const &ParseArchFlags, bool const &StripMultiArch);
-   static const char *ParseDepends(const char *Start,const char *Stop,
+   APT_PUBLIC static const char *ParseDepends(const char *Start,const char *Stop,
 	 std::string &Package,std::string &Ver,unsigned int &Op,
 	 std::string &Package,std::string &Ver,unsigned int &Op,
 	 bool const &ParseArchFlags, bool const &StripMultiArch,
 	 bool const &ParseArchFlags, bool const &StripMultiArch,
 	 bool const &ParseRestrictionsList);
 	 bool const &ParseRestrictionsList);
 
 
-   static const char *ConvertRelation(const char *I,unsigned int &Op);
+   APT_PUBLIC static const char *ConvertRelation(const char *I,unsigned int &Op);
 
 
    debListParser(FileFd *File, std::string const &Arch = "");
    debListParser(FileFd *File, std::string const &Arch = "");
    virtual ~debListParser();
    virtual ~debListParser();
 };
 };
 
 
-class debDebFileParser : public debListParser
+class APT_HIDDEN debDebFileParser : public debListParser
 {
 {
  private:
  private:
    std::string DebFile;
    std::string DebFile;
@@ -114,7 +114,7 @@ class debDebFileParser : public debListParser
 			   pkgCache::VerIterator &Ver);
 			   pkgCache::VerIterator &Ver);
 };
 };
 
 
-class debTranslationsParser : public debListParser
+class APT_HIDDEN debTranslationsParser : public debListParser
 {
 {
  public:
  public:
    // a translation can never be a real package
    // a translation can never be a real package

+ 333 - 269
apt-pkg/deb/debmetaindex.cc

@@ -1,5 +1,6 @@
 #include <config.h>
 #include <config.h>
 
 
+#include <apt-pkg/error.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>
@@ -10,10 +11,12 @@
 #include <apt-pkg/indexrecords.h>
 #include <apt-pkg/indexrecords.h>
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/hashes.h>
 #include <apt-pkg/hashes.h>
-#include <apt-pkg/macros.h>
 #include <apt-pkg/metaindex.h>
 #include <apt-pkg/metaindex.h>
+#include <apt-pkg/pkgcachegen.h>
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/gpgv.h>
+#include <apt-pkg/macros.h>
 
 
-#include <string.h>
 #include <map>
 #include <map>
 #include <string>
 #include <string>
 #include <utility>
 #include <utility>
@@ -21,30 +24,16 @@
 #include <set>
 #include <set>
 #include <algorithm>
 #include <algorithm>
 
 
-using namespace std;
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
 
 
-string debReleaseIndex::Info(const char *Type, string const &Section, string const &Arch) const
-{
-   string Info = ::URI::SiteOnly(URI) + ' ';
-   if (Dist[Dist.size() - 1] == '/')
-   {
-      if (Dist != "/")
-         Info += Dist;
-   }
-   else
-   {
-      Info += Dist + '/' + Section;
-      if (Arch.empty() != true)
-	 Info += " " + Arch;
-   }
-   Info += " ";
-   Info += Type;
-   return Info;
-}
+using namespace std;
 
 
 string debReleaseIndex::MetaIndexInfo(const char *Type) const
 string debReleaseIndex::MetaIndexInfo(const char *Type) const
 {
 {
-   string Info = ::URI::SiteOnly(URI) + ' ';
+   string Info = ::URI::ArchiveOnly(URI) + ' ';
    if (Dist[Dist.size() - 1] == '/')
    if (Dist[Dist.size() - 1] == '/')
    {
    {
       if (Dist != "/")
       if (Dist != "/")
@@ -56,6 +45,10 @@ string debReleaseIndex::MetaIndexInfo(const char *Type) const
    Info += Type;
    Info += Type;
    return Info;
    return Info;
 }
 }
+std::string debReleaseIndex::Describe() const
+{
+   return MetaIndexInfo("Release");
+}
 
 
 string debReleaseIndex::MetaIndexFile(const char *Type) const
 string debReleaseIndex::MetaIndexFile(const char *Type) const
 {
 {
@@ -78,7 +71,6 @@ string debReleaseIndex::MetaIndexURI(const char *Type) const
    return Res;
    return Res;
 }
 }
 
 
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
 std::string debReleaseIndex::LocalFileName() const
 std::string debReleaseIndex::LocalFileName() const
 {
 {
    // see if we have a InRelease file
    // see if we have a InRelease file
@@ -92,167 +84,183 @@ std::string debReleaseIndex::LocalFileName() const
 
 
    return "";
    return "";
 }
 }
-#endif
 
 
-string debReleaseIndex::IndexURISuffix(const char *Type, string const &Section, string const &Arch) const
-{
-   string Res ="";
-   if (Dist[Dist.size() - 1] != '/')
-   {
-      if (Arch == "native")
-	 Res += Section + "/binary-" + _config->Find("APT::Architecture") + '/';
-      else
-	 Res += Section + "/binary-" + Arch + '/';
-   }
-   return Res + Type;
+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() {
+	for (map<string, vector<debSectionEntry const*> >::const_iterator A = ArchEntries.begin();
+	     A != ArchEntries.end(); ++A)
+		for (vector<const debSectionEntry *>::const_iterator S = A->second.begin();
+		     S != A->second.end(); ++S)
+			delete *S;
 }
 }
-   
 
 
-string debReleaseIndex::IndexURI(const char *Type, string const &Section, string const &Arch) const
+template<typename CallC>
+void foreachTarget(std::string const URI, std::string const Dist,
+      std::map<std::string, std::vector<debReleaseIndex::debSectionEntry const *> > const &ArchEntries,
+      CallC &Call)
 {
 {
-   if (Dist[Dist.size() - 1] == '/')
+   bool const flatArchive = (Dist[Dist.length() - 1] == '/');
+   std::string baseURI = URI;
+   if (flatArchive)
    {
    {
-      string Res;
       if (Dist != "/")
       if (Dist != "/")
-         Res = URI + Dist;
-      else 
-         Res = URI;
-      return Res + Type;
+         baseURI += Dist;
    }
    }
    else
    else
-      return URI + "dists/" + Dist + '/' + IndexURISuffix(Type, Section, Arch);
- }
+      baseURI += "dists/" + Dist + "/";
+   std::string const Release = (Dist == "/") ? "" : Dist;
+   std::string const Site = ::URI::ArchiveOnly(URI);
+   std::vector<std::string> lang = APT::Configuration::getLanguages(true);
+   if (lang.empty())
+      lang.push_back("none");
+   map<string, vector<debReleaseIndex::debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source");
+   if (src != ArchEntries.end())
+   {
+      std::vector<std::string> const targets = _config->FindVector("APT::Acquire::Targets::deb-src", "", true);
+      for (std::vector<std::string>::const_iterator T = targets.begin(); T != targets.end(); ++T)
+      {
+#define APT_T_CONFIG(X) _config->Find(std::string("APT::Acquire::Targets::deb-src::") + *T + "::" + (X))
+	 std::string const MetaKey = APT_T_CONFIG(flatArchive ? "flatMetaKey" : "MetaKey");
+	 std::string const ShortDesc = APT_T_CONFIG("ShortDescription");
+	 std::string const LongDesc = APT_T_CONFIG(flatArchive ? "flatDescription" : "Description");
+	 bool const IsOptional = _config->FindB(std::string("APT::Acquire::Targets::deb-src::") + *T + "::Optional", true);
+#undef APT_T_CONFIG
+	 if (MetaKey.empty())
+	    continue;
 
 
-string debReleaseIndex::SourceIndexURISuffix(const char *Type, const string &Section) const
-{
-   string Res ="";
-   if (Dist[Dist.size() - 1] != '/')
-      Res += Section + "/source/";
-   return Res + Type;
-}
+	 vector<debReleaseIndex::debSectionEntry const*> const SectionEntries = src->second;
+	 for (vector<debReleaseIndex::debSectionEntry const*>::const_iterator I = SectionEntries.begin();
+	       I != SectionEntries.end(); ++I)
+	 {
+	    for (vector<std::string>::const_iterator l = lang.begin(); l != lang.end(); ++l)
+	    {
+	       if (*l == "none" && MetaKey.find("$(LANGUAGE)") != std::string::npos)
+		  continue;
+
+	       std::map<std::string, std::string> Options;
+	       Options.insert(std::make_pair("SITE", Site));
+	       Options.insert(std::make_pair("RELEASE", Release));
+	       if (MetaKey.find("$(COMPONENT)") != std::string::npos)
+		  Options.insert(std::make_pair("COMPONENT", (*I)->Section));
+	       if (MetaKey.find("$(LANGUAGE)") != std::string::npos)
+		  Options.insert(std::make_pair("LANGUAGE", *l));
+	       Options.insert(std::make_pair("ARCHITECTURE", "source"));
+	       Options.insert(std::make_pair("BASE_URI", baseURI));
+	       Options.insert(std::make_pair("REPO_URI", URI));
+	       Options.insert(std::make_pair("TARGET_OF", "deb-src"));
+	       Options.insert(std::make_pair("CREATED_BY", *T));
+	       Call(MetaKey, ShortDesc, LongDesc, IsOptional, Options);
+
+	       if (MetaKey.find("$(LANGUAGE)") == std::string::npos)
+		  break;
+	    }
 
 
-string debReleaseIndex::SourceIndexURI(const char *Type, const string &Section) const
-{
-   string Res;
-   if (Dist[Dist.size() - 1] == '/')
+	    if (MetaKey.find("$(COMPONENT)") == std::string::npos)
+	       break;
+	 }
+      }
+   }
+
+   std::vector<std::string> const targets = _config->FindVector("APT::Acquire::Targets::deb", "", true);
+   for (std::vector<std::string>::const_iterator T = targets.begin(); T != targets.end(); ++T)
    {
    {
-      if (Dist != "/")
-         Res = URI + Dist;
-      else 
-         Res = URI;
-      return Res + Type;
+#define APT_T_CONFIG(X) _config->Find(std::string("APT::Acquire::Targets::deb::") + *T + "::" + (X))
+      std::string const MetaKey = APT_T_CONFIG(flatArchive ? "flatMetaKey" : "MetaKey");
+      std::string const ShortDesc = APT_T_CONFIG("ShortDescription");
+      std::string const LongDesc = APT_T_CONFIG(flatArchive ? "flatDescription" : "Description");
+      bool const IsOptional = _config->FindB(std::string("APT::Acquire::Targets::deb::") + *T + "::Optional", true);
+#undef APT_T_CONFIG
+      if (MetaKey.empty())
+	 continue;
+
+      for (map<string, vector<debReleaseIndex::debSectionEntry const*> >::const_iterator a = ArchEntries.begin();
+	    a != ArchEntries.end(); ++a)
+      {
+	 if (a->first == "source")
+	    continue;
+
+	 for (vector <const debReleaseIndex::debSectionEntry *>::const_iterator I = a->second.begin();
+	       I != a->second.end(); ++I) {
+
+	    for (vector<std::string>::const_iterator l = lang.begin(); l != lang.end(); ++l)
+	    {
+	       if (*l == "none" && MetaKey.find("$(LANGUAGE)") != std::string::npos)
+		  continue;
+
+	       std::map<std::string, std::string> Options;
+	       Options.insert(std::make_pair("SITE", Site));
+	       Options.insert(std::make_pair("RELEASE", Release));
+	       if (MetaKey.find("$(COMPONENT)") != std::string::npos)
+		  Options.insert(std::make_pair("COMPONENT", (*I)->Section));
+	       if (MetaKey.find("$(LANGUAGE)") != std::string::npos)
+		  Options.insert(std::make_pair("LANGUAGE", *l));
+	       if (MetaKey.find("$(ARCHITECTURE)") != std::string::npos)
+		  Options.insert(std::make_pair("ARCHITECTURE", a->first));
+	       Options.insert(std::make_pair("BASE_URI", baseURI));
+	       Options.insert(std::make_pair("REPO_URI", URI));
+	       Options.insert(std::make_pair("TARGET_OF", "deb"));
+	       Options.insert(std::make_pair("CREATED_BY", *T));
+	       Call(MetaKey, ShortDesc, LongDesc, IsOptional, Options);
+
+	       if (MetaKey.find("$(LANGUAGE)") == std::string::npos)
+		  break;
+	    }
+
+	    if (MetaKey.find("$(COMPONENT)") == std::string::npos)
+	       break;
+	 }
+
+	 if (MetaKey.find("$(ARCHITECTURE)") == std::string::npos)
+	    break;
+      }
    }
    }
-   else
-      return URI + "dists/" + Dist + "/" + SourceIndexURISuffix(Type, Section);
 }
 }
 
 
-string debReleaseIndex::TranslationIndexURISuffix(const char *Type, const string &Section) const
-{
-   string Res ="";
-   if (Dist[Dist.size() - 1] != '/')
-      Res += Section + "/i18n/Translation-";
-   return Res + Type;
-}
 
 
-string debReleaseIndex::TranslationIndexURI(const char *Type, const string &Section) const
+struct ComputeIndexTargetsClass
 {
 {
-   string Res;
-   if (Dist[Dist.size() - 1] == '/')
+   vector <IndexTarget> IndexTargets;
+
+   void operator()(std::string MetaKey, std::string ShortDesc, std::string LongDesc,
+	 bool const IsOptional, std::map<std::string, std::string> Options)
    {
    {
-      if (Dist != "/")
-         Res = URI + Dist;
-      else 
-         Res = URI;
-      return Res + Type;
+      for (std::map<std::string, std::string>::const_iterator O = Options.begin(); O != Options.end(); ++O)
+      {
+	 MetaKey = SubstVar(MetaKey, std::string("$(") + O->first + ")", O->second);
+	 ShortDesc = SubstVar(ShortDesc, std::string("$(") + O->first + ")", O->second);
+	 LongDesc = SubstVar(LongDesc, std::string("$(") + O->first + ")", O->second);
+      }
+      IndexTarget Target(
+	    MetaKey,
+	    ShortDesc,
+	    LongDesc,
+	    Options.find("BASE_URI")->second + MetaKey,
+	    IsOptional,
+	    Options
+	    );
+      IndexTargets.push_back(Target);
    }
    }
-   else
-      return URI + "dists/" + Dist + "/" + TranslationIndexURISuffix(Type, Section);
-}
-
-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);
+std::vector<IndexTarget> debReleaseIndex::GetIndexTargets() const
+{
+   ComputeIndexTargetsClass comp;
+   foreachTarget(URI, Dist, ArchEntries, comp);
+   return comp.IndexTargets;
 }
 }
 
 
-debReleaseIndex::~debReleaseIndex() {
-	for (map<string, vector<debSectionEntry const*> >::const_iterator A = ArchEntries.begin();
-	     A != ArchEntries.end(); ++A)
-		for (vector<const debSectionEntry *>::const_iterator S = A->second.begin();
-		     S != A->second.end(); ++S)
-			delete *S;
-}
 
 
-vector <IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
-	vector <IndexTarget *>* IndexTargets = new vector <IndexTarget *>;
-
-	map<string, vector<debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source");
-	if (src != ArchEntries.end()) {
-		vector<debSectionEntry const*> const SectionEntries = src->second;
-		for (vector<debSectionEntry const*>::const_iterator I = SectionEntries.begin();
-		     I != SectionEntries.end(); ++I) {
-			IndexTarget * Target = new IndexTarget();
-			Target->ShortDesc = "Sources";
-			Target->MetaKey = SourceIndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section);
-			Target->URI = SourceIndexURI(Target->ShortDesc.c_str(), (*I)->Section);
-			Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section);
-			IndexTargets->push_back (Target);
-		}
-	}
-
-	// Only source release
-	if (IndexTargets->empty() == false && ArchEntries.size() == 1)
-		return IndexTargets;
-
-	std::set<std::string> sections;
-	for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin();
-	     a != ArchEntries.end(); ++a) {
-		if (a->first == "source")
-			continue;
-		for (vector <const debSectionEntry *>::const_iterator I = a->second.begin();
-		     I != a->second.end(); ++I) {
-			IndexTarget * Target = new IndexTarget();
-			Target->ShortDesc = "Packages";
-			Target->MetaKey = IndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section, a->first);
-			Target->URI = IndexURI(Target->ShortDesc.c_str(), (*I)->Section, a->first);
-			Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section, a->first);
-			IndexTargets->push_back (Target);
-			sections.insert((*I)->Section);
-		}
-	}
-
-	std::vector<std::string> lang = APT::Configuration::getLanguages(true);
-	std::vector<std::string>::iterator lend = std::remove(lang.begin(), lang.end(), "none");
-	if (lend != lang.end())
-		lang.erase(lend);
-
-	if (lang.empty() == true)
-		return IndexTargets;
-
-	// 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();
-			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);
-		}
-	}
-
-	return IndexTargets;
-}
 									/*}}}*/
 									/*}}}*/
 bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const
 bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const
 {
 {
-   bool const tryInRelease = _config->FindB("Acquire::TryInRelease", true);
-
    indexRecords * const iR = new indexRecords(Dist);
    indexRecords * const iR = new indexRecords(Dist);
    if (Trusted == ALWAYS_TRUSTED)
    if (Trusted == ALWAYS_TRUSTED)
       iR->SetTrusted(true);
       iR->SetTrusted(true);
@@ -260,37 +268,17 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const
       iR->SetTrusted(false);
       iR->SetTrusted(false);
 
 
    // special case for --print-uris
    // special case for --print-uris
-   if (GetAll) {
-      vector <IndexTarget *> *targets = ComputeIndexTargets();
-      for (vector <IndexTarget*>::const_iterator Target = targets->begin(); Target != targets->end(); ++Target) {
-	 new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
-			 (*Target)->ShortDesc, HashStringList());
-      }
-      delete targets;
-
-      // this is normally created in pkgAcqMetaSig, but if we run
-      // in --print-uris mode, we add it here
-      if (tryInRelease == false)
-	 new pkgAcqMetaIndex(Owner, NULL,
-                             MetaIndexURI("Release"),
-                             MetaIndexInfo("Release"), "Release",
-                             MetaIndexURI("Release.gpg"), MetaIndexInfo("Release.gpg"), "Release.gpg",
-                             ComputeIndexTargets(),
-                             iR);
+   std::vector<IndexTarget> const targets = GetIndexTargets();
+#define APT_TARGET(X) IndexTarget("", X, MetaIndexInfo(X), MetaIndexURI(X), false, std::map<std::string,std::string>())
+   pkgAcqMetaBase * const TransactionManager = new pkgAcqMetaClearSig(Owner,
+	 APT_TARGET("InRelease"), APT_TARGET("Release"), APT_TARGET("Release.gpg"),
+	 targets, iR);
+#undef APT_TARGET
+   if (GetAll)
+   {
+      for (std::vector<IndexTarget>::const_iterator Target = targets.begin(); Target != targets.end(); ++Target)
+	 new pkgAcqIndex(Owner, TransactionManager, *Target);
    }
    }
-   if (tryInRelease == true)
-      new pkgAcqMetaClearSig(Owner, 
-            MetaIndexURI("InRelease"), MetaIndexInfo("InRelease"), "InRelease",
-	    MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release",
-	    MetaIndexURI("Release.gpg"), MetaIndexInfo("Release.gpg"), "Release.gpg",
-	    ComputeIndexTargets(),
-	    iR);
-   else
-      new pkgAcqMetaIndex(Owner, NULL,
-          MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release",
-          MetaIndexURI("Release.gpg"), MetaIndexInfo("Release.gpg"), "Release.gpg",
-          ComputeIndexTargets(),
-          iR);
 
 
    return true;
    return true;
 }
 }
@@ -327,45 +315,25 @@ bool debReleaseIndex::IsTrusted() const
    return FileExists(VerifiedSigFile);
    return FileExists(VerifiedSigFile);
 }
 }
 
 
-vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() {
-	if (Indexes != NULL)
-		return Indexes;
-
-	Indexes = new vector <pkgIndexFile*>;
-	map<string, vector<debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source");
-	if (src != ArchEntries.end()) {
-		vector<debSectionEntry const*> const SectionEntries = src->second;
-		for (vector<debSectionEntry const*>::const_iterator I = SectionEntries.begin();
-		     I != SectionEntries.end(); ++I)
-			Indexes->push_back(new debSourcesIndex (URI, Dist, (*I)->Section, IsTrusted()));
-	}
-
-	// Only source release
-	if (Indexes->empty() == false && ArchEntries.size() == 1)
-		return Indexes;
-
-	std::vector<std::string> const lang = APT::Configuration::getLanguages(true);
-	map<string, set<string> > sections;
-	for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin();
-	     a != ArchEntries.end(); ++a) {
-		if (a->first == "source")
-			continue;
-		for (vector<debSectionEntry const*>::const_iterator I = a->second.begin();
-		     I != a->second.end(); ++I) {
-			Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted(), a->first));
-			sections[(*I)->Section].insert(lang.begin(), lang.end());
-		}
-	}
-
-	for (map<string, set<string> >::const_iterator s = sections.begin();
-	     s != sections.end(); ++s)
-		for (set<string>::const_iterator l = s->second.begin();
-		     l != s->second.end(); ++l) {
-			if (*l == "none") continue;
-			Indexes->push_back(new debTranslationsIndex(URI,Dist,s->first,(*l).c_str()));
-		}
-
-	return Indexes;
+std::vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles()
+{
+   if (Indexes != NULL)
+      return Indexes;
+
+   Indexes = new std::vector<pkgIndexFile*>();
+   std::vector<IndexTarget> const Targets = GetIndexTargets();
+   bool const istrusted = IsTrusted();
+   for (std::vector<IndexTarget>::const_iterator T = Targets.begin(); T != Targets.end(); ++T)
+   {
+      std::string const TargetName = T->Option(IndexTarget::CREATED_BY);
+      if (TargetName == "Packages")
+	 Indexes->push_back(new debPackagesIndex(*T, istrusted));
+      else if (TargetName == "Sources")
+	 Indexes->push_back(new debSourcesIndex(*T, istrusted));
+      else if (TargetName == "Translations")
+	 Indexes->push_back(new debTranslationsIndex(*T));
+   }
+   return Indexes;
 }
 }
 
 
 void debReleaseIndex::PushSectionEntry(vector<string> const &Archs, const debSectionEntry *Entry) {
 void debReleaseIndex::PushSectionEntry(vector<string> const &Archs, const debSectionEntry *Entry) {
@@ -379,22 +347,121 @@ void debReleaseIndex::PushSectionEntry(string const &Arch, const debSectionEntry
 	ArchEntries[Arch].push_back(Entry);
 	ArchEntries[Arch].push_back(Entry);
 }
 }
 
 
-void debReleaseIndex::PushSectionEntry(const debSectionEntry *Entry) {
-	if (Entry->IsSrc == true)
-		PushSectionEntry("source", Entry);
-	else {
-		for (map<string, vector<const debSectionEntry *> >::iterator a = ArchEntries.begin();
-		     a != ArchEntries.end(); ++a) {
-			a->second.push_back(Entry);
-		}
-	}
-}
-
 debReleaseIndex::debSectionEntry::debSectionEntry (string const &Section,
 debReleaseIndex::debSectionEntry::debSectionEntry (string const &Section,
 		bool const &IsSrc): Section(Section), IsSrc(IsSrc)
 		bool const &IsSrc): Section(Section), IsSrc(IsSrc)
 {}
 {}
 
 
-class debSLTypeDebian : public pkgSourceList::Type
+static bool ReleaseFileName(debReleaseIndex const * const That, std::string &ReleaseFile)
+{
+   ReleaseFile = That->MetaIndexFile("InRelease");
+   bool releaseExists = false;
+   if (FileExists(ReleaseFile) == true)
+      releaseExists = true;
+   else
+   {
+      ReleaseFile = That->MetaIndexFile("Release");
+      if (FileExists(ReleaseFile))
+	 releaseExists = true;
+   }
+   return releaseExists;
+}
+
+bool debReleaseIndex::Merge(pkgCacheGenerator &Gen,OpProgress * /*Prog*/) const/*{{{*/
+{
+   std::string ReleaseFile;
+   bool const releaseExists = ReleaseFileName(this, ReleaseFile);
+
+   ::URI Tmp(URI);
+   if (Gen.SelectReleaseFile(ReleaseFile, Tmp.Host) == false)
+      return _error->Error("Problem with SelectReleaseFile %s", ReleaseFile.c_str());
+
+   if (releaseExists == false)
+      return true;
+
+   FileFd Rel;
+   // Beware: The 'Release' file might be clearsigned in case the
+   // signature for an 'InRelease' file couldn't be checked
+   if (OpenMaybeClearSignedFile(ReleaseFile, Rel) == false)
+      return false;
+   if (_error->PendingError() == true)
+      return false;
+
+   // Store the IMS information
+   pkgCache::RlsFileIterator File = Gen.GetCurRlsFile();
+   pkgCacheGenerator::Dynamic<pkgCache::RlsFileIterator> DynFile(File);
+   // Rel can't be used as this is potentially a temporary file
+   struct stat Buf;
+   if (stat(ReleaseFile.c_str(), &Buf) != 0)
+      return _error->Errno("fstat", "Unable to stat file %s", ReleaseFile.c_str());
+   File->Size = Buf.st_size;
+   File->mtime = Buf.st_mtime;
+
+   pkgTagFile TagFile(&Rel, Rel.Size());
+   pkgTagSection Section;
+   if (_error->PendingError() == true || TagFile.Step(Section) == false)
+      return false;
+
+   std::string data;
+   #define APT_INRELEASE(TYPE, TAG, STORE) \
+   data = Section.FindS(TAG); \
+   if (data.empty() == false) \
+   { \
+      map_stringitem_t const storage = Gen.StoreString(pkgCacheGenerator::TYPE, data); \
+      STORE = storage; \
+   }
+   APT_INRELEASE(MIXED, "Suite", File->Archive)
+   APT_INRELEASE(VERSIONNUMBER, "Version", File->Version)
+   APT_INRELEASE(MIXED, "Origin", File->Origin)
+   APT_INRELEASE(MIXED, "Codename", File->Codename)
+   APT_INRELEASE(MIXED, "Label", File->Label)
+   #undef APT_INRELEASE
+   Section.FindFlag("NotAutomatic", File->Flags, pkgCache::Flag::NotAutomatic);
+   Section.FindFlag("ButAutomaticUpgrades", File->Flags, pkgCache::Flag::ButAutomaticUpgrades);
+
+   return !_error->PendingError();
+}
+									/*}}}*/
+// ReleaseIndex::FindInCache - Find this index				/*{{{*/
+pkgCache::RlsFileIterator debReleaseIndex::FindInCache(pkgCache &Cache, bool const ModifyCheck) const
+{
+   std::string ReleaseFile;
+   bool const releaseExists = ReleaseFileName(this, ReleaseFile);
+
+   pkgCache::RlsFileIterator File = Cache.RlsFileBegin();
+   for (; File.end() == false; ++File)
+   {
+       if (File->FileName == 0 || ReleaseFile != File.FileName())
+	 continue;
+
+       // empty means the file does not exist by "design"
+       if (ModifyCheck == false || (releaseExists == false && File->Size == 0))
+	  return File;
+
+      struct stat St;
+      if (stat(File.FileName(),&St) != 0)
+      {
+         if (_config->FindB("Debug::pkgCacheGen", false))
+	    std::clog << "ReleaseIndex::FindInCache - stat failed on " << File.FileName() << std::endl;
+	 return pkgCache::RlsFileIterator(Cache);
+      }
+      if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime)
+      {
+         if (_config->FindB("Debug::pkgCacheGen", false))
+	    std::clog << "ReleaseIndex::FindInCache - size (" << St.st_size << " <> " << File->Size
+			<< ") or mtime (" << St.st_mtime << " <> " << File->mtime
+			<< ") doesn't match for " << File.FileName() << std::endl;
+	 return pkgCache::RlsFileIterator(Cache);
+      }
+      return File;
+   }
+
+   return File;
+}
+									/*}}}*/
+
+debDebFileMetaIndex::~debDebFileMetaIndex() {}
+
+class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type
 {
 {
    protected:
    protected:
 
 
@@ -404,9 +471,12 @@ class debSLTypeDebian : public pkgSourceList::Type
    {
    {
       // parse arch=, arch+= and arch-= settings
       // parse arch=, arch+= and arch-= settings
       map<string, string>::const_iterator arch = Options.find("arch");
       map<string, string>::const_iterator arch = Options.find("arch");
-      vector<string> Archs =
-		(arch != Options.end()) ? VectorizeString(arch->second, ',') :
-				APT::Configuration::getArchitectures();
+      vector<string> Archs;
+      if (arch != Options.end())
+	 Archs = VectorizeString(arch->second, ',');
+      else
+	 Archs = APT::Configuration::getArchitectures();
+
       if ((arch = Options.find("arch+")) != Options.end())
       if ((arch = Options.find("arch+")) != Options.end())
       {
       {
 	 std::vector<std::string> const plusArch = VectorizeString(arch->second, ',');
 	 std::vector<std::string> const plusArch = VectorizeString(arch->second, ',');
@@ -427,6 +497,7 @@ class debSLTypeDebian : public pkgSourceList::Type
 
 
       map<string, string>::const_iterator const trusted = Options.find("trusted");
       map<string, string>::const_iterator const trusted = Options.find("trusted");
 
 
+      debReleaseIndex *Deb = NULL;
       for (vector<metaIndex *>::const_iterator I = List.begin();
       for (vector<metaIndex *>::const_iterator I = List.begin();
 	   I != List.end(); ++I)
 	   I != List.end(); ++I)
       {
       {
@@ -434,34 +505,23 @@ class debSLTypeDebian : public pkgSourceList::Type
 	 if (strcmp((*I)->GetType(), "deb") != 0)
 	 if (strcmp((*I)->GetType(), "deb") != 0)
 	    continue;
 	    continue;
 
 
-	 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. */
-	 if (Deb->GetURI() == URI && Deb->GetDist() == Dist)
+	 if ((*I)->GetURI() == URI && (*I)->GetDist() == Dist)
 	 {
 	 {
-	    if (IsSrc == true)
-	       Deb->PushSectionEntry("source", new debReleaseIndex::debSectionEntry(Section, IsSrc));
-	    else
-	    {
-	       if (Dist[Dist.size() - 1] == '/')
-		  Deb->PushSectionEntry("any", new debReleaseIndex::debSectionEntry(Section, IsSrc));
-	       else
-		  Deb->PushSectionEntry(Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc));
-	    }
-	    return true;
+	    Deb = dynamic_cast<debReleaseIndex*>(*I);
+	    if (Deb != NULL)
+	       break;
 	 }
 	 }
       }
       }
 
 
       // 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.
-      debReleaseIndex *Deb;
-      if (trusted != Options.end())
-	 Deb = new debReleaseIndex(URI, Dist, StringToBool(trusted->second, false));
-      else
+      if (Deb == NULL)
+      {
 	 Deb = new debReleaseIndex(URI, Dist);
 	 Deb = new debReleaseIndex(URI, Dist);
+	 List.push_back(Deb);
+      }
 
 
       if (IsSrc == true)
       if (IsSrc == true)
 	 Deb->PushSectionEntry ("source", new debReleaseIndex::debSectionEntry(Section, IsSrc));
 	 Deb->PushSectionEntry ("source", new debReleaseIndex::debSectionEntry(Section, IsSrc));
@@ -472,7 +532,10 @@ class debSLTypeDebian : public pkgSourceList::Type
 	 else
 	 else
 	    Deb->PushSectionEntry (Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc));
 	    Deb->PushSectionEntry (Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc));
       }
       }
-      List.push_back(Deb);
+
+      if (trusted != Options.end())
+	 Deb->SetTrusted(StringToBool(trusted->second, false));
+
       return true;
       return true;
    }
    }
 };
 };
@@ -486,7 +549,7 @@ debDebFileMetaIndex::debDebFileMetaIndex(std::string const &DebFile)
 }
 }
 
 
 
 
-class debSLTypeDeb : public debSLTypeDebian
+class APT_HIDDEN debSLTypeDeb : public debSLTypeDebian
 {
 {
    public:
    public:
 
 
@@ -504,7 +567,7 @@ class debSLTypeDeb : public debSLTypeDebian
    }   
    }   
 };
 };
 
 
-class debSLTypeDebSrc : public debSLTypeDebian
+class APT_HIDDEN debSLTypeDebSrc : public debSLTypeDebian
 {
 {
    public:
    public:
 
 
@@ -522,7 +585,7 @@ class debSLTypeDebSrc : public debSLTypeDebian
    }   
    }   
 };
 };
 
 
-class debSLTypeDebFile : public pkgSourceList::Type
+class APT_HIDDEN debSLTypeDebFile : public pkgSourceList::Type
 {
 {
    public:
    public:
 
 
@@ -541,6 +604,7 @@ class debSLTypeDebFile : public pkgSourceList::Type
       Label = "Debian Deb File";
       Label = "Debian Deb File";
    }   
    }   
 };
 };
-debSLTypeDeb _apt_DebType;
-debSLTypeDebSrc _apt_DebSrcType;
-debSLTypeDebFile _apt_DebFileType;
+
+APT_HIDDEN debSLTypeDeb _apt_DebType;
+APT_HIDDEN debSLTypeDebSrc _apt_DebSrcType;
+APT_HIDDEN debSLTypeDebFile _apt_DebFileType;

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

@@ -20,8 +20,10 @@ class pkgAcquire;
 class pkgIndexFile;
 class pkgIndexFile;
 class debDebPkgFileIndex;
 class debDebPkgFileIndex;
 class IndexTarget;
 class IndexTarget;
+class pkgCacheGenerator;
+class OpProgress;
 
 
-class debReleaseIndex : public metaIndex {
+class APT_HIDDEN debReleaseIndex : public metaIndex {
    public:
    public:
 
 
    class debSectionEntry
    class debSectionEntry
@@ -46,23 +48,21 @@ class debReleaseIndex : public metaIndex {
 
 
    virtual std::string ArchiveURI(std::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;
-   std::vector <IndexTarget *>* ComputeIndexTargets() const;
-   std::string Info(const char *Type, std::string const &Section, std::string const &Arch="") const;
+   virtual std::vector<IndexTarget> GetIndexTargets() const;
+
+   virtual std::string Describe() const;
+   virtual pkgCache::RlsFileIterator FindInCache(pkgCache &Cache, bool const ModifyCheck) const;
+   virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const;
 
 
    std::string MetaIndexInfo(const char *Type) const;
    std::string MetaIndexInfo(const char *Type) const;
    std::string MetaIndexFile(const char *Types) const;
    std::string MetaIndexFile(const char *Types) const;
    std::string MetaIndexURI(const char *Type) const;
    std::string MetaIndexURI(const char *Type) const;
 
 
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
-   virtual std::string LocalFileName() const;
+#if APT_PKG_ABI >= 413
+   virtual
 #endif
 #endif
+   std::string LocalFileName() 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();
    virtual std::vector <pkgIndexFile *> *GetIndexFiles();
 
 
    void SetTrusted(bool const Trusted);
    void SetTrusted(bool const Trusted);
@@ -70,12 +70,12 @@ class debReleaseIndex : public metaIndex {
 
 
    void PushSectionEntry(std::vector<std::string> const &Archs, 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(std::string const &Arch, const debSectionEntry *Entry);
-   void PushSectionEntry(const debSectionEntry *Entry);
 };
 };
 
 
-class debDebFileMetaIndex : public metaIndex
+class APT_HIDDEN debDebFileMetaIndex : public metaIndex
 {
 {
  private:
  private:
+    void *d;
    std::string DebFile;
    std::string DebFile;
    debDebPkgFileIndex *DebIndex;
    debDebPkgFileIndex *DebIndex;
  public:
  public:
@@ -85,6 +85,9 @@ class debDebFileMetaIndex : public metaIndex
    virtual bool GetIndexes(pkgAcquire* /*Owner*/, const bool& /*GetAll=false*/) const {
    virtual bool GetIndexes(pkgAcquire* /*Owner*/, const bool& /*GetAll=false*/) const {
       return true;
       return true;
    }
    }
+   virtual std::vector<IndexTarget> GetIndexTargets() const {
+      return std::vector<IndexTarget>();
+   }
    virtual std::vector<pkgIndexFile *> *GetIndexFiles() {
    virtual std::vector<pkgIndexFile *> *GetIndexFiles() {
       return Indexes;
       return Indexes;
    }
    }
@@ -92,7 +95,7 @@ class debDebFileMetaIndex : public metaIndex
       return true;
       return true;
    }
    }
    debDebFileMetaIndex(std::string const &DebFile);
    debDebFileMetaIndex(std::string const &DebFile);
-   virtual ~debDebFileMetaIndex() {};
+   virtual ~debDebFileMetaIndex();
 
 
 };
 };
 
 

+ 60 - 55
apt-pkg/deb/debrecords.cc

@@ -11,35 +11,35 @@
 #include <config.h>
 #include <config.h>
 
 
 #include <apt-pkg/debrecords.h>
 #include <apt-pkg/debrecords.h>
+#include <apt-pkg/debindexfile.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/tagfile.h>
+#include <apt-pkg/error.h>
 
 
 #include <string.h>
 #include <string.h>
 #include <algorithm>
 #include <algorithm>
+#include <sstream>
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
 #include <langinfo.h>
 #include <langinfo.h>
+
+#include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 
 
 using std::string;
 using std::string;
 
 
 // RecordParser::debRecordParser - Constructor				/*{{{*/
 // RecordParser::debRecordParser - Constructor				/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-debRecordParser::debRecordParser(string FileName,pkgCache &Cache) : 
-                  File(FileName,FileFd::ReadOnly, FileFd::Extension),
-                  Tags(&File, std::max(Cache.Head().MaxVerFileSize, 
-				       Cache.Head().MaxDescFileSize) + 200)
+debRecordParser::debRecordParser(string FileName,pkgCache &Cache) :
+   debRecordParserBase(), File(FileName, FileFd::ReadOnly, FileFd::Extension),
+   Tags(&File, std::max(Cache.Head().MaxVerFileSize, Cache.Head().MaxDescFileSize) + 200)
 {
 {
 }
 }
 									/*}}}*/
 									/*}}}*/
 // RecordParser::Jump - Jump to a specific record			/*{{{*/
 // RecordParser::Jump - Jump to a specific record			/*{{{*/
-// ---------------------------------------------------------------------
-/* */
 bool debRecordParser::Jump(pkgCache::VerFileIterator const &Ver)
 bool debRecordParser::Jump(pkgCache::VerFileIterator const &Ver)
 {
 {
    return Tags.Jump(Section,Ver->Offset);
    return Tags.Jump(Section,Ver->Offset);
@@ -49,32 +49,29 @@ bool debRecordParser::Jump(pkgCache::DescFileIterator const &Desc)
    return Tags.Jump(Section,Desc->Offset);
    return Tags.Jump(Section,Desc->Offset);
 }
 }
 									/*}}}*/
 									/*}}}*/
-// RecordParser::FileName - Return the archive filename on the site	/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debRecordParser::FileName()
+debRecordParser::~debRecordParser() {}
+
+debRecordParserBase::debRecordParserBase() : Parser() {}
+// RecordParserBase::FileName - Return the archive filename on the site	/*{{{*/
+string debRecordParserBase::FileName()
 {
 {
    return Section.FindS("Filename");
    return Section.FindS("Filename");
 }
 }
 									/*}}}*/
 									/*}}}*/
-// RecordParser::Name - Return the package name				/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debRecordParser::Name()
+// RecordParserBase::Name - Return the package name			/*{{{*/
+string debRecordParserBase::Name()
 {
 {
    return Section.FindS("Package");
    return Section.FindS("Package");
 }
 }
 									/*}}}*/
 									/*}}}*/
-// RecordParser::Homepage - Return the package homepage		       	/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debRecordParser::Homepage()
+// RecordParserBase::Homepage - Return the package homepage		/*{{{*/
+string debRecordParserBase::Homepage()
 {
 {
    return Section.FindS("Homepage");
    return Section.FindS("Homepage");
 }
 }
 									/*}}}*/
 									/*}}}*/
-// RecordParser::Hashes - return the available archive hashes		/*{{{*/
-HashStringList debRecordParser::Hashes() const
+// RecordParserBase::Hashes - return the available archive hashes	/*{{{*/
+HashStringList debRecordParserBase::Hashes() const
 {
 {
    HashStringList hashes;
    HashStringList hashes;
    for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type)
    for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type)
@@ -86,27 +83,20 @@ HashStringList debRecordParser::Hashes() const
    return hashes;
    return hashes;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// RecordParser::Maintainer - Return the maintainer email		/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debRecordParser::Maintainer()
+// RecordParserBase::Maintainer - Return the maintainer email		/*{{{*/
+string debRecordParserBase::Maintainer()
 {
 {
    return Section.FindS("Maintainer");
    return Section.FindS("Maintainer");
 }
 }
 									/*}}}*/
 									/*}}}*/
-// RecordParser::RecordField - Return the value of an arbitrary field       /*{{*/
-// ---------------------------------------------------------------------
-/* */
-string debRecordParser::RecordField(const char *fieldName)
+// RecordParserBase::RecordField - Return the value of an arbitrary field	/*{{*/
+string debRecordParserBase::RecordField(const char *fieldName)
 {
 {
    return Section.FindS(fieldName);
    return Section.FindS(fieldName);
 }
 }
-
-                                                                        /*}}}*/
-// RecordParser::ShortDesc - Return a 1 line description		/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debRecordParser::ShortDesc(std::string const &lang)
+									/*}}}*/
+// RecordParserBase::ShortDesc - Return a 1 line description		/*{{{*/
+string debRecordParserBase::ShortDesc(std::string const &lang)
 {
 {
    string const Res = LongDesc(lang);
    string const Res = LongDesc(lang);
    if (Res.empty() == true)
    if (Res.empty() == true)
@@ -117,10 +107,8 @@ string debRecordParser::ShortDesc(std::string const &lang)
    return string(Res,0,Pos);
    return string(Res,0,Pos);
 }
 }
 									/*}}}*/
 									/*}}}*/
-// RecordParser::LongDesc - Return a longer description			/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debRecordParser::LongDesc(std::string const &lang)
+// RecordParserBase::LongDesc - Return a longer description		/*{{{*/
+string debRecordParserBase::LongDesc(std::string const &lang)
 {
 {
    string orig;
    string orig;
    if (lang.empty() == true)
    if (lang.empty() == true)
@@ -162,12 +150,9 @@ string debRecordParser::LongDesc(std::string const &lang)
 }
 }
 									/*}}}*/
 									/*}}}*/
 
 
-static const char *SourceVerSeparators = " ()";
-
-// RecordParser::SourcePkg - Return the source package name if any	/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debRecordParser::SourcePkg()
+static const char * const SourceVerSeparators = " ()";
+// RecordParserBase::SourcePkg - Return the source package name if any	/*{{{*/
+string debRecordParserBase::SourcePkg()
 {
 {
    string Res = Section.FindS("Source");
    string Res = Section.FindS("Source");
    string::size_type Pos = Res.find_first_of(SourceVerSeparators);
    string::size_type Pos = Res.find_first_of(SourceVerSeparators);
@@ -176,10 +161,8 @@ string debRecordParser::SourcePkg()
    return string(Res,0,Pos);
    return string(Res,0,Pos);
 }
 }
 									/*}}}*/
 									/*}}}*/
-// RecordParser::SourceVer - Return the source version number if present	/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debRecordParser::SourceVer()
+// RecordParserBase::SourceVer - Return the source version number if present	/*{{{*/
+string debRecordParserBase::SourceVer()
 {
 {
    string Pkg = Section.FindS("Source");
    string Pkg = Section.FindS("Source");
    string::size_type Pos = Pkg.find_first_of(SourceVerSeparators);
    string::size_type Pos = Pkg.find_first_of(SourceVerSeparators);
@@ -199,13 +182,35 @@ string debRecordParser::SourceVer()
      return string(Pkg, VerStart, VerEnd - VerStart);
      return string(Pkg, VerStart, VerEnd - VerStart);
 }
 }
 									/*}}}*/
 									/*}}}*/
-// RecordParser::GetRec - Return the whole record			/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void debRecordParser::GetRec(const char *&Start,const char *&Stop)
+// RecordParserBase::GetRec - Return the whole record			/*{{{*/
+void debRecordParserBase::GetRec(const char *&Start,const char *&Stop)
 {
 {
    Section.GetSection(Start,Stop);
    Section.GetSection(Start,Stop);
 }
 }
 									/*}}}*/
 									/*}}}*/
+debRecordParserBase::~debRecordParserBase() {}
 
 
-debRecordParser::~debRecordParser() {}
+bool debDebFileRecordParser::LoadContent()
+{
+   // load content only once
+   if (controlContent.empty() == false)
+      return true;
+
+   std::ostringstream content;
+   if (debDebPkgFileIndex::GetContent(content, debFileName) == false)
+      return false;
+   // add two newlines to make sure the scanner finds the section,
+   // which is usually done by pkgTagFile automatically if needed.
+   content << "\n\n";
+
+   controlContent = content.str();
+   if (Section.Scan(controlContent.c_str(), controlContent.length()) == false)
+      return _error->Error(_("Unable to parse package file %s (%d)"), debFileName.c_str(), 3);
+   return true;
+}
+bool debDebFileRecordParser::Jump(pkgCache::VerFileIterator const &) { return LoadContent(); }
+bool debDebFileRecordParser::Jump(pkgCache::DescFileIterator const &) { return LoadContent(); }
+std::string debDebFileRecordParser::FileName() { return debFileName; }
+
+debDebFileRecordParser::debDebFileRecordParser(std::string FileName) : debRecordParserBase(), debFileName(FileName) {}
+debDebFileRecordParser::~debDebFileRecordParser() {}

+ 33 - 17
apt-pkg/deb/debrecords.h

@@ -25,21 +25,13 @@
 #include <apt-pkg/indexfile.h>
 #include <apt-pkg/indexfile.h>
 #endif
 #endif
 
 
-class debRecordParser : public pkgRecords::Parser
+class APT_HIDDEN debRecordParserBase : public pkgRecords::Parser
 {
 {
-   /** \brief dpointer placeholder (for later in case we need it) */
    void *d;
    void *d;
-   
  protected:
  protected:
-   FileFd File;
-   pkgTagFile Tags;
    pkgTagSection Section;
    pkgTagSection Section;
-   
-   virtual bool Jump(pkgCache::VerFileIterator const &Ver);
-   virtual bool Jump(pkgCache::DescFileIterator const &Desc);
-   
- public:
 
 
+ public:
    // These refer to the archive file for the Version
    // These refer to the archive file for the Version
    virtual std::string FileName();
    virtual std::string FileName();
    virtual std::string SourcePkg();
    virtual std::string SourcePkg();
@@ -58,20 +50,44 @@ class debRecordParser : public pkgRecords::Parser
    virtual std::string RecordField(const char *fieldName);
    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);
-   
+
+   debRecordParserBase();
+   virtual ~debRecordParserBase();
+};
+
+class APT_HIDDEN debRecordParser : public debRecordParserBase
+{
+   void *d;
+ protected:
+   FileFd File;
+   pkgTagFile Tags;
+
+   virtual bool Jump(pkgCache::VerFileIterator const &Ver);
+   virtual bool Jump(pkgCache::DescFileIterator const &Desc);
+
+ public:
    debRecordParser(std::string FileName,pkgCache &Cache);
    debRecordParser(std::string FileName,pkgCache &Cache);
    virtual ~debRecordParser();
    virtual ~debRecordParser();
 };
 };
 
 
 // custom record parser that reads deb files directly
 // custom record parser that reads deb files directly
-class debDebFileRecordParser : public debRecordParser
+class APT_HIDDEN debDebFileRecordParser : public debRecordParserBase
 {
 {
+   void *d;
+   std::string debFileName;
+   std::string controlContent;
+
+   APT_HIDDEN bool LoadContent();
+ protected:
+   // single file files, so no jumping whatsoever
+   bool Jump(pkgCache::VerFileIterator const &);
+   bool Jump(pkgCache::DescFileIterator const &);
+
  public:
  public:
-   virtual std::string FileName() {
-      return File.Name();
-   }
-   debDebFileRecordParser(std::string FileName,pkgCache &Cache)
-      : debRecordParser(FileName, Cache) {};
+   virtual std::string FileName();
+
+   debDebFileRecordParser(std::string FileName);
+   virtual ~debDebFileRecordParser();
 };
 };
 
 
 #endif
 #endif

+ 36 - 22
apt-pkg/deb/debsrcrecords.cc

@@ -32,6 +32,10 @@
 using std::max;
 using std::max;
 using std::string;
 using std::string;
 
 
+debSrcRecordParser::debSrcRecordParser(std::string const &File,pkgIndexFile const *Index)
+   : Parser(Index), Fd(File,FileFd::ReadOnly, FileFd::Extension), Tags(&Fd,102400),
+   iOffset(0), Buffer(NULL) {}
+
 // 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
@@ -121,9 +125,32 @@ bool debSrcRecordParser::BuildDepends(std::vector<pkgSrcRecords::Parser::BuildDe
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* 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(std::vector<pkgSrcRecords::File> &List)
+bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &F)
+{
+   std::vector<pkgSrcRecords::File2> F2;
+   if (Files2(F2) == false)
+      return false;
+   for (std::vector<pkgSrcRecords::File2>::const_iterator f2 = F2.begin(); f2 != F2.end(); ++f2)
+   {
+      pkgSrcRecords::File2 f;
+#if __GNUC__ >= 4
+	#pragma GCC diagnostic push
+	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+      f.MD5Hash = f2->MD5Hash;
+      f.Size = f2->Size;
+#if __GNUC__ >= 4
+	#pragma GCC diagnostic pop
+#endif
+      f.Path = f2->Path;
+      f.Type = f2->Type;
+      F.push_back(f);
+   }
+   return true;
+}
+bool debSrcRecordParser::Files2(std::vector<pkgSrcRecords::File2> &List)
 {
 {
-   List.erase(List.begin(),List.end());
+   List.clear();
 
 
    // Stash the / terminated directory prefix
    // Stash the / terminated directory prefix
    string Base = Sect.FindS("Directory");
    string Base = Sect.FindS("Directory");
@@ -162,7 +189,7 @@ bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List)
 	    path = Base + path;
 	    path = Base + path;
 
 
 	 // look if we have a record for this file already
 	 // look if we have a record for this file already
-	 std::vector<pkgSrcRecords::File>::iterator file = List.begin();
+	 std::vector<pkgSrcRecords::File2>::iterator file = List.begin();
 	 for (; file != List.end(); ++file)
 	 for (; file != List.end(); ++file)
 	    if (file->Path == path)
 	    if (file->Path == path)
 	       break;
 	       break;
@@ -170,16 +197,8 @@ bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List)
 	 // we have it already, store the new hash and be done
 	 // we have it already, store the new hash and be done
 	 if (file != List.end())
 	 if (file != List.end())
 	 {
 	 {
-#if __GNUC__ >= 4
-	// set for compatibility only, so warn users not us
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
 	    if (checksumField == "Files")
 	    if (checksumField == "Files")
-	       file->MD5Hash = hash;
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+	       APT_IGNORE_DEPRECATED(file->MD5Hash = hash;)
 	    // an error here indicates that we have two different hashes for the same file
 	    // an error here indicates that we have two different hashes for the same file
 	    if (file->Hashes.push_back(hashString) == false)
 	    if (file->Hashes.push_back(hashString) == false)
 	       return _error->Error("Error parsing checksum in %s of source package %s", checksumField.c_str(), Package().c_str());
 	       return _error->Error("Error parsing checksum in %s of source package %s", checksumField.c_str(), Package().c_str());
@@ -187,21 +206,16 @@ bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List)
 	 }
 	 }
 
 
 	 // we haven't seen this file yet
 	 // we haven't seen this file yet
-	 pkgSrcRecords::File F;
+	 pkgSrcRecords::File2 F;
 	 F.Path = path;
 	 F.Path = path;
-	 F.Size = strtoull(size.c_str(), NULL, 10);
+	 F.FileSize = strtoull(size.c_str(), NULL, 10);
 	 F.Hashes.push_back(hashString);
 	 F.Hashes.push_back(hashString);
 
 
-#if __GNUC__ >= 4
-	// set for compatibility only, so warn users not us
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+	 APT_IGNORE_DEPRECATED_PUSH
+	 F.Size = F.FileSize;
 	 if (checksumField == "Files")
 	 if (checksumField == "Files")
 	    F.MD5Hash = hash;
 	    F.MD5Hash = hash;
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+	 APT_IGNORE_DEPRECATED_POP
 
 
 	 // Try to guess what sort of file it is we are getting.
 	 // Try to guess what sort of file it is we are getting.
 	 string::size_type Pos = F.Path.length()-1;
 	 string::size_type Pos = F.Path.length()-1;

+ 4 - 5
apt-pkg/deb/debsrcrecords.h

@@ -21,7 +21,7 @@
 
 
 class pkgIndexFile;
 class pkgIndexFile;
 
 
-class debSrcRecordParser : public pkgSrcRecords::Parser
+class APT_HIDDEN debSrcRecordParser : public pkgSrcRecords::Parser
 {
 {
    /** \brief dpointer placeholder (for later in case we need it) */
    /** \brief dpointer placeholder (for later in case we need it) */
    void *d;
    void *d;
@@ -54,14 +54,13 @@ class debSrcRecordParser : public pkgSrcRecords::Parser
       return std::string(Start,Stop);
       return std::string(Start,Stop);
    };
    };
    virtual bool Files(std::vector<pkgSrcRecords::File> &F);
    virtual bool Files(std::vector<pkgSrcRecords::File> &F);
+   bool Files2(std::vector<pkgSrcRecords::File2> &F);
 
 
-   debSrcRecordParser(std::string const &File,pkgIndexFile const *Index) 
-      : Parser(Index), Fd(File,FileFd::ReadOnly, FileFd::Extension), Tags(&Fd,102400),
-        iOffset(0), Buffer(NULL) {}
+   debSrcRecordParser(std::string const &File,pkgIndexFile const *Index);
    virtual ~debSrcRecordParser();
    virtual ~debSrcRecordParser();
 };
 };
 
 
-class debDscRecordParser : public debSrcRecordParser
+class APT_HIDDEN debDscRecordParser : public debSrcRecordParser
 {
 {
  public:
  public:
    debDscRecordParser(std::string const &DscFile, pkgIndexFile const *Index);
    debDscRecordParser(std::string const &DscFile, pkgIndexFile const *Index);

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

@@ -38,7 +38,7 @@ using std::string;
 
 
 debSystem debSys;
 debSystem debSys;
 
 
-class debSystemPrivate {
+class APT_HIDDEN debSystemPrivate {
 public:
 public:
    debSystemPrivate() : LockFD(-1), LockCount(0), StatusFile(0)
    debSystemPrivate() : LockFD(-1), LockCount(0), StatusFile(0)
    {
    {

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

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: debversion.h,v 1.3 2001/05/03 05:25:04 jgg Exp $
 /* ######################################################################
 /* ######################################################################
 
 
    Debian Version - Versioning system for Debian
    Debian Version - Versioning system for Debian

+ 103 - 67
apt-pkg/deb/dpkgpm.cc

@@ -72,7 +72,9 @@ class pkgDPkgPMPrivate
 public:
 public:
    pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0),
    pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0),
 			term_out(NULL), history_out(NULL),
 			term_out(NULL), history_out(NULL),
-                        progress(NULL), master(-1), slave(NULL)
+			progress(NULL), tt_is_valid(false), master(-1),
+			slave(NULL), protect_slave_from_dying(-1),
+			direct_stdin(false)
    {
    {
       dpkgbuf[0] = '\0';
       dpkgbuf[0] = '\0';
    }
    }
@@ -90,13 +92,16 @@ public:
 
 
    // pty stuff
    // pty stuff
    struct termios tt;
    struct termios tt;
+   bool tt_is_valid;
    int master;
    int master;
    char * slave;
    char * slave;
+   int protect_slave_from_dying;
 
 
    // signals
    // signals
    sigset_t sigmask;
    sigset_t sigmask;
    sigset_t original_sigmask;
    sigset_t original_sigmask;
 
 
+   bool direct_stdin;
 };
 };
 
 
 namespace
 namespace
@@ -198,18 +203,12 @@ pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg)
 {
 {
    pkgCache::VerIterator Ver;
    pkgCache::VerIterator Ver;
    for (Ver = Pkg.VersionList(); Ver.end() == false; ++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;
-         }
-      }
-   }
+      for (pkgCache::VerFileIterator Vf = Ver.FileList(); Vf.end() == false; ++Vf)
+	 for (pkgCache::PkgFileIterator F = Vf.File(); F.end() == false; ++F)
+	 {
+	    if (F.Archive() != 0 && strcmp(F.Archive(), "now") == 0)
+	       return Ver;
+	 }
    return Ver;
    return Ver;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -1044,6 +1043,12 @@ void pkgDPkgPM::BuildPackagesProgressMap()
 	 PackagesTotal++;
 	 PackagesTotal++;
       }
       }
    }
    }
+   /* one extra: We don't want the progress bar to reach 100%, especially not
+      if we call dpkg --configure --pending and process a bunch of triggers
+      while showing 100%. Also, spindown takes a while, so never reaching 100%
+      is way more correct than reaching 100% while still doing stuff even if
+      doing it this way is slightly bending the rules */
+   ++PackagesTotal;
 }
 }
                                                                         /*}}}*/
                                                                         /*}}}*/
 bool pkgDPkgPM::Go(int StatusFd)
 bool pkgDPkgPM::Go(int StatusFd)
@@ -1068,48 +1073,44 @@ void pkgDPkgPM::StartPtyMagic()
       return;
       return;
    }
    }
 
 
+   if (isatty(STDIN_FILENO) == 0)
+      d->direct_stdin = true;
+
    _error->PushToStack();
    _error->PushToStack();
-   // if tcgetattr for both stdin/stdout returns 0 (no error)
-   // we do the pty magic
-   if (tcgetattr(STDOUT_FILENO, &d->tt) == 0 &&
-	 tcgetattr(STDIN_FILENO, &d->tt) == 0)
+
+   d->master = posix_openpt(O_RDWR | O_NOCTTY);
+   if (d->master == -1)
+      _error->Errno("posix_openpt", _("Can not write log (%s)"), _("Is /dev/pts mounted?"));
+   else if (unlockpt(d->master) == -1)
+      _error->Errno("unlockpt", "Unlocking the slave of master fd %d failed!", d->master);
+   else
    {
    {
-      d->master = posix_openpt(O_RDWR | O_NOCTTY);
-      if (d->master == -1)
-	 _error->Errno("posix_openpt", _("Can not write log (%s)"), _("Is /dev/pts mounted?"));
-      else if (unlockpt(d->master) == -1)
-      {
-	 _error->Errno("unlockpt", "Unlocking the slave of master fd %d failed!", d->master);
-	 close(d->master);
-	 d->master = -1;
-      }
+      char const * const slave_name = ptsname(d->master);
+      if (slave_name == NULL)
+	 _error->Errno("ptsname", "Getting name for slave of master fd %d failed!", d->master);
       else
       else
       {
       {
-	 char const * const slave_name = ptsname(d->master);
-	 if (slave_name == NULL)
-	 {
-	    _error->Errno("unlockpt", "Getting name for slave of master fd %d failed!", d->master);
-	    close(d->master);
-	    d->master = -1;
-	 }
-	 else
+	 d->slave = strdup(slave_name);
+	 if (d->slave == NULL)
+	    _error->Errno("strdup", "Copying name %s for slave of master fd %d failed!", slave_name, d->master);
+	 else if (grantpt(d->master) == -1)
+	    _error->Errno("grantpt", "Granting access to slave %s based on master fd %d failed!", slave_name, d->master);
+	 else if (tcgetattr(STDIN_FILENO, &d->tt) == 0)
 	 {
 	 {
-	    d->slave = strdup(slave_name);
-	    if (d->slave == NULL)
+	    d->tt_is_valid = true;
+	    struct termios raw_tt;
+	    // copy window size of stdout if its a 'good' terminal
+	    if (tcgetattr(STDOUT_FILENO, &raw_tt) == 0)
 	    {
 	    {
-	       _error->Errno("strdup", "Copying name %s for slave of master fd %d failed!", slave_name, d->master);
-	       close(d->master);
-	       d->master = -1;
+	       struct winsize win;
+	       if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) < 0)
+		  _error->Errno("ioctl", "Getting TIOCGWINSZ from stdout failed!");
+	       if (ioctl(d->master, TIOCSWINSZ, &win) < 0)
+		  _error->Errno("ioctl", "Setting TIOCSWINSZ for master fd %d failed!", d->master);
 	    }
 	    }
-	    struct winsize win;
-	    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) < 0)
-	       _error->Errno("ioctl", "Getting TIOCGWINSZ from stdout failed!");
-	    if (ioctl(d->master, TIOCSWINSZ, &win) < 0)
-	       _error->Errno("ioctl", "Setting TIOCSWINSZ for master fd %d failed!", d->master);
 	    if (tcsetattr(d->master, TCSANOW, &d->tt) == -1)
 	    if (tcsetattr(d->master, TCSANOW, &d->tt) == -1)
 	       _error->Errno("tcsetattr", "Setting in Start via TCSANOW for master fd %d failed!", d->master);
 	       _error->Errno("tcsetattr", "Setting in Start via TCSANOW for master fd %d failed!", d->master);
 
 
-	    struct termios raw_tt;
 	    raw_tt = d->tt;
 	    raw_tt = d->tt;
 	    cfmakeraw(&raw_tt);
 	    cfmakeraw(&raw_tt);
 	    raw_tt.c_lflag &= ~ECHO;
 	    raw_tt.c_lflag &= ~ECHO;
@@ -1121,18 +1122,22 @@ void pkgDPkgPM::StartPtyMagic()
 	    sigaddset(&d->sigmask, SIGTTOU);
 	    sigaddset(&d->sigmask, SIGTTOU);
 	    sigprocmask(SIG_BLOCK,&d->sigmask, &d->original_sigmask);
 	    sigprocmask(SIG_BLOCK,&d->sigmask, &d->original_sigmask);
 	    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw_tt) == -1)
 	    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw_tt) == -1)
-	       _error->Errno("tcsetattr", "Setting in Start via TCSAFLUSH for stdout failed!");
+	       _error->Errno("tcsetattr", "Setting in Start via TCSAFLUSH for stdin failed!");
 	    sigprocmask(SIG_SETMASK, &d->original_sigmask, NULL);
 	    sigprocmask(SIG_SETMASK, &d->original_sigmask, NULL);
+
+	 }
+	 if (d->slave != NULL)
+	 {
+	    /* on linux, closing (and later reopening) all references to the slave
+	       makes the slave a death end, so we open it here to have one open all
+	       the time. We could use this fd in SetupSlavePtyMagic() for linux, but
+	       on kfreebsd we get an incorrect ("step like") output then while it has
+	       no problem with closing all references… so to avoid platform specific
+	       code here we combine both and be happy once more */
+	    d->protect_slave_from_dying = open(d->slave, O_RDWR | O_CLOEXEC | O_NOCTTY);
 	 }
 	 }
       }
       }
    }
    }
-   else
-   {
-      // complain only if stdout is either a terminal (but still failed) or is an invalid
-      // descriptor otherwise we would complain about redirection to e.g. /dev/null as well.
-      if (isatty(STDOUT_FILENO) == 1 || errno == EBADF)
-	 _error->Errno("tcgetattr", _("Can not write log (%s)"), _("Is stdout a terminal?"));
-   }
 
 
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
    {
    {
@@ -1141,44 +1146,60 @@ void pkgDPkgPM::StartPtyMagic()
 	 close(d->master);
 	 close(d->master);
 	 d->master = -1;
 	 d->master = -1;
       }
       }
+      if (d->slave != NULL)
+      {
+	 free(d->slave);
+	 d->slave = NULL;
+      }
       _error->DumpErrors(std::cerr);
       _error->DumpErrors(std::cerr);
    }
    }
    _error->RevertToStack();
    _error->RevertToStack();
 }
 }
 void pkgDPkgPM::SetupSlavePtyMagic()
 void pkgDPkgPM::SetupSlavePtyMagic()
 {
 {
-   if(d->master == -1)
+   if(d->master == -1 || d->slave == NULL)
       return;
       return;
 
 
    if (close(d->master) == -1)
    if (close(d->master) == -1)
       _error->FatalE("close", "Closing master %d in child failed!", d->master);
       _error->FatalE("close", "Closing master %d in child failed!", d->master);
+   d->master = -1;
    if (setsid() == -1)
    if (setsid() == -1)
       _error->FatalE("setsid", "Starting a new session for child failed!");
       _error->FatalE("setsid", "Starting a new session for child failed!");
 
 
-   int const slaveFd = open(d->slave, O_RDWR);
+   int const slaveFd = open(d->slave, O_RDWR | O_NOCTTY);
    if (slaveFd == -1)
    if (slaveFd == -1)
       _error->FatalE("open", _("Can not write log (%s)"), _("Is /dev/pts mounted?"));
       _error->FatalE("open", _("Can not write log (%s)"), _("Is /dev/pts mounted?"));
-
-   if (ioctl(slaveFd, TIOCSCTTY, 0) < 0)
+   else if (ioctl(slaveFd, TIOCSCTTY, 0) < 0)
       _error->FatalE("ioctl", "Setting TIOCSCTTY for slave fd %d failed!", slaveFd);
       _error->FatalE("ioctl", "Setting TIOCSCTTY for slave fd %d failed!", slaveFd);
    else
    else
    {
    {
-      for (unsigned short i = 0; i < 3; ++i)
+      unsigned short i = 0;
+      if (d->direct_stdin == true)
+	 ++i;
+      for (; i < 3; ++i)
 	 if (dup2(slaveFd, i) == -1)
 	 if (dup2(slaveFd, i) == -1)
 	    _error->FatalE("dup2", "Dupping %d to %d in child failed!", slaveFd, i);
 	    _error->FatalE("dup2", "Dupping %d to %d in child failed!", slaveFd, i);
 
 
-      if (tcsetattr(0, TCSANOW, &d->tt) < 0)
+      if (d->tt_is_valid == true && tcsetattr(STDIN_FILENO, TCSANOW, &d->tt) < 0)
 	 _error->FatalE("tcsetattr", "Setting in Setup via TCSANOW for slave fd %d failed!", slaveFd);
 	 _error->FatalE("tcsetattr", "Setting in Setup via TCSANOW for slave fd %d failed!", slaveFd);
    }
    }
+
+   if (slaveFd != -1)
+      close(slaveFd);
 }
 }
 void pkgDPkgPM::StopPtyMagic()
 void pkgDPkgPM::StopPtyMagic()
 {
 {
    if (d->slave != NULL)
    if (d->slave != NULL)
       free(d->slave);
       free(d->slave);
    d->slave = NULL;
    d->slave = NULL;
+   if (d->protect_slave_from_dying != -1)
+   {
+      close(d->protect_slave_from_dying);
+      d->protect_slave_from_dying = -1;
+   }
    if(d->master >= 0) 
    if(d->master >= 0) 
    {
    {
-      if (tcsetattr(0, TCSAFLUSH, &d->tt) == -1)
+      if (d->tt_is_valid == true && tcsetattr(STDIN_FILENO, TCSAFLUSH, &d->tt) == -1)
 	 _error->FatalE("tcsetattr", "Setting in Stop via TCSAFLUSH for stdin failed!");
 	 _error->FatalE("tcsetattr", "Setting in Stop via TCSAFLUSH for stdin failed!");
       close(d->master);
       close(d->master);
       d->master = -1;
       d->master = -1;
@@ -1261,9 +1282,8 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
 
 
    // support subpressing of triggers processing for special
    // support subpressing of triggers processing for special
    // cases like d-i that runs the triggers handling manually
    // cases like d-i that runs the triggers handling manually
-   bool const SmartConf = (_config->Find("PackageManager::Configure", "all") != "all");
    bool const TriggersPending = _config->FindB("DPkg::TriggersPending", false);
    bool const TriggersPending = _config->FindB("DPkg::TriggersPending", false);
-   if (_config->FindB("DPkg::ConfigurePending", SmartConf) == true)
+   if (_config->FindB("DPkg::ConfigurePending", true) == true)
       List.push_back(Item(Item::ConfigurePending, PkgIterator()));
       List.push_back(Item(Item::ConfigurePending, PkgIterator()));
 
 
    // for the progress
    // for the progress
@@ -1572,8 +1592,8 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
 
 
 	 // wait for input or output here
 	 // wait for input or output here
 	 FD_ZERO(&rfds);
 	 FD_ZERO(&rfds);
-	 if (d->master >= 0 && !d->stdin_is_dev_null)
-	    FD_SET(0, &rfds); 
+	 if (d->master >= 0 && d->direct_stdin == false && d->stdin_is_dev_null == false)
+	    FD_SET(STDIN_FILENO, &rfds);
 	 FD_SET(_dpkgin, &rfds);
 	 FD_SET(_dpkgin, &rfds);
 	 if(d->master >= 0)
 	 if(d->master >= 0)
 	    FD_SET(d->master, &rfds);
 	    FD_SET(d->master, &rfds);
@@ -1684,7 +1704,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
    if (apportPkg.end() == true || apportPkg->CurrentVer == 0)
    if (apportPkg.end() == true || apportPkg->CurrentVer == 0)
       return;
       return;
 
 
-   string pkgname, reportfile, srcpkgname, pkgver, arch;
+   string pkgname, reportfile, pkgver, arch;
    string::size_type pos;
    string::size_type pos;
    FILE *report;
    FILE *report;
 
 
@@ -1823,7 +1843,16 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
    time_t now = time(NULL);
    time_t now = time(NULL);
    fprintf(report, "Date: %s" , ctime(&now));
    fprintf(report, "Date: %s" , ctime(&now));
    fprintf(report, "Package: %s %s\n", pkgname.c_str(), pkgver.c_str());
    fprintf(report, "Package: %s %s\n", pkgname.c_str(), pkgver.c_str());
+#if APT_PKG_ABI >= 413
    fprintf(report, "SourcePackage: %s\n", Ver.SourcePkgName());
    fprintf(report, "SourcePackage: %s\n", Ver.SourcePkgName());
+#else
+   pkgRecords Recs(Cache);
+   pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
+   std::string srcpkgname = Parse.SourcePkg();
+   if(srcpkgname.empty())
+      srcpkgname = pkgname;
+   fprintf(report, "SourcePackage: %s\n", srcpkgname.c_str());
+#endif
    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
@@ -1863,8 +1892,15 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
       }
       }
    }
    }
 
 
-   // log the ordering 
-   const char *ops_str[] = {"Install", "Configure","Remove","Purge"};
+   // log the ordering, see dpkgpm.h and the "Ops" enum there
+   const char *ops_str[] = {
+      "Install",
+      "Configure",
+      "Remove",
+      "Purge",
+      "ConfigurePending",
+      "TriggersPending",
+   };
    fprintf(report, "AptOrdering:\n");
    fprintf(report, "AptOrdering:\n");
    for (vector<Item>::iterator I = List.begin(); I != List.end(); ++I)
    for (vector<Item>::iterator I = List.begin(); I != List.end(); ++I)
       if ((*I).Pkg != NULL)
       if ((*I).Pkg != NULL)

+ 37 - 40
apt-pkg/depcache.cc

@@ -33,7 +33,6 @@
 #include <vector>
 #include <vector>
 #include <algorithm>
 #include <algorithm>
 #include <iostream>
 #include <iostream>
-#include <sstream>
 #include <set>
 #include <set>
 
 
 #include <sys/stat.h>
 #include <sys/stat.h>
@@ -237,9 +236,11 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly)	/*{{
 
 
    FileFd StateFile;
    FileFd StateFile;
    string const state = _config->FindFile("Dir::State::extended_states");
    string const state = _config->FindFile("Dir::State::extended_states");
+   if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::State"), flNotFile(state)) == false)
+      return false;
 
 
    // if it does not exist, create a empty one
    // if it does not exist, create a empty one
-   if(!RealFileExists(state)) 
+   if(!RealFileExists(state))
    {
    {
       StateFile.Open(state, FileFd::WriteAtomic);
       StateFile.Open(state, FileFd::WriteAtomic);
       StateFile.Close();
       StateFile.Close();
@@ -250,17 +251,14 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly)	/*{{
       return _error->Error(_("Failed to open StateFile %s"),
       return _error->Error(_("Failed to open StateFile %s"),
 			   state.c_str());
 			   state.c_str());
 
 
-   FILE *OutFile;
-   string const outfile = state + ".tmp";
-   if((OutFile = fopen(outfile.c_str(),"w")) == NULL)
-      return _error->Error(_("Failed to write temporary StateFile %s"),
-			   outfile.c_str());
+   FileFd OutFile(state, FileFd::ReadWrite | FileFd::Atomic);
+   if (OutFile.IsOpen() == false || OutFile.Failed() == true)
+      return _error->Error(_("Failed to write temporary StateFile %s"), state.c_str());
 
 
    // first merge with the existing sections
    // first merge with the existing sections
    pkgTagFile tagfile(&StateFile);
    pkgTagFile tagfile(&StateFile);
    pkgTagSection section;
    pkgTagSection section;
    std::set<string> pkgs_seen;
    std::set<string> pkgs_seen;
-   const char *nullreorderlist[] = {0};
    while(tagfile.Step(section)) {
    while(tagfile.Step(section)) {
 	 string const pkgname = section.FindS("Package");
 	 string const pkgname = section.FindS("Package");
 	 string pkgarch = section.FindS("Architecture");
 	 string pkgarch = section.FindS("Architecture");
@@ -269,7 +267,7 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly)	/*{{
 	 // Silently ignore unknown packages and packages with no actual
 	 // Silently ignore unknown packages and packages with no actual
 	 // version.
 	 // version.
 	 pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch);
 	 pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch);
-	 if(pkg.end() || pkg.VersionList().end()) 
+	 if(pkg.end() || pkg.VersionList().end())
 	    continue;
 	    continue;
 	 StateCache const &P = PkgState[pkg->ID];
 	 StateCache const &P = PkgState[pkg->ID];
 	 bool newAuto = (P.Flags & Flag::Auto);
 	 bool newAuto = (P.Flags & Flag::Auto);
@@ -290,21 +288,17 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly)	/*{{
 	 if(_config->FindB("Debug::pkgAutoRemove",false))
 	 if(_config->FindB("Debug::pkgAutoRemove",false))
 	    std::clog << "Update existing AutoInstall info: " 
 	    std::clog << "Update existing AutoInstall info: " 
 		      << pkg.FullName() << std::endl;
 		      << pkg.FullName() << std::endl;
-	 TFRewriteData rewrite[3];
-	 rewrite[0].Tag = "Architecture";
-	 rewrite[0].Rewrite = pkg.Arch();
-	 rewrite[0].NewTag = 0;
-	 rewrite[1].Tag = "Auto-Installed";
-	 rewrite[1].Rewrite = newAuto ? "1" : "0";
-	 rewrite[1].NewTag = 0;
-	 rewrite[2].Tag = 0;
-	 TFRewrite(OutFile, section, nullreorderlist, rewrite);
-	 fprintf(OutFile,"\n");
+
+	 std::vector<pkgTagSection::Tag> rewrite;
+	 rewrite.push_back(pkgTagSection::Tag::Rewrite("Architecture", pkg.Arch()));
+	 rewrite.push_back(pkgTagSection::Tag::Rewrite("Auto-Installed", newAuto ? "1" : "0"));
+	 section.Write(OutFile, NULL, rewrite);
+	 if (OutFile.Write("\n", 1) == false)
+	    return false;
 	 pkgs_seen.insert(pkg.FullName());
 	 pkgs_seen.insert(pkg.FullName());
    }
    }
-   
+
    // then write the ones we have not seen yet
    // then write the ones we have not seen yet
-   std::ostringstream ostr;
    for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); ++pkg) {
    for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); ++pkg) {
       StateCache const &P = PkgState[pkg->ID];
       StateCache const &P = PkgState[pkg->ID];
       if(P.Flags & Flag::Auto) {
       if(P.Flags & Flag::Auto) {
@@ -323,19 +317,17 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly)	/*{{
 	    continue;
 	    continue;
 	 if(debug_autoremove)
 	 if(debug_autoremove)
 	    std::clog << "Writing new AutoInstall: " << pkg.FullName() << std::endl;
 	    std::clog << "Writing new AutoInstall: " << pkg.FullName() << std::endl;
-	 ostr.str(string(""));
-	 ostr << "Package: " << pkg.Name()
-	      << "\nArchitecture: " << pkgarch
-	      << "\nAuto-Installed: 1\n\n";
-	 fprintf(OutFile,"%s",ostr.str().c_str());
+	 std::string stanza = "Package: ";
+	 stanza.append(pkg.Name())
+	      .append("\nArchitecture: ").append(pkgarch)
+	      .append("\nAuto-Installed: 1\n\n");
+	 if (OutFile.Write(stanza.c_str(), stanza.length()) == false)
+	    return false;
       }
       }
    }
    }
-   fclose(OutFile);
-
-   // move the outfile over the real file and set permissions
-   rename(outfile.c_str(), state.c_str());
+   if (OutFile.Close() == false)
+      return false;
    chmod(state.c_str(), 0644);
    chmod(state.c_str(), 0644);
-
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -1313,14 +1305,18 @@ bool pkgDepCache::IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg,
    GrpIterator const Grp = Pkg.Group();
    GrpIterator const Grp = Pkg.Group();
    for (PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
    for (PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
    {
    {
-      // not installed or version synced: fine by definition
+      // not installed or self-check: fine by definition
+      if (P->CurrentVer == 0 || P == Pkg)
+	 continue;
+
+      // not having a candidate or being in sync
       // (simple string-compare as stuff like '1' == '0:1-0' can't happen here)
       // (simple string-compare as stuff like '1' == '0:1-0' can't happen here)
-      if (P->CurrentVer == 0 || strcmp(Pkg.CandVersion(), P.CandVersion()) == 0)
+      VerIterator CV = PkgState[P->ID].CandidateVerIter(*this);
+      if (CV.end() == true || strcmp(Pkg.CandVersion(), CV.VerStr()) == 0)
 	 continue;
 	 continue;
+
       // packages losing M-A:same can be out-of-sync
       // packages losing M-A:same can be out-of-sync
-      VerIterator CV = PkgState[P->ID].CandidateVerIter(*this);
-      if (unlikely(CV.end() == true) ||
-	    (CV->MultiArch & pkgCache::Version::Same) != pkgCache::Version::Same)
+      if ((CV->MultiArch & pkgCache::Version::Same) != pkgCache::Version::Same)
 	 continue;
 	 continue;
 
 
       // not downloadable means the package is obsolete, so allow out-of-sync
       // not downloadable means the package is obsolete, so allow out-of-sync
@@ -1330,7 +1326,8 @@ bool pkgDepCache::IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg,
       PkgState[Pkg->ID].iFlags |= AutoKept;
       PkgState[Pkg->ID].iFlags |= AutoKept;
       if (unlikely(DebugMarker == true))
       if (unlikely(DebugMarker == true))
 	 std::clog << OutputInDepth(Depth) << "Ignore MarkInstall of " << Pkg
 	 std::clog << OutputInDepth(Depth) << "Ignore MarkInstall of " << Pkg
-	    << " as its M-A:same siblings are not version-synced" << std::endl;
+	    << " as it is not in sync with its M-A:same sibling " << P
+	    << " (" << Pkg.CandVersion() << " != " << CV.VerStr() << ")" << std::endl;
       return false;
       return false;
    }
    }
 
 
@@ -1688,13 +1685,13 @@ pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator const &Pk
       
       
       for (VerFileIterator J = I.FileList(); J.end() == false; ++J)
       for (VerFileIterator J = I.FileList(); J.end() == false; ++J)
       {
       {
-	 if ((J.File()->Flags & Flag::NotSource) != 0)
+	 if (J.File().Flagged(Flag::NotSource))
 	    continue;
 	    continue;
 
 
 	 /* Stash the highest version of a not-automatic source, we use it
 	 /* Stash the highest version of a not-automatic source, we use it
 	    if there is nothing better */
 	    if there is nothing better */
-	 if ((J.File()->Flags & Flag::NotAutomatic) != 0 ||
-	     (J.File()->Flags & Flag::ButAutomaticUpgrades) != 0)
+	 if (J.File().Flagged(Flag::NotAutomatic) ||
+	     J.File().Flagged(Flag::ButAutomaticUpgrades))
 	 {
 	 {
 	    if (Last.end() == true)
 	    if (Last.end() == true)
 	       Last = I;
 	       Last = I;

+ 6 - 4
apt-pkg/depcache.h

@@ -1,6 +1,5 @@
 // -*- mode: c++; mode: fold -*-
 // -*- mode: c++; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: depcache.h,v 1.14 2001/02/20 07:03:17 jgg Exp $
 /* ######################################################################
 /* ######################################################################
 
 
    DepCache - Dependency Extension data for the cache
    DepCache - Dependency Extension data for the cache
@@ -109,7 +108,7 @@ class pkgDepCache : protected pkgCache::Namespace
     *
     *
     *  \return \b false if an error occurred.
     *  \return \b false if an error occurred.
     */
     */
-   APT_HIDDEN bool MarkRequired(InRootSetFunc &rootFunc);
+   bool MarkRequired(InRootSetFunc &rootFunc);
 
 
    /** \brief Set the StateCache::Garbage flag on all packages that
    /** \brief Set the StateCache::Garbage flag on all packages that
     *  should be removed.
     *  should be removed.
@@ -120,7 +119,7 @@ class pkgDepCache : protected pkgCache::Namespace
     *
     *
     *  \return \b false if an error occurred.
     *  \return \b false if an error occurred.
     */
     */
-   APT_HIDDEN bool Sweep();
+   bool Sweep();
 
 
    public:
    public:
    
    
@@ -164,6 +163,7 @@ class pkgDepCache : protected pkgCache::Namespace
     */
     */
    class ActionGroup
    class ActionGroup
    {
    {
+       void *d;
        pkgDepCache &cache;
        pkgDepCache &cache;
 
 
        bool released;
        bool released;
@@ -192,7 +192,7 @@ class pkgDepCache : protected pkgCache::Namespace
 	*  If this is the last action group, the automatic cache
 	*  If this is the last action group, the automatic cache
 	*  cleanup operations will be undertaken.
 	*  cleanup operations will be undertaken.
 	*/
 	*/
-       ~ActionGroup();
+       virtual ~ActionGroup();
    };
    };
 
 
    /** \brief Returns \b true for packages matching a regular
    /** \brief Returns \b true for packages matching a regular
@@ -503,6 +503,8 @@ class pkgDepCache : protected pkgCache::Namespace
 	 bool const rPurge, unsigned long const Depth, bool const FromUser);
 	 bool const rPurge, unsigned long const Depth, bool const FromUser);
 
 
    private:
    private:
+   void *d;
+
    APT_HIDDEN bool IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
    APT_HIDDEN bool IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
 			unsigned long const Depth, bool const FromUser);
 			unsigned long const Depth, bool const FromUser);
 };
 };

+ 70 - 62
apt-pkg/edsp.cc

@@ -39,64 +39,26 @@
 using std::string;
 using std::string;
 
 
 // we could use pkgCache::DepType and ::Priority, but these would be localized strings…
 // we could use pkgCache::DepType and ::Priority, but these would be localized strings…
-const char * const EDSP::PrioMap[] = {0, "important", "required", "standard",
+const char * const PrioMap[] = {0, "important", "required", "standard",
 				      "optional", "extra"};
 				      "optional", "extra"};
-const char * const EDSP::DepMap[] = {"", "Depends", "Pre-Depends", "Suggests",
+const char * const DepMap[] = {"", "Depends", "Pre-Depends", "Suggests",
 				     "Recommends" , "Conflicts", "Replaces",
 				     "Recommends" , "Conflicts", "Replaces",
 				     "Obsoletes", "Breaks", "Enhances"};
 				     "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;
-   std::vector<std::string> archs = APT::Configuration::getArchitectures();
-   for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg)
-   {
-      std::string const arch = Pkg.Arch();
-      if (std::find(archs.begin(), archs.end(), arch) == archs.end())
-	 continue;
-      for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver, ++p)
-      {
-	 WriteScenarioVersion(Cache, output, Pkg, Ver);
-	 WriteScenarioDependency(output, 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(output, 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,
+
+// WriteScenarioVersion							/*{{{*/
+static void WriteScenarioVersion(pkgDepCache &Cache, FILE* output, pkgCache::PkgIterator const &Pkg,
 				pkgCache::VerIterator const &Ver)
 				pkgCache::VerIterator const &Ver)
 {
 {
    fprintf(output, "Package: %s\n", Pkg.Name());
    fprintf(output, "Package: %s\n", Pkg.Name());
+#if APT_PKG_ABI >= 413
    fprintf(output, "Source: %s\n", Ver.SourcePkgName());
    fprintf(output, "Source: %s\n", Ver.SourcePkgName());
+#else
+   pkgRecords Recs(Cache);
+   pkgRecords::Parser &rec = Recs.Lookup(Ver.FileList());
+   string srcpkg = rec.SourcePkg().empty() ? Pkg.Name() : rec.SourcePkg();
+   fprintf(output, "Source: %s\n", srcpkg.c_str());
+#endif
    fprintf(output, "Architecture: %s\n", Ver.Arch());
    fprintf(output, "Architecture: %s\n", Ver.Arch());
    fprintf(output, "Version: %s\n", Ver.VerStr());
    fprintf(output, "Version: %s\n", Ver.VerStr());
    if (Pkg.CurrentVer() == Ver)
    if (Pkg.CurrentVer() == Ver)
@@ -122,7 +84,7 @@ void EDSP::WriteScenarioVersion(pkgDepCache &Cache, FILE* output, pkgCache::PkgI
       signed short const p = Cache.GetPolicy().GetPriority(File);
       signed short const p = Cache.GetPolicy().GetPriority(File);
       if (Pin < p)
       if (Pin < p)
 	 Pin = p;
 	 Pin = p;
-      if ((File->Flags & pkgCache::Flag::NotSource) != pkgCache::Flag::NotSource) {
+      if (File.Flagged(pkgCache::Flag::NotSource) == false) {
 	 string Release = File.RelStr();
 	 string Release = File.RelStr();
 	 if (!Release.empty())
 	 if (!Release.empty())
 	    Releases.insert(Release);
 	    Releases.insert(Release);
@@ -140,8 +102,8 @@ void EDSP::WriteScenarioVersion(pkgDepCache &Cache, FILE* output, pkgCache::PkgI
       fprintf(output, "APT-Automatic: yes\n");
       fprintf(output, "APT-Automatic: yes\n");
 }
 }
 									/*}}}*/
 									/*}}}*/
-// EDSP::WriteScenarioDependency					/*{{{*/
-void EDSP::WriteScenarioDependency( FILE* output, pkgCache::VerIterator const &Ver)
+// WriteScenarioDependency						/*{{{*/
+static void WriteScenarioDependency( FILE* output, pkgCache::VerIterator const &Ver)
 {
 {
    std::string dependencies[pkgCache::Dep::Enhances + 1];
    std::string dependencies[pkgCache::Dep::Enhances + 1];
    bool orGroup = false;
    bool orGroup = false;
@@ -176,8 +138,8 @@ void EDSP::WriteScenarioDependency( FILE* output, pkgCache::VerIterator const &V
       fprintf(output, "Provides: %s\n", provides.c_str()+2);
       fprintf(output, "Provides: %s\n", provides.c_str()+2);
 }
 }
 									/*}}}*/
 									/*}}}*/
-// EDSP::WriteScenarioLimitedDependency					/*{{{*/
-void EDSP::WriteScenarioLimitedDependency(FILE* output,
+// WriteScenarioLimitedDependency					/*{{{*/
+static void WriteScenarioLimitedDependency(FILE* output,
 					  pkgCache::VerIterator const &Ver,
 					  pkgCache::VerIterator const &Ver,
 					  APT::PackageSet const &pkgset)
 					  APT::PackageSet const &pkgset)
 {
 {
@@ -228,6 +190,52 @@ void EDSP::WriteScenarioLimitedDependency(FILE* output,
       fprintf(output, "Provides: %s\n", provides.c_str()+2);
       fprintf(output, "Provides: %s\n", provides.c_str()+2);
 }
 }
 									/*}}}*/
 									/*}}}*/
+// 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;
+   std::vector<std::string> archs = APT::Configuration::getArchitectures();
+   for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg)
+   {
+      std::string const arch = Pkg.Arch();
+      if (std::find(archs.begin(), archs.end(), arch) == archs.end())
+	 continue;
+      for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver, ++p)
+      {
+	 WriteScenarioVersion(Cache, output, Pkg, Ver);
+	 WriteScenarioDependency(output, 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(output, Ver, pkgset);
+	 fprintf(output, "\n");
+	 if (Progress != NULL && p % 100 == 0)
+	    Progress->Progress(p);
+      }
+   if (Progress != NULL)
+      Progress->Done();
+   return true;
+}
+									/*}}}*/
 // EDSP::WriteRequest - to the given file descriptor			/*{{{*/
 // EDSP::WriteRequest - to the given file descriptor			/*{{{*/
 bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade,
 bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade,
 			bool const DistUpgrade, bool const AutoRemove,
 			bool const DistUpgrade, bool const AutoRemove,
@@ -358,13 +366,13 @@ bool EDSP::ReadResponse(int const input, pkgDepCache &Cache, OpProgress *Progres
 	return true;
 	return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// EDSP::ReadLine - first line from the given file descriptor		/*{{{*/
+// ReadLine - first line from the given file descriptor			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Little helper method to read a complete line into a string. Similar to
 /* 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
    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
    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 */
    a supported action according to the manpages and results are undefined */
-bool EDSP::ReadLine(int const input, std::string &line) {
+static bool ReadLine(int const input, std::string &line) {
 	char one;
 	char one;
 	ssize_t data = 0;
 	ssize_t data = 0;
 	line.erase();
 	line.erase();
@@ -383,11 +391,11 @@ bool EDSP::ReadLine(int const input, std::string &line) {
 	return false;
 	return false;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// EDSP::StringToBool - convert yes/no to bool				/*{{{*/
+// StringToBool - convert yes/no to bool				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* we are not as lazy as we are in the global StringToBool as we really
 /* 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 */
    only accept yes/no here - but we will ignore leading spaces */
-bool EDSP::StringToBool(char const *answer, bool const defValue) {
+static bool StringToBool(char const *answer, bool const defValue) {
    for (; isspace(*answer) != 0; ++answer);
    for (; isspace(*answer) != 0; ++answer);
    if (strncasecmp(answer, "yes", 3) == 0)
    if (strncasecmp(answer, "yes", 3) == 0)
       return true;
       return true;
@@ -436,11 +444,11 @@ bool EDSP::ReadRequest(int const input, std::list<std::string> &install,
 	    request = &remove;
 	    request = &remove;
 	 }
 	 }
 	 else if (line.compare(0, 8, "Upgrade:") == 0)
 	 else if (line.compare(0, 8, "Upgrade:") == 0)
-	    upgrade = EDSP::StringToBool(line.c_str() + 9, false);
+	    upgrade = StringToBool(line.c_str() + 9, false);
 	 else if (line.compare(0, 13, "Dist-Upgrade:") == 0)
 	 else if (line.compare(0, 13, "Dist-Upgrade:") == 0)
-	    distUpgrade = EDSP::StringToBool(line.c_str() + 14, false);
+	    distUpgrade = StringToBool(line.c_str() + 14, false);
 	 else if (line.compare(0, 11, "Autoremove:") == 0)
 	 else if (line.compare(0, 11, "Autoremove:") == 0)
-	    autoRemove = EDSP::StringToBool(line.c_str() + 12, false);
+	    autoRemove = StringToBool(line.c_str() + 12, false);
 	 else if (line.compare(0, 13, "Architecture:") == 0)
 	 else if (line.compare(0, 13, "Architecture:") == 0)
 	    _config->Set("APT::Architecture", line.c_str() + 14);
 	    _config->Set("APT::Architecture", line.c_str() + 14);
 	 else if (line.compare(0, 14, "Architectures:") == 0)
 	 else if (line.compare(0, 14, "Architectures:") == 0)

+ 13 - 29
apt-pkg/edsp.h

@@ -27,24 +27,8 @@
 class pkgDepCache;
 class pkgDepCache;
 class OpProgress;
 class OpProgress;
 
 
-class EDSP								/*{{{*/
+namespace EDSP								/*{{{*/
 {
 {
-	// we could use pkgCache::DepType and ::Priority, but these would be localized strings…
-	static const char * const PrioMap[];
-	static const char * const DepMap[];
-
-	APT_HIDDEN bool static ReadLine(int const input, std::string &line);
-	APT_HIDDEN bool static StringToBool(char const *answer, bool const defValue);
-
-	APT_HIDDEN void static WriteScenarioVersion(pkgDepCache &Cache, FILE* output,
-					 pkgCache::PkgIterator const &Pkg,
-					 pkgCache::VerIterator const &Ver);
-	APT_HIDDEN void static WriteScenarioDependency(FILE* output,
-					    pkgCache::VerIterator const &Ver);
-	APT_HIDDEN void static WriteScenarioLimitedDependency(FILE* output,
-						   pkgCache::VerIterator const &Ver,
-						   APT::PackageSet const &pkgset);
-public:
 	/** \brief creates the EDSP request stanza
 	/** \brief creates the EDSP request stanza
 	 *
 	 *
 	 *  In the EDSP protocol the first thing send to the resolver is a stanza
 	 *  In the EDSP protocol the first thing send to the resolver is a stanza
@@ -61,7 +45,7 @@ public:
 	 *
 	 *
 	 *  \return true if request was composed successfully, otherwise false
 	 *  \return true if request was composed successfully, otherwise false
 	 */
 	 */
-	bool static WriteRequest(pkgDepCache &Cache, FILE* output,
+	bool WriteRequest(pkgDepCache &Cache, FILE* output,
 				 bool const upgrade = false,
 				 bool const upgrade = false,
 				 bool const distUpgrade = false,
 				 bool const distUpgrade = false,
 				 bool const autoRemove = false,
 				 bool const autoRemove = false,
@@ -84,7 +68,7 @@ public:
 	 *
 	 *
 	 *  \return true if universe was composed successfully, otherwise false
 	 *  \return true if universe was composed successfully, otherwise false
 	 */
 	 */
-	bool static WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress = NULL);
+	bool WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress = NULL);
 
 
 	/** \brief creates a limited scenario representing the package universe
 	/** \brief creates a limited scenario representing the package universe
 	 *
 	 *
@@ -101,7 +85,7 @@ public:
 	 *
 	 *
 	 *  \return true if universe was composed successfully, otherwise false
 	 *  \return true if universe was composed successfully, otherwise false
 	 */
 	 */
-	bool static WriteLimitedScenario(pkgDepCache &Cache, FILE* output,
+	bool WriteLimitedScenario(pkgDepCache &Cache, FILE* output,
 					 APT::PackageSet const &pkgset,
 					 APT::PackageSet const &pkgset,
 					 OpProgress *Progress = NULL);
 					 OpProgress *Progress = NULL);
 
 
@@ -118,7 +102,7 @@ public:
 	 *
 	 *
 	 *  \return true if a solution is found and applied correctly, otherwise false
 	 *  \return true if a solution is found and applied correctly, otherwise false
 	 */
 	 */
-	bool static ReadResponse(int const input, pkgDepCache &Cache, OpProgress *Progress = NULL);
+	bool ReadResponse(int const input, pkgDepCache &Cache, OpProgress *Progress = NULL);
 
 
 	/** \brief search and read the request stanza for action later
 	/** \brief search and read the request stanza for action later
 	 *
 	 *
@@ -136,7 +120,7 @@ public:
 	 *
 	 *
 	 *  \return true if the request could be found and worked on, otherwise false
 	 *  \return true if the request could be found and worked on, otherwise false
 	 */
 	 */
-	bool static ReadRequest(int const input, std::list<std::string> &install,
+	bool ReadRequest(int const input, std::list<std::string> &install,
 			std::list<std::string> &remove, bool &upgrade,
 			std::list<std::string> &remove, bool &upgrade,
 			bool &distUpgrade, bool &autoRemove);
 			bool &distUpgrade, bool &autoRemove);
 
 
@@ -152,7 +136,7 @@ public:
 	 *
 	 *
 	 *  \return false if the request couldn't be applied, true otherwise
 	 *  \return false if the request couldn't be applied, true otherwise
 	 */
 	 */
-	bool static ApplyRequest(std::list<std::string> const &install,
+	bool ApplyRequest(std::list<std::string> const &install,
 				 std::list<std::string> const &remove,
 				 std::list<std::string> const &remove,
 				 pkgDepCache &Cache);
 				 pkgDepCache &Cache);
 
 
@@ -168,7 +152,7 @@ public:
 	 *
 	 *
 	 *  \return true if solution could be written, otherwise false
 	 *  \return true if solution could be written, otherwise false
 	 */
 	 */
-	bool static WriteSolution(pkgDepCache &Cache, FILE* output);
+	bool WriteSolution(pkgDepCache &Cache, FILE* output);
 
 
 	/** \brief sends a progress report
 	/** \brief sends a progress report
 	 *
 	 *
@@ -176,7 +160,7 @@ public:
 	 *  \param message the solver wants the user to see
 	 *  \param message the solver wants the user to see
 	 *  \param output the front-end listens for progress report
 	 *  \param output the front-end listens for progress report
 	 */
 	 */
-	bool static WriteProgress(unsigned short const percent, const char* const message, FILE* output);
+	bool WriteProgress(unsigned short const percent, const char* const message, FILE* output);
 
 
 	/** \brief sends an error report
 	/** \brief sends an error report
 	 *
 	 *
@@ -193,7 +177,7 @@ public:
 	 *  \param message is free form text to describe the error
 	 *  \param message is free form text to describe the error
 	 *  \param output the front-end listens for error messages
 	 *  \param output the front-end listens for error messages
 	 */
 	 */
-	bool static WriteError(char const * const uuid, std::string const &message, FILE* output);
+	bool WriteError(char const * const uuid, std::string const &message, FILE* output);
 
 
 
 
 	/** \brief executes the given solver and returns the pipe ends
 	/** \brief executes the given solver and returns the pipe ends
@@ -207,8 +191,8 @@ public:
 	 *
 	 *
 	 *  \return PID of the started solver or 0 if failure occurred
 	 *  \return PID of the started solver or 0 if failure occurred
 	 */
 	 */
-	pid_t static ExecuteSolver(const char* const solver, int * const solver_in, int * const solver_out, bool /*overload*/);
-	APT_DEPRECATED bool static ExecuteSolver(const char* const solver, int *solver_in, int *solver_out);
+	pid_t ExecuteSolver(const char* const solver, int * const solver_in, int * const solver_out, bool /*overload*/);
+	APT_DEPRECATED bool ExecuteSolver(const char* const solver, int *solver_in, int *solver_out);
 
 
 	/** \brief call an external resolver to handle the request
 	/** \brief call an external resolver to handle the request
 	 *
 	 *
@@ -224,7 +208,7 @@ public:
 	 *  \return true if the solver has successfully solved the problem,
 	 *  \return true if the solver has successfully solved the problem,
 	 *  otherwise false
 	 *  otherwise false
 	 */
 	 */
-	bool static ResolveExternal(const char* const solver, pkgDepCache &Cache,
+	bool ResolveExternal(const char* const solver, pkgDepCache &Cache,
 				    bool const upgrade, bool const distUpgrade,
 				    bool const upgrade, bool const distUpgrade,
 				    bool const autoRemove, OpProgress *Progress = NULL);
 				    bool const autoRemove, OpProgress *Progress = NULL);
 };
 };

+ 6 - 5
apt-pkg/edsp/edspindexfile.cc

@@ -49,15 +49,14 @@ bool edspIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 
 
    if (Prog != NULL)
    if (Prog != NULL)
       Prog->SubProgress(0,File);
       Prog->SubProgress(0,File);
-   if (Gen.SelectFile(File,std::string(),*this) == false)
+   if (Gen.SelectFile(File, *this, "", "edsp") == false)
       return _error->Error("Problem with SelectFile %s",File.c_str());
       return _error->Error("Problem with SelectFile %s",File.c_str());
 
 
    // Store the IMS information
    // Store the IMS information
    pkgCache::PkgFileIterator CFile = Gen.GetCurFile();
    pkgCache::PkgFileIterator CFile = Gen.GetCurFile();
+   pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(CFile);
    CFile->Size = Pkg.FileSize();
    CFile->Size = Pkg.FileSize();
    CFile->mtime = Pkg.ModificationTime();
    CFile->mtime = Pkg.ModificationTime();
-   map_stringitem_t const storage = Gen.StoreString(pkgCacheGenerator::MIXED, "edsp::scenario");
-   CFile->Archive = storage;
 
 
    if (Gen.MergeList(Parser) == false)
    if (Gen.MergeList(Parser) == false)
       return _error->Error("Problem with MergeList %s",File.c_str());
       return _error->Error("Problem with MergeList %s",File.c_str());
@@ -65,7 +64,7 @@ bool edspIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 }
 }
 									/*}}}*/
 									/*}}}*/
 // Index File types for APT						/*{{{*/
 // Index File types for APT						/*{{{*/
-class edspIFType: public pkgIndexFile::Type
+class APT_HIDDEN edspIFType: public pkgIndexFile::Type
 {
 {
    public:
    public:
    virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator) const
    virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator) const
@@ -75,10 +74,12 @@ class edspIFType: public pkgIndexFile::Type
    };
    };
    edspIFType() {Label = "EDSP scenario file";};
    edspIFType() {Label = "EDSP scenario file";};
 };
 };
-static edspIFType _apt_Universe;
+APT_HIDDEN edspIFType _apt_Universe;
 
 
 const pkgIndexFile::Type *edspIndex::GetType() const
 const pkgIndexFile::Type *edspIndex::GetType() const
 {
 {
    return &_apt_Universe;
    return &_apt_Universe;
 }
 }
 									/*}}}*/
 									/*}}}*/
+
+edspIndex::~edspIndex() {}

+ 2 - 1
apt-pkg/edsp/edspindexfile.h

@@ -18,7 +18,7 @@
 class OpProgress;
 class OpProgress;
 class pkgCacheGenerator;
 class pkgCacheGenerator;
 
 
-class edspIndex : public debStatusIndex
+class APT_HIDDEN edspIndex : public debStatusIndex
 {
 {
    /** \brief dpointer placeholder (for later in case we need it) */
    /** \brief dpointer placeholder (for later in case we need it) */
    void *d;
    void *d;
@@ -30,6 +30,7 @@ class edspIndex : public debStatusIndex
    virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const;
    virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const;
 
 
    edspIndex(std::string File);
    edspIndex(std::string File);
+   virtual ~edspIndex();
 };
 };
 
 
 #endif
 #endif

+ 4 - 2
apt-pkg/edsp/edsplistparser.cc

@@ -86,9 +86,11 @@ bool edspListParser::ParseStatus(pkgCache::PkgIterator &Pkg,
 }
 }
 									/*}}}*/
 									/*}}}*/
 // ListParser::LoadReleaseInfo - Load the release information		/*{{{*/
 // ListParser::LoadReleaseInfo - Load the release information		/*{{{*/
-APT_CONST bool edspListParser::LoadReleaseInfo(pkgCache::PkgFileIterator & /*FileI*/,
-				    FileFd & /*File*/, std::string /*component*/)
+APT_CONST bool edspListParser::LoadReleaseInfo(pkgCache::RlsFileIterator & /*FileI*/,
+				    FileFd & /*File*/, std::string const &/*component*/)
 {
 {
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
+
+edspListParser::~edspListParser() {}

+ 5 - 3
apt-pkg/edsp/edsplistparser.h

@@ -25,8 +25,9 @@
 
 
 class FileFd;
 class FileFd;
 
 
-class edspListParser : public debListParser
+class APT_HIDDEN edspListParser : public debListParser
 {
 {
+   void *d;
    public:
    public:
    virtual bool NewVersion(pkgCache::VerIterator &Ver);
    virtual bool NewVersion(pkgCache::VerIterator &Ver);
    virtual std::string Description();
    virtual std::string Description();
@@ -34,10 +35,11 @@ class edspListParser : public debListParser
    virtual MD5SumValue Description_md5();
    virtual MD5SumValue Description_md5();
    virtual unsigned short VersionHash();
    virtual unsigned short VersionHash();
 
 
-   bool LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,FileFd &File,
-			std::string section);
+   bool LoadReleaseInfo(pkgCache::RlsFileIterator &FileI,FileFd &File,
+			std::string const &section);
 
 
    edspListParser(FileFd *File, std::string const &Arch = "");
    edspListParser(FileFd *File, std::string const &Arch = "");
+   virtual ~edspListParser();
 
 
    protected:
    protected:
    virtual bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver);
    virtual bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver);

+ 2 - 2
apt-pkg/edsp/edspsystem.cc

@@ -26,8 +26,6 @@
 #include <apti18n.h>
 #include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 
 
-edspSystem edspSys;
-
 // System::debSystem - Constructor					/*{{{*/
 // System::debSystem - Constructor					/*{{{*/
 edspSystem::edspSystem()
 edspSystem::edspSystem()
 {
 {
@@ -126,3 +124,5 @@ bool edspSystem::FindIndex(pkgCache::PkgFileIterator File,
    return false;
    return false;
 }
 }
 									/*}}}*/
 									/*}}}*/
+
+APT_HIDDEN edspSystem edspSys;

+ 2 - 4
apt-pkg/edsp/edspsystem.h

@@ -22,7 +22,7 @@ class pkgIndexFile;
 class pkgPackageManager;
 class pkgPackageManager;
 class edspIndex;
 class edspIndex;
 
 
-class edspSystem : public pkgSystem
+class APT_HIDDEN edspSystem : public pkgSystem
 {
 {
    /** \brief dpointer placeholder (for later in case we need it) */
    /** \brief dpointer placeholder (for later in case we need it) */
    void *d;
    void *d;
@@ -42,9 +42,7 @@ class edspSystem : public pkgSystem
 			  pkgIndexFile *&Found) const;
 			  pkgIndexFile *&Found) const;
 
 
    edspSystem();
    edspSystem();
-   ~edspSystem();
+   virtual ~edspSystem();
 };
 };
 
 
-extern edspSystem edspSys;
-
 #endif
 #endif

+ 63 - 77
apt-pkg/indexcopy.cc

@@ -108,10 +108,7 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
       }
       }
       if (_error->PendingError() == true)
       if (_error->PendingError() == true)
 	 return false;
 	 return false;
-      FILE *TargetFl = fdopen(dup(Target.Fd()),"w");
-      if (TargetFl == 0)
-	 return _error->Errno("fdopen","Failed to reopen fd");
-      
+
       // Setup the progress meter
       // Setup the progress meter
       if(Progress)
       if(Progress)
 	 Progress->OverallProgress(CurrentSize,TotalSize,FileSize,
 	 Progress->OverallProgress(CurrentSize,TotalSize,FileSize,
@@ -132,14 +129,11 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
 	 string File;
 	 string File;
 	 unsigned long long Size;
 	 unsigned long long Size;
 	 if (GetFile(File,Size) == false)
 	 if (GetFile(File,Size) == false)
-	 {
-	    fclose(TargetFl);
 	    return false;
 	    return false;
-	 }
-	 
+
 	 if (Chop != 0)
 	 if (Chop != 0)
 	    File = OrigPath + ChopDirs(File,Chop);
 	    File = OrigPath + ChopDirs(File,Chop);
-	 
+
 	 // See if the file exists
 	 // See if the file exists
 	 if (NoStat == false || Hits < 10)
 	 if (NoStat == false || Hits < 10)
 	 {
 	 {
@@ -157,10 +151,10 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
 	       if (Chop != 0)
 	       if (Chop != 0)
 		  File = OrigPath + ChopDirs(File,Chop);
 		  File = OrigPath + ChopDirs(File,Chop);
 	    }
 	    }
-	    
+
 	    // Get the size
 	    // Get the size
 	    struct stat Buf;
 	    struct stat Buf;
-	    if (stat((CDROM + Prefix + File).c_str(),&Buf) != 0 || 
+	    if (stat((CDROM + Prefix + File).c_str(),&Buf) != 0 ||
 		Buf.st_size == 0)
 		Buf.st_size == 0)
 	    {
 	    {
 	       bool Mangled = false;
 	       bool Mangled = false;
@@ -173,7 +167,7 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
 		  File.replace(Start,End-Start,"binary-all");
 		  File.replace(Start,End-Start,"binary-all");
 		  Mangled = true;
 		  Mangled = true;
 	       }
 	       }
-	       
+
 	       if (Mangled == false ||
 	       if (Mangled == false ||
 		   stat((CDROM + Prefix + File).c_str(),&Buf) != 0)
 		   stat((CDROM + Prefix + File).c_str(),&Buf) != 0)
 	       {
 	       {
@@ -181,9 +175,9 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
 		     clog << "Missed(2): " << OrigFile << endl;
 		     clog << "Missed(2): " << OrigFile << endl;
 		  NotFound++;
 		  NotFound++;
 		  continue;
 		  continue;
-	       }	       
-	    }	    
-	    			    	    
+	       }
+	    }
+
 	    // Size match
 	    // Size match
 	    if ((unsigned long long)Buf.st_size != Size)
 	    if ((unsigned long long)Buf.st_size != Size)
 	    {
 	    {
@@ -193,21 +187,17 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
 	       continue;
 	       continue;
 	    }
 	    }
 	 }
 	 }
-	 
+
 	 Packages++;
 	 Packages++;
 	 Hits++;
 	 Hits++;
-	 
-	 if (RewriteEntry(TargetFl,File) == false)
-	 {
-	    fclose(TargetFl);
+
+	 if (RewriteEntry(Target, File) == false)
 	    return false;
 	    return false;
-	 }
       }
       }
-      fclose(TargetFl);
 
 
       if (Debug == true)
       if (Debug == true)
 	 cout << " Processed by using Prefix '" << Prefix << "' and chop " << Chop << endl;
 	 cout << " Processed by using Prefix '" << Prefix << "' and chop " << Chop << endl;
-	 
+
       if (_config->FindB("APT::CDROM::NoAct",false) == false)
       if (_config->FindB("APT::CDROM::NoAct",false) == false)
       {
       {
 	 // Move out of the partial directory
 	 // Move out of the partial directory
@@ -216,40 +206,40 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
 	 FinalF += URItoFileName(S);
 	 FinalF += URItoFileName(S);
 	 if (rename(TargetF.c_str(),FinalF.c_str()) != 0)
 	 if (rename(TargetF.c_str(),FinalF.c_str()) != 0)
 	    return _error->Errno("rename","Failed to rename");
 	    return _error->Errno("rename","Failed to rename");
+	 ChangeOwnerAndPermissionOfFile("CopyPackages", FinalF.c_str(), "root", "root", 0644);
       }
       }
-	 
+
       /* Mangle the source to be in the proper notation with
       /* Mangle the source to be in the proper notation with
-       	 prefix dist [component] */ 
+	 prefix dist [component] */
       *I = string(*I,Prefix.length());
       *I = string(*I,Prefix.length());
       ConvertToSourceList(CDROM,*I);
       ConvertToSourceList(CDROM,*I);
       *I = Prefix + ' ' + *I;
       *I = Prefix + ' ' + *I;
-      
+
       CurrentSize += FileSize;
       CurrentSize += FileSize;
-   }   
+   }
    if(Progress)
    if(Progress)
       Progress->Done();
       Progress->Done();
-   
+
    // Some stats
    // Some stats
    if(log) {
    if(log) {
       stringstream msg;
       stringstream msg;
       if(NotFound == 0 && WrongSize == 0)
       if(NotFound == 0 && WrongSize == 0)
 	 ioprintf(msg, _("Wrote %i records.\n"), Packages);
 	 ioprintf(msg, _("Wrote %i records.\n"), Packages);
       else if (NotFound != 0 && WrongSize == 0)
       else if (NotFound != 0 && WrongSize == 0)
-	 ioprintf(msg, _("Wrote %i records with %i missing files.\n"), 
+	 ioprintf(msg, _("Wrote %i records with %i missing files.\n"),
 		  Packages, NotFound);
 		  Packages, NotFound);
       else if (NotFound == 0 && WrongSize != 0)
       else if (NotFound == 0 && WrongSize != 0)
-	 ioprintf(msg, _("Wrote %i records with %i mismatched files\n"), 
+	 ioprintf(msg, _("Wrote %i records with %i mismatched files\n"),
 		  Packages, WrongSize);
 		  Packages, WrongSize);
       if (NotFound != 0 && WrongSize != 0)
       if (NotFound != 0 && WrongSize != 0)
 	 ioprintf(msg, _("Wrote %i records with %i missing files and %i mismatched files\n"), Packages, NotFound, WrongSize);
 	 ioprintf(msg, _("Wrote %i records with %i missing files and %i mismatched files\n"), Packages, NotFound, WrongSize);
    }
    }
-   
+
    if (Packages == 0)
    if (Packages == 0)
       _error->Warning("No valid records were found.");
       _error->Warning("No valid records were found.");
 
 
    if (NotFound + WrongSize > 10)
    if (NotFound + WrongSize > 10)
       _error->Warning("A lot of entries were discarded, something may be wrong.\n");
       _error->Warning("A lot of entries were discarded, something may be wrong.\n");
-   
 
 
    return true;
    return true;
 }
 }
@@ -266,10 +256,10 @@ string IndexCopy::ChopDirs(string Path,unsigned int Depth)
       Depth--;
       Depth--;
    }
    }
    while (I != string::npos && Depth != 0);
    while (I != string::npos && Depth != 0);
-   
+
    if (I == string::npos)
    if (I == string::npos)
       return string();
       return string();
-   
+
    return string(Path,I+1);
    return string(Path,I+1);
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -432,17 +422,15 @@ bool PackageCopy::GetFile(string &File,unsigned long long &Size)
 }
 }
 									/*}}}*/
 									/*}}}*/
 // PackageCopy::RewriteEntry - Rewrite the entry with a new filename	/*{{{*/
 // PackageCopy::RewriteEntry - Rewrite the entry with a new filename	/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool PackageCopy::RewriteEntry(FILE *Target,string File)
+bool PackageCopy::RewriteEntry(FileFd &Target,string const &File)
 {
 {
-   TFRewriteData Changes[] = {{ "Filename", File.c_str(), NULL },
-                              { NULL, NULL, NULL }};
-   
-   if (TFRewrite(Target,*Section,TFRewritePackageOrder,Changes) == false)
+   string const Dir(File,0,File.rfind('/'));
+   std::vector<pkgTagSection::Tag> Changes;
+   Changes.push_back(pkgTagSection::Tag::Rewrite("Filename", File));
+
+   if (Section->Write(Target, TFRewritePackageOrder, Changes) == false)
       return false;
       return false;
-   fputc('\n',Target);
-   return true;
+   return Target.Write("\n", 1);
 }
 }
 									/*}}}*/
 									/*}}}*/
 // SourceCopy::GetFile - Get the file information from the section	/*{{{*/
 // SourceCopy::GetFile - Get the file information from the section	/*{{{*/
@@ -477,23 +465,18 @@ bool SourceCopy::GetFile(string &File,unsigned long long &Size)
 }
 }
 									/*}}}*/
 									/*}}}*/
 // SourceCopy::RewriteEntry - Rewrite the entry with a new filename	/*{{{*/
 // SourceCopy::RewriteEntry - Rewrite the entry with a new filename	/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool SourceCopy::RewriteEntry(FILE *Target,string File)
+bool SourceCopy::RewriteEntry(FileFd &Target, std::string const &File)
 {
 {
-   string Dir(File,0,File.rfind('/'));
-   TFRewriteData Changes[] = {{ "Directory", Dir.c_str(), NULL },
-                              { NULL, NULL, NULL }};
-   
-   if (TFRewrite(Target,*Section,TFRewriteSourceOrder,Changes) == false)
+   string const Dir(File,0,File.rfind('/'));
+   std::vector<pkgTagSection::Tag> Changes;
+   Changes.push_back(pkgTagSection::Tag::Rewrite("Directory", Dir));
+
+   if (Section->Write(Target, TFRewriteSourceOrder, Changes) == false)
       return false;
       return false;
-   fputc('\n',Target);
-   return true;
+   return Target.Write("\n", 1);
 }
 }
 									/*}}}*/
 									/*}}}*/
-// SigVerify::Verify - Verify a files md5sum against its metaindex     	/*{{{*/
-// ---------------------------------------------------------------------
-/* */
+// SigVerify::Verify - Verify a files md5sum against its metaindex	/*{{{*/
 bool SigVerify::Verify(string prefix, string file, indexRecords *MetaIndex)
 bool SigVerify::Verify(string prefix, string file, indexRecords *MetaIndex)
 {
 {
    const indexRecords::checkSum *Record = MetaIndex->Lookup(file);
    const indexRecords::checkSum *Record = MetaIndex->Lookup(file);
@@ -546,8 +529,9 @@ bool SigVerify::CopyMetaIndex(string CDROM, string CDName,		/*{{{*/
       FileFd Rel;
       FileFd Rel;
       Target.Open(TargetF,FileFd::WriteAtomic);
       Target.Open(TargetF,FileFd::WriteAtomic);
       Rel.Open(prefix + file,FileFd::ReadOnly);
       Rel.Open(prefix + file,FileFd::ReadOnly);
-      if (CopyFile(Rel,Target) == false)
+      if (CopyFile(Rel,Target) == false || Target.Close() == false)
 	 return _error->Error("Copying of '%s' for '%s' from '%s' failed", file.c_str(), CDName.c_str(), prefix.c_str());
 	 return _error->Error("Copying of '%s' for '%s' from '%s' failed", file.c_str(), CDName.c_str(), prefix.c_str());
+      ChangeOwnerAndPermissionOfFile("CopyPackages", TargetF.c_str(), "root", "root", 0644);
 
 
       return true;
       return true;
 }
 }
@@ -700,7 +684,7 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name,	/*{{{*/
       pkgTagFile Parser(&Pkg);
       pkgTagFile Parser(&Pkg);
       if (_error->PendingError() == true)
       if (_error->PendingError() == true)
 	 return false;
 	 return false;
-      
+
       // Open the output file
       // Open the output file
       char S[400];
       char S[400];
       snprintf(S,sizeof(S),"cdrom:[%s]/%s",Name.c_str(),
       snprintf(S,sizeof(S),"cdrom:[%s]/%s",Name.c_str(),
@@ -717,10 +701,7 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name,	/*{{{*/
       }
       }
       if (_error->PendingError() == true)
       if (_error->PendingError() == true)
 	 return false;
 	 return false;
-      FILE *TargetFl = fdopen(dup(Target.Fd()),"w");
-      if (TargetFl == 0)
-	 return _error->Errno("fdopen","Failed to reopen fd");
-      
+
       // Setup the progress meter
       // Setup the progress meter
       if(Progress)
       if(Progress)
 	 Progress->OverallProgress(CurrentSize,TotalSize,FileSize,
 	 Progress->OverallProgress(CurrentSize,TotalSize,FileSize,
@@ -738,20 +719,16 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name,	/*{{{*/
 	 if(Progress)
 	 if(Progress)
 	    Progress->Progress(Parser.Offset());
 	    Progress->Progress(Parser.Offset());
 
 
-	 const char *Start;
-	 const char *Stop;
-	 Section.GetSection(Start,Stop);
-	 fwrite(Start,Stop-Start, 1, TargetFl);
-	 fputc('\n',TargetFl);
+	 if (Section.Write(Target) == false || Target.Write("\n", 1) == false)
+	    return false;
 
 
 	 Packages++;
 	 Packages++;
 	 Hits++;
 	 Hits++;
       }
       }
-      fclose(TargetFl);
 
 
       if (Debug == true)
       if (Debug == true)
 	 cout << " Processed by using Prefix '" << Prefix << "' and chop " << endl;
 	 cout << " Processed by using Prefix '" << Prefix << "' and chop " << endl;
-	 
+
       if (_config->FindB("APT::CDROM::NoAct",false) == false)
       if (_config->FindB("APT::CDROM::NoAct",false) == false)
       {
       {
 	 // Move out of the partial directory
 	 // Move out of the partial directory
@@ -760,38 +737,47 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name,	/*{{{*/
 	 FinalF += URItoFileName(S);
 	 FinalF += URItoFileName(S);
 	 if (rename(TargetF.c_str(),FinalF.c_str()) != 0)
 	 if (rename(TargetF.c_str(),FinalF.c_str()) != 0)
 	    return _error->Errno("rename","Failed to rename");
 	    return _error->Errno("rename","Failed to rename");
+	 ChangeOwnerAndPermissionOfFile("CopyTranslations", FinalF.c_str(), "root", "root", 0644);
       }
       }
-      
-      
+
       CurrentSize += FileSize;
       CurrentSize += FileSize;
-   }   
+   }
    if(Progress)
    if(Progress)
       Progress->Done();
       Progress->Done();
-   
+
    // Some stats
    // Some stats
    if(log) {
    if(log) {
       stringstream msg;
       stringstream msg;
       if(NotFound == 0 && WrongSize == 0)
       if(NotFound == 0 && WrongSize == 0)
 	 ioprintf(msg, _("Wrote %i records.\n"), Packages);
 	 ioprintf(msg, _("Wrote %i records.\n"), Packages);
       else if (NotFound != 0 && WrongSize == 0)
       else if (NotFound != 0 && WrongSize == 0)
-	 ioprintf(msg, _("Wrote %i records with %i missing files.\n"), 
+	 ioprintf(msg, _("Wrote %i records with %i missing files.\n"),
 		  Packages, NotFound);
 		  Packages, NotFound);
       else if (NotFound == 0 && WrongSize != 0)
       else if (NotFound == 0 && WrongSize != 0)
-	 ioprintf(msg, _("Wrote %i records with %i mismatched files\n"), 
+	 ioprintf(msg, _("Wrote %i records with %i mismatched files\n"),
 		  Packages, WrongSize);
 		  Packages, WrongSize);
       if (NotFound != 0 && WrongSize != 0)
       if (NotFound != 0 && WrongSize != 0)
 	 ioprintf(msg, _("Wrote %i records with %i missing files and %i mismatched files\n"), Packages, NotFound, WrongSize);
 	 ioprintf(msg, _("Wrote %i records with %i missing files and %i mismatched files\n"), Packages, NotFound, WrongSize);
    }
    }
-   
+
    if (Packages == 0)
    if (Packages == 0)
       _error->Warning("No valid records were found.");
       _error->Warning("No valid records were found.");
 
 
    if (NotFound + WrongSize > 10)
    if (NotFound + WrongSize > 10)
       _error->Warning("A lot of entries were discarded, something may be wrong.\n");
       _error->Warning("A lot of entries were discarded, something may be wrong.\n");
-   
 
 
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
 
 
+IndexCopy::IndexCopy() {}
 APT_CONST IndexCopy::~IndexCopy() {}
 APT_CONST IndexCopy::~IndexCopy() {}
+
+PackageCopy::PackageCopy() : IndexCopy() {}
+APT_CONST PackageCopy::~PackageCopy() {}
+SourceCopy::SourceCopy() : IndexCopy() {}
+APT_CONST SourceCopy::~SourceCopy() {}
+TranslationsCopy::TranslationsCopy() {}
+APT_CONST TranslationsCopy::~TranslationsCopy() {}
+SigVerify::SigVerify() {}
+APT_CONST SigVerify::~SigVerify() {}

+ 23 - 7
apt-pkg/indexcopy.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: indexcopy.h,v 1.3 2001/05/27 04:46:54 jgg Exp $
 /* ######################################################################
 /* ######################################################################
 
 
    Index Copying - Aid for copying and verifying the index files
    Index Copying - Aid for copying and verifying the index files
@@ -28,6 +27,7 @@ using std::vector;
 class pkgTagSection;
 class pkgTagSection;
 class indexRecords;
 class indexRecords;
 class pkgCdromStatus;
 class pkgCdromStatus;
+class FileFd;
 
 
 class IndexCopy								/*{{{*/
 class IndexCopy								/*{{{*/
 {
 {
@@ -45,7 +45,7 @@ class IndexCopy								/*{{{*/
    void ConvertToSourceList(std::string CD,std::string &Path);
    void ConvertToSourceList(std::string CD,std::string &Path);
    bool GrabFirst(std::string Path,std::string &To,unsigned int Depth);
    bool GrabFirst(std::string Path,std::string &To,unsigned int Depth);
    virtual bool GetFile(std::string &Filename,unsigned long long &Size) = 0;
    virtual bool GetFile(std::string &Filename,unsigned long long &Size) = 0;
-   virtual bool RewriteEntry(FILE *Target,std::string File) = 0;
+   virtual bool RewriteEntry(FileFd &Target, std::string const &File) = 0;
    virtual const char *GetFileName() = 0;
    virtual const char *GetFileName() = 0;
    virtual const char *Type() = 0;
    virtual const char *Type() = 0;
    
    
@@ -53,39 +53,52 @@ class IndexCopy								/*{{{*/
 
 
    bool CopyPackages(std::string CDROM,std::string Name,std::vector<std::string> &List,
    bool CopyPackages(std::string CDROM,std::string Name,std::vector<std::string> &List,
 		     pkgCdromStatus *log);
 		     pkgCdromStatus *log);
+   IndexCopy();
    virtual ~IndexCopy();
    virtual ~IndexCopy();
 };
 };
 									/*}}}*/
 									/*}}}*/
 class PackageCopy : public IndexCopy					/*{{{*/
 class PackageCopy : public IndexCopy					/*{{{*/
 {
 {
+   void *d;
    protected:
    protected:
-   
+
    virtual bool GetFile(std::string &Filename,unsigned long long &Size);
    virtual bool GetFile(std::string &Filename,unsigned long long &Size);
-   virtual bool RewriteEntry(FILE *Target,std::string File);
+   virtual bool RewriteEntry(FileFd &Target, std::string const &File);
    virtual const char *GetFileName() {return "Packages";};
    virtual const char *GetFileName() {return "Packages";};
    virtual const char *Type() {return "Package";};
    virtual const char *Type() {return "Package";};
-   
+
+   public:
+   PackageCopy();
+   virtual ~PackageCopy();
 };
 };
 									/*}}}*/
 									/*}}}*/
 class SourceCopy : public IndexCopy					/*{{{*/
 class SourceCopy : public IndexCopy					/*{{{*/
 {
 {
+   void *d;
    protected:
    protected:
    
    
    virtual bool GetFile(std::string &Filename,unsigned long long &Size);
    virtual bool GetFile(std::string &Filename,unsigned long long &Size);
-   virtual bool RewriteEntry(FILE *Target,std::string File);
+   virtual bool RewriteEntry(FileFd &Target, std::string const &File);
    virtual const char *GetFileName() {return "Sources";};
    virtual const char *GetFileName() {return "Sources";};
    virtual const char *Type() {return "Source";};
    virtual const char *Type() {return "Source";};
-   
+
+   public:
+   SourceCopy();
+   virtual ~SourceCopy();
 };
 };
 									/*}}}*/
 									/*}}}*/
 class TranslationsCopy							/*{{{*/
 class TranslationsCopy							/*{{{*/
 {
 {
+   void *d;
    protected:
    protected:
    pkgTagSection *Section;
    pkgTagSection *Section;
 
 
    public:
    public:
    bool CopyTranslations(std::string CDROM,std::string Name,std::vector<std::string> &List,
    bool CopyTranslations(std::string CDROM,std::string Name,std::vector<std::string> &List,
 			 pkgCdromStatus *log);
 			 pkgCdromStatus *log);
+
+   TranslationsCopy();
+   virtual ~TranslationsCopy();
 };
 };
 									/*}}}*/
 									/*}}}*/
 class SigVerify								/*{{{*/
 class SigVerify								/*{{{*/
@@ -105,6 +118,9 @@ class SigVerify								/*{{{*/
 		       int const &statusfd, int fd[2]);
 		       int const &statusfd, int fd[2]);
    APT_DEPRECATED static bool RunGPGV(std::string const &File, std::string const &FileOut,
    APT_DEPRECATED static bool RunGPGV(std::string const &File, std::string const &FileOut,
 			      int const &statusfd = -1);
 			      int const &statusfd = -1);
+
+   SigVerify();
+   virtual ~SigVerify();
 };
 };
 									/*}}}*/
 									/*}}}*/
 
 

+ 126 - 6
apt-pkg/indexfile.cc

@@ -10,8 +10,10 @@
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
 #include<config.h>
 #include<config.h>
 
 
+#include <apt-pkg/configuration.h>
 #include <apt-pkg/indexfile.h>
 #include <apt-pkg/indexfile.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
+#include <apt-pkg/fileutl.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/cacheiterators.h>
@@ -48,27 +50,26 @@ pkgIndexFile::Type *pkgIndexFile::Type::GetType(const char *Type)
       if (strcmp(GlobalList[I]->Label,Type) == 0)
       if (strcmp(GlobalList[I]->Label,Type) == 0)
 	 return GlobalList[I];
 	 return GlobalList[I];
    return 0;
    return 0;
+}
+									/*}}}*/
+pkgIndexFile::pkgIndexFile(bool Trusted) :				/*{{{*/
+   Trusted(Trusted)
+{
 }
 }
 									/*}}}*/
 									/*}}}*/
 // IndexFile::ArchiveInfo - Stub					/*{{{*/
 // IndexFile::ArchiveInfo - Stub					/*{{{*/
-// ---------------------------------------------------------------------
-/* */
 std::string pkgIndexFile::ArchiveInfo(pkgCache::VerIterator /*Ver*/) const
 std::string pkgIndexFile::ArchiveInfo(pkgCache::VerIterator /*Ver*/) const
 {
 {
    return std::string();
    return std::string();
 }
 }
 									/*}}}*/
 									/*}}}*/
 // IndexFile::FindInCache - Stub					/*{{{*/
 // IndexFile::FindInCache - Stub					/*{{{*/
-// ---------------------------------------------------------------------
-/* */
 pkgCache::PkgFileIterator pkgIndexFile::FindInCache(pkgCache &Cache) const
 pkgCache::PkgFileIterator pkgIndexFile::FindInCache(pkgCache &Cache) const
 {
 {
    return pkgCache::PkgFileIterator(Cache);
    return pkgCache::PkgFileIterator(Cache);
 }
 }
 									/*}}}*/
 									/*}}}*/
 // IndexFile::SourceIndex - Stub					/*{{{*/
 // IndexFile::SourceIndex - Stub					/*{{{*/
-// ---------------------------------------------------------------------
-/* */
 std::string pkgIndexFile::SourceInfo(pkgSrcRecords::Parser const &/*Record*/,
 std::string pkgIndexFile::SourceInfo(pkgSrcRecords::Parser const &/*Record*/,
 				pkgSrcRecords::File const &/*File*/) const
 				pkgSrcRecords::File const &/*File*/) const
 {
 {
@@ -110,3 +111,122 @@ APT_DEPRECATED std::string pkgIndexFile::LanguageCode() {
 	return APT::Configuration::getLanguages()[0];
 	return APT::Configuration::getLanguages()[0];
 }
 }
 									/*}}}*/
 									/*}}}*/
+
+// IndexTarget - Constructor						/*{{{*/
+IndexTarget::IndexTarget(std::string const &MetaKey, std::string const &ShortDesc,
+      std::string const &LongDesc, std::string const &URI, bool const IsOptional,
+      std::map<std::string, std::string> const &Options) :
+   URI(URI), Description(LongDesc), ShortDesc(ShortDesc), MetaKey(MetaKey), IsOptional(IsOptional), Options(Options)
+{
+}
+									/*}}}*/
+std::string IndexTarget::Option(OptionKeys const EnumKey) const		/*{{{*/
+{
+   std::string Key;
+   switch (EnumKey)
+   {
+#define APT_CASE(X) case X: Key = #X; break
+      APT_CASE(SITE);
+      APT_CASE(RELEASE);
+      APT_CASE(COMPONENT);
+      APT_CASE(LANGUAGE);
+      APT_CASE(ARCHITECTURE);
+      APT_CASE(BASE_URI);
+      APT_CASE(REPO_URI);
+      APT_CASE(TARGET_OF);
+      APT_CASE(CREATED_BY);
+#undef APT_CASE
+      case FILENAME: return _config->FindDir("Dir::State::lists") + URItoFileName(URI);
+      case EXISTING_FILENAME:
+	 std::string const filename = Option(FILENAME);
+	 std::vector<std::string> const types = APT::Configuration::getCompressionTypes();
+	 for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
+	 {
+	    if (t->empty())
+	       continue;
+	    std::string const file = (*t == "uncompressed") ? filename : (filename + "." + *t);
+	    if (FileExists(file))
+	       return file;
+	 }
+	 return "";
+   }
+   std::map<std::string,std::string>::const_iterator const M = Options.find(Key);
+   if (M == Options.end())
+      return "";
+   return M->second;
+}
+									/*}}}*/
+std::string IndexTarget::Format(std::string format) const		/*{{{*/
+{
+   for (std::map<std::string, std::string>::const_iterator O = Options.begin(); O != Options.end(); ++O)
+   {
+      format = SubstVar(format, std::string("$(") + O->first + ")", O->second);
+   }
+   format = SubstVar(format, "$(METAKEY)", MetaKey);
+   format = SubstVar(format, "$(SHORTDESC)", ShortDesc);
+   format = SubstVar(format, "$(DESCRIPTION)", Description);
+   format = SubstVar(format, "$(URI)", URI);
+   format = SubstVar(format, "$(FILENAME)", Option(IndexTarget::FILENAME));
+   return format;
+}
+									/*}}}*/
+
+pkgIndexTargetFile::pkgIndexTargetFile(IndexTarget const &Target, bool const Trusted) :/*{{{*/
+   pkgIndexFile(Trusted), Target(Target)
+{
+}
+									/*}}}*/
+std::string pkgIndexTargetFile::ArchiveURI(std::string File) const/*{{{*/
+{
+   return Target.Option(IndexTarget::REPO_URI) + File;
+}
+									/*}}}*/
+std::string pkgIndexTargetFile::Describe(bool Short) const		/*{{{*/
+{
+   if (Short)
+      return Target.Description;
+   return Target.Description + " (" + IndexFileName() + ")";
+}
+									/*}}}*/
+std::string pkgIndexTargetFile::IndexFileName() const			/*{{{*/
+{
+   std::string const s = Target.Option(IndexTarget::FILENAME);
+   if (FileExists(s))
+      return s;
+
+   std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+   for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
+   {
+      std::string p = s + '.' + *t;
+      if (FileExists(p))
+         return p;
+   }
+   return s;
+}
+									/*}}}*/
+unsigned long pkgIndexTargetFile::Size() const				/*{{{*/
+{
+   unsigned long size = 0;
+
+   /* we need to ignore errors here; if the lists are absent, just return 0 */
+   _error->PushToStack();
+
+   FileFd f(IndexFileName(), FileFd::ReadOnly, FileFd::Extension);
+   if (!f.Failed())
+      size = f.Size();
+
+   if (_error->PendingError() == true)
+       size = 0;
+   _error->RevertToStack();
+
+   return size;
+}
+									/*}}}*/
+bool pkgIndexTargetFile::Exists() const					/*{{{*/
+{
+   return FileExists(IndexFileName());
+}
+									/*}}}*/
+
+APT_CONST pkgIndexFile::~pkgIndexFile() {}
+APT_CONST pkgIndexTargetFile::~pkgIndexTargetFile() {}

+ 73 - 7
apt-pkg/indexfile.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: indexfile.h,v 1.6.2.1 2003/12/24 23:09:17 mdz Exp $
 /* ######################################################################
 /* ######################################################################
 
 
    Index File - Abstraction for an index of archive/source file.
    Index File - Abstraction for an index of archive/source file.
@@ -28,6 +27,7 @@
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/macros.h>
 #include <apt-pkg/macros.h>
 
 
+#include <map>
 #include <string>
 #include <string>
 
 
 #ifndef APT_8_CLEANER_HEADERS
 #ifndef APT_8_CLEANER_HEADERS
@@ -40,17 +40,65 @@ class pkgAcquire;
 class pkgCacheGenerator;
 class pkgCacheGenerator;
 class OpProgress;
 class OpProgress;
 
 
+class IndexTarget							/*{{{*/
+/** \brief Information about an index file. */
+{
+   public:
+   /** \brief A URI from which the index file can be downloaded. */
+   std::string URI;
+
+   /** \brief A description of the index file. */
+   std::string Description;
+
+   /** \brief A shorter description of the index file. */
+   std::string ShortDesc;
+
+   /** \brief The key by which this index file should be
+       looked up within the meta index file. */
+   std::string MetaKey;
+
+   /** \brief Is it okay if the file isn't found in the meta index */
+   bool IsOptional;
+
+   /** \brief options with which this target was created
+       Prefer the usage of #Option if at all possible.
+       Beware: Not all of these options are intended for public use */
+   std::map<std::string, std::string> Options;
+
+   IndexTarget(std::string const &MetaKey, std::string const &ShortDesc,
+	 std::string const &LongDesc, std::string const &URI, bool const IsOptional,
+	 std::map<std::string, std::string> const &Options);
+
+   enum OptionKeys {
+      SITE,
+      RELEASE,
+      COMPONENT,
+      LANGUAGE,
+      ARCHITECTURE,
+      BASE_URI,
+      REPO_URI,
+      CREATED_BY,
+      TARGET_OF,
+      FILENAME,
+      EXISTING_FILENAME,
+   };
+   std::string Option(OptionKeys const Key) const;
+   std::string Format(std::string format) const;
+};
+									/*}}}*/
+
 class pkgIndexFile
 class pkgIndexFile
 {
 {
+   void *d;
    protected:
    protected:
    bool Trusted;
    bool Trusted;
-     
+
    public:
    public:
 
 
    class Type
    class Type
    {
    {
       public:
       public:
-      
+
       // Global list of Items supported
       // Global list of Items supported
       static Type **GlobalList;
       static Type **GlobalList;
       static unsigned long GlobalListLen;
       static unsigned long GlobalListLen;
@@ -70,7 +118,7 @@ class pkgIndexFile
    virtual std::string ArchiveInfo(pkgCache::VerIterator Ver) const;
    virtual std::string ArchiveInfo(pkgCache::VerIterator Ver) const;
    virtual std::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 std::string Describe(bool Short = false) const = 0;   
+   virtual std::string Describe(bool Short = false) const = 0;
 
 
    // Interface for acquire
    // Interface for acquire
    virtual std::string ArchiveURI(std::string /*File*/) const {return std::string();};
    virtual std::string ArchiveURI(std::string /*File*/) const {return std::string();};
@@ -95,9 +143,27 @@ class pkgIndexFile
    static std::string LanguageCode();
    static std::string LanguageCode();
 
 
    bool IsTrusted() const { return Trusted; };
    bool IsTrusted() const { return Trusted; };
-   
-   pkgIndexFile(bool Trusted): Trusted(Trusted) {};
-   virtual ~pkgIndexFile() {};
+
+   pkgIndexFile(bool Trusted);
+   virtual ~pkgIndexFile();
+};
+
+class pkgIndexTargetFile : public pkgIndexFile
+{
+   void *d;
+protected:
+   IndexTarget const Target;
+
+   std::string IndexFileName() const;
+
+public:
+   virtual std::string ArchiveURI(std::string File) const;
+   virtual std::string Describe(bool Short = false) const;
+   virtual bool Exists() const;
+   virtual unsigned long Size() const;
+
+   pkgIndexTargetFile(IndexTarget const &Target, bool const Trusted);
+   virtual ~pkgIndexTargetFile();
 };
 };
 
 
 #endif
 #endif

+ 32 - 24
apt-pkg/indexrecords.cc

@@ -58,6 +58,11 @@ APT_PURE time_t indexRecords::GetValidUntil() const
    return this->ValidUntil;
    return this->ValidUntil;
 }
 }
 
 
+APT_PURE time_t indexRecords::GetDate() const
+{
+   return this->Date;
+}
+
 APT_PURE indexRecords::checkSum *indexRecords::Lookup(const string MetaKey)
 APT_PURE indexRecords::checkSum *indexRecords::Lookup(const string MetaKey)
 {
 {
    std::map<std::string, indexRecords::checkSum* >::const_iterator sum = Entries.find(MetaKey);
    std::map<std::string, indexRecords::checkSum* >::const_iterator sum = Entries.find(MetaKey);
@@ -68,7 +73,7 @@ APT_PURE indexRecords::checkSum *indexRecords::Lookup(const string MetaKey)
 
 
 APT_PURE bool indexRecords::Exists(string const &MetaKey) const
 APT_PURE bool indexRecords::Exists(string const &MetaKey) const
 {
 {
-   return Entries.count(MetaKey) == 1;
+   return Entries.find(MetaKey) != Entries.end();
 }
 }
 
 
 bool indexRecords::Load(const string Filename)				/*{{{*/
 bool indexRecords::Load(const string Filename)				/*{{{*/
@@ -116,17 +121,8 @@ bool indexRecords::Load(const string Filename)				/*{{{*/
             indexRecords::checkSum *Sum = new indexRecords::checkSum;
             indexRecords::checkSum *Sum = new indexRecords::checkSum;
             Sum->MetaKeyFilename = Name;
             Sum->MetaKeyFilename = Name;
             Sum->Size = Size;
             Sum->Size = Size;
-	    std::string SizeStr;
-	    strprintf(SizeStr, "%llu", Size);
-	    Sum->Hashes.push_back(HashString("Checksum-FileSize", SizeStr));
-#if __GNUC__ >= 4
-       #pragma GCC diagnostic push
-       #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
-            Sum->Hash = HashString(HashString::SupportedHashes()[i],Hash);
-#if __GNUC__ >= 4
-       #pragma GCC diagnostic pop
-#endif
+	    Sum->Hashes.FileSize(Size);
+            APT_IGNORE_DEPRECATED(Sum->Hash = HashString(HashString::SupportedHashes()[i],Hash);)
             Entries[Name] = Sum;
             Entries[Name] = Sum;
          }
          }
          Entries[Name]->Hashes.push_back(HashString(HashString::SupportedHashes()[i],Hash));
          Entries[Name]->Hashes.push_back(HashString(HashString::SupportedHashes()[i],Hash));
@@ -140,9 +136,15 @@ bool indexRecords::Load(const string Filename)				/*{{{*/
       return false;
       return false;
    }
    }
 
 
-   string Label = Section.FindS("Label");
-   string StrDate = Section.FindS("Date");
-   string StrValidUntil = Section.FindS("Valid-Until");
+   string const StrDate = Section.FindS("Date");
+   if (RFC1123StrToTime(StrDate.c_str(), Date) == false)
+   {
+      strprintf(ErrorText, _("Invalid 'Date' entry in Release file %s"), Filename.c_str());
+      return false;
+   }
+
+   string const Label = Section.FindS("Label");
+   string const StrValidUntil = Section.FindS("Valid-Until");
 
 
    // if we have a Valid-Until header in the Release file, use it as default
    // if we have a Valid-Until header in the Release file, use it as default
    if (StrValidUntil.empty() == false)
    if (StrValidUntil.empty() == false)
@@ -165,20 +167,13 @@ bool indexRecords::Load(const string Filename)				/*{{{*/
       (MinAge == 0 || ValidUntil == 0)) // No user settings, use the one from the Release file
       (MinAge == 0 || ValidUntil == 0)) // No user settings, use the one from the Release file
       return true;
       return true;
 
 
-   time_t date;
-   if (RFC1123StrToTime(StrDate.c_str(), date) == false)
-   {
-      strprintf(ErrorText, _("Invalid 'Date' entry in Release file %s"), Filename.c_str());
-      return false;
-   }
-
    if (MinAge != 0 && ValidUntil != 0) {
    if (MinAge != 0 && ValidUntil != 0) {
-      time_t const min_date = date + MinAge;
+      time_t const min_date = Date + MinAge;
       if (ValidUntil < min_date)
       if (ValidUntil < min_date)
 	 ValidUntil = min_date;
 	 ValidUntil = min_date;
    }
    }
    if (MaxAge != 0) {
    if (MaxAge != 0) {
-      time_t const max_date = date + MaxAge;
+      time_t const max_date = Date + MaxAge;
       if (ValidUntil == 0 || ValidUntil > max_date)
       if (ValidUntil == 0 || ValidUntil > max_date)
 	 ValidUntil = max_date;
 	 ValidUntil = max_date;
    }
    }
@@ -277,10 +272,23 @@ void indexRecords::SetTrusted(bool const Trusted)
       this->Trusted = NEVER_TRUSTED;
       this->Trusted = NEVER_TRUSTED;
 }
 }
 
 
+#if APT_PKG_ABI >= 413
 indexRecords::indexRecords(const string &ExpectedDist) :
 indexRecords::indexRecords(const string &ExpectedDist) :
    Trusted(CHECK_TRUST), d(NULL), ExpectedDist(ExpectedDist), ValidUntil(0),
    Trusted(CHECK_TRUST), d(NULL), ExpectedDist(ExpectedDist), ValidUntil(0),
    SupportsAcquireByHash(false)
    SupportsAcquireByHash(false)
 {
 {
 }
 }
+#else
+indexRecords::indexRecords() :
+   Trusted(CHECK_TRUST), d(NULL), ExpectedDist(""), ValidUntil(0),
+   SupportsAcquireByHash(false)
+{
+}
+indexRecords::indexRecords(const string ExpectedDist) :
+   Trusted(CHECK_TRUST), d(NULL), ExpectedDist(ExpectedDist), ValidUntil(0),
+   SupportsAcquireByHash(false)
+{
+}
+#endif
 
 
 indexRecords::~indexRecords() {}
 indexRecords::~indexRecords() {}

+ 9 - 12
apt-pkg/indexrecords.h

@@ -1,7 +1,4 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
-// Description								/*{{{*/
-// $Id: indexrecords.h,v 1.1.2.1 2003/12/24 23:09:17 mdz Exp $
-									/*}}}*/
 #ifndef PKGLIB_INDEXRECORDS_H
 #ifndef PKGLIB_INDEXRECORDS_H
 #define PKGLIB_INDEXRECORDS_H
 #define PKGLIB_INDEXRECORDS_H
 
 
@@ -36,14 +33,19 @@ class indexRecords
    std::string Dist;
    std::string Dist;
    std::string Suite;
    std::string Suite;
    std::string ExpectedDist;
    std::string ExpectedDist;
+   time_t Date;
    time_t ValidUntil;
    time_t ValidUntil;
    bool SupportsAcquireByHash;
    bool SupportsAcquireByHash;
 
 
    std::map<std::string,checkSum *> Entries;
    std::map<std::string,checkSum *> Entries;
 
 
    public:
    public:
-
+#if APT_PKG_ABI >= 413
    indexRecords(const std::string &ExpectedDist = "");
    indexRecords(const std::string &ExpectedDist = "");
+#else
+   indexRecords();
+   indexRecords(const std::string ExpectedDist);
+#endif
 
 
    // Lookup function
    // Lookup function
    virtual checkSum *Lookup(const std::string MetaKey);
    virtual checkSum *Lookup(const std::string MetaKey);
@@ -58,6 +60,7 @@ class indexRecords
    std::string GetSuite() const;
    std::string GetSuite() const;
    bool GetSupportsAcquireByHash() const;
    bool GetSupportsAcquireByHash() const;
    time_t GetValidUntil() const;
    time_t GetValidUntil() const;
+   time_t GetDate() const;
    std::string GetExpectedDist() const;
    std::string GetExpectedDist() const;
 
 
    /** \brief check if source is marked as always trusted */
    /** \brief check if source is marked as always trusted */
@@ -76,11 +79,7 @@ class indexRecords
    virtual ~indexRecords();
    virtual ~indexRecords();
 };
 };
 
 
-#if __GNUC__ >= 4
-	// ensure that con- & de-structor don't trigger this warning
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
 struct indexRecords::checkSum
 struct indexRecords::checkSum
 {
 {
    std::string MetaKeyFilename;
    std::string MetaKeyFilename;
@@ -89,8 +88,6 @@ struct indexRecords::checkSum
 
 
    APT_DEPRECATED HashString Hash;
    APT_DEPRECATED HashString Hash;
 };
 };
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 
 
 #endif
 #endif

+ 24 - 2
apt-pkg/init.cc

@@ -89,7 +89,7 @@ bool pkgInitConfig(Configuration &Cnf)
    Cnf.Set("Dir::Ignore-Files-Silently::", "\\.distUpgrade$");
    Cnf.Set("Dir::Ignore-Files-Silently::", "\\.distUpgrade$");
 
 
    // Repository security
    // Repository security
-   // FIXME: this is set to "true" for backward compatiblity, once
+   // FIXME: this is set to "true" for backward compatibility, once
    //        jessie is out we want to change this to "false" to
    //        jessie is out we want to change this to "false" to
    //        improve security
    //        improve security
    Cnf.CndSet("Acquire::AllowInsecureRepositories", true);
    Cnf.CndSet("Acquire::AllowInsecureRepositories", true);
@@ -101,8 +101,30 @@ bool pkgInitConfig(Configuration &Cnf)
    // The default user we drop to in the methods
    // The default user we drop to in the methods
    Cnf.CndSet("APT::Sandbox::User", "_apt");
    Cnf.CndSet("APT::Sandbox::User", "_apt");
 
 
+   Cnf.CndSet("APT::Acquire::Targets::deb::Packages::MetaKey", "$(COMPONENT)/binary-$(ARCHITECTURE)/Packages");
+   Cnf.CndSet("APT::Acquire::Targets::deb::Packages::flatMetaKey", "Packages");
+   Cnf.CndSet("APT::Acquire::Targets::deb::Packages::ShortDescription", "Packages");
+   Cnf.CndSet("APT::Acquire::Targets::deb::Packages::Description", "$(SITE) $(RELEASE)/$(COMPONENT) $(ARCHITECTURE) Packages");
+   Cnf.CndSet("APT::Acquire::Targets::deb::Packages::flatDescription", "$(SITE) $(RELEASE) Packages");
+   Cnf.CndSet("APT::Acquire::Targets::deb::Packages::Optional", false);
+   Cnf.CndSet("APT::Acquire::Targets::deb::Translations::MetaKey", "$(COMPONENT)/i18n/Translation-$(LANGUAGE)");
+   Cnf.CndSet("APT::Acquire::Targets::deb::Translations::flatMetaKey", "$(LANGUAGE)");
+   Cnf.CndSet("APT::Acquire::Targets::deb::Translations::ShortDescription", "Translation-$(LANGUAGE)");
+   Cnf.CndSet("APT::Acquire::Targets::deb::Translations::Description", "$(SITE) $(RELEASE)/$(COMPONENT) Translation-$(LANGUAGE)");
+   Cnf.CndSet("APT::Acquire::Targets::deb::Translations::flatDescription", "$(SITE) $(RELEASE) Translation-$(LANGUAGE)");
+   Cnf.CndSet("APT::Acquire::Targets::deb-src::Sources::MetaKey", "$(COMPONENT)/source/Sources");
+   Cnf.CndSet("APT::Acquire::Targets::deb-src::Sources::flatMetaKey", "Sources");
+   Cnf.CndSet("APT::Acquire::Targets::deb-src::Sources::ShortDescription", "Sources");
+   Cnf.CndSet("APT::Acquire::Targets::deb-src::Sources::Description", "$(SITE) $(RELEASE)/$(COMPONENT) Sources");
+   Cnf.CndSet("APT::Acquire::Targets::deb-src::Sources::flatDescription", "$(SITE) $(RELEASE) Sources");
+   Cnf.CndSet("APT::Acquire::Targets::deb-src::Sources::Optional", false);
+
+   Cnf.CndSet("Acquire::Changelogs::URI::Origin::Debian", "http://metadata.ftp-master.debian.org/changelogs/CHANGEPATH_changelog");
+   Cnf.CndSet("Acquire::Changelogs::URI::Origin::Ubuntu", "http://changelogs.ubuntu.com/changelogs/pool/CHANGEPATH/changelog");
+   Cnf.CndSet("Acquire::Changelogs::URI::Origin::Ultimedia", "http://packages.ultimediaos.com/changelogs/pool/CHANGEPATH/changelog.txt");
+
    bool Res = true;
    bool Res = true;
-   
+
    // Read an alternate config file
    // Read an alternate config file
    const char *Cfg = getenv("APT_CONFIG");
    const char *Cfg = getenv("APT_CONFIG");
    if (Cfg != 0 && strlen(Cfg) != 0)
    if (Cfg != 0 && strlen(Cfg) != 0)

+ 6 - 0
apt-pkg/install-progress.cc

@@ -69,6 +69,7 @@ PackageManagerProgressFd::PackageManagerProgressFd(int progress_fd)
 {
 {
    OutStatusFd = progress_fd;
    OutStatusFd = progress_fd;
 }
 }
+PackageManagerProgressFd::~PackageManagerProgressFd() {}
 
 
 void PackageManagerProgressFd::WriteToStatusFd(std::string s)
 void PackageManagerProgressFd::WriteToStatusFd(std::string s)
 {
 {
@@ -157,6 +158,7 @@ PackageManagerProgressDeb822Fd::PackageManagerProgressDeb822Fd(int progress_fd)
 {
 {
    OutStatusFd = progress_fd;
    OutStatusFd = progress_fd;
 }
 }
+PackageManagerProgressDeb822Fd::~PackageManagerProgressDeb822Fd() {}
 
 
 void PackageManagerProgressDeb822Fd::WriteToStatusFd(std::string s)
 void PackageManagerProgressDeb822Fd::WriteToStatusFd(std::string s)
 {
 {
@@ -433,6 +435,10 @@ bool PackageManagerText::StatusChanged(std::string PackageName,
    return true;
    return true;
 }
 }
 
 
+PackageManagerText::PackageManagerText() : PackageManager() {}
+PackageManagerText::~PackageManagerText() {}
+
+
 
 
 
 
 } // namespace progress
 } // namespace progress

+ 10 - 1
apt-pkg/install-progress.h

@@ -61,6 +61,7 @@ namespace Progress {
 
 
  class PackageManagerProgressFd : public PackageManager
  class PackageManagerProgressFd : public PackageManager
  {
  {
+    void *d;
  protected:
  protected:
     int OutStatusFd;
     int OutStatusFd;
     int StepsDone;
     int StepsDone;
@@ -69,6 +70,7 @@ namespace Progress {
 
 
  public:
  public:
     PackageManagerProgressFd(int progress_fd);
     PackageManagerProgressFd(int progress_fd);
+    virtual ~PackageManagerProgressFd();
 
 
     virtual void StartDpkg();
     virtual void StartDpkg();
     virtual void Stop();
     virtual void Stop();
@@ -90,6 +92,7 @@ namespace Progress {
 
 
  class PackageManagerProgressDeb822Fd : public PackageManager
  class PackageManagerProgressDeb822Fd : public PackageManager
  {
  {
+    void *d;
  protected:
  protected:
     int OutStatusFd;
     int OutStatusFd;
     int StepsDone;
     int StepsDone;
@@ -98,6 +101,7 @@ namespace Progress {
 
 
  public:
  public:
     PackageManagerProgressDeb822Fd(int progress_fd);
     PackageManagerProgressDeb822Fd(int progress_fd);
+    virtual ~PackageManagerProgressDeb822Fd();
 
 
     virtual void StartDpkg();
     virtual void StartDpkg();
     virtual void Stop();
     virtual void Stop();
@@ -118,6 +122,7 @@ namespace Progress {
 
 
  class PackageManagerFancy : public PackageManager
  class PackageManagerFancy : public PackageManager
  {
  {
+    void *d;
  private:
  private:
     APT_HIDDEN static void staticSIGWINCH(int);
     APT_HIDDEN static void staticSIGWINCH(int);
     static std::vector<PackageManagerFancy*> instances;
     static std::vector<PackageManagerFancy*> instances;
@@ -138,7 +143,7 @@ namespace Progress {
 
 
  public:
  public:
     PackageManagerFancy();
     PackageManagerFancy();
-    ~PackageManagerFancy();
+    virtual ~PackageManagerFancy();
     virtual void Start(int child_pty=-1);
     virtual void Start(int child_pty=-1);
     virtual void Stop();
     virtual void Stop();
     virtual bool StatusChanged(std::string PackageName,
     virtual bool StatusChanged(std::string PackageName,
@@ -153,11 +158,15 @@ namespace Progress {
 
 
  class PackageManagerText : public PackageManager
  class PackageManagerText : public PackageManager
  {
  {
+    void *d;
  public:
  public:
     virtual bool StatusChanged(std::string PackageName,
     virtual bool StatusChanged(std::string PackageName,
                                unsigned int StepsDone,
                                unsigned int StepsDone,
                                unsigned int TotalSteps,
                                unsigned int TotalSteps,
                                std::string HumanReadableAction);
                                std::string HumanReadableAction);
+
+    PackageManagerText();
+    virtual ~PackageManagerText();
  };
  };
 
 
 
 

+ 57 - 0
apt-pkg/metaindex.cc

@@ -0,0 +1,57 @@
+// Include Files                                                       /*{{{*/
+#include <apt-pkg/pkgcachegen.h>
+#include <apt-pkg/indexfile.h>
+#include <apt-pkg/metaindex.h>
+
+#include <stddef.h>
+
+#include <string>
+#include <vector>
+                                                                       /*}}}*/
+
+#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+std::string metaIndex::LocalFileName() const { return ""; }
+#else
+#include <apt-pkg/debmetaindex.h>
+std::string metaIndex::LocalFileName() const
+{
+   debReleaseIndex const * deb = dynamic_cast<debReleaseIndex const*>(this);
+   if (deb != NULL)
+      return deb->LocalFileName();
+
+   return "";
+}
+#endif
+
+std::string metaIndex::Describe() const
+{
+   return "Release";
+}
+
+pkgCache::RlsFileIterator metaIndex::FindInCache(pkgCache &Cache, bool const) const
+{
+   return pkgCache::RlsFileIterator(Cache);
+}
+
+bool metaIndex::Merge(pkgCacheGenerator &Gen,OpProgress *) const
+{
+   return Gen.SelectReleaseFile("", "");
+}
+
+
+metaIndex::metaIndex(std::string const &URI, std::string const &Dist,
+      char const * const Type)
+: Indexes(NULL), Type(Type), URI(URI), Dist(Dist), Trusted(false)
+{
+   /* nothing */
+}
+
+metaIndex::~metaIndex()
+{
+   if (Indexes == 0)
+      return;
+   for (std::vector<pkgIndexFile *>::iterator I = (*Indexes).begin();
+        I != (*Indexes).end(); ++I)
+      delete *I;
+   delete Indexes;
+}

+ 14 - 20
apt-pkg/metaindex.h

@@ -22,9 +22,13 @@ using std::string;
 #endif
 #endif
 
 
 class pkgAcquire;
 class pkgAcquire;
+class IndexTarget;
+class pkgCacheGenerator;
+class OpProgress;
 
 
 class metaIndex
 class metaIndex
 {
 {
+   void *d;
    protected:
    protected:
    std::vector <pkgIndexFile *> *Indexes;
    std::vector <pkgIndexFile *> *Indexes;
    const char *Type;
    const char *Type;
@@ -40,33 +44,23 @@ class metaIndex
    virtual const char* GetType() const {return Type;}
    virtual const char* GetType() const {return Type;}
 
 
    // interface to to query it
    // interface to to query it
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
-   // returns the path of the local file (or "" if its not available)
-   virtual std::string LocalFileName() const {return "";};
-#endif
+   /** \return the path of the local file (or "" if its not available) */
+   virtual std::string LocalFileName() const;
 
 
    // Interface for acquire
    // Interface for acquire
    virtual std::string ArchiveURI(std::string const& File) const = 0;
    virtual std::string ArchiveURI(std::string const& File) const = 0;
    virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const = 0;
    virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const = 0;
-   virtual std::vector<pkgIndexFile *> *GetIndexFiles() = 0; 
+   virtual std::vector<IndexTarget> GetIndexTargets() const = 0;
+   virtual std::vector<pkgIndexFile *> *GetIndexFiles() = 0;
    virtual bool IsTrusted() const = 0;
    virtual bool IsTrusted() const = 0;
 
 
-   metaIndex(std::string const &URI, std::string const &Dist, 
-             char const * const Type) 
-      : Indexes(NULL), Type(Type), URI(URI), Dist(Dist), Trusted(false)
-   {
-      /* nothing */
-   }
+   virtual std::string Describe() const;
+   virtual pkgCache::RlsFileIterator FindInCache(pkgCache &Cache, bool const ModifyCheck) const;
+   virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const;
 
 
-   virtual ~metaIndex() 
-   {
-      if (Indexes == 0)
-	 return;
-      for (std::vector<pkgIndexFile *>::iterator I = (*Indexes).begin();
-           I != (*Indexes).end(); ++I)
-	 delete *I;
-      delete Indexes;
-   }
+   metaIndex(std::string const &URI, std::string const &Dist,
+             char const * const Type);
+   virtual ~metaIndex();
 };
 };
 
 
 #endif
 #endif

+ 2 - 2
apt-pkg/orderlist.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: orderlist.h,v 1.9 2001/02/20 07:03:17 jgg Exp $
 /* ######################################################################
 /* ######################################################################
 
 
    Order List - Represents and Manipulates an ordered list of packages.
    Order List - Represents and Manipulates an ordered list of packages.
@@ -25,6 +24,7 @@
 class pkgDepCache;
 class pkgDepCache;
 class pkgOrderList : protected pkgCache::Namespace
 class pkgOrderList : protected pkgCache::Namespace
 {
 {
+   void *d;
    protected:
    protected:
 
 
    pkgDepCache &Cache;   
    pkgDepCache &Cache;   
@@ -123,7 +123,7 @@ class pkgOrderList : protected pkgCache::Namespace
    int Score(PkgIterator Pkg);
    int Score(PkgIterator Pkg);
 
 
    pkgOrderList(pkgDepCache *Cache);
    pkgOrderList(pkgDepCache *Cache);
-   ~pkgOrderList();
+   virtual ~pkgOrderList();
 };
 };
 
 
 #endif
 #endif

+ 39 - 13
apt-pkg/packagemanager.cc

@@ -400,7 +400,8 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
 	       // Check if the current version of the package is available and will satisfy this dependency
 	       // Check if the current version of the package is available and will satisfy this dependency
 	       if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true &&
 	       if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true &&
 		   List->IsFlag(DepPkg,pkgOrderList::Removed) == false &&
 		   List->IsFlag(DepPkg,pkgOrderList::Removed) == false &&
-		   DepPkg.State() == PkgIterator::NeedsNothing)
+		   DepPkg.State() == PkgIterator::NeedsNothing &&
+		   (Cache[DepPkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
 	       {
 	       {
 		  Bad = false;
 		  Bad = false;
 		  break;
 		  break;
@@ -413,8 +414,13 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
 	       if (PkgLoop == true)
 	       if (PkgLoop == true)
 	       {
 	       {
 		  if (Debug)
 		  if (Debug)
-		     std::clog << OutputInDepth(Depth) << "Package " << Pkg << " loops in SmartConfigure" << std::endl;
-	          Bad = false;
+		     std::clog << OutputInDepth(Depth) << "Package " << Pkg << " loops in SmartConfigure";
+		  if (List->IsFlag(DepPkg,pkgOrderList::UnPacked))
+		     Bad = false;
+		  else if (Debug)
+		     std::clog << ", but it isn't unpacked yet";
+		  if (Debug)
+		     std::clog << std::endl;
 	       }
 	       }
 	    }
 	    }
 
 
@@ -426,7 +432,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
          if (Bad == false)
          if (Bad == false)
          {
          {
             if (Debug)
             if (Debug)
-               std::clog << OutputInDepth(Depth) << "Found ok dep " << D.TargetPkg() << std::endl;
+               std::clog << OutputInDepth(Depth) << "Found ok dep " << Start.TargetPkg() << std::endl;
             continue;
             continue;
          }
          }
 
 
@@ -444,7 +450,8 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
 	       // Check if the current version of the package is available and will satisfy this dependency
 	       // Check if the current version of the package is available and will satisfy this dependency
 	       if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true &&
 	       if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true &&
 		   List->IsFlag(DepPkg,pkgOrderList::Removed) == false &&
 		   List->IsFlag(DepPkg,pkgOrderList::Removed) == false &&
-		   DepPkg.State() == PkgIterator::NeedsNothing)
+		   DepPkg.State() == PkgIterator::NeedsNothing &&
+		   (Cache[DepPkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
                   continue;
                   continue;
 
 
 	       // Check if the version that is going to be installed will satisfy the dependency
 	       // Check if the version that is going to be installed will satisfy the dependency
@@ -454,8 +461,13 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
 	       if (PkgLoop == true)
 	       if (PkgLoop == true)
 	       {
 	       {
 		  if (Debug)
 		  if (Debug)
-		     std::clog << OutputInDepth(Depth) << "Package " << Pkg << " loops in SmartConfigure" << std::endl;
-	          Bad = false;
+		     std::clog << OutputInDepth(Depth) << "Package " << Pkg << " loops in SmartConfigure";
+		  if (List->IsFlag(DepPkg,pkgOrderList::UnPacked))
+		     Bad = false;
+		  else if (Debug)
+		     std::clog << ", but it isn't unpacked yet";
+		  if (Debug)
+		     std::clog << std::endl;
 	       }
 	       }
 	       else
 	       else
 	       {
 	       {
@@ -722,7 +734,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c
 
 
 		  // See if the current version is ok
 		  // See if the current version is ok
 		  if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
 		  if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
-		      Pkg.State() == PkgIterator::NeedsNothing)
+		      Pkg.State() == PkgIterator::NeedsNothing &&
+		      (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
 		  {
 		  {
 		     Bad = false;
 		     Bad = false;
 		     if (Debug)
 		     if (Debug)
@@ -744,8 +757,11 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c
 		  PkgIterator DepPkg = Ver.ParentPkg();
 		  PkgIterator DepPkg = Ver.ParentPkg();
 
 
 		  // Not the install version
 		  // Not the install version
-		  if (Cache[DepPkg].InstallVer != *I ||
-		      (Cache[DepPkg].Keep() == true && DepPkg.State() == PkgIterator::NeedsNothing))
+		  if (Cache[DepPkg].InstallVer != *I)
+		     continue;
+
+		  if (Cache[DepPkg].Keep() == true && DepPkg.State() == PkgIterator::NeedsNothing &&
+			(Cache[DepPkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
 		     continue;
 		     continue;
 
 
 		  if (List->IsFlag(DepPkg,pkgOrderList::Configured))
 		  if (List->IsFlag(DepPkg,pkgOrderList::Configured))
@@ -757,6 +773,16 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c
 		  // check if it needs unpack or if if configure is enough
 		  // check if it needs unpack or if if configure is enough
 		  if (List->IsFlag(DepPkg,pkgOrderList::UnPacked) == false)
 		  if (List->IsFlag(DepPkg,pkgOrderList::UnPacked) == false)
 		  {
 		  {
+		     // two packages pre-depending on each other can't be handled sanely
+		     if (List->IsFlag(DepPkg,pkgOrderList::Loop) && PkgLoop)
+		     {
+			// this isn't an error as there is potential for something else to satisfy it
+			// (like a provides or an or-group member)
+			if (Debug)
+			   clog << OutputInDepth(Depth) << "Unpack loop detected between " << DepPkg.FullName() << " and " << Pkg.FullName() << endl;
+			continue;
+		     }
+
 		     if (Debug)
 		     if (Debug)
 			clog << OutputInDepth(Depth) << "Trying to SmartUnpack " << DepPkg.FullName() << endl;
 			clog << OutputInDepth(Depth) << "Trying to SmartUnpack " << DepPkg.FullName() << endl;
 		     if (NonLoopingSmart(UNPACK_IMMEDIATE, Pkg, DepPkg, Depth, PkgLoop, &Bad, &Changed) == false)
 		     if (NonLoopingSmart(UNPACK_IMMEDIATE, Pkg, DepPkg, Depth, PkgLoop, &Bad, &Changed) == false)
@@ -1059,7 +1085,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
 // PM::DoInstallPostFork - compat /*{{{*/
 // PM::DoInstallPostFork - compat /*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 									/*}}}*/
 									/*}}}*/
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+#if APT_PKG_ABI >= 413
 pkgPackageManager::OrderResult
 pkgPackageManager::OrderResult
 pkgPackageManager::DoInstallPostFork(int statusFd)
 pkgPackageManager::DoInstallPostFork(int statusFd)
 {
 {
@@ -1096,7 +1122,7 @@ pkgPackageManager::DoInstallPostFork(int statusFd)
 // PM::DoInstall - Does the installation				/*{{{*/
 // PM::DoInstall - Does the installation				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* compat */
 /* compat */
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+#if APT_PKG_ABI >= 413
 pkgPackageManager::OrderResult 
 pkgPackageManager::OrderResult 
 pkgPackageManager::DoInstall(int statusFd)
 pkgPackageManager::DoInstall(int statusFd)
 {
 {
@@ -1120,7 +1146,7 @@ pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd)
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This uses the filenames in FileNames and the information in the
 /* This uses the filenames in FileNames and the information in the
    DepCache to perform the installation of packages.*/
    DepCache to perform the installation of packages.*/
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+#if APT_PKG_ABI >= 413
 pkgPackageManager::OrderResult 
 pkgPackageManager::OrderResult 
 pkgPackageManager::DoInstall(APT::Progress::PackageManager *progress)
 pkgPackageManager::DoInstall(APT::Progress::PackageManager *progress)
 {
 {

+ 6 - 8
apt-pkg/packagemanager.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: packagemanager.h,v 1.14 2001/05/07 04:24:08 jgg Exp $
 /* ######################################################################
 /* ######################################################################
 
 
    Package Manager - Abstacts the package manager
    Package Manager - Abstacts the package manager
@@ -96,12 +95,10 @@ class pkgPackageManager : protected pkgCache::Namespace
    virtual bool Install(PkgIterator /*Pkg*/,std::string /*File*/) {return false;};
    virtual bool Install(PkgIterator /*Pkg*/,std::string /*File*/) {return false;};
    virtual bool Configure(PkgIterator /*Pkg*/) {return false;};
    virtual bool Configure(PkgIterator /*Pkg*/) {return false;};
    virtual bool Remove(PkgIterator /*Pkg*/,bool /*Purge*/=false) {return false;};
    virtual bool Remove(PkgIterator /*Pkg*/,bool /*Purge*/=false) {return false;};
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+#if APT_PKG_ABI >= 413
    virtual bool Go(APT::Progress::PackageManager * /*progress*/) {return true;};
    virtual bool Go(APT::Progress::PackageManager * /*progress*/) {return true;};
-   virtual bool Go(int /*statusFd*/=-1) {return true;};
-#else
-   virtual bool Go(int /*statusFd*/=-1) {return true;};
 #endif
 #endif
+   virtual bool Go(int /*statusFd*/=-1) {return true;};
 
 
    virtual void Reset() {};
    virtual void Reset() {};
 
 
@@ -114,8 +111,8 @@ class pkgPackageManager : protected pkgCache::Namespace
    bool GetArchives(pkgAcquire *Owner,pkgSourceList *Sources,
    bool GetArchives(pkgAcquire *Owner,pkgSourceList *Sources,
 		    pkgRecords *Recs);
 		    pkgRecords *Recs);
 
 
-   // Do the installation 
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+   // Do the installation
+#if APT_PKG_ABI >= 413
    OrderResult DoInstall(APT::Progress::PackageManager *progress);
    OrderResult DoInstall(APT::Progress::PackageManager *progress);
    // compat
    // compat
    APT_DEPRECATED OrderResult DoInstall(int statusFd=-1);
    APT_DEPRECATED OrderResult DoInstall(int statusFd=-1);
@@ -129,7 +126,7 @@ class pkgPackageManager : protected pkgCache::Namespace
       Res = OrderInstall();
       Res = OrderInstall();
       return Res;
       return Res;
    };
    };
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+#if APT_PKG_ABI >= 413
    // stuff that needs to be done after the fork
    // stuff that needs to be done after the fork
    OrderResult DoInstallPostFork(APT::Progress::PackageManager *progress);
    OrderResult DoInstallPostFork(APT::Progress::PackageManager *progress);
    // compat
    // compat
@@ -148,6 +145,7 @@ class pkgPackageManager : protected pkgCache::Namespace
    virtual ~pkgPackageManager();
    virtual ~pkgPackageManager();
 
 
    private:
    private:
+   void *d;
    enum APT_HIDDEN SmartAction { UNPACK_IMMEDIATE, UNPACK, CONFIGURE };
    enum APT_HIDDEN SmartAction { UNPACK_IMMEDIATE, UNPACK, CONFIGURE };
    APT_HIDDEN bool NonLoopingSmart(SmartAction const action, pkgCache::PkgIterator &Pkg,
    APT_HIDDEN bool NonLoopingSmart(SmartAction const action, pkgCache::PkgIterator &Pkg,
       pkgCache::PkgIterator DepPkg, int const Depth, bool const PkgLoop,
       pkgCache::PkgIterator DepPkg, int const Depth, bool const PkgLoop,

+ 81 - 57
apt-pkg/pkgcache.cc

@@ -61,6 +61,7 @@ pkgCache::Header::Header()
    HeaderSz = sizeof(pkgCache::Header);
    HeaderSz = sizeof(pkgCache::Header);
    GroupSz = sizeof(pkgCache::Group);
    GroupSz = sizeof(pkgCache::Group);
    PackageSz = sizeof(pkgCache::Package);
    PackageSz = sizeof(pkgCache::Package);
+   ReleaseFileSz = sizeof(pkgCache::ReleaseFile);
    PackageFileSz = sizeof(pkgCache::PackageFile);
    PackageFileSz = sizeof(pkgCache::PackageFile);
    VersionSz = sizeof(pkgCache::Version);
    VersionSz = sizeof(pkgCache::Version);
    DescriptionSz = sizeof(pkgCache::Description);
    DescriptionSz = sizeof(pkgCache::Description);
@@ -74,6 +75,7 @@ pkgCache::Header::Header()
    VersionCount = 0;
    VersionCount = 0;
    DescriptionCount = 0;
    DescriptionCount = 0;
    DependsCount = 0;
    DependsCount = 0;
+   ReleaseFileCount = 0;
    PackageFileCount = 0;
    PackageFileCount = 0;
    VerFileCount = 0;
    VerFileCount = 0;
    DescFileCount = 0;
    DescFileCount = 0;
@@ -82,10 +84,14 @@ pkgCache::Header::Header()
    MaxDescFileSize = 0;
    MaxDescFileSize = 0;
    
    
    FileList = 0;
    FileList = 0;
+   RlsFileList = 0;
+#if APT_PKG_ABI < 413
+   APT_IGNORE_DEPRECATED(StringList = 0;)
+#endif
    VerSysName = 0;
    VerSysName = 0;
    Architecture = 0;
    Architecture = 0;
-   Architectures = 0;
-   HashTableSize = _config->FindI("APT::Cache-HashTableSize", 10 * 1048);
+   SetArchitectures(0);
+   SetHashTableSize(_config->FindI("APT::Cache-HashTableSize", 10 * 1048));
    memset(Pools,0,sizeof(Pools));
    memset(Pools,0,sizeof(Pools));
 
 
    CacheFileSize = 0;
    CacheFileSize = 0;
@@ -99,6 +105,7 @@ bool pkgCache::Header::CheckSizes(Header &Against) const
    if (HeaderSz == Against.HeaderSz &&
    if (HeaderSz == Against.HeaderSz &&
        GroupSz == Against.GroupSz &&
        GroupSz == Against.GroupSz &&
        PackageSz == Against.PackageSz &&
        PackageSz == Against.PackageSz &&
+       ReleaseFileSz == Against.ReleaseFileSz &&
        PackageFileSz == Against.PackageFileSz &&
        PackageFileSz == Against.PackageFileSz &&
        VersionSz == Against.VersionSz &&
        VersionSz == Against.VersionSz &&
        DescriptionSz == Against.DescriptionSz &&
        DescriptionSz == Against.DescriptionSz &&
@@ -114,6 +121,7 @@ bool pkgCache::Header::CheckSizes(Header &Against) const
 // Cache::pkgCache - Constructor					/*{{{*/
 // Cache::pkgCache - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
+APT_IGNORE_DEPRECATED_PUSH
 pkgCache::pkgCache(MMap *Map, bool DoMap) : Map(*Map)
 pkgCache::pkgCache(MMap *Map, bool DoMap) : Map(*Map)
 {
 {
    // call getArchitectures() with cached=false to ensure that the 
    // call getArchitectures() with cached=false to ensure that the 
@@ -123,6 +131,7 @@ pkgCache::pkgCache(MMap *Map, bool DoMap) : Map(*Map)
    if (DoMap == true)
    if (DoMap == true)
       ReMap();
       ReMap();
 }
 }
+APT_IGNORE_DEPRECATED_POP
 									/*}}}*/
 									/*}}}*/
 // Cache::ReMap - Reopen the cache file					/*{{{*/
 // Cache::ReMap - Reopen the cache file					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
@@ -135,6 +144,7 @@ bool pkgCache::ReMap(bool const &Errorchecks)
    PkgP = (Package *)Map.Data();
    PkgP = (Package *)Map.Data();
    VerFileP = (VerFile *)Map.Data();
    VerFileP = (VerFile *)Map.Data();
    DescFileP = (DescFile *)Map.Data();
    DescFileP = (DescFile *)Map.Data();
+   RlsFileP = (ReleaseFile *)Map.Data();
    PkgFileP = (PackageFile *)Map.Data();
    PkgFileP = (PackageFile *)Map.Data();
    VerP = (Version *)Map.Data();
    VerP = (Version *)Map.Data();
    DescP = (Description *)Map.Data();
    DescP = (Description *)Map.Data();
@@ -162,7 +172,7 @@ bool pkgCache::ReMap(bool const &Errorchecks)
    if (Map.Size() < HeaderP->CacheFileSize)
    if (Map.Size() < HeaderP->CacheFileSize)
       return _error->Error(_("The package cache file is corrupted, it is too small"));
       return _error->Error(_("The package cache file is corrupted, it is too small"));
 
 
-   if (HeaderP->VerSysName == 0 || HeaderP->Architecture == 0 || HeaderP->Architectures == 0)
+   if (HeaderP->VerSysName == 0 || HeaderP->Architecture == 0 || HeaderP->GetArchitectures() == 0)
       return _error->Error(_("The package cache file is corrupted"));
       return _error->Error(_("The package cache file is corrupted"));
 
 
    // Locate our VS..
    // Locate our VS..
@@ -176,8 +186,8 @@ bool pkgCache::ReMap(bool const &Errorchecks)
    for (++a; a != archs.end(); ++a)
    for (++a; a != archs.end(); ++a)
       list.append(",").append(*a);
       list.append(",").append(*a);
    if (_config->Find("APT::Architecture") != StrP + HeaderP->Architecture ||
    if (_config->Find("APT::Architecture") != StrP + HeaderP->Architecture ||
-	 list != StrP + HeaderP->Architectures)
-      return _error->Error(_("The package cache was built for different architectures: %s vs %s"), StrP + HeaderP->Architectures, list.c_str());
+	 list != StrP + HeaderP->GetArchitectures())
+      return _error->Error(_("The package cache was built for different architectures: %s vs %s"), StrP + HeaderP->GetArchitectures(), list.c_str());
 
 
    return true;
    return true;
 }
 }
@@ -192,7 +202,7 @@ map_id_t pkgCache::sHash(const string &Str) const
    unsigned long Hash = 0;
    unsigned long Hash = 0;
    for (string::const_iterator I = Str.begin(); I != Str.end(); ++I)
    for (string::const_iterator I = Str.begin(); I != Str.end(); ++I)
       Hash = 41 * Hash + tolower_ascii(*I);
       Hash = 41 * Hash + tolower_ascii(*I);
-   return Hash % HeaderP->HashTableSize;
+   return Hash % HeaderP->GetHashTableSize();
 }
 }
 
 
 map_id_t pkgCache::sHash(const char *Str) const
 map_id_t pkgCache::sHash(const char *Str) const
@@ -200,7 +210,7 @@ map_id_t pkgCache::sHash(const char *Str) const
    unsigned long Hash = tolower_ascii(*Str);
    unsigned long Hash = tolower_ascii(*Str);
    for (const char *I = Str + 1; *I != 0; ++I)
    for (const char *I = Str + 1; *I != 0; ++I)
       Hash = 41 * Hash + tolower_ascii(*I);
       Hash = 41 * Hash + tolower_ascii(*I);
-   return Hash % HeaderP->HashTableSize;
+   return Hash % HeaderP->GetHashTableSize();
 }
 }
 									/*}}}*/
 									/*}}}*/
 // Cache::SingleArchFindPkg - Locate a package by name			/*{{{*/
 // Cache::SingleArchFindPkg - Locate a package by name			/*{{{*/
@@ -211,8 +221,8 @@ map_id_t pkgCache::sHash(const char *Str) const
 pkgCache::PkgIterator pkgCache::SingleArchFindPkg(const string &Name)
 pkgCache::PkgIterator pkgCache::SingleArchFindPkg(const string &Name)
 {
 {
    // Look at the hash bucket
    // Look at the hash bucket
-   Package *Pkg = PkgP + HeaderP->PkgHashTable()[Hash(Name)];
-   for (; Pkg != PkgP; Pkg = PkgP + Pkg->Next)
+   Package *Pkg = PkgP + HeaderP->PkgHashTableP()[Hash(Name)];
+   for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage)
    {
    {
       int const cmp = strcmp(Name.c_str(), StrP + (GrpP + Pkg->Group)->Name);
       int const cmp = strcmp(Name.c_str(), StrP + (GrpP + Pkg->Group)->Name);
       if (cmp == 0)
       if (cmp == 0)
@@ -229,12 +239,7 @@ pkgCache::PkgIterator pkgCache::SingleArchFindPkg(const string &Name)
 pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) {
 pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) {
 	size_t const found = Name.find(':');
 	size_t const found = Name.find(':');
 	if (found == string::npos)
 	if (found == string::npos)
-	{
-		if (MultiArchCache() == false)
-			return SingleArchFindPkg(Name);
-		else
-			return FindPkg(Name, "native");
-	}
+	   return FindPkg(Name, "native");
 	string const Arch = Name.substr(found+1);
 	string const Arch = Name.substr(found+1);
 	/* Beware: This is specialcased to handle pkg:any in dependencies as
 	/* Beware: This is specialcased to handle pkg:any in dependencies as
 	   these are linked to virtual pkg:any named packages with all archs.
 	   these are linked to virtual pkg:any named packages with all archs.
@@ -248,13 +253,6 @@ pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) {
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Returns 0 on error, pointer to the package otherwise */
 /* Returns 0 on error, pointer to the package otherwise */
 pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string const &Arch) {
 pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string const &Arch) {
-	if (MultiArchCache() == false && Arch != "none") {
-		if (Arch == "native" || Arch == "all" || Arch == "any" ||
-		    Arch == NativeArch())
-			return SingleArchFindPkg(Name);
-		else
-			return PkgIterator(*this,0);
-	}
 	/* We make a detour via the GrpIterator here as
 	/* We make a detour via the GrpIterator here as
 	   on a multi-arch environment a group is easier to
 	   on a multi-arch environment a group is easier to
 	   find than a package (less entries in the buckets) */
 	   find than a package (less entries in the buckets) */
@@ -273,7 +271,7 @@ pkgCache::GrpIterator pkgCache::FindGrp(const string &Name) {
 		return GrpIterator(*this,0);
 		return GrpIterator(*this,0);
 
 
 	// Look at the hash bucket for the group
 	// Look at the hash bucket for the group
-	Group *Grp = GrpP + HeaderP->GrpHashTable()[sHash(Name)];
+	Group *Grp = GrpP + HeaderP->GrpHashTableP()[sHash(Name)];
 	for (; Grp != GrpP; Grp = GrpP + Grp->Next) {
 	for (; Grp != GrpP; Grp = GrpP + Grp->Next) {
 		int const cmp = strcmp(Name.c_str(), StrP + Grp->Name);
 		int const cmp = strcmp(Name.c_str(), StrP + Grp->Name);
 		if (cmp == 0)
 		if (cmp == 0)
@@ -359,7 +357,7 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) const {
 
 
 	// Iterate over the list to find the matching arch
 	// Iterate over the list to find the matching arch
 	for (pkgCache::Package *Pkg = PackageList(); Pkg != Owner->PkgP;
 	for (pkgCache::Package *Pkg = PackageList(); Pkg != Owner->PkgP;
-	     Pkg = Owner->PkgP + Pkg->Next) {
+	     Pkg = Owner->PkgP + Pkg->NextPackage) {
 		if (stringcmp(Arch, Owner->StrP + Pkg->Arch) == 0)
 		if (stringcmp(Arch, Owner->StrP + Pkg->Arch) == 0)
 			return PkgIterator(*Owner, Pkg);
 			return PkgIterator(*Owner, Pkg);
 		if ((Owner->PkgP + S->LastPackage) == Pkg)
 		if ((Owner->PkgP + S->LastPackage) == Pkg)
@@ -407,7 +405,7 @@ pkgCache::PkgIterator pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator const
 	if (S->LastPackage == LastPkg.Index())
 	if (S->LastPackage == LastPkg.Index())
 		return PkgIterator(*Owner, 0);
 		return PkgIterator(*Owner, 0);
 
 
-	return PkgIterator(*Owner, Owner->PkgP + LastPkg->Next);
+	return PkgIterator(*Owner, Owner->PkgP + LastPkg->NextPackage);
 }
 }
 									/*}}}*/
 									/*}}}*/
 // GrpIterator::operator ++ - Postfix incr				/*{{{*/
 // GrpIterator::operator ++ - Postfix incr				/*{{{*/
@@ -420,10 +418,10 @@ void pkgCache::GrpIterator::operator ++(int)
       S = Owner->GrpP + S->Next;
       S = Owner->GrpP + S->Next;
 
 
    // Follow the hash table
    // Follow the hash table
-   while (S == Owner->GrpP && (HashIndex+1) < (signed)Owner->HeaderP->HashTableSize)
+   while (S == Owner->GrpP && (HashIndex+1) < (signed)Owner->HeaderP->GetHashTableSize())
    {
    {
       HashIndex++;
       HashIndex++;
-      S = Owner->GrpP + Owner->HeaderP->GrpHashTable()[HashIndex];
+      S = Owner->GrpP + Owner->HeaderP->GrpHashTableP()[HashIndex];
    }
    }
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -434,13 +432,13 @@ void pkgCache::PkgIterator::operator ++(int)
 {
 {
    // Follow the current links
    // Follow the current links
    if (S != Owner->PkgP)
    if (S != Owner->PkgP)
-      S = Owner->PkgP + S->Next;
+      S = Owner->PkgP + S->NextPackage;
 
 
    // Follow the hash table
    // Follow the hash table
-   while (S == Owner->PkgP && (HashIndex+1) < (signed)Owner->HeaderP->HashTableSize)
+   while (S == Owner->PkgP && (HashIndex+1) < (signed)Owner->HeaderP->GetHashTableSize())
    {
    {
       HashIndex++;
       HashIndex++;
-      S = Owner->PkgP + Owner->HeaderP->PkgHashTable()[HashIndex];
+      S = Owner->PkgP + Owner->HeaderP->PkgHashTableP()[HashIndex];
    }
    }
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -821,7 +819,7 @@ APT_PURE bool pkgCache::VerIterator::Downloadable() const
 {
 {
    VerFileIterator Files = FileList();
    VerFileIterator Files = FileList();
    for (; Files.end() == false; ++Files)
    for (; Files.end() == false; ++Files)
-      if ((Files.File()->Flags & pkgCache::Flag::NotSource) != pkgCache::Flag::NotSource)
+      if (Files.File().Flagged(pkgCache::Flag::NotSource) == false)
 	 return true;
 	 return true;
    return false;
    return false;
 }
 }
@@ -835,7 +833,7 @@ APT_PURE bool pkgCache::VerIterator::Automatic() const
    VerFileIterator Files = FileList();
    VerFileIterator Files = FileList();
    for (; Files.end() == false; ++Files)
    for (; Files.end() == false; ++Files)
       // Do not check ButAutomaticUpgrades here as it is kind of automatic…
       // Do not check ButAutomaticUpgrades here as it is kind of automatic…
-      if ((Files.File()->Flags & pkgCache::Flag::NotAutomatic) != pkgCache::Flag::NotAutomatic)
+      if (Files.File().Flagged(pkgCache::Flag::NotAutomatic) == false)
 	 return true;
 	 return true;
    return false;
    return false;
 }
 }
@@ -868,27 +866,27 @@ string pkgCache::VerIterator::RelStr() const
    for (pkgCache::VerFileIterator I = this->FileList(); I.end() == false; ++I)
    for (pkgCache::VerFileIterator I = this->FileList(); I.end() == false; ++I)
    {
    {
       // Do not print 'not source' entries'
       // Do not print 'not source' entries'
-      pkgCache::PkgFileIterator File = I.File();
-      if ((File->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource)
+      pkgCache::PkgFileIterator const File = I.File();
+      if (File.Flagged(pkgCache::Flag::NotSource))
 	 continue;
 	 continue;
 
 
       // See if we have already printed this out..
       // See if we have already printed this out..
       bool Seen = false;
       bool Seen = false;
       for (pkgCache::VerFileIterator J = this->FileList(); I != J; ++J)
       for (pkgCache::VerFileIterator J = this->FileList(); I != J; ++J)
       {
       {
-	 pkgCache::PkgFileIterator File2 = J.File();
-	 if (File2->Label == 0 || File->Label == 0)
+	 pkgCache::PkgFileIterator const File2 = J.File();
+	 if (File2.Label() == 0 || File.Label() == 0)
 	    continue;
 	    continue;
 
 
 	 if (strcmp(File.Label(),File2.Label()) != 0)
 	 if (strcmp(File.Label(),File2.Label()) != 0)
 	    continue;
 	    continue;
 	 
 	 
-	 if (File2->Version == File->Version)
+	 if (File2.Version() == File.Version())
 	 {
 	 {
 	    Seen = true;
 	    Seen = true;
 	    break;
 	    break;
 	 }
 	 }
-	 if (File2->Version == 0 || File->Version == 0)
+	 if (File2.Version() == 0 || File.Version() == 0)
 	    break;
 	    break;
 	 if (strcmp(File.Version(),File2.Version()) == 0)
 	 if (strcmp(File.Version(),File2.Version()) == 0)
 	    Seen = true;
 	    Seen = true;
@@ -902,12 +900,12 @@ string pkgCache::VerIterator::RelStr() const
       else
       else
 	 First = false;
 	 First = false;
       
       
-      if (File->Label != 0)
+      if (File.Label() != 0)
 	 Res = Res + File.Label() + ':';
 	 Res = Res + File.Label() + ':';
 
 
-      if (File->Archive != 0)
+      if (File.Archive() != 0)
       {
       {
-	 if (File->Version == 0)
+	 if (File.Version() == 0)
 	    Res += File.Archive();
 	    Res += File.Archive();
 	 else
 	 else
 	    Res = Res + File.Version() + '/' +  File.Archive();
 	    Res = Res + File.Version() + '/' +  File.Archive();
@@ -915,7 +913,7 @@ string pkgCache::VerIterator::RelStr() const
       else
       else
       {
       {
 	 // No release file, print the host name that this came from
 	 // No release file, print the host name that this came from
-	 if (File->Site == 0 || File.Site()[0] == 0)
+	 if (File.Site() == 0 || File.Site()[0] == 0)
 	    Res += "localhost";
 	    Res += "localhost";
 	 else
 	 else
 	    Res += File.Site();
 	    Res += File.Site();
@@ -938,12 +936,12 @@ const char * pkgCache::VerIterator::MultiArchType() const
    return "none";
    return "none";
 }
 }
 									/*}}}*/
 									/*}}}*/
-// PkgFileIterator::IsOk - Checks if the cache is in sync with the file	/*{{{*/
+// RlsFileIterator::IsOk - Checks if the cache is in sync with the file	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This stats the file and compares its stats with the ones that were
 /* This stats the file and compares its stats with the ones that were
-   stored during generation. Date checks should probably also be 
+   stored during generation. Date checks should probably also be
    included here. */
    included here. */
-bool pkgCache::PkgFileIterator::IsOk()
+bool pkgCache::RlsFileIterator::IsOk()
 {
 {
    struct stat Buf;
    struct stat Buf;
    if (stat(FileName(),&Buf) != 0)
    if (stat(FileName(),&Buf) != 0)
@@ -955,10 +953,8 @@ bool pkgCache::PkgFileIterator::IsOk()
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// PkgFileIterator::RelStr - Return the release string			/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string pkgCache::PkgFileIterator::RelStr()
+// RlsFileIterator::RelStr - Return the release string			/*{{{*/
+string pkgCache::RlsFileIterator::RelStr()
 {
 {
    string Res;
    string Res;
    if (Version() != 0)
    if (Version() != 0)
@@ -971,8 +967,40 @@ string pkgCache::PkgFileIterator::RelStr()
       Res = Res + (Res.empty() == true?"n=":",n=")  + Codename();
       Res = Res + (Res.empty() == true?"n=":",n=")  + Codename();
    if (Label() != 0)
    if (Label() != 0)
       Res = Res + (Res.empty() == true?"l=":",l=")  + Label();
       Res = Res + (Res.empty() == true?"l=":",l=")  + Label();
-   if (Component() != 0)
-      Res = Res + (Res.empty() == true?"c=":",c=")  + Component();
+   return Res;
+}
+									/*}}}*/
+// PkgFileIterator::IsOk - Checks if the cache is in sync with the file	/*{{{*/
+// ---------------------------------------------------------------------
+/* This stats the file and compares its stats with the ones that were
+   stored during generation. Date checks should probably also be
+   included here. */
+bool pkgCache::PkgFileIterator::IsOk()
+{
+   struct stat Buf;
+   if (stat(FileName(),&Buf) != 0)
+      return false;
+
+   if (Buf.st_size != (signed)S->Size || Buf.st_mtime != S->mtime)
+      return false;
+
+   return true;
+}
+									/*}}}*/
+string pkgCache::PkgFileIterator::RelStr()				/*{{{*/
+{
+   std::string Res;
+   if (ReleaseFile() == 0)
+   {
+      if (Component() != 0)
+	 Res = Res + (Res.empty() == true?"a=":",a=")  + Component();
+   }
+   else
+   {
+      Res = ReleaseFile().RelStr();
+      if (Component() != 0)
+	 Res = Res + (Res.empty() == true?"c=":",c=")  + Component();
+   }
    if (Architecture() != 0)
    if (Architecture() != 0)
       Res = Res + (Res.empty() == true?"b=":",b=")  + Architecture();
       Res = Res + (Res.empty() == true?"b=":",b=")  + Architecture();
    return Res;
    return Res;
@@ -1031,9 +1059,5 @@ bool pkgCache::PrvIterator::IsMultiArchImplicit() const
    return false;
    return false;
 }
 }
 									/*}}}*/
 									/*}}}*/
-APT_DEPRECATED APT_PURE const char * pkgCache::PkgIterator::Section() const {/*{{{*/
-   if (S->VersionList == 0)
-      return 0;
-   return VersionList().Section();
-}
-									/*}}}*/
+
+pkgCache::~pkgCache() {}

+ 151 - 26
apt-pkg/pkgcache.h

@@ -85,16 +85,45 @@
 using std::string;
 using std::string;
 #endif
 #endif
 
 
+#if APT_PKG_ABI >= 413
 // storing file sizes of indexes, which are way below 4 GB for now
 // storing file sizes of indexes, which are way below 4 GB for now
 typedef uint32_t map_filesize_t;
 typedef uint32_t map_filesize_t;
+typedef map_filesize_t should_be_map_filesize_t;
+#else
+typedef unsigned long map_filesize_t;
+typedef unsigned int should_be_map_filesize_t;
+#endif
+#if APT_PKG_ABI >= 413
 // each package/group/dependency gets an id
 // each package/group/dependency gets an id
 typedef uint32_t map_id_t;
 typedef uint32_t map_id_t;
+typedef map_id_t should_be_map_id_t;
+#else
+typedef unsigned long map_id_t;
+typedef unsigned int should_be_map_id_t;
+#endif
+#if APT_PKG_ABI >= 413
 // some files get an id, too, but in far less absolute numbers
 // some files get an id, too, but in far less absolute numbers
 typedef uint16_t map_fileid_t;
 typedef uint16_t map_fileid_t;
+typedef map_fileid_t should_be_map_fileid_t;
+#else
+typedef unsigned long map_fileid_t;
+typedef unsigned int should_be_map_fileid_t;
+#endif
+#if APT_PKG_ABI >= 413
 // relative pointer from cache start
 // relative pointer from cache start
 typedef uint32_t map_pointer_t;
 typedef uint32_t map_pointer_t;
+#else
+typedef unsigned int map_pointer_t;
+#endif
 // same as the previous, but documented to be to a string item
 // same as the previous, but documented to be to a string item
 typedef map_pointer_t map_stringitem_t;
 typedef map_pointer_t map_stringitem_t;
+#if APT_PKG_ABI >= 413
+typedef uint64_t should_be_uint64_t;
+typedef uint64_t should_be_uint64_small_t;
+#else
+typedef unsigned long long should_be_uint64_t;
+typedef unsigned long should_be_uint64_small_t;
+#endif
 
 
 class pkgVersioningSystem;
 class pkgVersioningSystem;
 class pkgCache								/*{{{*/
 class pkgCache								/*{{{*/
@@ -104,11 +133,13 @@ class pkgCache								/*{{{*/
    struct Header;
    struct Header;
    struct Group;
    struct Group;
    struct Package;
    struct Package;
+   struct ReleaseFile;
    struct PackageFile;
    struct PackageFile;
    struct Version;
    struct Version;
    struct Description;
    struct Description;
    struct Provides;
    struct Provides;
    struct Dependency;
    struct Dependency;
+   struct StringItem;
    struct VerFile;
    struct VerFile;
    struct DescFile;
    struct DescFile;
    
    
@@ -120,6 +151,7 @@ class pkgCache								/*{{{*/
    class DescIterator;
    class DescIterator;
    class DepIterator;
    class DepIterator;
    class PrvIterator;
    class PrvIterator;
+   class RlsFileIterator;
    class PkgFileIterator;
    class PkgFileIterator;
    class VerFileIterator;
    class VerFileIterator;
    class DescFileIterator;
    class DescFileIterator;
@@ -160,7 +192,15 @@ class pkgCache								/*{{{*/
    struct Flag
    struct Flag
    {
    {
       enum PkgFlags {Auto=(1<<0),Essential=(1<<3),Important=(1<<4)};
       enum PkgFlags {Auto=(1<<0),Essential=(1<<3),Important=(1<<4)};
-      enum PkgFFlags {NotSource=(1<<0),NotAutomatic=(1<<1),ButAutomaticUpgrades=(1<<2)};
+      enum PkgFFlags {
+	 NotSource=(1<<0), /*!< packages can't be fetched from here, e.g. dpkg/status file */
+	 LocalSource=(1<<1), /*!< local sources can't and will not be verified by hashes */
+	 NoPackages=(1<<2), /*!< the file includes no package records itself, but additions like Translations */
+      };
+      enum ReleaseFileFlags {
+	 NotAutomatic=(1<<0), /*!< archive has a default pin of 1 */
+	 ButAutomaticUpgrades=(1<<1), /*!< (together with the previous) archive has a default pin of 100 */
+      };
    };
    };
    
    
    protected:
    protected:
@@ -180,11 +220,13 @@ class pkgCache								/*{{{*/
    Package *PkgP;
    Package *PkgP;
    VerFile *VerFileP;
    VerFile *VerFileP;
    DescFile *DescFileP;
    DescFile *DescFileP;
+   ReleaseFile *RlsFileP;
    PackageFile *PkgFileP;
    PackageFile *PkgFileP;
    Version *VerP;
    Version *VerP;
    Description *DescP;
    Description *DescP;
    Provides *ProvideP;
    Provides *ProvideP;
    Dependency *DepP;
    Dependency *DepP;
+   APT_DEPRECATED StringItem *StringItemP;
    char *StrP;
    char *StrP;
 
 
    virtual bool ReMap(bool const &Errorchecks = true);
    virtual bool ReMap(bool const &Errorchecks = true);
@@ -211,6 +253,8 @@ class pkgCache								/*{{{*/
    inline PkgIterator PkgEnd();
    inline PkgIterator PkgEnd();
    inline PkgFileIterator FileBegin();
    inline PkgFileIterator FileBegin();
    inline PkgFileIterator FileEnd();
    inline PkgFileIterator FileEnd();
+   inline RlsFileIterator RlsFileBegin();
+   inline RlsFileIterator RlsFileEnd();
 
 
    inline bool MultiArchCache() const { return MultiArchEnabled; }
    inline bool MultiArchCache() const { return MultiArchEnabled; }
    inline char const * NativeArch();
    inline char const * NativeArch();
@@ -222,11 +266,12 @@ class pkgCache								/*{{{*/
    static const char *CompTypeDeb(unsigned char Comp) APT_CONST;
    static const char *CompTypeDeb(unsigned char Comp) APT_CONST;
    static const char *CompType(unsigned char Comp) APT_CONST;
    static const char *CompType(unsigned char Comp) APT_CONST;
    static const char *DepType(unsigned char Dep);
    static const char *DepType(unsigned char Dep);
-   
+
    pkgCache(MMap *Map,bool DoMap = true);
    pkgCache(MMap *Map,bool DoMap = true);
-   virtual ~pkgCache() {}
+   virtual ~pkgCache();
 
 
 private:
 private:
+   void *d;
    bool MultiArchEnabled;
    bool MultiArchEnabled;
    APT_HIDDEN PkgIterator SingleArchFindPkg(const std::string &Name);
    APT_HIDDEN PkgIterator SingleArchFindPkg(const std::string &Name);
 };
 };
@@ -260,6 +305,7 @@ struct pkgCache::Header
    unsigned short HeaderSz;
    unsigned short HeaderSz;
    unsigned short GroupSz;
    unsigned short GroupSz;
    unsigned short PackageSz;
    unsigned short PackageSz;
+   unsigned short ReleaseFileSz;
    unsigned short PackageFileSz;
    unsigned short PackageFileSz;
    unsigned short VersionSz;
    unsigned short VersionSz;
    unsigned short DescriptionSz;
    unsigned short DescriptionSz;
@@ -278,6 +324,7 @@ struct pkgCache::Header
    map_id_t VersionCount;
    map_id_t VersionCount;
    map_id_t DescriptionCount;
    map_id_t DescriptionCount;
    map_id_t DependsCount;
    map_id_t DependsCount;
+   map_fileid_t ReleaseFileCount;
    map_fileid_t PackageFileCount;
    map_fileid_t PackageFileCount;
    map_fileid_t VerFileCount;
    map_fileid_t VerFileCount;
    map_fileid_t DescFileCount;
    map_fileid_t DescFileCount;
@@ -288,12 +335,20 @@ struct pkgCache::Header
        The PackageFile structures are singly linked lists that represent
        The PackageFile structures are singly linked lists that represent
        all package files that have been merged into the cache. */
        all package files that have been merged into the cache. */
    map_pointer_t FileList;
    map_pointer_t FileList;
+   /** \brief index of the first ReleaseFile structure */
+   map_pointer_t RlsFileList;
+
+#if APT_PKG_ABI < 413
+   APT_DEPRECATED map_pointer_t StringList;
+#endif
    /** \brief String representing the version system used */
    /** \brief String representing the version system used */
    map_pointer_t VerSysName;
    map_pointer_t VerSysName;
    /** \brief native architecture the cache was built against */
    /** \brief native architecture the cache was built against */
    map_pointer_t Architecture;
    map_pointer_t Architecture;
+#if APT_PKG_ABI >= 413
    /** \brief all architectures the cache was built against */
    /** \brief all architectures the cache was built against */
    map_pointer_t Architectures;
    map_pointer_t Architectures;
+#endif
    /** \brief The maximum size of a raw entry from the original Package file */
    /** \brief The maximum size of a raw entry from the original Package file */
    map_filesize_t MaxVerFileSize;
    map_filesize_t MaxVerFileSize;
    /** \brief The maximum size of a raw entry from the original Translation file */
    /** \brief The maximum size of a raw entry from the original Translation file */
@@ -319,12 +374,26 @@ struct pkgCache::Header
        In the PkgHashTable is it possible that multiple packages have the same name -
        In the PkgHashTable is it possible that multiple packages have the same name -
        these packages are stored as a sequence in the list.
        these packages are stored as a sequence in the list.
        The size of both tables is the same. */
        The size of both tables is the same. */
+#if APT_PKG_ABI >= 413
    unsigned int HashTableSize;
    unsigned int HashTableSize;
-   map_pointer_t * PkgHashTable() const { return (map_pointer_t*) (this + 1); }
-   map_pointer_t * GrpHashTable() const { return PkgHashTable() + HashTableSize; }
+   unsigned int GetHashTableSize() const { return HashTableSize; }
+   void SetHashTableSize(unsigned int const sz) { HashTableSize = sz; }
+   map_pointer_t GetArchitectures() const { return Architectures; }
+   void SetArchitectures(map_pointer_t const idx) { Architectures = idx; }
+#else
+   // BEWARE: these tables are pretty much empty and just here for abi compat
+   map_ptrloc PkgHashTable[2*1048];
+   map_ptrloc GrpHashTable[2*1048];
+   unsigned int GetHashTableSize() const { return PkgHashTable[0]; }
+   void SetHashTableSize(unsigned int const sz) { PkgHashTable[0] = sz; }
+   map_pointer_t GetArchitectures() const { return PkgHashTable[1]; }
+   void SetArchitectures(map_pointer_t const idx) { PkgHashTable[1] = idx; }
+#endif
+   map_pointer_t * PkgHashTableP() const { return (map_pointer_t*) (this + 1); }
+   map_pointer_t * GrpHashTableP() const { return PkgHashTableP() + GetHashTableSize(); }
 
 
    /** \brief Size of the complete cache file */
    /** \brief Size of the complete cache file */
-   unsigned long long CacheFileSize;
+   should_be_uint64_small_t CacheFileSize;
 
 
    bool CheckSizes(Header &Against) const APT_PURE;
    bool CheckSizes(Header &Against) const APT_PURE;
    Header();
    Header();
@@ -350,7 +419,7 @@ struct pkgCache::Group
    /** \brief Link to the next Group */
    /** \brief Link to the next Group */
    map_pointer_t Next;		// Group
    map_pointer_t Next;		// Group
    /** \brief unique sequel ID */
    /** \brief unique sequel ID */
-   map_id_t ID;
+   should_be_map_id_t ID;
 
 
 };
 };
 									/*}}}*/
 									/*}}}*/
@@ -387,12 +456,18 @@ struct pkgCache::Package
    map_pointer_t VersionList;       // Version
    map_pointer_t VersionList;       // Version
    /** \brief index to the installed version */
    /** \brief index to the installed version */
    map_pointer_t CurrentVer;        // Version
    map_pointer_t CurrentVer;        // Version
+   /** \brief indicates nothing (consistently)
+       This field used to contain ONE section the package belongs to,
+       if those differs between versions it is a RANDOM one.
+       The Section() method tries to reproduce it, but the only sane
+       thing to do is use the Section field from the version! */
+   APT_DEPRECATED map_ptrloc Section; // StringItem
    /** \brief index of the group this package belongs to */
    /** \brief index of the group this package belongs to */
    map_pointer_t Group;             // Group the Package belongs to
    map_pointer_t Group;             // Group the Package belongs to
 
 
    // Linked list
    // Linked list
    /** \brief Link to the next package in the same bucket */
    /** \brief Link to the next package in the same bucket */
-   map_pointer_t Next;       // Package
+   map_pointer_t NextPackage;       // Package
    /** \brief List of all dependencies on this package */
    /** \brief List of all dependencies on this package */
    map_pointer_t RevDepends;        // Dependency
    map_pointer_t RevDepends;        // Dependency
    /** \brief List of all "packages" this package provide */
    /** \brief List of all "packages" this package provide */
@@ -416,20 +491,19 @@ struct pkgCache::Package
        This allows clients to create an array of size PackageCount and use it to store
        This allows clients to create an array of size PackageCount and use it to store
        state information for the package map. For instance the status file emitter uses
        state information for the package map. For instance the status file emitter uses
        this to track which packages have been emitted already. */
        this to track which packages have been emitted already. */
-   map_id_t ID;
+   should_be_map_id_t ID;
    /** \brief some useful indicators of the package's state */
    /** \brief some useful indicators of the package's state */
    unsigned long Flags;
    unsigned long Flags;
 };
 };
 									/*}}}*/
 									/*}}}*/
-// Package File structure						/*{{{*/
-/** \brief stores information about the files used to generate the cache
+// Release File structure						/*{{{*/
+/** \brief stores information about the release files used to generate the cache
 
 
-    Package files are referenced by Version structures to be able to know
-    after the generation still from which Packages file includes this Version
-    as we need this information later on e.g. for pinning. */
-struct pkgCache::PackageFile
+    PackageFiles reference ReleaseFiles as we need to keep record of which
+    version belongs to which release e.g. for pinning. */
+struct pkgCache::ReleaseFile
 {
 {
-   /** \brief physical disk file that this PackageFile represents */
+   /** \brief physical disk file that this ReleaseFile represents */
    map_stringitem_t FileName;
    map_stringitem_t FileName;
    /** \brief the release information
    /** \brief the release information
 
 
@@ -437,13 +511,47 @@ struct pkgCache::PackageFile
        release information means. */
        release information means. */
    map_stringitem_t Archive;
    map_stringitem_t Archive;
    map_stringitem_t Codename;
    map_stringitem_t Codename;
-   map_stringitem_t Component;
    map_stringitem_t Version;
    map_stringitem_t Version;
    map_stringitem_t Origin;
    map_stringitem_t Origin;
    map_stringitem_t Label;
    map_stringitem_t Label;
-   map_stringitem_t Architecture;
    /** \brief The site the index file was fetched from */
    /** \brief The site the index file was fetched from */
    map_stringitem_t Site;
    map_stringitem_t Site;
+
+   /** \brief Size of the file
+
+       Used together with the modification time as a
+       simple check to ensure that the Packages
+       file has not been altered since Cache generation. */
+   map_filesize_t Size;
+   /** \brief Modification time for the file */
+   time_t mtime;
+
+   /** @TODO document PackageFile::Flags */
+   unsigned long Flags;
+
+   // Linked list
+   /** \brief Link to the next ReleaseFile in the Cache */
+   map_pointer_t NextFile;
+   /** \brief unique sequel ID */
+   should_be_map_fileid_t ID;
+};
+									/*}}}*/
+// Package File structure						/*{{{*/
+/** \brief stores information about the files used to generate the cache
+
+    Package files are referenced by Version structures to be able to know
+    after the generation still from which Packages file includes this Version
+    as we need this information later on e.g. for pinning. */
+struct pkgCache::PackageFile
+{
+   /** \brief physical disk file that this PackageFile represents */
+   map_stringitem_t FileName;
+   /** \brief the release information */
+   map_pointer_t Release;
+
+   map_stringitem_t Component;
+   map_stringitem_t Architecture;
+
    /** \brief indicates what sort of index file this is
    /** \brief indicates what sort of index file this is
 
 
        @TODO enumerate at least the possible indexes */
        @TODO enumerate at least the possible indexes */
@@ -464,7 +572,7 @@ struct pkgCache::PackageFile
    /** \brief Link to the next PackageFile in the Cache */
    /** \brief Link to the next PackageFile in the Cache */
    map_pointer_t NextFile;        // PackageFile
    map_pointer_t NextFile;        // PackageFile
    /** \brief unique sequel ID */
    /** \brief unique sequel ID */
-   map_fileid_t ID;
+   should_be_map_fileid_t ID;
 };
 };
 									/*}}}*/
 									/*}}}*/
 // VerFile structure							/*{{{*/
 // VerFile structure							/*{{{*/
@@ -479,7 +587,7 @@ struct pkgCache::VerFile
    /** \brief next step in the linked list */
    /** \brief next step in the linked list */
    map_pointer_t NextFile;       // PkgVerFile
    map_pointer_t NextFile;       // PkgVerFile
    /** \brief position in the package file */
    /** \brief position in the package file */
-   map_filesize_t Offset;         // File offset
+   should_be_map_filesize_t Offset;         // File offset
    /** @TODO document pkgCache::VerFile::Size */
    /** @TODO document pkgCache::VerFile::Size */
    map_filesize_t Size;
    map_filesize_t Size;
 };
 };
@@ -493,7 +601,7 @@ struct pkgCache::DescFile
    /** \brief next step in the linked list */
    /** \brief next step in the linked list */
    map_pointer_t NextFile;       // PkgVerFile
    map_pointer_t NextFile;       // PkgVerFile
    /** \brief position in the file */
    /** \brief position in the file */
-   map_filesize_t Offset;         // File offset
+   should_be_map_filesize_t Offset;         // File offset
    /** @TODO document pkgCache::DescFile::Size */
    /** @TODO document pkgCache::DescFile::Size */
    map_filesize_t Size;
    map_filesize_t Size;
 };
 };
@@ -510,12 +618,14 @@ struct pkgCache::Version
    map_stringitem_t VerStr;
    map_stringitem_t VerStr;
    /** \brief section this version is filled in */
    /** \brief section this version is filled in */
    map_stringitem_t Section;
    map_stringitem_t Section;
+#if APT_PKG_ABI >= 413
    /** \brief source package name this version comes from
    /** \brief source package name this version comes from
       Always contains the name, even if it is the same as the binary name */
       Always contains the name, even if it is the same as the binary name */
    map_stringitem_t SourcePkgName;
    map_stringitem_t SourcePkgName;
    /** \brief source version this version comes from
    /** \brief source version this version comes from
       Always contains the version string, even if it is the same as the binary version */
       Always contains the version string, even if it is the same as the binary version */
    map_stringitem_t SourceVerStr;
    map_stringitem_t SourceVerStr;
+#endif
 
 
    /** \brief Multi-Arch capabilities of a package version */
    /** \brief Multi-Arch capabilities of a package version */
    enum VerMultiArch { None = 0, /*!< is the default and doesn't trigger special behaviour */
    enum VerMultiArch { None = 0, /*!< is the default and doesn't trigger special behaviour */
@@ -554,16 +664,16 @@ struct pkgCache::Version
    /** \brief archive size for this version
    /** \brief archive size for this version
 
 
        For Debian this is the size of the .deb file. */
        For Debian this is the size of the .deb file. */
-   uint64_t Size; // These are the .deb size
+   should_be_uint64_t Size; // These are the .deb size
    /** \brief uncompressed size for this version */
    /** \brief uncompressed size for this version */
-   uint64_t InstalledSize;
+   should_be_uint64_t InstalledSize;
    /** \brief characteristic value representing this version
    /** \brief characteristic value representing this version
 
 
        No two packages in existence should have the same VerStr
        No two packages in existence should have the same VerStr
        and Hash with different contents. */
        and Hash with different contents. */
    unsigned short Hash;
    unsigned short Hash;
    /** \brief unique sequel ID */
    /** \brief unique sequel ID */
-   map_id_t ID;
+   should_be_map_id_t ID;
    /** \brief parsed priority value */
    /** \brief parsed priority value */
    unsigned char Priority;
    unsigned char Priority;
 };
 };
@@ -591,7 +701,7 @@ struct pkgCache::Description
    map_pointer_t ParentPkg;         // Package
    map_pointer_t ParentPkg;         // Package
 
 
    /** \brief unique sequel ID */
    /** \brief unique sequel ID */
-   map_id_t ID;
+   should_be_map_id_t ID;
 };
 };
 									/*}}}*/
 									/*}}}*/
 // Dependency structure							/*{{{*/
 // Dependency structure							/*{{{*/
@@ -618,7 +728,7 @@ struct pkgCache::Dependency
    map_pointer_t ParentVer;       // Version
    map_pointer_t ParentVer;       // Version
 
 
    /** \brief unique sequel ID */
    /** \brief unique sequel ID */
-   map_id_t ID;
+   should_be_map_id_t ID;
    /** \brief Dependency type - Depends, Recommends, Conflicts, etc */
    /** \brief Dependency type - Depends, Recommends, Conflicts, etc */
    unsigned char Type;
    unsigned char Type;
    /** \brief comparison operator specified on the depends line
    /** \brief comparison operator specified on the depends line
@@ -654,6 +764,15 @@ struct pkgCache::Provides
    map_pointer_t NextPkgProv;      // Provides
    map_pointer_t NextPkgProv;      // Provides
 };
 };
 									/*}}}*/
 									/*}}}*/
+// UNUSED StringItem structure						/*{{{*/
+struct APT_DEPRECATED  pkgCache::StringItem
+{
+   /** \brief string this refers to */
+   map_ptrloc String;        // StringItem
+   /** \brief Next link in the chain */
+   map_ptrloc NextItem;      // StringItem
+};
+									/*}}}*/
 
 
 inline char const * pkgCache::NativeArch()
 inline char const * pkgCache::NativeArch()
 	{ return StrP + HeaderP->Architecture; }
 	{ return StrP + HeaderP->Architecture; }
@@ -672,6 +791,11 @@ inline pkgCache::PkgFileIterator pkgCache::FileBegin()
        {return PkgFileIterator(*this,PkgFileP + HeaderP->FileList);}
        {return PkgFileIterator(*this,PkgFileP + HeaderP->FileList);}
 inline pkgCache::PkgFileIterator pkgCache::FileEnd()
 inline pkgCache::PkgFileIterator pkgCache::FileEnd()
        {return PkgFileIterator(*this,PkgFileP);}
        {return PkgFileIterator(*this,PkgFileP);}
+inline pkgCache::RlsFileIterator pkgCache::RlsFileBegin()
+       {return RlsFileIterator(*this,RlsFileP + HeaderP->RlsFileList);}
+inline pkgCache::RlsFileIterator pkgCache::RlsFileEnd()
+       {return RlsFileIterator(*this,RlsFileP);}
+
 
 
 // Oh I wish for Real Name Space Support
 // Oh I wish for Real Name Space Support
 class pkgCache::Namespace						/*{{{*/
 class pkgCache::Namespace						/*{{{*/
@@ -683,6 +807,7 @@ class pkgCache::Namespace						/*{{{*/
    typedef pkgCache::DescIterator DescIterator;
    typedef pkgCache::DescIterator DescIterator;
    typedef pkgCache::DepIterator DepIterator;
    typedef pkgCache::DepIterator DepIterator;
    typedef pkgCache::PrvIterator PrvIterator;
    typedef pkgCache::PrvIterator PrvIterator;
+   typedef pkgCache::RlsFileIterator RlsFileIterator;
    typedef pkgCache::PkgFileIterator PkgFileIterator;
    typedef pkgCache::PkgFileIterator PkgFileIterator;
    typedef pkgCache::VerFileIterator VerFileIterator;
    typedef pkgCache::VerFileIterator VerFileIterator;
    typedef pkgCache::Version Version;
    typedef pkgCache::Version Version;

+ 200 - 66
apt-pkg/pkgcachegen.cc

@@ -54,10 +54,8 @@ using std::string;
 /* We set the dirty flag and make sure that is written to the disk */
 /* We set the dirty flag and make sure that is written to the disk */
 pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
 pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
 		    Map(*pMap), Cache(pMap,false), Progress(Prog),
 		    Map(*pMap), Cache(pMap,false), Progress(Prog),
-		    FoundFileDeps(0)
+		     CurrentRlsFile(NULL), CurrentFile(NULL), FoundFileDeps(0)
 {
 {
-   CurrentFile = 0;
-
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
       return;
       return;
 
 
@@ -74,7 +72,7 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
       *Cache.HeaderP = pkgCache::Header();
       *Cache.HeaderP = pkgCache::Header();
 
 
       // make room for the hashtables for packages and groups
       // make room for the hashtables for packages and groups
-      if (Map.RawAllocate(2 * (Cache.HeaderP->HashTableSize * sizeof(map_pointer_t))) == 0)
+      if (Map.RawAllocate(2 * (Cache.HeaderP->GetHashTableSize() * sizeof(map_pointer_t))) == 0)
 	 return;
 	 return;
 
 
       map_stringitem_t const idxVerSysName = WriteStringInMap(_system->VS->Label);
       map_stringitem_t const idxVerSysName = WriteStringInMap(_system->VS->Label);
@@ -96,10 +94,10 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
 	 map_stringitem_t const idxArchitectures = WriteStringInMap(list);
 	 map_stringitem_t const idxArchitectures = WriteStringInMap(list);
 	 if (unlikely(idxArchitectures == 0))
 	 if (unlikely(idxArchitectures == 0))
 	    return;
 	    return;
-	 Cache.HeaderP->Architectures = idxArchitectures;
+	 Cache.HeaderP->SetArchitectures(idxArchitectures);
       }
       }
       else
       else
-	 Cache.HeaderP->Architectures = idxArchitecture;
+	 Cache.HeaderP->SetArchitectures(idxArchitecture);
 
 
       Cache.ReMap();
       Cache.ReMap();
    }
    }
@@ -145,6 +143,7 @@ void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newM
    Cache.ReMap(false);
    Cache.ReMap(false);
 
 
    CurrentFile += (pkgCache::PackageFile const * const) newMap - (pkgCache::PackageFile const * const) oldMap;
    CurrentFile += (pkgCache::PackageFile const * const) newMap - (pkgCache::PackageFile const * const) oldMap;
+   CurrentRlsFile += (pkgCache::ReleaseFile const * const) newMap - (pkgCache::ReleaseFile const * const) oldMap;
 
 
    for (std::vector<pkgCache::GrpIterator*>::const_iterator i = Dynamic<pkgCache::GrpIterator>::toReMap.begin();
    for (std::vector<pkgCache::GrpIterator*>::const_iterator i = Dynamic<pkgCache::GrpIterator>::toReMap.begin();
 	i != Dynamic<pkgCache::GrpIterator>::toReMap.end(); ++i)
 	i != Dynamic<pkgCache::GrpIterator>::toReMap.end(); ++i)
@@ -167,6 +166,9 @@ void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newM
    for (std::vector<pkgCache::PkgFileIterator*>::const_iterator i = Dynamic<pkgCache::PkgFileIterator>::toReMap.begin();
    for (std::vector<pkgCache::PkgFileIterator*>::const_iterator i = Dynamic<pkgCache::PkgFileIterator>::toReMap.begin();
 	i != Dynamic<pkgCache::PkgFileIterator>::toReMap.end(); ++i)
 	i != Dynamic<pkgCache::PkgFileIterator>::toReMap.end(); ++i)
       (*i)->ReMap(oldMap, newMap);
       (*i)->ReMap(oldMap, newMap);
+   for (std::vector<pkgCache::RlsFileIterator*>::const_iterator i = Dynamic<pkgCache::RlsFileIterator>::toReMap.begin();
+	i != Dynamic<pkgCache::RlsFileIterator>::toReMap.end(); ++i)
+      (*i)->ReMap(oldMap, newMap);
 }									/*}}}*/
 }									/*}}}*/
 // CacheGenerator::WriteStringInMap					/*{{{*/
 // CacheGenerator::WriteStringInMap					/*{{{*/
 map_stringitem_t pkgCacheGenerator::WriteStringInMap(const char *String,
 map_stringitem_t pkgCacheGenerator::WriteStringInMap(const char *String,
@@ -616,7 +618,7 @@ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name)
 
 
    // Insert it into the hash table
    // Insert it into the hash table
    unsigned long const Hash = Cache.Hash(Name);
    unsigned long const Hash = Cache.Hash(Name);
-   map_pointer_t *insertAt = &Cache.HeaderP->GrpHashTable()[Hash];
+   map_pointer_t *insertAt = &Cache.HeaderP->GrpHashTableP()[Hash];
    while (*insertAt != 0 && strcasecmp(Name.c_str(), Cache.StrP + (Cache.GrpP + *insertAt)->Name) > 0)
    while (*insertAt != 0 && strcasecmp(Name.c_str(), Cache.StrP + (Cache.GrpP + *insertAt)->Name) > 0)
       insertAt = &(Cache.GrpP + *insertAt)->Next;
       insertAt = &(Cache.GrpP + *insertAt)->Next;
    Grp->Next = *insertAt;
    Grp->Next = *insertAt;
@@ -652,30 +654,23 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name
       Grp->FirstPackage = Package;
       Grp->FirstPackage = Package;
       // Insert it into the hash table
       // Insert it into the hash table
       map_id_t const Hash = Cache.Hash(Name);
       map_id_t const Hash = Cache.Hash(Name);
-      map_pointer_t *insertAt = &Cache.HeaderP->PkgHashTable()[Hash];
+      map_pointer_t *insertAt = &Cache.HeaderP->PkgHashTableP()[Hash];
       while (*insertAt != 0 && strcasecmp(Name.c_str(), Cache.StrP + (Cache.GrpP + (Cache.PkgP + *insertAt)->Group)->Name) > 0)
       while (*insertAt != 0 && strcasecmp(Name.c_str(), Cache.StrP + (Cache.GrpP + (Cache.PkgP + *insertAt)->Group)->Name) > 0)
-	 insertAt = &(Cache.PkgP + *insertAt)->Next;
-      Pkg->Next = *insertAt;
+	 insertAt = &(Cache.PkgP + *insertAt)->NextPackage;
+      Pkg->NextPackage = *insertAt;
       *insertAt = Package;
       *insertAt = Package;
    }
    }
    else // Group the Packages together
    else // Group the Packages together
    {
    {
       // this package is the new last package
       // this package is the new last package
       pkgCache::PkgIterator LastPkg(Cache, Cache.PkgP + Grp->LastPackage);
       pkgCache::PkgIterator LastPkg(Cache, Cache.PkgP + Grp->LastPackage);
-      Pkg->Next = LastPkg->Next;
-      LastPkg->Next = Package;
+      Pkg->NextPackage = LastPkg->NextPackage;
+      LastPkg->NextPackage = Package;
    }
    }
    Grp->LastPackage = Package;
    Grp->LastPackage = Package;
 
 
    // Set the name, arch and the ID
    // Set the name, arch and the ID
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
-   Pkg->Name = Grp->Name;
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+   APT_IGNORE_DEPRECATED(Pkg->Name = Grp->Name;)
    Pkg->Group = Grp.Index();
    Pkg->Group = Grp.Index();
    // all is mapped to the native architecture
    // all is mapped to the native architecture
    map_stringitem_t const idxArch = (Arch == "all") ? Cache.HeaderP->Architecture : StoreString(MIXED, Arch);
    map_stringitem_t const idxArch = (Arch == "all") ? Cache.HeaderP->Architecture : StoreString(MIXED, Arch);
@@ -1079,13 +1074,48 @@ bool pkgCacheGenerator::ListParser::SameVersion(unsigned short const Hash,/*{{{*
    return Hash == Ver->Hash;
    return Hash == Ver->Hash;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// CacheGenerator::SelectReleaseFile - Select the current release file the indexes belong to	/*{{{*/
+bool pkgCacheGenerator::SelectReleaseFile(const string &File,const string &Site,
+				   unsigned long Flags)
+{
+   if (File.empty() && Site.empty())
+   {
+      CurrentRlsFile = NULL;
+      return true;
+   }
+
+   // Get some space for the structure
+   map_pointer_t const idxFile = AllocateInMap(sizeof(*CurrentRlsFile));
+   if (unlikely(idxFile == 0))
+      return false;
+   CurrentRlsFile = Cache.RlsFileP + idxFile;
+
+   // Fill it in
+   map_stringitem_t const idxFileName = WriteStringInMap(File);
+   map_stringitem_t const idxSite = StoreString(MIXED, Site);
+   if (unlikely(idxFileName == 0 || idxSite == 0))
+      return false;
+   CurrentRlsFile->FileName = idxFileName;
+   CurrentRlsFile->Site = idxSite;
+   CurrentRlsFile->NextFile = Cache.HeaderP->RlsFileList;
+   CurrentRlsFile->Flags = Flags;
+   CurrentRlsFile->ID = Cache.HeaderP->ReleaseFileCount;
+   RlsFileName = File;
+   Cache.HeaderP->RlsFileList = CurrentRlsFile - Cache.RlsFileP;
+   Cache.HeaderP->ReleaseFileCount++;
+
+   return true;
+}
+									/*}}}*/
 // CacheGenerator::SelectFile - Select the current file being parsed	/*{{{*/
 // CacheGenerator::SelectFile - Select the current file being parsed	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This is used to select which file is to be associated with all newly
 /* This is used to select which file is to be associated with all newly
    added versions. The caller is responsible for setting the IMS fields. */
    added versions. The caller is responsible for setting the IMS fields. */
-bool pkgCacheGenerator::SelectFile(const string &File,const string &Site,
-				   const pkgIndexFile &Index,
-				   unsigned long Flags)
+bool pkgCacheGenerator::SelectFile(std::string const &File,
+				   pkgIndexFile const &Index,
+				   std::string const &Architecture,
+				   std::string const &Component,
+				   unsigned long const Flags)
 {
 {
    // Get some space for the structure
    // Get some space for the structure
    map_pointer_t const idxFile = AllocateInMap(sizeof(*CurrentFile));
    map_pointer_t const idxFile = AllocateInMap(sizeof(*CurrentFile));
@@ -1095,18 +1125,33 @@ bool pkgCacheGenerator::SelectFile(const string &File,const string &Site,
 
 
    // Fill it in
    // Fill it in
    map_stringitem_t const idxFileName = WriteStringInMap(File);
    map_stringitem_t const idxFileName = WriteStringInMap(File);
-   map_stringitem_t const idxSite = StoreString(MIXED, Site);
-   if (unlikely(idxFileName == 0 || idxSite == 0))
+   if (unlikely(idxFileName == 0))
       return false;
       return false;
    CurrentFile->FileName = idxFileName;
    CurrentFile->FileName = idxFileName;
-   CurrentFile->Site = idxSite;
    CurrentFile->NextFile = Cache.HeaderP->FileList;
    CurrentFile->NextFile = Cache.HeaderP->FileList;
-   CurrentFile->Flags = Flags;
    CurrentFile->ID = Cache.HeaderP->PackageFileCount;
    CurrentFile->ID = Cache.HeaderP->PackageFileCount;
    map_stringitem_t const idxIndexType = StoreString(MIXED, Index.GetType()->Label);
    map_stringitem_t const idxIndexType = StoreString(MIXED, Index.GetType()->Label);
    if (unlikely(idxIndexType == 0))
    if (unlikely(idxIndexType == 0))
       return false;
       return false;
    CurrentFile->IndexType = idxIndexType;
    CurrentFile->IndexType = idxIndexType;
+   if (Architecture.empty())
+      CurrentFile->Architecture = 0;
+   else
+   {
+      map_stringitem_t const arch = StoreString(pkgCacheGenerator::MIXED, Architecture);
+      if (unlikely(arch == 0))
+	 return false;
+      CurrentFile->Architecture = arch;
+   }
+   map_stringitem_t const component = StoreString(pkgCacheGenerator::MIXED, Component);
+   if (unlikely(component == 0))
+      return false;
+   CurrentFile->Component = component;
+   CurrentFile->Flags = Flags;
+   if (CurrentRlsFile != NULL)
+      CurrentFile->Release = CurrentRlsFile - Cache.RlsFileP;
+   else
+      CurrentFile->Release = 0;
    PkgFileName = File;
    PkgFileName = File;
    Cache.HeaderP->FileList = CurrentFile - Cache.PkgFileP;
    Cache.HeaderP->FileList = CurrentFile - Cache.PkgFileP;
    Cache.HeaderP->PackageFileCount++;
    Cache.HeaderP->PackageFileCount++;
@@ -1181,35 +1226,59 @@ static bool CheckValidity(const string &CacheFile,
       _error->Discard();
       _error->Discard();
       return false;
       return false;
    }
    }
-   
+
+   SPtrArray<bool> RlsVisited = new bool[Cache.HeaderP->ReleaseFileCount];
+   memset(RlsVisited,0,sizeof(*RlsVisited)*Cache.HeaderP->ReleaseFileCount);
+   std::vector<pkgIndexFile *> Files;
+   for (pkgSourceList::const_iterator i = List.begin(); i != List.end(); ++i)
+   {
+      if (Debug == true)
+	 std::clog << "Checking RlsFile " << (*i)->Describe() << ": ";
+      pkgCache::RlsFileIterator const RlsFile = (*i)->FindInCache(Cache, true);
+      if (RlsFile.end() == true)
+      {
+	 if (Debug == true)
+	    std::clog << "FindInCache returned end-Pointer" << std::endl;
+	 return false;
+      }
+
+      RlsVisited[RlsFile->ID] = true;
+      if (Debug == true)
+	 std::clog << "with ID " << RlsFile->ID << " is valid" << std::endl;
+
+      std::vector <pkgIndexFile *> *Indexes = (*i)->GetIndexFiles();
+      for (std::vector<pkgIndexFile *>::const_iterator j = Indexes->begin(); j != Indexes->end(); ++j)
+	 if ((*j)->HasPackages())
+	    Files.push_back (*j);
+   }
+   for (unsigned I = 0; I != Cache.HeaderP->ReleaseFileCount; ++I)
+      if (RlsVisited[I] == false)
+      {
+	 if (Debug == true)
+	    std::clog << "RlsFile with ID" << I << " wasn't visited" << std::endl;
+	 return false;
+      }
+
+   for (; Start != End; ++Start)
+      Files.push_back(*Start);
+
    /* Now we check every index file, see if it is in the cache,
    /* Now we check every index file, see if it is in the cache,
       verify the IMS data and check that it is on the disk too.. */
       verify the IMS data and check that it is on the disk too.. */
    SPtrArray<bool> Visited = new bool[Cache.HeaderP->PackageFileCount];
    SPtrArray<bool> Visited = new bool[Cache.HeaderP->PackageFileCount];
    memset(Visited,0,sizeof(*Visited)*Cache.HeaderP->PackageFileCount);
    memset(Visited,0,sizeof(*Visited)*Cache.HeaderP->PackageFileCount);
-   for (; Start != End; ++Start)
+   for (std::vector<pkgIndexFile *>::const_reverse_iterator PkgFile = Files.rbegin(); PkgFile != Files.rend(); ++PkgFile)
    {
    {
       if (Debug == true)
       if (Debug == true)
-	 std::clog << "Checking PkgFile " << (*Start)->Describe() << ": ";
-      if ((*Start)->HasPackages() == false)
-      {
-         if (Debug == true)
-	    std::clog << "Has NO packages" << std::endl;
-	 continue;
-      }
-    
-      if ((*Start)->Exists() == false)
+	 std::clog << "Checking PkgFile " << (*PkgFile)->Describe() << ": ";
+      if ((*PkgFile)->Exists() == false)
       {
       {
-#if 0 // mvo: we no longer give a message here (Default Sources spec)
-	 _error->WarningE("stat",_("Couldn't stat source package list %s"),
-			  (*Start)->Describe().c_str());
-#endif
          if (Debug == true)
          if (Debug == true)
 	    std::clog << "file doesn't exist" << std::endl;
 	    std::clog << "file doesn't exist" << std::endl;
 	 continue;
 	 continue;
       }
       }
 
 
       // FindInCache is also expected to do an IMS check.
       // FindInCache is also expected to do an IMS check.
-      pkgCache::PkgFileIterator File = (*Start)->FindInCache(Cache);
+      pkgCache::PkgFileIterator File = (*PkgFile)->FindInCache(Cache);
       if (File.end() == true)
       if (File.end() == true)
       {
       {
 	 if (Debug == true)
 	 if (Debug == true)
@@ -1221,15 +1290,15 @@ static bool CheckValidity(const string &CacheFile,
       if (Debug == true)
       if (Debug == true)
 	 std::clog << "with ID " << File->ID << " is valid" << std::endl;
 	 std::clog << "with ID " << File->ID << " is valid" << std::endl;
    }
    }
-   
+
    for (unsigned I = 0; I != Cache.HeaderP->PackageFileCount; I++)
    for (unsigned I = 0; I != Cache.HeaderP->PackageFileCount; I++)
       if (Visited[I] == false)
       if (Visited[I] == false)
       {
       {
 	 if (Debug == true)
 	 if (Debug == true)
-	    std::clog << "File with ID" << I << " wasn't visited" << std::endl;
+	    std::clog << "PkgFile with ID" << I << " wasn't visited" << std::endl;
 	 return false;
 	 return false;
       }
       }
-   
+
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
    {
    {
       if (Debug == true)
       if (Debug == true)
@@ -1250,9 +1319,20 @@ static bool CheckValidity(const string &CacheFile,
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Size is kind of an abstract notion that is only used for the progress
 /* Size is kind of an abstract notion that is only used for the progress
    meter */
    meter */
-static map_filesize_t ComputeSize(FileIterator Start,FileIterator End)
+static map_filesize_t ComputeSize(pkgSourceList const * const List, FileIterator Start,FileIterator End)
 {
 {
    map_filesize_t TotalSize = 0;
    map_filesize_t TotalSize = 0;
+   if (List !=  NULL)
+   {
+      for (pkgSourceList::const_iterator i = List->begin(); i != List->end(); ++i)
+      {
+	 std::vector <pkgIndexFile *> *Indexes = (*i)->GetIndexFiles();
+	 for (std::vector<pkgIndexFile *>::const_iterator j = Indexes->begin(); j != Indexes->end(); ++j)
+	    if ((*j)->HasPackages() == true)
+	       TotalSize += (*j)->Size();
+      }
+   }
+
    for (; Start < End; ++Start)
    for (; Start < End; ++Start)
    {
    {
       if ((*Start)->HasPackages() == false)
       if ((*Start)->HasPackages() == false)
@@ -1268,11 +1348,63 @@ static map_filesize_t ComputeSize(FileIterator Start,FileIterator End)
 static bool BuildCache(pkgCacheGenerator &Gen,
 static bool BuildCache(pkgCacheGenerator &Gen,
 		       OpProgress *Progress,
 		       OpProgress *Progress,
 		       map_filesize_t &CurrentSize,map_filesize_t TotalSize,
 		       map_filesize_t &CurrentSize,map_filesize_t TotalSize,
+		       pkgSourceList const * const List,
 		       FileIterator Start, FileIterator End)
 		       FileIterator Start, FileIterator End)
 {
 {
+   std::vector<pkgIndexFile *> Files;
+   bool const HasFileDeps = Gen.HasFileDeps();
+
+   if (List !=  NULL)
+   {
+      for (pkgSourceList::const_iterator i = List->begin(); i != List->end(); ++i)
+      {
+	 if ((*i)->FindInCache(Gen.GetCache(), false).end() == false)
+	 {
+	    _error->Warning("Duplicate sources.list entry %s",
+		  (*i)->Describe().c_str());
+	    continue;
+	 }
+
+	 if ((*i)->Merge(Gen, Progress) == false)
+	    return false;
+
+	 std::vector <pkgIndexFile *> *Indexes = (*i)->GetIndexFiles();
+	 for (std::vector<pkgIndexFile *>::const_iterator I = Indexes->begin(); I != Indexes->end(); ++I)
+	 {
+	    if (HasFileDeps)
+	       Files.push_back(*I);
+
+	    if ((*I)->HasPackages() == false)
+	       continue;
+
+	    if ((*I)->Exists() == false)
+	       continue;
+
+	    if ((*I)->FindInCache(Gen.GetCache()).end() == false)
+	    {
+	       _error->Warning("Duplicate sources.list entry %s",
+		     (*I)->Describe().c_str());
+	       continue;
+	    }
+
+	    map_filesize_t Size = (*I)->Size();
+	    if (Progress != NULL)
+	       Progress->OverallProgress(CurrentSize,TotalSize,Size,_("Reading package lists"));
+	    CurrentSize += Size;
+
+	    if ((*I)->Merge(Gen,Progress) == false)
+	       return false;
+	 }
+      }
+   }
+
+   Gen.SelectReleaseFile("", "");
    FileIterator I;
    FileIterator I;
    for (I = Start; I != End; ++I)
    for (I = Start; I != End; ++I)
    {
    {
+      if (HasFileDeps)
+	 Files.push_back(*I);
+
       if ((*I)->HasPackages() == false)
       if ((*I)->HasPackages() == false)
 	 continue;
 	 continue;
       
       
@@ -1295,13 +1427,13 @@ static bool BuildCache(pkgCacheGenerator &Gen,
 	 return false;
 	 return false;
    }   
    }   
 
 
-   if (Gen.HasFileDeps() == true)
+   if (HasFileDeps == true)
    {
    {
       if (Progress != NULL)
       if (Progress != NULL)
 	 Progress->Done();
 	 Progress->Done();
-      TotalSize = ComputeSize(Start, End);
+      TotalSize = ComputeSize(List, Start, End);
       CurrentSize = 0;
       CurrentSize = 0;
-      for (I = Start; I != End; ++I)
+      for (std::vector<pkgIndexFile *>::const_iterator I = Files.begin(); I != Files.end(); ++I)
       {
       {
 	 map_filesize_t Size = (*I)->Size();
 	 map_filesize_t Size = (*I)->Size();
 	 if (Progress != NULL)
 	 if (Progress != NULL)
@@ -1346,6 +1478,7 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress
    bool const Debug = _config->FindB("Debug::pkgCacheGen", false);
    bool const Debug = _config->FindB("Debug::pkgCacheGen", false);
 
 
    std::vector<pkgIndexFile *> Files;
    std::vector<pkgIndexFile *> Files;
+   /*
    for (std::vector<metaIndex *>::const_iterator i = List.begin();
    for (std::vector<metaIndex *>::const_iterator i = List.begin();
         i != List.end();
         i != List.end();
         ++i)
         ++i)
@@ -1356,8 +1489,7 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress
 	   ++j)
 	   ++j)
          Files.push_back (*j);
          Files.push_back (*j);
    }
    }
-   
-   map_filesize_t const EndOfSource = Files.size();
+*/
    if (_system->AddStatusFiles(Files) == false)
    if (_system->AddStatusFiles(Files) == false)
       return false;
       return false;
 
 
@@ -1449,8 +1581,8 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress
    // Lets try the source cache.
    // Lets try the source cache.
    map_filesize_t CurrentSize = 0;
    map_filesize_t CurrentSize = 0;
    map_filesize_t TotalSize = 0;
    map_filesize_t TotalSize = 0;
-   if (CheckValidity(SrcCacheFile, List, Files.begin(),
-		     Files.begin()+EndOfSource) == true)
+   if (CheckValidity(SrcCacheFile, List, Files.end(),
+		     Files.end()) == true)
    {
    {
       if (Debug == true)
       if (Debug == true)
 	 std::clog << "srcpkgcache.bin is valid - populate MMap with it." << std::endl;
 	 std::clog << "srcpkgcache.bin is valid - populate MMap with it." << std::endl;
@@ -1462,28 +1594,28 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress
 				SCacheF.Size()) == false)
 				SCacheF.Size()) == false)
 	 return false;
 	 return false;
 
 
-      TotalSize = ComputeSize(Files.begin()+EndOfSource,Files.end());
+      TotalSize = ComputeSize(NULL, Files.begin(), Files.end());
 
 
       // Build the status cache
       // Build the status cache
       pkgCacheGenerator Gen(Map.Get(),Progress);
       pkgCacheGenerator Gen(Map.Get(),Progress);
       if (_error->PendingError() == true)
       if (_error->PendingError() == true)
 	 return false;
 	 return false;
-      if (BuildCache(Gen,Progress,CurrentSize,TotalSize,
-		     Files.begin()+EndOfSource,Files.end()) == false)
+      if (BuildCache(Gen, Progress, CurrentSize, TotalSize, NULL,
+		     Files.begin(),Files.end()) == false)
 	 return false;
 	 return false;
    }
    }
    else
    else
    {
    {
       if (Debug == true)
       if (Debug == true)
 	 std::clog << "srcpkgcache.bin is NOT valid - rebuild" << std::endl;
 	 std::clog << "srcpkgcache.bin is NOT valid - rebuild" << std::endl;
-      TotalSize = ComputeSize(Files.begin(),Files.end());
+      TotalSize = ComputeSize(&List, Files.begin(),Files.end());
       
       
       // Build the source cache
       // Build the source cache
       pkgCacheGenerator Gen(Map.Get(),Progress);
       pkgCacheGenerator Gen(Map.Get(),Progress);
       if (_error->PendingError() == true)
       if (_error->PendingError() == true)
 	 return false;
 	 return false;
-      if (BuildCache(Gen,Progress,CurrentSize,TotalSize,
-		     Files.begin(),Files.begin()+EndOfSource) == false)
+      if (BuildCache(Gen, Progress, CurrentSize, TotalSize, &List,
+		     Files.end(),Files.end()) == false)
 	 return false;
 	 return false;
       
       
       // Write it back
       // Write it back
@@ -1510,8 +1642,8 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress
       }
       }
       
       
       // Build the status cache
       // Build the status cache
-      if (BuildCache(Gen,Progress,CurrentSize,TotalSize,
-		     Files.begin()+EndOfSource,Files.end()) == false)
+      if (BuildCache(Gen, Progress, CurrentSize, TotalSize, NULL,
+		     Files.begin(), Files.end()) == false)
 	 return false;
 	 return false;
    }
    }
    if (Debug == true)
    if (Debug == true)
@@ -1543,7 +1675,6 @@ APT_DEPRECATED bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **Ou
 bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **OutMap)
 bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **OutMap)
 {
 {
    std::vector<pkgIndexFile *> Files;
    std::vector<pkgIndexFile *> Files;
-   map_filesize_t EndOfSource = Files.size();
    if (_system->AddStatusFiles(Files) == false)
    if (_system->AddStatusFiles(Files) == false)
       return false;
       return false;
 
 
@@ -1551,7 +1682,7 @@ bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **O
    map_filesize_t CurrentSize = 0;
    map_filesize_t CurrentSize = 0;
    map_filesize_t TotalSize = 0;
    map_filesize_t TotalSize = 0;
    
    
-   TotalSize = ComputeSize(Files.begin()+EndOfSource,Files.end());
+   TotalSize = ComputeSize(NULL, Files.begin(), Files.end());
    
    
    // Build the status cache
    // Build the status cache
    if (Progress != NULL)
    if (Progress != NULL)
@@ -1559,8 +1690,8 @@ bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **O
    pkgCacheGenerator Gen(Map.Get(),Progress);
    pkgCacheGenerator Gen(Map.Get(),Progress);
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
       return false;
       return false;
-   if (BuildCache(Gen,Progress,CurrentSize,TotalSize,
-		  Files.begin()+EndOfSource,Files.end()) == false)
+   if (BuildCache(Gen,Progress,CurrentSize,TotalSize, NULL,
+		  Files.begin(), Files.end()) == false)
       return false;
       return false;
 
 
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
@@ -1589,3 +1720,6 @@ bool pkgCacheGenerator::FinishCache(OpProgress * /*Progress*/)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
+
+pkgCacheGenerator::ListParser::ListParser() : Owner(NULL), OldDepLast(NULL), FoundFileDeps(false) {}
+pkgCacheGenerator::ListParser::~ListParser() {}

+ 20 - 17
apt-pkg/pkgcachegen.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: pkgcachegen.h,v 1.19 2002/07/08 03:13:30 jgg Exp $
 /* ######################################################################
 /* ######################################################################
    
    
    Package Cache Generator - Generator for the cache structure.
    Package Cache Generator - Generator for the cache structure.
@@ -34,7 +33,7 @@ class pkgSourceList;
 class OpProgress;
 class OpProgress;
 class pkgIndexFile;
 class pkgIndexFile;
 
 
-class pkgCacheGenerator							/*{{{*/
+class APT_HIDDEN pkgCacheGenerator					/*{{{*/
 {
 {
    private:
    private:
    APT_HIDDEN map_stringitem_t WriteStringInMap(std::string const &String) { return WriteStringInMap(String.c_str()); };
    APT_HIDDEN map_stringitem_t WriteStringInMap(std::string const &String) { return WriteStringInMap(String.c_str()); };
@@ -69,7 +68,9 @@ class pkgCacheGenerator							/*{{{*/
    DynamicMMap &Map;
    DynamicMMap &Map;
    pkgCache Cache;
    pkgCache Cache;
    OpProgress *Progress;
    OpProgress *Progress;
-   
+
+   std::string RlsFileName;
+   pkgCache::ReleaseFile *CurrentRlsFile;
    std::string PkgFileName;
    std::string PkgFileName;
    pkgCache::PackageFile *CurrentFile;
    pkgCache::PackageFile *CurrentFile;
 
 
@@ -100,28 +101,31 @@ class pkgCacheGenerator							/*{{{*/
    inline map_stringitem_t StoreString(enum StringType const type, const std::string &S) {return StoreString(type, S.c_str(),S.length());};
    inline map_stringitem_t StoreString(enum StringType const type, const std::string &S) {return StoreString(type, S.c_str(),S.length());};
 
 
    void DropProgress() {Progress = 0;};
    void DropProgress() {Progress = 0;};
-   bool SelectFile(const std::string &File,const std::string &Site,pkgIndexFile const &Index,
-		   unsigned long Flags = 0);
+   bool SelectFile(const std::string &File,pkgIndexFile const &Index, std::string const &Architecture, std::string const &Component, unsigned long Flags = 0);
+   bool SelectReleaseFile(const std::string &File, const std::string &Site, unsigned long Flags = 0);
    bool MergeList(ListParser &List,pkgCache::VerIterator *Ver = 0);
    bool MergeList(ListParser &List,pkgCache::VerIterator *Ver = 0);
    inline pkgCache &GetCache() {return Cache;};
    inline pkgCache &GetCache() {return Cache;};
    inline pkgCache::PkgFileIterator GetCurFile() 
    inline pkgCache::PkgFileIterator GetCurFile() 
          {return pkgCache::PkgFileIterator(Cache,CurrentFile);};
          {return pkgCache::PkgFileIterator(Cache,CurrentFile);};
+   inline pkgCache::RlsFileIterator GetCurRlsFile() 
+         {return pkgCache::RlsFileIterator(Cache,CurrentRlsFile);};
 
 
    bool HasFileDeps() {return FoundFileDeps;};
    bool HasFileDeps() {return FoundFileDeps;};
    bool MergeFileProvides(ListParser &List);
    bool MergeFileProvides(ListParser &List);
    bool FinishCache(OpProgress *Progress) APT_DEPRECATED APT_CONST;
    bool FinishCache(OpProgress *Progress) APT_DEPRECATED APT_CONST;
 
 
-   static bool MakeStatusCache(pkgSourceList &List,OpProgress *Progress,
+   APT_PUBLIC static bool MakeStatusCache(pkgSourceList &List,OpProgress *Progress,
 			MMap **OutMap = 0,bool AllowMem = false);
 			MMap **OutMap = 0,bool AllowMem = false);
-   static bool MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **OutMap);
-   static DynamicMMap* CreateDynamicMMap(FileFd *CacheF, unsigned long Flags = 0);
+   APT_PUBLIC static bool MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **OutMap);
+   APT_PUBLIC static DynamicMMap* CreateDynamicMMap(FileFd *CacheF, unsigned long Flags = 0);
 
 
    void ReMap(void const * const oldMap, void const * const newMap);
    void ReMap(void const * const oldMap, void const * const newMap);
 
 
    pkgCacheGenerator(DynamicMMap *Map,OpProgress *Progress);
    pkgCacheGenerator(DynamicMMap *Map,OpProgress *Progress);
-   ~pkgCacheGenerator();
+   virtual ~pkgCacheGenerator();
 
 
    private:
    private:
+   void *d;
    APT_HIDDEN bool MergeListGroup(ListParser &List, std::string const &GrpName);
    APT_HIDDEN bool MergeListGroup(ListParser &List, std::string const &GrpName);
    APT_HIDDEN bool MergeListPackage(ListParser &List, pkgCache::PkgIterator &Pkg);
    APT_HIDDEN bool MergeListPackage(ListParser &List, pkgCache::PkgIterator &Pkg);
    APT_HIDDEN bool MergeListVersion(ListParser &List, pkgCache::PkgIterator &Pkg,
    APT_HIDDEN bool MergeListVersion(ListParser &List, pkgCache::PkgIterator &Pkg,
@@ -136,7 +140,7 @@ class pkgCacheGenerator							/*{{{*/
 };
 };
 									/*}}}*/
 									/*}}}*/
 // This is the abstract package list parser class.			/*{{{*/
 // This is the abstract package list parser class.			/*{{{*/
-class pkgCacheGenerator::ListParser
+class APT_HIDDEN pkgCacheGenerator::ListParser
 {
 {
    pkgCacheGenerator *Owner;
    pkgCacheGenerator *Owner;
    friend class pkgCacheGenerator;
    friend class pkgCacheGenerator;
@@ -147,7 +151,9 @@ class pkgCacheGenerator::ListParser
 
 
    // Flag file dependencies
    // Flag file dependencies
    bool FoundFileDeps;
    bool FoundFileDeps;
-      
+
+   void *d;
+
    protected:
    protected:
 
 
    inline map_stringitem_t StoreString(pkgCacheGenerator::StringType const type, std::string const &S) {return Owner->StoreString(type, S);};
    inline map_stringitem_t StoreString(pkgCacheGenerator::StringType const type, std::string const &S) {return Owner->StoreString(type, S);};
@@ -178,10 +184,7 @@ class pkgCacheGenerator::ListParser
     * \param Hash of the currently parsed version
     * \param Hash of the currently parsed version
     * \param Ver to compare with
     * \param Ver to compare with
     */
     */
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
-   virtual
-#endif
-      APT_PURE bool SameVersion(unsigned short const Hash, pkgCache::VerIterator const &Ver);
+   virtual bool SameVersion(unsigned short const Hash, pkgCache::VerIterator const &Ver);
    virtual bool UsePackage(pkgCache::PkgIterator &Pkg,
    virtual bool UsePackage(pkgCache::PkgIterator &Pkg,
 			   pkgCache::VerIterator &Ver) = 0;
 			   pkgCache::VerIterator &Ver) = 0;
    virtual map_filesize_t Offset() = 0;
    virtual map_filesize_t Offset() = 0;
@@ -193,8 +196,8 @@ class pkgCacheGenerator::ListParser
    virtual bool CollectFileProvides(pkgCache &/*Cache*/,
    virtual bool CollectFileProvides(pkgCache &/*Cache*/,
 				    pkgCache::VerIterator &/*Ver*/) {return true;};
 				    pkgCache::VerIterator &/*Ver*/) {return true;};
 
 
-   ListParser() : Owner(NULL), OldDepLast(NULL), FoundFileDeps(false) {};
-   virtual ~ListParser() {};
+   ListParser();
+   virtual ~ListParser();
 };
 };
 									/*}}}*/
 									/*}}}*/
 
 

+ 3 - 0
apt-pkg/pkgrecords.cc

@@ -76,3 +76,6 @@ pkgRecords::Parser &pkgRecords::Lookup(pkgCache::DescFileIterator const &Desc)
    return *Files[Desc.File()->ID];
    return *Files[Desc.File()->ID];
 }
 }
 									/*}}}*/
 									/*}}}*/
+
+pkgRecords::Parser::Parser() {}
+pkgRecords::Parser::~Parser() {}

+ 12 - 3
apt-pkg/pkgrecords.h

@@ -43,7 +43,7 @@ class pkgRecords							/*{{{*/
 
 
    // Construct destruct
    // Construct destruct
    pkgRecords(pkgCache &Cache);
    pkgRecords(pkgCache &Cache);
-   ~pkgRecords();
+   virtual ~pkgRecords();
 };
 };
 									/*}}}*/
 									/*}}}*/
 class pkgRecords::Parser						/*{{{*/
 class pkgRecords::Parser						/*{{{*/
@@ -68,10 +68,17 @@ class pkgRecords::Parser						/*{{{*/
     * choose the hash to be used.
     * choose the hash to be used.
     */
     */
    virtual HashStringList Hashes() const { return HashStringList(); };
    virtual HashStringList Hashes() const { return HashStringList(); };
+#if APT_PKG_ABI >= 413
    APT_DEPRECATED std::string MD5Hash() const { return GetHashFromHashes("MD5Sum"); };
    APT_DEPRECATED std::string MD5Hash() const { return GetHashFromHashes("MD5Sum"); };
    APT_DEPRECATED std::string SHA1Hash() const { return GetHashFromHashes("SHA1"); };
    APT_DEPRECATED std::string SHA1Hash() const { return GetHashFromHashes("SHA1"); };
    APT_DEPRECATED std::string SHA256Hash() const { return GetHashFromHashes("SHA256"); };
    APT_DEPRECATED std::string SHA256Hash() const { return GetHashFromHashes("SHA256"); };
    APT_DEPRECATED std::string SHA512Hash() const { return GetHashFromHashes("SHA512"); };
    APT_DEPRECATED std::string SHA512Hash() const { return GetHashFromHashes("SHA512"); };
+#else
+   APT_DEPRECATED std::string MD5Hash() { return GetHashFromHashes("MD5Sum"); };
+   APT_DEPRECATED std::string SHA1Hash() { return GetHashFromHashes("SHA1"); };
+   APT_DEPRECATED std::string SHA256Hash() { return GetHashFromHashes("SHA256"); };
+   APT_DEPRECATED std::string SHA512Hash() { return GetHashFromHashes("SHA512"); };
+#endif
 
 
    // These are some general stats about the package
    // These are some general stats about the package
    virtual std::string Maintainer() {return std::string();};
    virtual std::string Maintainer() {return std::string();};
@@ -99,10 +106,12 @@ class pkgRecords::Parser						/*{{{*/
 
 
    // The record in binary form
    // The record in binary form
    virtual void GetRec(const char *&Start,const char *&Stop) {Start = Stop = 0;};
    virtual void GetRec(const char *&Start,const char *&Stop) {Start = Stop = 0;};
-   
-   virtual ~Parser() {};
+
+   Parser();
+   virtual ~Parser();
 
 
    private:
    private:
+   void *d;
    APT_HIDDEN std::string GetHashFromHashes(char const * const type) const
    APT_HIDDEN std::string GetHashFromHashes(char const * const type) const
    {
    {
       HashStringList const hashes = Hashes();
       HashStringList const hashes = Hashes();

+ 2 - 0
apt-pkg/pkgsystem.cc

@@ -45,3 +45,5 @@ APT_PURE pkgSystem *pkgSystem::GetSystem(const char *Label)
    return 0;   
    return 0;   
 }
 }
 									/*}}}*/
 									/*}}}*/
+
+pkgSystem::~pkgSystem() {}

+ 3 - 2
apt-pkg/pkgsystem.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: pkgsystem.h,v 1.6 2002/11/11 06:55:50 doogie Exp $
 /* ######################################################################
 /* ######################################################################
 
 
    System - Abstraction for running on different systems.
    System - Abstraction for running on different systems.
@@ -93,7 +92,9 @@ class pkgSystem
    };
    };
    
    
    pkgSystem();
    pkgSystem();
-   virtual ~pkgSystem() {};
+   virtual ~pkgSystem();
+   private:
+   void *d;
 };
 };
 
 
 // The environment we are operating in.
 // The environment we are operating in.

+ 29 - 54
apt-pkg/policy.cc

@@ -4,22 +4,12 @@
 /* ######################################################################
 /* ######################################################################
 
 
    Package Version Policy implementation
    Package Version Policy implementation
-   
+
    This is just a really simple wrapper around pkgVersionMatch with
    This is just a really simple wrapper around pkgVersionMatch with
    some added goodies to manage the list of things..
    some added goodies to manage the list of things..
-   
-   Priority Table:
-   
-   1000 -> inf = Downgradeable priorities
-   1000        = The 'no downgrade' pseduo-status file
-   100 -> 1000 = Standard priorities
-   990         = Config file override package files
-   989         = Start for preference auto-priorities
-   500         = Default package files
-   100         = The status file and ButAutomaticUpgrades sources
-   0 -> 100    = NotAutomatic sources like experimental
-   -inf -> 0   = Never selected   
-   
+
+   See man apt_preferences for what value means what.
+
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
@@ -56,7 +46,7 @@ using namespace std;
    file matches the V0 policy engine. */
    file matches the V0 policy engine. */
 pkgPolicy::pkgPolicy(pkgCache *Owner) : Pins(0), PFPriority(0), Cache(Owner)
 pkgPolicy::pkgPolicy(pkgCache *Owner) : Pins(0), PFPriority(0), Cache(Owner)
 {
 {
-   if (Owner == 0 || &(Owner->Head()) == 0)
+   if (Owner == 0)
       return;
       return;
    PFPriority = new signed short[Owner->Head().PackageFileCount];
    PFPriority = new signed short[Owner->Head().PackageFileCount];
    Pins = new Pin[Owner->Head().PackageCount];
    Pins = new Pin[Owner->Head().PackageCount];
@@ -73,9 +63,9 @@ pkgPolicy::pkgPolicy(pkgCache *Owner) : Pins(0), PFPriority(0), Cache(Owner)
       pkgVersionMatch vm("", pkgVersionMatch::None);
       pkgVersionMatch vm("", pkgVersionMatch::None);
       for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F)
       for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F)
       {
       {
-	 if ((F->Archive != 0 && vm.ExpressionMatches(DefRel, F.Archive()) == true) ||
-	     (F->Codename != 0 && vm.ExpressionMatches(DefRel, F.Codename()) == true) ||
-	     (F->Version != 0 && vm.ExpressionMatches(DefRel, F.Version()) == true) ||
+	 if (vm.ExpressionMatches(DefRel, F.Archive()) ||
+	     vm.ExpressionMatches(DefRel, F.Codename()) ||
+	     vm.ExpressionMatches(DefRel, F.Version()) ||
 	     (DefRel.length() > 2 && DefRel[1] == '='))
 	     (DefRel.length() > 2 && DefRel[1] == '='))
 	    found = true;
 	    found = true;
       }
       }
@@ -96,48 +86,40 @@ bool pkgPolicy::InitDefaults()
    for (pkgCache::PkgFileIterator I = Cache->FileBegin(); I != Cache->FileEnd(); ++I)
    for (pkgCache::PkgFileIterator I = Cache->FileBegin(); I != Cache->FileEnd(); ++I)
    {
    {
       PFPriority[I->ID] = 500;
       PFPriority[I->ID] = 500;
-      if ((I->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource)
+      if (I.Flagged(pkgCache::Flag::NotSource))
 	 PFPriority[I->ID] = 100;
 	 PFPriority[I->ID] = 100;
-      else if ((I->Flags & pkgCache::Flag::ButAutomaticUpgrades) == pkgCache::Flag::ButAutomaticUpgrades)
+      else if (I.Flagged(pkgCache::Flag::ButAutomaticUpgrades))
 	 PFPriority[I->ID] = 100;
 	 PFPriority[I->ID] = 100;
-      else if ((I->Flags & pkgCache::Flag::NotAutomatic) == pkgCache::Flag::NotAutomatic)
+      else if (I.Flagged(pkgCache::Flag::NotAutomatic))
 	 PFPriority[I->ID] = 1;
 	 PFPriority[I->ID] = 1;
    }
    }
 
 
    // Apply the defaults..
    // Apply the defaults..
    SPtrArray<bool> Fixed = new bool[Cache->HeaderP->PackageFileCount];
    SPtrArray<bool> Fixed = new bool[Cache->HeaderP->PackageFileCount];
    memset(Fixed,0,sizeof(*Fixed)*Cache->HeaderP->PackageFileCount);
    memset(Fixed,0,sizeof(*Fixed)*Cache->HeaderP->PackageFileCount);
-   signed Cur = 989;
    StatusOverride = false;
    StatusOverride = false;
-   for (vector<Pin>::const_iterator I = Defaults.begin(); I != Defaults.end();
-	++I, --Cur)
+   for (vector<Pin>::const_iterator I = Defaults.begin(); I != Defaults.end(); ++I)
    {
    {
       pkgVersionMatch Match(I->Data,I->Type);
       pkgVersionMatch Match(I->Data,I->Type);
       for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F)
       for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F)
       {
       {
-	 if (Match.FileMatch(F) == true && Fixed[F->ID] == false)
+	 if (Fixed[F->ID] == false && Match.FileMatch(F) == true)
 	 {
 	 {
-	    if (I->Priority != 0 && I->Priority > 0)
-	       Cur = I->Priority;
-	    
-	    if (I->Priority < 0)
-	       PFPriority[F->ID] =  I->Priority;
-	    else
-	       PFPriority[F->ID] = Cur;
-	    
-	    if (PFPriority[F->ID] > 1000)
+	    PFPriority[F->ID] = I->Priority;
+
+	    if (PFPriority[F->ID] >= 1000)
 	       StatusOverride = true;
 	       StatusOverride = true;
-	    
+
 	    Fixed[F->ID] = true;
 	    Fixed[F->ID] = true;
-	 }      
-      }      
+	 }
+      }
    }
    }
 
 
    if (_config->FindB("Debug::pkgPolicy",false) == true)
    if (_config->FindB("Debug::pkgPolicy",false) == true)
       for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F)
       for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F)
-	 std::clog << "Prio of " << F.FileName() << ' ' << PFPriority[F->ID] << std::endl; 
-   
-   return true;   
+	 std::clog << "Prio of " << F.FileName() << ' ' << PFPriority[F->ID] << std::endl;
+
+   return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // Policy::GetCandidateVer - Get the candidate install version		/*{{{*/
 // Policy::GetCandidateVer - Get the candidate install version		/*{{{*/
@@ -166,9 +148,7 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator const &Pk
       effectively excludes everything <= 0 which are the non-automatic
       effectively excludes everything <= 0 which are the non-automatic
       priorities.. The status file is given a prio of 100 which will exclude
       priorities.. The status file is given a prio of 100 which will exclude
       not-automatic sources, except in a single shot not-installed mode.
       not-automatic sources, except in a single shot not-installed mode.
-      The second pseduo-status file is at prio 1000, above which will permit
-      the user to force-downgrade things.
-      
+
       The user pin is subject to the same priority rules as default 
       The user pin is subject to the same priority rules as default 
       selections. Thus there are two ways to create a pin - a pin that
       selections. Thus there are two ways to create a pin - a pin that
       tracks the default when the default is taken away, and a permanent
       tracks the default when the default is taken away, and a permanent
@@ -190,8 +170,7 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator const &Pk
 	    then it is not a candidate for installation, ever. This weeds
 	    then it is not a candidate for installation, ever. This weeds
 	    out bogus entries that may be due to config-file states, or
 	    out bogus entries that may be due to config-file states, or
 	    other. */
 	    other. */
-	 if ((VF.File()->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource &&
-	     instVer == false)
+	 if (VF.File().Flagged(pkgCache::Flag::NotSource) && instVer == false)
 	    continue;
 	    continue;
 
 
 	 signed Prio = PFPriority[VF.File()->ID];
 	 signed Prio = PFPriority[VF.File()->ID];
@@ -218,9 +197,9 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator const &Pk
 	    Pref = Ver;
 	    Pref = Ver;
 	    PrefSeen = true;
 	    PrefSeen = true;
 	 }
 	 }
-	 /* Elevate our current selection (or the status file itself)
-	    to the Pseudo-status priority. */
-	 Max = 1000;
+	 /* Elevate our current selection (or the status file itself) so that only
+	    a downgrade can override it from now on */
+	 Max = 999;
 
 
 	 // Fast path optimize.
 	 // Fast path optimize.
 	 if (StatusOverride == false)
 	 if (StatusOverride == false)
@@ -336,13 +315,7 @@ pkgCache::VerIterator pkgPolicy::GetMatch(pkgCache::PkgIterator const &Pkg)
 APT_PURE signed short pkgPolicy::GetPriority(pkgCache::PkgIterator const &Pkg)
 APT_PURE signed short pkgPolicy::GetPriority(pkgCache::PkgIterator const &Pkg)
 {
 {
    if (Pins[Pkg->ID].Type != pkgVersionMatch::None)
    if (Pins[Pkg->ID].Type != pkgVersionMatch::None)
-   {
-      // In this case 0 means default priority
-      if (Pins[Pkg->ID].Priority == 0)
-	 return 989;
       return Pins[Pkg->ID].Priority;
       return Pins[Pkg->ID].Priority;
-   }
-   
    return 0;
    return 0;
 }
 }
 APT_PURE signed short pkgPolicy::GetPriority(pkgCache::PkgFileIterator const &File)
 APT_PURE signed short pkgPolicy::GetPriority(pkgCache::PkgFileIterator const &File)
@@ -466,3 +439,5 @@ bool ReadPinFile(pkgPolicy &Plcy,string File)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
+
+pkgPolicy::~pkgPolicy() {delete [] PFPriority; delete [] Pins;}

+ 3 - 2
apt-pkg/policy.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: policy.h,v 1.4 2001/05/07 04:24:08 jgg Exp $
 /* ######################################################################
 /* ######################################################################
 
 
    Package Version Policy implementation
    Package Version Policy implementation
@@ -85,7 +84,9 @@ class pkgPolicy : public pkgDepCache::Policy
    bool InitDefaults();
    bool InitDefaults();
    
    
    pkgPolicy(pkgCache *Owner);
    pkgPolicy(pkgCache *Owner);
-   virtual ~pkgPolicy() {delete [] PFPriority; delete [] Pins;};
+   virtual ~pkgPolicy();
+   private:
+   void *d;
 };
 };
 
 
 bool ReadPinFile(pkgPolicy &Plcy, std::string File = "");
 bool ReadPinFile(pkgPolicy &Plcy, std::string File = "");

+ 1 - 1
apt-pkg/sourcelist.cc

@@ -331,7 +331,7 @@ bool pkgSourceList::ParseFileOldStyle(string File)
 {
 {
    // Open the stream for reading
    // Open the stream for reading
    ifstream F(File.c_str(),ios::in /*| ios::nocreate*/);
    ifstream F(File.c_str(),ios::in /*| ios::nocreate*/);
-   if (!F != 0)
+   if (F.fail() == true)
       return _error->Errno("ifstream::ifstream",_("Opening %s"),File.c_str());
       return _error->Errno("ifstream::ifstream",_("Opening %s"),File.c_str());
 
 
    // CNC:2003-12-10 - 300 is too short.
    // CNC:2003-12-10 - 300 is too short.

+ 12 - 16
apt-pkg/sourcelist.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: sourcelist.h,v 1.12.2.1 2003/12/24 23:09:17 mdz Exp $
 /* ######################################################################
 /* ######################################################################
 
 
    SourceList - Manage a list of sources
    SourceList - Manage a list of sources
@@ -52,23 +51,16 @@ class pkgAcquire;
 class pkgIndexFile;
 class pkgIndexFile;
 class metaIndex;
 class metaIndex;
 
 
-class pkgSource
-{
-   protected:
-
-   std::vector<metaIndex *> SrcList;
-
-};
-
-class pkgSourceList : public pkgSource
+class pkgSourceList
 {
 {
+   void *d;
    public:
    public:
-   
+
    // List of supported source list types
    // List of supported source list types
    class Type
    class Type
    {
    {
       public:
       public:
-      
+
       // Global list of Items supported
       // Global list of Items supported
       static Type **GlobalList;
       static Type **GlobalList;
       static unsigned long GlobalListLen;
       static unsigned long GlobalListLen;
@@ -91,14 +83,18 @@ class pkgSourceList : public pkgSource
       Type();
       Type();
       virtual ~Type() {};
       virtual ~Type() {};
    };
    };
-   
+
    typedef std::vector<metaIndex *>::const_iterator const_iterator;
    typedef std::vector<metaIndex *>::const_iterator const_iterator;
-   
-   public:
+
+   protected:
+
+   std::vector<metaIndex *> SrcList;
 
 
    int ParseFileDeb822(std::string File);
    int ParseFileDeb822(std::string File);
    bool ParseFileOldStyle(std::string File);
    bool ParseFileOldStyle(std::string File);
 
 
+   public:
+
    bool ReadMainList();
    bool ReadMainList();
    bool Read(std::string File);
    bool Read(std::string File);
 
 
@@ -122,7 +118,7 @@ class pkgSourceList : public pkgSource
 
 
    pkgSourceList();
    pkgSourceList();
    pkgSourceList(std::string File);
    pkgSourceList(std::string File);
-   ~pkgSourceList();      
+   virtual ~pkgSourceList();
 };
 };
 
 
 #endif
 #endif

+ 30 - 1
apt-pkg/srcrecords.cc

@@ -14,6 +14,7 @@
 #include<config.h>
 #include<config.h>
 
 
 #include <apt-pkg/srcrecords.h>
 #include <apt-pkg/srcrecords.h>
+#include <apt-pkg/debsrcrecords.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/metaindex.h>
 #include <apt-pkg/metaindex.h>
@@ -147,5 +148,33 @@ const char *pkgSrcRecords::Parser::BuildDepType(unsigned char const &Type)
    return fields[Type];
    return fields[Type];
 }
 }
 									/*}}}*/
 									/*}}}*/
+bool pkgSrcRecords::Parser::Files2(std::vector<pkgSrcRecords::File2> &F2)/*{{{*/
+{
+   debSrcRecordParser * const deb = dynamic_cast<debSrcRecordParser*>(this);
+   if (deb != NULL)
+      return deb->Files2(F2);
 
 
-
+   std::vector<pkgSrcRecords::File> F;
+   if (Files(F) == false)
+      return false;
+   for (std::vector<pkgSrcRecords::File>::const_iterator f = F.begin(); f != F.end(); ++f)
+   {
+      pkgSrcRecords::File2 f2;
+#if __GNUC__ >= 4
+	#pragma GCC diagnostic push
+	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+      f2.MD5Hash = f->MD5Hash;
+      f2.Size = f->Size;
+      f2.Hashes.push_back(HashString("MD5Sum", f->MD5Hash));
+      f2.FileSize = f->Size;
+#if __GNUC__ >= 4
+	#pragma GCC diagnostic pop
+#endif
+      f2.Path = f->Path;
+      f2.Type = f->Type;
+      F2.push_back(f2);
+   }
+   return true;
+}
+									/*}}}*/

+ 9 - 11
apt-pkg/srcrecords.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: srcrecords.h,v 1.8.2.1 2003/12/26 16:27:34 mdz Exp $
 /* ######################################################################
 /* ######################################################################
    
    
    Source Package Records - Allows access to source package records
    Source Package Records - Allows access to source package records
@@ -30,23 +29,21 @@ class pkgSrcRecords
 {
 {
    public:
    public:
 
 
-#if __GNUC__ >= 4
-	// ensure that con- & de-structor don't trigger this warning
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+APT_IGNORE_DEPRECATED_PUSH
    // Describes a single file
    // Describes a single file
    struct File
    struct File
    {
    {
+      APT_DEPRECATED std::string MD5Hash;
+      APT_DEPRECATED unsigned long Size;
       std::string Path;
       std::string Path;
       std::string Type;
       std::string Type;
-      unsigned long long Size;
+   };
+   struct File2 : public File
+   {
+      unsigned long long FileSize;
       HashStringList Hashes;
       HashStringList Hashes;
-      APT_DEPRECATED std::string MD5Hash;
    };
    };
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
 
 
    // Abstract parser for each source record
    // Abstract parser for each source record
    class Parser
    class Parser
@@ -87,6 +84,7 @@ class pkgSrcRecords
       static const char *BuildDepType(unsigned char const &Type) APT_PURE;
       static const char *BuildDepType(unsigned char const &Type) APT_PURE;
 
 
       virtual bool Files(std::vector<pkgSrcRecords::File> &F) = 0;
       virtual bool Files(std::vector<pkgSrcRecords::File> &F) = 0;
+      bool Files2(std::vector<pkgSrcRecords::File2> &F);
       
       
       Parser(const pkgIndexFile *Index) : iIndex(Index) {};
       Parser(const pkgIndexFile *Index) : iIndex(Index) {};
       virtual ~Parser() {};
       virtual ~Parser() {};

+ 109 - 0
apt-pkg/tagfile-order.c

@@ -0,0 +1,109 @@
+/* In this file is the order defined in which e.g. apt-ftparchive will write stanzas in.
+   Other commands might or might not use this. 'apt-cache show' e.g. does NOT!
+
+   The order we chose here is inspired by both dpkg and dak.
+   The testcase test/integration/test-apt-tagfile-fields-order intends to ensure that
+   this file isn't lacking (too far) behind dpkg over time. */
+
+static const char *iTFRewritePackageOrder[] = {
+   "Package",
+   "Package-Type",
+   "Architecture",
+   "Subarchitecture", // Used only by d-i
+   "Version",
+   "Revision",         // Obsolete (warning in dpkg)
+   "Package-Revision", // Obsolete (warning in dpkg)
+   "Package_Revision", // Obsolete (warning in dpkg)
+   "Kernel-Version", // Used only by d-i
+   "Built-Using",
+   "Built-For-Profiles",
+   "Multi-Arch",
+   "Status",
+   "Priority",
+   "Class", // dpkg nickname for Priority
+   "Essential",
+   "Installer-Menu-Item", // Used only by d-i
+   "Section",
+   "Source",
+   "Origin",
+   "Maintainer",
+   "Original-Maintainer", // unknown in dpkg order
+   "Bugs",
+   "Config-Version", // Internal of dpkg
+   "Conffiles",
+   "Triggers-Awaited",
+   "Triggers-Pending",
+   "Installed-Size",
+   "Provides",
+   "Pre-Depends",
+   "Depends",
+   "Recommends",
+   "Recommended", // dpkg nickname for Recommends
+   "Suggests",
+   "Optional", // dpkg nickname for Suggests
+   "Conflicts",
+   "Breaks",
+   "Replaces",
+   "Enhances",
+   "Filename",
+   "MSDOS-Filename", // Obsolete (used by dselect)
+   "Size",
+   "MD5sum",
+   "SHA1",
+   "SHA256",
+   "SHA512",
+   "Homepage",
+   "Description",
+   "Tag",
+   "Task",
+   0
+};
+static const char *iTFRewriteSourceOrder[] = {
+   "Package",
+   "Source", // dsc file, renamed to Package in Sources
+   "Format",
+   "Binary",
+   "Architecture",
+   "Version",
+   "Priority",
+   "Class", // dpkg nickname for Priority
+   "Section",
+   "Origin",
+   "Maintainer",
+   "Original-Maintainer", // unknown in dpkg order
+   "Uploaders",
+   "Dm-Upload-Allowed", // Obsolete (ignored by dak)
+   "Standards-Version",
+   "Build-Depends",
+   "Build-Depends-Arch",
+   "Build-Depends-Indep",
+   "Build-Conflicts",
+   "Build-Conflicts-Arch",
+   "Build-Conflicts-Indep",
+   "Testsuite",
+   "Homepage",
+   "Vcs-Browser",
+   "Vcs-Browse", // dak only (nickname?)
+   "Vcs-Arch",
+   "Vcs-Bzr",
+   "Vcs-Cvs",
+   "Vcs-Darcs",
+   "Vcs-Git",
+   "Vcs-Hg",
+   "Vcs-Mtn",
+   "Vcs-Svn",
+   "Directory",
+   "Package-List",
+   "Files",
+   "Checksums-Md5",
+   "Checksums-Sha1",
+   "Checksums-Sha256",
+   "Checksums-Sha512",
+   0
+};
+
+/* Two levels of initialization are used because gcc will set the symbol
+   size of an array to the length of the array, causing dynamic relinking
+   errors. Doing this makes the symbol size constant */
+const char **TFRewritePackageOrder = iTFRewritePackageOrder;
+const char **TFRewriteSourceOrder = iTFRewriteSourceOrder;

+ 237 - 95
apt-pkg/tagfile.cc

@@ -47,6 +47,23 @@ public:
    unsigned long long Size;
    unsigned long long Size;
 };
 };
 
 
+class pkgTagSectionPrivate
+{
+public:
+   pkgTagSectionPrivate()
+   {
+   }
+   struct TagData {
+      unsigned int StartTag;
+      unsigned int EndTag;
+      unsigned int StartValue;
+      unsigned int NextInBucket;
+
+      TagData(unsigned int const StartTag) : StartTag(StartTag), EndTag(0), StartValue(0), NextInBucket(0) {}
+   };
+   std::vector<TagData> Tags;
+};
+
 static unsigned long AlphaHash(const char *Text, size_t Length)		/*{{{*/
 static unsigned long AlphaHash(const char *Text, size_t Length)		/*{{{*/
 {
 {
    /* This very simple hash function for the last 8 letters gives
    /* This very simple hash function for the last 8 letters gives
@@ -166,8 +183,8 @@ bool pkgTagFile::Step(pkgTagSection &Tag)
 	    break;
 	    break;
 
 
 	 if (Resize() == false)
 	 if (Resize() == false)
-	    return _error->Error(_("Unable to parse package file %s (1)"),
-		  d->Fd.Name().c_str());
+	    return _error->Error(_("Unable to parse package file %s (%d)"),
+		  d->Fd.Name().c_str(), 1);
 
 
       } while (Tag.Scan(d->Start,d->End - d->Start, false) == false);
       } while (Tag.Scan(d->Start,d->End - d->Start, false) == false);
    }
    }
@@ -266,7 +283,7 @@ bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long long Offset)
       return false;
       return false;
    
    
    if (Tag.Scan(d->Start, d->End - d->Start, false) == false)
    if (Tag.Scan(d->Start, d->End - d->Start, false) == false)
-      return _error->Error(_("Unable to parse package file %s (2)"),d->Fd.Name().c_str());
+      return _error->Error(_("Unable to parse package file %s (%d)"),d->Fd.Name().c_str(), 2);
    
    
    return true;
    return true;
 }
 }
@@ -274,21 +291,34 @@ bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long long Offset)
 // pkgTagSection::pkgTagSection - Constructor				/*{{{*/
 // pkgTagSection::pkgTagSection - Constructor				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
+APT_IGNORE_DEPRECATED_PUSH
 pkgTagSection::pkgTagSection()
 pkgTagSection::pkgTagSection()
    : Section(0), d(NULL), Stop(0)
    : Section(0), d(NULL), Stop(0)
 {
 {
-   memset(&LookupTable, 0, sizeof(LookupTable));
+   d = new pkgTagSectionPrivate();
+#if APT_PKG_ABI < 413
+   TagCount = 0;
+   memset(&Indexes, 0, sizeof(Indexes));
+#endif
+   memset(&AlphaIndexes, 0, sizeof(AlphaIndexes));
 }
 }
+APT_IGNORE_DEPRECATED_POP
 									/*}}}*/
 									/*}}}*/
 // TagSection::Scan - Scan for the end of the header information	/*{{{*/
 // TagSection::Scan - Scan for the end of the header information	/*{{{*/
+#if APT_PKG_ABI < 413
+bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
+{
+   return Scan(Start, MaxLength, true);
+}
+#endif
 bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const Restart)
 bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const Restart)
 {
 {
    Section = Start;
    Section = Start;
    const char *End = Start + MaxLength;
    const char *End = Start + MaxLength;
 
 
-   if (Restart == false && Tags.empty() == false)
+   if (Restart == false && d->Tags.empty() == false)
    {
    {
-      Stop = Section + Tags.back().StartTag;
+      Stop = Section + d->Tags.back().StartTag;
       if (End <= Stop)
       if (End <= Stop)
 	 return false;
 	 return false;
       Stop = (const char *)memchr(Stop,'\n',End - Stop);
       Stop = (const char *)memchr(Stop,'\n',End - Stop);
@@ -299,19 +329,23 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R
    else
    else
    {
    {
       Stop = Section;
       Stop = Section;
-      if (Tags.empty() == false)
+      if (d->Tags.empty() == false)
       {
       {
-	 memset(&LookupTable, 0, sizeof(LookupTable));
-	 Tags.clear();
+	 memset(&AlphaIndexes, 0, sizeof(AlphaIndexes));
+	 d->Tags.clear();
       }
       }
-      Tags.reserve(0x100);
+      d->Tags.reserve(0x100);
    }
    }
-   size_t TagCount = Tags.size();
+#if APT_PKG_ABI >= 413
+   unsigned int TagCount = d->Tags.size();
+#else
+   APT_IGNORE_DEPRECATED(TagCount = d->Tags.size();)
+#endif
 
 
    if (Stop == 0)
    if (Stop == 0)
       return false;
       return false;
 
 
-   TagData lastTagData(0);
+   pkgTagSectionPrivate::TagData lastTagData(0);
    lastTagData.EndTag = 0;
    lastTagData.EndTag = 0;
    unsigned long lastTagHash = 0;
    unsigned long lastTagHash = 0;
    while (Stop < End)
    while (Stop < End)
@@ -329,14 +363,20 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R
 	 // store the last found tag
 	 // store the last found tag
 	 if (lastTagData.EndTag != 0)
 	 if (lastTagData.EndTag != 0)
 	 {
 	 {
-	    if (LookupTable[lastTagHash] != 0)
-	       lastTagData.NextInBucket = LookupTable[lastTagHash];
-	    LookupTable[lastTagHash] = TagCount;
-	    Tags.push_back(lastTagData);
+	    if (AlphaIndexes[lastTagHash] != 0)
+	       lastTagData.NextInBucket = AlphaIndexes[lastTagHash];
+	    APT_IGNORE_DEPRECATED_PUSH
+	    AlphaIndexes[lastTagHash] = TagCount;
+#if APT_PKG_ABI < 413
+	    if (d->Tags.size() < sizeof(Indexes)/sizeof(Indexes[0]))
+	       Indexes[d->Tags.size()] = lastTagData.StartTag;
+#endif
+	    APT_IGNORE_DEPRECATED_POP
+	    d->Tags.push_back(lastTagData);
 	 }
 	 }
 
 
-	 ++TagCount;
-	 lastTagData = TagData(Stop - Section);
+	 APT_IGNORE_DEPRECATED(++TagCount;)
+	 lastTagData = pkgTagSectionPrivate::TagData(Stop - Section);
 	 // find the colon separating tag and value
 	 // find the colon separating tag and value
 	 char const * Colon = (char const *) memchr(Stop, ':', End - Stop);
 	 char const * Colon = (char const *) memchr(Stop, ':', End - Stop);
 	 if (Colon == NULL)
 	 if (Colon == NULL)
@@ -371,14 +411,20 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R
       {
       {
 	 if (lastTagData.EndTag != 0)
 	 if (lastTagData.EndTag != 0)
 	 {
 	 {
-	    if (LookupTable[lastTagHash] != 0)
-	       lastTagData.NextInBucket = LookupTable[lastTagHash];
-	    LookupTable[lastTagHash] = TagCount;
-	    Tags.push_back(lastTagData);
+	    if (AlphaIndexes[lastTagHash] != 0)
+	       lastTagData.NextInBucket = AlphaIndexes[lastTagHash];
+	    APT_IGNORE_DEPRECATED(AlphaIndexes[lastTagHash] = TagCount;)
+#if APT_PKG_ABI < 413
+	    APT_IGNORE_DEPRECATED(Indexes[d->Tags.size()] = lastTagData.StartTag;)
+#endif
+	    d->Tags.push_back(lastTagData);
 	 }
 	 }
 
 
-	 TagData const td(Stop - Section);
-	 Tags.push_back(td);
+	 pkgTagSectionPrivate::TagData const td(Stop - Section);
+#if APT_PKG_ABI < 413
+	 APT_IGNORE_DEPRECATED(Indexes[d->Tags.size()] = td.StartTag;)
+#endif
+	 d->Tags.push_back(td);
 	 TrimRecord(false,End);
 	 TrimRecord(false,End);
 	 return true;
 	 return true;
       }
       }
@@ -408,7 +454,11 @@ void pkgTagSection::Trim()
 }
 }
 									/*}}}*/
 									/*}}}*/
 // TagSection::Exists - return True if a tag exists			/*{{{*/
 // TagSection::Exists - return True if a tag exists			/*{{{*/
+#if APT_PKG_ABI >= 413
 bool pkgTagSection::Exists(const char* const Tag) const
 bool pkgTagSection::Exists(const char* const Tag) const
+#else
+bool pkgTagSection::Exists(const char* const Tag)
+#endif
 {
 {
    unsigned int tmp;
    unsigned int tmp;
    return Find(Tag, tmp);
    return Find(Tag, tmp);
@@ -420,16 +470,16 @@ bool pkgTagSection::Exists(const char* const Tag) const
 bool pkgTagSection::Find(const char *Tag,unsigned int &Pos) const
 bool pkgTagSection::Find(const char *Tag,unsigned int &Pos) const
 {
 {
    size_t const Length = strlen(Tag);
    size_t const Length = strlen(Tag);
-   unsigned int Bucket = LookupTable[AlphaHash(Tag, Length)];
+   unsigned int Bucket = AlphaIndexes[AlphaHash(Tag, Length)];
    if (Bucket == 0)
    if (Bucket == 0)
       return false;
       return false;
 
 
-   for (; Bucket != 0; Bucket = Tags[Bucket - 1].NextInBucket)
+   for (; Bucket != 0; Bucket = d->Tags[Bucket - 1].NextInBucket)
    {
    {
-      if ((Tags[Bucket - 1].EndTag - Tags[Bucket - 1].StartTag) != Length)
+      if ((d->Tags[Bucket - 1].EndTag - d->Tags[Bucket - 1].StartTag) != Length)
 	 continue;
 	 continue;
 
 
-      char const * const St = Section + Tags[Bucket - 1].StartTag;
+      char const * const St = Section + d->Tags[Bucket - 1].StartTag;
       if (strncasecmp(Tag,St,Length) != 0)
       if (strncasecmp(Tag,St,Length) != 0)
 	 continue;
 	 continue;
 
 
@@ -447,9 +497,9 @@ bool pkgTagSection::Find(const char *Tag,const char *&Start,
    if (Find(Tag, Pos) == false)
    if (Find(Tag, Pos) == false)
       return false;
       return false;
 
 
-   Start = Section + Tags[Pos].StartValue;
+   Start = Section + d->Tags[Pos].StartValue;
    // Strip off the gunk from the end
    // Strip off the gunk from the end
-   End = Section + Tags[Pos + 1].StartTag;
+   End = Section + d->Tags[Pos + 1].StartTag;
    if (unlikely(Start > End))
    if (unlikely(Start > End))
       return _error->Error("Internal parsing error");
       return _error->Error("Internal parsing error");
 
 
@@ -459,8 +509,6 @@ bool pkgTagSection::Find(const char *Tag,const char *&Start,
 }
 }
 									/*}}}*/
 									/*}}}*/
 // TagSection::FindS - Find a string					/*{{{*/
 // TagSection::FindS - Find a string					/*{{{*/
-// ---------------------------------------------------------------------
-/* */
 string pkgTagSection::FindS(const char *Tag) const
 string pkgTagSection::FindS(const char *Tag) const
 {
 {
    const char *Start;
    const char *Start;
@@ -470,6 +518,24 @@ string pkgTagSection::FindS(const char *Tag) const
    return string(Start,End);      
    return string(Start,End);      
 }
 }
 									/*}}}*/
 									/*}}}*/
+// TagSection::FindRawS - Find a string					/*{{{*/
+string pkgTagSection::FindRawS(const char *Tag) const
+{
+   unsigned int Pos;
+   if (Find(Tag, Pos) == false)
+      return "";
+
+   char const *Start = (char const *) memchr(Section + d->Tags[Pos].EndTag, ':', d->Tags[Pos].StartValue - d->Tags[Pos].EndTag);
+   ++Start;
+   char const *End = Section + d->Tags[Pos + 1].StartTag;
+   if (unlikely(Start > End))
+      return "";
+
+   for (; isspace(End[-1]) != 0 && End > Start; --End);
+
+   return std::string(Start, End - Start);
+}
+									/*}}}*/
 // TagSection::FindI - Find an integer					/*{{{*/
 // TagSection::FindI - Find an integer					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -561,78 +627,153 @@ bool pkgTagSection::FindFlag(unsigned long &Flags, unsigned long Flag,
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
+void pkgTagSection::Get(const char *&Start,const char *&Stop,unsigned int I) const
+{
+   Start = Section + d->Tags[I].StartTag;
+   Stop = Section + d->Tags[I+1].StartTag;
+}
 APT_PURE unsigned int pkgTagSection::Count() const {			/*{{{*/
 APT_PURE unsigned int pkgTagSection::Count() const {			/*{{{*/
-   if (Tags.empty() == true)
+   if (d->Tags.empty() == true)
       return 0;
       return 0;
    // the last element is just marking the end and isn't a real one
    // the last element is just marking the end and isn't a real one
-   return Tags.size() - 1;
+   return d->Tags.size() - 1;
+}
+									/*}}}*/
+// TagSection::Write - Ordered (re)writing of fields			/*{{{*/
+pkgTagSection::Tag pkgTagSection::Tag::Remove(std::string const &Name)
+{
+   return Tag(REMOVE, Name, "");
+}
+pkgTagSection::Tag pkgTagSection::Tag::Rename(std::string const &OldName, std::string const &NewName)
+{
+   return Tag(RENAME, OldName, NewName);
+}
+pkgTagSection::Tag pkgTagSection::Tag::Rewrite(std::string const &Name, std::string const &Data)
+{
+   if (Data.empty() == true)
+      return Tag(REMOVE, Name, "");
+   else
+      return Tag(REWRITE, Name, Data);
+}
+static bool WriteTag(FileFd &File, std::string Tag, std::string const &Value)
+{
+   if (Value.empty() || isspace(Value[0]) != 0)
+      Tag.append(":");
+   else
+      Tag.append(": ");
+   Tag.append(Value);
+   Tag.append("\n");
+   return File.Write(Tag.c_str(), Tag.length());
+}
+static bool RewriteTags(FileFd &File, pkgTagSection const * const This, char const * const Tag,
+      std::vector<pkgTagSection::Tag>::const_iterator &R,
+      std::vector<pkgTagSection::Tag>::const_iterator const &REnd)
+{
+   size_t const TagLen = strlen(Tag);
+   for (; R != REnd; ++R)
+   {
+      std::string data;
+      if (R->Name.length() == TagLen && strncasecmp(R->Name.c_str(), Tag, R->Name.length()) == 0)
+      {
+	 if (R->Action != pkgTagSection::Tag::REWRITE)
+	    break;
+	 data = R->Data;
+      }
+      else if(R->Action == pkgTagSection::Tag::RENAME && R->Data.length() == TagLen &&
+	    strncasecmp(R->Data.c_str(), Tag, R->Data.length()) == 0)
+	 data = This->FindRawS(R->Name.c_str());
+      else
+	 continue;
+
+      return WriteTag(File, Tag, data);
+   }
+   return true;
+}
+bool pkgTagSection::Write(FileFd &File, char const * const * const Order, std::vector<Tag> const &Rewrite) const
+{
+   // first pass: Write everything we have an order for
+   if (Order != NULL)
+   {
+      for (unsigned int I = 0; Order[I] != 0; ++I)
+      {
+	 std::vector<Tag>::const_iterator R = Rewrite.begin();
+	 if (RewriteTags(File, this, Order[I], R, Rewrite.end()) == false)
+	    return false;
+	 if (R != Rewrite.end())
+	    continue;
+
+	 if (Exists(Order[I]) == false)
+	    continue;
+
+	 if (WriteTag(File, Order[I], FindRawS(Order[I])) == false)
+	    return false;
+      }
+   }
+   // second pass: See if we have tags which aren't ordered
+   if (d->Tags.empty() == false)
+   {
+      for (std::vector<pkgTagSectionPrivate::TagData>::const_iterator T = d->Tags.begin(); T != d->Tags.end() - 1; ++T)
+      {
+	 char const * const fieldname = Section + T->StartTag;
+	 size_t fieldnamelen = T->EndTag - T->StartTag;
+	 if (Order != NULL)
+	 {
+	    unsigned int I = 0;
+	    for (; Order[I] != 0; ++I)
+	    {
+	       if (fieldnamelen == strlen(Order[I]) && strncasecmp(fieldname, Order[I], fieldnamelen) == 0)
+		  break;
+	    }
+	    if (Order[I] != 0)
+	       continue;
+	 }
+
+	 std::string const name(fieldname, fieldnamelen);
+	 std::vector<Tag>::const_iterator R = Rewrite.begin();
+	 if (RewriteTags(File, this, name.c_str(), R, Rewrite.end()) == false)
+	    return false;
+	 if (R != Rewrite.end())
+	    continue;
+
+	 if (WriteTag(File, name, FindRawS(name.c_str())) == false)
+	    return false;
+      }
+   }
+   // last pass: see if there are any rewrites remaining we haven't done yet
+   for (std::vector<Tag>::const_iterator R = Rewrite.begin(); R != Rewrite.end(); ++R)
+   {
+      if (R->Action == Tag::REMOVE)
+	 continue;
+      std::string const name = ((R->Action == Tag::RENAME) ? R->Data : R->Name);
+      if (Exists(name.c_str()))
+	 continue;
+      if (Order != NULL)
+      {
+	 unsigned int I = 0;
+	 for (; Order[I] != 0; ++I)
+	 {
+	    if (strncasecmp(name.c_str(), Order[I], name.length()) == 0 && name.length() == strlen(Order[I]))
+	       break;
+	 }
+	 if (Order[I] != 0)
+	    continue;
+      }
+
+      if (WriteTag(File, name, ((R->Action == Tag::RENAME) ? FindRawS(R->Name.c_str()) : R->Data)) == false)
+	 return false;
+   }
+   return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
+
+#include "tagfile-order.c"
+
 // TFRewrite - Rewrite a control record					/*{{{*/
 // TFRewrite - Rewrite a control record					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This writes the control record to stdout rewriting it as necessary. The
 /* This writes the control record to stdout rewriting it as necessary. The
    override map item specificies the rewriting rules to follow. This also
    override map item specificies the rewriting rules to follow. This also
    takes the time to sort the feild list. */
    takes the time to sort the feild list. */
-
-/* The order of this list is taken from dpkg source lib/parse.c the fieldinfos
-   array. */
-static const char *iTFRewritePackageOrder[] = {
-                          "Package",
-                          "Essential",
-                          "Status",
-                          "Priority",
-                          "Section",
-                          "Installed-Size",
-                          "Maintainer",
-                          "Original-Maintainer",
-                          "Architecture",
-                          "Source",
-                          "Version",
-                           "Revision",         // Obsolete
-                           "Config-Version",   // Obsolete
-                          "Replaces",
-                          "Provides",
-                          "Depends",
-                          "Pre-Depends",
-                          "Recommends",
-                          "Suggests",
-                          "Conflicts",
-                          "Breaks",
-                          "Conffiles",
-                          "Filename",
-                          "Size",
-                          "MD5sum",
-                          "SHA1",
-                          "SHA256",
-                          "SHA512",
-                           "MSDOS-Filename",   // Obsolete
-                          "Description",
-                          0};
-static const char *iTFRewriteSourceOrder[] = {"Package",
-                                      "Source",
-                                      "Binary",
-                                      "Version",
-                                      "Priority",
-                                      "Section",
-                                      "Maintainer",
-				      "Original-Maintainer",
-                                      "Build-Depends",
-                                      "Build-Depends-Indep",
-                                      "Build-Conflicts",
-                                      "Build-Conflicts-Indep",
-                                      "Architecture",
-                                      "Standards-Version",
-                                      "Format",
-                                      "Directory",
-                                      "Files",
-                                      0};   
-
-/* Two levels of initialization are used because gcc will set the symbol
-   size of an array to the length of the array, causing dynamic relinking 
-   errors. Doing this makes the symbol size constant */
-const char **TFRewritePackageOrder = iTFRewritePackageOrder;
-const char **TFRewriteSourceOrder = iTFRewriteSourceOrder;
-   
+APT_IGNORE_DEPRECATED_PUSH
 bool TFRewrite(FILE *Output,pkgTagSection const &Tags,const char *Order[],
 bool TFRewrite(FILE *Output,pkgTagSection const &Tags,const char *Order[],
 	       TFRewriteData *Rewrite)
 	       TFRewriteData *Rewrite)
 {
 {
@@ -756,6 +897,7 @@ bool TFRewrite(FILE *Output,pkgTagSection const &Tags,const char *Order[],
       
       
    return true;
    return true;
 }
 }
+APT_IGNORE_DEPRECATED_POP
 									/*}}}*/
 									/*}}}*/
 
 
-pkgTagSection::~pkgTagSection() {}
+pkgTagSection::~pkgTagSection() { delete d; }

+ 56 - 27
apt-pkg/tagfile.h

@@ -1,6 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // Description								/*{{{*/
-// $Id: tagfile.h,v 1.20 2003/05/19 17:13:57 doogie Exp $
 /* ######################################################################
 /* ######################################################################
 
 
    Fast scanner for RFC-822 type header information
    Fast scanner for RFC-822 type header information
@@ -33,35 +32,34 @@
 #endif
 #endif
 
 
 class FileFd;
 class FileFd;
+class pkgTagSectionPrivate;
 
 
 class pkgTagSection
 class pkgTagSection
 {
 {
    const char *Section;
    const char *Section;
-   struct TagData {
-      unsigned int StartTag;
-      unsigned int EndTag;
-      unsigned int StartValue;
-      unsigned int NextInBucket;
-
-      TagData(unsigned int const StartTag) : StartTag(StartTag), EndTag(0), StartValue(0), NextInBucket(0) {}
-   };
-   std::vector<TagData> Tags;
-   unsigned int LookupTable[0x100];
+   // We have a limit of 256 tags per section with the old abi
+#if APT_PKG_ABI < 413
+   APT_DEPRECATED unsigned int Indexes[256];
+#endif
+   unsigned int AlphaIndexes[0x100];
+#if APT_PKG_ABI < 413
+   APT_DEPRECATED unsigned int TagCount;
+#endif
 
 
-   // dpointer placeholder (for later in case we need it)
-   void *d;
+   pkgTagSectionPrivate *d;
 
 
    protected:
    protected:
    const char *Stop;
    const char *Stop;
 
 
    public:
    public:
-   
+
    inline bool operator ==(const pkgTagSection &rhs) {return Section == rhs.Section;};
    inline bool operator ==(const pkgTagSection &rhs) {return Section == rhs.Section;};
    inline bool operator !=(const pkgTagSection &rhs) {return Section != rhs.Section;};
    inline bool operator !=(const pkgTagSection &rhs) {return Section != rhs.Section;};
-   
+
    bool Find(const char *Tag,const char *&Start, const char *&End) const;
    bool Find(const char *Tag,const char *&Start, const char *&End) const;
    bool Find(const char *Tag,unsigned int &Pos) const;
    bool Find(const char *Tag,unsigned int &Pos) const;
    std::string FindS(const char *Tag) const;
    std::string FindS(const char *Tag) const;
+   std::string FindRawS(const char *Tag) const;
    signed int FindI(const char *Tag,signed long Default = 0) const;
    signed int FindI(const char *Tag,signed long Default = 0) const;
    bool FindB(const char *Tag, bool const &Default = false) const;
    bool FindB(const char *Tag, bool const &Default = false) const;
    unsigned long long FindULL(const char *Tag, unsigned long long const &Default = 0) const;
    unsigned long long FindULL(const char *Tag, unsigned long long const &Default = 0) const;
@@ -86,7 +84,13 @@ class pkgTagSection
     * @return \b true if section end was found, \b false otherwise.
     * @return \b true if section end was found, \b false otherwise.
     *  Beware that internal state will be inconsistent if \b false is returned!
     *  Beware that internal state will be inconsistent if \b false is returned!
     */
     */
+#if APT_PKG_ABI >= 413
    APT_MUSTCHECK bool Scan(const char *Start, unsigned long MaxLength, bool const Restart = true);
    APT_MUSTCHECK bool Scan(const char *Start, unsigned long MaxLength, bool const Restart = true);
+#else
+   APT_MUSTCHECK bool Scan(const char *Start, unsigned long MaxLength, bool const Restart);
+   APT_MUSTCHECK bool Scan(const char *Start, unsigned long MaxLength);
+#endif
+
    inline unsigned long size() const {return Stop - Section;};
    inline unsigned long size() const {return Stop - Section;};
    void Trim();
    void Trim();
    virtual void TrimRecord(bool BeforeRecord, const char* &End);
    virtual void TrimRecord(bool BeforeRecord, const char* &End);
@@ -97,19 +101,45 @@ class pkgTagSection
     * times, but only the last occurrence is available via Find methods.
     * times, but only the last occurrence is available via Find methods.
     */
     */
    unsigned int Count() const;
    unsigned int Count() const;
+#if APT_PKG_ABI >= 413
    bool Exists(const char* const Tag) const;
    bool Exists(const char* const Tag) const;
+#else
+   bool Exists(const char* const Tag);
+#endif
 
 
-   inline void Get(const char *&Start,const char *&Stop,unsigned int I) const
-                   {Start = Section + Tags[I].StartTag; Stop = Section + Tags[I+1].StartTag;}
+   void Get(const char *&Start,const char *&Stop,unsigned int I) const;
 
 
    inline void GetSection(const char *&Start,const char *&Stop) const
    inline void GetSection(const char *&Start,const char *&Stop) const
    {
    {
       Start = Section;
       Start = Section;
       Stop = this->Stop;
       Stop = this->Stop;
    };
    };
-   
+
    pkgTagSection();
    pkgTagSection();
    virtual ~pkgTagSection();
    virtual ~pkgTagSection();
+
+   struct Tag
+   {
+      enum ActionType { REMOVE, RENAME, REWRITE } Action;
+      std::string Name;
+      std::string Data;
+
+      static Tag Remove(std::string const &Name);
+      static Tag Rename(std::string const &OldName, std::string const &NewName);
+      static Tag Rewrite(std::string const &Name, std::string const &Data);
+      private:
+      Tag(ActionType const Action, std::string const &Name, std::string const &Data) :
+	 Action(Action), Name(Name), Data(Data) {}
+   };
+
+   /** Write this section (with optional rewrites) to a file
+    *
+    * @param File to write the section to
+    * @param Order in which tags should appear in the file
+    * @param Rewrite is a set of tags to be renamed, rewitten and/or removed
+    * @return \b true if successful, otherwise \b false
+    */
+   bool Write(FileFd &File, char const * const * const Order = NULL, std::vector<Tag> const &Rewrite = std::vector<Tag>()) const;
 };
 };
 
 
 class pkgTagFilePrivate;
 class pkgTagFilePrivate;
@@ -133,20 +163,19 @@ class pkgTagFile
    virtual ~pkgTagFile();
    virtual ~pkgTagFile();
 };
 };
 
 
-/* This is the list of things to rewrite. The rewriter
-   goes through and changes or adds each of these headers
-   to suit. A zero forces the header to be erased, an empty string
-   causes the old value to be used. (rewrite rule ignored) */
-struct TFRewriteData
+extern const char **TFRewritePackageOrder;
+extern const char **TFRewriteSourceOrder;
+
+// Use pkgTagSection::Tag and pkgTagSection::Write() instead
+APT_IGNORE_DEPRECATED_PUSH
+struct APT_DEPRECATED TFRewriteData
 {
 {
    const char *Tag;
    const char *Tag;
    const char *Rewrite;
    const char *Rewrite;
    const char *NewTag;
    const char *NewTag;
 };
 };
-extern const char **TFRewritePackageOrder;
-extern const char **TFRewriteSourceOrder;
-
-bool TFRewrite(FILE *Output,pkgTagSection const &Tags,const char *Order[],
+APT_DEPRECATED bool TFRewrite(FILE *Output,pkgTagSection const &Tags,const char *Order[],
 	       TFRewriteData *Rewrite);
 	       TFRewriteData *Rewrite);
+APT_IGNORE_DEPRECATED_POP
 
 
 #endif
 #endif

+ 18 - 10
apt-pkg/upgrade.cc

@@ -24,7 +24,7 @@
    
    
    The problem resolver is used to resolve the problems.
    The problem resolver is used to resolve the problems.
  */
  */
-bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
+static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
 {
 {
    std::string const solver = _config->Find("APT::Solver", "internal");
    std::string const solver = _config->Find("APT::Solver", "internal");
    if (solver != "internal")
    if (solver != "internal")
@@ -119,6 +119,10 @@ bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
    if (Progress != NULL)
    if (Progress != NULL)
       Progress->Done();
       Progress->Done();
    return success;
    return success;
+}
+bool pkgDistUpgrade(pkgDepCache &Cache)
+{
+   return pkgDistUpgrade(Cache, NULL);
 }
 }
 									/*}}}*/
 									/*}}}*/
 // AllUpgradeNoNewPackages - Upgrade but no removals or new pkgs        /*{{{*/
 // AllUpgradeNoNewPackages - Upgrade but no removals or new pkgs        /*{{{*/
@@ -229,9 +233,13 @@ static bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache, OpProgress * const
 /* Right now the system must be consistent before this can be called.
 /* Right now the system must be consistent before this can be called.
    It also will not change packages marked for install, it only tries
    It also will not change packages marked for install, it only tries
    to install packages not marked for install */
    to install packages not marked for install */
-bool pkgAllUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
+static bool pkgAllUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
 {
 {
    return pkgAllUpgradeNoNewPackages(Cache, Progress);
    return pkgAllUpgradeNoNewPackages(Cache, Progress);
+}
+bool pkgAllUpgrade(pkgDepCache &Cache)
+{
+   return pkgAllUpgrade(Cache, NULL);
 }
 }
 									/*}}}*/
 									/*}}}*/
 // MinimizeUpgrade - Minimizes the set of packages to be upgraded	/*{{{*/
 // MinimizeUpgrade - Minimizes the set of packages to be upgraded	/*{{{*/
@@ -280,13 +288,15 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache)
 }
 }
 									/*}}}*/
 									/*}}}*/
 // APT::Upgrade::Upgrade - Upgrade using a specific strategy		/*{{{*/
 // APT::Upgrade::Upgrade - Upgrade using a specific strategy		/*{{{*/
-bool APT::Upgrade::Upgrade(pkgDepCache &Cache, int mode, OpProgress * const Progress)
+#if APT_PKG_ABI < 413
+bool APT::Upgrade::Upgrade(pkgDepCache &Cache, int mode)
 {
 {
-#if __GNUC__ >= 4
-	// the deprecated methods will become our privates, so that is fine
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+   return Upgrade(Cache, mode, NULL);
+}
 #endif
 #endif
+bool APT::Upgrade::Upgrade(pkgDepCache &Cache, int mode, OpProgress * const Progress)
+{
+APT_IGNORE_DEPRECATED_PUSH
    if (mode == ALLOW_EVERYTHING)
    if (mode == ALLOW_EVERYTHING)
       return pkgDistUpgrade(Cache, Progress);
       return pkgDistUpgrade(Cache, Progress);
    else if ((mode & ~FORBID_REMOVE_PACKAGES) == 0)
    else if ((mode & ~FORBID_REMOVE_PACKAGES) == 0)
@@ -295,9 +305,7 @@ bool APT::Upgrade::Upgrade(pkgDepCache &Cache, int mode, OpProgress * const Prog
       return pkgAllUpgradeNoNewPackages(Cache, Progress);
       return pkgAllUpgradeNoNewPackages(Cache, Progress);
    else
    else
       _error->Error("pkgAllUpgrade called with unsupported mode %i", mode);
       _error->Error("pkgAllUpgrade called with unsupported mode %i", mode);
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP
    return false;
    return false;
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 9 - 4
apt-pkg/upgrade.h

@@ -20,17 +20,22 @@ namespace APT {
    namespace Upgrade {
    namespace Upgrade {
       // FIXME: make this "enum class UpgradeMode {" once we enable c++11
       // FIXME: make this "enum class UpgradeMode {" once we enable c++11
       enum UpgradeMode {
       enum UpgradeMode {
-	 ALLOW_EVERYTHING = 0,
          FORBID_REMOVE_PACKAGES = 1,
          FORBID_REMOVE_PACKAGES = 1,
-         FORBID_INSTALL_NEW_PACKAGES = 2
+         FORBID_INSTALL_NEW_PACKAGES = 2,
+	 ALLOW_EVERYTHING = 0
       };
       };
+#if APT_PKG_ABI >= 413
       bool Upgrade(pkgDepCache &Cache, int UpgradeMode, OpProgress * const Progress = NULL);
       bool Upgrade(pkgDepCache &Cache, int UpgradeMode, OpProgress * const Progress = NULL);
+#else
+      bool Upgrade(pkgDepCache &Cache, int UpgradeMode);
+      bool Upgrade(pkgDepCache &Cache, int UpgradeMode, OpProgress * const Progress);
+#endif
    }
    }
 }
 }
 
 
 // please use APT::Upgrade::Upgrade() instead
 // please use APT::Upgrade::Upgrade() instead
-APT_DEPRECATED bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress = NULL);
-APT_DEPRECATED bool pkgAllUpgrade(pkgDepCache &Cache, OpProgress * const Progress = NULL);
+APT_DEPRECATED bool pkgDistUpgrade(pkgDepCache &Cache);
+APT_DEPRECATED bool pkgAllUpgrade(pkgDepCache &Cache);
 
 
 bool pkgMinimizeUpgrade(pkgDepCache &Cache);
 bool pkgMinimizeUpgrade(pkgDepCache &Cache);
 #endif
 #endif

+ 3 - 7
apt-pkg/vendorlist.cc

@@ -11,10 +11,8 @@
 
 
 #include <apti18n.h>
 #include <apti18n.h>
 
 
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+// The whole vendor system is deprecated
+APT_IGNORE_DEPRECATED_PUSH
 
 
 #include <apt-pkg/vendor.h>
 #include <apt-pkg/vendor.h>
 #include <apt-pkg/vendorlist.h>
 #include <apt-pkg/vendorlist.h>
@@ -163,6 +161,4 @@ const Vendor* pkgVendorList::FindVendor(const std::vector<string> GPGVOutput)	/*
 }
 }
 									/*}}}*/
 									/*}}}*/
 
 
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif
+APT_IGNORE_DEPRECATED_POP

+ 3 - 0
apt-pkg/version.cc

@@ -40,3 +40,6 @@ pkgVersioningSystem *pkgVersioningSystem::GetVS(const char *Label)
    return 0;
    return 0;
 }
 }
 									/*}}}*/
 									/*}}}*/
+
+
+pkgVersioningSystem::~pkgVersioningSystem() {}

+ 1 - 1
apt-pkg/version.h

@@ -55,7 +55,7 @@ class pkgVersioningSystem
    APT_MKSTRCMP(CmpReleaseVer,DoCmpReleaseVer);
    APT_MKSTRCMP(CmpReleaseVer,DoCmpReleaseVer);
    
    
    pkgVersioningSystem();
    pkgVersioningSystem();
-   virtual ~pkgVersioningSystem() {};
+   virtual ~pkgVersioningSystem();
 };
 };
 
 
 #endif
 #endif

+ 23 - 22
apt-pkg/versionmatch.cc

@@ -137,7 +137,10 @@ pkgVersionMatch::pkgVersionMatch(string Data,MatchType Type) : Type(Type)
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
 bool pkgVersionMatch::MatchVer(const char *A,string B,bool Prefix)
 bool pkgVersionMatch::MatchVer(const char *A,string B,bool Prefix)
-{   
+{
+   if (A == NULL)
+      return false;
+
    const char *Ab = A;
    const char *Ab = A;
    const char *Ae = Ab + strlen(A);
    const char *Ae = Ab + strlen(A);
    
    
@@ -178,13 +181,16 @@ pkgCache::VerIterator pkgVersionMatch::Find(pkgCache::PkgIterator Pkg)
    // This will be Ended by now.
    // This will be Ended by now.
    return Ver;
    return Ver;
 }
 }
+									/*}}}*/
 
 
 #ifndef FNM_CASEFOLD
 #ifndef FNM_CASEFOLD
 #define FNM_CASEFOLD 0
 #define FNM_CASEFOLD 0
 #endif
 #endif
 
 
-bool pkgVersionMatch::ExpressionMatches(const char *pattern, const char *string)
+bool pkgVersionMatch::ExpressionMatches(const char *pattern, const char *string)/*{{{*/
 {
 {
+   if (pattern == NULL || string == NULL)
+      return false;
    if (pattern[0] == '/') {
    if (pattern[0] == '/') {
       size_t length = strlen(pattern);
       size_t length = strlen(pattern);
       if (pattern[length - 1] == '/') {
       if (pattern[length - 1] == '/') {
@@ -230,38 +236,30 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File)
 	 return false;
 	 return false;
 
 
       if (RelVerStr.empty() == false)
       if (RelVerStr.empty() == false)
-	 if (File->Version == 0 ||
-	     (MatchVer(File.Version(),RelVerStr,RelVerPrefixMatch) == false &&
-	      ExpressionMatches(RelVerStr, File.Version()) == false))
+	 if (MatchVer(File.Version(),RelVerStr,RelVerPrefixMatch) == false &&
+	       ExpressionMatches(RelVerStr, File.Version()) == false)
 	    return false;
 	    return false;
       if (RelOrigin.empty() == false)
       if (RelOrigin.empty() == false)
-	 if (File->Origin == 0 || !ExpressionMatches(RelOrigin,File.Origin()))
+	 if (!ExpressionMatches(RelOrigin,File.Origin()))
 	    return false;
 	    return false;
       if (RelArchive.empty() == false)
       if (RelArchive.empty() == false)
-	 if (File->Archive == 0 ||
-	     !ExpressionMatches(RelArchive,File.Archive()))
+	 if (!ExpressionMatches(RelArchive,File.Archive()))
             return false;
             return false;
       if (RelCodename.empty() == false)
       if (RelCodename.empty() == false)
-	 if (File->Codename == 0 ||
-	     !ExpressionMatches(RelCodename,File.Codename()))
+	 if (!ExpressionMatches(RelCodename,File.Codename()))
             return false;
             return false;
       if (RelRelease.empty() == false)
       if (RelRelease.empty() == false)
-	 if ((File->Archive == 0 ||
-	     !ExpressionMatches(RelRelease,File.Archive())) &&
-             (File->Codename == 0 ||
-	      !ExpressionMatches(RelRelease,File.Codename())))
+	 if (!ExpressionMatches(RelRelease,File.Archive()) &&
+             !ExpressionMatches(RelRelease,File.Codename()))
 	       return false;
 	       return false;
       if (RelLabel.empty() == false)
       if (RelLabel.empty() == false)
-	 if (File->Label == 0 ||
-	     !ExpressionMatches(RelLabel,File.Label()))
+	 if (!ExpressionMatches(RelLabel,File.Label()))
 	    return false;
 	    return false;
       if (RelComponent.empty() == false)
       if (RelComponent.empty() == false)
-	 if (File->Component == 0 ||
-	     !ExpressionMatches(RelComponent,File.Component()))
+	 if (!ExpressionMatches(RelComponent,File.Component()))
 	    return false;
 	    return false;
       if (RelArchitecture.empty() == false)
       if (RelArchitecture.empty() == false)
-	 if (File->Architecture == 0 ||
-	     !ExpressionMatches(RelArchitecture,File.Architecture()))
+	 if (!ExpressionMatches(RelArchitecture,File.Architecture()))
 	    return false;
 	    return false;
       return true;
       return true;
    }
    }
@@ -269,11 +267,14 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File)
    if (Type == Origin)
    if (Type == Origin)
    {
    {
       if (OrSite.empty() == false) {
       if (OrSite.empty() == false) {
-	 if (File->Site == 0)
+	 if (File.Site() == NULL)
 	    return false;
 	    return false;
       } else // so we are talking about file:// or status file
       } else // so we are talking about file:// or status file
-	 if (strcmp(File.Site(),"") == 0 && File->Archive != 0 && strcmp(File.Archive(),"now") == 0) // skip the status file
+      {
+	 pkgCache::RlsFileIterator const RlsFile = File.ReleaseFile();
+	 if (strcmp(File.Site(),"") == 0 && RlsFile->Archive != 0 && strcmp(RlsFile.Archive(),"now") == 0) // skip the status file
 	    return false;
 	    return false;
+      }
       return (ExpressionMatches(OrSite, File.Site())); /* both strings match */
       return (ExpressionMatches(OrSite, File.Site())); /* both strings match */
    }
    }
 
 

+ 2 - 2
apt-pkg/versionmatch.h

@@ -70,8 +70,8 @@ class pkgVersionMatch
    enum MatchType {None = 0,Version,Release,Origin} Type;
    enum MatchType {None = 0,Version,Release,Origin} Type;
 
 
    bool MatchVer(const char *A,std::string B,bool Prefix) APT_PURE;
    bool MatchVer(const char *A,std::string B,bool Prefix) APT_PURE;
-   bool ExpressionMatches(const char *pattern, const char *string);
-   bool ExpressionMatches(const std::string& pattern, const char *string);
+   static bool ExpressionMatches(const char *pattern, const char *string);
+   static bool ExpressionMatches(const std::string& pattern, const char *string);
    bool FileMatch(pkgCache::PkgFileIterator File);
    bool FileMatch(pkgCache::PkgFileIterator File);
    pkgCache::VerIterator Find(pkgCache::PkgIterator Pkg);
    pkgCache::VerIterator Find(pkgCache::PkgIterator Pkg);
 
 

+ 0 - 0
apt-private/acqprogress.cc


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