00001
00002
00003
00004
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
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
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(),
00045 false)
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
00221
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
00260
00261
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 }
00301
00303 }
00305
00306
00307