[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#203741: apt sigcheck patches



On Wed, 2003-08-20 at 18:33, Matt Zimmerman wrote:
> Could you send your patches to me or to #203741 so that I can look into
> merging them into apt CVS?

The patch is attached, I updated it to the latest CVS.
Let us know if you have any questions!

I'd also like to try merging the documentation we have into the apt docs
at some point.

diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/acquire-item.cc apt-HEAD/apt-pkg/acquire-item.cc
--- apt/apt-pkg/acquire-item.cc	2003-02-02 17:19:17.000000000 -0500
+++ apt-HEAD/apt-pkg/acquire-item.cc	2003-08-20 20:56:55.000000000 -0400
@@ -134,8 +134,9 @@
 /* The package file is added to the queue and a second class is 
    instantiated to fetch the revision file */   
 pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
-			 string URI,string URIDesc,string ShortDesc) :
-                      Item(Owner), RealURI(URI)
+			 string URI,string URIDesc,string ShortDesc,
+			 string ExpectedMD5) :
+   Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5)
 {
    Decompression = false;
    Erase = false;
@@ -181,6 +182,19 @@
 
    if (Decompression == true)
    {
+      if (_config->FindB("Debug::pkgAcquire::Auth", false))
+      {
+         std::cerr << std::endl << RealURI << ": Computed MD5: " << MD5;
+         std::cerr << "  Expected MD5: " << ExpectedMD5 << std::endl;
+      }
+
+      if (!ExpectedMD5.empty() && MD5 != ExpectedMD5)
+      {
+         Status = StatAuthError;
+         ErrorText = _("MD5Sum mismatch");
+         Rename(DestFile,DestFile + ".FAILED");
+         return;
+      }
       // Done, move it into position
       string FinalFile = _config->FindDir("Dir::State::lists");
       FinalFile += URItoFileName(RealURI);
@@ -208,7 +222,7 @@
       // The files timestamp matches
       if (StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false) == true)
 	 return;
-      
+
       Decompression = true;
       Local = true;
       DestFile += ".decomp";
@@ -240,7 +254,225 @@
    QueueURI(Desc);
    Mode = "gzip";
 }
+
+pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner,
+			     string URI,string URIDesc,string ShortDesc,
+			     string MetaIndexURI, string MetaIndexURIDesc,
+			     string MetaIndexShortDesc,
+			     const vector<IndexTarget*>* IndexTargets,
+			     indexRecords* MetaIndexParser,
+			     const Vendor *Verifier) :
+   Item(Owner), RealURI(URI), MetaIndexURI(MetaIndexURI),
+   MetaIndexURIDesc(MetaIndexURIDesc), MetaIndexShortDesc(MetaIndexShortDesc)
+{
+   this->MetaIndexParser = MetaIndexParser;
+   this->IndexTargets = IndexTargets;
+   this->Verifier = Verifier;
+   DestFile = _config->FindDir("Dir::State::lists") + "partial/";
+   DestFile += URItoFileName(URI);
+
+   // Create the item
+   Desc.Description = URIDesc;
+   Desc.Owner = this;
+   Desc.ShortDesc = ShortDesc;
+   Desc.URI = URI;
+   
+      
+   QueueURI(Desc);
+}
+									/*}}}*/
+void pkgAcqMetaSig::Done(string Message,unsigned long Size,string MD5,
+			 pkgAcquire::MethodConfig *Cfg)
+{
+   Item::Done(Message,Size,MD5,Cfg);
+
+   string FileName = LookupTag(Message,"Filename");
+   if (FileName.empty() == true)
+   {
+      Status = StatError;
+      ErrorText = "Method gave a blank filename";
+      return;
+   }
+
+   Complete = true;
+   
+   // The files timestamp matches
+   if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
+      return;
+   
+   // We have to copy it into place
+   if (FileName != DestFile)
+   {
+      Local = true;
+      Desc.URI = "copy:" + FileName;
+      QueueURI(Desc);
+      return;
+   }
+   
+   // Done, move it into position
+   string FinalFile = _config->FindDir("Dir::State::lists");
+   FinalFile += URItoFileName(RealURI);
+   Rename(DestFile,FinalFile);
+   
+   chmod(FinalFile.c_str(),0644);
+   
+   // need to queue a pkgAcqMetaIndex here
+   new pkgAcqMetaIndex(Owner, MetaIndexURI, MetaIndexURIDesc, MetaIndexShortDesc,
+		       FinalFile, IndexTargets, MetaIndexParser, Verifier);
+
+}
+									/*}}}*/
+pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner,
+				 string URI,string URIDesc,string ShortDesc,
+				 string SigFile,
+				 const vector<struct IndexTarget*>* IndexTargets,
+				 indexRecords* MetaIndexParser,
+				 const Vendor *Verifier) :
+  Item(Owner), RealURI(URI), SigFile(SigFile)
+{
+   this->Authentication = false;
+   this->MetaIndexParser = MetaIndexParser;
+   this->IndexTargets = IndexTargets;
+   this->Verifier = Verifier;
+   DestFile = _config->FindDir("Dir::State::lists") + "partial/";
+   DestFile += URItoFileName(URI);
+
+   // Create the item
+   Desc.Description = URIDesc;
+   Desc.Owner = this;
+   Desc.ShortDesc = ShortDesc;
+   Desc.URI = URI;
+
+   QueueURI(Desc);
+}
 									/*}}}*/
+void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string MD5,
+			   pkgAcquire::MethodConfig *Cfg)
+{
+   Item::Done(Message,Size,MD5,Cfg);
+
+   if (Authentication == true)
+   {
+      string GPGVOutputStr = LookupTag(Message,"GPGVOutput");
+      if (_config->FindB("Debug::pkgAcquire::Auth", false))
+         std::cerr << std::endl << "Got GPGVOutput: " << GPGVOutputStr
+		   << std::endl;
+
+      std::vector <string> GPGVOutput;
+      string::size_type pos;
+      // Skip the first \n
+      while ((pos = GPGVOutputStr.find('\n')) != string::npos)
+      {
+         GPGVOutput.push_back (GPGVOutputStr.substr(0, pos));
+         GPGVOutputStr = GPGVOutputStr.substr(pos+2);
+      }
+      if (_config->FindB("Debug::pkgAcquire::Auth", false))
+         std::cerr << std::endl << "Pushing \"" << GPGVOutputStr << "\"" << std::endl;
+      GPGVOutput.push_back (GPGVOutputStr);
+
+      if (_config->FindB("Debug::pkgAcquire::Auth", false))
+         std::cerr <<  "Verifying signature fingerprints..." << std::endl;
+      string CheckErrorText;
+      if (!Verifier->CheckFingerprints(GPGVOutput, ErrorText))
+      {
+         if (_config->FindB("Debug::pkgAcquire::Auth", false))
+            std::cerr <<  "Signature verification failed!" << std::endl;
+         Status = StatAuthError;
+         ErrorText = CheckErrorText;
+         return;
+      }
+
+      if (_config->FindB("Debug::pkgAcquire::Auth", false))
+         std::cerr << "Signature verification succeeded, parsing Meta-Index: "
+		   << DestFile << std::endl;
+
+      if (!MetaIndexParser->Load(DestFile))
+      {
+         Status = StatAuthError;
+         ErrorText = MetaIndexParser->ErrorText;
+         return;
+      }
+      string Transformed = MetaIndexParser->GetExpectedDist();
+      pos = Transformed.find('/');
+      if (pos)
+      {
+	 Transformed = Transformed.substr(0, pos);
+      }
+
+      if (_config->FindB("Debug::pkgAcquire::Auth", false)) 
+      {
+         std::cerr << "Got Codename: " << MetaIndexParser->GetDist() << std::endl;
+         std::cerr << "Expecting Dist: " << MetaIndexParser->GetExpectedDist() << std::endl;
+         std::cerr << "Transformed Dist: " << Transformed << std::endl;
+      }
+      
+      if (MetaIndexParser->CheckDist(Transformed) == false)
+      {
+         Status = StatAuthError;
+         ErrorText = "Conflicting distribution; expected "
+	   + MetaIndexParser->GetExpectedDist() + " but got "
+	   + MetaIndexParser->GetDist();
+         return;
+      }
+
+      for (vector <struct IndexTarget*>::const_iterator Target = IndexTargets->begin();
+	   Target != IndexTargets->end();
+	   Target++)
+      {
+         const indexRecords::checkSum *Record = MetaIndexParser->Lookup((*Target)->MetaKey);
+         if (!Record)
+         {
+            Status = StatAuthError;
+            ErrorText = "Unable to find expected entry  "
+	      + (*Target)->MetaKey + " in Meta-index file (malformed Release file?)";
+            return;
+         }
+         string ExpectedIndexMD5 = Record->MD5Hash;
+         if (_config->FindB("Debug::pkgAcquire::Auth", false))
+         {
+            std::cerr << "Queueing: " << (*Target)->URI << std::endl;
+            std::cerr << "Expected MD5: " << ExpectedIndexMD5 << std::endl;
+         }
+         if (ExpectedIndexMD5.empty())
+         {
+            Status = StatAuthError;
+            ErrorText = "Unable to find MD5 sum for "
+	      + (*Target)->MetaKey + " in Meta-index file";
+            return;
+         }
+      
+	// Queue Packages file
+         new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
+			(*Target)->ShortDesc, ExpectedIndexMD5);
+      }
+      // Done, move it into position
+      string FinalFile = _config->FindDir("Dir::State::lists");
+      FinalFile += URItoFileName(RealURI);
+      Rename(DestFile,FinalFile);
+      return;
+   }
+
+   Complete = true;
+   if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
+      return;
+
+   string FileName = LookupTag(Message,"Filename");
+   if (FileName.empty() == true)
+   {
+      Status = StatError;
+      ErrorText = "Method gave a blank filename";
+   }
+
+   if (FileName != DestFile)
+      Local = true;
+   
+   Authentication = true;
+   Desc.URI = "gpgv:" + SigFile;
+   QueueURI(Desc);
+   Mode = "gpgv";
+}
+									/*}}}*/
+
 
 // AcqIndexRel::pkgAcqIndexRel - Constructor				/*{{{*/
 // ---------------------------------------------------------------------
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/acquire-item.h apt-HEAD/apt-pkg/acquire-item.h
--- apt/apt-pkg/acquire-item.h	2003-02-01 22:13:13.000000000 -0500
+++ apt-HEAD/apt-pkg/acquire-item.h	2003-08-20 20:56:37.000000000 -0400
@@ -22,7 +22,10 @@
 
 #include <apt-pkg/acquire.h>
 #include <apt-pkg/indexfile.h>
