monday progres...
authorDuncan Mac-Vicar P <dmacvicar@suse.de>
Mon, 10 Jul 2006 16:32:19 +0000 (16:32 +0000)
committerDuncan Mac-Vicar P <dmacvicar@suse.de>
Mon, 10 Jul 2006 16:32:19 +0000 (16:32 +0000)
YUMSOurceCacher downloads metadata,
using MediaSetAccess, trying to
connect it with the source cache now
and parse it with sax

12 files changed:
zypp/MediaSetAccess.cc
zypp/MediaSetAccess.h
zypp/cache/SourceCache.cpp
zypp/cache/SourceCache.h
zypp/cache/SourceCacheInitializer.cpp
zypp/data/ResolvableData.cc
zypp/data/ResolvableData.h
zypp/parser/Makefile.am
zypp/parser/SAXParser.cc [new file with mode: 0644]
zypp/parser/SAXParser.h [new file with mode: 0644]
zypp/source/yum/YUMSourceCacher.cc
zypp/source/yum/YUMSourceCacher.h

index 811c6e09f0fc84743f6c8415c373cfa730569ba9..ca26bfb4a8dcc727d6e7cff7b1a97e65349e3b9a 100644 (file)
@@ -16,7 +16,7 @@
 #include "zypp/PathInfo.h"
 //#include "zypp/source/MediaSetAccessReportReceivers.h"
 
-using std::endl;
+using namespace std;
 
 ///////////////////////////////////////////////////////////////////
 namespace zypp
@@ -43,6 +43,11 @@ namespace zypp
     }
   }
 
+  bool NullFileChecker::operator()(const Pathname &file )
+  {
+    return true;
+  }
+
   MediaSetAccess::MediaSetAccess(  const Url &url, const Pathname &path )
       : _url(url),
         _path(path)
@@ -72,12 +77,35 @@ namespace zypp
 //       report->finish( file_url, source::DownloadFileReport::NO_ERROR, "" );
 //       return file;
 
-  const Pathname MediaSetAccess::provideFile(const Pathname & file, const unsigned media_nr )
+
+  void MediaSetAccess::providePossiblyCachedMetadataFile( const Pathname &file_to_download, unsigned medianr, const Pathname &destination, const Pathname &cached_file, const CheckSum &checksum )
+  {
+    Url file_url( _url.asString() + file_to_download.asString() );
+    // if we have a cached file and its the same
+    if ( PathInfo(cached_file).isExist() && (! checksum.empty()) && is_checksum( cached_file, checksum ) )
+    {
+      MIL << "file " << file_url << " found in previous cache. Using cached copy." << std::endl;
+      // checksum is already checked.
+      // we could later implement double failover and try to download if file copy fails.
+      if ( filesystem::copy(cached_file, destination) != 0 )
+        ZYPP_THROW(Exception("Can't copy " + cached_file.asString() + " to " + destination.asString()));
+    }
+    else
+    {
+      // we dont have it or its not the same, download it.
+      Pathname downloaded_file = provideFile( file_to_download, medianr, ChecksumFileChecker(checksum) );
+      
+      if ( filesystem::copy(downloaded_file, destination) != 0 )
+        ZYPP_THROW(Exception("Can't copy " + downloaded_file.asString() + " to " + destination.asString()));      
+    }
+  }
+
+  Pathname MediaSetAccess::provideFile(const Pathname & file, unsigned media_nr )
   {
     return provideFileInternal( file, media_nr, false, false);
   }
 
-  const Pathname  MediaSetAccess::provideFile(const Pathname & file, const unsigned media_nr, FileChecker checker )
+  Pathname  MediaSetAccess::provideFile(const Pathname & file, unsigned media_nr, FileChecker checker )
   {
     Pathname p = provideFileInternal( file, media_nr, false, false);
     
@@ -88,7 +116,7 @@ namespace zypp
     return p;
   }
 
