MediaManager.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <map>
00013 #include <list>
00014 #include <iostream>
00015 #include <typeinfo>
00016 
00017 #include "zypp/media/MediaException.h"
00018 #include "zypp/media/MediaManager.h"
00019 #include "zypp/media/MediaHandler.h"
00020 #include "zypp/media/Mount.h"
00021 #include "zypp/thread/Mutex.h"
00022 #include "zypp/thread/MutexLock.h"
00023 
00024 #include "zypp/base/String.h"
00025 #include "zypp/base/Logger.h"
00026 #include "zypp/Pathname.h"
00027 #include "zypp/PathInfo.h"
00028 
00030 namespace zypp
00031 { 
00032 
00034   namespace media
00035   { 
00036 
00037     using zypp::thread::Mutex;
00038     using zypp::thread::MutexLock;
00039 
00041     namespace // anonymous
00042     { 
00043 
00044 
00045       // -------------------------------------------------------------
00046       // STATIC
00047       static Mutex  g_Mutex;
00048 
00049 
00050       // -------------------------------------------------------------
00051       struct ManagedMedia
00052       {
00053         ~ManagedMedia()
00054         {}
00055 
00056         ManagedMedia()
00057           : desired (false)
00058         {}
00059 
00060         ManagedMedia(const ManagedMedia &m)
00061           : desired (m.desired)
00062           , handler (m.handler)
00063           , verifier(m.verifier)
00064         {}
00065 
00066         ManagedMedia(const MediaAccessRef &h, const MediaVerifierRef &v)
00067           : desired (false)
00068           , handler (h)
00069           , verifier(v)
00070         {}
00071 
00072         inline void
00073         checkAttached(MediaAccessId id)
00074         {
00075           if( !handler->isAttached())
00076           {
00077             DBG << "checkAttached(" << id << ") not attached" << std::endl;
00078             desired = false;
00079             ZYPP_THROW(MediaNotAttachedException(
00080               handler->url()
00081             ));
00082           }
00083         }
00084 
00085         inline void
00086         checkDesired(MediaAccessId id)
00087         {
00088           checkAttached(id);
00089 
00090           if( !desired)
00091           {
00092             try {
00093               desired = verifier->isDesiredMedia(handler);
00094             }
00095             catch(const zypp::Exception &e) {
00096               ZYPP_CAUGHT(e);
00097               desired = false;
00098             }
00099 
00100             if( !desired)
00101             {
00102               DBG << "checkDesired(" << id << "): not desired (report by "
00103                   << verifier->info() << ")" << std::endl;
00104               ZYPP_THROW(MediaNotDesiredException(
00105                 handler->url()
00106               ));
00107             }
00108 
00109             DBG << "checkDesired(" << id << "): desired (report by "
00110                 << verifier->info() << ")" << std::endl;
00111           } else {
00112             DBG << "checkDesired(" << id << "): desired (cached)" << std::endl;
00113           }
00114         }
00115 
00116         bool             desired;
00117         MediaAccessRef   handler;
00118         MediaVerifierRef verifier;
00119       };
00120 
00121 
00122       // -------------------------------------------------------------
00123       typedef std::map<MediaAccessId, ManagedMedia> ManagedMediaMap;
00124 
00126     } // anonymous
00128 
00129 
00131     std::string
00132     MediaVerifierBase::info() const
00133     {
00134       return std::string(typeid((*this)).name());
00135     }
00136 
00137 
00139     std::string
00140     NoVerifier::info() const
00141     {
00142       return std::string("zypp::media::NoVerifier");
00143     }
00144 
00145 
00147     class MediaManager_Impl
00148     {
00149     private:
00150       friend class MediaManager;
00151 
00152       MediaAccessId       last_accessid;
00153       ManagedMediaMap     mediaMap;
00154 
00155       MediaManager_Impl()
00156         : last_accessid(0)
00157       {}
00158 
00159     public:
00160       ~MediaManager_Impl()
00161       {
00162         MutexLock glock(g_Mutex);
00163 
00164         try
00165         {
00166           // remove depending (iso) handlers first
00167           ManagedMediaMap::iterator it;
00168           bool found;
00169           do
00170           {
00171             found = false;
00172             for(it = mediaMap.begin(); it != mediaMap.end(); )
00173             {
00174               if( it->second.handler->dependsOnParent())
00175               {
00176                 found = true;
00177                 // let it forget its parent, we will
00178                 // destroy it later (in clear())...
00179                 it->second.handler->resetParentId();
00180                 mediaMap.erase( it++ ); // postfix! Incrementing before erase
00181               } else {
00182                 ++it;
00183               }
00184             }
00185           } while(found);
00186 
00187           // remove all other handlers
00188           mediaMap.clear();
00189         }
00190         catch( ... )
00191         {}
00192       }
00193 
00194       inline MediaAccessId
00195       nextAccessId()
00196       {
00197         return ++last_accessid;
00198       }
00199 
00200       inline bool
00201       hasId(MediaAccessId accessId) const
00202       {
00203         return mediaMap.find(accessId) != mediaMap.end();
00204       }
00205 
00206       inline ManagedMedia &
00207       findMM(MediaAccessId accessId)
00208       {
00209         ManagedMediaMap::iterator it( mediaMap.find(accessId));
00210         if( it == mediaMap.end())
00211         {
00212           ZYPP_THROW(MediaNotOpenException(
00213             "Invalid media access id " + str::numstring(accessId)
00214           ));
00215         }
00216         return it->second;
00217       }
00218 
00219       static inline time_t
00220       getMountTableMTime()
00221       {
00222         time_t mtime = zypp::PathInfo("/etc/mtab").mtime();
00223         if( mtime <= 0)
00224         {
00225           WAR << "Failed to retrieve modification time of '/etc/mtab'"
00226               << std::endl;
00227         }
00228         return mtime;
00229       }
00230 
00231       static inline MountEntries
00232       getMountEntries()
00233       {
00234         // use "/etc/mtab" by default,
00235         // fallback to "/proc/mounts"
00236         return Mount::getEntries(/* "/etc/mtab" */);
00237       }
00238 
00239     };
00240 
00241 
00243     // STATIC
00244     zypp::RW_pointer<MediaManager_Impl> MediaManager::m_impl(NULL);
00245 
00246 
00248     MediaManager::MediaManager()
00249     {
00250       MutexLock glock(g_Mutex);
00251       if( !m_impl)
00252       {
00253         m_impl.reset( new MediaManager_Impl());
00254       }
00255     }
00256 
00257     // ---------------------------------------------------------------
00258     MediaManager::~MediaManager()
00259     {
00260     }
00261 
00262     // ---------------------------------------------------------------
00263     MediaAccessId
00264     MediaManager::open(const Url &url, const Pathname &preferred_attach_point)
00265     {
00266       MutexLock glock(g_Mutex);
00267 
00268       // create new access handler for it
00269       MediaAccessRef handler( new MediaAccess());
00270       MediaVerifierRef verifier( new NoVerifier());
00271       ManagedMedia tmp( handler, verifier);
00272 
00273       tmp.handler->open(url, preferred_attach_point);
00274 
00275       MediaAccessId nextId = m_impl->nextAccessId();
00276 
00277       m_impl->mediaMap[nextId] = tmp;
00278 
00279       DBG << "Opened new media access using id " << nextId
00280           << " to " << url.asString() << std::endl;
00281       return nextId;
00282     }
00283 
00284     // ---------------------------------------------------------------
00285     void
00286     MediaManager::close(MediaAccessId accessId)
00287     {
00288       MutexLock glock(g_Mutex);
00289 
00290       //
00291       // The MediaISO handler internally requests an accessId
00292       // of a "parent" handler providing the iso file.
00293       // The parent handler accessId is private to MediaISO,
00294       // but the attached media source may be shared reference.
00295       // This means, that if the accessId exactly matches the
00296       // parent handler id, close was used on uninitialized
00297       // accessId variable (or the accessId was guessed) and
00298       // the close request to this id will be rejected here.
00299       //
00300       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00301       for( ; m != m_impl->mediaMap.end(); ++m)
00302       {
00303         if( m->second.handler->dependsOnParent(accessId, true))
00304         {
00305           ZYPP_THROW(MediaIsSharedException(
00306             m->second.handler->url().asString()
00307           ));
00308         }
00309       }
00310 
00311       DBG << "Close to access handler using id "
00312           << accessId << " requested" << std::endl;
00313 
00314       ManagedMedia &ref( m_impl->findMM(accessId));
00315       ref.handler->close();
00316 
00317       m_impl->mediaMap.erase(accessId);
00318     }
00319 
00320     // ---------------------------------------------------------------
00321     bool
00322     MediaManager::isOpen(MediaAccessId accessId) const
00323     {
00324       MutexLock glock(g_Mutex);
00325 
00326       ManagedMediaMap::iterator it( m_impl->mediaMap.find(accessId));
00327       return it != m_impl->mediaMap.end() &&
00328              it->second.handler->isOpen();
00329     }
00330 
00331     // ---------------------------------------------------------------
00332     std::string
00333     MediaManager::protocol(MediaAccessId accessId) const
00334     {
00335       MutexLock glock(g_Mutex);
00336 
00337       ManagedMedia &ref( m_impl->findMM(accessId));
00338 
00339       return ref.handler->protocol();
00340     }
00341 
00342     // ---------------------------------------------------------------
00343           bool
00344     MediaManager::downloads(MediaAccessId accessId) const
00345     {
00346       MutexLock glock(g_Mutex);
00347 
00348       ManagedMedia &ref( m_impl->findMM(accessId));
00349 
00350       return ref.handler->downloads();
00351     }
00352 
00353     // ---------------------------------------------------------------
00354     Url
00355     MediaManager::url(MediaAccessId accessId) const
00356     {
00357       MutexLock glock(g_Mutex);
00358 
00359       ManagedMedia &ref( m_impl->findMM(accessId));
00360 
00361       return ref.handler->url();
00362     }
00363 
00364     // ---------------------------------------------------------------
00365     void
00366     MediaManager::addVerifier(MediaAccessId           accessId,
00367                               const MediaVerifierRef &verifier)
00368     {
00369       MutexLock glock(g_Mutex);
00370 
00371       if( !verifier)
00372         ZYPP_THROW(MediaException("Invalid verifier reference"));
00373 
00374       ManagedMedia &ref( m_impl->findMM(accessId));
00375 
00376       ref.desired = false;
00377       MediaVerifierRef(verifier).swap(ref.verifier);
00378 
00379       DBG << "MediaVerifier change: id=" << accessId << ", verifier="
00380           << verifier->info() << std::endl;
00381     }
00382 
00383     // ---------------------------------------------------------------
00384     void
00385     MediaManager::delVerifier(MediaAccessId accessId)
00386     {
00387       MutexLock glock(g_Mutex);
00388 
00389       ManagedMedia &ref( m_impl->findMM(accessId));
00390 
00391       MediaVerifierRef verifier( new NoVerifier());
00392       ref.desired  = false;
00393       ref.verifier.swap(verifier);
00394 
00395       DBG << "MediaVerifier change: id=" << accessId << ", verifier="
00396           << verifier->info() << std::endl;
00397     }
00398 
00399     // ---------------------------------------------------------------
00400     bool
00401     MediaManager::setAttachPrefix(const Pathname &attach_prefix)
00402     {
00403       MutexLock glock(g_Mutex);
00404 
00405       return MediaHandler::setAttachPrefix(attach_prefix);
00406     }
00407 
00408     // ---------------------------------------------------------------
00409     void MediaManager::attach(MediaAccessId accessId)
00410     {
00411       MutexLock glock(g_Mutex);
00412 
00413       ManagedMedia &ref( m_impl->findMM(accessId));
00414 
00415       DBG << "attach(id=" << accessId << ")" << std::endl;
00416 
00417       // try first mountable/mounted device
00418       ref.handler->attach(false);
00419       try
00420       {
00421         ref.checkDesired(accessId);
00422         return;
00423       }
00424       catch (const MediaException & ex)
00425       {
00426         ZYPP_CAUGHT(ex);
00427 
00428         if (!ref.handler->hasMoreDevices())
00429           ZYPP_RETHROW(ex);
00430 
00431         if (ref.handler->isAttached())
00432           ref.handler->release();
00433       }
00434 
00435       MIL << "checkDesired(" << accessId << ") of first device failed,"
00436         " going to try others with attach(true)" << std::endl;
00437 
00438       while (ref.handler->hasMoreDevices())
00439       {
00440         try
00441         {
00442           // try to attach next device
00443           ref.handler->attach(true);
00444           ref.checkDesired(accessId);
00445           return;
00446         }
00447         catch (const MediaNotDesiredException & ex)
00448         {
00449           ZYPP_CAUGHT(ex);
00450 
00451           if (!ref.handler->hasMoreDevices())
00452           {
00453             MIL << "No desired media found after trying all detected devices." << std::endl;
00454             ZYPP_RETHROW(ex);
00455           }
00456 
00457           AttachedMedia media(ref.handler->attachedMedia());
00458           DBG << "Skipping " << media.mediaSource->asString() << ": not desired media." << std::endl;
00459 
00460           ref.handler->release();
00461         }
00462         catch (const MediaException & ex)
00463         {
00464           ZYPP_CAUGHT(ex);
00465 
00466           if (!ref.handler->hasMoreDevices())
00467             ZYPP_RETHROW(ex);
00468 
00469           AttachedMedia media(ref.handler->attachedMedia());
00470           DBG << "Skipping " << media.mediaSource->asString() << " because of exception thrown by attach(true)" << std::endl;
00471 
00472           if (ref.handler->isAttached()) ref.handler->release();
00473         }
00474       }
00475     }
00476 
00477     // ---------------------------------------------------------------
00478     void
00479     MediaManager::release(MediaAccessId accessId, const std::string & ejectDev)
00480     {
00481       MutexLock glock(g_Mutex);
00482 
00483       ManagedMedia &ref( m_impl->findMM(accessId));
00484 
00485       DBG << "release(id=" << accessId;
00486       if (!ejectDev.empty())
00487         DBG << ", " << ejectDev;
00488       DBG << ")" << std::endl;
00489 
00490       if(!ejectDev.empty())
00491       {
00492         //
00493         // release MediaISO handlers, that are using the one
00494         // specified with accessId, because it provides the
00495         // iso file and it will disappear now (forced release
00496         // with eject).
00497         //
00498         ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00499         for( ; m != m_impl->mediaMap.end(); ++m)
00500         {
00501           if( m->second.handler->dependsOnParent(accessId, false))
00502           {
00503             try
00504             {
00505               DBG << "Forcing release of handler depending on access id "
00506                   << accessId << std::endl;
00507               m->second.desired  = false;
00508               m->second.handler->release();
00509             }
00510             catch(const MediaException &e)
00511             {
00512               ZYPP_CAUGHT(e);
00513             }
00514           }
00515         }
00516       }
00517       ref.desired  = false;
00518       ref.handler->release(ejectDev);
00519     }
00520 
00521     // ---------------------------------------------------------------
00522     void
00523     MediaManager::releaseAll()
00524     {
00525       MutexLock glock(g_Mutex);
00526 
00527       MIL << "Releasing all attached media" << std::endl;
00528 
00529       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00530       for( ; m != m_impl->mediaMap.end(); ++m)
00531       {
00532         if( m->second.handler->dependsOnParent())
00533           continue;
00534 
00535         try
00536         {
00537           if(m->second.handler->isAttached())
00538           {
00539             DBG << "Releasing media id " << m->first << std::endl;
00540             m->second.desired  = false;
00541             m->second.handler->release();
00542           }
00543           else
00544           {
00545             DBG << "Media id " << m->first << " not attached " << std::endl;
00546           }
00547         }
00548         catch(const MediaException & e)
00549         {
00550           ZYPP_CAUGHT(e);
00551           ERR << "Failed to release media id " << m->first << std::endl;
00552         }
00553       }
00554 
00555       MIL << "Exit" << std::endl;
00556     }
00557 
00558     // ---------------------------------------------------------------
00559     void
00560     MediaManager::disconnect(MediaAccessId accessId)
00561     {
00562       MutexLock glock(g_Mutex);
00563 
00564       ManagedMedia &ref( m_impl->findMM(accessId));
00565 
00566       ref.handler->disconnect();
00567     }
00568 
00569     // ---------------------------------------------------------------
00570     bool
00571     MediaManager::isAttached(MediaAccessId accessId) const
00572     {
00573       MutexLock glock(g_Mutex);
00574 
00575       ManagedMedia &ref( m_impl->findMM(accessId));
00576 
00577       return ref.handler->isAttached();
00578     }
00579 
00580     // ---------------------------------------------------------------
00581     bool MediaManager::isSharedMedia(MediaAccessId accessId) const
00582     {
00583       MutexLock glock(g_Mutex);
00584 
00585       ManagedMedia &ref( m_impl->findMM(accessId));
00586 
00587       return ref.handler->isSharedMedia();
00588     }
00589 
00590     // ---------------------------------------------------------------
00591     bool
00592     MediaManager::isDesiredMedia(MediaAccessId accessId) const
00593     {
00594       MutexLock glock(g_Mutex);
00595 
00596       ManagedMedia &ref( m_impl->findMM(accessId));
00597 
00598       if( !ref.handler->isAttached())
00599       {
00600         ref.desired = false;
00601       }
00602       else
00603       {
00604         try {
00605           ref.desired = ref.verifier->isDesiredMedia(ref.handler);
00606         }
00607         catch(const zypp::Exception &e) {
00608           ZYPP_CAUGHT(e);
00609           ref.desired = false;
00610         }
00611       }
00612       DBG << "isDesiredMedia(" << accessId << "): "
00613           << (ref.desired ? "" : "not ")
00614           << "desired (report by "
00615           << ref.verifier->info() << ")" << std::endl;
00616       return ref.desired;
00617     }
00618 
00619     // ---------------------------------------------------------------
00620     bool
00621     MediaManager::isDesiredMedia(MediaAccessId           accessId,
00622                                  const MediaVerifierRef &verifier) const
00623     {
00624       MutexLock glock(g_Mutex);
00625 
00626       MediaVerifierRef v(verifier);
00627       if( !v)
00628         ZYPP_THROW(MediaException("Invalid verifier reference"));
00629 
00630       ManagedMedia &ref( m_impl->findMM(accessId));
00631 
00632       bool desired = false;
00633       if( ref.handler->isAttached())
00634       {
00635         try {
00636           desired = v->isDesiredMedia(ref.handler);
00637         }
00638         catch(const zypp::Exception &e) {
00639           ZYPP_CAUGHT(e);
00640           desired = false;
00641         }
00642       }
00643       DBG << "isDesiredMedia(" << accessId << "): "
00644           << (desired ? "" : "not ")
00645           << "desired (report by "
00646           << v->info() << ")" << std::endl;
00647       return desired;
00648     }
00649 
00650     // ---------------------------------------------------------------
00651     bool
00652     MediaManager::isChangeable(MediaAccessId accessId)
00653     {
00654       return url(accessId).getScheme() == "cd" || url(accessId).getScheme() == "dvd";
00655     }
00656 
00657     // ---------------------------------------------------------------
00658     Pathname
00659     MediaManager::localRoot(MediaAccessId accessId) const
00660     {
00661       MutexLock glock(g_Mutex);
00662 
00663       ManagedMedia &ref( m_impl->findMM(accessId));
00664 
00665       Pathname path;
00666       path = ref.handler->localRoot();
00667       return path;
00668     }
00669 
00670     // ---------------------------------------------------------------
00671     Pathname
00672     MediaManager::localPath(MediaAccessId accessId,
00673                             const Pathname & pathname) const
00674     {
00675       MutexLock glock(g_Mutex);
00676 
00677       ManagedMedia &ref( m_impl->findMM(accessId));
00678 
00679       Pathname path;
00680       path = ref.handler->localPath(pathname);
00681       return path;
00682     }
00683 
00684     // ---------------------------------------------------------------
00685     void
00686     MediaManager::provideFile(MediaAccessId   accessId,
00687                               const Pathname &filename ) const
00688     {
00689       MutexLock glock(g_Mutex);
00690 
00691       ManagedMedia &ref( m_impl->findMM(accessId));
00692 
00693       ref.checkDesired(accessId);
00694 
00695       ref.handler->provideFile(filename);
00696     }
00697 
00698     // ---------------------------------------------------------------
00699     void
00700     MediaManager::provideDir(MediaAccessId   accessId,
00701                              const Pathname &dirname) const
00702     {
00703       MutexLock glock(g_Mutex);
00704 
00705       ManagedMedia &ref( m_impl->findMM(accessId));
00706 
00707       ref.checkDesired(accessId);
00708 
00709       ref.handler->provideDir(dirname);
00710     }
00711 
00712     // ---------------------------------------------------------------
00713     void
00714     MediaManager::provideDirTree(MediaAccessId   accessId,
00715                                  const Pathname &dirname) const
00716     {
00717       MutexLock glock(g_Mutex);
00718 
00719       ManagedMedia &ref( m_impl->findMM(accessId));
00720 
00721       ref.checkDesired(accessId);
00722 
00723       ref.handler->provideDirTree(dirname);
00724     }
00725 
00726     // ---------------------------------------------------------------
00727     void
00728     MediaManager::releaseFile(MediaAccessId   accessId,
00729                               const Pathname &filename) const
00730     {
00731       MutexLock glock(g_Mutex);
00732 
00733       ManagedMedia &ref( m_impl->findMM(accessId));
00734 
00735       ref.checkAttached(accessId);
00736 
00737       ref.handler->releaseFile(filename);
00738     }
00739 
00740     // ---------------------------------------------------------------
00741     void
00742     MediaManager::releaseDir(MediaAccessId   accessId,
00743                              const Pathname &dirname) const
00744     {
00745       MutexLock glock(g_Mutex);
00746 
00747       ManagedMedia &ref( m_impl->findMM(accessId));
00748 
00749       ref.checkAttached(accessId);
00750 
00751       ref.handler->releaseDir(dirname);
00752     }
00753 
00754 
00755     // ---------------------------------------------------------------
00756     void
00757     MediaManager::releasePath(MediaAccessId   accessId,
00758                               const Pathname &pathname) const
00759     {
00760       MutexLock glock(g_Mutex);
00761 
00762       ManagedMedia &ref( m_impl->findMM(accessId));
00763 
00764       ref.checkAttached(accessId);
00765 
00766       ref.handler->releasePath(pathname);
00767     }
00768 
00769     // ---------------------------------------------------------------
00770     void
00771     MediaManager::dirInfo(MediaAccessId           accessId,
00772                           std::list<std::string> &retlist,
00773                           const Pathname         &dirname,
00774                           bool                    dots) const
00775     {
00776       MutexLock glock(g_Mutex);
00777 
00778       ManagedMedia &ref( m_impl->findMM(accessId));
00779 
00780       // FIXME: ref.checkDesired(accessId); ???
00781       ref.checkAttached(accessId);
00782 
00783       ref.handler->dirInfo(retlist, dirname, dots);
00784     }
00785 
00786     // ---------------------------------------------------------------
00787     void
00788     MediaManager::dirInfo(MediaAccessId           accessId,
00789                           filesystem::DirContent &retlist,
00790                           const Pathname         &dirname,
00791                           bool                    dots) const
00792     {
00793       MutexLock glock(g_Mutex);
00794 
00795       ManagedMedia &ref( m_impl->findMM(accessId));
00796 
00797       // FIXME: ref.checkDesired(accessId); ???
00798       ref.checkAttached(accessId);
00799 
00800       ref.handler->dirInfo(retlist, dirname, dots);
00801     }
00802 
00803     // ---------------------------------------------------------------
00804     bool
00805     MediaManager::doesFileExist(MediaAccessId  accessId, const Pathname & filename ) const
00806     {
00807       MutexLock glock(g_Mutex);
00808       ManagedMedia &ref( m_impl->findMM(accessId));
00809 
00810       // FIXME: ref.checkDesired(accessId); ???
00811       ref.checkAttached(accessId);
00812 
00813       return ref.handler->doesFileExist(filename);
00814     }
00815 
00816     // ---------------------------------------------------------------
00817     void
00818     MediaManager::getDetectedDevices(MediaAccessId accessId,
00819                                      std::vector<std::string> & devices,
00820                                      unsigned int & index) const
00821     {
00822       MutexLock glock(g_Mutex);
00823       ManagedMedia &ref( m_impl->findMM(accessId));
00824       return ref.handler->getDetectedDevices(devices, index);
00825     }
00826 
00827     // ---------------------------------------------------------------
00828     // STATIC
00829     time_t
00830     MediaManager::getMountTableMTime()
00831     {
00832       MutexLock glock(g_Mutex);
00833       return MediaManager_Impl::getMountTableMTime();
00834     }
00835 
00836     // ---------------------------------------------------------------
00837     // STATIC
00838     MountEntries
00839     MediaManager::getMountEntries()
00840     {
00841       MutexLock glock(g_Mutex);
00842 
00843       return MediaManager_Impl::getMountEntries();
00844     }
00845 
00846     // ---------------------------------------------------------------
00847     bool
00848     MediaManager::isUseableAttachPoint(const Pathname &path,
00849                                        bool            mtab) const
00850     {
00851       if( path.empty() || path == "/" || !PathInfo(path).isDir())
00852         return false;
00853 
00854       MutexLock glock(g_Mutex);
00855 
00856       //
00857       // check against our current attach points
00858       //
00859       ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
00860       for( ; m != m_impl->mediaMap.end(); ++m)
00861       {
00862         AttachedMedia ret = m->second.handler->attachedMedia();
00863         if( ret.mediaSource && ret.attachPoint)
00864         {
00865           std::string mnt(ret.attachPoint->path.asString());
00866           std::string our(path.asString());
00867 
00868           if( our == mnt)
00869           {
00870             // already used as attach point
00871             return false;
00872           }
00873           else
00874           if( mnt.size() > our.size()   &&
00875               mnt.at(our.size()) == '/' &&
00876              !mnt.compare(0, our.size(), our))
00877           {
00878             // mountpoint is bellow of path
00879             // (would hide the content)
00880             return false;
00881           }
00882         }
00883       }
00884 
00885       if( !mtab)
00886         return true;
00887 
00888       //
00889       // check against system mount entries
00890       //
00891       MountEntries  entries( m_impl->getMountEntries());
00892       MountEntries::const_iterator e;
00893       for( e = entries.begin(); e != entries.end(); ++e)
00894       {
00895         std::string mnt(Pathname(e->dir).asString());
00896         std::string our(path.asString());
00897 
00898         if( our == mnt)
00899         {
00900           // already used as mountpoint
00901           return false;
00902         }
00903         else
00904         if( mnt.size() > our.size()   &&
00905             mnt.at(our.size()) == '/' &&
00906            !mnt.compare(0, our.size(), our))
00907         {
00908           // mountpoint is bellow of path
00909           // (would hide the content)
00910           return false;
00911         }
00912       }
00913 
00914       return true;
00915     }
00916 
00917     // ---------------------------------------------------------------
00918     AttachedMedia
00919     MediaManager::getAttachedMedia(MediaAccessId &accessId) const
00920     {
00921       MutexLock glock(g_Mutex);
00922 
00923       ManagedMedia &ref( m_impl->findMM(accessId));
00924 
00925       return ref.handler->attachedMedia();
00926     }
00927 
00928     // ---------------------------------------------------------------
00929     AttachedMedia
00930     MediaManager::findAttachedMedia(const MediaSourceRef &media) const
00931     {
00932       MutexLock glock(g_Mutex);
00933 
00934       if( !media || media->type.empty())
00935         return AttachedMedia();
00936 
00937       ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
00938       for( ; m != m_impl->mediaMap.end(); ++m)
00939       {
00940         if( !m->second.handler->isAttached())
00941           continue;
00942 
00943         AttachedMedia ret = m->second.handler->attachedMedia();
00944         if( ret.mediaSource && ret.mediaSource->equals( *media))
00945             return ret;
00946       }
00947       return AttachedMedia();
00948     }
00949 
00950     // ---------------------------------------------------------------
00951     void
00952     MediaManager::forceReleaseShared(const MediaSourceRef &media)
00953     {
00954       MutexLock glock(g_Mutex);
00955 
00956       if( !media || media->type.empty())
00957         return;
00958 
00959       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00960       for( ; m != m_impl->mediaMap.end(); ++m)
00961       {
00962         if( !m->second.handler->isAttached())
00963           continue;
00964 
00965         AttachedMedia ret = m->second.handler->attachedMedia();
00966         if( ret.mediaSource && ret.mediaSource->equals( *media))
00967         {
00968           m->second.handler->release();
00969           m->second.desired  = false;
00970         }
00971       }
00972     }
00973 
00975   } // namespace media
00977 
00979 } // namespace zypp
00981 /*
00982 ** vim: set ts=2 sts=2 sw=2 ai et:
00983 */

doxygen