MediaISO.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include "zypp/media/MediaISO.h"
00013 #include "zypp/base/Logger.h"
00014 #include "zypp/media/Mount.h"
00015 
00016 #include <iostream>
00017 
00019 namespace zypp
00020 { 
00021 
00023   namespace media
00024   { 
00025 
00027     //
00028     // MediaISO Url:
00029     //
00030     //   Schema: iso
00031     //   Path name: subdir to the location of desired files inside
00032     //              of the ISO.
00033     //   Query parameters:
00034     //     url:        The iso filename source media url pointing
00035     //                 to a directory containing the ISO file.
00036     //     mnt:        Prefered attach point for source media url.
00037     //     iso:        The name of the iso file.
00038     //     filesystem: Optional, defaults to "auto".
00039     //
00041     MediaISO::MediaISO(const Url      &url_r,
00042                        const Pathname &attach_point_hint_r)
00043       : MediaHandler(url_r, attach_point_hint_r,
00044                      url_r.getPathName(), // urlpath below attachpoint
00045                      false)               // does_download
00046     {
00047       MIL << "MediaISO::MediaISO(" << url_r << ", "
00048           << attach_point_hint_r << ")" << std::endl;
00049 
00050       _isofile    = _url.getQueryParam("iso");
00051       if( _isofile.empty())
00052       {
00053         ERR << "Media url does not contain iso filename" << std::endl;
00054         ZYPP_THROW(MediaBadUrlEmptyDestinationException(_url));
00055       }
00056 
00057       _filesystem = _url.getQueryParam("filesystem");
00058       if( _filesystem.empty())
00059         _filesystem = "auto";
00060 
00061       std::string arg;
00062       zypp::Url   src;
00063       try
00064       {
00065         arg = _url.getQueryParam("url");
00066         if( arg.empty() && _isofile.dirname().absolute())
00067         {
00068           src = std::string("dir:///");
00069           src.setPathName(_isofile.dirname().asString());
00070           _isofile = _isofile.basename();
00071         }
00072         else
00073         {
00074           src = arg;
00075         }
00076       }
00077       catch(const zypp::url::UrlException &e)
00078       {
00079         ZYPP_CAUGHT(e);
00080         ERR << "Unable to parse iso filename source media url" << std::endl;
00081         MediaBadUrlException ne(_url);
00082         ne.remember(e);
00083         ZYPP_THROW(ne);
00084       }
00085       if( !src.isValid())
00086       {
00087         ERR << "Invalid iso filename source media url" << std::endl;
00088         ZYPP_THROW(MediaBadUrlException(src));
00089       }
00090       if( src.getScheme() == "iso")
00091       {
00092         ERR << "ISO filename source media url with iso scheme (nested iso): "
00093             << src.asString() << std::endl;
00094         ZYPP_THROW(MediaUnsupportedUrlSchemeException(src));
00095       }
00096 #if 1
00097       else
00098       if( !(src.getScheme() == "hd"   ||
00099             src.getScheme() == "dir"  ||
00100             src.getScheme() == "file" ||
00101             src.getScheme() == "nfs"  ||
00102             src.getScheme() == "smb"  ||
00103             src.getScheme() == "cifs"))
00104       {
00105         ERR << "ISO filename source media url scheme is not supported: "
00106             << src.asString() << std::endl;
00107         ZYPP_THROW(MediaUnsupportedUrlSchemeException(src));
00108       }
00109 #endif
00110 
00111       MediaManager manager;
00112 
00113       _parentId = manager.open(src, _url.getQueryParam("mnt"));
00114     }
00115 
00116     // ---------------------------------------------------------------
00117     MediaISO::~MediaISO()
00118     {
00119       try
00120       {
00121         release();
00122 
00123         if( _parentId)
00124         {
00125           DBG << "Closing parent handler..." << std::endl;
00126           MediaManager manager;
00127           if(manager.isOpen(_parentId))
00128             manager.close(_parentId);
00129           _parentId = 0;
00130         }
00131       }
00132       catch( ... )
00133       {}
00134     }
00135 
00136     // ---------------------------------------------------------------
00137     bool
00138     MediaISO::isAttached() const
00139     {
00140       return checkAttached(false);
00141     }
00142 
00143     // ---------------------------------------------------------------
00144     void MediaISO::attachTo(bool next)
00145     {
00146       if(next)
00147         ZYPP_THROW(MediaNotSupportedException(_url));
00148 
00149       MediaManager manager;
00150       manager.attach(_parentId, false);
00151 
00152       try
00153       {
00154         manager.provideFile(_parentId, _isofile);
00155       }
00156       catch(const MediaException &e1)
00157       {
00158         ZYPP_CAUGHT(e1);
00159         try
00160         {
00161           manager.release(_parentId, false);
00162         }
00163         catch(const MediaException &e2)
00164         {
00165           ZYPP_CAUGHT(e2);
00166         }
00167 
00168         MediaMountException e3(
00169           "Unable to find iso filename on source media",
00170           _url.asString(), attachPoint().asString()
00171         );
00172         e3.remember(e1);
00173         ZYPP_THROW(e3);
00174       }
00175 
00176       Pathname isofile = manager.localPath(_parentId, _isofile);
00177       PathInfo isoinfo( isofile, PathInfo::LSTAT);
00178       if( !isoinfo.isFile())
00179       {
00180         ZYPP_THROW(MediaNotSupportedException(_url));
00181       }
00182 
00183       MediaSourceRef media( new MediaSource(
00184         "iso", isofile.asString()
00185       ));
00186 
00187       AttachedMedia  ret( findAttachedMedia( media));
00188       if( ret.mediaSource &&
00189           ret.attachPoint &&
00190           !ret.attachPoint->empty())
00191       {
00192         DBG << "Using a shared media "
00193             << ret.mediaSource->name
00194             << " attached on "
00195             << ret.attachPoint->path
00196             << std::endl;
00197         removeAttachPoint();
00198         setAttachPoint(ret.attachPoint);
00199         setMediaSource(ret.mediaSource);
00200         return;
00201       }
00202 
00203       std::string mountpoint = attachPoint().asString();
00204       if( !isUseableAttachPoint(attachPoint()))
00205       {
00206         mountpoint = createAttachPoint().asString();
00207         if( mountpoint.empty())
00208           ZYPP_THROW( MediaBadAttachPointException(url()));
00209         setAttachPoint( mountpoint, true);
00210       }
00211 
00212       std::string mountopts("ro,loop");
00213 
00214       Mount mount;
00215       mount.mount(isofile.asString(), mountpoint,
00216                   _filesystem, mountopts);
00217 
00218       setMediaSource(media);
00219 
00220       // wait for /etc/mtab update ...
00221       // (shouldn't be needed)
00222       int limit = 3;
00223       bool mountsucceeded;
00224       while( !(mountsucceeded=isAttached()) && --limit)
00225       {
00226         sleep(1);
00227       }
00228 
00229       if( !mountsucceeded)
00230       {
00231         setMediaSource(MediaSourceRef());
00232         try
00233         {
00234           mount.umount(attachPoint().asString());
00235           manager.release(_parentId);
00236         }
00237         catch (const MediaException & excpt_r)
00238         {
00239           ZYPP_CAUGHT(excpt_r);
00240         }
00241         ZYPP_THROW(MediaMountException(
00242           "Unable to verify that the media was mounted",
00243           isofile.asString(), mountpoint
00244         ));
00245       }
00246     }
00247 
00248     // ---------------------------------------------------------------
00249     void MediaISO::releaseFrom(bool eject)
00250     {
00251       Mount mount;
00252       mount.umount(attachPoint().asString());
00253 
00254       if( _parentId)
00255       {
00256         MediaManager manager;
00257         manager.release(_parentId);
00258       }
00259       // else:
00260       // the media manager has reset the _parentId
00261       // and will destroy the parent handler itself.
00262     }
00263 
00264     // ---------------------------------------------------------------
00265     void MediaISO::getFile(const Pathname &filename) const
00266     {
00267       MediaHandler::getFile(filename);
00268     }
00269 
00270     // ---------------------------------------------------------------
00271     void MediaISO::getDir(const Pathname &dirname,
00272                            bool            recurse_r) const
00273     {
00274       MediaHandler::getDir(dirname, recurse_r);
00275     }
00276 
00277     // ---------------------------------------------------------------
00278     void MediaISO::getDirInfo(std::list<std::string> &retlist,
00279                                const Pathname         &dirname,
00280                                bool                    dots) const
00281     {
00282       MediaHandler::getDirInfo( retlist, dirname, dots );
00283     }
00284 
00285     // ---------------------------------------------------------------
00286     void MediaISO::getDirInfo(filesystem::DirContent &retlist,
00287                                const Pathname         &dirname,
00288                                bool                    dots) const
00289     {
00290       MediaHandler::getDirInfo(retlist, dirname, dots);
00291     }
00292 
00293     bool MediaISO::getDoesFileExist( const Pathname & filename ) const
00294     {
00295       return MediaHandler::getDoesFileExist( filename );
00296     }
00297 
00299   } // namespace media
00301 
00303 } // namespace zypp
00305 
00306 // vim: set ts=2 sts=2 sw=2 ai et:
00307 

Generated on Tue Sep 25 19:23:02 2007 for libzypp by  doxygen 1.5.3