- Extended checkAttached() to allow to specify if fstype should match
[platform/upstream/libzypp.git] / zypp / media / MediaHandler.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaHandler.h
10  *
11 */
12 #ifndef ZYPP_MEDIA_MEDIAHANDLERL_H
13 #define ZYPP_MEDIA_MEDIAHANDLERL_H
14
15 #include <iosfwd>
16 #include <string>
17 #include <list>
18
19 #include "zypp/Pathname.h"
20 #include "zypp/PathInfo.h"
21 #include "zypp/base/PtrTypes.h"
22
23 #include "zypp/Url.h"
24
25 #include "zypp/media/MediaSource.h"
26 #include "zypp/media/MediaException.h"
27
28 namespace zypp {
29   namespace media {
30
31
32 ///////////////////////////////////////////////////////////////////
33 //
34 //      CLASS NAME : MediaHandler
35 /**
36  * @short Abstract base class for 'physical' MediaHandler like MediaCD, etc.
37  *
38  * Handles the requests forwarded by @ref MediaAccess. The public interface
39  * contains nonvirtual methods, which should do common sanitychecks and
40  * logging. For the real action they call virtual methods overloaded by the
41  * concrete handler.
42  **/
43 class MediaHandler {
44     friend std::ostream & operator<<( std::ostream & str, const MediaHandler & obj );
45
46     public:
47         typedef shared_ptr<MediaHandler> Ptr;
48         typedef shared_ptr<const MediaHandler> constPtr;
49
50     private:
51         /**
52          * The attached media source.
53          */
54         MediaSourceRef _mediaSource;
55
56         /**
57          * this is where the media will be actually "mounted"
58          * all files are provided 'below' this directory.
59          **/
60         AttachPointRef _attachPoint;
61
62         /**
63          * The relative root directory of the data on the media.
64          * See also _localRoot and urlpath_below_attachpoint_r
65          * constructor argument.
66          */
67         Pathname _relativeRoot;
68
69         /**
70          * The local directory that corresponds to the media url.
71          * With NFS it's the '_attachPoint', as the directory on the
72          * server is mounted. With CD/DVD it's 'attach point+_relativeRoot'
73          * because the CDs root directory is mounted. And with CIFS
74          * it's '_url.path() without the shares name'.
75          **/
76         Pathname _localRoot;
77
78         /**
79          * True if concrete handler downloads files to the local
80          * filesystem. If true releaseFile/Dir will delete them.
81          **/
82         bool _does_download;
83
84         /** timestamp of the the last attach verification */
85         mutable time_t _attach_mtime;
86
87     protected:
88         /**
89          * Url to handle
90          **/
91         const Url        _url;
92
93         /**
94          * Access Id of media handler we depend on.
95          */
96         MediaAccessId    _parentId;
97
98         /**
99          * Return the currently used attach point.
100          **/
101         Pathname         attachPoint() const;
102
103         /**
104          * Set a new attach point and update localRoot.
105          */
106         void             setAttachPoint(const Pathname &path, bool _temporary);
107
108         /**
109          * Set a (shared) attach point and update localRoot.
110          */
111         void             setAttachPoint(const AttachPointRef &ref);
112
113         /**
114          * Try to create a default / temporary attach point.
115          * \return The name of the new attach point or empty path name.
116          */
117         Pathname         createAttachPoint() const;
118
119         /**
120          * Remove unused attach point.
121          */
122         void             removeAttachPoint();
123
124         bool             isUseableAttachPoint(const Pathname &path) const;
125
126         std::string      mediaSourceName() const
127         {
128           return _mediaSource ? _mediaSource->name : "";
129         }
130
131         void             setMediaSource(const MediaSourceRef &ref);
132
133         /**
134          * MediaAccess (MediaManager) needs access to the
135          * attachedMedia() function to deliver a shared
136          * media source and its attach point to other
137          * media handler instances.
138          */
139         friend class MediaAccess;
140
141         /**
142          * Ask the media manager if specified media source
143          * is already attached.
144          */
145         AttachedMedia
146         findAttachedMedia(const MediaSourceRef &media) const;
147
148         bool                 dependsOnParent(MediaAccessId parentId);
149
150         /**
151          * Returns the attached media. Used by MediaManager
152          * to find other handlers using the same source.
153          */
154         AttachedMedia        attachedMedia() const;
155
156         bool                 isSharedMedia() const;
157
158         bool                 checkAttached(bool aDevice,
159                                            bool fsType=false) const;
160
161     protected:
162
163         ///////////////////////////////////////////////////////////////////
164         //
165         // Real action interface to be overloaded by concrete handler.
166         //
167         ///////////////////////////////////////////////////////////////////
168
169         /**
170          * Call concrete handler to attach the media.
171          *
172          * Asserted that not already attached, and attachPoint is a directory.
173          *
174          * @param next try next available device in turn until end of device
175          * list is reached (for media which are accessible through multiple
176          * devices like cdroms).
177          *
178          * \throws MediaException
179          *
180          **/
181         virtual void attachTo(bool next = false) = 0;
182
183         /**
184          * Call concrete handler to disconnect media.
185          *
186          * Asserted that media is attached.
187          *
188          * This is useful for media which e.g. holds open a connection to a
189          * server like FTP. After calling disconnect() the media object still is
190          * valid and files are present.
191          *
192          * After calling disconnect() it's not possible to call provideFile() or
193          * provideDir() anymore.
194          *
195          * \throws MediaException
196          *
197          **/
198         virtual void disconnectFrom() { return; }
199
200         /**
201          * Call concrete handler to release the media.
202          *
203          * If eject is true, and the media is used in one handler
204          * instance only, physically eject the media (i.e. CD-ROM).
205          *
206          * Asserted that media is attached.
207          *
208          * \throws MediaException
209          *
210          **/
211         virtual void releaseFrom( bool eject ) = 0;
212
213         /**
214          * Call concrete handler to physically eject the media (i.e. CD-ROM)
215          * in case the media is not attached..
216          *
217          * Asserted that media is not attached.
218          **/
219         virtual void forceEject() {}
220
221         /**
222          * Call concrete handler to provide file below attach point.
223          *
224          * Default implementation provided, that returns whether a file
225          * is located at '_localRoot + filename'.
226          *
227          * Asserted that media is attached.
228          *
229          * \throws MediaException
230          *
231          **/
232         virtual void getFile( const Pathname & filename ) const = 0;
233
234         /**
235          * Call concrete handler to provide a file under a different place
236          * in the file system (usually not under attach point) as a copy.
237          * Media must be attached before by callee.
238          *
239          * Default implementation provided that calls getFile(srcFilename)
240          * and copies the result around.
241          *
242          * \throws MediaException
243          *
244          **/
245         virtual void getFileCopy( const Pathname & srcFilename, const Pathname & targetFilename ) const;
246
247
248         /**
249          * Call concrete handler to provide directory content (not recursive!)
250          * below attach point.
251          *
252          * Return E_not_supported_by_media if media does not support retrieval of
253          * directory content.
254          *
255          * Default implementation provided, that returns whether a directory
256          * is located at '_localRoot + dirname'.
257          *
258          * Asserted that media is attached.
259          *
260          * \throws MediaException
261          *
262          **/
263         virtual void getDir( const Pathname & dirname, bool recurse_r ) const = 0;
264
265         /**
266          * Call concrete handler to provide a content list of directory on media
267          * via retlist. If dots is false entries starting with '.' are not reported.
268          *
269          * Return E_not_supported_by_media if media does not support retrieval of
270          * directory content.
271          *
272          * Default implementation provided, that returns the content of a
273          * directory at '_localRoot + dirnname' retrieved via 'readdir'.
274          *
275          * Asserted that media is attached and retlist is empty.
276          *
277          * \throws MediaException
278          *
279          **/
280         virtual void getDirInfo( std::list<std::string> & retlist,
281                                  const Pathname & dirname, bool dots = true ) const = 0;
282
283         /**
284          * Basically the same as getDirInfo above. The content list is returned as
285          * filesystem::DirContent, which includes name and filetype of each directory
286          * entry. Retrieving the filetype usg. requires an additional ::stat call for
287          * each entry, thus it's more expensive than a simple readdir.
288          *
289          * Asserted that media is attached and retlist is empty.
290          *
291          * \throws MediaException
292          *
293          **/
294         virtual void getDirInfo( filesystem::DirContent & retlist,
295                                  const Pathname & dirname, bool dots = true ) const = 0;
296
297   protected:
298
299         /**
300          * Retrieve and if available scan dirname/directory.yast.
301          *
302          * Asserted that media is attached.
303          *
304          * \throws MediaException
305          *
306          **/
307         void getDirectoryYast( std::list<std::string> & retlist,
308                                const Pathname & dirname, bool dots = true ) const;
309
310         /**
311          * Retrieve and if available scan dirname/directory.yast.
312          *
313          * Asserted that media is attached.
314          *
315          * \throws MediaException
316          *
317          **/
318         void getDirectoryYast( filesystem::DirContent & retlist,
319                                const Pathname & dirname, bool dots = true ) const;
320
321   public:
322
323         /**
324          * If the concrete media handler provides a nonempty
325          * attach_point, it must be an existing directory.
326          *
327          * On an empty attach_point, MediaHandler will create
328          * a temporay directory, which will be erased from
329          * destructor.
330          *
331          * On any error, the attach_point is set to an empty Pathname,
332          * which should lead to E_bad_attachpoint.
333          **/
334         MediaHandler ( const Url&       url_r,
335                        const Pathname & attach_point_r,
336                        const Pathname & urlpath_below_attachpoint_r,
337                        const bool       does_download_r );
338
339         /**
340          * Contolling MediaAccess takes care, that attached media is released
341          * prior to deleting this.
342          **/
343         virtual ~MediaHandler();
344
345     public:
346
347
348         ///////////////////////////////////////////////////////////////////
349         //
350         // MediaAccess interface. Does common checks and logging.
351         // Invokes real action if necessary.
352         //
353         ///////////////////////////////////////////////////////////////////
354
355         /**
356          * Protocol hint for MediaAccess.
357          **/
358         std::string protocol() const { return _url.getScheme(); }
359
360         /**
361          * Url used.
362          **/
363         Url url() const { return _url; }
364
365         /**
366          * Use concrete handler to attach the media.
367          *
368          * @param next try next available device in turn until end of device
369          * list is reached (for media which are accessible through multiple
370          * devices like cdroms).
371          *
372          * \throws MediaException
373          *
374          **/
375         void attach(bool next);
376
377         /**
378          * True if media is attached.
379          **/
380         virtual bool isAttached() const { return _mediaSource; }
381
382         /**
383          * Return the local directory that corresponds to medias url,
384          * no matter if media isAttached or not. Files requested will
385          * be available at 'localRoot() + filename' or better
386          * 'localPath( filename )'.
387          *
388          * Returns empty pathname if E_bad_attachpoint
389          **/
390         const Pathname & localRoot() const { return _localRoot; }
391
392         /**
393          * Files provided will be available at 'localPath(filename)'.
394          *
395          * Returns empty pathname if E_bad_attachpoint
396          **/
397          Pathname localPath( const Pathname & pathname ) const;
398
399         /**
400          * Use concrete handler to isconnect media.
401          *
402          * This is useful for media which e.g. holds open a connection to a
403          * server like FTP. After calling disconnect() the media object still is
404          * valid and files are present.
405          *
406          * After calling disconnect() it's not possible to call provideFile() or
407          * provideDir() anymore.
408          *
409          * \throws MediaException
410          *
411          **/
412         void disconnect();
413
414         /**
415          * Use concrete handler to release the media.
416          * @param eject if true, physically eject the media * (i.e. CD-ROM)
417          *
418          * \throws MediaException
419          *
420          **/
421         void release( bool eject = false );
422
423         /**
424          * Use concrete handler to provide file denoted by path below
425          * 'localRoot'. Filename is interpreted relative to the
426          * attached url and a path prefix is preserved.
427          *
428          * \throws MediaException
429          *
430          **/
431         void provideFile( Pathname filename ) const;
432
433         /**
434          * Call concrete handler to provide a copy of a file under a different place
435          * in the file system (usually not under attach point) as a copy.
436          * Media must be attached before by callee.
437          *
438          * @param srcFilename    Filename of source file on the media
439          * @param targetFilename Filename for the target in the file system
440          *
441          * \throws MediaException
442          *
443          **/
444         void provideFileCopy( Pathname srcFilename, Pathname targetFilename) const;
445
446         /**
447          * Use concrete handler to provide directory denoted
448          * by path below 'localRoot' (not recursive!).
449          * dirname is interpreted relative to the
450          * attached url and a path prefix is preserved.
451          *
452          * \throws MediaException
453          *
454          **/
455         void provideDir( Pathname dirname ) const;
456
457         /**
458          * Use concrete handler to provide directory tree denoted
459          * by path below 'localRoot' (recursive!!).
460          * dirname is interpreted relative to the
461          * attached url and a path prefix is preserved.
462          *
463          * \throws MediaException
464          *
465          **/
466         void provideDirTree( Pathname dirname ) const;
467
468         /**
469          * Remove filename below localRoot IFF handler downloads files
470          * to the local filesystem. Never remove anything from media.
471          *
472          * \throws MediaException
473          *
474          **/
475         void releaseFile( const Pathname & filename ) const { return releasePath( filename ); }
476
477         /**
478          * Remove directory tree below localRoot IFF handler downloads files
479          * to the local filesystem. Never remove anything from media.
480          *
481          * \throws MediaException
482          *
483          **/
484         void releaseDir( const Pathname & dirname ) const { return releasePath( dirname ); }
485
486         /**
487          * Remove pathname below localRoot IFF handler downloads files
488          * to the local filesystem. Never remove anything from media.
489          *
490          * If pathname denotes a directory it is recursively removed.
491          * If pathname is empty or '/' everything below the localRoot
492          * is recursively removed.
493          * If pathname denotes a file it is unlinked.
494          *
495          * \throws MediaException
496          *
497          **/
498         void releasePath( Pathname pathname ) const;
499
500     public:
501
502         /**
503          * Return content of directory on media via retlist. If dots is false
504          * entries starting with '.' are not reported.
505          *
506          * The request is forwarded to the concrete handler,
507          * which may atempt to retieve the content e.g. via 'readdir'
508          *
509          * <B>Caution:</B> This is not supported by all media types.
510          * Be prepared to handle E_not_supported_by_media.
511          *
512          * \throws MediaException
513          *
514          **/
515         void dirInfo( std::list<std::string> & retlist,
516                       const Pathname & dirname, bool dots = true ) const;
517
518         /**
519          * Basically the same as dirInfo above. The content is returned as
520          * filesystem::DirContent, which includes name and filetype of each directory
521          * entry. Retrieving the filetype usg. requires an additional ::stat call for
522          * each entry, thus it's more expensive than a simple readdir.
523          *
524          * <B>Caution:</B> This is not supported by all media types.
525          * Be prepared to handle E_not_supported_by_media.
526          *
527          * \throws MediaException
528          *
529          **/
530         void dirInfo( filesystem::DirContent & retlist,
531                       const Pathname & dirname, bool dots = true ) const;
532 };
533
534 ///////////////////////////////////////////////////////////////////
535
536 #define MEDIA_HANDLER_API                                               \
537     protected:                                                          \
538         virtual void attachTo (bool next = false);                      \
539         virtual void releaseFrom( bool eject );                 \
540         virtual void getFile( const Pathname & filename ) const;        \
541         virtual void getDir( const Pathname & dirname, bool recurse_r ) const;  \
542         virtual void getDirInfo( std::list<std::string> & retlist,      \
543                                     const Pathname & dirname, bool dots = true ) const; \
544         virtual void getDirInfo( filesystem::DirContent & retlist,      \
545                                     const Pathname & dirname, bool dots = true ) const;
546
547   } // namespace media
548 } // namespace zypp
549
550
551 #endif // ZYPP_MEDIA_MEDIAHANDLERL_H
552
553