- More 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 singleton like implementation.<br>
124      *       This means, you can create as many managers as you want,
125      *       also temporary in a function call.<br>
126      *       Don't declare static MediaManager instances, unless
127      *       you want to force (mutex) initialization order problems!
128      *
129      * \section MediaAccessUrl Media Access Url
130      * The Media Manager currently supports following access handlers
131      * (backends), that can be specified by the media access URLs in
132      * the media manager's open() method.
133      *
134      * - MediaCD:
135      *   Supports multiple CD or DVD drives.
136      *   - Examples:
137      *     \code
138      *       "cd:/"
139      *       "cd:/?devices=/dev/hda,/dev/hdb"
140      *       "cd:/subdir?devices=/dev/hda,/dev/hdb"
141      *       "dvd:/"
142      *       "dvd:/?devices=/dev/hda,/dev/hdb"
143      *       "dvd:/subdir?devices=/dev/hda,/dev/hdb"
144      *     \endcode
145      *   - Scheme:
146      *     - <b>cd</b>: Requires a drive supporting CD media.
147      *     - <b>dvd</b>: Requires a drive supporting DVD media.
148      *   - Authority:
149      *     A non-empty authority URL component (e.g. containing a host
150      *     name) is not allowed.
151      *   - Path name:
152      *     Specifies a subdirectory on the CD/DVD, where the desired files
153      *     are located. In case of "/", the CD/DVD's root directory (the
154      *     mount point) is used.
155      *   - Query parameters:
156      *     - <tt>devices</tt>:
157      *       Optional parameter, containing a comma separated list of block
158      *       device names to use.
159      *       <br>
160      *       The device names will be verified using a HAL query. If one of
161      *       the provided devices is not usable (not a block device, or does
162      *       not support required media type), exception is thrown.
163      *       <br>
164      *       If the devices parameter is not provided (or empty), all
165      *       avaliable CD/DVD drives 'detected' using a HAL query. The
166      *       preferred drive (used as first drive) is the drive pointed to
167      *       by the symlink "/dev/dvd" ("dvd" scheme only) or "/dev/cdrom".
168      *
169      * - MediaNFS:
170      *   - Examples:
171      *     \code
172      *        "nfs://nfs-server/exported/path"
173      *        "nfs://nfs-server/exported/path?mountoptions=ro"
174      *     \endcode
175      *   - Scheme:
176      *     - <b>nfs</b>
177      *   - Authority:
178      *     The authority component has to provide a hostname.
179      *     Username, password and port are currently ignored.
180      *   - Path name:
181      *     Exported (sub-)directory on the NFS server where the desired
182      *     files are located.
183      *   - Query parameters:
184      *     - <tt>mountoptions</tt>:
185      *       The mount options separated by comma ','.
186      *       Default is the "ro" option.
187      *
188      * - MediaCIFS (MediaSMB):
189      *   - Examples:
190      *     \code
191      *       "cifs://servername/share/path/on/the/share"
192      *       "cifs://username:passwd@servername/share/path/on/the/share?mountoptions=ro"
193      *       "smb://servername/share/path/on/the/share"
194      *       "smb://username:passwd@servername/share/path/on/the/share?mountoptions=ro"
195      *     \endcode
196      *   - Scheme:
197      *     - <b>cifs</b>
198      *     - <b>smb</b>: Just an alias for 'cifs'.
199      *   - Authority:
200      *     The authority component has to provide a hostname. Optionally
201      *     also a username and password.
202      *   - Path name:
203      *     The share name with optional subdirectory where the desired
204      *     files are located.
205      *   - Query parameters:
206      *     - <tt>mountoptions</tt>:
207      *       The mount options separated by a comma ','. Default are the
208      *       "ro" and "guest" options.
209      *     - <tt>workgroup</tt>:
210      *       The name of the workgroup.
211      *     - <tt>username</tt>:
212      *       Alternative username to username in URL authority.
213      *     - <tt>password</tt>:
214      *       Alternative password to password in URL authority.
215      *     - <tt>user</tt>:
216      *       Alternative username (cifs specific variant?)
217      *     - <tt>pass</tt>:
218      *       Alternative password (cifs specific variant?)
219      *
220      * - MediaCurl:
221      *   - Examples:
222      *     \code
223      *       "ftp://server/path/on/server"
224      *       "http://server/path/on/server"
225      *       "https://server/path/on/server"
226      *       "http://user:pass@server/path"
227      *       "http://user:pass@server/path?proxy=foo&proxyuser=me&proxypass=pw"
228      *     \endcode
229      *   - Scheme:
230      *     - <b>ftp</b>
231      *     - <b>http</b>
232      *     - <b>https</b>
233      *   - Authority:
234      *     The authority component has to provide a hostname. Optionally
235      *     also a username and password. In case of the 'ftp' scheme,
236      *     username and password defaults to 'anonymous' and 'yast2@'.
237      *   - Path name:
238      *     The path name on the server where the desired files are located.
239      *   - Query parameters:
240      *     - <tt>proxy</tt>:
241      *       A proxy hostname or hostname and port separated by ':'.
242      *     - <tt>proxyport</tt>:
243      *       Alternative way to provide the proxy port.
244      *     - <tt>proxyuser</tt>:
245      *       The proxy username.
246      *     - <tt>proxypass</tt>:
247      *       The proxy password. 
248      *
249      * - MediaDIR:
250      *   - Examples:
251      *     \code
252      *       "dir:/directory/name"
253      *       "file:/directory/name"
254      *     \endcode
255      *   - Scheme:
256      *     - <b>dir</b>
257      *     - <b>file</b>
258      *   - Authority:
259      *     A non-empty authority URL component (e.g. containing
260      *     a host name) is not allowed.
261      *   - Path name:
262      *     Specifies a directory, where the desired files are located.
263      *   - Query parameters:
264      *     none 
265      *
266      * - MediaDISK:
267      *   - Examples:
268      *     \code
269      *       "hd:/?device=/dev/hda1"
270      *       "hd:/subdir?device=/dev/sda1"
271      *       "hd:/subdir?device=/dev/sda1&filesystem=reiserfs"
272      *     \endcode
273      *   - Scheme:
274      *     - <b>hd</b>
275      *   - Authority:
276      *     A non-empty authority URL component is not allowed.
277      *   - Path name:
278      *     Specifies a subdirectory on the disk partition, where the desired
279      *     files are located. In case of "/", the partition's root directory
280      *     (its mount point) is used.
281      *   - Query parameters:
282      *     - <tt>device</tt>:
283      *       Mandatory parameter specifying the name of the block device of
284      *       the partition to mount.
285      *     - <tt>filesystem</tt>:
286      *       The name of the filesystem. Defaults to "auto". 
287      *
288      * - MediaISO:
289      *   - Examples:
290      *     \code
291      *       "iso:/?iso=/local/directory/filename.iso"
292      *       "iso:/?iso=filename.iso&url=nfs://nfs-server/exported/directory"
293      *       "iso:/isoSubdir?iso=urlSubdir/filename.iso&filesystem=iso9660&mnt=/urlAttachPoint&url=nfs://nfs-server/directory"
294      *     \endcode
295      *   - Scheme:
296      *     - <b>iso</b>
297      *   - Authority:
298      *     A non-empty authority URL component is not allowed.
299      *   - Path name:
300      *     Specifies a subdirectory inside of the iso file, where the desired
301      *     files are located. In case of "/", the iso files's root directory
302      *     (its mount point) is used.
303      *   - Query parameters:
304      *     - <tt>iso</tt>:
305      *       Mandatory parameter specifying the name of the iso file.
306      *       - If the url parameter is present, the filename can contain a
307      *        relative path to the iso file below of the location pointed by
308      *        the url parameter.
309      *       - If the url parameter is missed, the iso parameter has to point
310      *         to the absolute iso file name.
311      *     - <tt>url</tt>:
312      *       Optional parameter specifying the iso filename's source media url
313      *       pointing to a directory.
314      *       <br>
315      *       Note: <i>The iso filename's source media url schemes are limited
316      *             to: <b>hd</b>, <b>dir</b>, <b>file</b>,
317      *                 <b>nfs</b>, <b>smb</b>, <b>cifs</b>.</i>
318      *     - <tt>mnt</tt>:
319      *       Optional parameter specifying the prefered attach point for the
320      *       source media url.
321      *     - <tt>filesystem</tt>:
322      *       Optional name of the filesystem used in the iso file. Defaults
323      *       to "auto". 
324      */
325     class MediaManager: private zypp::base::NonCopyable
326     {
327     public:
328       /**
329        * Creates a MediaManager envelope instance.
330        *
331        * In the case, that the inner implementation is not already
332        * allocated, and the MediaManager constructor was unable to
333        * allocate it, a std::bad_alloc exception is thrown.
334        *
335        * All further instances increase the use counter only.
336        *
337        * \throws std::bad_alloc
338        */
339       MediaManager();
340
341       /**
342        * Destroys MediaManager envelope instance.
343        * Decreases the use counter of the inner implementation.
344        */
345       ~MediaManager();
346
347       /**
348        * Opens the media access for specified with the url.
349        *
350        * If the \p preferred_attach_point parameter does not
351        * point to a usable attach point directory, the media
352        * manager automatically creates a temporary attach
353        * point in a default directory. This default directory
354        * can be changed using setAttachPrefix() function.
355        *
356        * Remember to close() each id you've opened and not
357        * need any more. It is like a new and delete!
358        *
359        * \param  url The \ref MediaAccessUrl.
360        * \param  preferred_attach_point The preferred, already
361        *         existing directory, where the media should be
362        *         attached.
363        * \return a new media access id.
364        * \throws std::bad_alloc
365        * \throws MediaException
366        */
367       MediaAccessId
368       open(const Url &url, const Pathname & preferred_attach_point = "");
369
370       /**
371        * Close the media access with specified id.
372        * \param accessId The media access id to close.
373        */
374       void
375       close(MediaAccessId accessId);
376
377       /**
378        * Query if the media access is open / exists.
379        *
380        * \param accessId The media access id to query.
381        * \return true, if access id is known and open.
382        */
383       bool
384       isOpen(MediaAccessId accessId) const;
385
386       /**
387        * Query the protocol name used by the media access
388        * handler. Similar to url().getScheme().
389        *
390        * \param accessId The media access id to query.
391        * \return The protocol name used by the media access
392        *         handler, otherwise 'unknown'.
393        * \throws MediaNotOpenException for invalid access id.
394        */
395       std::string
396       protocol(MediaAccessId accessId) const;
397
398       /**
399              * Hint if files are downloaded or not.
400        * \param accessId The media access id to query.
401        * \return True, if provideFile downloads files.
402              */
403             bool
404       downloads(MediaAccessId accessId) const;
405
406       /**
407        * Returns the \ref MediaAccessUrl of the media access id.
408        *
409        * \param accessId The media access id to query.
410        * \return The \ref MediaAccessUrl used by the media access id.
411        * \throws MediaNotOpenException for invalid access id.
412        */
413       Url
414       url(MediaAccessId accessId) const;
415
416     public:
417       /**
418        * Add verifier implementation for the specified media id.
419        * By default, the NoVerifier is used.
420        *
421        * \param accessId A media access id.
422        * \param verifier The new verifier.
423        * \throws MediaNotOpenException for invalid access id.
424        */
425       void
426       addVerifier(MediaAccessId accessId,
427                   const MediaVerifierRef &verifier);
428
429       /**
430        * Remove verifier for specified media id.
431        * It resets the verifier to NoVerifier.
432        *
433        * \param accessId A media access id.
434        * \throws MediaNotOpenException for invalid access id.
435        */
436       void
437       delVerifier(MediaAccessId accessId);
438
439     public:
440       /**
441        * Set or resets the directory name, where the media manager
442        * handlers create their temporary attach points (see open()
443        * function).
444        * It has effect to newly created temporary attach points only.
445        *
446        * \param attach_prefix The new prefix for temporary attach
447        *        points, or empty pathname to reset to defaults.
448        * \return True on success, false if the \p attach_prefix
449        *         parameters contains a path name, that does not
450        *         point to a writable directory.
451        */
452       bool
453       setAttachPrefix(const Pathname &attach_prefix);
454
455       /**
456        * Attach the media using the concrete handler.
457        *
458        * Remember to release() or close() each id you've attached
459        * and not need any more. Attach is like an open of a file!
460        *
461        * \param accessId A media access id.
462        * \param next     Whether to try the next drive if avaliable.
463        * \throws MediaNotOpenException for invalid access id.
464        */
465       void
466       attach(MediaAccessId accessId, bool next = false);
467
468       /**
469        * Reattach to a new attach point.
470        *
471        * \deprecated This function will be removed, because the
472        * reattach function has race conditions (e.g. open file
473        * in the old attach point). Use setAttachPrefix() instead.
474        *
475        * \param accessId A media access Id.
476        * \param attach_point A new attach point directory.
477        * \param temporary    Whether to reattach to a temporary
478        *      attach point bellow of \p attach_point and cleanup
479        *      it on release (temporary=true), or use the provided
480        *      directory as attach point without to cleanup it on
481        *      release (temporary=false, default behaviour).
482        * \throws MediaNotOpenException
483        * \throws MediaNotSupportedException
484        */
485       private:
486       void
487       reattach(MediaAccessId   accessId,
488                const Pathname &attach_point,
489                bool            temporary = false) ZYPP_DEPRECATED;
490       public:
491
492       /**
493        * Release the attached media and optionally eject.
494        *
495        * If the \p eject parameter is set to true and there
496        * is currently an attached drive, all other access
497        * id's are released and the drive (CD/DVD drive) is
498        * ejected.
499        * In case that there is currently no attached drive,
500        * a \p eject set to true causes to eject all drives
501        * that are _not_ used by another access id's.
502        *
503        * \param accessId A media access id.
504        * \param eject    Whether to eject the drive.
505        * \throws MediaNotOpenException for invalid access id.
506        */
507       void
508       release(MediaAccessId accessId, bool eject = false);
509
510       /**
511        * Disconnect a remote media.
512        *
513        * This is useful for media which e.g. holds open a connection
514        * to a server like FTP. After calling disconnect() the media
515        * object (attach point) is still valid and files are present.
516        *
517        * But after calling disconnect() it's not possible to call
518        * fetch more data using the provideFile() or provideDir()
519        * functions anymore.
520        *
521        * \param accessId A media access id.
522        * \throws MediaNotOpenException for invalid access id.
523        */
524       void
525       disconnect(MediaAccessId accessId);
526
527       /**
528        * Check if media is attached or not.
529        *
530        * \param accessId A media access id.
531        * \return True if media is attached.
532        * \throws MediaNotOpenException for invalid access id.
533        */
534       bool
535       isAttached(MediaAccessId accessId) const;
536
537       /**
538        * Returns information if media is on a shared
539        * physical device or not.
540        *
541        * \param accessId A media access id.
542        * \return True if it is shared, false if not.
543        * \throws MediaNotOpenException for invalid access id.
544        */
545       bool
546       isSharedMedia(MediaAccessId accessId) const;
547
548       /**
549        * Ask the registered verifier if the attached
550        * media is the desired one or not.
551        *
552        * \param accessId A media access id.
553        * \return True if media is attached and desired
554        *         according to the actual verifier.
555        * \throws MediaNotOpenException for invalid access id.
556        */
557       bool
558       isDesiredMedia(MediaAccessId accessId) const;
559
560       /**
561        * Ask the specified verifier if the attached
562        * media is the desired one or not.
563        *
564        * \param accessId A media access id.
565        * \param verifier A verifier to use.
566        * \return True if media is attached and desired
567        *         according to the specified verifier.
568        * \throws MediaNotOpenException for invalid access id.
569        */
570       bool
571       isDesiredMedia(MediaAccessId           accessId,
572                      const MediaVerifierRef &verifier) const;
573
574       /**
575        * Return the local directory that corresponds to medias url,
576        * no matter if media isAttached or not. Files requested will
577        * be available at 'localRoot() + filename' or even better
578        * 'localPath( filename )'
579        *
580        * \param accessId A media access id.
581        * \returns The directory name pointing to the media root
582        *          in local filesystem or an empty pathname if the
583        *          media is not attached.
584        * \throws MediaNotOpenException for invalid access id.
585        */
586       Pathname
587       localRoot(MediaAccessId accessId) const;
588
589       /**
590        * Shortcut for 'localRoot() + pathname', but returns an empty
591        * pathname if media is not attached.
592        * Files provided will be available at 'localPath(filename)'.
593        *
594        * \param accessId A media access id.
595        * \param pathname A path name relative to the localRoot().
596        * \returns The directory name in local filesystem pointing
597        *          to the desired relative pathname on the media
598        *          or an empty pathname if the media is not attached.
599        * \throws MediaNotOpenException for invalid access id.
600        */
601       Pathname
602       localPath(MediaAccessId accessId, const Pathname & pathname) const;
603
604     public:
605       /**
606        * Provide provide file denoted by relative path below of the
607        * 'attach point' of the specified media and the path prefix
608        * on the media.
609        *
610        * \param accessId  The media access id to use.
611        * \param filename  The filename to provide, relative to localRoot().
612        * \param cached    If cached is set to true, the function checks, if
613        *                  the file already exists and doesn't download it again
614        *                  if it does. Currently only the existence is checked,
615        *                  no other file attributes.
616        * \param checkonly If this and 'cached' are set to true only the
617        *                  existence of the file is checked but it's not
618        *                  downloaded. If 'cached' is unset an errer is
619        *                  returned always.
620        *
621        * \throws MediaNotOpenException in case of invalid access id.
622        * \throws MediaNotAttachedException in case, that the media is not attached.
623        * \throws MediaNotDesiredException in case, that the media verification failed.
624        * \throws MediaNotAFileException in case, that the requested filename is not a file.
625        * \throws MediaFileNotFoundException in case, that the requested filenamedoes not exists.
626        * \throws MediaWriteException in case, that the file can't be copied from from remote source.
627        * \throws MediaSystemException in case a system operation fails.
628        * \throws MediaException derived exception, depending on the url (handler).
629        */
630       void
631       provideFile(MediaAccessId   accessId,
632                   const Pathname &filename,
633                   bool            cached    = false,
634                   bool            checkonly = false) const;
635
636       /**
637        * FIXME: see MediaAccess class.
638        */
639       void
640       provideDir(MediaAccessId   accessId,
641                  const Pathname &dirname) const;
642
643       /**
644        * FIXME: see MediaAccess class.
645        */
646       void
647       provideDirTree(MediaAccessId  accessId,
648                      const Pathname &dirname) const;
649
650       /**
651        * FIXME: see MediaAccess class.
652        */
653       void
654       releaseFile(MediaAccessId   accessId,
655                   const Pathname &filename) const;
656
657       /**
658        * FIXME: see MediaAccess class.
659        */
660       void
661       releaseDir(MediaAccessId   accessId,
662                  const Pathname &dirname) const;
663
664       /**
665        * FIXME: see MediaAccess class.
666        */
667       void
668       releasePath(MediaAccessId   accessId,
669                   const Pathname &pathname) const;
670
671       /**
672        * FIXME: see MediaAccess class.
673        */
674       void
675       dirInfo(MediaAccessId           accessId,
676               std::list<std::string> &retlist,
677               const Pathname         &dirname,
678               bool                    dots = true) const;
679
680       /**
681        * FIXME: see MediaAccess class.
682        */
683       void
684       dirInfo(MediaAccessId           accessId,
685               filesystem::DirContent &retlist,
686               const Pathname         &dirname,
687               bool                   dots = true) const;
688
689
690     public:
691       /**
692        * Get the modification time of the /etc/mtab file.
693        * \return Modification time of the /etc/mtab file.
694        */
695       time_t
696       getMountTableMTime() const;
697
698       /**
699        * Get current mount entries from /etc/mtab file.
700        * \return Current mount entries from /etc/mtab file.
701        */
702       std::vector<MountEntry>
703       getMountEntries() const;
704
705       /**
706        * Check if the specified \p path is useable as
707        * attach point.
708        *
709        * \param path The attach point to check.
710        * \return True, if it is a directory and there are
711        *         no another attach points bellow of it.
712        */
713       bool
714       isUseableAttachPoint(const Pathname &path) const;
715
716     private:
717       friend class MediaHandler;
718
719       /**
720        * \internal
721        * Return the attached media reference of the specified
722        * media access id. Used to resolve nested attachments
723        * as used in the MediaISO (iso-loop) handler.
724        * Causes temporary creation of a shared attachment
725        * (increases reference counters on attachedMedia).
726        * \param media A media access id.
727        */
728       AttachedMedia
729       getAttachedMedia(MediaAccessId &accessId) const;
730
731       /**
732        * \internal
733        * Called by media handler in while attach() to retrieve
734        * attached media reference matching the specified media
735        * source reference.
736        * Causes temporary creation of a shared attachment
737        * (increases reference counters on attachedMedia).
738        * \param media The media source reference to search for.
739        */
740       AttachedMedia
741       findAttachedMedia(const MediaSourceRef &media) const;
742
743       /**
744        * \internal
745        * Called by media handler in case of relase(eject=true)
746        * to release all access id's using the specified media.
747        * Causes temporary creation of a shared attachment
748        * (increases reference counters on attachedMedia).
749        * \param media The media source reference to release.
750        */
751       void
752       forceMediaRelease(const MediaSourceRef &media);
753
754     private:
755       class  Impl;
756       /**
757        * Static reference to the implementation (singleton).
758        */
759       static zypp::RW_pointer<MediaManager::Impl> m_impl;
760     };
761
762
763     //////////////////////////////////////////////////////////////////
764   } // namespace media
765   ////////////////////////////////////////////////////////////////////
766
767   ////////////////////////////////////////////////////////////////////
768 } // namespace zypp
769 //////////////////////////////////////////////////////////////////////
770
771 #endif // ZYPP_MEDIA_MEDIAMANAGER_H
772
773 /*
774 ** vim: set ts=2 sts=2 sw=2 ai et:
775 */