Cleanup and remove deprecated interface methods
[platform/upstream/libzypp.git] / zypp / media / MediaManager.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaManager.cc
10  *
11 */
12 #include <map>
13 #include <list>
14 #include <iostream>
15 #include <typeinfo>
16
17 #include "zypp/media/MediaException.h"
18 #include "zypp/media/MediaManager.h"
19 #include "zypp/media/MediaHandler.h"
20 #include "zypp/media/Mount.h"
21 #include "zypp/thread/Mutex.h"
22 #include "zypp/thread/MutexLock.h"
23 #include "zypp/target/hal/HalContext.h"
24
25 #include "zypp/base/String.h"
26 #include "zypp/base/Logger.h"
27 #include "zypp/Pathname.h"
28 #include "zypp/PathInfo.h"
29
30 #define  DISABLE_AUTOMOUNTER      0
31
32
33 //////////////////////////////////////////////////////////////////////
34 namespace zypp
35 { ////////////////////////////////////////////////////////////////////
36
37   ////////////////////////////////////////////////////////////////////
38   namespace media
39   { //////////////////////////////////////////////////////////////////
40
41     using zypp::thread::Mutex;
42     using zypp::thread::MutexLock;
43
44     //////////////////////////////////////////////////////////////////
45     namespace // anonymous
46     { ////////////////////////////////////////////////////////////////
47
48
49       // -------------------------------------------------------------
50       // STATIC
51       static Mutex  g_Mutex;
52
53
54       // -------------------------------------------------------------
55       struct ManagedMedia
56       {
57         ~ManagedMedia()
58         {}
59
60         ManagedMedia()
61           : desired (false)
62         {}
63
64         ManagedMedia(const ManagedMedia &m)
65           : desired (m.desired)
66           , handler (m.handler)
67           , verifier(m.verifier)
68         {}
69
70         ManagedMedia(const MediaAccessRef &h, const MediaVerifierRef &v)
71           : desired (false)
72           , handler (h)
73           , verifier(v)
74         {}
75
76         inline void
77         checkAttached(MediaAccessId id)
78         {
79           if( !handler->isAttached())
80           {
81             DBG << "checkAttached(" << id << ") not attached" << std::endl;
82             desired = false;
83             ZYPP_THROW(MediaNotAttachedException(
84               handler->url()
85             ));
86           }
87         }
88
89         inline void
90         checkDesired(MediaAccessId id)
91         {
92           checkAttached(id);
93
94           if( !desired)
95           {
96             try {
97               desired = verifier->isDesiredMedia(handler);
98             }
99             catch(const zypp::Exception &e) {
100               ZYPP_CAUGHT(e);
101               desired = false;
102             }
103
104             if( !desired)
105             {
106               DBG << "checkDesired(" << id << "): not desired (report by "
107                   << verifier->info() << ")" << std::endl;
108               ZYPP_THROW(MediaNotDesiredException(
109                 handler->url()
110               ));
111             }
112
113             DBG << "checkDesired(" << id << "): desired (report by "
114                 << verifier->info() << ")" << std::endl;
115           } else {
116             DBG << "checkDesired(" << id << "): desired (cached)" << std::endl;
117           }
118         }
119
120         bool             desired;
121         MediaAccessRef   handler;
122         MediaVerifierRef verifier;
123       };
124
125
126       // -------------------------------------------------------------
127       typedef std::map<MediaAccessId, ManagedMedia> ManagedMediaMap;
128
129
130       // -------------------------------------------------------------
131       enum AutoMounterCleanUp
132       {
133         NONE, ENABLE, REMOVE
134       };
135
136       #define HAL_AUTOMOUNTER_UDI  "/org/freedesktop/Hal/devices/computer"
137       #define HAL_AUTOMOUNTER_KEY  "storage.disable_volume_handling"
138
139       // -------------------------------------------------------------
140       AutoMounterCleanUp
141       disableAutoMounter()
142       {
143         using namespace zypp::target::hal;
144
145         AutoMounterCleanUp cleanup(NONE);
146 #if DISABLE_AUTOMOUNTER
147         try
148         {
149           HalContext hal(true);
150           bool disabled(false);
151
152           // query
153           XXX << "Checking HAL volume handling property"
154               << std::endl;
155           try
156           {
157             disabled = hal.getDevicePropertyBool(
158               HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY
159             );
160
161             if( disabled)
162             {
163               MIL << "HAL volume handling is already disabled"
164                   << std::endl;
165             }
166             else
167             {
168               cleanup = ENABLE;
169               XXX << "HAL volume handling is enabled"
170                   << std::endl;
171             }
172           }
173           catch(const HalException &e)
174           {
175             ZYPP_CAUGHT(e);
176             XXX << "HAL volume handling is enabled (no property)"
177                 << std::endl;
178             disabled = false;
179             cleanup  = REMOVE;
180           }
181
182           // disable
183           if( !disabled)
184           {
185             XXX << "Trying to disable HAL volume handling"
186                 << std::endl;
187             try
188             {
189               hal.setDevicePropertyBool(
190                 HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY,
191                 true
192               );
193
194               MIL << "Disabled HAL volume handling (automounter)"
195                   << std::endl;
196             }
197             catch(const HalException &e)
198             {
199               ZYPP_CAUGHT(e);
200               WAR << "Unable to disable HAL volume handling (automounter)"
201                   << std::endl;
202
203               cleanup  = NONE;
204             }
205           }
206         }
207         catch(const HalException &e)
208         {
209           ZYPP_CAUGHT(e);
210           WAR << "Unable to disable HAL volume handling (automounter)"
211               << std::endl;
212         }
213 #endif // DISABLE_AUTOMOUNTER
214         return cleanup;
215       }
216
217       // -------------------------------------------------------------
218       void
219       restoreAutoMounter(AutoMounterCleanUp cleanup)
220       {
221         using namespace zypp::target::hal;
222
223         if(cleanup == NONE)
224           return;
225
226 #if DISABLE_AUTOMOUNTER
227         try
228         {
229           HalContext hal(true);
230
231           if(cleanup == ENABLE)
232           {
233             XXX << "Trying to restore HAL volume handling -- enable"
234                 << std::endl;
235
236             hal.setDevicePropertyBool(
237               HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY,
238               false
239             );
240           }
241           else
242           if(cleanup == REMOVE)
243           {
244             XXX << "Trying to restore HAL volume handling -- remove"
245                 << std::endl;
246
247             hal.removeDeviceProperty(
248               HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY
249             );
250           }
251
252           cleanup = NONE;
253           MIL << "Restored HAL volume handling (automounter)"
254               << std::endl;
255         }
256         catch(const HalException &e)
257         {
258           ZYPP_CAUGHT(e);
259           WAR << "Unable to restore HAL volume handling (automounter)"
260               << std::endl;
261         }
262 #endif // DISABLE_AUTOMOUNTER
263       }
264
265       ////////////////////////////////////////////////////////////////
266     } // anonymous
267     //////////////////////////////////////////////////////////////////
268
269
270     //////////////////////////////////////////////////////////////////
271     std::string
272     MediaVerifierBase::info() const
273     {
274       return std::string(typeid((*this)).name());
275     }
276
277
278     //////////////////////////////////////////////////////////////////
279     std::string
280     NoVerifier::info() const
281     {
282       return std::string("zypp::media::NoVerifier");
283     }
284
285
286     //////////////////////////////////////////////////////////////////
287     class MediaManager_Impl
288     {
289     private:
290       friend class MediaManager;
291
292       MediaAccessId       last_accessid;
293       AutoMounterCleanUp  am_cleanup;
294       ManagedMediaMap     mediaMap;
295
296       MediaManager_Impl()
297         : last_accessid(0)
298       {
299         // disable automounter
300         am_cleanup = disableAutoMounter();
301       }
302
303     public:
304       ~MediaManager_Impl()
305       {
306         MutexLock glock(g_Mutex);
307
308         try
309         {
310           // remove depending (iso) handlers first
311           ManagedMediaMap::iterator it;
312           bool found;
313           do
314           {
315             found = false;
316             for(it = mediaMap.begin(); it != mediaMap.end(); /**/)
317             {
318               if( it->second.handler->dependsOnParent())
319               {
320                 found = true;
321                 // let it forget its parent, we will
322                 // destroy it later (in clear())...
323                 it->second.handler->resetParentId();
324                 mediaMap.erase( it++ ); // postfix! Incrementing before erase
325               } else {
326                 ++it;
327               }
328             }
329           } while(found);
330
331           // remove all other handlers
332           mediaMap.clear();
333
334           // restore automounter state
335           restoreAutoMounter(am_cleanup);
336         }
337         catch( ... )
338         {}
339       }
340
341       inline MediaAccessId
342       nextAccessId()
343       {
344         return ++last_accessid;
345       }
346
347       inline bool
348       hasId(MediaAccessId accessId) const
349       {
350         return mediaMap.find(accessId) != mediaMap.end();
351       }
352
353       inline ManagedMedia &
354       findMM(MediaAccessId accessId)
355       {
356         ManagedMediaMap::iterator it( mediaMap.find(accessId));
357         if( it == mediaMap.end())
358         {
359           ZYPP_THROW(MediaNotOpenException(
360             "Invalid media access id " + str::numstring(accessId)
361           ));
362         }
363         return it->second;
364       }
365
366       static inline time_t
367       getMountTableMTime()
368       {
369         time_t mtime = zypp::PathInfo("/etc/mtab").mtime();
370         if( mtime <= 0)
371         {
372           WAR << "Failed to retrieve modification time of '/etc/mtab'"
373               << std::endl;
374         }
375         return mtime;
376       }
377
378       static inline MountEntries
379       getMountEntries()
380       {
381         // use "/etc/mtab" by default,
382         // fallback to "/proc/mounts"
383         return Mount::getEntries(/* "/etc/mtab" */);
384       }
385
386     };
387
388
389     //////////////////////////////////////////////////////////////////
390     // STATIC
391     zypp::RW_pointer<MediaManager_Impl> MediaManager::m_impl(NULL);
392
393
394     //////////////////////////////////////////////////////////////////
395     MediaManager::MediaManager()
396     {
397       MutexLock glock(g_Mutex);
398       if( !m_impl)
399       {
400         m_impl.reset( new MediaManager_Impl());
401       }
402     }
403
404     // ---------------------------------------------------------------
405     MediaManager::~MediaManager()
406     {
407     }
408
409     // ---------------------------------------------------------------
410     MediaAccessId
411     MediaManager::open(const Url &url, const Pathname &preferred_attach_point)
412     {
413       MutexLock glock(g_Mutex);
414
415       // create new access handler for it
416       MediaAccessRef handler( new MediaAccess());
417       MediaVerifierRef verifier( new NoVerifier());
418       ManagedMedia tmp( handler, verifier);
419
420       tmp.handler->open(url, preferred_attach_point);
421
422       MediaAccessId nextId = m_impl->nextAccessId();
423
424       m_impl->mediaMap[nextId] = tmp;
425
426       DBG << "Opened new media access using id " << nextId
427           << " to " << url.asString() << std::endl;
428       return nextId;
429     }
430
431     // ---------------------------------------------------------------
432     void
433     MediaManager::close(MediaAccessId accessId)
434     {
435       MutexLock glock(g_Mutex);
436
437       //
438       // The MediaISO handler internally requests an accessId
439       // of a "parent" handler providing the iso file.
440       // The parent handler accessId is private to MediaISO,
441       // but the attached media source may be shared reference.
442       // This means, that if the accessId exactly matches the
443       // parent handler id, close was used on uninitialized
444       // accessId variable (or the accessId was guessed) and
445       // the close request to this id will be rejected here.
446       //
447       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
448       for( ; m != m_impl->mediaMap.end(); ++m)
449       {
450         if( m->second.handler->dependsOnParent(accessId, true))
451         {
452           ZYPP_THROW(MediaIsSharedException(
453             m->second.handler->url().asString()
454           ));
455         }
456       }
457
458       DBG << "Close to access handler using id "
459           << accessId << " requested" << std::endl;
460
461       ManagedMedia &ref( m_impl->findMM(accessId));
462       ref.handler->close();
463
464       m_impl->mediaMap.erase(accessId);
465     }
466
467     // ---------------------------------------------------------------
468     bool
469     MediaManager::isOpen(MediaAccessId accessId) const
470     {
471       MutexLock glock(g_Mutex);
472
473       ManagedMediaMap::iterator it( m_impl->mediaMap.find(accessId));
474       return it != m_impl->mediaMap.end() &&
475              it->second.handler->isOpen();
476     }
477
478     // ---------------------------------------------------------------
479     std::string
480     MediaManager::protocol(MediaAccessId accessId) const
481     {
482       MutexLock glock(g_Mutex);
483
484       ManagedMedia &ref( m_impl->findMM(accessId));
485
486       return ref.handler->protocol();
487     }
488
489     // ---------------------------------------------------------------
490           bool
491     MediaManager::downloads(MediaAccessId accessId) const
492     {
493       MutexLock glock(g_Mutex);
494
495       ManagedMedia &ref( m_impl->findMM(accessId));
496
497       return ref.handler->downloads();
498     }
499
500     // ---------------------------------------------------------------
501     // STATIC
502     bool
503     MediaManager::downloads(const Url &url)
504     {
505       return MediaAccess::downloads( url);
506     }
507
508     // ---------------------------------------------------------------
509     Url
510     MediaManager::url(MediaAccessId accessId) const
511     {
512       MutexLock glock(g_Mutex);
513
514       ManagedMedia &ref( m_impl->findMM(accessId));
515
516       return ref.handler->url();
517     }
518
519     // ---------------------------------------------------------------
520     void
521     MediaManager::addVerifier(MediaAccessId           accessId,
522                               const MediaVerifierRef &verifier)
523     {
524       MutexLock glock(g_Mutex);
525
526       if( !verifier)
527         ZYPP_THROW(MediaException("Invalid verifier reference"));
528
529       ManagedMedia &ref( m_impl->findMM(accessId));
530
531       ref.desired = false;
532       MediaVerifierRef(verifier).swap(ref.verifier);
533
534       DBG << "MediaVerifier change: id=" << accessId << ", verifier="
535           << verifier->info() << std::endl;
536     }
537
538     // ---------------------------------------------------------------
539     void
540     MediaManager::delVerifier(MediaAccessId accessId)
541     {
542       MutexLock glock(g_Mutex);
543
544       ManagedMedia &ref( m_impl->findMM(accessId));
545
546       MediaVerifierRef verifier( new NoVerifier());
547       ref.desired  = false;
548       ref.verifier.swap(verifier);
549
550       DBG << "MediaVerifier change: id=" << accessId << ", verifier="
551           << verifier->info() << std::endl;
552     }
553
554     // ---------------------------------------------------------------
555     bool
556     MediaManager::setAttachPrefix(const Pathname &attach_prefix)
557     {
558       MutexLock glock(g_Mutex);
559
560       return MediaHandler::setAttachPrefix(attach_prefix);
561     }
562
563     // ---------------------------------------------------------------
564     void MediaManager::attach(MediaAccessId accessId)
565     {
566       MutexLock glock(g_Mutex);
567
568       ManagedMedia &ref( m_impl->findMM(accessId));
569
570       DBG << "attach(id=" << accessId << ")" << std::endl;
571
572       // try first mountable/mounted device
573       ref.handler->attach(false);
574       try
575       {
576         ref.checkDesired(accessId);
577         return;
578       }
579       catch (const MediaException & ex)
580       {
581         ZYPP_CAUGHT(ex);
582
583         if (!ref.handler->hasMoreDevices())
584           ZYPP_RETHROW(ex);
585
586         if (ref.handler->isAttached())
587           ref.handler->release();
588       }
589
590       MIL << "checkDesired(" << accessId << ") of first device failed,"
591         " going to try others with attach(true)" << std::endl;
592
593       while (ref.handler->hasMoreDevices())
594       {
595         try
596         {
597           // try to attach next device
598           ref.handler->attach(true);
599           ref.checkDesired(accessId);
600           return;
601         }
602         catch (const MediaNotDesiredException & ex)
603         {
604           ZYPP_CAUGHT(ex);
605
606           if (!ref.handler->hasMoreDevices())
607           {
608             MIL << "No desired media found after trying all detected devices." << std::endl;
609             ZYPP_RETHROW(ex);
610           }
611
612           AttachedMedia media(ref.handler->attachedMedia());
613           DBG << "Skipping " << media.mediaSource->asString() << ": not desired media." << std::endl;
614
615           ref.handler->release();
616         }
617         catch (const MediaException & ex)
618         {
619           ZYPP_CAUGHT(ex);
620
621           if (!ref.handler->hasMoreDevices())
622             ZYPP_RETHROW(ex);
623
624           AttachedMedia media(ref.handler->attachedMedia());
625           DBG << "Skipping " << media.mediaSource->asString() << " because of exception thrown by attach(true)" << std::endl;
626
627           if (ref.handler->isAttached()) ref.handler->release();
628         }
629       }
630     }
631
632     // ---------------------------------------------------------------
633     void
634     MediaManager::release(MediaAccessId accessId, const std::string & ejectDev)
635     {
636       MutexLock glock(g_Mutex);
637
638       ManagedMedia &ref( m_impl->findMM(accessId));
639
640       DBG << "release(id=" << accessId;
641       if (!ejectDev.empty())
642         DBG << ", " << ejectDev;
643       DBG << ")" << std::endl;
644
645       if(!ejectDev.empty())
646       {
647         //
648         // release MediaISO handlers, that are using the one
649         // specified with accessId, because it provides the
650         // iso file and it will disappear now (forced release
651         // with eject).
652         //
653         ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
654         for( ; m != m_impl->mediaMap.end(); ++m)
655         {
656           if( m->second.handler->dependsOnParent(accessId, false))
657           {
658             try
659             {
660               DBG << "Forcing release of handler depending on access id "
661                   << accessId << std::endl;
662               m->second.desired  = false;
663               m->second.handler->release();
664             }
665             catch(const MediaException &e)
666             {
667               ZYPP_CAUGHT(e);
668             }
669           }
670         }
671       }
672       ref.desired  = false;
673       ref.handler->release(ejectDev);
674     }
675
676     // ---------------------------------------------------------------
677     void
678     MediaManager::releaseAll()
679     {
680       MutexLock glock(g_Mutex);
681
682       MIL << "Releasing all attached media" << std::endl;
683
684       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
685       for( ; m != m_impl->mediaMap.end(); ++m)
686       {
687         if( m->second.handler->dependsOnParent())
688           continue;
689
690         try
691         {
692           if(m->second.handler->isAttached())
693           {
694             DBG << "Releasing media id " << m->first << std::endl;
695             m->second.desired  = false;
696             m->second.handler->release();
697           }
698           else
699           {
700             DBG << "Media id " << m->first << " not attached " << std::endl;
701           }
702         }
703         catch(const MediaException & e)
704         {
705           ZYPP_CAUGHT(e);
706           ERR << "Failed to release media id " << m->first << std::endl;
707         }
708       }
709
710       MIL << "Exit" << std::endl;
711     }
712
713     // ---------------------------------------------------------------
714     void
715     MediaManager::disconnect(MediaAccessId accessId)
716     {
717       MutexLock glock(g_Mutex);
718
719       ManagedMedia &ref( m_impl->findMM(accessId));
720
721       ref.handler->disconnect();
722     }
723
724     // ---------------------------------------------------------------
725     bool
726     MediaManager::isAttached(MediaAccessId accessId) const
727     {
728       MutexLock glock(g_Mutex);
729
730       ManagedMedia &ref( m_impl->findMM(accessId));
731
732       return ref.handler->isAttached();
733     }
734
735     // ---------------------------------------------------------------
736     bool MediaManager::isSharedMedia(MediaAccessId accessId) const
737     {
738       MutexLock glock(g_Mutex);
739
740       ManagedMedia &ref( m_impl->findMM(accessId));
741
742       return ref.handler->isSharedMedia();
743     }
744
745     // ---------------------------------------------------------------
746     bool
747     MediaManager::isDesiredMedia(MediaAccessId accessId) const
748     {
749       MutexLock glock(g_Mutex);
750
751       ManagedMedia &ref( m_impl->findMM(accessId));
752
753       if( !ref.handler->isAttached())
754       {
755         ref.desired = false;
756       }
757       else
758       {
759         try {
760           ref.desired = ref.verifier->isDesiredMedia(ref.handler);
761         }
762         catch(const zypp::Exception &e) {
763           ZYPP_CAUGHT(e);
764           ref.desired = false;
765         }
766       }
767       DBG << "isDesiredMedia(" << accessId << "): "
768           << (ref.desired ? "" : "not ")
769           << "desired (report by "
770           << ref.verifier->info() << ")" << std::endl;
771       return ref.desired;
772     }
773
774     // ---------------------------------------------------------------
775     bool
776     MediaManager::isDesiredMedia(MediaAccessId           accessId,
777                                  const MediaVerifierRef &verifier) const
778     {
779       MutexLock glock(g_Mutex);
780
781       MediaVerifierRef v(verifier);
782       if( !v)
783         ZYPP_THROW(MediaException("Invalid verifier reference"));
784
785       ManagedMedia &ref( m_impl->findMM(accessId));
786
787       bool desired = false;
788       if( ref.handler->isAttached())
789       {
790         try {
791           desired = v->isDesiredMedia(ref.handler);
792         }
793         catch(const zypp::Exception &e) {
794           ZYPP_CAUGHT(e);
795           desired = false;
796         }
797       }
798       DBG << "isDesiredMedia(" << accessId << "): "
799           << (desired ? "" : "not ")
800           << "desired (report by "
801           << v->info() << ")" << std::endl;
802       return desired;
803     }
804
805     // ---------------------------------------------------------------
806     bool
807     MediaManager::isChangeable(MediaAccessId accessId)
808     {
809       return url(accessId).getScheme() == "cd" || url(accessId).getScheme() == "dvd";
810     }
811
812     // ---------------------------------------------------------------
813     Pathname
814     MediaManager::localRoot(MediaAccessId accessId) const
815     {
816       MutexLock glock(g_Mutex);
817
818       ManagedMedia &ref( m_impl->findMM(accessId));
819
820       Pathname path;
821       path = ref.handler->localRoot();
822       return path;
823     }
824
825     // ---------------------------------------------------------------
826     Pathname
827     MediaManager::localPath(MediaAccessId accessId,
828                             const Pathname & pathname) const
829     {
830       MutexLock glock(g_Mutex);
831
832       ManagedMedia &ref( m_impl->findMM(accessId));
833
834       Pathname path;
835       path = ref.handler->localPath(pathname);
836       return path;
837     }
838
839     // ---------------------------------------------------------------
840     void
841     MediaManager::provideFile(MediaAccessId   accessId,
842                               const Pathname &filename ) const
843     {
844       MutexLock glock(g_Mutex);
845
846       ManagedMedia &ref( m_impl->findMM(accessId));
847
848       ref.checkDesired(accessId);
849
850       ref.handler->provideFile(filename);
851     }
852
853     // ---------------------------------------------------------------
854     void
855     MediaManager::provideDir(MediaAccessId   accessId,
856                              const Pathname &dirname) const
857     {
858       MutexLock glock(g_Mutex);
859
860       ManagedMedia &ref( m_impl->findMM(accessId));
861
862       ref.checkDesired(accessId);
863
864       ref.handler->provideDir(dirname);
865     }
866
867     // ---------------------------------------------------------------
868     void
869     MediaManager::provideDirTree(MediaAccessId   accessId,
870                                  const Pathname &dirname) const
871     {
872       MutexLock glock(g_Mutex);
873
874       ManagedMedia &ref( m_impl->findMM(accessId));
875
876       ref.checkDesired(accessId);
877
878       ref.handler->provideDirTree(dirname);
879     }
880
881     // ---------------------------------------------------------------
882     void
883     MediaManager::releaseFile(MediaAccessId   accessId,
884                               const Pathname &filename) const
885     {
886       MutexLock glock(g_Mutex);
887
888       ManagedMedia &ref( m_impl->findMM(accessId));
889
890       ref.checkAttached(accessId);
891
892       ref.handler->releaseFile(filename);
893     }
894
895     // ---------------------------------------------------------------
896     void
897     MediaManager::releaseDir(MediaAccessId   accessId,
898                              const Pathname &dirname) const
899     {
900       MutexLock glock(g_Mutex);
901
902       ManagedMedia &ref( m_impl->findMM(accessId));
903
904       ref.checkAttached(accessId);
905
906       ref.handler->releaseDir(dirname);
907     }
908
909
910     // ---------------------------------------------------------------
911     void
912     MediaManager::releasePath(MediaAccessId   accessId,
913                               const Pathname &pathname) const
914     {
915       MutexLock glock(g_Mutex);
916
917       ManagedMedia &ref( m_impl->findMM(accessId));
918
919       ref.checkAttached(accessId);
920
921       ref.handler->releasePath(pathname);
922     }
923
924     // ---------------------------------------------------------------
925     void
926     MediaManager::dirInfo(MediaAccessId           accessId,
927                           std::list<std::string> &retlist,
928                           const Pathname         &dirname,
929                           bool                    dots) const
930     {
931       MutexLock glock(g_Mutex);
932
933       ManagedMedia &ref( m_impl->findMM(accessId));
934
935       // FIXME: ref.checkDesired(accessId); ???
936       ref.checkAttached(accessId);
937
938       ref.handler->dirInfo(retlist, dirname, dots);
939     }
940
941     // ---------------------------------------------------------------
942     void
943     MediaManager::dirInfo(MediaAccessId           accessId,
944                           filesystem::DirContent &retlist,
945                           const Pathname         &dirname,
946                           bool                    dots) const
947     {
948       MutexLock glock(g_Mutex);
949
950       ManagedMedia &ref( m_impl->findMM(accessId));
951
952       // FIXME: ref.checkDesired(accessId); ???
953       ref.checkAttached(accessId);
954
955       ref.handler->dirInfo(retlist, dirname, dots);
956     }
957
958     // ---------------------------------------------------------------
959     bool
960     MediaManager::doesFileExist(MediaAccessId  accessId, const Pathname & filename ) const
961     {
962       MutexLock glock(g_Mutex);
963       ManagedMedia &ref( m_impl->findMM(accessId));
964
965       // FIXME: ref.checkDesired(accessId); ???
966       ref.checkAttached(accessId);
967
968       return ref.handler->doesFileExist(filename);
969     }
970
971     // ---------------------------------------------------------------
972     void
973     MediaManager::getDetectedDevices(MediaAccessId accessId,
974                                      std::vector<std::string> & devices,
975                                      unsigned int & index) const
976     {
977       MutexLock glock(g_Mutex);
978       ManagedMedia &ref( m_impl->findMM(accessId));
979       return ref.handler->getDetectedDevices(devices, index);
980     }
981
982     // ---------------------------------------------------------------
983     // STATIC
984     time_t
985     MediaManager::getMountTableMTime()
986     {
987       MutexLock glock(g_Mutex);
988       return MediaManager_Impl::getMountTableMTime();
989     }
990
991     // ---------------------------------------------------------------
992     // STATIC
993     MountEntries
994     MediaManager::getMountEntries()
995     {
996       MutexLock glock(g_Mutex);
997
998       return MediaManager_Impl::getMountEntries();
999     }
1000
1001     // ---------------------------------------------------------------
1002     bool
1003     MediaManager::isUseableAttachPoint(const Pathname &path,
1004                                        bool            mtab) const
1005     {
1006       if( path.empty() || path == "/" || !PathInfo(path).isDir())
1007         return false;
1008
1009       MutexLock glock(g_Mutex);
1010
1011       //
1012       // check against our current attach points
1013       //
1014       ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
1015       for( ; m != m_impl->mediaMap.end(); ++m)
1016       {
1017         AttachedMedia ret = m->second.handler->attachedMedia();
1018         if( ret.mediaSource && ret.attachPoint)
1019         {
1020           std::string mnt(ret.attachPoint->path.asString());
1021           std::string our(path.asString());
1022
1023           if( our == mnt)
1024           {
1025             // already used as attach point
1026             return false;
1027           }
1028           else
1029           if( mnt.size() > our.size()   &&
1030               mnt.at(our.size()) == '/' &&
1031              !mnt.compare(0, our.size(), our))
1032           {
1033             // mountpoint is bellow of path
1034             // (would hide the content)
1035             return false;
1036           }
1037         }
1038       }
1039
1040       if( !mtab)
1041         return true;
1042
1043       //
1044       // check against system mount entries
1045       //
1046       MountEntries  entries( m_impl->getMountEntries());
1047       MountEntries::const_iterator e;
1048       for( e = entries.begin(); e != entries.end(); ++e)
1049       {
1050         std::string mnt(Pathname(e->dir).asString());
1051         std::string our(path.asString());
1052
1053         if( our == mnt)
1054         {
1055           // already used as mountpoint
1056           return false;
1057         }
1058         else
1059         if( mnt.size() > our.size()   &&
1060             mnt.at(our.size()) == '/' &&
1061            !mnt.compare(0, our.size(), our))
1062         {
1063           // mountpoint is bellow of path
1064           // (would hide the content)
1065           return false;
1066         }
1067       }
1068
1069       return true;
1070     }
1071
1072     // ---------------------------------------------------------------
1073     AttachedMedia
1074     MediaManager::getAttachedMedia(MediaAccessId &accessId) const
1075     {
1076       MutexLock glock(g_Mutex);
1077
1078       ManagedMedia &ref( m_impl->findMM(accessId));
1079
1080       return ref.handler->attachedMedia();
1081     }
1082
1083     // ---------------------------------------------------------------
1084     AttachedMedia
1085     MediaManager::findAttachedMedia(const MediaSourceRef &media) const
1086     {
1087       MutexLock glock(g_Mutex);
1088
1089       if( !media || media->type.empty())
1090         return AttachedMedia();
1091
1092       ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
1093       for( ; m != m_impl->mediaMap.end(); ++m)
1094       {
1095         if( !m->second.handler->isAttached())
1096           continue;
1097
1098         AttachedMedia ret = m->second.handler->attachedMedia();
1099         if( ret.mediaSource && ret.mediaSource->equals( *media))
1100             return ret;
1101       }
1102       return AttachedMedia();
1103     }
1104
1105     // ---------------------------------------------------------------
1106     void
1107     MediaManager::forceReleaseShared(const MediaSourceRef &media)
1108     {
1109       MutexLock glock(g_Mutex);
1110
1111       if( !media || media->type.empty())
1112         return;
1113
1114       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
1115       for( ; m != m_impl->mediaMap.end(); ++m)
1116       {
1117         if( !m->second.handler->isAttached())
1118           continue;
1119
1120         AttachedMedia ret = m->second.handler->attachedMedia();
1121         if( ret.mediaSource && ret.mediaSource->equals( *media))
1122         {
1123           m->second.handler->release();
1124           m->second.desired  = false;
1125         }
1126       }
1127     }
1128
1129     //////////////////////////////////////////////////////////////////
1130   } // namespace media
1131   ////////////////////////////////////////////////////////////////////
1132
1133   ////////////////////////////////////////////////////////////////////
1134 } // namespace zypp
1135 //////////////////////////////////////////////////////////////////////
1136 /*
1137 ** vim: set ts=2 sts=2 sw=2 ai et:
1138 */