+#include <apt-pkg/vendor.h>
+#include <apt-pkg/sourcelist.h>
 #include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/indexrecords.h>
 
 #ifdef __GNUG__
 #pragma interface "apt-pkg/acquire-item.h"
@@ -45,7 +48,7 @@
    public:
 
    // State of the item
-   enum {StatIdle, StatFetching, StatDone, StatError} Status;
+   enum {StatIdle, StatFetching, StatDone, StatError, StatAuthError} Status;
    string ErrorText;
    unsigned long FileSize;
    unsigned long PartialSize;   
@@ -86,6 +89,7 @@
    bool Erase;
    pkgAcquire::ItemDesc Desc;
    string RealURI;
+   string ExpectedMD5;
    
    public:
    
@@ -96,7 +100,68 @@
    virtual string DescURI() {return RealURI + ".gz";};
 
    pkgAcqIndex(pkgAcquire *Owner,string URI,string URIDesc,
-	       string ShortDesct);
+	       string ShortDesct, string ExpectedMD5);
+};
+
+struct IndexTarget
+{
+   string URI;
+   string Description;
+   string ShortDesc;
+   string MetaKey;
+};
+
+// Item class for index signatures
+class pkgAcqMetaSig : public pkgAcquire::Item
+{
+   protected:
+   
+   pkgAcquire::ItemDesc Desc;
+   string RealURI,MetaIndexURI,MetaIndexURIDesc,MetaIndexShortDesc;
+   indexRecords* MetaIndexParser;
+   const vector<struct IndexTarget*>* IndexTargets;
+
+   const Vendor *Verifier;
+  
+   public:
+   
+   // Specialized action members
+   virtual void Done(string Message,unsigned long Size,string Md5Hash,
+		     pkgAcquire::MethodConfig *Cnf);
+   virtual string DescURI() {return RealURI; };
+
+   pkgAcqMetaSig(pkgAcquire *Owner,string URI,string URIDesc, string ShortDesc,
+		 string MetaIndexURI, string MetaIndexURIDesc, string MetaIndexShortDesc,
+		 const vector<struct IndexTarget*>* IndexTargets,
+		 indexRecords* MetaIndexParser, const Vendor *Verifier);
+};
+
+// Item class for index signatures
+class pkgAcqMetaIndex : public pkgAcquire::Item
+{
+   protected:
+   
+   pkgAcquire::ItemDesc Desc;
+   string RealURI; // FIXME: is this redundant w/ Desc.URI?
+   string SigFile;
+   const vector<struct IndexTarget*>* IndexTargets;
+   indexRecords* MetaIndexParser;
+   bool Authentication;
+   const Vendor *Verifier;
+   
+   public:
+   
+   // Specialized action members
+   virtual void Done(string Message,unsigned long Size,string Md5Hash,
+		     pkgAcquire::MethodConfig *Cnf);
+   virtual string DescURI() {return RealURI; };
+
+   pkgAcqMetaIndex(pkgAcquire *Owner,
+		   string URI,string URIDesc, string ShortDesc,
+		   string SigFile,
+		   const vector<struct IndexTarget*>* IndexTargets,
+		   indexRecords* MetaIndexParser,
+		   const Vendor *Verifier);
 };
 
 // Item class for index files
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/acquire-method.cc apt-HEAD/apt-pkg/acquire-method.cc
--- apt/apt-pkg/acquire-method.cc	2001-05-22 00:27:11.000000000 -0400
+++ apt-HEAD/apt-pkg/acquire-method.cc	2003-08-20 20:56:37.000000000 -0400
@@ -29,6 +29,7 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <sys/signal.h>
 									/*}}}*/
 
 using namespace std;
@@ -181,6 +182,11 @@
       End += snprintf(End,sizeof(S)-50 - (End - S),"MD5-Hash: %s\n",Res.MD5Sum.c_str());
    if (Res.SHA1Sum.empty() == false)
       End += snprintf(End,sizeof(S)-50 - (End - S),"SHA1-Hash: %s\n",Res.SHA1Sum.c_str());
+   if (Res.GPGVOutput.size() > 0)
+      End += snprintf(End,sizeof(S)-50 - (End - S),"GPGVOutput:\n");     
+   for (vector<string>::iterator I = Res.GPGVOutput.begin();
+      I != Res.GPGVOutput.end(); I++)
+      End += snprintf(End,sizeof(S)-50 - (End - S), " %s\n", (*I).c_str());
 
    if (Res.ResumePoint != 0)
       End += snprintf(End,sizeof(S)-50 - (End - S),"Resume-Point: %lu\n",
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/acquire-method.h apt-HEAD/apt-pkg/acquire-method.h
--- apt/apt-pkg/acquire-method.h	2001-03-13 01:51:46.000000000 -0500
+++ apt-HEAD/apt-pkg/acquire-method.h	2003-08-20 20:56:37.000000000 -0400
@@ -39,6 +39,7 @@
    {
       string MD5Sum;
       string SHA1Sum;
+      vector<string> GPGVOutput;
       time_t LastModified;
       bool IMSHit;
       string Filename;
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/deb/debindexfile.cc apt-HEAD/apt-pkg/deb/debindexfile.cc
--- apt/apt-pkg/deb/debindexfile.cc	2001-04-29 01:13:51.000000000 -0400
+++ apt-HEAD/apt-pkg/deb/debindexfile.cc	2003-08-20 20:56:37.000000000 -0400
@@ -129,16 +129,6 @@
    return Res;
 }
 									/*}}}*/
-// SourcesIndex::GetIndexes - Fetch the index files			/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool debSourcesIndex::GetIndexes(pkgAcquire *Owner) const
-{
-   new pkgAcqIndex(Owner,IndexURI("Sources"),Info("Sources"),"Sources");
-   new pkgAcqIndexRel(Owner,IndexURI("Release"),Info("Release"),"Release");
-   return true;
-}
-									/*}}}*/
 // SourcesIndex::Exists - Check if the index is available		/*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -246,16 +236,6 @@
    return Res;
 }
 									/*}}}*/
-// PackagesIndex::GetIndexes - Fetch the index files			/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool debPackagesIndex::GetIndexes(pkgAcquire *Owner) const
-{
-   new pkgAcqIndex(Owner,IndexURI("Packages"),Info("Packages"),"Packages");
-   new pkgAcqIndexRel(Owner,IndexURI("Release"),Info("Release"),"Release");
-   return true;
-}
-									/*}}}*/
 // PackagesIndex::Exists - Check if the index is available		/*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -418,48 +398,6 @@
 }
 									/*}}}*/
 
