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