libzypp  14.48.5
RepoMirrorList.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
13 #include <iostream>
14 #include <vector>
15 #include <time.h>
18 #include "zypp/MediaSetAccess.h"
19 #include "zypp/base/LogTools.h"
20 #include "zypp/ZConfig.h"
21 #include "zypp/PathInfo.h"
22 
23 using namespace std;
24 
26 namespace zypp
27 {
28  namespace repo
30  {
31 
33  namespace
34  {
42  struct RepoMirrorListTempProvider
43  {
44  RepoMirrorListTempProvider()
45  {}
46  RepoMirrorListTempProvider( const Pathname & localfile_r )
47  : _localfile( localfile_r )
48  {}
49  RepoMirrorListTempProvider( const Url & url_r )
50  {
51  Url abs_url( url_r );
52  abs_url.setPathName( "/" );
53  abs_url.setQueryParam( "mediahandler", "curl" );
54  _access.reset( new MediaSetAccess( abs_url ) );
55  _localfile = _access->provideFile( url_r.getPathName() );
56  }
57 
58  const Pathname & localfile() const
59  { return _localfile; }
60 
61  private:
62  shared_ptr<MediaSetAccess> _access;
63  Pathname _localfile;
64  };
66 
67  inline std::vector<Url> RepoMirrorListParseXML( const Pathname &tmpfile )
68  {
69  InputStream tmpfstream (tmpfile);
70  media::MetaLinkParser metalink;
71  metalink.parse(tmpfstream);
72  return metalink.getUrls();
73  }
74 
75  inline std::vector<Url> RepoMirrorListParseTXT( const Pathname &tmpfile )
76  {
77  InputStream tmpfstream (tmpfile);
78  std::vector<Url> my_urls;
79  string tmpurl;
80  while (getline(tmpfstream.stream(), tmpurl))
81  {
82  my_urls.push_back(Url(tmpurl));
83  }
84  return my_urls;
85  }
86 
88  inline std::vector<Url> RepoMirrorListParse( const Url & url_r, const Pathname & listfile_r )
89  {
90  USR << url_r << " " << listfile_r << endl;
91 
92  std::vector<Url> mirrorurls;
93  if ( url_r.asString().find( "/metalink" ) != string::npos )
94  mirrorurls = RepoMirrorListParseXML( listfile_r );
95  else
96  mirrorurls = RepoMirrorListParseTXT( listfile_r );
97 
98 
99  std::vector<Url> ret;
100  for ( auto & murl : mirrorurls )
101  {
102  if ( murl.getScheme() != "rsync" )
103  {
104  size_t delpos = murl.getPathName().find("repodata/repomd.xml");
105  if( delpos != string::npos )
106  {
107  murl.setPathName( murl.getPathName().erase(delpos) );
108  }
109  ret.push_back( murl );
110 
111  if ( ret.size() >= 4 ) // why 4?
112  break;
113  }
114  }
115  return ret;
116  }
117 
118  } // namespace
120 
121 
122  RepoMirrorList::RepoMirrorList( const Url & url_r, const Pathname & metadatapath_r )
123  {
124  if ( url_r.getScheme() == "file" )
125  {
126  // never cache for local mirrorlist
127  _urls = RepoMirrorListParse( url_r, url_r.getPathName() );
128  }
129  else if ( ! PathInfo( metadatapath_r).isDir() )
130  {
131  // no cachedir
132  RepoMirrorListTempProvider provider( url_r ); // RAII: lifetime of any downloaded files
133  _urls = RepoMirrorListParse( url_r, provider.localfile() );
134  }
135  else
136  {
137  // have cachedir
138  Pathname cachefile( metadatapath_r );
139  if ( url_r.asString().find( "/metalink" ) != string::npos )
140  cachefile /= "mirrorlist.xml";
141  else
142  cachefile /= "mirrorlist.txt";
143 
144  zypp::filesystem::PathInfo cacheinfo( cachefile );
145  if ( !cacheinfo.isFile() || cacheinfo.mtime() < time(NULL) - (long) ZConfig::instance().repo_refresh_delay() * 60 )
146  {
147  DBG << "Getting MirrorList from URL: " << url_r << endl;
148  RepoMirrorListTempProvider provider( url_r ); // RAII: lifetime of downloaded file
149 
150  // Create directory, if not existing
151  DBG << "Copy MirrorList file to " << cachefile << endl;
152  zypp::filesystem::assert_dir( metadatapath_r );
153  zypp::filesystem::hardlinkCopy( provider.localfile(), cachefile );
154  }
155 
156  _urls = RepoMirrorListParse( url_r, cachefile );
157  if( _urls.empty() )
158  {
159  DBG << "Removing Cachefile as it contains no URLs" << endl;
160  zypp::filesystem::unlink( cachefile );
161  }
162  }
163  }
164 
166  } // namespace repo
169 } // namespace zypp
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Definition: PathInfo.cc:329
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
Definition: Url.cc:598
Pathname _localfile
std::string asString() const
Returns a default string representation of the Url object.
Definition: Url.cc:491
std::string getline(std::istream &str)
Read one line from stream.
Definition: IOStream.cc:33
time_t mtime() const
Definition: PathInfo.h:382
int unlink(const Pathname &path)
Like 'unlink'.
Definition: PathInfo.cc:668
#define USR
Definition: Logger.h:52
int hardlinkCopy(const Pathname &oldpath, const Pathname &newpath)
Create newpath as hardlink or copy of oldpath.
Definition: PathInfo.cc:823
bool isFile() const
Definition: PathInfo.h:290
shared_ptr< MediaSetAccess > _access
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:221
std::string getScheme() const
Returns the scheme name of the URL.
Definition: Url.cc:527
Url manipulation class.
Definition: Url.h:87
#define DBG
Definition: Logger.h:46