1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaAccess.h
12 #ifndef ZYPP_MEDIA_MEDIAACCESS_H
13 #define ZYPP_MEDIA_MEDIAACCESS_H
20 #include "zypp/base/ReferenceCounted.h"
21 #include "zypp/base/NonCopyable.h"
22 #include "zypp/base/PtrTypes.h"
24 #include "zypp/Pathname.h"
25 #include "zypp/PathInfo.h"
27 #include "zypp/media/MediaException.h"
28 #include "zypp/media/MediaSource.h"
31 #include "zypp/base/Logger.h"
33 #include <iostream> // endl
40 ///////////////////////////////////////////////////////////////////
42 // CLASS NAME : MediaAccess
44 * @short Handle access to a medium
46 * The concrete @ref MediaHandler for a certain url is created
47 * on @ref open and deleted on @close.
49 * The inteface here basically checks whether the handler exists,
50 * then forwards the request to @ref MediaHandler.
52 class MediaAccess : public base::ReferenceCounted, private base::NonCopyable
55 typedef intrusive_ptr<MediaAccess> Ptr;
56 typedef intrusive_ptr<const MediaAccess> constPtr;
60 static const Pathname _noPath;
63 * handler for 'physical' media
66 MediaHandler * _handler;
68 friend class MediaManager;
69 AttachedMedia attachedMedia() const;
71 bool isSharedMedia() const;
73 bool dependsOnParent(MediaAccessId parentId) const;
83 * open url. If preferred_attach_point is given,
84 * try to use it as attach point.
86 * <b>Caution:</b> The medium can choose a different attach point.
87 * Only getAttachPoint() knows the real attach point.
89 * \throws MediaException
92 void open( const Url& url, const Pathname & preferred_attach_point = "" );
95 * True if media is open.
97 bool isOpen() const { return( _handler != 0 ); }
100 * Hint if files are downloaded or not.
101 * @return True, if the files are downloaded.
103 bool downloads() const;
106 * Hint if files will be downloaded when using the
107 * specified media \p url.
109 * @note This hint is based on the \p url scheme
110 * only and does not imply, that the URL is valid.
112 * @param url The media URL to check.
113 * @return True, if the files are downloaded.
116 bool downloads(const Url &url);
119 * Used Protocol if media is opened, otherwise 'unknown'.
121 std::string protocol() const;
124 * Url if media is opened, otherwise empty.
131 * \throws MediaException
139 * Use concrete handler to attach the media.
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).
145 * \throws MediaException
148 void attach(bool next = false);
151 * True if media is attached.
153 * \throws MediaException
156 bool isAttached() const;
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 )'.
164 * If media is not open an empty pathname is returned.
166 Pathname localRoot() const;
169 * Short for 'localRoot() + pathname', but returns an empty
170 * pathname if media is not open.
172 * Files provided will be available at 'localPath(filename)'.
174 Pathname localPath( const Pathname & pathname ) const;
177 Use concrete handler to disconnect the media.
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.
183 After calling disconnect() it's not possible to call provideFile() or
184 provideDir() anymore.
186 * \throws MediaException
192 * Use concrete handler to release the media.
193 * @param eject if true, physically eject the media * (i.e. CD-ROM)
195 * \throws MediaException
198 void release( bool eject = false );
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.
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
214 * \throws MediaException
217 void provideFile( const Pathname & filename, bool cached = false, bool checkonly = false ) const;
220 * Remove filename below attach point IFF handler downloads files
221 * to the local filesystem. Never remove anything from media.
223 * \throws MediaException
226 void releaseFile( const Pathname & filename ) const;
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.
234 * \throws MediaException
237 void provideDir( const Pathname & dirname ) const;
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.
245 * \throws MediaException
248 void provideDirTree( const Pathname & dirname ) const;
251 * Remove directory tree below attach point IFF handler downloads files
252 * to the local filesystem. Never remove anything from media.
254 * \throws MediaException
257 void releaseDir( const Pathname & dirname ) const;
260 * Remove pathname below attach point IFF handler downloads files
261 * to the local filesystem. Never remove anything from media.
263 * If pathname denotes a directory it is recursively removed.
264 * If pathname is empty or '/' everything below the attachpoint
265 * is recursively removed.
267 * \throws MediaException
270 void releasePath( const Pathname & pathname ) const;
275 * Return content of directory on media via retlist. If dots is false
276 * entries starting with '.' are not reported.
278 * The request is forwarded to the concrete handler,
279 * which may atempt to retieve the content e.g. via 'readdir'
281 * <B>Caution:</B> This is not supported by all media types.
282 * Be prepared to handle E_not_supported_by_media.
284 * \throws MediaException
287 void dirInfo( std::list<std::string> & retlist,
288 const Pathname & dirname, bool dots = true ) const;
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.
296 * <B>Caution:</B> This is not supported by all media types.
297 * Be prepared to handle E_not_supported_by_media.
299 * \throws MediaException
302 void dirInfo( filesystem::DirContent & retlist,
303 const Pathname & dirname, bool dots = true ) const;
308 virtual ~MediaAccess();
312 virtual std::ostream & dumpOn( std::ostream & str ) const;
316 * Get file from location at specified by URL and copy it to
319 * @param from Source URL
320 * @param to Destination file name
322 * \throws MediaException
325 void getFile( const Url &from, const Pathname &to );
330 * Helper class that provides file on construction
331 * and cleans up on destruction.
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'.
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
343 * Currently we can not releaseFile after the media was closed
344 * (it's passed to the handler, which is deleted on close).
346 * \throws MediaBadFilenameException
347 * \throws MediaException
350 FileProvider( const FileProvider & ); // no copy
351 FileProvider & operator=( const FileProvider & ); // no assign
353 MediaAccess::constPtr _media;
355 Pathname _local_file;
358 * \throws MediaException
360 FileProvider( MediaAccess::constPtr media_r, const Pathname & file_r )
365 if ( _file.empty() ) {
366 ZYPP_THROW(MediaBadFilenameException(_file.asString()));
367 } else if ( _media ) {
369 _media->provideFile( _file );
370 _local_file = _media->localPath( _file );
372 catch (const MediaException & excpt_r)
374 ZYPP_CAUGHT(excpt_r);
376 ZYPP_RETHROW(excpt_r);
385 _media->releaseFile( _file );
387 catch (const MediaException &excpt_r)
389 ZYPP_CAUGHT(excpt_r);
390 INT << "Exception raised while releasing file" << std::endl;
392 catch(...) {} // No exception from dtor!
399 * If no error, expect operator() to return the local
400 * Pathname of the provided file.
402 Pathname localFile() const { return _local_file; }
405 * Return the local Pathname of the provided file or
406 * an empty Pathname on error.
408 Pathname operator()() const {
410 return _media->localPath( _file );
416 std::ostream & operator<<( std::ostream & str, const MediaAccess & obj );
418 ///////////////////////////////////////////////////////////////////
423 #endif // ZYPP_MEDIA_MEDIAACCESS_H