00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <zypp/media/MediaException.h>
00013 #include <zypp/media/MediaManager.h>
00014 #include <zypp/media/MediaHandler.h>
00015 #include <zypp/media/Mount.h>
00016 #include <zypp/thread/Mutex.h>
00017 #include <zypp/thread/MutexLock.h>
00018 #include <zypp/target/hal/HalContext.h>
00019
00020 #include <zypp/base/String.h>
00021 #include <zypp/base/Logger.h>
00022 #include <zypp/Pathname.h>
00023 #include <zypp/PathInfo.h>
00024
00025 #include <map>
00026 #include <list>
00027 #include <iostream>
00028 #include <typeinfo>
00029
00030 #define DISABLE_AUTOMOUNTER 0
00031
00032
00034 namespace zypp
00035 {
00036
00038 namespace media
00039 {
00040
00041 using zypp::thread::Mutex;
00042 using zypp::thread::MutexLock;
00043
00045 namespace
00046 {
00047
00048
00049
00050
00051 static Mutex g_Mutex;
00052
00053
00054
00055 struct ManagedMedia
00056 {
00057 ~ManagedMedia()
00058 {}
00059
00060 ManagedMedia()
00061 : desired (false)
00062 {}
00063
00064 ManagedMedia(const ManagedMedia &m)
00065 : desired (m.desired)
00066 , handler (m.handler)
00067 , verifier(m.verifier)
00068 {}
00069
00070 ManagedMedia(const MediaAccessRef &h, const MediaVerifierRef &v)
00071 : desired (false)
00072 , handler (h)
00073 , verifier(v)
00074 {}
00075
00076 inline void
00077 checkAttached(MediaAccessId id)
00078 {
00079 if( !handler->isAttached())
00080 {
00081 DBG << "checkAttached(" << id << ") not attached" << std::endl;
00082 desired = false;
00083 ZYPP_THROW(MediaNotAttachedException(
00084 handler->url()
00085 ));
00086 }
00087 }
00088
00089 inline void
00090 checkDesired(MediaAccessId id)
00091 {
00092 checkAttached(id);
00093
00094 if( !desired)
00095 {
00096 try {
00097 desired = verifier->isDesiredMedia(handler);
00098 }
00099 catch(const zypp::Exception &e) {
00100 ZYPP_CAUGHT(e);
00101 desired = false;
00102 }
00103
00104 if( !desired)
00105 {
00106 DBG << "checkDesired(" << id << "): not desired (report by "
00107 << verifier->info() << ")" << std::endl;
00108 ZYPP_THROW(MediaNotDesiredException(
00109 handler->url()
00110 ));
00111 }
00112
00113 DBG << "checkDesired(" << id << "): desired (report by "
00114 << verifier->info() << ")" << std::endl;
00115 } else {
00116 DBG << "checkDesired(" << id << "): desired (cached)" << std::endl;
00117 }
00118 }
00119
00120 bool desired;
00121 MediaAccessRef handler;
00122 MediaVerifierRef verifier;
00123 };
00124
00125
00126
00127 typedef std::map<MediaAccessId, ManagedMedia> ManagedMediaMap;
00128
00129
00130
00131 enum AutoMounterCleanUp
00132 {
00133 NONE, ENABLE, REMOVE
00134 };
00135
00136 #define HAL_AUTOMOUNTER_UDI "/org/freedesktop/Hal/devices/computer"
00137 #define HAL_AUTOMOUNTER_KEY "storage.disable_volume_handling"
00138
00139
00140 AutoMounterCleanUp
00141 disableAutoMounter()
00142 {
00143 using namespace zypp::target::hal;
00144
00145 AutoMounterCleanUp cleanup(NONE);
00146 #if DISABLE_AUTOMOUNTER
00147 try
00148 {
00149 HalContext hal(true);
00150 bool disabled(false);
00151
00152
00153 XXX << "Checking HAL volume handling property"
00154 << std::endl;
00155 try
00156 {
00157 disabled = hal.getDevicePropertyBool(
00158 HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY
00159 );
00160
00161 if( disabled)
00162 {
00163 MIL << "HAL volume handling is already disabled"
00164 << std::endl;
00165 }
00166 else
00167 {
00168 cleanup = ENABLE;
00169 XXX << "HAL volume handling is enabled"
00170 << std::endl;
00171 }
00172 }
00173 catch(const HalException &e)
00174 {
00175 ZYPP_CAUGHT(e);
00176 XXX << "HAL volume handling is enabled (no property)"
00177 << std::endl;
00178 disabled = false;
00179 cleanup = REMOVE;
00180 }
00181
00182
00183 if( !disabled)
00184 {
00185 XXX << "Trying to disable HAL volume handling"
00186 << std::endl;
00187 try
00188 {
00189 hal.setDevicePropertyBool(
00190 HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY,
00191 true
00192 );
00193
00194 MIL << "Disabled HAL volume handling (automounter)"
00195 << std::endl;
00196 }
00197 catch(const HalException &e)
00198 {
00199 ZYPP_CAUGHT(e);
00200 WAR << "Unable to disable HAL volume handling (automounter)"
00201 << std::endl;
00202
00203 cleanup = NONE;
00204 }
00205 }
00206 }
00207 catch(const HalException &e)
00208 {
00209 ZYPP_CAUGHT(e);
00210 WAR << "Unable to disable HAL volume handling (automounter)"
00211 << std::endl;
00212 }
00213 #endif // DISABLE_AUTOMOUNTER
00214 return cleanup;
00215 }
00216
00217
00218 void
00219 restoreAutoMounter(AutoMounterCleanUp cleanup)
00220 {
00221 using namespace zypp::target::hal;
00222
00223 if(cleanup == NONE)
00224 return;
00225
00226 #if DISABLE_AUTOMOUNTER
00227 try
00228 {
00229 HalContext hal(true);
00230
00231 if(cleanup == ENABLE)
00232 {
00233 XXX << "Trying to restore HAL volume handling -- enable"
00234 << std::endl;
00235
00236 hal.setDevicePropertyBool(
00237 HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY,
00238 false
00239 );
00240 }
00241 else
00242 if(cleanup == REMOVE)
00243 {
00244 XXX << "Trying to restore HAL volume handling -- remove"
00245 << std::endl;
00246
00247 hal.removeDeviceProperty(
00248 HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY
00249 );
00250 }
00251
00252 cleanup = NONE;
00253 MIL << "Restored HAL volume handling (automounter)"
00254 << std::endl;
00255 }
00256 catch(const HalException &e)
00257 {
00258 ZYPP_CAUGHT(e);
00259 WAR << "Unable to restore HAL volume handling (automounter)"
00260 << std::endl;
00261 }
00262 #endif // DISABLE_AUTOMOUNTER
00263 }
00264
00266 }
00268
00269
00271 std::string
00272 MediaVerifierBase::info() const
00273 {
00274 return std::string(typeid((*this)).name());
00275 }
00276
00277
00279 std::string
00280 NoVerifier::info() const
00281 {
00282 return std::string("zypp::media::NoVerifier");
00283 }
00284
00285
00287 class MediaManager_Impl
00288 {
00289 private:
00290 friend class MediaManager;
00291
00292 MediaAccessId last_accessid;
00293 AutoMounterCleanUp am_cleanup;
00294 ManagedMediaMap mediaMap;
00295
00296 MediaManager_Impl()
00297 : last_accessid(0)
00298 {
00299
00300 am_cleanup = disableAutoMounter();
00301 }
00302
00303 public:
00304 ~MediaManager_Impl()
00305 {
00306 MutexLock glock(g_Mutex);
00307
00308 try
00309 {
00310
00311 ManagedMediaMap::iterator it;
00312 bool found;
00313 do
00314 {
00315 found = false;
00316 for(it = mediaMap.begin(); it != mediaMap.end(); )
00317 {
00318 if( it->second.handler->dependsOnParent())
00319 {
00320 found = true;
00321
00322
00323 it->second.handler->resetParentId();
00324 mediaMap.erase( it++ );
00325 } else {
00326 ++it;
00327 }
00328 }
00329 } while(found);
00330
00331
00332 mediaMap.clear();
00333
00334
00335 restoreAutoMounter(am_cleanup);
00336 }
00337 catch( ... )
00338 {}
00339 }
00340
00341 inline MediaAccessId
00342 nextAccessId()
00343 {
00344 return ++last_accessid;
00345 }
00346
00347 inline bool
00348 hasId(MediaAccessId accessId) const
00349 {
00350 return mediaMap.find(accessId) != mediaMap.end();
00351 }
00352
00353 inline ManagedMedia &
00354 findMM(MediaAccessId accessId)
00355 {
00356 ManagedMediaMap::iterator it( mediaMap.find(accessId));
00357 if( it == mediaMap.end())
00358 {
00359 ZYPP_THROW(MediaNotOpenException(
00360 "Invalid media access id " + str::numstring(accessId)
00361 ));
00362 }
00363 return it->second;
00364 }
00365
00366 static inline time_t
00367 getMountTableMTime()
00368 {
00369 time_t mtime = zypp::PathInfo("/etc/mtab").mtime();
00370 if( mtime <= 0)
00371 {
00372 WAR << "Failed to retrieve modification time of '/etc/mtab'"
00373 << std::endl;
00374 }
00375 return mtime;
00376 }
00377
00378 static inline MountEntries
00379 getMountEntries()
00380 {
00381
00382
00383 return Mount::getEntries();
00384 }
00385
00386 };
00387
00388
00390
00391 zypp::RW_pointer<MediaManager_Impl> MediaManager::m_impl(NULL);
00392
00393
00395 MediaManager::MediaManager()
00396 {
00397 MutexLock glock(g_Mutex);
00398 if( !m_impl)
00399 {
00400 m_impl.reset( new MediaManager_Impl());
00401 }
00402 }
00403
00404
00405 MediaManager::~MediaManager()
00406 {
00407 }
00408
00409
00410 MediaAccessId
00411 MediaManager::open(const Url &url, const Pathname &preferred_attach_point)
00412 {
00413 MutexLock glock(g_Mutex);
00414
00415
00416 MediaAccessRef handler( new MediaAccess());
00417 MediaVerifierRef verifier( new NoVerifier());
00418 ManagedMedia tmp( handler, verifier);
00419
00420 tmp.handler->open(url, preferred_attach_point);
00421
00422 MediaAccessId nextId = m_impl->nextAccessId();
00423
00424 m_impl->mediaMap[nextId] = tmp;
00425
00426 DBG << "Opened new media access using id " << nextId
00427 << " to " << url.asString() << std::endl;
00428 return nextId;
00429 }
00430
00431
00432 void
00433 MediaManager::close(MediaAccessId accessId)
00434 {
00435 MutexLock glock(g_Mutex);
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00448 for( ; m != m_impl->mediaMap.end(); ++m)
00449 {
00450 if( m->second.handler->dependsOnParent(accessId, true))
00451 {
00452 ZYPP_THROW(MediaIsSharedException(
00453 m->second.handler->url().asString()
00454 ));
00455 }
00456 }
00457
00458 DBG << "Close to access handler using id "
00459 << accessId << " requested" << std::endl;
00460
00461 ManagedMedia &ref( m_impl->findMM(accessId));
00462 ref.handler->close();
00463
00464 m_impl->mediaMap.erase(accessId);
00465 }
00466
00467
00468 bool
00469 MediaManager::isOpen(MediaAccessId accessId) const
00470 {
00471 MutexLock glock(g_Mutex);
00472
00473 ManagedMediaMap::iterator it( m_impl->mediaMap.find(accessId));
00474 return it != m_impl->mediaMap.end() &&
00475 it->second.handler->isOpen();
00476 }
00477
00478
00479 std::string
00480 MediaManager::protocol(MediaAccessId accessId) const
00481 {
00482 MutexLock glock(g_Mutex);
00483
00484 ManagedMedia &ref( m_impl->findMM(accessId));
00485
00486 return ref.handler->protocol();
00487 }
00488
00489
00490 bool
00491 MediaManager::downloads(MediaAccessId accessId) const
00492 {
00493 MutexLock glock(g_Mutex);
00494
00495 ManagedMedia &ref( m_impl->findMM(accessId));
00496
00497 return ref.handler->downloads();
00498 }
00499
00500
00501
00502 bool
00503 MediaManager::downloads(const Url &url)
00504 {
00505 return MediaAccess::downloads( url);
00506 }
00507
00508
00509 Url
00510 MediaManager::url(MediaAccessId accessId) const
00511 {
00512 MutexLock glock(g_Mutex);
00513
00514 ManagedMedia &ref( m_impl->findMM(accessId));
00515
00516 return ref.handler->url();
00517 }
00518
00519
00520 void
00521 MediaManager::addVerifier(MediaAccessId accessId,
00522 const MediaVerifierRef &verifier)
00523 {
00524 MutexLock glock(g_Mutex);
00525
00526 if( !verifier)
00527 ZYPP_THROW(MediaException("Invalid verifier reference"));
00528
00529 ManagedMedia &ref( m_impl->findMM(accessId));
00530
00531 ref.desired = false;
00532 MediaVerifierRef(verifier).swap(ref.verifier);
00533
00534 DBG << "MediaVerifier change: id=" << accessId << ", verifier="
00535 << verifier->info() << std::endl;
00536 }
00537
00538
00539 void
00540 MediaManager::delVerifier(MediaAccessId accessId)
00541 {
00542 MutexLock glock(g_Mutex);
00543
00544 ManagedMedia &ref( m_impl->findMM(accessId));
00545
00546 MediaVerifierRef verifier( new NoVerifier());
00547 ref.desired = false;
00548 ref.verifier.swap(verifier);
00549
00550 DBG << "MediaVerifier change: id=" << accessId << ", verifier="
00551 << verifier->info() << std::endl;
00552 }
00553
00554
00555 bool
00556 MediaManager::setAttachPrefix(const Pathname &attach_prefix)
00557 {
00558 MutexLock glock(g_Mutex);
00559
00560 return MediaHandler::setAttachPrefix(attach_prefix);
00561 }
00562
00563
00564 void
00565 MediaManager::attach(MediaAccessId accessId, bool next)
00566 {
00567 MutexLock glock(g_Mutex);
00568
00569 ManagedMedia &ref( m_impl->findMM(accessId));
00570
00571 DBG << "attach(id=" << accessId << ")" << std::endl;
00572
00573 return ref.handler->attach(next);
00574 }
00575
00576
00577 void MediaManager::attachDesiredMedia(MediaAccessId accessId)
00578 {
00579 MutexLock glock(g_Mutex);
00580
00581 ManagedMedia &ref( m_impl->findMM(accessId));
00582
00583 DBG << "attach(id=" << accessId << ")" << std::endl;
00584
00585
00586 ref.handler->attach(false);
00587 try
00588 {
00589 ref.checkDesired(accessId);
00590 return;
00591 }
00592 catch (const MediaException & ex)
00593 {
00594 ZYPP_CAUGHT(ex);
00595
00596 if (!ref.handler->hasMoreDevices())
00597 ZYPP_RETHROW(ex);
00598
00599 if (ref.handler->isAttached())
00600 ref.handler->release();
00601 }
00602
00603 MIL << "checkDesired(" << accessId << ") of first device failed,"
00604 " going to try others with attach(true)" << std::endl;
00605
00606 while (ref.handler->hasMoreDevices())
00607 {
00608 try
00609 {
00610
00611 ref.handler->attach(true);
00612 ref.checkDesired(accessId);
00613 return;
00614 }
00615 catch (const MediaNotDesiredException & ex)
00616 {
00617 ZYPP_CAUGHT(ex);
00618
00619 if (!ref.handler->hasMoreDevices())
00620 {
00621 MIL << "No desired media found after trying all detected devices." << std::endl;
00622 ZYPP_RETHROW(ex);
00623 }
00624
00625 AttachedMedia media(ref.handler->attachedMedia());
00626 DBG << "Skipping " << media.mediaSource->asString() << ": not desired media." << std::endl;
00627
00628 ref.handler->release();
00629 }
00630 catch (const MediaException & ex)
00631 {
00632 ZYPP_CAUGHT(ex);
00633
00634 if (!ref.handler->hasMoreDevices())
00635 ZYPP_RETHROW(ex);
00636
00637 AttachedMedia media(ref.handler->attachedMedia());
00638 DBG << "Skipping " << media.mediaSource->asString() << " because of exception thrown by attach(true)" << std::endl;
00639
00640 if (ref.handler->isAttached()) ref.handler->release();
00641 }
00642 }
00643 }
00644
00645
00646 void
00647 MediaManager::release(MediaAccessId accessId, bool eject)
00648 {
00649 MutexLock glock(g_Mutex);
00650
00651 ManagedMedia &ref( m_impl->findMM(accessId));
00652
00653 DBG << "release(id=" << accessId
00654 << (eject ? ", eject)" : ")") << std::endl;
00655 if( eject)
00656 {
00657
00658
00659
00660
00661
00662
00663 ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00664 for( ; m != m_impl->mediaMap.end(); ++m)
00665 {
00666 if( m->second.handler->dependsOnParent(accessId, false))
00667 {
00668 try
00669 {
00670 DBG << "Forcing release of handler depending on access id "
00671 << accessId << std::endl;
00672 m->second.desired = false;
00673 m->second.handler->release(!eject);
00674 }
00675 catch(const MediaException &e)
00676 {
00677 ZYPP_CAUGHT(e);
00678 }
00679 }
00680 }
00681 }
00682 ref.desired = false;
00683 ref.handler->release(eject);
00684 }
00685
00686
00687 void
00688 MediaManager::releaseAll()
00689 {
00690 MutexLock glock(g_Mutex);
00691
00692 MIL << "Releasing all attached media" << std::endl;
00693
00694 ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00695 for( ; m != m_impl->mediaMap.end(); ++m)
00696 {
00697 if( m->second.handler->dependsOnParent())
00698 continue;
00699
00700 try
00701 {
00702 if(m->second.handler->isAttached())
00703 {
00704 DBG << "Releasing media id " << m->first << std::endl;
00705 m->second.desired = false;
00706 m->second.handler->release(false);
00707 }
00708 else
00709 {
00710 DBG << "Media id " << m->first << " not attached " << std::endl;
00711 }
00712 }
00713 catch(const MediaException & e)
00714 {
00715 ZYPP_CAUGHT(e);
00716 ERR << "Failed to release media id " << m->first << std::endl;
00717 }
00718 }
00719
00720 MIL << "Exit" << std::endl;
00721 }
00722
00723
00724 void
00725 MediaManager::disconnect(MediaAccessId accessId)
00726 {
00727 MutexLock glock(g_Mutex);
00728
00729 ManagedMedia &ref( m_impl->findMM(accessId));
00730
00731 ref.handler->disconnect();
00732 }
00733
00734
00735 bool
00736 MediaManager::isAttached(MediaAccessId accessId) const
00737 {
00738 MutexLock glock(g_Mutex);
00739
00740 ManagedMedia &ref( m_impl->findMM(accessId));
00741
00742 return ref.handler->isAttached();
00743 }
00744
00745
00746 bool MediaManager::isSharedMedia(MediaAccessId accessId) const
00747 {
00748 MutexLock glock(g_Mutex);
00749
00750 ManagedMedia &ref( m_impl->findMM(accessId));
00751
00752 return ref.handler->isSharedMedia();
00753 }
00754
00755
00756 bool
00757 MediaManager::isDesiredMedia(MediaAccessId accessId) const
00758 {
00759 MutexLock glock(g_Mutex);
00760
00761 ManagedMedia &ref( m_impl->findMM(accessId));
00762
00763 if( !ref.handler->isAttached())
00764 {
00765 ref.desired = false;
00766 }
00767 else
00768 {
00769 try {
00770 ref.desired = ref.verifier->isDesiredMedia(ref.handler);
00771 }
00772 catch(const zypp::Exception &e) {
00773 ZYPP_CAUGHT(e);
00774 ref.desired = false;
00775 }
00776 }
00777 DBG << "isDesiredMedia(" << accessId << "): "
00778 << (ref.desired ? "" : "not ")
00779 << "desired (report by "
00780 << ref.verifier->info() << ")" << std::endl;
00781 return ref.desired;
00782 }
00783
00784
00785 bool
00786 MediaManager::isDesiredMedia(MediaAccessId accessId,
00787 const MediaVerifierRef &verifier) const
00788 {
00789 MutexLock glock(g_Mutex);
00790
00791 MediaVerifierRef v(verifier);
00792 if( !v)
00793 ZYPP_THROW(MediaException("Invalid verifier reference"));
00794
00795 ManagedMedia &ref( m_impl->findMM(accessId));
00796
00797 bool desired = false;
00798 if( ref.handler->isAttached())
00799 {
00800 try {
00801 desired = v->isDesiredMedia(ref.handler);
00802 }
00803 catch(const zypp::Exception &e) {
00804 ZYPP_CAUGHT(e);
00805 desired = false;
00806 }
00807 }
00808 DBG << "isDesiredMedia(" << accessId << "): "
00809 << (desired ? "" : "not ")
00810 << "desired (report by "
00811 << v->info() << ")" << std::endl;
00812 return desired;
00813 }
00814
00815
00816 bool
00817 MediaManager::isChangeable(MediaAccessId accessId)
00818 {
00819 return url(accessId).getScheme() == "cd" || url(accessId).getScheme() == "dvd";
00820 }
00821
00822
00823 Pathname
00824 MediaManager::localRoot(MediaAccessId accessId) const
00825 {
00826 MutexLock glock(g_Mutex);
00827
00828 ManagedMedia &ref( m_impl->findMM(accessId));
00829
00830 Pathname path;
00831 path = ref.handler->localRoot();
00832 return path;
00833 }
00834
00835
00836 Pathname
00837 MediaManager::localPath(MediaAccessId accessId,
00838 const Pathname & pathname) const
00839 {
00840 MutexLock glock(g_Mutex);
00841
00842 ManagedMedia &ref( m_impl->findMM(accessId));
00843
00844 Pathname path;
00845 path = ref.handler->localPath(pathname);
00846 return path;
00847 }
00848
00849
00850 void
00851 MediaManager::provideFile(MediaAccessId accessId,
00852 const Pathname &filename,
00853 bool cached,
00854 bool checkonly) const
00855 {
00856 MutexLock glock(g_Mutex);
00857
00858 ManagedMedia &ref( m_impl->findMM(accessId));
00859
00860 ref.checkDesired(accessId);
00861
00862 ref.handler->provideFile(filename, cached, checkonly);
00863 }
00864
00865
00866 void
00867 MediaManager::provideDir(MediaAccessId accessId,
00868 const Pathname &dirname) const
00869 {
00870 MutexLock glock(g_Mutex);
00871
00872 ManagedMedia &ref( m_impl->findMM(accessId));
00873
00874 ref.checkDesired(accessId);
00875
00876 ref.handler->provideDir(dirname);
00877 }
00878
00879
00880 void
00881 MediaManager::provideDirTree(MediaAccessId accessId,
00882 const Pathname &dirname) const
00883 {
00884 MutexLock glock(g_Mutex);
00885
00886 ManagedMedia &ref( m_impl->findMM(accessId));
00887
00888 ref.checkDesired(accessId);
00889
00890 ref.handler->provideDirTree(dirname);
00891 }
00892
00893
00894 void
00895 MediaManager::releaseFile(MediaAccessId accessId,
00896 const Pathname &filename) const
00897 {
00898 MutexLock glock(g_Mutex);
00899
00900 ManagedMedia &ref( m_impl->findMM(accessId));
00901
00902 ref.checkAttached(accessId);
00903
00904 ref.handler->releaseFile(filename);
00905 }
00906
00907
00908 void
00909 MediaManager::releaseDir(MediaAccessId accessId,
00910 const Pathname &dirname) const
00911 {
00912 MutexLock glock(g_Mutex);
00913
00914 ManagedMedia &ref( m_impl->findMM(accessId));
00915
00916 ref.checkAttached(accessId);
00917
00918 ref.handler->releaseDir(dirname);
00919 }
00920
00921
00922
00923 void
00924 MediaManager::releasePath(MediaAccessId accessId,
00925 const Pathname &pathname) const
00926 {
00927 MutexLock glock(g_Mutex);
00928
00929 ManagedMedia &ref( m_impl->findMM(accessId));
00930
00931 ref.checkAttached(accessId);
00932
00933 ref.handler->releasePath(pathname);
00934 }
00935
00936
00937 void
00938 MediaManager::dirInfo(MediaAccessId accessId,
00939 std::list<std::string> &retlist,
00940 const Pathname &dirname,
00941 bool dots) const
00942 {
00943 MutexLock glock(g_Mutex);
00944
00945 ManagedMedia &ref( m_impl->findMM(accessId));
00946
00947
00948 ref.checkAttached(accessId);
00949
00950 ref.handler->dirInfo(retlist, dirname, dots);
00951 }
00952
00953
00954 void
00955 MediaManager::dirInfo(MediaAccessId accessId,
00956 filesystem::DirContent &retlist,
00957 const Pathname &dirname,
00958 bool dots) const
00959 {
00960 MutexLock glock(g_Mutex);
00961
00962 ManagedMedia &ref( m_impl->findMM(accessId));
00963
00964
00965 ref.checkAttached(accessId);
00966
00967 ref.handler->dirInfo(retlist, dirname, dots);
00968 }
00969
00970
00971 bool
00972 MediaManager::doesFileExist(MediaAccessId accessId, const Pathname & filename ) const
00973 {
00974 MutexLock glock(g_Mutex);
00975 ManagedMedia &ref( m_impl->findMM(accessId));
00976
00977
00978 ref.checkAttached(accessId);
00979
00980 return ref.handler->doesFileExist(filename);
00981 }
00982
00983
00984
00985 time_t
00986 MediaManager::getMountTableMTime()
00987 {
00988 MutexLock glock(g_Mutex);
00989 return MediaManager_Impl::getMountTableMTime();
00990 }
00991
00992
00993
00994 MountEntries
00995 MediaManager::getMountEntries()
00996 {
00997 MutexLock glock(g_Mutex);
00998
00999 return MediaManager_Impl::getMountEntries();
01000 }
01001
01002
01003 bool
01004 MediaManager::isUseableAttachPoint(const Pathname &path,
01005 bool mtab) const
01006 {
01007 if( path.empty() || path == "/" || !PathInfo(path).isDir())
01008 return false;
01009
01010 MutexLock glock(g_Mutex);
01011
01012
01013
01014
01015 ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
01016 for( ; m != m_impl->mediaMap.end(); ++m)
01017 {
01018 AttachedMedia ret = m->second.handler->attachedMedia();
01019 if( ret.mediaSource && ret.attachPoint)
01020 {
01021 std::string mnt(ret.attachPoint->path.asString());
01022 std::string our(path.asString());
01023
01024 if( our == mnt)
01025 {
01026
01027 return false;
01028 }
01029 else
01030 if( mnt.size() > our.size() &&
01031 mnt.at(our.size()) == '/' &&
01032 !mnt.compare(0, our.size(), our))
01033 {
01034
01035
01036 return false;
01037 }
01038 }
01039 }
01040
01041 if( !mtab)
01042 return true;
01043
01044
01045
01046
01047 MountEntries entries( m_impl->getMountEntries());
01048 MountEntries::const_iterator e;
01049 for( e = entries.begin(); e != entries.end(); ++e)
01050 {
01051 std::string mnt(Pathname(e->dir).asString());
01052 std::string our(path.asString());
01053
01054 if( our == mnt)
01055 {
01056
01057 return false;
01058 }
01059 else
01060 if( mnt.size() > our.size() &&
01061 mnt.at(our.size()) == '/' &&
01062 !mnt.compare(0, our.size(), our))
01063 {
01064
01065
01066 return false;
01067 }
01068 }
01069
01070 return true;
01071 }
01072
01073
01074 AttachedMedia
01075 MediaManager::getAttachedMedia(MediaAccessId &accessId) const
01076 {
01077 MutexLock glock(g_Mutex);
01078
01079 ManagedMedia &ref( m_impl->findMM(accessId));
01080
01081 return ref.handler->attachedMedia();
01082 }
01083
01084
01085 AttachedMedia
01086 MediaManager::findAttachedMedia(const MediaSourceRef &media) const
01087 {
01088 MutexLock glock(g_Mutex);
01089
01090 if( !media || media->type.empty())
01091 return AttachedMedia();
01092
01093 ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
01094 for( ; m != m_impl->mediaMap.end(); ++m)
01095 {
01096 if( !m->second.handler->isAttached())
01097 continue;
01098
01099 AttachedMedia ret = m->second.handler->attachedMedia();
01100 if( ret.mediaSource && ret.mediaSource->equals( *media))
01101 return ret;
01102 }
01103 return AttachedMedia();
01104 }
01105
01106
01107 void
01108 MediaManager::forceReleaseShared(const MediaSourceRef &media)
01109 {
01110 MutexLock glock(g_Mutex);
01111
01112 if( !media || media->type.empty())
01113 return;
01114
01115 ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
01116 for( ; m != m_impl->mediaMap.end(); ++m)
01117 {
01118 if( !m->second.handler->isAttached())
01119 continue;
01120
01121 AttachedMedia ret = m->second.handler->attachedMedia();
01122 if( ret.mediaSource && ret.mediaSource->equals( *media))
01123 {
01124 m->second.handler->release(false);
01125 m->second.desired = false;
01126 }
01127 }
01128 }
01129
01131 }
01133
01135 }
01137
01138
01139