- Removed deprecated reattach functions
[platform/upstream/libzypp.git] / zypp / media / MediaAccess.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaAccess.h
10  *
11 */
12 #ifndef ZYPP_MEDIA_MEDIAACCESS_H
13 #define ZYPP_MEDIA_MEDIAACCESS_H
14
15 #include <iosfwd>
16 #include <map>
17 #include <list>
18 #include <string>
19
20 #include "zypp/base/ReferenceCounted.h"
21 #include "zypp/base/NonCopyable.h"
22 #include "zypp/base/PtrTypes.h"
23
24 #include "zypp/Pathname.h"
25 #include "zypp/PathInfo.h"
26
27 #include "zypp/media/MediaException.h"
28 #include "zypp/media/MediaSource.h"
29
30 #include "zypp/Url.h"
31 #include "zypp/base/Logger.h"
32
33 #include <iostream> // endl
34
35 namespace zypp {
36   namespace media {
37
38     class MediaHandler;
39
40     ///////////////////////////////////////////////////////////////////
41     //
42     //  CLASS NAME : MediaAccess
43     /**
44      * @short Handle access to a medium
45      *
46      * The concrete @ref MediaHandler for a certain url is created
47      * on @ref open and deleted on @close.
48      *
49      * The inteface here basically checks whether the handler exists,
50      * then forwards the request to @ref MediaHandler.
51      **/
52     class MediaAccess : public base::ReferenceCounted, private base::NonCopyable
53     {
54     public:
55         typedef intrusive_ptr<MediaAccess> Ptr;
56         typedef intrusive_ptr<const MediaAccess> constPtr;
57
58     private:
59
60         static const Pathname _noPath;
61
62         /**
63          * handler for 'physical' media
64          * == 0 if not open
65          **/
66         MediaHandler * _handler;
67
68         friend class MediaManager;
69         AttachedMedia        attachedMedia() const;
70
71         bool                 isSharedMedia() const;
72
73         bool                 dependsOnParent(MediaAccessId parentId) const;
74
75     public:
76
77        /**
78         * constructor
79         **/
80         MediaAccess();
81
82         /**
83          * open url. If preferred_attach_point is given,
84          * try to use it as attach point.
85          *
86          * <b>Caution:</b> The medium can choose a different attach point.
87          * Only getAttachPoint() knows the real attach point.
88          *
89          * \throws MediaException
90          *
91          **/
92         void open( const Url& url, const Pathname & preferred_attach_point = "" );
93
94         /**
95          * True if media is open.
96          **/
97         bool isOpen() const { return( _handler != 0 ); }
98
99         /**
100          * Hint if files are downloaded or not.
101          * @return True, if the files are downloaded.
102          */
103         bool        downloads() const;
104
105         /**
106          * Hint if files will be downloaded when using the
107          * specified media \p url.
108          *
109          * @note This hint is based on the \p url scheme
110          * only and does not imply, that the URL is valid.
111          *
112          * @param url The media URL to check.
113          * @return True, if the files are downloaded.
114          */
115         static
116         bool        downloads(const Url &url);
117
118         /**
119          * Used Protocol if media is opened, otherwise 'unknown'.
120          **/
121         std::string protocol() const;
122
123         /**
124          * Url if media is opened, otherwise empty.
125          **/
126         Url url() const;
127
128         /**
129          * close url
130          *
131          * \throws MediaException
132          *
133          **/
134         void close();
135
136     public:
137
138         /**
139          * Use concrete handler to attach the media.
140          *
141          * @param next try next available device in turn until end of device
142          * list is reached (for media which are accessible through multiple
143          * devices like cdroms).
144          *
145          * \throws MediaException
146          *
147          **/
148         void attach(bool next = false);
149
150         /**
151          * True if media is attached.
152          *
153          * \throws MediaException
154          *
155          **/
156         bool isAttached() const;
157
158         /**
159          * Return the local directory that corresponds to medias url,
160          * no matter if media isAttached or not. Files requested will
161          * be available at 'localRoot() + filename' or better
162          * 'localPath( filename )'.
163          *
164          * If media is not open an empty pathname is returned.
165          **/
166         Pathname localRoot() const;
167
168         /**
169          * Short for 'localRoot() + pathname', but returns an empty
170          * pathname if media is not open.
171          *
172          * Files provided will be available at 'localPath(filename)'.
173          **/
174         Pathname localPath( const Pathname & pathname ) const;
175
176         /**
177           Use concrete handler to disconnect the media.
178
179           This is useful for media which e.g. holds open a connection to a
180           server like FTP. After calling disconnect() the media object still is
181           valid and files are present.
182
183           After calling disconnect() it's not possible to call provideFile() or
184           provideDir() anymore.
185          *
186          * \throws MediaException
187          *
188         */
189         void disconnect();
190
191         /**
192          * Use concrete handler to release the media.
193          * @param eject if true, physically eject the media * (i.e. CD-ROM)
194          *
195          * \throws MediaException
196          *
197          **/
198         void release( bool eject = false );
199
200         /**
201          * Use concrete handler to provide file denoted by path below
202          * 'attach point'. Filename is interpreted relative to the
203          * attached url and a path prefix is preserved.
204          *
205          * @param cached  If cached is set to true, the function checks, if
206          *                the file already exists and doesn't download it again
207          *                if it does. Currently only the existence is checked,
208          *                no other file attributes.
209          * @param checkonly If this and 'cached' are set to true only the
210          *                  existence of the file is checked but it's not
211          *                  downloaded. If 'cached' is unset an errer is
212          *                  returned always.
213          *
214          * \throws MediaException
215          *
216          **/
217         void provideFile( const Pathname & filename, bool cached = false, bool checkonly = false ) const;
218
219         /**
220          * Remove filename below attach point IFF handler downloads files
221          * to the local filesystem. Never remove anything from media.
222          *
223          * \throws MediaException
224          *
225          **/
226         void releaseFile( const Pathname & filename ) const;
227
228         /**
229          * Use concrete handler to provide directory denoted
230          * by path below 'attach point' (not recursive!).
231          * 'dirname' is interpreted relative to the
232          * attached url and a path prefix is preserved.
233          *
234          * \throws MediaException
235          *
236          **/
237         void provideDir( const Pathname & dirname ) const;
238
239         /**
240          * Use concrete handler to provide directory tree denoted
241          * by path below 'attach point' (recursive!!).
242          * 'dirname' is interpreted relative to the
243          * attached url and a path prefix is preserved.
244          *
245          * \throws MediaException
246          *
247          **/
248         void provideDirTree( const Pathname & dirname ) const;
249
250         /**
251          * Remove directory tree below attach point IFF handler downloads files
252          * to the local filesystem. Never remove anything from media.
253          *
254          * \throws MediaException
255          *
256          **/
257         void releaseDir( const Pathname & dirname ) const;
258
259         /**
260          * Remove pathname below attach point IFF handler downloads files
261          * to the local filesystem. Never remove anything from media.
262          *
263          * If pathname denotes a directory it is recursively removed.
264          * If pathname is empty or '/' everything below the attachpoint
265          * is recursively removed.
266          *
267          * \throws MediaException
268          *
269          **/
270         void releasePath( const Pathname & pathname ) const;
271
272     public:
273
274         /**
275          * Return content of directory on media via retlist. If dots is false
276          * entries starting with '.' are not reported.
277          *
278          * The request is forwarded to the concrete handler,
279          * which may atempt to retieve the content e.g. via 'readdir'
280          *
281          * <B>Caution:</B> This is not supported by all media types.
282          * Be prepared to handle E_not_supported_by_media.
283          *
284          * \throws MediaException
285          *
286          **/
287         void dirInfo( std::list<std::string> & retlist,
288                          const Pathname & dirname, bool dots = true ) const;
289
290         /**
291          * Basically the same as dirInfo above. The content is returned as
292          * filesystem::DirContent, which includes name and filetype of each directory
293          * entry. Retrieving the filetype usg. requires an additional ::stat call for
294          * each entry, thus it's more expensive than a simple readdir.
295          *
296          * <B>Caution:</B> This is not supported by all media types.
297          * Be prepared to handle E_not_supported_by_media.
298          *
299          * \throws MediaException
300          *
301          **/
302         void dirInfo( filesystem::DirContent & retlist,
303                       const Pathname & dirname, bool dots = true ) const;
304
305         /**
306          * Destructor
307          **/
308         virtual ~MediaAccess();
309
310     public:
311
312         virtual std::ostream & dumpOn( std::ostream & str ) const;
313
314     public:
315         /**
316          * Get file from location at specified by URL and copy it to
317          * destination.
318          *
319          * @param from Source URL
320          * @param to   Destination file name
321          *
322          * \throws MediaException
323          *
324          **/
325         void getFile( const Url &from, const Pathname &to );
326
327     public:
328
329       /**
330        * Helper class that provides file on construction
331        * and cleans up on destruction.
332        *
333        * <b>Caution:</b> There's no synchronisation between multiple
334        * FileProvider instances, that provide the same file from the
335        * same media. If the first one goes out of scope, the file is
336        * cleaned. It's just a convenience for 'access and forgett'.
337        *
338        * <b>Caution:</b> We should either store the reference MediaAccess'
339        * MediaHandler here (for this MediaHandler must become a
340        * ref counting pointer class), or we need more info from MediaHandler
341        * (whether he's downloading to the local fs. If not, no releasefile
342        * is necessary).
343        * Currently we can not releaseFile after the media was closed
344        * (it's passed to the handler, which is deleted on close).
345        *
346        * \throws MediaBadFilenameException
347        * \throws MediaException
348        **/
349       class FileProvider {
350         FileProvider( const FileProvider & );             // no copy
351         FileProvider & operator=( const FileProvider & ); // no assign
352         private:
353           MediaAccess::constPtr _media;
354           Pathname              _file;
355           Pathname              _local_file;
356         public:
357           /**
358            * \throws MediaException
359            */
360           FileProvider( MediaAccess::constPtr media_r, const Pathname & file_r )
361             : _media( media_r )
362             , _file( file_r )
363             , _local_file( "" )
364           {
365             if ( _file.empty() ) {
366               ZYPP_THROW(MediaBadFilenameException(_file.asString()));
367             } else if ( _media ) {
368               try {
369                 _media->provideFile( _file );
370                 _local_file = _media->localPath( _file );
371               }
372               catch (const MediaException & excpt_r)
373               {
374                 ZYPP_CAUGHT(excpt_r);
375                 _media = NULL;
376                 ZYPP_RETHROW(excpt_r);
377               }
378             }
379           }
380
381           ~FileProvider() {
382             if ( _media )
383             {
384               try {
385                 _media->releaseFile( _file );
386               }
387               catch (const MediaException &excpt_r)
388               {
389                 ZYPP_CAUGHT(excpt_r);
390                 INT << "Exception raised while releasing file" << std::endl;
391               }
392               catch(...) {} // No exception from dtor!
393             }
394           }
395
396         public:
397
398           /**
399            * If no error, expect operator() to return the local
400            * Pathname of the provided file.
401            **/
402           Pathname localFile() const { return _local_file; }
403
404           /**
405            * Return the local Pathname of the provided file or
406            * an empty Pathname on error.
407            **/
408           Pathname operator()() const {
409             if ( _media )
410               return _media->localPath( _file );
411             return Pathname();
412           }
413       };
414     };
415
416     std::ostream & operator<<( std::ostream & str, const MediaAccess & obj );
417
418 ///////////////////////////////////////////////////////////////////
419
420   } // namespace media
421 } // namespace zypp
422
423 #endif // ZYPP_MEDIA_MEDIAACCESS_H
424