-// Source List types for Debian						/*{{{*/
-class debSLTypeDeb : public pkgSourceList::Type
-{
-   public:
-
-   bool CreateItem(vector<pkgIndexFile *> &List,string URI,
-		   string Dist,string Section,
-		   pkgSourceList::Vendor const *Vendor) const
-   {
-      List.push_back(new debPackagesIndex(URI,Dist,Section));
-      return true;
-   };
-
-   debSLTypeDeb()
-   {
-      Name = "deb";
-      Label = "Standard Debian binary tree";
-   }   
-};
-
-class debSLTypeDebSrc : public pkgSourceList::Type
-{
-   public:
-
-   bool CreateItem(vector<pkgIndexFile *> &List,string URI,
-		   string Dist,string Section,
-		   pkgSourceList::Vendor const *Vendor) const 
-   {      
-      List.push_back(new debSourcesIndex(URI,Dist,Section));
-      return true;
-   };  
-   
-   debSLTypeDebSrc()
-   {
-      Name = "deb-src";
-      Label = "Standard Debian source tree";
-   }   
-};
-
-debSLTypeDeb _apt_DebType;
-debSLTypeDebSrc _apt_DebSrcType;
-									/*}}}*/
 // Index File types for Debian						/*{{{*/
 class debIFTypeSrc : public pkgIndexFile::Type
 {
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/deb/debindexfile.h apt-HEAD/apt-pkg/deb/debindexfile.h
--- apt/apt-pkg/deb/debindexfile.h	2001-04-29 01:13:51.000000000 -0400
+++ apt-HEAD/apt-pkg/deb/debindexfile.h	2003-08-20 20:56:37.000000000 -0400
@@ -63,7 +63,6 @@
    
    // Interface for acquire
    virtual string Describe(bool Short) const;   
-   virtual bool GetIndexes(pkgAcquire *Owner) const;
    
    // Interface for the Cache Generator
    virtual bool Exists() const;
@@ -96,7 +95,6 @@
    
    // Interface for acquire
    virtual string Describe(bool Short) const;   
-   virtual bool GetIndexes(pkgAcquire *Owner) const;
 
    // Interface for the record parsers
    virtual pkgSrcRecords::Parser *CreateSrcParser() const;
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/deb/debmetaindex.cc apt-HEAD/apt-pkg/deb/debmetaindex.cc
--- apt/apt-pkg/deb/debmetaindex.cc	1969-12-31 19:00:00.000000000 -0500
+++ apt-HEAD/apt-pkg/deb/debmetaindex.cc	2003-08-20 20:56:55.000000000 -0400
@@ -0,0 +1,265 @@
+// ijones, walters
+
+#ifdef __GNUG__
+#pragma implementation "apt-pkg/debmetaindex.h"
+#endif
+
+#include <apt-pkg/debmetaindex.h>
+#include <apt-pkg/debindexfile.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/error.h>
+
+using namespace std;
+
+string debReleaseIndex::Info(const char *Type, const string Section) const
+{
+   string Info = ::URI::SiteOnly(URI) + ' ';
+   if (Dist[Dist.size() - 1] == '/')
+   {
+      if (Dist != "/")
+         Info += Dist;
+   }
+   else
+      Info += Dist + '/' + Section;   
+   Info += " ";
+   Info += Type;
+   return Info;
+}
+
+string debReleaseIndex::MetaIndexInfo(const char *Type) const
+{
+   string Info = ::URI::SiteOnly(URI) + ' ';
+   if (Dist[Dist.size() - 1] == '/')
+   {
+      if (Dist != "/")
+	 Info += Dist;
+   }
+   else
+      Info += Dist;
+   Info += " ";
+   Info += Type;
+   return Info;
+}
+
+string debReleaseIndex::MetaIndexURI(const char *Type) const
+{
+   string Res;
+
+   if (Dist == "/")
+      Res = URI;
+   else
+      Res = URI + "dists/" + Dist + "/";
+   
+   Res += Type;
+   return Res;
+}
+
+string debReleaseIndex::IndexURISuffix(const char *Type, const string Section) const
+{
+   string Res ="";
+   if (Dist[Dist.size() - 1] != '/')
+      Res += Section + "/binary-" + _config->Find("APT::Architecture") + '/';
+   return Res + Type;
+}
+   
+
+string debReleaseIndex::IndexURI(const char *Type, const string Section) const
+{
+   if (Dist[Dist.size() - 1] == '/')
+   {
+      string Res;
+      if (Dist != "/")
+         Res = URI + Dist;
+      else 
+         Res = URI;
+      return Res + Type;
+   }
+   else
+      return URI + "dists/" + Dist + '/' + IndexURISuffix(Type, Section);
+ }
+
+string debReleaseIndex::SourceIndexURISuffix(const char *Type, const string Section) const
+{
+   return Section + "/source/" + Type;
+}
+
+string debReleaseIndex::SourceIndexURI(const char *Type, const string Section) const
+{
+   string Res;
+   if (Dist[Dist.size() - 1] == '/')
+   {
+      if (Dist != "/")
+         Res = URI + Dist;
+      else 
+         Res = URI;
+      return Res + Type;
+   }
+   else
+      return URI + "dists/" + Dist + "/" + SourceIndexURISuffix(Type, Section);
+}
+
+debReleaseIndex::debReleaseIndex(string URI,string Dist,
+				 const Vendor *Verifier)
+{
+   this->URI = URI;
+   this->Dist = Dist;
+   this->Verifier = Verifier;
+   this->Indexes = NULL;
+   this->Type = "deb";
+}
+
+vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const
+{
+   vector <struct IndexTarget *>* IndexTargets = new vector <IndexTarget *>;
+   for (vector <const debSectionEntry *>::const_iterator I = SectionEntries.begin();
+	I != SectionEntries.end();
+	I++)
+   {
+      IndexTarget * Target = new IndexTarget();
+      Target->ShortDesc = (*I)->IsSrc ? "Sources" : "Packages";
+      Target->MetaKey
+	= (*I)->IsSrc ? SourceIndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section)
+	              : IndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section);
+      Target->URI 
+	= (*I)->IsSrc ? SourceIndexURI(Target->ShortDesc.c_str(), (*I)->Section)
+	              : IndexURI(Target->ShortDesc.c_str(), (*I)->Section);
+      
+      Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section);
+      IndexTargets->push_back (Target);
+   }
+   return IndexTargets;
+}
+									/*}}}*/
+bool debReleaseIndex::GetIndexes(pkgAcquire *Owner) const
+{
+   // this means that the user didn't enter a vendor in the
+   // sources.list file, so we don't do any authentication here.  This
+   // may change later.
+
+   if (Verifier != NULL)
+      new pkgAcqMetaSig(Owner, MetaIndexURI("Release.gpg"),
+			MetaIndexInfo("Release.gpg"), "Release.gpg",
+			MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release",
+			ComputeIndexTargets(),
+			new indexRecords (Dist), Verifier);
+   else
+   {
+      for (vector<const debSectionEntry *>::const_iterator I = SectionEntries.begin(); 
+	   I != SectionEntries.end(); I++)
+      {
+         const char *IndexType = (*I)->IsSrc ? "Sources" : "Packages";
+         string indexURI = (*I)->IsSrc ? SourceIndexURI(IndexType, (*I)->Section)
+                                       : IndexURI(IndexType, (*I)->Section);
+         new pkgAcqIndex(Owner, indexURI, Info(IndexType, (*I)->Section), IndexType, "");
+      }
+   }
+   return true;
+}
+
+vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles()
+{
+   if (Indexes != NULL)
+      return Indexes;
+
+   Indexes = new vector <pkgIndexFile*>;
+   for (vector<const debSectionEntry *>::const_iterator I = SectionEntries.begin(); 
+	I != SectionEntries.end(); I++)
+      if ((*I)->IsSrc)
+         Indexes->push_back(new debSourcesIndex (URI, Dist, (*I)->Section));
+      else 
+         Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section));
+   return Indexes;
+}
+
+void debReleaseIndex::PushSectionEntry(const debSectionEntry *Entry)
+{
+   SectionEntries.push_back(Entry);
+}
+
+debReleaseIndex::debSectionEntry::debSectionEntry (string Section, bool IsSrc): Section(Section)
+{
+   this->IsSrc = IsSrc;
+}
+
+class debSLTypeDebian : public pkgSourceList::Type
+{
+   protected:
+
+   bool CreateItemInternal(vector<metaIndex *> &List,string URI,
+			   string Dist,string Section,
+			   const Vendor *Verifier,
+			   bool IsSrc) const
+   {
+      for (vector<metaIndex *>::const_iterator I = List.begin(); 
+	   I != List.end(); I++)
+      {
+	 // This check insures that there will be only one Release file
+	 // queued for all the Packages files and Sources files it
+	 // corresponds to.
+	 if ((*I)->GetType() == "deb")
+	 {
+	    debReleaseIndex *Deb = (debReleaseIndex *) (*I);
+	    // If one verifier is NULL and the other isn't, they're not equal.
+	    // A verifier being NULL indicates that this is not a secure source.
+	    if ((Verifier == NULL && Deb->GetVendor() != NULL)
+		|| (Verifier != NULL && Deb->GetVendor() == NULL))
+	       continue;
+	    // This check insures that there will be only one Release file
+	    // queued for all the Packages files and Sources files it
+	    // corresponds to.
+	    if (Deb->GetURI() == URI && Deb->GetDist() == Dist)
+	       //Verifier == NULL indicates that this is not a secure source.
+	    {
+	       Deb->PushSectionEntry(new debReleaseIndex::debSectionEntry(Section, IsSrc));
+	       return true;
+	    }
+	 }
+      }
+      // No currently created Release file indexes this entry, so we create a new one.
+      debReleaseIndex *Deb = new debReleaseIndex(URI,Dist,Verifier);
+      Deb->PushSectionEntry (new debReleaseIndex::debSectionEntry(Section, IsSrc));
+      List.push_back(Deb);
+      return true;
+   }
+};
+
+class debSLTypeDeb : public debSLTypeDebian
+{
+   public:
+
+   bool CreateItem(vector<metaIndex *> &List,string URI,
+		   string Dist,string Section,
+		   const Vendor *Verifier) const
+   {
+      return CreateItemInternal(List, URI, Dist, Section, Verifier, false);
+   }
+
+   debSLTypeDeb()
+   {
+      Name = "deb";
+      Label = "Standard Debian binary tree";
+   }   
+};
+
+class debSLTypeDebSrc : public debSLTypeDebian
+{
+   public:
+
+   bool CreateItem(vector<metaIndex *> &List,string URI,
+		   string Dist,string Section,
+		   const Vendor *Verifier) const 
+   {
+      return CreateItemInternal(List, URI, Dist, Section, Verifier, true);
+   }
+   
+   debSLTypeDebSrc()
+   {
+      Name = "deb-src";
+      Label = "Standard Debian source tree";
+   }   
+};
+
+debSLTypeDeb _apt_DebType;
+debSLTypeDebSrc _apt_DebSrcType;
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/deb/debmetaindex.h apt-HEAD/apt-pkg/deb/debmetaindex.h
--- apt/apt-pkg/deb/debmetaindex.h	1969-12-31 19:00:00.000000000 -0500
+++ apt-HEAD/apt-pkg/deb/debmetaindex.h	2003-08-20 20:56:37.000000000 -0400
@@ -0,0 +1,47 @@
+// ijones, walters
+#ifndef PKGLIB_DEBMETAINDEX_H
+#define PKGLIB_DEBMETAINDEX_H
+
+#ifdef __GNUG__
+#pragma interface "apt-pkg/debmetaindex.h"
+#endif
+
+#include <apt-pkg/metaindex.h>
+#include <apt-pkg/sourcelist.h>
+
+class debReleaseIndex : public metaIndex {
+   public:
+
+   class debSectionEntry
+   {
+      public:
+      debSectionEntry (string Section, bool IsSrc);
+      bool IsSrc;
+      string Section;
+   };
+
+   private:
+   vector <const debSectionEntry *> SectionEntries;
+
+   public:
+
+   debReleaseIndex(string URI, string Dist,
+		   const Vendor *Verifier);
+
+   virtual string ArchiveURI(string File) const {return URI + File;};
+   virtual bool GetIndexes(pkgAcquire *Owner) const;
+   vector <struct IndexTarget *>* ComputeIndexTargets() const;
+   string Info(const char *Type, const string Section) const;
+   string MetaIndexInfo(const char *Type) const;
+   string MetaIndexFile(const char *Types) const;
+   string MetaIndexURI(const char *Type) const;
+   string IndexURI(const char *Type, const string Section) const;
+   string IndexURISuffix(const char *Type, const string Section) const;
+   string SourceIndexURI(const char *Type, const string Section) const;
+   string SourceIndexURISuffix(const char *Type, const string Section) const;
+   virtual vector <pkgIndexFile *> *GetIndexFiles();
+
+   void PushSectionEntry(const debSectionEntry *Entry);
+};
+
+#endif
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/indexfile.cc apt-HEAD/apt-pkg/indexfile.cc
--- apt/apt-pkg/indexfile.cc	2001-02-20 02:03:17.000000000 -0500
+++ apt-HEAD/apt-pkg/indexfile.cc	2003-08-20 20:56:37.000000000 -0400
@@ -42,14 +42,6 @@
 }
 									/*}}}*/
     
