Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / repo / ServiceRepos.cc
1 #include <iostream>
2 #include <sstream>
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"
11
12 using std::stringstream;
13 using std::endl;
14
15 ///////////////////////////////////////////////////////////////////
16 namespace zypp
17 {
18   ///////////////////////////////////////////////////////////////////
19   namespace repo
20   {
21     struct ServiceRepos::Impl
22     { virtual ~Impl() {} };
23
24     ///////////////////////////////////////////////////////////////////
25
26     struct RIMServiceRepos : public ServiceRepos::Impl
27     {
28       RIMServiceRepos( const ServiceInfo & service,
29                        const ServiceRepos::ProcessRepo & callback,
30                        const ProgressData::ReceiverFnc & progress = ProgressData::ReceiverFnc() )
31       {
32         // repoindex.xml must be fetched always without using cookies (bnc #573897)
33         Url serviceUrl( service.url() );
34         serviceUrl.setQueryParam( "cookies", "0" );
35
36         // download the repo index file
37         media::MediaManager mediamanager;
38         media::MediaAccessId mid = mediamanager.open( serviceUrl );
39         mediamanager.attach( mid );
40         mediamanager.provideFile( mid, "repo/repoindex.xml" );
41         Pathname path = mediamanager.localPath(mid, "repo/repoindex.xml" );
42         parser::RepoindexFileReader reader(path, callback);
43         service.setProbedTtl( reader.ttl() );   // hack! Modifying the const Service to set parsed TTL
44         mediamanager.release( mid );
45         mediamanager.close( mid );
46       }
47     };
48
49     ///////////////////////////////////////////////////////////////////
50
51     struct PluginServiceRepos : public ServiceRepos::Impl
52     {
53       PluginServiceRepos( const ServiceInfo & service,
54                           const ServiceRepos::ProcessRepo & callback,
55                           const ProgressData::ReceiverFnc & progress = ProgressData::ReceiverFnc() )
56       {
57         Url serviceUrl( service.url() );
58         stringstream buffer;
59
60         ExternalProgram::Arguments args;
61         args.reserve( 3 );
62         args.push_back( "/bin/sh" );
63         args.push_back( "-c" );
64         args.push_back( serviceUrl.getPathName() );
65         ExternalProgramWithStderr prog( args );
66         prog >> buffer;
67
68         if ( prog.close() != 0 )
69         {
70           // ServicePluginInformalException:
71           // Ignore this error but we'd like to report it somehow...
72           std::string errbuffer;
73           prog.stderrGetUpTo( errbuffer, '\0' );
74           ERR << "Capture plugin error:[" << endl << errbuffer << endl << ']' << endl;
75           ZYPP_THROW( repo::ServicePluginInformalException( service, errbuffer ) );
76         }
77         parser::RepoFileReader parser( buffer, callback );
78       }
79     };
80
81     ///////////////////////////////////////////////////////////////////
82
83     ServiceRepos::ServiceRepos( const ServiceInfo & service,
84                                 const ServiceRepos::ProcessRepo & callback,
85                                 const ProgressData::ReceiverFnc &progress )
86     : _impl( ( service.type() == ServiceType::PLUGIN )
87            ? static_cast<ServiceRepos::Impl*>( new PluginServiceRepos( service, callback, progress ) )
88            : static_cast<ServiceRepos::Impl*>( new RIMServiceRepos (service, callback, progress ) ) )
89     {}
90
91     ServiceRepos::~ServiceRepos()
92     {}
93
94   } // namespace repo
95   ///////////////////////////////////////////////////////////////////
96 } //namespace zypp
97 ///////////////////////////////////////////////////////////////////