#include <iostream>
#include <fstream>
-#include <zypp/base/Logger.h>
-#include <zypp/detail/MessageImpl.h>
-#include <zypp/Message.h>
-#include <zypp/parser/yum/YUMParser.h>
-#include <zypp/base/Logger.h>
#include <map>
-#include "zypp/source/yum/YUMSource.h"
-
+#include "zypp/base/Logger.h"
+#include "zypp/SourceFactory.h"
+#include "zypp/Source.h"
+#include "zypp/source/SourceImpl.h"
using namespace std;
using namespace zypp;
-using namespace zypp::source::yum;
-
/******************************************************************
**
int main( int argc, char * argv[] )
{
INT << "===[START]==========================================" << endl;
- YUMSource src;
-
- src.parseSourceMetadata("repodata");
-
+ SourceFactory _f;
+ Pathname p = "/";
+ Url url = Url("ftp://cml.suse.cz/netboot/find/SUSE-10.1-CD-OSS-i386-Alpha4-CD1");
+// Url url = Url("http://lide.suse.cz/~~jsrain/devel.jsrain");
+// Url url = Url("dir:/local/zypp/libzypp/devel/devel.jsrain");
+ Source s = _f.createFrom( url, p );
+ ResStore store = s.resolvables();
+ for (ResStore::const_iterator it = store.begin();
+ it != store.end(); it++)
+ {
+ ERR << **it << endl;
+ }
+ ERR << store << endl;
INT << "===[END]============================================" << endl;
return 0;
}
*
*/
#include <iostream>
+#include <fstream>
#include "zypp/base/Logger.h"
#include "zypp/base/Exception.h"
+#include "zypp/base/String.h"
#include "zypp/SourceFactory.h"
#include "zypp/source/Builtin.h"
+#include "zypp/media/MediaAccess.h"
using std::endl;
+using namespace zypp::source;
///////////////////////////////////////////////////////////////////
namespace zypp
return Source( impl_r );
}
+
+ void SourceFactory::listProducts( const Url & url_r, ProductSet & products_r )
+ {
+ if (! url_r.isValid())
+ ZYPP_THROW( Exception("Empty URL passed to SourceFactory") );
+
+ // open the media
+ media::MediaAccess::Ptr media = new media::MediaAccess();
+ media->open( url_r );
+ media->attach();
+ Pathname products_file = Pathname("media.1/products");
+ media->provideFile (products_file);
+ products_file = media->localPath (products_file);
+ scanProductsFile (products_file, products_r);
+ media->release();
+ media->close();
+ }
+
+ Source SourceFactory::createFrom( const Url & url_r, const Pathname & path_r )
+ {
+ if (! url_r.isValid())
+ ZYPP_THROW( Exception("Empty URL passed to SourceFactory") );
+
+ // open the media
+ media::MediaAccess::Ptr media;
+ try {
+ media = new media::MediaAccess();
+ media->open( url_r );
+ media->attach();
+ try
+ {
+ MIL << "Trying the YUM source" << endl;
+ Source::Impl_Ptr impl = new yum::YUMSourceImpl(media, path_r);
+ERR << "Impl created" << endl;
+ return Source(impl);
+ }
+ catch (const Exception & excpt_r)
+ {
+ ZYPP_CAUGHT(excpt_r);
+ WAR << "Not YUM source, trying next type" << endl;
+ }
+ catch (...)
+ {
+ INT << "Unknown exception" << endl;
+ }
+ try
+ {
+ MIL << "Trying the SUSE tags source" << endl;
+ Source::Impl_Ptr impl = new susetags::SuseTagsImpl(media, path_r);
+ return Source(impl);
+ }
+ catch (const Exception & excpt_r)
+ {
+ ZYPP_CAUGHT(excpt_r);
+ WAR << "Not SUSE tags source, trying next type" << endl;
+ }
+ }
+ catch (const media::MediaException & excpt_r)
+ {
+ ZYPP_CAUGHT(excpt_r);
+ }
+ catch (const Exception & excpt_r)
+ {
+ ZYPP_CAUGHT(excpt_r);
+ }
+ ZYPP_THROW(Exception("Cannot create the installatino source"));
+ }
/******************************************************************
**
return str << "SourceFactory";
}
+ void SourceFactory::scanProductsFile( const Pathname & file_r, ProductSet & pset_r ) const
+ {
+ std::ifstream pfile( file_r.asString().c_str() );
+ while ( pfile.good() ) {
+
+ std::string value = str::getline( pfile, str::TRIM );
+ if ( pfile.bad() ) {
+ ERR << "Error parsing " << file_r << endl;
+ ZYPP_THROW(Exception("Error parsing " + file_r.asString()));
+ }
+ if ( pfile.fail() ) {
+ break; // no data on last line
+ }
+ std::string tag = str::stripFirstWord( value, true );
+
+ if ( tag.size() ) {
+ pset_r.insert( ProductEntry( tag, value ) );
+ }
+ }
+ }
+
+
+
/////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////
#include "zypp/base/PtrTypes.h"
#include "zypp/Source.h"
+#include "zypp/Url.h"
+#include "zypp/Pathname.h"
///////////////////////////////////////////////////////////////////
namespace zypp
*/
Source createFrom( const Source::Impl_Ptr & impl_r );
+ /** Construct source from an implementation.
+ * \throw EXCEPTION on fail
+ */
+ Source createFrom( const Url & url_r, const Pathname & path_r = "/" );
+
private:
/** Implementation */
class Impl;
/** Pointer to implementation */
RW_pointer<Impl> _pimpl;
+
+ public:
+ struct ProductEntry {
+ Pathname _dir;
+ std::string _name;
+ ProductEntry( const Pathname & dir_r = "/", const std::string & name_r = std::string() ){
+ _dir = dir_r;
+ _name = name_r;
+ }
+ bool operator<( const ProductEntry & rhs ) const {
+ return( _dir.asString() < rhs._dir.asString() );
+ }
+ };
+
+ typedef std::set<ProductEntry> ProductSet;
+
+ /** Check which products are available on the media
+ * \throw Exception or MediaException on fail
+ */
+ void listProducts( const Url & url_r, ProductSet & products_r );
+
+ private:
+ void scanProductsFile( const Pathname & file_r, ProductSet & pset_r ) const;
};
///////////////////////////////////////////////////////////////////
return ret;
}
+ /******************************************************************
+ **
+ ** FUNCTION NAME : stripFirstWord
+ ** FUNCTION TYPE : std::string
+ **
+ ** DESCRIPTION :
+ */
+ std::string stripFirstWord( std::string & line, const bool ltrim_first )
+ {
+ if ( ltrim_first )
+ line = ltrim( line );
+
+ if ( line.empty() )
+ return line;
+
+ std::string ret;
+ std::string::size_type p = line.find_first_of( " \t" );
+
+ if ( p == std::string::npos ) {
+ // no ws on line
+ ret = line;
+ line.erase();
+ } else if ( p == 0 ) {
+ // starts with ws
+ // ret remains empty
+ line = ltrim( line );
+ }
+ else {
+ // strip word and ltim line
+ ret = line.substr( 0, p );
+ line = ltrim( line.erase( 0, p ) );
+ }
+ return ret;
+ }
+
+ /******************************************************************
+ **
+ **
+ ** FUNCTION NAME : getline
+ ** FUNCTION TYPE : std::string
+ **
+ ** DESCRIPTION :
+ */
+ static inline std::string _getline( std::istream & str, const Trim trim_r )
+ {
+ const unsigned tmpBuffLen = 1024;
+ char tmpBuff[tmpBuffLen];
+
+ std::string ret;
+ do {
+ str.clear();
+ str.getline( tmpBuff, tmpBuffLen ); // always writes '\0' terminated
+ ret += tmpBuff;
+ } while( str.rdstate() == std::ios::failbit );
+
+ return trim( ret, trim_r );
+ }
+
+ std::string getline( std::istream & str, const Trim trim_r )
+ {
+ return _getline(str, trim_r);
+ }
+
+ std::string getline( std::istream & str, bool trim )
+ {
+ return _getline(str, trim?TRIM:NO_TRIM);
+ }
+
+
/////////////////////////////////////////////////////////////////
} // namespace str
{ return trim( s, R_TRIM ); }
//@}
+ std::string stripFirstWord( std::string & line, const bool ltrim_first );
+
+ std::string getline( std::istream & str, bool trim = false );
+
+ std::string getline( std::istream & str, const Trim trim_r );
+
/////////////////////////////////////////////////////////////////
} // namespace str
///////////////////////////////////////////////////////////////////
#include "zypp/media/MediaException.h"
#include "zypp/Url.h"
+#include "zypp/base/Logger.h"
namespace zypp {
namespace media {
std::ostream& operator<<(std::ostream &out, const YUMRepomdData& data);
std::ostream& operator<<(std::ostream &out, const YUMPrimaryData& data);
std::ostream& operator<<(std::ostream &out, const YUMGroupData& data);
+ std::ostream& operator<<(std::ostream &out, const YUMPatternData& data);
std::ostream& operator<<(std::ostream &out, const YUMFileListData& data);
std::ostream& operator<<(std::ostream& out, const YUMOtherData& data);
std::ostream& operator<<(std::ostream& out, const YUMPatchData& data);
/**
*
- * @short Parser for YUM group files.
+ * @short Parser for YUM pattern files.
*
* Use this class as an iterator that produces, one after one,
- * YUMPatternData_Ptr(s) for the XML group elements.
+ * YUMPatternData_Ptr(s) for the XML pattern elements.
* Here's an example:
*
* for (YUMPatternParser iter(anIstream, baseUrl),
// METHOD NAME : SourceImpl::SourceImpl
// METHOD TYPE : Ctor
//
- SourceImpl::SourceImpl()
+ SourceImpl::SourceImpl(media::MediaAccess::Ptr & media_r,
+ const Pathname & path_r)
+ : _media (media_r)
+ , _path(path_r)
{}
///////////////////////////////////////////////////////////////////
SourceImpl::~SourceImpl()
{}
+ const Pathname SourceImpl::provideFile(const Pathname & file_r)
+ {
+ _media->provideFile (file_r);
+ return _media->localPath (file_r);
+ }
+
/////////////////////////////////////////////////////////////////
} // namespace source
///////////////////////////////////////////////////////////////////
#include "zypp/base/PtrTypes.h"
#include "zypp/ResStore.h"
+#include "zypp/Pathname.h"
+#include "zypp/media/MediaAccess.h"
+
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
friend std::ostream & operator<<( std::ostream & str, const SourceImpl & obj );
public:
+ /** Ctor, FIXME it is here only because of target storage */
+ SourceImpl()
+ {}
/** Ctor. */
- SourceImpl();
+ SourceImpl(media::MediaAccess::Ptr & media_r,
+ const Pathname & path_r = "/");
/** Dtor. */
virtual ~SourceImpl();
const ResStore & resolvables() const
{ return _store; }
+ /** Provide a file to local filesystem */
+ const Pathname provideFile(const Pathname & file);
+
/** Overload to realize stream output. */
virtual std::ostream & dumpOn( std::ostream & str ) const
{ return str << "SourceImpl"; }
protected:
/** All resolvables provided by this source. */
ResStore _store;
+ /** Handle to media which contains this source */
+ media::MediaAccess::Ptr _media;
+ /** Path to the source on the media */
+ Pathname _path;
};
///////////////////////////////////////////////////////////////////
// METHOD NAME : SuseTagsImpl::SuseTagsImpl
// METHOD TYPE : Ctor
//
- SuseTagsImpl::SuseTagsImpl( const Pathname & localDir_r )
+ SuseTagsImpl::SuseTagsImpl( media::MediaAccess::Ptr & media_r, const Pathname & path_r )
+ : SourceImpl(media_r, path_r)
{
- PathInfo p( localDir_r );
+ Pathname p = provideFile(path_r + "suse/setup/descr/packages");
+/* PathInfo p( localDir_r );
if ( p.isDir() )
p( localDir_r + "packages" );
if ( ! p.isFile() )
ZYPP_THROW( Exception( p.asString()+" is not a file" ) );
if ( ! p.userMayR() )
ZYPP_THROW( Exception( p.asString()+" no permission to read" ) );
-
+*/
DBG << "Going to parse " << p << endl;
- std::list<Package::Ptr> content( parsePackages( p.path() ) );
+ std::list<Package::Ptr> content( parsePackages( p ) );
_store.insert( content.begin(), content.end() );
- DBG << "SuseTagsImpl (fake) from " << p.path() << ": "
+ DBG << "SuseTagsImpl (fake) from " << p << ": "
<< content.size() << " packages" << endl;
}
/** \deprecated Interim ctor
* \throw EXCEPTION on parse error
*/
- SuseTagsImpl( const Pathname & localDir_r );
+ SuseTagsImpl( media::MediaAccess::Ptr & media_r, const Pathname & path_r = "/" );
/** Dtor */
~SuseTagsImpl();
/** Default ctor
*/
- YUMSourceImpl::YUMSourceImpl()
- {}
-
- void YUMSourceImpl::parseSourceMetadata(std::string path)
+ YUMSourceImpl::YUMSourceImpl(media::MediaAccess::Ptr & media_r,
+ const Pathname & path_r)
+ : SourceImpl(media_r, path_r)
{
std::list<YUMRepomdData_Ptr> repo_primary;
std::list<YUMRepomdData_Ptr> repo_files;
try {
// first read list of all files in the reposotory
- std::string filename = path + "/repmod.xml";
+ Pathname filename = provideFile(path_r + "/repomd.xml");
DBG << "Reading file " << filename << endl;
- ifstream repo_st(filename.c_str());
+ ifstream repo_st(filename.asString().c_str());
YUMRepomdParser repomd(repo_st, "");
for(;
repo_other.push_back(*repomd);
else if ((*repomd)->type == "group")
repo_group.push_back(*repomd);
+ else if ((*repomd)->type == "pattern")
+ repo_pattern.push_back(*repomd);
else if ((*repomd)->type == "product")
repo_product.push_back(*repomd);
else if ((*repomd)->type == "patches")
catch (...)
{
ERR << "Cannot read repomd file, cannot initialize source" << endl;
-// ZYPP_THROW( Exception("Cannot read repomd file, cannot initialize source") );
+ ZYPP_THROW( Exception("Cannot read repomd file, cannot initialize source") );
}
try {
// now put other and filelist data to structures for easier find
it++)
{
// TODO check checksum
- string filename = (*it)->location;
+ Pathname filename = provideFile(path_r + (*it)->location);
DBG << "Reading file " << filename << endl;
- ifstream st(filename.c_str());
+ ifstream st(filename.asString().c_str());
YUMFileListParser filelist(st, "");
for (;
! filelist.atEnd();
it++)
{
// TODO check checksum
- string filename = (*it)->location;
+ Pathname filename = provideFile(path_r + (*it)->location);
DBG << "Reading file " << filename << endl;
- ifstream st(filename.c_str());
+ ifstream st(filename.asString().c_str());
YUMOtherParser other(st, "");
for (;
! other.atEnd();
it++)
{
// TODO check checksum
- string filename = (*it)->location;
+ Pathname filename = provideFile(path_r + (*it)->location);
DBG << "Reading file " << filename << endl;
- ifstream st(filename.c_str());
+ ifstream st(filename.asString().c_str());
YUMPrimaryParser prim(st, "");
for (;
!prim.atEnd();
it++)
{
// TODO check checksum
- string filename = (*it)->location;
+ Pathname filename = provideFile(path_r + (*it)->location);
DBG << "Reading file " << filename << endl;
- ifstream st(filename.c_str());
+ ifstream st(filename.asString().c_str());
YUMGroupParser group(st, "");
for (;
!group.atEnd();
it++)
{
// TODO check checksum
- string filename = (*it)->location;
+ Pathname filename = provideFile(path_r + (*it)->location);
DBG << "Reading file " << filename << endl;
- ifstream st(filename.c_str());
+ ifstream st(filename.asString().c_str());
YUMPatternParser pattern(st, "");
for (;
!pattern.atEnd();
it++)
{
// TODO check checksum
- string filename = (*it)->location;
+ Pathname filename = provideFile(path_r + (*it)->location);
DBG << "Reading file " << filename << endl;
- ifstream st(filename.c_str());
+ ifstream st(filename.asString().c_str());
YUMProductParser product(st, "");
for (;
!product.atEnd();
it++)
{
// TODO check checksum
- string filename = (*it)->location;
+ Pathname filename = provideFile(path_r + (*it)->location);
DBG << "Reading file " << filename << endl;
- ifstream st(filename.c_str());
+ ifstream st(filename.asString().c_str());
YUMPatchesParser patch(st, "");
for (;
!patch.atEnd();
it != patch_files.end();
it++)
{
- std::string filename = *it;
+ Pathname filename = provideFile(path_r + *it);
DBG << "Reading file " << filename << endl;
- ifstream st(filename.c_str());
+ ifstream st(filename.asString().c_str());
YUMPatchParser ptch(st, "");
for(;
!ptch.atEnd();
class YUMSourceImpl : public SourceImpl
{
public:
+ /** Ctor, FIXME it is here only because of target storage */
+ YUMSourceImpl()
+ {}
/** Default ctor */
- YUMSourceImpl();
-
- void parseSourceMetadata(std::string path);
+ YUMSourceImpl(media::MediaAccess::Ptr & media_r, const Pathname & path_r = "/");
Package::Ptr createPackage(
const zypp::parser::yum::YUMPrimaryData & parsed,