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"
27 ///////////////////////////////////////////////////////////////////
29 { /////////////////////////////////////////////////////////////////
31 DEFINE_PTR_TYPE(MediaSetAccess);
33 ///////////////////////////////////////////////////////////////////
35 // CLASS NAME : MediaSetAccess
38 * Media access layer responsible for handling files distributed on a set
39 * of media with media change and abort/retry/ingore user callback handling.
41 * This is provided as a means to handle CD or DVD sets accessible through
42 * dir, iso, nfs or other URL schemes other than cd/dvd (see
43 * \ref MediaManager for info on different implemented media backends).
44 * Currently it handles URLs containing cdN, CDN, dvdN, and DVDN strings,
45 * where N is the number of particular media in the set.
49 * "iso:/?iso=/path/to/iso/images/openSUSE-10.3-Alpha2plus-DVD-x86_64-DVD1.iso"
50 * "dir:/path/to/cdset/sources/openSUSE-10.3/Alpha2plus/CD1"
53 * MediaSetAccess accesses files on desired media by rewriting
54 * the original URL, replacing the digit (usually) 1 with requested media
55 * number and uses \ref MediaManager to get the files from the new URL.
57 * Additionaly, each media number can be assined a media verifier which
58 * checks if the media we are trying to access is the desired one. See
59 * \ref MediaVerifierBase for more info.
63 * Url url("dir:/path/to/cdset/sources/openSUSE-10.3/Alpha2plus/CD1");
65 * MediaSetAccess access(url);
67 * access.setVerifier(1, media1VerifierRef);
68 * access.setVerifier(2, media2VerifierRef);
70 * Pathname file1 = "/some/file/on/media1";
71 * Pathname providedfile1 = access.provideFile(file1, 1);
72 * Pathname file2 = "/some/file/on/media2";
73 * Pathname providedfile2 = access.provideFile(file1, 2);
77 class MediaSetAccess : public base::ReferenceCounted, private base::NonCopyable
79 friend std::ostream & operator<<( std::ostream & str, const MediaSetAccess & obj );
83 * Creates a callback enabled media access for specified \a url.
86 * \param prefered_attach_point Prefered attach (mount) point. Use, if
87 * you want to mount the media to a specific directory.
89 MediaSetAccess( const Url &url, const Pathname & prefered_attach_point = "" );
90 /** \overload Also taking a \ref label. */
91 MediaSetAccess( const std::string & label_r, const Url &url, const Pathname & prefered_attach_point = "" );
95 * Sets a \ref MediaVerifier verifier for given media number.
97 void setVerifier( unsigned media_nr, media::MediaVerifierRef verifier );
100 * The label identifing this media set and to be sent in a media change request.
102 const std::string & label() const
106 * Set the label identifing this media set and to be sent in a media change request.
108 void setLabel( const std::string & label_r )
109 { _label = label_r; }
111 enum ProvideFileOption
114 * The user is not asked anything, and the error
115 * exception is just propagated */
116 PROVIDE_DEFAULT = 0x0,
117 PROVIDE_NON_INTERACTIVE = 0x1
119 ZYPP_DECLARE_FLAGS(ProvideFileOptions,ProvideFileOption);
122 * Provides a file from a media location.
124 * \param resource location of the file on media
125 * \return local pathname of the requested file
127 * \throws MediaException if a problem occured and user has chosen to
128 * abort the operation. The calling code should take care
129 * to quit the current operation.
130 * \throws SkipRequestException if a problem occured and user has chosen
131 * to skip the current operation. The calling code should continue
132 * with the next one, if possible.
135 * If the resource is marked as optional, no Exception is thrown
136 * and Pathname() is returned
138 * the optional deltafile argument describes a file that can
139 * be used for delta download algorithms.
141 * \note interaction with the user does not ocurr if
142 * \ref ProvideFileOptions::NON_INTERACTIVE is set.
144 * \note OnMediaLocation::optional() hint has no effect on the transfer.
146 * \see zypp::media::MediaManager::provideFile()
148 Pathname provideFile( const OnMediaLocation & resource, ProvideFileOptions options = PROVIDE_DEFAULT, const Pathname &deltafile = Pathname() );
151 * Provides \a file from media \a media_nr.
153 * \param file path to the file relative to media URL
154 * \param media_nr the media number in the media set
155 * \return local pathname of the requested file
157 * \note interaction with the user does not ocurr if
158 * \ref ProvideFileOptions::NON_INTERACTIVE is set.
160 * \note OnMediaLocation::optional() hint has no effect on the transfer.
162 * \throws MediaException if a problem occured and user has chosen to
163 * abort the operation. The calling code should take care
164 * to quit the current operation.
165 * \throws SkipRequestException if a problem occured and user has chosen
166 * to skip the current operation. The calling code should continue
167 * with the next one, if possible.
168 * \see zypp::media::MediaManager::provideFile()
170 Pathname provideFile(const Pathname & file, unsigned media_nr = 1, ProvideFileOptions options = PROVIDE_DEFAULT );
173 * Release file from media.
174 * This signal that file is not needed anymore.
176 * \param resource location of the file on media
178 void releaseFile( const OnMediaLocation &resource );
182 * Release file from media.
183 * This signal that file is not needed anymore.
185 * \param file path to the file relative to media URL
186 * \param media_nr the media number in the media set
188 void releaseFile(const Pathname & file, unsigned media_nr = 1 );
190 ///////////////////////////////////////////////////////////////////
191 /// \class MediaSetAccess::ReleaseFileGuard
192 /// \brief Release a provided file upon destruction.
193 /// In case you don't want to wait until the \ref MediaSetAccess
194 /// itself goes out of scope.
196 /// MediaSetAccess media;
197 /// OnMediaLocation loc;
199 /// Pathname file = media.provideFile( loc );
200 /// ReleaseFileGuard guard( media, loc );
201 /// } // provided file is released here.
204 ///////////////////////////////////////////////////////////////////
205 struct ReleaseFileGuard
207 NON_COPYABLE( ReleaseFileGuard );
208 NON_MOVABLE( ReleaseFileGuard );
209 ReleaseFileGuard( MediaSetAccess & media_r, const OnMediaLocation & loc_r )
214 { _media.releaseFile( _loc ); }
216 MediaSetAccess & _media;
217 const OnMediaLocation & _loc;
221 * Provides direcotry \a dir from media number \a media_nr.
223 * \param dir path to the directory relative to media URL
224 * \param recursive whether to provide the whole directory subtree
225 * \param media_nr the media number in the media set
226 * \return local pathname of the requested directory
228 * \throws MediaException if a problem occured and user has chosen to
229 * abort the operation. The calling code should take care
230 * to quit the current operation.
231 * \todo throw SkipRequestException if a problem occured and user has chosen
232 * to skip the current operation. The calling code should continue
233 * with the next one, if possible.
234 * \see zypp::media::MediaManager::provideDir()
235 * \see zypp::media::MediaManager::provideDirTree()
237 Pathname provideDir(const Pathname & dir, bool recursive, unsigned media_nr = 1, ProvideFileOptions options = PROVIDE_DEFAULT );
240 * Checks if a file exists on the specified media, with user callbacks.
242 * \param file file to check
243 * \param media_nr Media number
245 * \throws MediaException if a problem occured and user has chosen to
246 * abort the operation. The calling code should take care
247 * to quit the current operation.
248 * \throws SkipRequestException if a problem occured and user has chosen
249 * to skip the current operation. The calling code should continue
250 * with the next one, if possible.
251 * \see zypp::media::MediaManager::doesFileExist(MediaAccessId,const Pathname&)
253 bool doesFileExist(const Pathname & file, unsigned media_nr = 1 );
256 * Fills \ref retlist with directory information.
258 void dirInfo( filesystem::DirContent &retlist, const Pathname &dirname,
259 bool dots = true, unsigned media_nr = 1 );
262 * Release all attached media of this set.
264 * \throws MediaNotOpenException for invalid access IDs.
269 * Replaces media number in specified url with given \a medianr.
271 * Media number in the URL is searched for with regex
272 * <tt> "^(.*(cd|dvd))([0-9]+)(\\.iso)$" </tt> for iso scheme and
273 * with <tt> "^(.*(cd|dvd))([0-9]+)(/?)$" </tt> for other schemes.
275 * For cd and dvd scheme it returns the original URL, as well as for
276 * URL which do not match the above regexes.
278 * \param url_r original URL
279 * \param medianr requested media number
280 * \return rewritten URL if applicable, the original URL otherwise
282 static Url rewriteUrl (const Url & url_r, const media::MediaNr medianr);
286 * Provides the \a file from medium number \a media_nr and returns its
289 * \note The method must not throw if \a checkonly is <tt>true</tt>.
291 * \throws MediaException \a checkonly is <tt>false</tt> and
292 * a problem occured and user has chosen to
293 * abort the operation. The calling code should take care
294 * to quit the current operation.
295 * \throws SkipRequestException \a checkonly is <tt>false</tt> and
296 * a problem occured and user has chosen
297 * to skip the current operation. The calling code should continue
298 * with the next one, if possible.
300 Pathname provideFileInternal( const OnMediaLocation &resource, ProvideFileOptions options );
302 typedef function<void( media::MediaAccessId, const Pathname & )> ProvideOperation;
304 void provide( ProvideOperation op, const OnMediaLocation &resource, ProvideFileOptions options, const Pathname &deltafile );
306 media::MediaAccessId getMediaAccessId (media::MediaNr medianr);
307 virtual std::ostream & dumpOn( std::ostream & str ) const;
310 /** Media or media set URL */
314 * Prefered mount point.
316 * \see MediaManager::open(Url,Pathname)
317 * \see MediaHandler::_attachPoint
319 Pathname _prefAttachPoint;
323 typedef std::map<media::MediaNr, media::MediaAccessId> MediaMap;
324 typedef std::map<media::MediaNr, media::MediaVerifierRef > VerifierMap;
326 /** Mapping between media number and Media Access ID */
328 /** Mapping between media number and corespondent verifier */
329 VerifierMap _verifiers;
331 ///////////////////////////////////////////////////////////////////
332 ZYPP_DECLARE_OPERATORS_FOR_FLAGS(MediaSetAccess::ProvideFileOptions);
334 /** \relates MediaSetAccess Stream output */
335 inline std::ostream & operator<<( std::ostream & str, const MediaSetAccess & obj )
336 { return obj.dumpOn( str ); }
340 ///////////////////////////////////////////////////////////////////
341 #endif // ZYPP_SOURCE_MediaSetAccess_H