3 #include "zypp/base/Logger.h"
4 #include "zypp/repo/ServiceRepos.h"
5 #include "zypp/repo/RepoException.h"
6 #include "zypp/media/MediaException.h"
7 #include "zypp/parser/RepoFileReader.h"
8 #include "zypp/media/MediaManager.h"
9 #include "zypp/parser/RepoindexFileReader.h"
10 #include "zypp/ExternalProgram.h"
12 using std::stringstream;
15 ///////////////////////////////////////////////////////////////////
18 ///////////////////////////////////////////////////////////////////
21 struct ServiceRepos::Impl
22 { virtual ~Impl() {} };
24 ///////////////////////////////////////////////////////////////////
26 struct RIMServiceRepos : public ServiceRepos::Impl
28 RIMServiceRepos( const Pathname & /*root_r*/,
29 const ServiceInfo & service,
30 const ServiceRepos::ProcessRepo & callback,
31 const ProgressData::ReceiverFnc & progress = ProgressData::ReceiverFnc() )
33 // repoindex.xml must be fetched always without using cookies (bnc #573897)
34 Url serviceUrl( service.url() );
35 serviceUrl.setQueryParam( "cookies", "0" );
37 // download the repo index file
38 media::MediaManager mediamanager;
39 media::MediaAccessId mid = mediamanager.open( serviceUrl );
40 mediamanager.attach( mid );
41 mediamanager.provideFile( mid, "repo/repoindex.xml" );
42 Pathname path = mediamanager.localPath(mid, "repo/repoindex.xml" );
44 parser::RepoindexFileReader reader(path, callback);
45 service.setProbedTtl( reader.ttl() ); // hack! Modifying the const Service to set parsed TTL
46 mediamanager.release( mid );
47 mediamanager.close( mid );
48 } catch ( const Exception &e ) {
49 //Reader throws a bare exception, we need to translate it into something our calling
50 //code expects and handles (bnc#1116840)
52 ServicePluginInformalException ex ( e.msg() );
59 ///////////////////////////////////////////////////////////////////
61 struct PluginServiceRepos : public ServiceRepos::Impl
63 PluginServiceRepos( const Pathname & root_r,
64 const ServiceInfo & service,
65 const ServiceRepos::ProcessRepo & callback,
66 const ProgressData::ReceiverFnc & progress = ProgressData::ReceiverFnc() )
68 // bsc#1080693: Service script needs to be executed chrooted to the RepoManagers rootDir.
69 // The service is not aware of the rootDir, so it's explicitly passed and needs to be
70 // stripped from the URLs path.
73 ExternalProgram::Arguments args;
75 args.push_back( "/bin/sh" );
76 args.push_back( "-c" );
77 args.push_back( Pathname::stripprefix( root_r, service.url().getPathName() ).asString() );
78 ExternalProgramWithStderr prog( args, root_r );
81 if ( prog.close() != 0 )
83 // ServicePluginInformalException:
84 // Ignore this error but we'd like to report it somehow...
85 std::string errbuffer;
86 prog.stderrGetUpTo( errbuffer, '\0' );
87 ERR << "Capture plugin error:[" << endl << errbuffer << endl << ']' << endl;
88 ZYPP_THROW( repo::ServicePluginInformalException( service, errbuffer ) );
90 parser::RepoFileReader parser( buffer, callback );
94 ///////////////////////////////////////////////////////////////////
96 ServiceRepos::ServiceRepos( const Pathname & root_r,
97 const ServiceInfo & service,
98 const ServiceRepos::ProcessRepo & callback,
99 const ProgressData::ReceiverFnc &progress )
100 : _impl( ( service.type() == ServiceType::PLUGIN )
101 ? static_cast<ServiceRepos::Impl*>( new PluginServiceRepos( root_r, service, callback, progress ) )
102 : static_cast<ServiceRepos::Impl*>( new RIMServiceRepos( root_r, service, callback, progress ) ) )
105 ServiceRepos::~ServiceRepos()
109 ///////////////////////////////////////////////////////////////////
111 ///////////////////////////////////////////////////////////////////