-// IndexFile::GetIndexes - Stub						/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool pkgIndexFile::GetIndexes(pkgAcquire *Owner) const
-{
-   return _error->Error("Internal Error, this index file is not downloadable");
-}
-									/*}}}*/
 // IndexFile::ArchiveInfo - Stub					/*{{{*/
 // ---------------------------------------------------------------------
 /* */
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/indexfile.h apt-HEAD/apt-pkg/indexfile.h
--- apt/apt-pkg/indexfile.h	2002-07-07 23:13:30.000000000 -0400
+++ apt-HEAD/apt-pkg/indexfile.h	2003-08-20 20:56:37.000000000 -0400
@@ -64,7 +64,6 @@
 
    // Interface for acquire
    virtual string ArchiveURI(string /*File*/) const {return string();};
-   virtual bool GetIndexes(pkgAcquire *Owner) const;
 
    // Interface for the record parsers
    virtual pkgSrcRecords::Parser *CreateSrcParser() const {return 0;};
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/indexrecords.cc apt-HEAD/apt-pkg/indexrecords.cc
--- apt/apt-pkg/indexrecords.cc	1969-12-31 19:00:00.000000000 -0500
+++ apt-HEAD/apt-pkg/indexrecords.cc	2003-08-20 20:56:55.000000000 -0400
@@ -0,0 +1,158 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+// $Id: indexrecords.cc,v 1.1 2003/02/20 03:50:44 ijones Exp $
+									/*}}}*/
+// Include Files							/*{{{*/
+#ifdef __GNUG__
+#pragma implementation "apt-pkg/indexrecords.h"
+#endif
+#include <apt-pkg/indexrecords.h>
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/strutl.h>
+#include <apti18n.h>
+#include <sys/stat.h>
+
+string indexRecords::GetDist() const
+{
+   return this->Dist;
+}
+
+bool indexRecords::CheckDist(const string MaybeDist) const
+{
+   return (this->Dist == MaybeDist
+	   || this->Suite == MaybeDist);
+}
+
+string indexRecords::GetExpectedDist() const
+{
+   return this->ExpectedDist;
+}
+
+const indexRecords::checkSum *indexRecords::Lookup(const string MetaKey)
+{
+   return Entries[MetaKey];
+}
+
+bool indexRecords::Load(const string Filename)
+{
+   struct stat buf;
+   if (stat(Filename.c_str(), &buf) != 0)
+   {
+      ErrorText = _(("Unable to stat Release file " + Filename).c_str());
+      return false;
+   }
+     
+   FileFd Fd(Filename, FileFd::ReadOnly);
+   pkgTagFile TagFile(&Fd, buf.st_size + 256); //FIX: ??
+   if (_error->PendingError() == true)
+   {
+      ErrorText = _(("Unable to parse Release file " + Filename).c_str());
+      return false;
+   }
+
+   pkgTagSection Section;
+   if (TagFile.Step(Section) == false)
+   {
+      ErrorText = _(("No sections in Release file " + Filename).c_str());
+      return false;
+   }
+
+   const char *Start, *End;
+   Section.Get (Start, End, 0);
+   Suite = Section.FindS("Suite");
+   Dist = Section.FindS("Codename");
+   if (Dist.empty())
+   {
+      ErrorText = _(("No Codename entry in Release file " + Filename).c_str());
+      return false;
+   }
+   if (!Section.Find("MD5Sum", Start, End))
+   {
+      ErrorText = _(("No MD5Sum entry in Release file " + Filename).c_str());
+      return false;
+   }
+   string Name;
+   string MD5Hash;
+   size_t Size;
+   while (Start < End)
+   {
+      if (!parseSumData(Start, End, Name, MD5Hash, Size))
+	 return false;
+      indexRecords::checkSum *Sum = new indexRecords::checkSum;
+      Sum->MetaKeyFilename = Name;
+      Sum->MD5Hash = MD5Hash;
+      Sum->Size = Size;
+      Entries[Name] = Sum;
+   }
+   
+   string Strdate = Section.FindS("Date"); // FIXME: verify this somehow?
+   return true;
+}
+
+bool indexRecords::parseSumData(const char *&Start, const char *End,
+				   string &Name, string &Hash, size_t &Size)
+{
+   Name = "";
+   Hash = "";
+   Size = 0;
+   /* Skip over the first blank */
+   while ((*Start == '\t' || *Start == ' ' || *Start == '\n')
+	  && Start < End)
+      Start++;
+   if (Start >= End)
+      return false;
+
+   /* Move EntryEnd to the end of the first entry (the hash) */
+   const char *EntryEnd = Start;
+   while ((*EntryEnd != '\t' && *EntryEnd != ' ')
+	  && EntryEnd < End)
+      EntryEnd++;
+   if (EntryEnd == End)
+      return false;
+
+   Hash.append(Start, EntryEnd-Start);
+
+   /* Skip over intermediate blanks */
+   Start = EntryEnd;
+   while (*Start == '\t' || *Start == ' ')
+      Start++;
+   if (Start >= End)
+      return false;
+   
+   EntryEnd = Start;
+   /* Find the end of the second entry (the size) */
+   while ((*EntryEnd != '\t' && *EntryEnd != ' ' )
+	  && EntryEnd < End)
+      EntryEnd++;
+   if (EntryEnd == End)
+      return false;
+   
+   Size = strtol (Start, NULL, 10);
+      
+   /* Skip over intermediate blanks */
+   Start = EntryEnd;
+   while (*Start == '\t' || *Start == ' ')
+      Start++;
+   if (Start >= End)
+      return false;
+   
+   EntryEnd = Start;
+   /* Find the end of the third entry (the filename) */
+   while ((*EntryEnd != '\t' && *EntryEnd != ' ' && *EntryEnd != '\n')
+	  && EntryEnd < End)
+      EntryEnd++;
+
+   Name.append(Start, EntryEnd-Start);
+   Start = EntryEnd; //prepare for the next round
+   return true;
+}
+
+indexRecords::indexRecords()
+{
+}
+
+indexRecords::indexRecords(const string ExpectedDist) :
+   ExpectedDist(ExpectedDist)
+{
+}
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/indexrecords.h apt-HEAD/apt-pkg/indexrecords.h
--- apt/apt-pkg/indexrecords.h	1969-12-31 19:00:00.000000000 -0500
+++ apt-HEAD/apt-pkg/indexrecords.h	2003-08-20 20:56:37.000000000 -0400
@@ -0,0 +1,52 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+// $Id: indexrecords.h,v 1.1 2003/02/20 03:50:44 ijones Exp $
+									/*}}}*/
+#ifndef PKGLIB_INDEXRECORDS_H
+#define PKGLIB_INDEXRECORDS_H
+
+#ifdef __GNUG__
+#pragma interface "apt-pkg/indexrecords.h"
+#endif 
+#include <apt-pkg/pkgcache.h>
+#include <apt-pkg/fileutl.h>
+
+#include <map>
+
+class indexRecords
+{
+   bool parseSumData(const char *&Start, const char *End, string &Name,
+		     string &Hash, size_t &Size);
+   public:
+   struct checkSum;
+   string ErrorText;
+   
+   protected:
+   string Dist;
+   string Suite;
+   string ExpectedDist;
+   std::map<string,checkSum *> Entries;
+
+   public:
+
+   indexRecords();
+   indexRecords(const string ExpectedDist);
+
+   // Lookup function
+   virtual const checkSum *Lookup(const string MetaKey);
+   
+   virtual bool Load(string Filename);
+   string GetDist() const;
+   virtual bool CheckDist(const string MaybeDist) const;
+   string GetExpectedDist() const;
+   virtual ~indexRecords(){};
+};
+
+struct indexRecords::checkSum
+{
+   string MetaKeyFilename;
+   string MD5Hash;
+   size_t Size;      
+};
+
+#endif
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/makefile apt-HEAD/apt-pkg/makefile
--- apt/apt-pkg/makefile	2003-02-09 17:02:45.000000000 -0500
+++ apt-HEAD/apt-pkg/makefile	2003-08-20 20:56:37.000000000 -0400
@@ -33,21 +33,22 @@
 	 pkgrecords.cc algorithms.cc acquire.cc\
 	 acquire-worker.cc acquire-method.cc init.cc clean.cc \
 	 srcrecords.cc cachefile.cc versionmatch.cc policy.cc \
