00001
00002
00003
00004
00005
00006
00007
00008
00013 #include <iostream>
00014 #include <fstream>
00015
00016 #include "zypp/base/Logger.h"
00017 #include "zypp/TmpPath.h"
00018 #include "zypp/KVMap.h"
00019 #include "zypp/media/Mount.h"
00020 #include "zypp/media/MediaSMB.h"
00021
00022 #include <sys/types.h>
00023 #include <sys/mount.h>
00024 #include <errno.h>
00025 #include <dirent.h>
00026
00027 using namespace std;
00028
00029 namespace zypp {
00030 namespace media {
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 inline string getShare( Pathname spath_r )
00041 {
00042 if ( spath_r.empty() )
00043 return string();
00044
00045 string share( spath_r.absolutename().asString() );
00046 string::size_type sep = share.find( "/", 1 );
00047 if ( sep == string::npos )
00048 share = share.erase( 0, 1 );
00049 else
00050 share = share.substr( 1, sep-1 );
00051
00052
00053 while ( (sep = share.find( "%2f" )) != string::npos ) {
00054 share.replace( sep, 3, "/" );
00055 }
00056
00057 return share;
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 inline Pathname stripShare( Pathname spath_r )
00069 {
00070 if ( spath_r.empty() )
00071 return Pathname();
00072
00073 string striped( spath_r.absolutename().asString() );
00074 string::size_type sep = striped.find( "/", 1 );
00075 if ( sep == string::npos )
00076 return "/";
00077
00078 return striped.substr( sep );
00079 }
00080
00082
00083
00084
00086
00088
00089
00090
00091
00092
00093
00094
00095 MediaSMB::MediaSMB( const Url & url_r,
00096 const Pathname & attach_point_hint_r )
00097 : MediaHandler( url_r, attach_point_hint_r,
00098 stripShare( url_r.getPathName() ),
00099 false )
00100 , _vfstype( "cifs" )
00101 {
00102 MIL << "MediaSMB::MediaSMB(" << url_r << ", " << attach_point_hint_r << ")" << endl;
00103 }
00104
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 void MediaSMB::attachTo(bool next)
00119 {
00120 if(_url.getHost().empty())
00121 ZYPP_THROW(MediaBadUrlEmptyHostException(_url));
00122 if(next)
00123 ZYPP_THROW(MediaNotSupportedException(_url));
00124
00125 string path = "//";
00126 path += _url.getHost() + "/" + getShare( _url.getPathName() );
00127
00128 MediaSourceRef media( new MediaSource( _vfstype, path));
00129 AttachedMedia ret( findAttachedMedia( media));
00130
00131 if( ret.mediaSource &&
00132 ret.attachPoint &&
00133 !ret.attachPoint->empty())
00134 {
00135 DBG << "Using a shared media "
00136 << ret.mediaSource->name
00137 << " attached on "
00138 << ret.attachPoint->path
00139 << endl;
00140
00141 removeAttachPoint();
00142 setAttachPoint(ret.attachPoint);
00143 setMediaSource(ret.mediaSource);
00144 return;
00145 }
00146
00147 std::string mountpoint = attachPoint().asString();
00148 if( !isUseableAttachPoint(attachPoint()))
00149 {
00150 mountpoint = createAttachPoint().asString();
00151 if( mountpoint.empty())
00152 ZYPP_THROW( MediaBadAttachPointException(url()));
00153 setAttachPoint( mountpoint, true);
00154 }
00155
00156 Mount mount;
00157
00158 Mount::Options options( _url.getQueryParam("mountoptions") );
00159 string username = _url.getUsername();
00160 string password = _url.getPassword();
00161
00162 if ( ! options.has( "rw" ) ) {
00163 options["ro"];
00164 }
00165
00166 Mount::Options::iterator toEnv;
00167
00168
00169 toEnv = options.find("username");
00170 if ( toEnv != options.end() ) {
00171 if ( username.empty() )
00172 username = toEnv->second;
00173 options.erase( toEnv );
00174 }
00175 toEnv = options.find("user");
00176 if ( toEnv != options.end() ) {
00177 if ( username.empty() )
00178 username = toEnv->second;
00179 options.erase( toEnv );
00180 }
00181
00182
00183 toEnv = options.find("password");
00184 if ( toEnv != options.end() ) {
00185 if ( password.empty() )
00186 password = toEnv->second;
00187 options.erase( toEnv );
00188 }
00189 toEnv = options.find("pass");
00190 if ( toEnv != options.end() ) {
00191 if ( password.empty() )
00192 password = toEnv->second;
00193 options.erase( toEnv );
00194 }
00195
00196
00197 string workgroup = _url.getQueryParam("workgroup");
00198 if ( workgroup.size() ) {
00199 options["workgroup"] = workgroup;
00200 }
00201
00202
00203 Mount::Environment environment;
00204 if ( username.size() )
00205 environment["USER"] = username;
00206 if ( password.size() )
00207 environment["PASSWD"] = password;
00208
00210
00211
00212 filesystem::TmpPath credentials;
00213 if ( username.size() || password.size() )
00214 {
00215 filesystem::TmpFile tmp;
00216 ofstream outs( tmp.path().asString().c_str() );
00217 outs << "username=" << username << endl;
00218 outs << "password=" << password << endl;
00219 outs.close();
00220
00221 credentials = tmp;
00222 options["credentials"] = credentials.path().asString();
00223 }
00224 else
00225
00226
00227 options["guest"];
00228
00229
00231
00232 mount.mount( path, mountpoint, _vfstype,
00233 options.asString(), environment );
00234
00235 setMediaSource(media);
00236
00237
00238
00239 int limit = 3;
00240 bool mountsucceeded;
00241 while( !(mountsucceeded=isAttached()) && --limit)
00242 {
00243 sleep(1);
00244 }
00245
00246 if( !mountsucceeded)
00247 {
00248 setMediaSource(MediaSourceRef());
00249 try
00250 {
00251 mount.umount(attachPoint().asString());
00252 }
00253 catch (const MediaException & excpt_r)
00254 {
00255 ZYPP_CAUGHT(excpt_r);
00256 }
00257 ZYPP_THROW(MediaMountException(
00258 "Unable to verify that the media was mounted",
00259 path, mountpoint
00260 ));
00261 }
00262 }
00263
00265
00266
00267
00268
00269
00270
00271 bool
00272 MediaSMB::isAttached() const
00273 {
00274 return checkAttached(true);
00275 }
00276
00278
00279
00280
00281
00282
00283
00284
00285 void MediaSMB::releaseFrom( bool eject )
00286 {
00287 Mount mount;
00288 mount.umount(attachPoint().asString());
00289 }
00290
00291
00293
00294
00295
00296
00297
00298
00299 void MediaSMB::getFile (const Pathname & filename) const
00300 {
00301 MediaHandler::getFile( filename );
00302 }
00303
00305
00306
00307
00308
00309
00310
00311 void MediaSMB::getDir( const Pathname & dirname, bool recurse_r ) const
00312 {
00313 MediaHandler::getDir( dirname, recurse_r );
00314 }
00315
00317
00318
00319
00320
00321
00322
00323
00324 void MediaSMB::getDirInfo( std::list<std::string> & retlist,
00325 const Pathname & dirname, bool dots ) const
00326 {
00327 MediaHandler::getDirInfo( retlist, dirname, dots );
00328 }
00329
00331
00332
00333
00334
00335
00336
00337
00338 void MediaSMB::getDirInfo( filesystem::DirContent & retlist,
00339 const Pathname & dirname, bool dots ) const
00340 {
00341 MediaHandler::getDirInfo( retlist, dirname, dots );
00342 }
00343
00344 bool MediaSMB::getDoesFileExist( const Pathname & filename ) const
00345 {
00346 return MediaHandler::getDoesFileExist( filename );
00347 }
00348
00349 }
00350 }