1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
13 #include "zypp/base/LogTools.h"
14 #include "zypp/ZYppCallbacks.h"
15 #include "zypp/MediaSetAccess.h"
16 #include "zypp/PathInfo.h"
17 //#include "zypp/source/MediaSetAccessReportReceivers.h"
21 ///////////////////////////////////////////////////////////////////
23 { /////////////////////////////////////////////////////////////////
24 ///////////////////////////////////////////////////////////////////
26 ChecksumFileChecker::ChecksumFileChecker( const CheckSum &checksum )
31 bool ChecksumFileChecker::operator()( const Pathname &file )
33 // FIXME probably this funcionality should be in CheckSum itself
34 CheckSum real_checksum( _checksum.type(), filesystem::checksum( file, _checksum.type() ));
35 if ( real_checksum == _checksum )
41 ERR << "Got " << real_checksum << ", expected " << _checksum << std::endl;
46 bool NullFileChecker::operator()(const Pathname &file )
52 MediaSetAccess::MediaSetAccess( const Url &url, const Pathname &path )
56 MIL << "initializing.." << std::endl;
57 //std::vector<media::MediaVerifierRef> single_media;
58 //single_media[0] = media::MediaVerifierRef(new media::NoVerifier());
59 //_verifiers = single_media;
63 MediaSetAccess::~MediaSetAccess()
68 void MediaSetAccess::setVerifier( unsigned media_nr, media::MediaVerifierRef verifier )
70 if (_medias.find(media_nr) != _medias.end())
72 // the media already exists, set theverifier
73 media::MediaAccessId id = _medias[media_nr];
74 media::MediaManager media_mgr;
75 media_mgr.addVerifier( id, verifier );
76 // remove any saved verifier for this media
77 _verifiers.erase(media_nr);
78 //if (! noattach && ! media_mgr.isAttached(id))
79 //media_mgr.attach(id);
83 // save the verifier in the map, and set it when
84 // the media number is first attached
85 _verifiers[media_nr] = verifier;
89 // callback::SendReport<source::DownloadFileReport> report;
90 // DownloadProgressFileReceiver download_report( report );
91 // SourceFactory source_factory;
92 // Url file_url( url().asString() + file_r.asString() );
93 // report->start( source_factory.createFrom(this), file_url );
94 // callback::TempConnect<media::DownloadProgressReport> tmp_download( download_report );
95 // Pathname file = provideJustFile( file_r, media_nr, cached, checkonly );
96 // report->finish( file_url, source::DownloadFileReport::NO_ERROR, "" );
100 Pathname MediaSetAccess::provideFile( const OnMediaLocation & on_media_file )
102 return provideFile( on_media_file.filename(), on_media_file.medianr() );
106 Pathname MediaSetAccess::provideFile(const Pathname & file, unsigned media_nr )
108 return provideFileInternal( file, media_nr, false, false);
112 Pathname MediaSetAccess::provideFile(const Pathname & file, unsigned media_nr, FileChecker checker )
114 Pathname p = provideFileInternal( file, media_nr, false, false);
118 ZYPP_THROW(Exception("Error checker"));
124 Pathname MediaSetAccess::provideFileInternal(const Pathname & file, unsigned media_nr, bool cached, bool checkonly )
126 callback::SendReport<media::MediaChangeReport> report;
127 media::MediaManager media_mgr;
128 // get the mediaId, but don't try to attach it here
129 media::MediaAccessId media = getMediaAccessId( media_nr);
135 DBG << "Going to try to provide file " << file
136 << " from media number " << media_nr << endl;
137 // try to attach the media
138 if ( ! media_mgr.isAttached(media) )
139 media_mgr.attachDesiredMedia(media);
140 media_mgr.provideFile (media, file, false, false);
143 catch ( Exception & excp )
146 media::MediaChangeReport::Action user;
149 DBG << "Media couldn't provide file " << file << " , releasing." << endl;
152 media_mgr.release (media, false);
154 catch (const Exception & excpt_r)
156 ZYPP_CAUGHT(excpt_r);
157 MIL << "Failed to release media " << media << endl;
160 /*MIL << "Releasing all _medias of all sources" << endl;
163 //zypp::SourceManager::sourceManager()->releaseAllSources();
165 catch (const zypp::Exception& excpt_r)
167 ZYPP_CAUGHT(excpt_r);
168 ERR << "Failed to release all sources" << endl;
172 media::MediaChangeReport::Error reason = media::MediaChangeReport::INVALID;
174 if( typeid(excp) == typeid( media::MediaFileNotFoundException ) ||
175 typeid(excp) == typeid( media::MediaNotAFileException ) )
177 reason = media::MediaChangeReport::NOT_FOUND;
179 else if( typeid(excp) == typeid( media::MediaNotDesiredException) ||
180 typeid(excp) == typeid( media::MediaNotAttachedException) )
182 reason = media::MediaChangeReport::WRONG;
185 user = checkonly ? media::MediaChangeReport::ABORT :
186 report->requestMedia (
187 Source_Ref::noSource,
193 DBG << "ProvideFile exception caught, callback answer: " << user << endl;
195 if( user == media::MediaChangeReport::ABORT )
197 DBG << "Aborting" << endl;
198 ZYPP_RETHROW ( excp );
200 else if ( user == media::MediaChangeReport::IGNORE )
202 DBG << "Skipping" << endl;
203 ZYPP_THROW ( source::SkipRequestedException("User-requested skipping of a file") );
205 else if ( user == media::MediaChangeReport::EJECT )
207 DBG << "Eject: try to release" << endl;
210 //zypp::SourceManager::sourceManager()->releaseAllSources();
212 catch (const zypp::Exception& excpt_r)
214 ZYPP_CAUGHT(excpt_r);
215 ERR << "Failed to release all sources" << endl;
217 media_mgr.release (media, true); // one more release needed for eject
218 // FIXME: this will not work, probably
220 else if ( user == media::MediaChangeReport::RETRY ||
221 user == media::MediaChangeReport::CHANGE_URL )
224 DBG << "Going to try again" << endl;
226 // not attaching, media set will do that for us
227 // this could generate uncaught exception (#158620)
232 DBG << "Don't know, let's ABORT" << endl;
233 ZYPP_RETHROW ( excp );
235 } while( user == media::MediaChangeReport::EJECT );
238 // retry or change URL
241 return media_mgr.localPath( media, file );
244 media::MediaAccessId MediaSetAccess::getMediaAccessId (media::MediaNr medianr)
246 media::MediaManager media_mgr;
248 if (_medias.find(medianr) != _medias.end())
250 media::MediaAccessId id = _medias[medianr];
251 //if (! noattach && ! media_mgr.isAttached(id))
252 //media_mgr.attach(id);
256 url = rewriteUrl (_url, medianr);
257 media::MediaAccessId id = media_mgr.open(url, _path);
258 _medias[medianr] = id;
262 if (_verifiers.find(medianr) != _verifiers.end())
264 // a verifier is set for this media
265 // FIXME check the case where the verifier exists
266 // but we have no access id for the media
267 media::MediaAccessId id = _medias[medianr];
268 media::MediaManager media_mgr;
269 media_mgr.delVerifier(id);
270 media_mgr.addVerifier( id, _verifiers[medianr] );
271 // remove any saved verifier for this media
272 _verifiers.erase(medianr);
275 catch ( const Exception &e )
278 WAR << "Verifier not found" << endl;
285 Url MediaSetAccess::rewriteUrl (const Url & url_r, const media::MediaNr medianr)
287 std::string scheme = url_r.getScheme();
288 if (scheme == "cd" || scheme == "dvd")
291 DBG << "Rewriting url " << url_r << endl;
295 // TODO the iso parameter will not be required in the future, this
296 // code has to be adapted together with the MediaISO change.
297 // maybe some MediaISOURL interface should be used.
298 std::string isofile = url_r.getQueryParam("iso");
299 boost::regex e("^(.*(cd|dvd))([0-9]+)(\\.iso)$", boost::regex::icase);
301 if(boost::regex_match(isofile, what, e, boost::match_extra))
304 isofile = what[1] + str::numstring(medianr) + what[4];
305 url.setQueryParam("iso", isofile);
306 DBG << "Url rewrite result: " << url << endl;
312 std::string pathname = url_r.getPathName();
313 boost::regex e("^(.*(cd|dvd))([0-9]+)(/?)$", boost::regex::icase);
315 if(boost::regex_match(pathname, what, e, boost::match_extra))
318 pathname = what[1] + str::numstring(medianr) + what[4];
319 url.setPathName(pathname);
320 DBG << "Url rewrite result: " << url << endl;
327 std::ostream & MediaSetAccess::dumpOn( std::ostream & str ) const
329 str << "MediaSetAccess (URL='" << _url << "', path='" << _path << "')";
333 // media::MediaVerifierRef MediaSetAccess::verifier(unsigned media_nr)
334 // { return media::MediaVerifierRef(new media::NoVerifier()); }
336 /////////////////////////////////////////////////////////////////
338 ///////////////////////////////////////////////////////////////////