-	 pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc
+	 pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \
+	 indexrecords.cc vendor.cc
 HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \
 	  orderlist.h sourcelist.h packagemanager.h tagfile.h \
 	  init.h pkgcache.h version.h progress.h pkgrecords.h \
 	  acquire.h acquire-worker.h acquire-item.h acquire-method.h \
 	  clean.h srcrecords.h cachefile.h versionmatch.h policy.h \
-	  pkgsystem.h indexfile.h
+	  pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h
 
 # Source code for the debian specific components
 # In theory the deb headers do not need to be exported..
 SOURCE+= deb/deblistparser.cc deb/debrecords.cc deb/dpkgpm.cc \
          deb/debsrcrecords.cc deb/debversion.cc deb/debsystem.cc \
-	 deb/debindexfile.cc deb/debindexfile.cc
+	 deb/debindexfile.cc deb/debindexfile.cc deb/debmetaindex.cc
 HEADERS+= debversion.h debsrcrecords.h dpkgpm.h debrecords.h \
-	  deblistparser.h debsystem.h debindexfile.h
+	  deblistparser.h debsystem.h debindexfile.h debmetaindex.h
 
 HEADERS := $(addprefix apt-pkg/,$(HEADERS))
 
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/metaindex.h apt-HEAD/apt-pkg/metaindex.h
--- apt/apt-pkg/metaindex.h	1969-12-31 19:00:00.000000000 -0500
+++ apt-HEAD/apt-pkg/metaindex.h	2003-08-20 20:56:37.000000000 -0400
@@ -0,0 +1,49 @@
+#ifndef PKGLIB_METAINDEX_H
+#define PKGLIB_METAINDEX_H
+
+/* #ifdef __GNUG__ */
+/* #pragma interface "apt-pkg/metaindex.h" */
+/* #endif */
+
+#include <string>
+#include <apt-pkg/pkgcache.h>
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/indexfile.h>
+#include <apt-pkg/vendor.h>
+    
+using std::string;
+
+class pkgAcquire;
+class pkgCacheGenerator;
+class OpProgress;
+
+class metaIndex
+{
+   protected:
+   vector <pkgIndexFile *> *Indexes;
+   const char *Type;
+   string URI;
+   string Dist;
+   const Vendor *Verifier;
+
+   public:
+
+   
+   // Return descriptive strings of various sorts
+   virtual string GetURI() const {return URI;}
+   virtual string GetDist() const {return Dist;}
+   virtual const Vendor *GetVendor() const {return Verifier;}
+   virtual const char* GetType() const {return Type;}
+
+   // Interface for acquire
+   virtual string ArchiveURI(string /*File*/) const = 0;
+   virtual bool GetIndexes(pkgAcquire *Owner) const = 0;
+   
+
+   virtual vector<pkgIndexFile *> *GetIndexFiles() = 0; 
+
+   virtual ~metaIndex() {};
+};
+
+#endif
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/pkgcachegen.cc apt-HEAD/apt-pkg/pkgcachegen.cc
--- apt/apt-pkg/pkgcachegen.cc	2003-02-01 21:44:20.000000000 -0500
+++ apt-HEAD/apt-pkg/pkgcachegen.cc	2003-08-20 20:56:37.000000000 -0400
@@ -678,7 +678,18 @@
 {
    unsigned long MapSize = _config->FindI("APT::Cache-Limit",12*1024*1024);
    
-   vector<pkgIndexFile *> Files(List.begin(),List.end());
+   vector<pkgIndexFile *> Files;
+   for (vector<metaIndex *>::const_iterator i = List.begin();
+        i != List.end();
+        i++)
+   {
+      vector <pkgIndexFile *> *Indexes = (*i)->GetIndexFiles();
+      for (vector<pkgIndexFile *>::const_iterator j = Indexes->begin();
+	   j != Indexes->end();
+	   j++)
+         Files.push_back (*j);
+   }
+   
    unsigned long EndOfSource = Files.size();
    if (_system->AddStatusFiles(Files) == false)
       return false;
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/sourcelist.cc apt-HEAD/apt-pkg/sourcelist.cc
--- apt/apt-pkg/sourcelist.cc	2002-07-08 00:18:07.000000000 -0400
+++ apt-HEAD/apt-pkg/sourcelist.cc	2003-08-20 20:56:37.000000000 -0400
@@ -74,8 +74,8 @@
 // ---------------------------------------------------------------------
 /* This is a generic one that is the 'usual' format for sources.list
    Weird types may override this. */
-bool pkgSourceList::Type::ParseLine(vector<pkgIndexFile *> &List,
-				    Vendor const *Vendor,
+bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
+				    const Vendor *Verifier,
 				    const char *Buffer,
 				    unsigned long CurLine,
 				    string File) const
@@ -98,7 +98,7 @@
       if (ParseQuoteWord(Buffer,Section) == true)
 	 return _error->Error(_("Malformed line %lu in source list %s (Absolute dist)"),CurLine,File.c_str());
       Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture"));
-      return CreateItem(List,URI,Dist,Section,Vendor);
+      return CreateItem(List,URI,Dist,Section,Verifier);
    }
    
    // Grab the rest of the dists
@@ -107,7 +107,7 @@
    
    do
    {
-      if (CreateItem(List,URI,Dist,Section,Vendor) == false)
+      if (CreateItem(List,URI,Dist,Section,Verifier) == false)
 	 return false;
    }
    while (ParseQuoteWord(Buffer,Section) == true);