-  const Pathname MediaSetAccess::provideFileInternal(const Pathname & file, const unsigned media_nr, bool cached, bool checkonly )
+  Pathname MediaSetAccess::provideFileInternal(const Pathname & file, unsigned media_nr, bool cached, bool checkonly )
   {
     callback::SendReport<media::MediaChangeReport> report;
     media::MediaManager media_mgr;
index 21e2198b799c99314f9ec2575e6ab3323487ec6e..846be755d12806e37c00d928564af87b029a790e 100644 (file)
@@ -13,6 +13,7 @@
 #include <iosfwd>
 #include <string>
 #include <vector>
+#include <boost/function.hpp>
 
 #include "zypp/base/ReferenceCounted.h"
 #include "zypp/base/NonCopyable.h"
@@ -58,8 +59,7 @@ namespace zypp
     class NullFileChecker
     {
       public:
-      bool operator()( const Pathname &file )
-      { return true; }
+      bool operator()( const Pathname &file );
     };
 
     class ChecksumFileChecker
@@ -90,10 +90,11 @@ namespace zypp
        * the media change callbacks depend on the verifiers given for each media.
        */
       void setVerifiers( const std::vector<media::MediaVerifierRef> &verifiers );
-      const Pathname provideFile(const Pathname & file, const unsigned media_nr = 1 );
-      const Pathname provideFile(const Pathname & file, const unsigned media_nr, const FileChecker checker );
+      Pathname provideFile(const Pathname & file, unsigned media_nr = 1 );
+      Pathname provideFile(const Pathname & file, unsigned media_nr, const FileChecker checker );
+      void providePossiblyCachedMetadataFile( const Pathname &file_to_download, unsigned medianr, const Pathname &destination, const Pathname &cached_file, const CheckSum &checksum );
     protected:
-      const Pathname provideFileInternal(const Pathname & file, const unsigned media_nr, bool checkonly, bool cached);
+      Pathname provideFileInternal(const Pathname & file, unsigned media_nr, bool checkonly, bool cached);
       Url rewriteUrl (const Url & url_r, const media::MediaNr medianr);
       media::MediaAccessId getMediaAccessId (media::MediaNr medianr);
       virtual std::ostream & dumpOn( std::ostream & str ) const;
index bf07261a2321ae0b2cb575b255bdef2c5e557611..b9f3672bc6ff42aaee7b825bfc526c2c7f7d291e 100644 (file)
@@ -49,6 +49,11 @@ SourceCache::~SourceCache()
   _con->close();
 }
 
