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"
23 #include "zypp/APIConfig.h"
25 #include "zypp/Pathname.h"
26 #include "zypp/PathInfo.h"
28 #include "zypp/media/MediaException.h"
29 #include "zypp/media/MediaSource.h"
38 ///////////////////////////////////////////////////////////////////
40 // CLASS NAME : MediaAccess
42 * @short Handle access to a medium
44 * The concrete @ref MediaHandler for a certain url is created
45 * on @ref open and deleted on @close.
47 * The inteface here basically checks whether the handler exists,
48 * then forwards the request to @ref MediaHandler.
50 class MediaAccess : public base::ReferenceCounted, private base::NonCopyable
53 typedef intrusive_ptr<MediaAccess> Ptr;
54 typedef intrusive_ptr<const MediaAccess> constPtr;
58 static const Pathname _noPath;
61 * handler for 'physical' media
64 MediaHandler * _handler;
66 friend class MediaManager;
67 friend class MediaManager_Impl;
69 AttachedMedia attachedMedia() const;
71 bool isSharedMedia() const;
74 bool dependsOnParent() const;
76 bool dependsOnParent(MediaAccessId parentId,
77 bool exactIdMatch) const;
86 * open url. If preferred_attach_point is given,
87 * try to use it as attach point.
89 * <b>Caution:</b> The medium can choose a different attach point.
90 * Only getAttachPoint() knows the real attach point.
92 * \throws MediaException
95 void open( const Url& url, const Pathname & preferred_attach_point = "" );
98 * True if media is open.
100 bool isOpen() const { return( _handler != 0 ); }
103 * Hint if files are downloaded or not.
104 * @return True, if the files are downloaded.
106 bool downloads() const;
109 * Used Protocol if media is opened, otherwise 'unknown'.
111 std::string protocol() const;
114 * Url if media is opened, otherwise empty.
121 * \throws MediaException
129 * Use concrete handler to attach the media.
131 * @param next try next available device in turn until end of device
132 * list is reached (for media which are accessible through multiple
133 * devices like cdroms).
135 * \throws MediaException
138 void attach(bool next = false);
141 * True if media is attached.
143 * \throws MediaException
146 bool isAttached() const;
148 bool hasMoreDevices() const;
151 * Fill in a vector of detected ejectable devices and the index of the
152 * currently attached device within the vector. The contents of the vector
153 * are the device names (/dev/cdrom and such).
155 * \param devices vector to load with the device names
156 * \param index index of the currently used device in the devices vector
159 getDetectedDevices(std::vector<std::string> & devices,
160 unsigned int & index) const;
164 * Return the local directory that corresponds to medias url,
165 * no matter if media isAttached or not. Files requested will
166 * be available at 'localRoot() + filename' or better
167 * 'localPath( filename )'.
169 * If media is not open an empty pathname is returned.
171 Pathname localRoot() const;
174 * Short for 'localRoot() + pathname', but returns an empty
175 * pathname if media is not open.
177 * Files provided will be available at 'localPath(filename)'.
179 Pathname localPath( const Pathname & pathname ) const;
182 Use concrete handler to disconnect the media.
184 This is useful for media which e.g. holds open a connection to a
185 server like FTP. After calling disconnect() the media object still is
186 valid and files are present.
188 After calling disconnect() it's not possible to call provideFile() or
189 provideDir() anymore.
191 * \throws MediaException
197 * Use concrete handler to release the media.
198 * @param ejectDev Device to eject. None if empty.
200 * \throws MediaException
203 void release( const std::string & ejectDev = "" );
206 * Use concrete handler to provide file denoted by path below
207 * 'attach point'. Filename is interpreted relative to the
208 * attached url and a path prefix is preserved.
210 * @param cached If cached is set to true, the function checks, if
211 * the file already exists and doesn't download it again
212 * if it does. Currently only the existence is checked,
213 * no other file attributes.
214 * @param checkonly If this and 'cached' are set to true only the
215 * existence of the file is checked but it's not
216 * downloaded. If 'cached' is unset an errer is
219 * \throws MediaException
222 void provideFile( const Pathname & filename ) const;
225 * Remove filename below attach point IFF handler downloads files
226 * to the local filesystem. Never remove anything from media.
228 * \throws MediaException
231 void releaseFile( const Pathname & filename ) const;
234 * Use concrete handler to provide directory denoted
235 * by path below 'attach point' (not recursive!).
236 * 'dirname' is interpreted relative to the
237 * attached url and a path prefix is preserved.
239 * \throws MediaException
242 void provideDir( const Pathname & dirname ) const;
245 * Use concrete handler to provide directory tree denoted
246 * by path below 'attach point' (recursive!!).
247 * 'dirname' is interpreted relative to the
248 * attached url and a path prefix is preserved.
250 * \throws MediaException
253 void provideDirTree( const Pathname & dirname ) const;
256 * Remove directory tree below attach point IFF handler downloads files
257 * to the local filesystem. Never remove anything from media.
259 * \throws MediaException
262 void releaseDir( const Pathname & dirname ) const;
265 * Remove pathname below attach point IFF handler downloads files
266 * to the local filesystem. Never remove anything from media.
268 * If pathname denotes a directory it is recursively removed.
269 * If pathname is empty or '/' everything below the attachpoint
270 * is recursively removed.
272 * \throws MediaException
275 void releasePath( const Pathname & pathname ) const;
278 * set a deltafile to be used in the next download
280 void setDeltafile( const Pathname & filename ) const;
285 * Return content of directory on media via retlist. If dots is false
286 * entries starting with '.' are not reported.
288 * The request is forwarded to the concrete handler,
289 * which may atempt to retieve the content e.g. via 'readdir'
291 * <B>Caution:</B> This is not supported by all media types.
292 * Be prepared to handle E_not_supported_by_media.
294 * \throws MediaException
297 void dirInfo( std::list<std::string> & retlist,
298 const Pathname & dirname, bool dots = true ) const;
301 * Basically the same as dirInfo above. The content is returned as
302 * filesystem::DirContent, which includes name and filetype of each directory
303 * entry. Retrieving the filetype usg. requires an additional ::stat call for
304 * each entry, thus it's more expensive than a simple readdir.
306 * <B>Caution:</B> This is not supported by all media types.
307 * Be prepared to handle E_not_supported_by_media.
309 * \throws MediaException
312 void dirInfo( filesystem::DirContent & retlist,
313 const Pathname & dirname, bool dots = true ) const;
316 * check if a file exists
318 * Asserted that url is a file and not a dir.
320 * \throws MediaException
323 bool doesFileExist( const Pathname & filename ) const;
328 virtual ~MediaAccess();
332 virtual std::ostream & dumpOn( std::ostream & str ) const;
336 * Get file from location at specified by URL and copy it to
339 * @param from Source URL
340 * @param to Destination file name
342 * \throws MediaException
345 void getFile( const Url &from, const Pathname &to );
350 * Helper class that provides file on construction
351 * and cleans up on destruction.
353 * <b>Caution:</b> There's no synchronisation between multiple
354 * FileProvider instances, that provide the same file from the
355 * same media. If the first one goes out of scope, the file is
356 * cleaned. It's just a convenience for 'access and forgett'.
358 * <b>Caution:</b> We should either store the reference MediaAccess'
359 * MediaHandler here (for this MediaHandler must become a
360 * ref counting pointer class), or we need more info from MediaHandler
361 * (whether he's downloading to the local fs. If not, no releasefile
363 * Currently we can not releaseFile after the media was closed
364 * (it's passed to the handler, which is deleted on close).
366 * \throws MediaBadFilenameException
367 * \throws MediaException
370 FileProvider( const FileProvider & ); // no copy
371 FileProvider & operator=( const FileProvider & ); // no assign
373 MediaAccess::constPtr _media;
375 Pathname _local_file;
378 * \throws MediaException
380 FileProvider( MediaAccess::constPtr media_r, const Pathname & file_r )
385 if ( _file.empty() ) {
386 ZYPP_THROW(MediaBadFilenameException(_file.asString()));
387 } else if ( _media ) {
389 _media->provideFile( _file );
390 _local_file = _media->localPath( _file );
392 catch (const MediaException & excpt_r)
394 ZYPP_CAUGHT(excpt_r);
396 ZYPP_RETHROW(excpt_r);
405 _media->releaseFile( _file );
407 catch (const MediaException &excpt_r)
409 ZYPP_CAUGHT(excpt_r);
411 catch(...) {} // No exception from dtor!
418 * If no error, expect operator() to return the local
419 * Pathname of the provided file.
421 Pathname localFile() const { return _local_file; }
424 * Return the local Pathname of the provided file or
425 * an empty Pathname on error.
427 Pathname operator()() const {
429 return _media->localPath( _file );
435 std::ostream & operator<<( std::ostream & str, const MediaAccess & obj );
437 ///////////////////////////////////////////////////////////////////
442 #endif // ZYPP_MEDIA_MEDIAACCESS_H