libzypp  10.5.0
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         return Mount::getEntries();
00235       }
00236 
00237     };
00238 
00239 
00241     // STATIC
00242     zypp::RW_pointer<MediaManager_Impl> MediaManager::m_impl(NULL);
00243 
00244 
00246     MediaManager::MediaManager()
00247     {
00248       MutexLock glock(g_Mutex);
00249       if( !m_impl)
00250       {
00251         m_impl.reset( new MediaManager_Impl());
00252       }
00253     }
00254 
00255     // ---------------------------------------------------------------
00256     MediaManager::~MediaManager()
00257     {
00258     }
00259 
00260     // ---------------------------------------------------------------
00261     MediaAccessId
00262     MediaManager::open(const Url &url, const Pathname &preferred_attach_point)
00263     {
00264       MutexLock glock(g_Mutex);
00265 
00266       // create new access handler for it
00267       MediaAccessRef handler( new MediaAccess());
00268       MediaVerifierRef verifier( new NoVerifier());
00269       ManagedMedia tmp( handler, verifier);
00270 
00271       tmp.handler->open(url, preferred_attach_point);
00272 
00273       MediaAccessId nextId = m_impl->nextAccessId();
00274 
00275       m_impl->mediaMap[nextId] = tmp;
00276 
00277       DBG << "Opened new media access using id " << nextId
00278           << " to " << url.asString() << std::endl;
00279       return nextId;
00280     }
00281 
00282     // ---------------------------------------------------------------
00283     void
00284     MediaManager::close(MediaAccessId accessId)
00285     {
00286       MutexLock glock(g_Mutex);
00287 
00288       //
00289       // The MediaISO handler internally requests an accessId
00290       // of a "parent" handler providing the iso file.
00291       // The parent handler accessId is private to MediaISO,
00292       // but the attached media source may be shared reference.
00293       // This means, that if the accessId exactly matches the
00294       // parent handler id, close was used on uninitialized
00295       // accessId variable (or the accessId was guessed) and
00296       // the close request to this id will be rejected here.
00297       //
00298       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00299       for( ; m != m_impl->mediaMap.end(); ++m)
00300       {
00301         if( m->second.handler->dependsOnParent(accessId, true))
00302         {
00303           ZYPP_THROW(MediaIsSharedException(
00304             m->second.handler->url().asString()
00305           ));
00306         }
00307       }
00308 
00309       DBG << "Close to access handler using id "
00310           << accessId << " requested" << std::endl;
00311 
00312       ManagedMedia &ref( m_impl->findMM(accessId));
00313       ref.handler->close();
00314 
00315       m_impl->mediaMap.erase(accessId);
00316     }
00317 
00318     // ---------------------------------------------------------------
00319     bool
00320     MediaManager::isOpen(MediaAccessId accessId) const
00321     {
00322       MutexLock glock(g_Mutex);
00323 
00324       ManagedMediaMap::iterator it( m_impl->mediaMap.find(accessId));
00325       return it != m_impl->mediaMap.end() &&
00326              it->second.handler->isOpen();
00327     }
00328 
00329     // ---------------------------------------------------------------
00330     std::string
00331     MediaManager::protocol(MediaAccessId accessId) const
00332     {
00333       MutexLock glock(g_Mutex);
00334 
00335       ManagedMedia &ref( m_impl->findMM(accessId));
00336 
00337       return ref.handler->protocol();
00338     }
00339 
00340     // ---------------------------------------------------------------
00341           bool
00342     MediaManager::downloads(MediaAccessId accessId) const
00343     {
00344       MutexLock glock(g_Mutex);
00345 
00346       ManagedMedia &ref( m_impl->findMM(accessId));
00347 
00348       return ref.handler->downloads();
00349     }
00350 
00351     // ---------------------------------------------------------------
00352     Url
00353     MediaManager::url(MediaAccessId accessId) const
00354     {
00355       MutexLock glock(g_Mutex);
00356 
00357       ManagedMedia &ref( m_impl->findMM(accessId));
00358 
00359       return ref.handler->url();
00360     }
00361 
00362     // ---------------------------------------------------------------
00363     void
00364     MediaManager::addVerifier(MediaAccessId           accessId,
00365                               const MediaVerifierRef &verifier)
00366     {
00367       MutexLock glock(g_Mutex);
00368 
00369       if( !verifier)
00370         ZYPP_THROW(MediaException("Invalid verifier reference"));
00371 
00372       ManagedMedia &ref( m_impl->findMM(accessId));
00373 
00374       ref.desired = false;
00375       MediaVerifierRef(verifier).swap(ref.verifier);
00376 
00377       DBG << "MediaVerifier change: id=" << accessId << ", verifier="
00378           << verifier->info() << std::endl;
00379     }
00380 
00381     // ---------------------------------------------------------------
00382     void
00383     MediaManager::delVerifier(MediaAccessId accessId)
00384     {
00385       MutexLock glock(g_Mutex);
00386 
00387       ManagedMedia &ref( m_impl->findMM(accessId));
00388 
00389       MediaVerifierRef verifier( new NoVerifier());
00390       ref.desired  = false;
00391       ref.verifier.swap(verifier);
00392 
00393       DBG << "MediaVerifier change: id=" << accessId << ", verifier="
00394           << verifier->info() << std::endl;
00395     }
00396 
00397     // ---------------------------------------------------------------
00398     bool
00399     MediaManager::setAttachPrefix(const Pathname &attach_prefix)
00400     {
00401       MutexLock glock(g_Mutex);
00402 
00403       return MediaHandler::setAttachPrefix(attach_prefix);
00404     }
00405 
00406     // ---------------------------------------------------------------
00407     void MediaManager::attach(MediaAccessId accessId)
00408     {
00409       MutexLock glock(g_Mutex);
00410 
00411       ManagedMedia &ref( m_impl->findMM(accessId));
00412 
00413       DBG << "attach(id=" << accessId << ")" << std::endl;
00414 
00415       // try first mountable/mounted device
00416       ref.handler->attach(false);
00417       try
00418       {
00419         ref.checkDesired(accessId);
00420         return;
00421       }
00422       catch (const MediaException & ex)
00423       {
00424         ZYPP_CAUGHT(ex);
00425 
00426         if (!ref.handler->hasMoreDevices())
00427           ZYPP_RETHROW(ex);
00428 
00429         if (ref.handler->isAttached())
00430           ref.handler->release();
00431       }
00432 
00433       MIL << "checkDesired(" << accessId << ") of first device failed,"
00434         " going to try others with attach(true)" << std::endl;
00435 
00436       while (ref.handler->hasMoreDevices())
00437       {
00438         try
00439         {
00440           // try to attach next device
00441           ref.handler->attach(true);
00442           ref.checkDesired(accessId);
00443           return;
00444         }
00445         catch (const MediaNotDesiredException & ex)
00446         {
00447           ZYPP_CAUGHT(ex);
00448 
00449           if (!ref.handler->hasMoreDevices())
00450           {
00451             MIL << "No desired media found after trying all detected devices." << std::endl;
00452             ZYPP_RETHROW(ex);
00453           }
00454 
00455           AttachedMedia media(ref.handler->attachedMedia());
00456           DBG << "Skipping " << media.mediaSource->asString() << ": not desired media." << std::endl;
00457 
00458           ref.handler->release();
00459         }
00460         catch (const MediaException & ex)
00461         {
00462           ZYPP_CAUGHT(ex);
00463 
00464           if (!ref.handler->hasMoreDevices())
00465             ZYPP_RETHROW(ex);
00466 
00467           AttachedMedia media(ref.handler->attachedMedia());
00468           DBG << "Skipping " << media.mediaSource->asString() << " because of exception thrown by attach(true)" << std::endl;
00469 
00470           if (ref.handler->isAttached()) ref.handler->release();
00471         }
00472       }
00473     }
00474 
00475     // ---------------------------------------------------------------
00476     void
00477     MediaManager::release(MediaAccessId accessId, const std::string & ejectDev)
00478     {
00479       MutexLock glock(g_Mutex);
00480 
00481       ManagedMedia &ref( m_impl->findMM(accessId));
00482 
00483       DBG << "release(id=" << accessId;
00484       if (!ejectDev.empty())
00485         DBG << ", " << ejectDev;
00486       DBG << ")" << std::endl;
00487 
00488       if(!ejectDev.empty())
00489       {
00490         //
00491         // release MediaISO handlers, that are using the one
00492         // specified with accessId, because it provides the
00493         // iso file and it will disappear now (forced release
00494         // with eject).
00495         //
00496         ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00497         for( ; m != m_impl->mediaMap.end(); ++m)
00498         {
00499           if( m->second.handler->dependsOnParent(accessId, false))
00500           {
00501             try
00502             {
00503               DBG << "Forcing release of handler depending on access id "
00504                   << accessId << std::endl;
00505               m->second.desired  = false;
00506               m->second.handler->release();
00507             }
00508             catch(const MediaException &e)
00509             {
00510               ZYPP_CAUGHT(e);
00511             }
00512           }
00513         }
00514       }
00515       ref.desired  = false;
00516       ref.handler->release(ejectDev);
00517     }
00518 
00519     // ---------------------------------------------------------------
00520     void
00521     MediaManager::releaseAll()
00522     {
00523       MutexLock glock(g_Mutex);
00524 
00525       MIL << "Releasing all attached media" << std::endl;
00526 
00527       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00528       for( ; m != m_impl->mediaMap.end(); ++m)
00529       {
00530         if( m->second.handler->dependsOnParent())
00531           continue;
00532 
00533         try
00534         {
00535           if(m->second.handler->isAttached())
00536           {
00537             DBG << "Releasing media id " << m->first << std::endl;
00538             m->second.desired  = false;
00539             m->second.handler->release();
00540           }
00541           else
00542           {
00543             DBG << "Media id " << m->first << " not attached " << std::endl;
00544           }
00545         }
00546         catch(const MediaException & e)
00547         {
00548           ZYPP_CAUGHT(e);
00549           ERR << "Failed to release media id " << m->first << std::endl;
00550         }
00551       }
00552 
00553       MIL << "Exit" << std::endl;
00554     }
00555 
00556     // ---------------------------------------------------------------
00557     void
00558     MediaManager::disconnect(MediaAccessId accessId)
00559     {
00560       MutexLock glock(g_Mutex);
00561 
00562       ManagedMedia &ref( m_impl->findMM(accessId));
00563 
00564       ref.handler->disconnect();
00565     }
00566 
00567     // ---------------------------------------------------------------
00568     bool
00569     MediaManager::isAttached(MediaAccessId accessId) const
00570     {
00571       MutexLock glock(g_Mutex);
00572 
00573       ManagedMedia &ref( m_impl->findMM(accessId));
00574 
00575       return ref.handler->isAttached();
00576     }
00577 
00578     // ---------------------------------------------------------------
00579     bool MediaManager::isSharedMedia(MediaAccessId accessId) const
00580     {
00581       MutexLock glock(g_Mutex);
00582 
00583       ManagedMedia &ref( m_impl->findMM(accessId));
00584 
00585       return ref.handler->isSharedMedia();
00586     }
00587 
00588     // ---------------------------------------------------------------
00589     bool
00590     MediaManager::isDesiredMedia(MediaAccessId accessId) const
00591     {
00592       MutexLock glock(g_Mutex);
00593 
00594       ManagedMedia &ref( m_impl->findMM(accessId));
00595 
00596       if( !ref.handler->isAttached())
00597       {
00598         ref.desired = false;
00599       }
00600       else
00601       {
00602         try {
00603           ref.desired = ref.verifier->isDesiredMedia(ref.handler);
00604         }
00605         catch(const zypp::Exception &e) {
00606           ZYPP_CAUGHT(e);
00607           ref.desired = false;
00608         }
00609       }
00610       DBG << "isDesiredMedia(" << accessId << "): "
00611           << (ref.desired ? "" : "not ")
00612           << "desired (report by "
00613           << ref.verifier->info() << ")" << std::endl;
00614       return ref.desired;
00615     }
00616 
00617     // ---------------------------------------------------------------
00618     bool
00619     MediaManager::isDesiredMedia(MediaAccessId           accessId,
00620                                  const MediaVerifierRef &verifier) const
00621     {
00622       MutexLock glock(g_Mutex);
00623 
00624       MediaVerifierRef v(verifier);
00625       if( !v)
00626         ZYPP_THROW(MediaException("Invalid verifier reference"));
00627 
00628       ManagedMedia &ref( m_impl->findMM(accessId));
00629 
00630       bool desired = false;
00631       if( ref.handler->isAttached())
00632       {
00633         try {
00634           desired = v->isDesiredMedia(ref.handler);
00635         }
00636         catch(const zypp::Exception &e) {
00637           ZYPP_CAUGHT(e);
00638           desired = false;
00639         }
00640       }
00641       DBG << "isDesiredMedia(" << accessId << "): "
00642           << (desired ? "" : "not ")
00643           << "desired (report by "
00644           << v->info() << ")" << std::endl;
00645       return desired;
00646     }
00647 
00648     // ---------------------------------------------------------------
00649     bool
00650     MediaManager::isChangeable(MediaAccessId accessId)
00651     {
00652       return url(accessId).getScheme() == "cd" || url(accessId).getScheme() == "dvd";
00653     }
00654 
00655     // ---------------------------------------------------------------
00656     Pathname
00657     MediaManager::localRoot(MediaAccessId accessId) const
00658     {
00659       MutexLock glock(g_Mutex);
00660 
00661       ManagedMedia &ref( m_impl->findMM(accessId));
00662 
00663       Pathname path;
00664       path = ref.handler->localRoot();
00665       return path;
00666     }
00667 
00668     // ---------------------------------------------------------------
00669     Pathname
00670     MediaManager::localPath(MediaAccessId accessId,
00671                             const Pathname & pathname) const
00672     {
00673       MutexLock glock(g_Mutex);
00674 
00675       ManagedMedia &ref( m_impl->findMM(accessId));
00676 
00677       Pathname path;
00678       path = ref.handler->localPath(pathname);
00679       return path;
00680     }
00681 
00682     // ---------------------------------------------------------------
00683     void
00684     MediaManager::provideFile(MediaAccessId   accessId,
00685                               const Pathname &filename ) const
00686     {
00687       MutexLock glock(g_Mutex);
00688 
00689       ManagedMedia &ref( m_impl->findMM(accessId));
00690 
00691       ref.checkDesired(accessId);
00692 
00693       ref.handler->provideFile(filename);
00694     }
00695 
00696     // ---------------------------------------------------------------
00697     void
00698     MediaManager::setDeltafile(MediaAccessId   accessId,
00699                               const Pathname &filename ) const
00700     {
00701       MutexLock glock(g_Mutex);
00702 
00703       ManagedMedia &ref( m_impl->findMM(accessId));
00704 
00705       ref.checkDesired(accessId);
00706 
00707       ref.handler->setDeltafile(filename);
00708     }
00709 
00710     // ---------------------------------------------------------------
00711     void
00712     MediaManager::provideDir(MediaAccessId   accessId,
00713                              const Pathname &dirname) const
00714     {
00715       MutexLock glock(g_Mutex);
00716 
00717       ManagedMedia &ref( m_impl->findMM(accessId));
00718 
00719       ref.checkDesired(accessId);
00720 
00721       ref.handler->provideDir(dirname);
00722     }
00723 
00724     // ---------------------------------------------------------------
00725     void
00726     MediaManager::provideDirTree(MediaAccessId   accessId,
00727                                  const Pathname &dirname) const
00728     {
00729       MutexLock glock(g_Mutex);
00730 
00731       ManagedMedia &ref( m_impl->findMM(accessId));
00732 
00733       ref.checkDesired(accessId);
00734 
00735       ref.handler->provideDirTree(dirname);
00736     }
00737 
00738     // ---------------------------------------------------------------
00739     void
00740     MediaManager::releaseFile(MediaAccessId   accessId,
00741                               const Pathname &filename) const
00742     {
00743       MutexLock glock(g_Mutex);
00744 
00745       ManagedMedia &ref( m_impl->findMM(accessId));
00746 
00747       ref.checkAttached(accessId);
00748 
00749       ref.handler->releaseFile(filename);
00750     }
00751 
00752     // ---------------------------------------------------------------
00753     void
00754     MediaManager::releaseDir(MediaAccessId   accessId,
00755                              const Pathname &dirname) const
00756     {
00757       MutexLock glock(g_Mutex);
00758 
00759       ManagedMedia &ref( m_impl->findMM(accessId));
00760 
00761       ref.checkAttached(accessId);
00762 
00763       ref.handler->releaseDir(dirname);
00764     }
00765 
00766 
00767     // ---------------------------------------------------------------
00768     void
00769     MediaManager::releasePath(MediaAccessId   accessId,
00770                               const Pathname &pathname) const
00771     {
00772       MutexLock glock(g_Mutex);
00773 
00774       ManagedMedia &ref( m_impl->findMM(accessId));
00775 
00776       ref.checkAttached(accessId);
00777 
00778       ref.handler->releasePath(pathname);
00779     }
00780 
00781     // ---------------------------------------------------------------
00782     void
00783     MediaManager::dirInfo(MediaAccessId           accessId,
00784                           std::list<std::string> &retlist,
00785                           const Pathname         &dirname,
00786                           bool                    dots) const
00787     {
00788       MutexLock glock(g_Mutex);
00789 
00790       ManagedMedia &ref( m_impl->findMM(accessId));
00791 
00792       // FIXME: ref.checkDesired(accessId); ???
00793       ref.checkAttached(accessId);
00794 
00795       ref.handler->dirInfo(retlist, dirname, dots);
00796     }
00797 
00798     // ---------------------------------------------------------------
00799     void
00800     MediaManager::dirInfo(MediaAccessId           accessId,
00801                           filesystem::DirContent &retlist,
00802                           const Pathname         &dirname,
00803                           bool                    dots) const
00804     {
00805       MutexLock glock(g_Mutex);
00806 
00807       ManagedMedia &ref( m_impl->findMM(accessId));
00808 
00809       // FIXME: ref.checkDesired(accessId); ???
00810       ref.checkAttached(accessId);
00811 
00812       ref.handler->dirInfo(retlist, dirname, dots);
00813     }
00814 
00815     // ---------------------------------------------------------------
00816     bool
00817     MediaManager::doesFileExist(MediaAccessId  accessId, const Pathname & filename ) const
00818     {
00819       MutexLock glock(g_Mutex);
00820       ManagedMedia &ref( m_impl->findMM(accessId));
00821 
00822       // FIXME: ref.checkDesired(accessId); ???
00823       ref.checkAttached(accessId);
00824 
00825       return ref.handler->doesFileExist(filename);
00826     }
00827 
00828     // ---------------------------------------------------------------
00829     void
00830     MediaManager::getDetectedDevices(MediaAccessId accessId,
00831                                      std::vector<std::string> & devices,
00832                                      unsigned int & index) const
00833     {
00834       MutexLock glock(g_Mutex);
00835       ManagedMedia &ref( m_impl->findMM(accessId));
00836       return ref.handler->getDetectedDevices(devices, index);
00837     }
00838 
00839     // ---------------------------------------------------------------
00840     // STATIC
00841     time_t
00842     MediaManager::getMountTableMTime()
00843     {
00844       MutexLock glock(g_Mutex);
00845       return MediaManager_Impl::getMountTableMTime();
00846     }
00847 
00848     // ---------------------------------------------------------------
00849     // STATIC
00850     MountEntries
00851     MediaManager::getMountEntries()
00852     {
00853       MutexLock glock(g_Mutex);
00854 
00855       return MediaManager_Impl::getMountEntries();
00856     }
00857 
00858     // ---------------------------------------------------------------
00859     bool
00860     MediaManager::isUseableAttachPoint(const Pathname &path,
00861                                        bool            mtab) const
00862     {
00863       if( path.empty() || path == "/" || !PathInfo(path).isDir())
00864         return false;
00865 
00866       MutexLock glock(g_Mutex);
00867 
00868       //
00869       // check against our current attach points
00870       //
00871       ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
00872       for( ; m != m_impl->mediaMap.end(); ++m)
00873       {
00874         AttachedMedia ret = m->second.handler->attachedMedia();
00875         if( ret.mediaSource && ret.attachPoint)
00876         {
00877           std::string mnt(ret.attachPoint->path.asString());
00878           std::string our(path.asString());
00879 
00880           if( our == mnt)
00881           {
00882             // already used as attach point
00883             return false;
00884           }
00885           else
00886           if( mnt.size() > our.size()   &&
00887               mnt.at(our.size()) == '/' &&
00888              !mnt.compare(0, our.size(), our))
00889           {
00890             // mountpoint is bellow of path
00891             // (would hide the content)
00892             return false;
00893           }
00894         }
00895       }
00896 
00897       if( !mtab)
00898         return true;
00899 
00900       //
00901       // check against system mount entries
00902       //
00903       MountEntries  entries( m_impl->getMountEntries());
00904       MountEntries::const_iterator e;
00905       for( e = entries.begin(); e != entries.end(); ++e)
00906       {
00907         std::string mnt(Pathname(e->dir).asString());
00908         std::string our(path.asString());
00909 
00910         if( our == mnt)
00911         {
00912           // already used as mountpoint
00913           return false;
00914         }
00915         else
00916         if( mnt.size() > our.size()   &&
00917             mnt.at(our.size()) == '/' &&
00918            !mnt.compare(0, our.size(), our))
00919         {
00920           // mountpoint is bellow of path
00921           // (would hide the content)
00922           return false;
00923         }
00924       }
00925 
00926       return true;
00927     }
00928 
00929     // ---------------------------------------------------------------
00930     AttachedMedia
00931     MediaManager::getAttachedMedia(MediaAccessId &accessId) const
00932     {
00933       MutexLock glock(g_Mutex);
00934 
00935       ManagedMedia &ref( m_impl->findMM(accessId));
00936 
00937       return ref.handler->attachedMedia();
00938     }
00939 
00940     // ---------------------------------------------------------------
00941     AttachedMedia
00942     MediaManager::findAttachedMedia(const MediaSourceRef &media) const
00943     {
00944       MutexLock glock(g_Mutex);
00945 
00946       if( !media || media->type.empty())
00947         return AttachedMedia();
00948 
00949       ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
00950       for( ; m != m_impl->mediaMap.end(); ++m)
00951       {
00952         if( !m->second.handler->isAttached())
00953           continue;
00954 
00955         AttachedMedia ret = m->second.handler->attachedMedia();
00956         if( ret.mediaSource && ret.mediaSource->equals( *media))
00957             return ret;
00958       }
00959       return AttachedMedia();
00960     }
00961 
00962     // ---------------------------------------------------------------
00963     void
00964     MediaManager::forceReleaseShared(const MediaSourceRef &media)
00965     {
00966       MutexLock glock(g_Mutex);
00967 
00968       if( !media || media->type.empty())
00969         return;
00970 
00971       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00972       for( ; m != m_impl->mediaMap.end(); ++m)
00973       {
00974         if( !m->second.handler->isAttached())
00975           continue;
00976 
00977         AttachedMedia ret = m->second.handler->attachedMedia();
00978         if( ret.mediaSource && ret.mediaSource->equals( *media))
00979         {
00980           m->second.handler->release();
00981           m->second.desired  = false;
00982         }
00983       }
00984     }
00985 
00987   } // namespace media
00989 
00991 } // namespace zypp
00993 /*
00994 ** vim: set ts=2 sts=2 sw=2 ai et:
00995 */