+void SourceCache::cachePackage( const data::Package package )
+{
+  MIL << "caching: " << package << std::endl;
+}
+
 void SourceCache::cachePattern( const data::Pattern pattern )
 {
 
index 86b92f9e1c8532bf52ea36c1a5ac78a3a50ebf5b..6c557ea6b800326a2eb66ffa13f83ecc0d7f4035 100644 (file)
@@ -45,6 +45,7 @@ namespace zypp
       SourceCache( const Pathname &root_r, const std::string alias );
       ~SourceCache();
       void cachePattern( const data::Pattern pattern );
+      void cachePackage( const data::Package package );
     protected:
       void cacheResolvable( const data::ResObject );
       /** Overload to realize stream output. */
index 9c9260f1c34bbab55075f47b6a1fcc49cba34619..1a596246007716d1f11c774ebca66b9898e22c4d 100644 (file)
@@ -27,8 +27,10 @@ namespace zypp
 namespace cache
 { /////////////////////////////////////////////////////////////////
   
-#define SOURCES_TABLE_SCHEMA "create table sources ( alias varchar primary key, type varchar, description varchar,  url varchar, path varchar,  enabled integer, autorefresh integer, timestamp varchar, checksum varchar);"
-// alias 0 , type 1, desc 2, url 3, path 4, enabled 5, autorefresh 6, timestamp 7, checksum 8
+
+static const char * SOURCES_TABLE_SCHEMA = "create table sources ( id integer primary key autoincrement, alias varchar unique, type varchar, description varchar,  url varchar, path varchar,  enabled integer, autorefresh integer, timestamp varchar, checksum varchar);";
+
+// id 0, alias 1 , type 2, desc 3, url 4, path 5, enabled 6, autorefresh 7, timestamp 8, checksum 9
   
 SourceCacheInitializer::SourceCacheInitializer( const Pathname &root_r, const Pathname &db_file )
   : _root(root_r), _just_initialized(false)
index 8e176705a98eecb95525c18df52bb16cfd186b66..3a6bc31a56d3b4e8980cd1aab64287e4f845584a 100644 (file)
@@ -28,23 +28,23 @@ IMPL_PTR_TYPE(Message);
 IMPL_PTR_TYPE(Selection);  
 IMPL_PTR_TYPE(Pattern);
   
-/*
+
 std::ostream& operator<<(std::ostream& out, const ResObject &data)
 {
-       out << "Script Data: " << endl
-      << "  name: " << data.name << endl
-      << "  edition: " << data.edition << endl
-      << "  provides: " << data.provides << endl
-      << "  conflicts: " << data.conflicts << endl
-      << "  obsoletes: " << data.obsoletes << endl
-      << "  freshens: " << data.freshens << endl
-      << "  requires: " << data.requires << endl
-      << "  recommends:" << endl << data.recommends << endl
-      << "  suggests:" << endl << data.suggests << endl
-      << "  supplements:" << endl << data.supplements << endl
-      << "  enhances:" << endl << data.enhances << endl
+      out << "[ " << data.name << " " << data.edition << " ]" << endl;
+      return out;
+//       << "  provides: " << data.provides << endl
+//       << "  conflicts: " << data.conflicts << endl
+//       << "  obsoletes: " << data.obsoletes << endl
+//       << "  freshens: " << data.freshens << endl
+//       << "  requires: " << data.requires << endl
+//       << "  recommends:" << endl << data.recommends << endl
+//       << "  suggests:" << endl << data.suggests << endl
+//       << "  supplements:" << endl << data.supplements << endl
+//       << "  enhances:" << endl << data.enhances << endl
 }
 
+/*
 std::ostream& operator<<(std::ostream& out, const zypp::shared_ptr<AtomBase> data)
 {
   out << "Atom data" << endl;
@@ -70,7 +70,7 @@ std::ostream& operator<<(std::ostream& out, const zypp::shared_ptr<AtomBase> dat
   
 std::ostream& operator<<(std::ostream& out, const Script& data)
 {
-      << "  do script: " << data.do_script << endl
+      out << "  do script: " << data.do_script << endl
       << "  undo script: " << data.undo_script << endl
       << "  do script location: " << data.do_location << endl
       << "  undo script location: " << data.undo_location << endl
index 31c155c879cd4774315780b0d5fc4b0f9a074024..c2ee38f65837d9f58bbbe98cc9bfa04eafe041dc 100644 (file)
@@ -16,6 +16,9 @@
 #include "zypp/Pathname.h"
 #include "zypp/Edition.h"
 #include "zypp/Arch.h"
+#include "zypp/CheckSum.h"
+#include "zypp/Url.h"
+#include "zypp/Date.h"
 #include "zypp/TranslatedText.h"
 #include <string>
 #include <list>
@@ -107,6 +110,12 @@ namespace data
       //std::list<PackageReq> packageList;
   };
 
+  class Patch : public ResObject
+  {
+    public:
+      Patch() {};
+  };
+
   class Pattern : public ResObject
   {
     public:
@@ -133,10 +142,41 @@ namespace data
         // those are suse specific tags
       std::string releasenotesurl;
   };
+
+  class Package : public ResObject
+  {
+    public:
+      Package() {};
+      ~Package() {};
+
+      std::string type;
+      CheckSum checksum;
+      std::string packager;
+      Url url;
+      unsigned int archive_size;
+      unsigned int installed_size;
+      Date build_time;
+      Pathname location;
+      std::string license;
+      std::string vendor;
+      std::string group;
+      std::string buildhost;
+      
+      //std::list<FileData> files;
+
+      // SuSE specific data
+      std::list<std::string> authors;
+      std::list<std::string> keywords;
+      //std::string  media;
+      //std::list<YUMDirSize> dirSizes;
+      //bool installOnly;
+      //TranslatedText license_to_confirm;
+  };
   
   /* Easy output */
 //   std::ostream& operator<<(std::ostream &out, const Dependency& data);
-//   std::ostream& operator<<(std::ostream &out, const ResObject& data);
+   std::ostream& operator<<(std::ostream &out, const ResObject& data);
+   //std::ostream& operator<<(std::ostream &out, const Package& data);
 //   std::ostream& operator<<(std::ostream &out, const Product& data);
 //   std::ostream& operator<<(std::ostream &out, const Pattern& data);
 //   std::ostream& operator<<(std::ostream &out, const Selection& data);
index b88161c87f4039004fd34ba163a2609eebe1eff4..f9db48ed60d2a58d2d51fe0e17cc14b5d5bb62e3 100644 (file)
@@ -12,6 +12,7 @@ parserincludedir = $(pkgincludedir)/parser
 
 parserinclude_HEADERS = \
        XMLNodeIterator.h       \
+       SAXParser.h     \
        LibXMLHelper.h          \
        xml_parser_assert.h
 
@@ -22,7 +23,8 @@ noinst_LTLIBRARIES =  lib@PACKAGE@_parser.la
 
 lib@PACKAGE@_parser_la_SOURCES = \
        XMLNodeIterator.cc      \
-       LibXMLHelper.cc
+       LibXMLHelper.cc \
+       SAXParser.cc
 
 lib@PACKAGE@_parser_la_LIBADD =        yum/lib@PACKAGE@_parser_yum.la  \
                                -lxml2  \
diff --git a/zypp/parser/SAXParser.cc b/zypp/parser/SAXParser.cc
new file mode 100644 (file)
index 0000000..bba14cc
--- /dev/null
@@ -0,0 +1,200 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <streambuf>
+
+#include <zypp/parser/SAXParser.h>
+#include <zypp/base/Logger.h>
+
+namespace zypp
+{
+namespace parser
+{
+
+static xmlSAXHandler emptySAXHandlerStruct = {
+    NULL, /* internalSubset */
+    NULL, /* isStandalone */
+    NULL, /* hasInternalSubset */
+    NULL, /* hasExternalSubset */
+    NULL, /* resolveEntity */
+    NULL, /* getEntity */
+    NULL, /* entityDecl */
+    NULL, /* notationDecl */
+    NULL, /* attributeDecl */
+    NULL, /* elementDecl */
+    NULL, /* unparsedEntityDecl */
+    NULL, /* setDocumentLocator */
+    NULL, /* startDocument */
+    NULL, /* endDocument */
+    NULL, /* startElement */
+    NULL, /* endElement */
+    NULL, /* reference */
+    NULL, /* characters */
+    NULL, /* ignorableWhitespace */
+    NULL, /* processingInstruction */
+    NULL, /* comment */
+    NULL, /* xmlParserWarning */
+    NULL, /* xmlParserError */
+    NULL, /* xmlParserError */
+    NULL, /* getParameterEntity */
+    NULL, /* cdataBlock; */
+    NULL,  /* externalSubset; */
+    1
+};
+
+static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
+extern xmlSAXHandlerPtr debugSAXHandler;
+
+/**
+ * startElementDebug:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
+{
+    int i;
+
+    fprintf(stdout, "SAX.startElement(%s", (char *) name);
+    if (atts != NULL) {
+        for (i = 0;(atts[i] != NULL);i++) {
+      fprintf(stdout, ", %s='", atts[i++]);
+      if (atts[i] != NULL)
+          fprintf(stdout, "%s'", atts[i]);
+  }
+    }
+    fprintf(stdout, ")\n");
+}
+
+static xmlEntityPtr
+my_getEntity(void *user_data, const xmlChar *name)
+{
+  return xmlGetPredefinedEntity(name);
+}
+
+static void
+endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+    fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
+}
+
+void
+SAXParser::startElement_receiver(void *ctx, const xmlChar *name, const xmlChar **atts)
+{
+  SAXParser *rcv = (SAXParser *)(ctx);
+  if ( rcv )
+    rcv->startElement(std::string( (const char*) name), atts);
+}
+
+void
+SAXParser::characters_receiver (void *ctx, const xmlChar *ch, int len)
+{
+  SAXParser *rcv = (SAXParser *)(ctx);
+  if ( rcv )
+    rcv->characters( ch, len);
+}
+
+void
+SAXParser::endElement_receiver(void *ctx, const xmlChar *name)
+{
+  SAXParser *rcv = (SAXParser *)(ctx);
+  if ( rcv )
+    rcv->endElement(std::string( (const char*) name));
+}
+
+static xmlEntityPtr getEntity_receiver(void *user_data, const xmlChar *name)
+{
+    return xmlGetPredefinedEntity(name);
+}
+
+
+void SAXParser::startElement(const std::string name, const xmlChar **atts)
+{
+  MIL << "start-element:" <<  name << std::endl;
+}
+
+void SAXParser::endElement(const std::string name)
+{
+  MIL << "end-element:" << name << std::endl;
+}
+
+void SAXParser::characters(const xmlChar *ch, int len)
+{
+  MIL << "characters:" << std::string( (const char *)ch, len) << std::endl;
+}
+
+void SAXParser::parseFile( const Pathname &p)
+{
+  FILE *f = fopen(p.asString().c_str(), "r");
+  if (f != NULL)
+  {
+    int res = xmlSAXUserParseFile(&_saxHandler, (void *) this, p.asString().c_str());
+    if (res != 0)
+    {
+      fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
+    }
+    fclose(f);
+  }
+  else
+  {
+    fprintf(stdout, "UPS\n");
+  }
+}
+
+SAXParser::SAXParser()
+{
+  _saxHandler.internalSubset = NULL;
+  _saxHandler.isStandalone = NULL;   
+  _saxHandler.hasInternalSubset = NULL;
+  _saxHandler.hasExternalSubset = NULL;
+  _saxHandler.resolveEntity = NULL;
+  _saxHandler.getEntity = NULL;
+  _saxHandler.entityDecl = NULL;
+  _saxHandler.notationDecl = NULL;
+  _saxHandler.attributeDecl = NULL;
+  _saxHandler.elementDecl = NULL;
+  _saxHandler.unparsedEntityDecl = NULL;
+  _saxHandler.setDocumentLocator = NULL;
+  _saxHandler.startDocument = NULL;
+  _saxHandler.endDocument = NULL;
+  _saxHandler.startElement = NULL;
+  _saxHandler.endElement = NULL;
+  _saxHandler.reference = NULL;
+  _saxHandler.characters = NULL;
+  _saxHandler.ignorableWhitespace = NULL;
+  _saxHandler.processingInstruction = NULL;
+  _saxHandler.comment = NULL;
+   
+  //_saxHandler.xmlParserWarning = NULL;
+  //_saxHandler.xmlParserError = NULL;
+  //_saxHandler.xmlParserError = NULL;
+  
+  _saxHandler.getParameterEntity = NULL;
+  _saxHandler.cdataBlock = NULL;
+  _saxHandler.externalSubset = NULL; 
+
+  _saxHandler = emptySAXHandlerStruct;
+  //_saxHandler.startDocument = startElement_receiver;
+ _saxHandler.startElement = startElement_receiver;
+ _saxHandler.endElement = endElement_receiver;
+ _saxHandler.getEntity = getEntity_receiver;
+  _saxHandler.characters = characters_receiver;
+}
+
+SAXParser::~SAXParser()
+{
+}
+
+} // ns parser
+} // ns zypp
\ No newline at end of file
diff --git a/zypp/parser/SAXParser.h b/zypp/parser/SAXParser.h
new file mode 100644 (file)
index 0000000..4436051
--- /dev/null
@@ -0,0 +1,53 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+
+#ifndef ZYPP_SAXParser_H
+#define ZYPP_SAXParser_H
+
+#include <iosfwd>
+#include <string>
+#include <vector>
+#include <libxml/parser.h>
+
+#include <boost/function.hpp>
+
+#include "zypp/Pathname.h"
+
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+namespace parser
+{ /////////////////////////////////////////////////////////////////
+
+  class SAXParser
+  {
+    public:
+
+    SAXParser();
+    virtual ~SAXParser();
+
+    void parseFile( const Pathname &p);
+
+    virtual void startElement(const std::string name, const xmlChar **atts);
+    virtual void endElement(const std::string name);
+    virtual void characters(const xmlChar *ch, int len);
+  
+    static void startElement_receiver(void *ctx, const xmlChar *name, const xmlChar **atts);
+    static void endElement_receiver(void *ctx, const xmlChar *name);
+    static void characters_receiver (void *data, const xmlChar *ch, int len);
+    private:
+    xmlSAXHandler _saxHandler;
+   
+  };
+
+} // namespace parser
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_SOURCE_SAXParser_H
index d9ced6d51da7be486b4cf1daa0c1e2b424eae1f8..a7645f2ca1ee69c2fb4b3ab0a866cd43beea7d6e 100644 (file)
@@ -7,11 +7,20 @@
 |                                                                      |
 \---------------------------------------------------------------------*/
 
+#include <fstream>
+
 #include "zypp/base/Logger.h"
+#include "zypp/MediaSetAccess.h"
 #include "zypp/cache/SourceCacher.h"
+
+#include "zypp/base/GzStream.h"
+#include "zypp/parser/yum/YUMParser.h"
+
+#include "zypp/parser/SAXParser.h"
 #include "zypp/source/yum/YUMSourceCacher.h"
 
 using namespace std;
+using namespace zypp::parser::yum;
 
 //////////////////////////////////////////////////////////////////
 namespace zypp
@@ -22,7 +31,52 @@ namespace yum
 { /////////////////////////////////////////////////////////////////
 
 
-YUMSourceCacher::YUMSourceCacher( const Pathname &root_r ) : cache::SourceCacher(root_r)
+class YUMPrimaryReader : public parser::SAXParser
+{
+  public:
+  YUMPrimaryReader( YUMSourceCacher &cacher )
+  {
+    _cacher.reset(&cacher);
+  }
+  
+  virtual void startElement(const std::string name, const xmlChar **atts)
+  {
+    if ( name == "package" )
+      _package.reset(new zypp::data::Package());
+  }
+
+  virtual void characters(const xmlChar *ch, int len)
+  {
+    _buffer.append( (const char *)ch, len);
+  }
+
+  virtual void endElement(const std::string name)
+  {
+    if ( name == "name" )
+      _package->name = popBuffer();
+    if ( name == "arch" )
+      _package->arch = Arch(popBuffer());
+
+    if ( name == "package" )
+    {
+      _cacher->packageParsed(*_package);
+    }
+  }
+  
+  std::string popBuffer()
+  {
+    std::string rt = _buffer;
+    _buffer.clear();
+    return rt;
+  }
+
+  private:
+  shared_ptr<zypp::data::Package> _package;
+  shared_ptr<YUMSourceCacher> _cacher;
+  std::string _buffer;
+};
+
+YUMSourceCacher::YUMSourceCacher( const Pathname &root_r ) : zypp::cache::SourceCacher(root_r)
 {
   
 }
@@ -31,6 +85,122 @@ YUMSourceCacher::~YUMSourceCacher()
 {
 }
 
+void YUMSourceCacher::packageParsed( const data::Package &package)
+{
+  MIL << "caching " << package << std::endl;
+}
+
+void YUMSourceCacher::cache( const Url &url, const Pathname &path )
+{
+  filesystem::TmpDir tmpdir = downloadMetadata(url, path);
+  YUMPrimaryReader reader(*this);
+  reader.parseFile( tmpdir.path() + "/repodata/primary.xml.gz");
+
+}
+
+filesystem::TmpDir YUMSourceCacher::downloadMetadata(const Url &url, const Pathname &path)
+{
+  filesystem::TmpDir tmpdir;
+  filesystem::TmpDir _cache_dir;
+
+  MediaSetAccess media(url, path);
+
+  int copy_result;
+  MIL << "Downloading metadata to " << tmpdir.path() << std::endl;
+
+  Pathname local_dir = tmpdir.path();
+  if (0 != assert_dir(local_dir + "/repodata" , 0755))
+    ZYPP_THROW(Exception("Cannot create /repodata in download directory"));
+
+  MIL << "Storing data to tmp dir " << local_dir << endl;
+
+  // first read list of all files in the repository
+  Pathname remote_repomd;
+  try
+  {
+    remote_repomd = media.provideFile( path + "/repodata/repomd.xml");
+  }
+  catch(Exception &e)
+  {
+    ZYPP_THROW(Exception("Can't provide " + path.asString() + "/repodata/repomd.xml from " + url.asString() ));
+  }
+
+  // provide optional files
+  //Pathname remote_repomd_key;
+  //Pathname remote_repomd_signature;
+  //try {
+  //  remote_repomd_key = tryToProvideFile( _path + "/repodata/repomd.xml.key");
+  //}
+  //catch( const Exception &e ) {
+  //  WAR << "Repository does not contain repomd signing key" << std::endl;
+  //}
+
+  //try {
+  //  remote_repomd_signature = tryToProvideFile( _path + "/repodata/repomd.xml.asc");
+  //}
+  //catch( const Exception &e ) {
+  //  WAR << "Repository does not contain repomd signature" << std::endl;
+  //}
+
+  copy_result = filesystem::copy( remote_repomd, local_dir + "/repodata/repomd.xml");
+  if ( copy_result != 0 )
+    ZYPP_THROW(Exception("Can't copy " + remote_repomd.asString() + " to " + local_dir.asString() + "/repodata/repomd.xml"));
+
+  //   if (PathInfo(remote_repomd_key).isExist())
+  //   {
+  //     copy_result = filesystem::copy( remote_repomd_key, local_dir + "/repodata/repomd.xml.key");
+  //     if ( copy_result != 0 )
+  //       ZYPP_THROW(Exception("Can't copy " + remote_repomd_key.asString() + " to " + local_dir.asString() + "/repodata/repomd.xml.key"));
+  //     getZYpp()->keyRing()->importKey(local_dir + "/repodata/repomd.xml.key" , false);
+  //   }
+  // 
+  //   if (PathInfo(remote_repomd_signature).isExist())
+  //   {
+  //     copy_result = filesystem::copy( remote_repomd_signature, local_dir + "/repodata/repomd.xml.asc");
+  //     if ( copy_result != 0 )
+  //       ZYPP_THROW(Exception("Can't copy " + remote_repomd_signature.asString() + " to " + local_dir.asString() + "/repodata/repomd.xml.asc"));
+  //   }
+
+  DBG << "Reading file " << remote_repomd << endl;
+  ifstream repo_st(remote_repomd.asString().c_str());
+  YUMRepomdParser repomd(repo_st, "");
+
+  for(; ! repomd.atEnd(); ++repomd)
+  {
+    if ((*repomd)->type == "other")     // don't parse 'other.xml' (#159316)
+      continue;
+
+    if ((*repomd)->type == "filelists")
+      continue;
+
+    media.providePossiblyCachedMetadataFile( path + (*repomd)->location, 1, local_dir + (*repomd)->location, _cache_dir + (*repomd)->location, CheckSum((*repomd)->checksumType, (*repomd)->checksum) );
+
+    // if it is a patch, we read the patches individually
+    if ((*repomd)->type == "patches")
+    {
+      // use the local copy now
+      Pathname patches_list = local_dir + (*repomd)->location;
+      MIL << "Reading patches file " << patches_list << std::endl;
+      ifgzstream st ( patches_list.asString().c_str() );
+      YUMPatchesParser patch(st, "");
+      for (; !patch.atEnd(); ++patch)
+      {
+
+        media.providePossiblyCachedMetadataFile( path + (*patch)->location, 1, local_dir + (*patch)->location, _cache_dir + (*patch)->location, CheckSum((*patch)->checksumType, (*patch)->checksum) );
+      } // end of single patch parsing
+    }// end of patches file parsing
+  } // end of copying
+
+  // check signature
+  //   MIL << "Checking [" << (local_dir + "/repodata/repomd.xml") << "] signature"  << endl;
+  //   if (! getZYpp()->keyRing()->verifyFileSignatureWorkflow(local_dir + "/repodata/repomd.xml", (_path + "/repodata/repomd.xml").asString()+ " (" + url().asString() + ")", local_dir + "/repodata/repomd.xml.asc"))
+  //     ZYPP_THROW(Exception(N_("Signed repomd.xml file fails signature check")));
+
+  // ok, now we have a consistent repo in the tmpdir.
+  return tmpdir;
+}
+
+
 std::ostream & YUMSourceCacher::dumpOn( std::ostream & str ) const
 {
   return str;
index 1283bf83047ad72ff87ef45959a9b7056a0a3d6d..1c2ce4a3fceff072806394577c041e313e539661 100644 (file)
@@ -14,7 +14,9 @@
 #include <string>
 
 #include "zypp/cache/SourceCacher.h"
+#include "zypp/data/ResolvableData.h"
 #include "zypp/Pathname.h"
+#include "zypp/TmpPath.h"
 
 ///////////////////////////////////////////////////////////////////
 namespace zypp
@@ -40,7 +42,11 @@ namespace zypp
       /** root path */
       YUMSourceCacher( const Pathname &root_r );
       ~YUMSourceCacher();
+      void cache( const Url &url, const Pathname &path );
+
+      void packageParsed( const data::Package &package);
     protected:
+      filesystem::TmpDir downloadMetadata(const Url &url, const Pathname &path);
 
       /** Overload to realize stream output. */
       virtual std::ostream & dumpOn( std::ostream & str ) const;