1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
10 #ifndef ZYPP_MediaSetAccess_H
11 #define ZYPP_MediaSetAccess_H
16 #include <zypp/base/Function.h>
18 #include <zypp/base/ReferenceCounted.h>
19 #include <zypp/base/NonCopyable.h>
20 #include <zypp/base/Flags.h>
21 #include <zypp/base/PtrTypes.h>
22 #include <zypp/media/MediaManager.h>
23 #include <zypp/Pathname.h>
24 #include <zypp/CheckSum.h>
25 #include <zypp/OnMediaLocation.h>
26 #include <zypp/ManagedFile.h>
28 ///////////////////////////////////////////////////////////////////
30 { /////////////////////////////////////////////////////////////////
32 DEFINE_PTR_TYPE(MediaSetAccess);
34 ///////////////////////////////////////////////////////////////////
36 // CLASS NAME : MediaSetAccess
39 * Media access layer responsible for handling files distributed on a set
40 * of media with media change and abort/retry/ingore user callback handling.
42 * This is provided as a means to handle CD or DVD sets accessible through
43 * dir, iso, nfs or other URL schemes other than cd/dvd (see
44 * \ref MediaManager for info on different implemented media backends).
45 * Currently it handles URLs ending on (case insensitive ) CD#, DVD# or MEDIA#,
46 * where # is the number of a particular medium in the set.
50 * "iso:/?iso=/path/to/iso/images/openSUSE-10.3-Alpha2plus-DVD-x86_64-DVD1.iso"
51 * "dir:/path/to/cdset/sources/openSUSE-10.3/Alpha2plus/CD1"
54 * MediaSetAccess accesses files on the desired medium by rewriting
55 * the original URL, replacing the digit (usually) 1 with requested media
56 * number and uses \ref MediaManager to get the files from the new URL.
58 * NOTE: Access to medium #1 always uses the url passed to the CTOR!
60 * Additionaly, each media number can be assinged a media verifier which
61 * checks if the media we are trying to access is the desired one. See
62 * \ref MediaVerifierBase for more info.
66 * Url url("dir:/path/to/cdset/sources/openSUSE-10.3/Alpha2plus/CD1");
68 * MediaSetAccess access(url);
70 * access.setVerifier(1, media1VerifierRef);
71 * access.setVerifier(2, media2VerifierRef);
73 * Pathname file1 = "/some/file/on/media1";
74 * Pathname providedfile1 = access.provideFile(file1, 1);
75 * Pathname file2 = "/some/file/on/media2";
76 * Pathname providedfile2 = access.provideFile(file1, 2);
80 class MediaSetAccess : public base::ReferenceCounted, private base::NonCopyable
82 friend std::ostream & operator<<( std::ostream & str, const MediaSetAccess & obj );
86 * Creates a callback enabled media access for specified \a url.
89 * \param prefered_attach_point Prefered attach (mount) point. Use, if
90 * you want to mount the media to a specific directory.
92 MediaSetAccess( const Url &url, const Pathname & prefered_attach_point = "" );
93 /** \overload Also taking a \ref label. */
94 MediaSetAccess( const std::string & label_r, const Url &url, const Pathname & prefered_attach_point = "" );
98 * Sets a \ref MediaVerifier verifier for given media number.
100 void setVerifier( unsigned media_nr, media::MediaVerifierRef verifier );
103 * The label identifing this media set and to be sent in a media change request.
105 const std::string & label() const
109 * Set the label identifing this media set and to be sent in a media change request.
111 void setLabel( const std::string & label_r )
112 { _label = label_r; }
114 enum ProvideFileOption
117 * The user is not asked anything, and the error
118 * exception is just propagated */
119 PROVIDE_DEFAULT = 0x0,
120 PROVIDE_NON_INTERACTIVE = 0x1
122 ZYPP_DECLARE_FLAGS(ProvideFileOptions,ProvideFileOption);
125 * Provides a file from a media location.
127 * \param resource location of the file on media
128 * \return local pathname of the requested file
130 * \throws MediaException if a problem occured and user has chosen to
131 * abort the operation. The calling code should take care
132 * to quit the current operation.
133 * \throws SkipRequestException if a problem occured and user has chosen
134 * to skip the current operation. The calling code should continue
135 * with the next one, if possible.
138 * If the resource is marked as optional, no Exception is thrown
139 * and Pathname() is returned
141 * the optional deltafile argument describes a file that can
142 * be used for delta download algorithms.
144 * \note interaction with the user does not ocurr if
145 * \ref ProvideFileOptions::NON_INTERACTIVE is set.
147 * \note OnMediaLocation::optional() hint has no effect on the transfer.
149 * \see zypp::media::MediaManager::provideFile()
151 Pathname provideFile( const OnMediaLocation & resource, ProvideFileOptions options = PROVIDE_DEFAULT, const Pathname &deltafile = Pathname() );
154 * Provides \a file from media \a media_nr.
156 * \param file path to the file relative to media URL
157 * \param media_nr the media number in the media set
158 * \return local pathname of the requested file
160 * \note interaction with the user does not ocurr if
161 * \ref ProvideFileOptions::NON_INTERACTIVE is set.
163 * \note OnMediaLocation::optional() hint has no effect on the transfer.
165 * \throws MediaException if a problem occured and user has chosen to
166 * abort the operation. The calling code should take care
167 * to quit the current operation.
168 * \throws SkipRequestException if a problem occured and user has chosen
169 * to skip the current operation. The calling code should continue
170 * with the next one, if possible.
171 * \see zypp::media::MediaManager::provideFile()
173 Pathname provideFile(const Pathname & file, unsigned media_nr = 1, ProvideFileOptions options = PROVIDE_DEFAULT );
176 * Provides an optional \a file from media \a media_nr.
178 * Like \ref provideFile (NON_INTERACTIVE), but return an empty \ref Pathname
179 * rather than throwing a \ref MediaException if the file is not present on
182 Pathname provideOptionalFile( const Pathname & file, unsigned media_nr = 1 );
185 * Provides \a file from \a url.
187 * \param absolute url to the file
188 * \return local pathname of the requested file
190 * \note interaction with the user does not ocurr if
191 * \ref ProvideFileOptions::NON_INTERACTIVE is set.
193 * \throws MediaException if a problem occured and user has chosen to
194 * abort the operation. The calling code should take care
195 * to quit the current operation.
196 * \throws SkipRequestException if a problem occured and user has chosen
197 * to skip the current operation. The calling code should continue
198 * with the next one, if possible.
199 * \see zypp::media::MediaManager::provideFile()
201 static ManagedFile provideFileFromUrl( const Url & file_url, ProvideFileOptions options = PROVIDE_DEFAULT );
204 * Provides an optional \a file from \a url.
206 * Like \ref provideFileFromUrl( NON_INTERACTIVE ), but return an empty \ref Pathname
207 * rather than throwing a \ref MediaException if the file is not present on
210 static ManagedFile provideOptionalFileFromUrl( const Url & file_url );
213 * Release file from media.
214 * This signal that file is not needed anymore.
216 * \param resource location of the file on media
218 void releaseFile( const OnMediaLocation &resource );
222 * Release file from media.
223 * This signal that file is not needed anymore.
225 * \param file path to the file relative to media URL
226 * \param media_nr the media number in the media set
228 void releaseFile(const Pathname & file, unsigned media_nr = 1 );
230 ///////////////////////////////////////////////////////////////////
231 /// \class MediaSetAccess::ReleaseFileGuard
232 /// \brief Release a provided file upon destruction.
233 /// In case you don't want to wait until the \ref MediaSetAccess
234 /// itself goes out of scope.
236 /// MediaSetAccess media;
237 /// OnMediaLocation loc;
239 /// Pathname file = media.provideFile( loc );
240 /// ReleaseFileGuard guard( media, loc );
241 /// } // provided file is released here.
244 ///////////////////////////////////////////////////////////////////
245 struct ReleaseFileGuard
247 NON_COPYABLE( ReleaseFileGuard );
248 NON_MOVABLE( ReleaseFileGuard );
249 ReleaseFileGuard( MediaSetAccess & media_r, const OnMediaLocation & loc_r )
254 { _media.releaseFile( _loc ); }
256 MediaSetAccess & _media;
257 const OnMediaLocation & _loc;
261 * Provides direcotry \a dir from media number \a media_nr.
263 * \param dir path to the directory relative to media URL
264 * \param recursive whether to provide the whole directory subtree
265 * \param media_nr the media number in the media set
266 * \return local pathname of the requested directory
268 * \throws MediaException if a problem occured and user has chosen to
269 * abort the operation. The calling code should take care
270 * to quit the current operation.
271 * \todo throw SkipRequestException if a problem occured and user has chosen
272 * to skip the current operation. The calling code should continue
273 * with the next one, if possible.
274 * \see zypp::media::MediaManager::provideDir()
275 * \see zypp::media::MediaManager::provideDirTree()
277 Pathname provideDir(const Pathname & dir, bool recursive, unsigned media_nr = 1, ProvideFileOptions options = PROVIDE_DEFAULT );
280 * Checks if a file exists on the specified media, with user callbacks.
282 * \param file file to check
283 * \param media_nr Media number
285 * \throws MediaException if a problem occured and user has chosen to
286 * abort the operation. The calling code should take care
287 * to quit the current operation.
288 * \throws SkipRequestException if a problem occured and user has chosen
289 * to skip the current operation. The calling code should continue
290 * with the next one, if possible.
291 * \see zypp::media::MediaManager::doesFileExist(MediaAccessId,const Pathname&)
293 bool doesFileExist(const Pathname & file, unsigned media_nr = 1 );
296 * Fills \ref retlist with directory information.
298 void dirInfo( filesystem::DirContent &retlist, const Pathname &dirname,
299 bool dots = true, unsigned media_nr = 1 );
302 * Release all attached media of this set.
304 * \throws MediaNotOpenException for invalid access IDs.
309 * Replaces media number in specified url with given \a medianr.
311 * Media number in the URL is searched for with regex
312 * <tt> "^(.*(cd|dvd|media))([0-9]+)(\\.iso)$" </tt> for iso scheme and
313 * with <tt> "^(.*(cd|dvd|media))([0-9]+)(/?)$" </tt> for other schemes.
315 * For cd and dvd scheme it returns the original URL, as well as for
316 * URL which do not match the above regexes.
318 * \param url_r original URL
319 * \param medianr requested media number
320 * \return rewritten URL if applicable, the original URL otherwise
322 static Url rewriteUrl (const Url & url_r, const media::MediaNr medianr);
326 * Provides the \a file from medium number \a media_nr and returns its
329 * \note The method must not throw if \a checkonly is <tt>true</tt>.
331 * \throws MediaException \a checkonly is <tt>false</tt> and
332 * a problem occured and user has chosen to
333 * abort the operation. The calling code should take care
334 * to quit the current operation.
335 * \throws SkipRequestException \a checkonly is <tt>false</tt> and
336 * a problem occured and user has chosen
337 * to skip the current operation. The calling code should continue
338 * with the next one, if possible.
340 Pathname provideFileInternal( const OnMediaLocation &resource, ProvideFileOptions options );
342 typedef function<void( media::MediaAccessId, const Pathname & )> ProvideOperation;
344 void provide( ProvideOperation op, const OnMediaLocation &resource, ProvideFileOptions options, const Pathname &deltafile );
346 media::MediaAccessId getMediaAccessId (media::MediaNr medianr);
347 virtual std::ostream & dumpOn( std::ostream & str ) const;
350 /** Media or media set URL */
354 * Prefered mount point.
356 * \see MediaManager::open(Url,Pathname)
357 * \see MediaHandler::_attachPoint
359 Pathname _prefAttachPoint;
363 typedef std::map<media::MediaNr, media::MediaAccessId> MediaMap;
364 typedef std::map<media::MediaNr, media::MediaVerifierRef > VerifierMap;
366 /** Mapping between media number and Media Access ID */
368 /** Mapping between media number and corespondent verifier */
369 VerifierMap _verifiers;
371 ///////////////////////////////////////////////////////////////////
372 ZYPP_DECLARE_OPERATORS_FOR_FLAGS(MediaSetAccess::ProvideFileOptions);
374 /** \relates MediaSetAccess Stream output */
375 inline std::ostream & operator<<( std::ostream & str, const MediaSetAccess & obj )
376 { return obj.dumpOn( str ); }
380 ///////////////////////////////////////////////////////////////////
381 #endif // ZYPP_SOURCE_MediaSetAccess_H