- Added Media Access Url documentation.
[platform/upstream/libzypp.git] / zypp / media / MediaManager.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaManager.h
10  *
11 */
12 #ifndef ZYPP_MEDIA_MEDIAMANAGER_H
13 #define ZYPP_MEDIA_MEDIAMANAGER_H
14
15 #include <zypp/media/MediaAccess.h>
16
17 #include <zypp/base/Deprecated.h>
18 #include <zypp/base/NonCopyable.h>
19 #include <zypp/base/PtrTypes.h>
20 #include <zypp/Pathname.h>
21 #include <zypp/Url.h>
22
23 #include <list>
24
25
26 //////////////////////////////////////////////////////////////////////
27 namespace zypp
28 { ////////////////////////////////////////////////////////////////////
29
30   ////////////////////////////////////////////////////////////////////
31   namespace media
32   { //////////////////////////////////////////////////////////////////
33
34
35     ///////////////////////////////////////////////////////////////////
36     typedef zypp::RW_pointer<MediaAccess> MediaAccessRef;
37
38     // OBSOLETE HERE:
39     typedef MediaAccessId                 MediaId;
40     typedef unsigned int                  MediaNr;
41
42
43     ///////////////////////////////////////////////////////////////////
44     // forward declaration
45     class MountEntry;
46
47
48     ///////////////////////////////////////////////////////////////////
49     //
50     // CLASS NAME : MediaVerifierBase
51     //
52     /**
53      * Interface to implement a media verifier.
54      */
55     class MediaVerifierBase //: private zypp::NonCopyable
56     {
57     public:
58       MediaVerifierBase()
59       {}
60
61       virtual
62       ~MediaVerifierBase()
63       {}
64
65       /*
66       ** Check if the specified attached media contains
67       ** the desired media (e.g. SLES10 CD1).
68       */
69       virtual bool
70       isDesiredMedia(const MediaAccessRef &ref) = 0;
71     };
72
73
74     ///////////////////////////////////////////////////////////////////
75     //
76     // CLASS NAME : NoVerifier
77     //
78     /**
79      * Dummy default media verifier, which is always happy.
80      */
81     class NoVerifier : public MediaVerifierBase
82     {
83     public:
84       NoVerifier(): MediaVerifierBase()
85       {}
86
87       virtual
88       ~NoVerifier()
89       {}
90
91       /*
92       ** Don't check if the specified attached media contains
93       ** the desired media number. Always return true.
94       */
95       virtual bool
96       isDesiredMedia(const MediaAccessRef &ref)
97       {
98         (void)ref;
99         return true;
100       }
101     };
102
103
104     ///////////////////////////////////////////////////////////////////
105     //
106     // CLASS NAME : MediaVerifierRef
107     //
108     /**
109      * A shared reference to the MediaVerifier implementation.
110      */
111     typedef zypp::RW_pointer<MediaVerifierBase> MediaVerifierRef;
112
113
114     ///////////////////////////////////////////////////////////////////
115     //
116     // CLASS NAME : MediaManager
117     //
118     /**
119      * Manages coordinated access to 'physical' media, e.g CDROM
120      * drives using \ref MediaAccessUrl's.
121      *
122      * \note The MediaManager class is just an envelope around an
123      *       inner singelton like implementation.
124      *       <br>
125      *       This means, you can create as many managers as you want,
126      *       also temporary in a function call.
127      *       <br>
128      *       Don't declare static MediaManager instances, unless
129      *       you want to force (mutex) initialization order problems!
130      *
131      * \section MediaAccessUrl Media Access Url
132      * The Media Manager currently supports following access handlers
133      * (backends), that can be specified by the media access URLs in
134      * the media manager's open() method.
135      *
136      * - MediaCD:
137      *   Supports multiple CD or DVD drives.
138      *   - Examples:
139      *     \code
140      *       "cd:/"
141      *       "cd:/?devices=/dev/hda,/dev/hdb"
142      *       "cd:/subdir?devices=/dev/hda,/dev/hdb"
143      *       "dvd:/"
144      *       "dvd:/?devices=/dev/hda,/dev/hdb"
145      *       "dvd:/subdir?devices=/dev/hda,/dev/hdb"
146      *     \endcode
147      *   - Scheme:
148      *     - <b>cd</b>: Requires a drive supporting CD media.
149      *     - <b>dvd</b>: Requires a drive supporting DVD media.
150      *   - Authority:
151      *     A non-empty authority URL component (e.g. containing a host
152      *     name) is not allowed.
153      *   - Path name:
154      *     Specifies a subdirectory on the CD/DVD, where the desired files
155      *     are located. In case of "/", the CD/DVD's root directory (the
156      *     mount point) is used.
157      *   - Query parameters:
158      *     - <tt>devices</tt>:
159      *       Optional parameter, containing a comma separated list of block
160      *       device names to use.
161      *       <br>
162      *       The device names will be verified using a HAL query. If one of
163      *       the provided devices is not usable (not a block device, or does
164      *       not support required media type), exception is thrown.
165      *       <br>
166      *       If the devices parameter is not provided (or empty), all
167      *       avaliable CD/DVD drives 'detected' using a HAL query. The
168      *       preferred drive (used as first drive) is the drive pointed to
169      *       by the symlink "/dev/dvd" ("dvd" scheme only) or "/dev/cdrom".
170      *
171      * - MediaNFS:
172      *   - Examples:
173      *     \code
174      *        "nfs://nfs-server/exported/path"
175      *        "nfs://nfs-server/exported/path?mountoptions=ro"
176      *     \endcode
177      *   - Scheme:
178      *     - <b>nfs</b>
179      *   - Authority:
180      *     The authority component has to provide a hostname.
181      *     Username, password and port are currently ignored.
182      *   - Path name:
183      *     Exported (sub-)directory on the NFS server where the desired
184      *     files are located.
185      *   - Query parameters:
186      *     - <tt>mountoptions</tt>:
187      *       The mount options separated by comma ','.
188      *       Default is the "ro" option.
189      *
190      * - MediaCIFS (MediaSMB):
191      *   - Examples:
192      *     \code
193      *       "cifs://servername/share/path/on/the/share"
194      *       "cifs://username:passwd@servername/share/path/on/the/share?mountoptions=ro"
195      *       "smb://servername/share/path/on/the/share"
196      *       "smb://username:passwd@servername/share/path/on/the/share?mountoptions=ro"
197      *     \endcode
198      *   - Scheme:
199      *     - <b>cifs</b>
200      *     - <b>smb</b>: Just an alias for 'cifs'.
201      *   - Authority:
202      *     The authority component has to provide a hostname. Optionally
203      *     also a username and password.
204      *   - Path name:
205      *     The share name with optional subdirectory where the desired
206      *     files are located.
207      *   - Query parameters:
208      *     - <tt>mountoptions</tt>:
209      *       The mount options separated by a comma ','. Default are the
210      *       "ro" and "guest" options.
211      *     - <tt>workgroup</tt>:
212      *       The name of the workgroup.
213      *     - <tt>username</tt>:
214      *       Alternative username to username in URL authority.
215      *     - <tt>password</tt>:
216      *       Alternative password to password in URL authority.
217      *     - <tt>user</tt>:
218      *       Alternative username (cifs specific variant?)
219      *     - <tt>pass</tt>:
220      *       Alternative password (cifs specific variant?)
221      *
222      * - MediaCurl:
223      *   - Examples:
224      *     \code
225      *       "ftp://server/path/on/server"
226      *       "http://server/path/on/server"
227      *       "https://server/path/on/server"
228      *       "http://user:pass@server/path"
229      *       "http://user:pass@server/path?proxy=foo&proxyuser=me&proxypass=pw"
230      *     \endcode
231      *   - Scheme:
232      *     - <b>ftp</b>
233      *     - <b>http</b>
234      *     - <b>https</b>
235      *   - Authority:
236      *     The authority component has to provide a hostname. Optionally
237      *     also a username and password. In case of the 'ftp' scheme,
238      *     username and password defaults to 'anonymous' and 'yast2@'.
239      *   - Path name:
240      *     The path name on the server where the desired files are located.
241      *   - Query parameters:
242      *     - <tt>proxy</tt>:
243      *       A proxy hostname or hostname and port separated by ':'.
244      *     - <tt>proxyport</tt>:
245      *       Alternative way to provide the proxy port.
246      *     - <tt>proxyuser</tt>:
247      *       The proxy username.
248      *     - <tt>proxypass</tt>:
249      *       The proxy password. 
250      *
251      * - MediaDIR:
252      *   - Examples:
253      *     \code
254      *       "dir:/directory/name"
255      *       "file:/directory/name"
256      *     \endcode
257      *   - Scheme:
258      *     - <b>dir</b>
259      *     - <b>file</b>
260      *   - Authority:
261      *     A non-empty authority URL component (e.g. containing
262      *     a host name) is not allowed.
263      *   - Path name:
264      *     Specifies a directory, where the desired files are located.
265      *   - Query parameters:
266      *     none 
267      *
268      * - MediaDISK:
269      *   - Examples:
270      *     \code
271      *       "hd:/?device=/dev/hda1"
272      *       "hd:/subdir?device=/dev/sda1"
273      *       "hd:/subdir?device=/dev/sda1&filesystem=reiserfs"
274      *     \endcode
275      *   - Scheme:
276      *     - <b>hd</b>
277      *   - Authority:
278      *     A non-empty authority URL component is not allowed.
279      *   - Path name:
280      *     Specifies a subdirectory on the disk partition, where the desired
281      *     files are located. In case of "/", the partition's root directory
282      *     (its mount point) is used.
283      *   - Query parameters:
284      *     - <tt>device</tt>:
285      *       Mandatory parameter specifying the name of the block device of
286      *       the partition to mount.
287      *     - <tt>filesystem</tt>:
288      *       The name of the filesystem. Defaults to "auto". 
289      *
290      * - MediaISO:
291      *   - Examples:
292      *     \code
293      *       "iso:/?iso=/local/directory/filename.iso"
294      *       "iso:/?iso=filename.iso&url=nfs://nfs-server/exported/directory"
295      *       "iso:/isoSubdir?iso=urlSubdir/filename.iso&filesystem=iso9660&mnt=/urlAttachPoint&url=nfs://nfs-server/directory"
296      *     \endcode
297      *   - Scheme:
298      *     - <b>iso</b>
299      *   - Authority:
300      *     A non-empty authority URL component is not allowed.
301      *   - Path name:
302      *     Specifies a subdirectory inside of the iso file, where the desired
303      *     files are located. In case of "/", the iso files's root directory
304      *     (its mount point) is used.
305      *   - Query parameters:
306      *     - <tt>iso</tt>:
307      *       Mandatory parameter specifying the name of the iso file.
308      *       - If the url parameter is present, the filename can contain a
309      *        relative path to the iso file below of the location pointed by
310      *        the url parameter.
311      *       - If the url parameter is missed, the iso parameter has to point
312      *         to the absolute iso file name.
313      *     - <tt>url</tt>:
314      *       Optional parameter specifying the iso filename's source media url
315      *       pointing to a directory.
316      *       <br>
317      *       Note: <i>The iso filename's source media url schemes are limited
318      *             to: <b>hd</b>, <b>dir</b>, <b>file</b>,
319      *                 <b>nfs</b>, <b>smb</b>, <b>cifs</b>.</i>
320      *     - <tt>mnt</tt>:
321      *       Optional parameter specifying the prefered attach point for the
322      *       source media url.
323      *     - <tt>filesystem</tt>:
324      *       Optional name of the filesystem used in the iso file. Defaults
325      *       to "auto". 
326      */
327     class MediaManager: private zypp::base::NonCopyable
328     {
329     public:
330       /**
331        * Creates a MediaManager envelope instance.
332        *
333        * In the case, that the inner implementation is not already
334        * allocated, and the MediaManager constructor was unable to
335        * allocate it, a std::bad_alloc exception is thrown.
336        *
337        * All further instances increase the use counter only.
338        *
339        * \throws std::bad_alloc
340        */
341       MediaManager();
342
343       /**
344        * Destroys MediaManager envelope instance.
345        * Decreases the use counter of the inner implementation.
346        */
347       ~MediaManager();
348
349       /**
350        * Opens the media access for specified with the url.
351        *
352        * If the \p preferred_attach_point parameter does not
353        * point to a usable attach point directory, the media
354        * manager automatically creates a temporary attach
355        * point in a default directory. This default directory
356        * can be changed using setAttachPrefix() function.
357        *
358        * Remember to close() each id you've opened and not
359        * need any more. It is like a new and delete!
360        *
361        * \param  url The \ref MediaAccessUrl.
362        * \param  preferred_attach_point The preferred, already
363        *         existing directory, where the media should be
364        *         attached.
365        * \return a new media access id.
366        * \throws std::bad_alloc
367        * \throws MediaException
368        */
369       MediaAccessId
370       open(const Url &url, const Pathname & preferred_attach_point = "");
371
372       /**
373        * Close the media access with specified id.
374        * \param accessId The media access id to close.
375        */
376       void
377       close(MediaAccessId accessId);
378
379       /**
380        * Query if the media access is open / exists.
381        *
382        * \param accessId The media access id query.
383        * \return true, if access id is known and open.
384        */
385       bool
386       isOpen(MediaAccessId accessId) const;
387
388       /**
389        * Query the protocol name used by the media access
390        * handler. Similar to url().getScheme().
391        *
392        * \param accessId The media access id query.
393        * \return The protocol name used by the media access
394        *         handler, otherwise 'unknown'.
395        * \throws MediaNotOpenException for invalid access id.
396        */
397       std::string
398       protocol(MediaAccessId accessId) const;
399
400       /**
401              * Hint if files are downloaded or not.
402              */
403             bool
404       downloads(MediaAccessId accessId) const;
405
406       /**
407        * Returns the \ref MediaAccessUrl of the media access id.
408        *
409        * \throws MediaNotOpenException for invalid access id.
410        */
411       Url
412       url(MediaAccessId accessId) const;
413
414     public:
415       /**
416        * Add verifier implementation for the specified media id.
417        * By default, the NoVerifier is used.
418        *
419        * \throws MediaNotOpenException for invalid access id.
420        */
421       void
422       addVerifier(MediaAccessId accessId,
423                   const MediaVerifierRef &verifier);
424
425       /**
426        * Remove verifier for specified media id.
427        *
428        * \throws MediaNotOpenException for invalid access id.
429        */
430       void
431       delVerifier(MediaAccessId accessId);
432
433     public:
434       /**
435        * Set or resets the directory name, where the media manager
436        * handlers create their temporary attach points (see open()
437        * function).
438        * It has effect to newly created temporary attach points only.
439        *
440        * \param attach_prefix The new prefix for temporary attach
441        *        points, or empty pathname to reset to defaults.
442        * \return True on success, false if the \p attach_prefix
443        *         parameters contains a path name, that does not
444        *         point to a writable directory.
445        */
446       bool
447       setAttachPrefix(const Pathname &attach_prefix);
448
449       /**
450        * Attach the media using the concrete handler.
451        *
452        * Remember to release() or close() each id you've attached
453        * and not need any more. Attach is like an open of a file!
454        *
455        * \throws MediaNotOpenException for invalid access id.
456        */
457       void
458       attach(MediaAccessId accessId, bool next = false);
459
460       /**
461        * Reattach to a new attach point.
462        *
463        * \deprecated This function will be removed, because the
464        * reattach function has race conditions (e.g. open file
465        * in the old attach point). Use setAttachPrefix() instead.
466        *
467        * \param accessId A media access Id.
468        * \param attach_point A new attach point directory.
469        * \param temporary    Whether to reattach to a temporary
470        *      attach point bellow of \p attach_point and cleanup
471        *      it on release (temporary=true), or use the provided
472        *      directory as attach point without to cleanup it on
473        *      release (temporary=false, default behaviour).
474        * \throws MediaNotOpenException
475        * \throws MediaNotSupportedException
476        */
477       void
478       reattach(MediaAccessId   accessId,
479                const Pathname &attach_point,
480                bool            temporary = false) ZYPP_DEPRECATED;
481
482       /**
483        * Release the attached media and optionally eject.
484        *
485        * \throws MediaNotOpenException for invalid access id.
486        */
487       void
488       release(MediaAccessId accessId, bool eject = false);
489
490       /**
491        * Disconnect a remote media.
492        *
493        * This is useful for media which e.g. holds open a connection
494        * to a server like FTP. After calling disconnect() the media
495        * object (attach point) is still valid and files are present.
496        *
497        * But after calling disconnect() it's not possible to call
498        * fetch more data using the provideFile() or provideDir()
499        * functions anymore.
500        *
501        * \throws MediaNotOpenException for invalid access id.
502        */
503       void
504       disconnect(MediaAccessId accessId);
505
506       /**
507        * Check if media is attached or not.
508        *
509        * \return True if media is attached.
510        * \throws MediaNotOpenException for invalid access id.
511        */
512       bool
513       isAttached(MediaAccessId accessId) const;
514
515       /**
516        * Returns information if media is on a shared
517        * physical device or not.
518        *
519        * \return True if it is shared, false if not.
520        * \throws MediaNotOpenException for invalid access id.
521        */
522       bool
523       isSharedMedia(MediaAccessId accessId) const;
524
525       /**
526        * Ask the registered verifier if the attached
527        * media is the desired one or not.
528        * \return True if media is attached and desired
529        *         according to the actual verifier.
530        * \throws MediaNotOpenException for invalid access id.
531        */
532       bool
533       isDesiredMedia(MediaAccessId accessId) const;
534
535       /**
536        * Ask the specified verifier if the attached
537        * media is the desired one or not.
538        * \return True if media is attached and desired
539        *         according to the specified verifier.
540        * \throws MediaNotOpenException for invalid access id.
541        */
542       bool
543       isDesiredMedia(MediaAccessId           accessId,
544                      const MediaVerifierRef &verifier) const;
545
546       /**
547        * Return the local directory that corresponds to medias url,
548        * no matter if media isAttached or not. Files requested will
549        * be available at 'localRoot() + filename' or even better
550        * 'localPath( filename )'
551        *
552        * \returns The directory name pointing to the media root
553        *          in local filesystem or an empty pathname if the
554        *          media is not attached.
555        * \throws MediaNotOpenException for invalid access id.
556        */
557       Pathname
558       localRoot(MediaAccessId accessId) const;
559
560       /**
561        * Shortcut for 'localRoot() + pathname', but returns an empty
562        * pathname if media is not attached.
563        * Files provided will be available at 'localPath(filename)'.
564        * \returns The directory name in local filesystem pointing
565        *          to the desired relative pathname on the media
566        *          or an empty pathname if the media is not attached.
567        * \throws MediaNotOpenException for invalid access id.
568        */
569       Pathname
570       localPath(MediaAccessId accessId, const Pathname & pathname) const;
571
572     public:
573       /**
574        * Provide provide file denoted by relative path below of the
575        * 'attach point' of the specified media and the path prefix
576        * on the media.
577        *
578        * \param accessId  The media access id to use.
579        * \param filename  The filename to provide, relative on the media.
580        * \param cached    If cached is set to true, the function checks, if
581        *                  the file already exists and doesn't download it again
582        *                  if it does. Currently only the existence is checked,
583        *                  no other file attributes.
584        * \param checkonly If this and 'cached' are set to true only the
585        *                  existence of the file is checked but it's not
586        *                  downloaded. If 'cached' is unset an errer is
587        *                  returned always.
588        *
589        * \throws MediaNotOpenException in case of invalid access id.
590        * \throws MediaNotAttachedException in case, that the media is not attached.
591        * \throws MediaNotDesiredException in case, that the media verification failed.
592        * \throws MediaNotAFileException in case, that the requested filename is not a file.
593        * \throws MediaFileNotFoundException in case, that the requested filenamedoes not exists.
594        * \throws MediaWriteException in case, that the file can't be copied from from remote source.
595        * \throws MediaSystemException in case a system operation fails.
596        * \throws MediaException derived exception, depending on the url (handler).
597        */
598       void
599       provideFile(MediaAccessId   accessId,
600                   const Pathname &filename,
601                   bool            cached    = false,
602                   bool            checkonly = false) const;
603
604       /**
605        */
606       void
607       provideDir(MediaAccessId   accessId,
608                  const Pathname &dirname) const;
609
610       /**
611        */
612       void
613       provideDirTree(MediaAccessId  accessId,
614                      const Pathname &dirname) const;
615
616       /**
617        */
618       void
619       releaseFile(MediaAccessId   accessId,
620                   const Pathname &filename) const;
621
622       /**
623        */
624       void
625       releaseDir(MediaAccessId   accessId,
626                  const Pathname &dirname) const;
627
628       /**
629        */
630       void
631       releasePath(MediaAccessId   accessId,
632                   const Pathname &pathname) const;
633
634       /**
635        */
636       void
637       dirInfo(MediaAccessId           accessId,
638               std::list<std::string> &retlist,
639               const Pathname         &dirname,
640               bool                    dots = true) const;
641
642       /**
643        */
644       void
645       dirInfo(MediaAccessId           accessId,
646               filesystem::DirContent &retlist,
647               const Pathname         &dirname,
648               bool                   dots = true) const;
649
650
651     public:
652       time_t
653       getMountTableMTime() const;
654
655       std::vector<MountEntry>
656       getMountEntries() const;
657
658       bool
659       isUseableAttachPoint(const Pathname &path) const;
660
661     private:
662       friend class MediaHandler;
663
664       AttachedMedia
665       getAttachedMedia(MediaAccessId &accessId) const;
666
667       AttachedMedia
668       findAttachedMedia(const MediaSourceRef &media) const;
669
670       void
671       forceMediaRelease(const MediaSourceRef &media);
672
673     private:
674       class  Impl;
675       static zypp::RW_pointer<MediaManager::Impl> m_impl;
676     };
677
678
679     //////////////////////////////////////////////////////////////////
680   } // namespace media
681   ////////////////////////////////////////////////////////////////////
682
683   ////////////////////////////////////////////////////////////////////
684 } // namespace zypp
685 //////////////////////////////////////////////////////////////////////
686
687 #endif // ZYPP_MEDIA_MEDIAMANAGER_H
688
689 /*
690 ** vim: set ts=2 sts=2 sw=2 ai et:
691 */