b91c7c8c4713913064ab309e0458e1c44c914d28
[platform/upstream/libzypp.git] / zypp / MediaSetAccess.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9
10 #ifndef ZYPP_MediaSetAccess_H
11 #define ZYPP_MediaSetAccess_H
12
13 #include <iosfwd>
14 #include <string>
15 #include <vector>
16 #include "zypp/base/Function.h"
17
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
27 ///////////////////////////////////////////////////////////////////
28 namespace zypp
29 { /////////////////////////////////////////////////////////////////
30
31     DEFINE_PTR_TYPE(MediaSetAccess);
32
33     ///////////////////////////////////////////////////////////////////
34     //
35     //  CLASS NAME : MediaSetAccess
36     //
37     /**
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.
40      *
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.
46      *
47      * Examples:
48      * \code
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"
51      * \endcode
52      *
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.
56      *
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.
60      *
61      * Code example:
62      * \code
63      * Url url("dir:/path/to/cdset/sources/openSUSE-10.3/Alpha2plus/CD1");
64      *
65      * MediaSetAccess access(url);
66      *
67      * access.setVerifier(1, media1VerifierRef);
68      * access.setVerifier(2, media2VerifierRef);
69      *
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);
74      *
75      * \endcode
76      */
77     class MediaSetAccess : public base::ReferenceCounted, private base::NonCopyable
78     {
79       friend std::ostream & operator<<( std::ostream & str, const MediaSetAccess & obj );
80
81     public:
82       /**
83        * Creates a callback enabled media access for specified \a url.
84        *
85        * \param url
86        * \param prefered_attach_point Prefered attach (mount) point. Use, if
87        *        you want to mount the media to a specific directory.
88        */
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 = "" );
92       ~MediaSetAccess();
93
94       /**
95        * Sets a \ref MediaVerifier verifier for given media number.
96        */
97       void setVerifier( unsigned media_nr, media::MediaVerifierRef verifier );
98
99       /**
100        * The label identifing this media set and to be sent in a media change request.
101        */
102       const std::string & label() const
103       { return _label; }
104
105       /**
106        * Set the label identifing this media set and to be sent in a media change request.
107        */
108       void setLabel( const std::string & label_r )
109       { _label = label_r; }
110
111       enum ProvideFileOption
112       {
113         /**
114          * The user is not asked anything, and the error
115          * exception is just propagated */
116         PROVIDE_DEFAULT = 0x0,
117         PROVIDE_NON_INTERACTIVE = 0x1
118       };
119       ZYPP_DECLARE_FLAGS(ProvideFileOptions,ProvideFileOption);
120
121       /**
122        * Provides a file from a media location.
123        *
124        * \param resource location of the file on media
125        * \return local pathname of the requested file
126        *
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.
133        *
134        *
135        * If the resource is marked as optional, no Exception is thrown
136        * and Pathname() is returned
137        *
138        * the optional deltafile argument describes a file that can
139        * be used for delta download algorithms.
140        *
141        * \note interaction with the user does not ocurr if
142        * \ref ProvideFileOptions::NON_INTERACTIVE is set.
143        *
144        * \note OnMediaLocation::optional() hint has no effect on the transfer.
145        *
146        * \see zypp::media::MediaManager::provideFile()
147        */
148       Pathname provideFile( const OnMediaLocation & resource, ProvideFileOptions options = PROVIDE_DEFAULT, const Pathname &deltafile = Pathname() );
149
150       /**
151        * Provides \a file from media \a media_nr.
152        *
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
156        *
157        * \note interaction with the user does not ocurr if
158        * \ref ProvideFileOptions::NON_INTERACTIVE is set.
159        *
160        * \note OnMediaLocation::optional() hint has no effect on the transfer.
161        *
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()
169        */
170       Pathname provideFile(const Pathname & file, unsigned media_nr = 1, ProvideFileOptions options = PROVIDE_DEFAULT );
171
172       /**
173        * Release file from media.
174        * This signal that file is not needed anymore.
175        *
176        * \param resource location of the file on media
177        */
178       void releaseFile( const OnMediaLocation &resource );
179
180
181       /**
182        * Release file from media.
183        * This signal that file is not needed anymore.
184        *
185        * \param file path to the file relative to media URL
186        * \param media_nr the media number in the media set
187        */
188       void releaseFile(const Pathname & file, unsigned media_nr = 1 );
189
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.
195       /// \code
196       ///   MediaSetAccess media;
197       ///   OnMediaLocation loc;
198       ///   {
199       ///       Pathname file = media.provideFile( loc );
200       ///       ReleaseFileGuard guard( media, loc );
201       ///   }   // provided file is released here.
202       /// \endcode
203       /// \ingroup g_RAII
204       ///////////////////////////////////////////////////////////////////
205       struct ReleaseFileGuard
206       {
207         NON_COPYABLE( ReleaseFileGuard );
208         NON_MOVABLE( ReleaseFileGuard );
209         ReleaseFileGuard( MediaSetAccess & media_r, const OnMediaLocation & loc_r )
210         : _media( media_r )
211         , _loc( loc_r )
212         {}
213         ~ReleaseFileGuard()
214         { _media.releaseFile( _loc ); }
215       private:
216         MediaSetAccess & _media;
217         const OnMediaLocation & _loc;
218       };
219
220       /**
221        * Provides direcotry \a dir from media number \a media_nr.
222        *
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
227        *
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()
236        */
237       Pathname provideDir(const Pathname & dir, bool recursive, unsigned media_nr = 1, ProvideFileOptions options = PROVIDE_DEFAULT );
238
239       /**
240        * Checks if a file exists on the specified media, with user callbacks.
241        *
242        * \param file file to check
243        * \param media_nr Media number
244        *
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&)
252        */
253       bool doesFileExist(const Pathname & file, unsigned media_nr = 1 );
254
255       /**
256        * Fills \ref retlist with directory information.
257        */
258       void dirInfo( filesystem::DirContent &retlist, const Pathname &dirname,
259                     bool dots = true, unsigned media_nr = 1 );
260
261       /**
262        * Release all attached media of this set.
263        *
264        * \throws MediaNotOpenException for invalid access IDs.
265        */
266       void release();
267
268       /**
269        * Replaces media number in specified url with given \a medianr.
270        *
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.
274        *
275        * For cd and dvd scheme it returns the original URL, as well as for
276        * URL which do not match the above regexes.
277        *
278        * \param url_r   original URL
279        * \param medianr requested media number
280        * \return        rewritten URL if applicable, the original URL otherwise
281        */
282       static Url rewriteUrl (const Url & url_r, const media::MediaNr medianr);
283
284     protected:
285       /**
286        * Provides the \a file from medium number \a media_nr and returns its
287        * local path.
288        *
289        * \note   The method must not throw if \a checkonly is <tt>true</tt>.
290        *
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.
299        */
300       Pathname provideFileInternal( const OnMediaLocation &resource, ProvideFileOptions options );
301
302       typedef function<void( media::MediaAccessId, const Pathname & )> ProvideOperation;
303
304       void provide( ProvideOperation op, const OnMediaLocation &resource, ProvideFileOptions options, const Pathname &deltafile );
305
306       media::MediaAccessId getMediaAccessId (media::MediaNr medianr);
307       virtual std::ostream & dumpOn( std::ostream & str ) const;
308
309     private:
310       /** Media or media set URL */
311       Url _url;
312
313       /**
314        * Prefered mount point.
315        *
316        * \see MediaManager::open(Url,Pathname)
317        * \see MediaHandler::_attachPoint
318        */
319       Pathname _prefAttachPoint;
320
321       std::string _label;
322
323       typedef std::map<media::MediaNr, media::MediaAccessId> MediaMap;
324       typedef std::map<media::MediaNr, media::MediaVerifierRef > VerifierMap;
325
326       /** Mapping between media number and Media Access ID */
327       MediaMap _medias;
328       /** Mapping between media number and corespondent verifier */
329       VerifierMap _verifiers;
330     };
331     ///////////////////////////////////////////////////////////////////
332     ZYPP_DECLARE_OPERATORS_FOR_FLAGS(MediaSetAccess::ProvideFileOptions);
333
334     /** \relates MediaSetAccess Stream output */
335     inline std::ostream & operator<<( std::ostream & str, const MediaSetAccess & obj )
336     { return obj.dumpOn( str ); }
337
338
339 } // namespace zypp
340 ///////////////////////////////////////////////////////////////////
341 #endif // ZYPP_SOURCE_MediaSetAccess_H