libzypp  17.31.31
SUSEMediaVerifier.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
9 
10 #include <fstream>
11 #include <zypp/base/Logger.h>
12 #include <zypp/base/Gettext.h>
15 
16 using std::endl;
17 
18 namespace zypp
19 {
20  namespace repo
21  {
25  struct SMVData
26  {
27  SMVData( const Pathname & path_r )
28  {
29  std::ifstream inp( path_r.c_str() );
30  if ( !inp ) {
31  ERR << "Can't setup a SUSEMediaVerifier from file: " << path_r.asString() << endl;
32  return;
33  }
34  getline( inp, _mediaVendor );
35  getline( inp, _mediaIdent );
36  std::string buffer;
37  getline( inp, buffer );
38  str::strtonum( buffer, _totalMedia );
39  //if ( !_totalMedia ) _totalMedia = 1;
40  }
41 
43  explicit operator bool() const
44  { return valid(); }
45 
47  bool valid() const
48  { return ! (_mediaVendor.empty() || _mediaIdent.empty()); }
49 
51  bool matches( const SMVData & rhs ) const
52  { return valid() && rhs._mediaVendor == _mediaVendor && rhs._mediaIdent == _mediaIdent; }
53 
54  std::string _mediaVendor;
55  std::string _mediaIdent;
57  };
58 
60  inline std::ostream & operator<<( std::ostream & str, const SMVData & obj )
61  { return str << "[" << obj._mediaVendor << "|" << obj._mediaIdent << "/" << obj._totalMedia << "]"; }
62 
63 
76  {
77  public:
78  Impl( const Pathname & path_r, media::MediaNr mediaNr_r )
79  : _smvData { new SMVData( path_r ) }
80  , _mediaNr { mediaNr_r }
81  {}
82 
83  Impl( const Impl & rhs, media::MediaNr mediaNr_r )
84  : _smvData { rhs._smvData }
85  , _mediaNr { mediaNr_r }
86  {}
87 
88  const SMVData & smvData() const
89  { return *_smvData; }
90 
92  { return _mediaNr; }
93 
94  Pathname mediaFilePath( media::MediaNr mediaNr_r = 0 ) const
95  {
96  str::Format fmt { "/media.%d/media" };
97  fmt % str::numstring( mediaNr_r ? mediaNr_r : _mediaNr );
98  return fmt.str();
99  }
100 
101  std::string expectedAsUserString() const
102  {
103  // Translator: %1% the expected medium number; %2% the total number of media in the set; %3% the ident file on the medium.
104  str::Format fmt { _("Expected medium %1%/%2% identified by file '%3%' with content:") };
105  return str::Str()
106  << ( fmt % mediaNr() % smvData()._totalMedia % mediaFilePath() ) << endl
107  << " " << smvData()._mediaVendor << endl
108  << " " << smvData()._mediaIdent;
109  }
110 
111  private:
112  shared_ptr<SMVData> _smvData;
114  };
115 
117  inline std::ostream & operator<<( std::ostream & str, const SUSEMediaVerifier::Impl & obj )
118  { return str << obj.smvData() << "(" << obj.mediaNr() << ")"; }
119 
120 
122  // SUSEMediaVerifier
124 
126  : _pimpl { new Impl( path_r, mediaNr_r ) }
127  {}
128 
130  : _pimpl { new Impl( *rhs._pimpl, mediaNr_r ) }
131  {}
132 
134  {}
135 
137  { return _pimpl->smvData().valid(); }
138 
139  const std::string & SUSEMediaVerifier::vendor() const
140  { return _pimpl->smvData()._mediaVendor; }
141 
142  const std::string & SUSEMediaVerifier::ident() const
143  { return _pimpl->smvData()._mediaIdent; }
144 
146  { return _pimpl->smvData()._totalMedia; }
147 
149  { return _pimpl->mediaNr(); }
150 
151 
153  {
154  bool ret = true; // optimistic return unless we definitely know it does not match
155 
156  const SMVData & smvData = _pimpl->smvData();
157  if ( ! smvData )
158  return ret; // we have no valid data
159 
160  // bsc#1180851: If there is just one not-volatile medium in the set
161  // tolerate a missing (vanished) media identifier and let the URL rule.
162  bool relaxed = smvData._totalMedia == 1 && ! Url::schemeIsVolatile( ref.protocol() );
163  SEC << smvData << endl;
164  SEC << ref.protocol() << " " << Url::schemeIsVolatile( ref.protocol() ) << endl;
165 
166  // if we have a downloading URL and can do relaxed verification we do not check the media file again
167  if ( relaxed && Url::schemeIsDownloading( ref.protocol() ) ) {
168  DBG << "Skipping verification due to downloading medium" << std::endl;
169  return ret;
170  }
171 
172  Pathname mediaFile { _pimpl->mediaFilePath() };
173  try {
174  ref.provideFile( OnMediaLocation(mediaFile) );
175  mediaFile = ref.localPath( mediaFile );
176  }
177  catch ( media::MediaFileNotFoundException & excpt_r )
178  {
179  if ( relaxed ) {
180  ZYPP_CAUGHT( excpt_r );
181  return ret;
182  }
183  excpt_r.addHistory( _pimpl->expectedAsUserString() );
184  ZYPP_RETHROW( excpt_r );
185  }
186  catch ( media::MediaNotAFileException & excpt_r )
187  {
188  if ( relaxed ) {
189  ZYPP_CAUGHT( excpt_r );
190  return ret;
191  }
192  excpt_r.addHistory( _pimpl->expectedAsUserString() );
193  ZYPP_CAUGHT( excpt_r ); return ret;
194  }
195 
196  SMVData remote { mediaFile };
197  ret = smvData.matches( remote );
198  if ( ! ret ) {
199  DBG << "expect: " << smvData << " medium " << mediaNr() << endl;
200  DBG << "remote: " << remote << endl;
201  }
202  return ret;
203  }
204 
205  std::ostream & operator<<( std::ostream & str, const SUSEMediaVerifier & obj )
206  { return str << *obj._pimpl; }
207 
208  } // namespace repo
209 } // namespace zypp
bool valid() const
Data considered to be valid if we have vendor and ident.
Implementation of the traditional SUSE media verifier.
#define _(MSG)
Definition: Gettext.h:37
Describes a resource file located on a medium.
SUSEMediaVerifier(const Pathname &path_r, media::MediaNr mediaNr_r=1)
Ctor creating a verifier by parsing media file.
Impl(const Pathname &path_r, media::MediaNr mediaNr_r)
std::string protocol() const
Protocol hint for MediaAccess.
Definition: MediaHandler.h:498
const std::string & vendor() const
Medias expected vendor string.
bool isDesiredMedia(const media::MediaHandler &ref_r) const override
Check if accesses the desired media.
const char * c_str() const
String representation.
Definition: Pathname.h:110
void addHistory(const std::string &msg_r)
Add some message text to the history.
Definition: Exception.cc:140
String related utilities and Regular expression matching.
media::MediaNr _totalMedia
Convenient building of std::string with boost::format.
Definition: String.h:252
media::MediaNr mediaNr() const
Media number expected by this verifier (starts with 1).
#define ERR
Definition: Logger.h:98
Pathname localPath(const Pathname &pathname) const
Files provided will be available at &#39;localPath(filename)&#39;.
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition: Exception.h:440
std::ostream & operator<<(std::ostream &str, const SUSEMediaVerifier::Impl &obj)
RW_pointer< Impl > _pimpl
Pointer to implementation.
std::string getline(std::istream &str)
Read one line from stream.
Definition: IOStream.cc:33
Abstract base class for &#39;physical&#39; MediaHandler like MediaCD, etc.
Definition: MediaHandler.h:51
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:211
void provideFile(const OnMediaLocation &file) const
Use concrete handler to provide file denoted by path below &#39;localRoot&#39;.
const std::string & asString() const
String representation.
Definition: Pathname.h:91
std::ostream & operator<<(std::ostream &str, const DeltaCandidates &obj)
bool schemeIsVolatile() const
Definition: Url.h:271
#define SEC
Definition: Logger.h:99
const std::string & ident() const
Medias expected ident string.
TInt strtonum(const C_Str &str)
Parsing numbers from string.
Definition: String.h:388
Data parsed from a media.1/media file.
std::string numstring(char n, int w=0)
Definition: String.h:289
bool valid() const
Data considered to be valid if we have vendor and ident.
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:436
media::MediaNr totalMedia() const
The total number of media in this set (or 0 if not known).
bool schemeIsDownloading() const
Definition: Url.h:276
Pathname mediaFilePath(media::MediaNr mediaNr_r=0) const
Impl(const Impl &rhs, media::MediaNr mediaNr_r)
bool matches(const SMVData &rhs) const
Whether rhs belongs to the same media set.
SMVData(const Pathname &path_r)
std::ostream & operator<<(std::ostream &str, const SMVData &obj)
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
unsigned int MediaNr
Definition: MediaManager.h:30
#define DBG
Definition: Logger.h:95