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         ZYPP_THROW(MediaBadUrlException(_url));
00082       }
00083       if( !src.isValid())
00084       {
00085         ERR << "Invalid iso filename source media url" << std::endl;
00086         ZYPP_THROW(MediaBadUrlException(src));
00087       }
00088       if( src.getScheme() == "iso")
00089       {
00090         ERR << "ISO filename source media url with iso scheme (nested iso): "
00091             << src.asString() << std::endl;
00092         ZYPP_THROW(MediaUnsupportedUrlSchemeException(src));
00093       }
00094 #if 1
00095       else
00096       if( !(src.getScheme() == "hd"   ||
00097             src.getScheme() == "dir"  ||
00098             src.getScheme() == "file" ||
00099             src.getScheme() == "nfs"  ||
00100             src.getScheme() == "smb"  ||
00101             src.getScheme() == "cifs"))
00102       {
00103         ERR << "ISO filename source media url scheme is not supported: "
00104             << src.asString() << std::endl;
00105         ZYPP_THROW(MediaUnsupportedUrlSchemeException(src));
00106       }
00107 #endif
00108 
00109       MediaManager manager;
00110 
00111       _parentId = manager.open(src, _url.getQueryParam("mnt"));
00112     }
00113 
00114     // ---------------------------------------------------------------
00115     MediaISO::~MediaISO()
00116     {
00117       try
00118       {
00119         release();
00120 
00121         if( _parentId)
00122         {
00123           DBG << "Closing parent handler..." << std::endl;
00124           MediaManager manager;
00125           if(manager.isOpen(_parentId))
00126             manager.close(_parentId);
00127           _parentId = 0;
00128         }
00129       }
00130       catch( ... )
00131       {}
00132     }
00133 
00134     // ---------------------------------------------------------------
00135     bool
00136     MediaISO::isAttached() const
00137     {
00138       return checkAttached(false);
00139     }
00140 
00141     // ---------------------------------------------------------------
00142     void MediaISO::attachTo(bool next)
00143     {
00144       if(next)
00145         ZYPP_THROW(MediaNotSupportedException(_url));
00146 
00147       MediaManager manager;
00148       manager.attach(_parentId, false);
00149 
00150       try
00151       {
00152         manager.provideFile(_parentId, _isofile);
00153       }
00154       catch(const MediaException &e1)
00155       {
00156         ZYPP_CAUGHT(e1);
00157         try
00158         {
00159           manager.release(_parentId, false);
00160         }
00161         catch(const MediaException &e2)
00162         {
00163           ZYPP_CAUGHT(e2);
00164         }
00165         ZYPP_THROW(MediaMountException(
00166           "Unable to find iso filename on source media",
00167           _url.asString(), attachPoint().asString()
00168         ));
00169       }
00170 
00171       Pathname isofile = manager.localPath(_parentId, _isofile);
00172       PathInfo isoinfo( isofile, PathInfo::LSTAT);
00173       if( !isoinfo.isFile())
00174       {
00175         ZYPP_THROW(MediaNotSupportedException(_url));
00176       }
00177 
00178       MediaSourceRef media( new MediaSource(
00179         "iso", isofile.asString()
00180       ));
00181 
00182       AttachedMedia  ret( findAttachedMedia( media));
00183       if( ret.mediaSource &&
00184           ret.attachPoint &&
00185           !ret.attachPoint->empty())
00186       {
00187         DBG << "Using a shared media "
00188             << ret.mediaSource->name
00189             << " attached on "
00190             << ret.attachPoint->path
00191             << std::endl;
00192         removeAttachPoint();
00193         setAttachPoint(ret.attachPoint);
00194         setMediaSource(ret.mediaSource);
00195         return;
00196       }
00197 
00198       std::string mountpoint = attachPoint().asString();
00199       if( !isUseableAttachPoint(attachPoint()))
00200       {
00201         mountpoint = createAttachPoint().asString();
00202         if( mountpoint.empty())
00203           ZYPP_THROW( MediaBadAttachPointException(url()));
00204         setAttachPoint( mountpoint, true);
00205       }
00206 
00207       std::string mountopts("ro,loop");
00208 
00209       Mount mount;
00210       mount.mount(isofile.asString(), mountpoint,
00211                   _filesystem, mountopts);
00212 
00213       setMediaSource(media);
00214 
00215       // wait for /etc/mtab update ...
00216       // (shouldn't be needed)
00217       int limit = 3;
00218       bool mountsucceeded;
00219       while( !(mountsucceeded=isAttached()) && --limit)
00220       {
00221         sleep(1);
00222       }
00223 
00224       if( !mountsucceeded)
00225       {
00226         setMediaSource(MediaSourceRef());
00227         try
00228         {
00229           mount.umount(attachPoint().asString());
00230           manager.release(_parentId);
00231         }
00232         catch (const MediaException & excpt_r)
00233         {
00234           ZYPP_CAUGHT(excpt_r);
00235         }
00236         ZYPP_THROW(MediaMountException(isofile.asString(), mountpoint,
00237           "Unable to verify that the media was mounted"
00238         ));
00239       }
00240     }
00241 
00242     // ---------------------------------------------------------------
00243     void MediaISO::releaseFrom(bool eject)
00244     {
00245       Mount mount;
00246       mount.umount(attachPoint().asString());
00247 
00248       if( _parentId)
00249       {
00250         MediaManager manager;
00251         manager.release(_parentId);
00252       }
00253       // else:
00254       // the media manager has reset the _parentId
00255       // and will destroy the parent handler itself.
00256     }
00257 
00258     // ---------------------------------------------------------------
00259     void MediaISO::getFile(const Pathname &filename) const
00260     {
00261       MediaHandler::getFile(filename);
00262     }
00263 
00264     // ---------------------------------------------------------------
00265     void MediaISO::getDir(const Pathname &dirname,
00266                            bool            recurse_r) const
00267     {
00268       MediaHandler::getDir(dirname, recurse_r);
00269     }
00270 
00271     // ---------------------------------------------------------------
00272     void MediaISO::getDirInfo(std::list<std::string> &retlist,
00273                                const Pathname         &dirname,
00274                                bool                    dots) const
00275     {
00276       MediaHandler::getDirInfo( retlist, dirname, dots );
00277     }
00278 
00279     // ---------------------------------------------------------------
00280     void MediaISO::getDirInfo(filesystem::DirContent &retlist,
00281                                const Pathname         &dirname,
00282                                bool                    dots) const
00283     {
00284       MediaHandler::getDirInfo(retlist, dirname, dots);
00285     }
00286 
00287 
00289   } // namespace media
00291 
00293 } // namespace zypp
00295 
00296 // vim: set ts=2 sts=2 sw=2 ai et:
00297 

Generated on Thu Jul 6 00:07:21 2006 for zypp by  doxygen 1.4.6