@@ -135,7 +135,7 @@
 {
    for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
       delete *I;
-   for (vector<Vendor const *>::const_iterator I = VendorList.begin(); 
+   for (vector<const Vendor *>::const_iterator I = VendorList.begin(); 
 	I != VendorList.end(); I++)
       delete *I;
 }
@@ -159,7 +159,7 @@
       if (ReadConfigFile(Cnf,CnfFile,true) == false)
 	 return false;
 
-   for (vector<Vendor const *>::const_iterator I = VendorList.begin(); 
+   for (vector<const Vendor *>::const_iterator I = VendorList.begin(); 
 	I != VendorList.end(); I++)
       delete *I;
    VendorList.erase(VendorList.begin(),VendorList.end());
@@ -169,48 +169,59 @@
    for (Top = (Top == 0?0:Top->Child); Top != 0; Top = Top->Next)
    {
       Configuration Block(Top);
-      Vendor *Vendor;
-      
-      Vendor = new pkgSourceList::Vendor;
-      
-      Vendor->VendorID = Top->Tag;
-      Vendor->FingerPrint = Block.Find("Fingerprint");
-      Vendor->Description = Block.Find("Name");
-      
-      if (Vendor->FingerPrint.empty() == true || 
-	  Vendor->Description.empty() == true)
+      vector <struct Vendor::Fingerprint *> *Fingerprints = new vector<Vendor::Fingerprint *>;
+      string VendorID = Top->Tag;
+      struct Vendor::Fingerprint *Fingerprint = new struct Vendor::Fingerprint;
+
+      Fingerprint->Print = Block.Find("Fingerprint");
+      Fingerprint->Description = Block.Find("Name");
+      Fingerprints->push_back(Fingerprint);
+
+      if (Fingerprint->Print.empty() || Fingerprint->Description.empty())
       {
-         _error->Error(_("Vendor block %s is invalid"), Vendor->VendorID.c_str());
-	 delete Vendor;
-	 continue;
+         _error->Error(_("Vendor block %s is invalid"), VendorID.c_str());
+         delete Fingerprints;
+         continue;
       }
-      
-      VendorList.push_back(Vendor);
+      if (_config->FindB("Debug::sourceList", false)) 
+         std::cerr << "Adding vendor with ID: " << VendorID
+		   << " Fingerprint: " << Fingerprint->Print << std::endl;
+
+      VendorList.push_back(new Vendor(VendorID, Fingerprints));
    }
 
-   /* XXX Process 'group-key' type sections
-      This is currently faked out so that the vendors file format is
-      parsed but nothing is done with it except check for validity */
+   /* Process 'group-key' type sections */
    Top = Cnf.Tree("group-key");
    for (Top = (Top == 0?0:Top->Child); Top != 0; Top = Top->Next)
    {
-      Configuration Block(Top);
-      Vendor *Vendor;
-      
-      Vendor = new pkgSourceList::Vendor;
-      
-      Vendor->VendorID = Top->Tag;
-      Vendor->Description = Block.Find("Name");
+//       Configuration Block(Top);
+//       vector<Vendor::Fingerprint *> Fingerprints;
+//       string VendorID = Top->Tag;
+
+//       while (Block->Next)
+//       {
+// 	 struct Vendor::Fingerprint Fingerprint = new struct Vendor::Fingerprint;
+// 	 Fingerprint->Print = Block.Find("Fingerprint");
+// 	 Fingerprint->Description = Block.Find("Name");
+// 	 if (Fingerprint->print.empty() || Fingerprint->Description.empty())
+// 	 {
+// 	    _error->Error(_("Vendor block %s is invalid"), 
+// 			  Vendor->VendorID.c_str());
+// 	    delete Fingerprint;
+// 	    break;
+// 	 }
+// 	 Block = Block->Next->Next;
+//       }
+//       if (_error->PendingError())
+//       {
+// 	 for (vector <struct Vendor::Fingerprint *>::iterator I = Fingerprints.begin();
+// 	      I != Fingerprints.end(); I++)
+// 	    delete *I;
+// 	 delete Fingerprints;
+// 	 continue;
+//       }
 
-      if (Vendor->Description.empty() == true)
-      {
-         _error->Error(_("Vendor block %s is invalid"), 
-		       Vendor->VendorID.c_str());
-	 delete Vendor;
-	 continue;
-      }
-      
-      VendorList.push_back(Vendor);
+//       VendorList.push_back(new Vendor(VendorID, Fingerprints));
    }
    
    return !_error->PendingError();
@@ -270,7 +281,7 @@
 	 return _error->Error(_("Type '%s' is not known in on line %u in source list %s"),LineType.c_str(),CurLine,File.c_str());
       
       // Authenticated repository
-      Vendor const *Vndr = 0;
+      const Vendor *Verifier = 0;
       if (C[0] == '[')
       {
 	 string VendorID;
@@ -282,22 +293,23 @@
 	     return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str());
 	 VendorID = string(VendorID,1,VendorID.size()-2);
 	 
-	 for (vector<Vendor const *>::const_iterator iter = VendorList.begin();
+	 for (vector<const Vendor *>::const_iterator iter = VendorList.begin();
 	      iter != VendorList.end(); iter++) 
 	 {
-	    if ((*iter)->VendorID == VendorID)
+	    if ((*iter)->GetVendorID() == VendorID)
 	    {
-	       Vndr = *iter;
+	      if (_config->FindB("Debug::sourceList", false)) 
+		std::cerr << "Comparing VendorID \"" << VendorID << "\" with \"" << (*iter)->GetVendorID() << '"' << std::endl;
+	       Verifier = *iter;
 	       break;
 	    }
 	 }
 
-	 if (Vndr == 0)
+	 if (Verifier == 0)
 	    return _error->Error(_("Unknown vendor ID '%s' in line %u of source list %s"),
 				 VendorID.c_str(),CurLine,File.c_str());
       }
-      
-      if (Parse->ParseLine(SrcList,Vndr,C,CurLine,File) == false)
+      if (Parse->ParseLine(SrcList,Verifier,C,CurLine,File) == false)
 	 return false;
    }
    return true;
@@ -311,10 +323,15 @@
 {
    for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
    {
-      if ((*I)->FindInCache(*File.Cache()) == File)
+      vector<pkgIndexFile *> *Indexes = (*I)->GetIndexFiles();
+      for (vector<pkgIndexFile *>::const_iterator J = Indexes->begin();
+	   J != Indexes->end(); J++)
       {
-	 Found = *I;
-	 return true;
+         if ((*J)->FindInCache(*File.Cache()) == File)
+         {
+            Found = (*J);
+             return true;
+         }
       }
    }
    
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/sourcelist.h apt-HEAD/apt-pkg/sourcelist.h
--- apt/apt-pkg/sourcelist.h	2002-07-01 17:41:11.000000000 -0400
+++ apt-HEAD/apt-pkg/sourcelist.h	2003-08-20 20:56:37.000000000 -0400
@@ -30,7 +30,8 @@
 #include <string>
 #include <vector>
 #include <apt-pkg/pkgcache.h>
-#include <apt-pkg/indexfile.h>
+#include <apt-pkg/metaindex.h>
+#include <apt-pkg/vendor.h>
 
 using std::string;
 using std::vector;
@@ -44,18 +45,6 @@
 {
    public:
    
-   // An available vendor
-   struct Vendor
-   {
-      string VendorID;
-      string FingerPrint;
-      string Description;
-
-      /* Lets revisit these..
-      bool MatchFingerPrint(string FingerPrint);
-      string FingerPrintDescr();*/
-   };
-   
    // List of supported source list types
    class Type
    {
@@ -70,23 +59,22 @@
       const char *Label;
 
       bool FixupURI(string &URI) const;
-      virtual bool ParseLine(vector<pkgIndexFile *> &List,
-			     Vendor const *Vendor,
+      virtual bool ParseLine(vector<metaIndex *> &List,
+			     const Vendor *Verifier,
 			     const char *Buffer,
 			     unsigned long CurLine,string File) const;
-      virtual bool CreateItem(vector<pkgIndexFile *> &List,string URI,
+      virtual bool CreateItem(vector<metaIndex *> &List,string URI,
 			      string Dist,string Section,
-			      Vendor const *Vendor) const = 0;
-
+			      const Vendor *Verifier) const = 0;
       Type();
       virtual ~Type() {};
    };
    
-   typedef vector<pkgIndexFile *>::const_iterator const_iterator;
+   typedef vector<metaIndex *>::const_iterator const_iterator;
    
    protected:
 
-   vector<pkgIndexFile *> SrcList;
+   vector<metaIndex *> SrcList;
    vector<Vendor const *> VendorList;
    
    public:
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/srcrecords.cc apt-HEAD/apt-pkg/srcrecords.cc
--- apt/apt-pkg/srcrecords.cc	2002-11-09 15:38:02.000000000 -0500
+++ apt-HEAD/apt-pkg/srcrecords.cc	2003-08-20 20:56:37.000000000 -0400
@@ -35,11 +35,16 @@
    pkgSourceList::const_iterator I = List.begin();
    for (; I != List.end(); I++)
    {
-      Files[Count] = (*I)->CreateSrcParser();
-      if (_error->PendingError() == true)
-	 return;
-      if (Files[Count] != 0)
-	 Count++;
+      vector<pkgIndexFile *> *Indexes = (*I)->GetIndexFiles();
+      for (vector<pkgIndexFile *>::const_iterator J = Indexes->begin();
+	   J != Indexes->end(); J++)
+      {
+         Files[Count] = (*J)->CreateSrcParser();
+	 if (_error->PendingError() == true)
+            return;
+         if (Files[Count] != 0)
+            Count++;
+      }
    }
    Files[Count] = 0;
    
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/vendor.cc apt-HEAD/apt-pkg/vendor.cc
--- apt/apt-pkg/vendor.cc	1969-12-31 19:00:00.000000000 -0500
+++ apt-HEAD/apt-pkg/vendor.cc	2003-08-20 20:56:37.000000000 -0400
@@ -0,0 +1,56 @@
+#ifdef __GNUG__
+#pragma implementation "apt-pkg/vendor.h"
+#endif
+
+#include <iostream>
+#include <apt-pkg/error.h>
+#include <apt-pkg/vendor.h>
+#include <apt-pkg/configuration.h>
+
+Vendor::Vendor(std::string VendorID,
+	       std::vector<struct Vendor::Fingerprint *> *FingerprintList)
+{
+   this->VendorID = VendorID;
+   for (std::vector<struct Vendor::Fingerprint *>::iterator I = FingerprintList->begin();
+	I != FingerprintList->end(); I++)
+   {
+      if (_config->FindB("Debug::Vendor", false))
+         std::cerr << "Vendor \"" << VendorID << "\": Mapping \""
+		   << (*I)->Print << "\" to \"" << (*I)->Description << '"' << std::endl;
+      Fingerprints[(*I)->Print] = (*I)->Description;
+   }
+   delete FingerprintList;
+}
+
+const string Vendor::LookupFingerprint(string Print) const
+{
+   std::map<string,string>::const_iterator Elt = Fingerprints.find(Print);
+   if (Elt == Fingerprints.end())
+      return "";
+   else
+      return (*Elt).second;
+}
+
+bool Vendor::CheckFingerprints(const std::vector<string> GPGVOutput,
+			       string &ErrorText) const
+{
+   // In this policy, one good signature from a key with a known fingerprint is acceptable.
+   for (std::vector<string>::const_iterator I = GPGVOutput.begin(); I != GPGVOutput.end(); I++)
+   {
+      string::size_type pos = (*I).find("VALIDSIG ");
+      if (_config->FindB("Debug::Vendor", false))
+	 std::cerr << "Looking for VALIDSIG in \"" << (*I) << "\": pos " << pos << std::endl;
+      if (pos != std::string::npos)
+      {
+	 string Fingerprint = (*I).substr(pos+sizeof("VALIDSIG"));
+	 if (_config->FindB("Debug::Vendor", false))
+	    std::cerr << "Looking for \"" << Fingerprint << "\" in vendor..." << std::endl;
+	 if (this->LookupFingerprint(Fingerprint) != "")
+	    return true;
+      }
+   }
+   if (_config->FindB("Debug::Vendor", false))
+      std::cerr << "Couldn't find VALIDSIG in vendor..." << std::endl;
+   ErrorText = "No valid signature from an authenticated key found.";
+   return false;
+}
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/apt-pkg/vendor.h apt-HEAD/apt-pkg/vendor.h
--- apt/apt-pkg/vendor.h	1969-12-31 19:00:00.000000000 -0500
+++ apt-HEAD/apt-pkg/vendor.h	2003-08-20 20:56:37.000000000 -0400
@@ -0,0 +1,36 @@
+#ifndef PKGLIB_VENDOR_H
+#define PKGLIB_VENDOR_H
+#include <string>
+#include <vector>
+#include <map>
+
+#ifdef __GNUG__
+#pragma interface "apt-pkg/vendor.h"
+#endif
+
+using std::string;
+
+// A class representing a particular software provider. 
+class Vendor
+{
+   public:
+   struct Fingerprint
+   {
+      string Print;
+      string Description;
+   };
+
+   protected:
+   string VendorID;
+   std::map<string, string> Fingerprints;
+
+   public:
+   Vendor(string VendorID, std::vector<struct Fingerprint *> *FingerprintList);
+   virtual const string& GetVendorID() const { return VendorID; };
+   virtual const string LookupFingerprint(string Print) const;
+   virtual bool CheckFingerprints(const std::vector<string> Fingerprints,
+				  string &ErrorText) const;
+   virtual ~Vendor(){};
+};
+
+#endif
Files apt/bin/apt-cache and apt-HEAD/bin/apt-cache differ
Files apt/bin/apt-cdrom and apt-HEAD/bin/apt-cdrom differ
Files apt/bin/apt-config and apt-HEAD/bin/apt-config differ
Files apt/bin/apt-extracttemplates and apt-HEAD/bin/apt-extracttemplates differ
Files apt/bin/apt-get and apt-HEAD/bin/apt-get differ
Files apt/bin/apt-sortpkgs and apt-HEAD/bin/apt-sortpkgs differ
Files apt/bin/libapt-inst-libc6.3-5.so.1.0 and apt-HEAD/bin/libapt-inst-libc6.3-5.so.1.0 differ
Files apt/bin/libapt-inst-libc6.3-5.so.1.0.0 and apt-HEAD/bin/libapt-inst-libc6.3-5.so.1.0.0 differ
Files apt/bin/libapt-inst.so and apt-HEAD/bin/libapt-inst.so differ
Files apt/bin/libapt-pkg-libc6.3-5.so.3.3 and apt-HEAD/bin/libapt-pkg-libc6.3-5.so.3.3 differ
Files apt/bin/libapt-pkg-libc6.3-5.so.3.3.0 and apt-HEAD/bin/libapt-pkg-libc6.3-5.so.3.3.0 differ
Files apt/bin/libapt-pkg.so and apt-HEAD/bin/libapt-pkg.so differ
Files apt/bin/methods/bzip2 and apt-HEAD/bin/methods/bzip2 differ
Files apt/bin/methods/cdrom and apt-HEAD/bin/methods/cdrom differ
Files apt/bin/methods/copy and apt-HEAD/bin/methods/copy differ
Files apt/bin/methods/file and apt-HEAD/bin/methods/file differ
Files apt/bin/methods/ftp and apt-HEAD/bin/methods/ftp differ
Files apt/bin/methods/gpgv and apt-HEAD/bin/methods/gpgv differ
Files apt/bin/methods/gzip and apt-HEAD/bin/methods/gzip differ
Files apt/bin/methods/http and apt-HEAD/bin/methods/http differ
Files apt/bin/methods/rsh and apt-HEAD/bin/methods/rsh differ
Files apt/bin/methods/ssh and apt-HEAD/bin/methods/ssh differ
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/methods/gpgv.cc apt-HEAD/methods/gpgv.cc
--- apt/methods/gpgv.cc	1969-12-31 19:00:00.000000000 -0500
+++ apt-HEAD/methods/gpgv.cc	2003-08-20 20:56:37.000000000 -0400
@@ -0,0 +1,261 @@
+#include <apt-pkg/error.h>
+#include <apt-pkg/acquire-method.h>
+#include <apt-pkg/strutl.h>
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <utime.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <iostream>
+
+#define GNUPGPREFIX "[GNUPG:]"
+#define GNUPGBADSIG "[GNUPG:] BADSIG"
+#define GNUPGNOPUBKEY "[GNUPG:] NO_PUBKEY"
+#define GNUPGVALIDSIG "[GNUPG:] VALIDSIG"
+
+class GPGVMethod : public pkgAcqMethod
+{
+   private:
+   const char *VerifyGetSigners(const char *file, const char *outfile,
+				vector<string> &GoodSigners, vector<string> &BadSigners,
+				vector<string> &NoPubKeySigners);
+   
+   protected:
+   virtual bool Fetch(FetchItem *Itm);
+   
+   public:
+   
+   GPGVMethod() : pkgAcqMethod("1.0",SingleInstance | SendConfig) {};
+};
+
+const char *GPGVMethod::VerifyGetSigners(const char *file, const char *outfile,
+					 vector<string> &GoodSigners,
+					 vector<string> &BadSigners,
+					 vector<string> &NoPubKeySigners)
+{
+   if (_config->FindB("Debug::Acquire::gpg", false))
+   {
+      std::cerr << "inside VerifyGetSigners" << std::endl;
+   }
+   pid_t pid;
+   int fd[2];
+   FILE *pipein;
+   int status;
+   struct stat buff;
+   string gpgvpath = _config->Find("Dir::Bin::gpg", "/usr/bin/gpgv");
+   string pubringpath = _config->Find("Apt::GPGV::TrustedKeyring", "/etc/apt/trusted.gpg");
+   if (_config->FindB("Debug::Acquire::gpg", false))
+   {
+      std::cerr << "gpgv path: " << gpgvpath << std::endl;
+      std::cerr << "Keyring path: " << pubringpath << std::endl;
+   }
+
+   if (stat(pubringpath.c_str(), &buff))
+      return (string("Couldn't access keyring: ") + strerror(errno)).c_str();
+
+   if (pipe(fd) < 0)
+   {
+      return "Couldn't create pipe";
+   }
+
+   pid = fork();
+   if (pid < 0)
+   {
+      return (string("Couldn't spawn new process") + strerror(errno)).c_str();
+   }
+   else if (pid == 0)
+   {
+      if (_config->FindB("Debug::Acquire::gpg", false))
+      {
+         std::cerr << "Preparing to exec: " << gpgvpath
+		   << " --status-fd 3 --keyring " << pubringpath
+		   << " " << file << " " << outfile << std::endl;
+      }
+      int nullfd = open("/dev/null", O_RDONLY);
+      close(fd[0]);
+      // Redirect output to /dev/null; we read from the status fd
+      dup2(nullfd, STDOUT_FILENO); 
+      dup2(nullfd, STDERR_FILENO); 
+      // Redirect the pipe to the status fd (3)
+      dup2(fd[1], 3);
+
+      putenv("LANG=");
+      putenv("LC_ALL=");
+      putenv("LC_MESSAGES=");
+      execlp(gpgvpath.c_str(), gpgvpath.c_str(), "--status-fd", "3", "--keyring", 
+	     pubringpath.c_str(), file, outfile, NULL);
+             
+      exit(111);
+   }
+   close(fd[1]);
+
+   pipein = fdopen(fd[0], "r"); 
+   
+   // Loop over the output of gpgv, and check the signatures.
+   size_t buffersize = 64;
+   char *buffer = (char *) malloc(buffersize);
+   size_t bufferoff = 0;
+   while (1)
+   {
+      int c;
+
+      // Read a line.  Sigh.
+      while ((c = getc(pipein)) != EOF && c != '\n')
+      {
+         if (bufferoff == buffersize)
+            buffer = (char *) realloc(buffer, buffersize *= 2);
+         *(buffer+bufferoff) = c;
+         bufferoff++;
+      }
+      if (bufferoff == 0 && c == EOF)
+         break;
+      *(buffer+bufferoff) = '\0';
+      bufferoff = 0;
+      if (_config->FindB("Debug::Acquire::gpg", false))
+         std::cerr << "Read: " << buffer << std::endl;
+
+      // Push the data into three separate vectors, which
+      // we later concatenate.  They're kept separate so
+      // if we improve the apt method communication stuff later
+      // it will be better.
+      if (strncmp(buffer, GNUPGBADSIG, sizeof(GNUPGBADSIG)-1) == 0)
+      {
+         if (_config->FindB("Debug::Acquire::gpg", false))
+            std::cerr << "Got BADSIG! " << std::endl;
+         BadSigners.push_back(string(buffer+sizeof(GNUPGPREFIX)));
+      }
+      
+      if (strncmp(buffer, GNUPGNOPUBKEY, sizeof(GNUPGNOPUBKEY)-1) == 0)
+      {
+         if (_config->FindB("Debug::Acquire::gpg", false))
+            std::cerr << "Got NO_PUBKEY " << std::endl;
+         NoPubKeySigners.push_back(string(buffer+sizeof(GNUPGPREFIX)));
+      }
+
+      if (strncmp(buffer, GNUPGVALIDSIG, sizeof(GNUPGVALIDSIG)-1) == 0)
+      {
+         char *sig = buffer + sizeof(GNUPGPREFIX);
+         char *p = sig + sizeof("VALIDSIG");
+         while (*p && isxdigit(*p)) 
+            p++;
+         *p = 0;
+         if (_config->FindB("Debug::Acquire::gpg", false))
+            std::cerr << "Got VALIDSIG, key ID:" << sig << std::endl;
+         GoodSigners.push_back(string(sig));
+      }
+   }
+   fclose(pipein);
+
+   waitpid(pid, &status, 0);
+   if (_config->FindB("Debug::Acquire::gpg", false))
+   {
+      std::cerr <<"gpgv exited\n";
+   }
+   
+   if (WEXITSTATUS(status) == 0)
+   {
+      if (GoodSigners.empty())
+         return "Internal error: Good signature, but could not determine key fingerprint?!";
+      return NULL;
+   }
+   else if (WEXITSTATUS(status) == 1)
+   {
+      return "At least one invalid signature was encountered.";
+   }
+   else if (WEXITSTATUS(status) == 111)
+   {
+      return (string("Could not execute ") + gpgvpath +
+	      string(" to verify signature")).c_str();
+   }
+   else
+   {
+      return "Unknown error executing gpgv";
+   }
+}
+
+bool GPGVMethod::Fetch(FetchItem *Itm)
+{
+   URI Get = Itm->Uri;
+   string Path = Get.Host + Get.Path; // To account for relative paths
+   string keyID;
+   vector<string> GoodSigners;
+   vector<string> BadSigners;
+   vector<string> NoPubKeySigners;
+   
+   FetchResult Res;
+   Res.Filename = Itm->DestFile;
+   URIStart(Res);
+
+   // Run gpgv on file, extract contents and get the key ID of the signer
+   const char *msg = VerifyGetSigners(Path.c_str(), Itm->DestFile.c_str(),
+				      GoodSigners, BadSigners, NoPubKeySigners);
+   if (GoodSigners.empty() || !BadSigners.empty() || !NoPubKeySigners.empty())
+   {
+      string errmsg;
+      // In this case, something bad probably happened, so we just go
+      // with what the other method gave us for an error message.
+      if (BadSigners.empty() && NoPubKeySigners.empty())
+         errmsg = msg;
+      else
+      {
+         if (!BadSigners.empty())
+         {
+            errmsg += "The following signatures were invalid:\n";
+            for (vector<string>::iterator I = BadSigners.begin();
+		 I != BadSigners.end(); I++)
+               errmsg += (*I + "\n");
+         }
+         if (!NoPubKeySigners.empty())
+         {
+             errmsg += "The following signatures couldn't be verified because the public key is not available:\n";
+            for (vector<string>::iterator I = NoPubKeySigners.begin();
+		 I != NoPubKeySigners.end(); I++)
+               errmsg += (*I + "\n");
+         }
+      }
+      return _error->Error(errmsg.c_str());
+   }
+      
+   // Transfer the modification times
+   struct stat Buf;
+   if (stat(Path.c_str(),&Buf) != 0)
+      return _error->Errno("stat","Failed to stat %s", Path.c_str());
+
+   struct utimbuf TimeBuf;
+   TimeBuf.actime = Buf.st_atime;
+   TimeBuf.modtime = Buf.st_mtime;
+   if (utime(Itm->DestFile.c_str(),&TimeBuf) != 0)
+      return _error->Errno("utime","Failed to set modification time");
+
+   if (stat(Itm->DestFile.c_str(),&Buf) != 0)
+      return _error->Errno("stat","Failed to stat");
+   
+   // Return a Done response
+   Res.LastModified = Buf.st_mtime;
+   Res.Size = Buf.st_size;
+   // Just pass the raw output up, because passing it as a real data
+   // structure is too difficult with the method stuff.  We keep it
+   // as three separate vectors for future extensibility.
+   Res.GPGVOutput = GoodSigners;
+   Res.GPGVOutput.insert(Res.GPGVOutput.end(),BadSigners.begin(),BadSigners.end());
+   Res.GPGVOutput.insert(Res.GPGVOutput.end(),NoPubKeySigners.begin(),NoPubKeySigners.end());
+   URIDone(Res);
+
+   if (_config->FindB("Debug::Acquire::gpg", false))
+   {
+      std::cerr <<"gpgv suceeded\n";
+   }
+
+   return true;
+}
+
+
+int main()
+{
+   GPGVMethod Mth;
+
+   return Mth.Run();
+}
diff -uNr -x '*.d' -x '*.o' -x po -x scripts -x CVS -x scripts -x include -x docs -x doc -x configure -x autom4te.cache -x build -x aclocal.m4 apt/methods/makefile apt-HEAD/methods/makefile
--- apt/methods/makefile	2002-11-11 02:00:16.000000000 -0500
+++ apt-HEAD/methods/makefile	2003-08-20 20:56:37.000000000 -0400
@@ -31,6 +31,13 @@
 SOURCE = gzip.cc
 include $(PROGRAM_H)
 
+# The gpgv method
+PROGRAM=gpgv
+SLIBS = -lapt-pkg
+LIB_MAKES = apt-pkg/makefile
+SOURCE = gpgv.cc
+include $(PROGRAM_H)
+
 # The cdrom method
 PROGRAM=cdrom
 SLIBS = -lapt-pkg 
Files apt/obj/apt-inst/arfile.opic and apt-HEAD/obj/apt-inst/arfile.opic differ
Files apt/obj/apt-inst/database.opic and apt-HEAD/obj/apt-inst/database.opic differ
Files apt/obj/apt-inst/debfile.opic and apt-HEAD/obj/apt-inst/debfile.opic differ
Files apt/obj/apt-inst/dirstream.opic and apt-HEAD/obj/apt-inst/dirstream.opic differ
Files apt/obj/apt-inst/dpkgdb.opic and apt-HEAD/obj/apt-inst/dpkgdb.opic differ
Files apt/obj/apt-inst/extract.opic and apt-HEAD/obj/apt-inst/extract.opic differ
Files apt/obj/apt-inst/extracttar.opic and apt-HEAD/obj/apt-inst/extracttar.opic differ
Files apt/obj/apt-inst/filelist.opic and apt-HEAD/obj/apt-inst/filelist.opic differ
Files apt/obj/apt-pkg/acquire-item.opic and apt-HEAD/obj/apt-pkg/acquire-item.opic differ
Files apt/obj/apt-pkg/acquire-method.opic and apt-HEAD/obj/apt-pkg/acquire-method.opic differ
Files apt/obj/apt-pkg/acquire.opic and apt-HEAD/obj/apt-pkg/acquire.opic differ
Files apt/obj/apt-pkg/acquire-worker.opic and apt-HEAD/obj/apt-pkg/acquire-worker.opic differ
Files apt/obj/apt-pkg/algorithms.opic and apt-HEAD/obj/apt-pkg/algorithms.opic differ
Files apt/obj/apt-pkg/cachefile.opic and apt-HEAD/obj/apt-pkg/cachefile.opic differ
Files apt/obj/apt-pkg/cdromutl.opic and apt-HEAD/obj/apt-pkg/cdromutl.opic differ
Files apt/obj/apt-pkg/clean.opic and apt-HEAD/obj/apt-pkg/clean.opic differ
Files apt/obj/apt-pkg/cmndline.opic and apt-HEAD/obj/apt-pkg/cmndline.opic differ
Files apt/obj/apt-pkg/configuration.opic and apt-HEAD/obj/apt-pkg/configuration.opic differ
Files apt/obj/apt-pkg/crc-16.opic and apt-HEAD/obj/apt-pkg/crc-16.opic differ
Files apt/obj/apt-pkg/debindexfile.opic and apt-HEAD/obj/apt-pkg/debindexfile.opic differ
Files apt/obj/apt-pkg/deblistparser.opic and apt-HEAD/obj/apt-pkg/deblistparser.opic differ
Files apt/obj/apt-pkg/debmetaindex.opic and apt-HEAD/obj/apt-pkg/debmetaindex.opic differ
Files apt/obj/apt-pkg/debrecords.opic and apt-HEAD/obj/apt-pkg/debrecords.opic differ
Files apt/obj/apt-pkg/debsrcrecords.opic and apt-HEAD/obj/apt-pkg/debsrcrecords.opic differ
Files apt/obj/apt-pkg/debsystem.opic and apt-HEAD/obj/apt-pkg/debsystem.opic differ
Files apt/obj/apt-pkg/debversion.opic and apt-HEAD/obj/apt-pkg/debversion.opic differ
Files apt/obj/apt-pkg/depcache.opic and apt-HEAD/obj/apt-pkg/depcache.opic differ
Files apt/obj/apt-pkg/dpkgpm.opic and apt-HEAD/obj/apt-pkg/dpkgpm.opic differ
Files apt/obj/apt-pkg/error.opic and apt-HEAD/obj/apt-pkg/error.opic differ
Files apt/obj/apt-pkg/fileutl.opic and apt-HEAD/obj/apt-pkg/fileutl.opic differ
Files apt/obj/apt-pkg/hashes.opic and apt-HEAD/obj/apt-pkg/hashes.opic differ
Files apt/obj/apt-pkg/indexfile.opic and apt-HEAD/obj/apt-pkg/indexfile.opic differ
Files apt/obj/apt-pkg/indexrecords.opic and apt-HEAD/obj/apt-pkg/indexrecords.opic differ
Files apt/obj/apt-pkg/init.opic and apt-HEAD/obj/apt-pkg/init.opic differ
Files apt/obj/apt-pkg/md5.opic and apt-HEAD/obj/apt-pkg/md5.opic differ
Files apt/obj/apt-pkg/mmap.opic and apt-HEAD/obj/apt-pkg/mmap.opic differ
Files apt/obj/apt-pkg/orderlist.opic and apt-HEAD/obj/apt-pkg/orderlist.opic differ
Files apt/obj/apt-pkg/packagemanager.opic and apt-HEAD/obj/apt-pkg/packagemanager.opic differ
Files apt/obj/apt-pkg/pkgcachegen.opic and apt-HEAD/obj/apt-pkg/pkgcachegen.opic differ
Files apt/obj/apt-pkg/pkgcache.opic and apt-HEAD/obj/apt-pkg/pkgcache.opic differ
Files apt/obj/apt-pkg/pkgrecords.opic and apt-HEAD/obj/apt-pkg/pkgrecords.opic differ
Files apt/obj/apt-pkg/pkgsystem.opic and apt-HEAD/obj/apt-pkg/pkgsystem.opic differ
Files apt/obj/apt-pkg/policy.opic and apt-HEAD/obj/apt-pkg/policy.opic differ
Files apt/obj/apt-pkg/progress.opic and apt-HEAD/obj/apt-pkg/progress.opic differ
Files apt/obj/apt-pkg/sha1.opic and apt-HEAD/obj/apt-pkg/sha1.opic differ
Files apt/obj/apt-pkg/sourcelist.opic and apt-HEAD/obj/apt-pkg/sourcelist.opic differ
Files apt/obj/apt-pkg/srcrecords.opic and apt-HEAD/obj/apt-pkg/srcrecords.opic differ
Files apt/obj/apt-pkg/strutl.opic and apt-HEAD/obj/apt-pkg/strutl.opic differ
Files apt/obj/apt-pkg/tagfile.opic and apt-HEAD/obj/apt-pkg/tagfile.opic differ
Files apt/obj/apt-pkg/vendor.opic and apt-HEAD/obj/apt-pkg/vendor.opic differ
Files apt/obj/apt-pkg/versionmatch.opic and apt-HEAD/obj/apt-pkg/versionmatch.opic differ
Files apt/obj/apt-pkg/version.opic and apt-HEAD/obj/apt-pkg/version.opic differ

Reply to: