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 options["guest"];
00163
00164 if ( ! options.has( "rw" ) ) {
00165 options["ro"];
00166 }
00167
00168 Mount::Options::iterator toEnv;
00169
00170
00171 toEnv = options.find("username");
00172 if ( toEnv != options.end() ) {
00173 if ( username.empty() )
00174 username = toEnv->second;
00175 options.erase( toEnv );
00176 }
00177 toEnv = options.find("user");
00178 if ( toEnv != options.end() ) {
00179 if ( username.empty() )
00180 username = toEnv->second;
00181 options.erase( toEnv );
00182 }
00183
00184
00185 toEnv = options.find("password");
00186 if ( toEnv != options.end() ) {
00187 if ( password.empty() )
00188 password = toEnv->second;
00189 options.erase( toEnv );
00190 }
00191 toEnv = options.find("pass");
00192 if ( toEnv != options.end() ) {
00193 if ( password.empty() )
00194 password = toEnv->second;
00195 options.erase( toEnv );
00196 }
00197
00198
00199 string workgroup = _url.getQueryParam("workgroup");
00200 if ( workgroup.size() ) {
00201 options["workgroup"] = workgroup;
00202 }
00203
00204
00205 Mount::Environment environment;
00206 if ( username.size() )
00207 environment["USER"] = username;
00208 if ( password.size() )
00209 environment["PASSWD"] = password;
00210
00212
00213
00214 filesystem::TmpPath credentials;
00215 if ( username.size() || password.size() )
00216 {
00217 filesystem::TmpFile tmp;
00218 ofstream outs( tmp.path().asString().c_str() );
00219 outs << "username=" << username << endl;
00220 outs << "password=" << password << endl;
00221 outs.close();
00222
00223 credentials = tmp;
00224 options["credentials"] = credentials.path().asString();
00225 }
00226
00228
00229 mount.mount( path, mountpoint, _vfstype,
00230 options.asString(), environment );
00231
00232 setMediaSource(media);
00233
00234
00235
00236 int limit = 3;
00237 bool mountsucceeded;
00238 while( !(mountsucceeded=isAttached()) && --limit)
00239 {
00240 sleep(1);
00241 }
00242
00243 if( !mountsucceeded)
00244 {
00245 setMediaSource(MediaSourceRef());
00246 try
00247 {
00248 mount.umount(attachPoint().asString());
00249 }
00250 catch (const MediaException & excpt_r)
00251 {
00252 ZYPP_CAUGHT(excpt_r);
00253 }
00254 ZYPP_THROW(MediaMountException(
00255 "Unable to verify that the media was mounted",
00256 path, mountpoint
00257 ));
00258 }
00259 }
00260
00262
00263
00264
00265
00266
00267
00268 bool
00269 MediaSMB::isAttached() const
00270 {
00271 return checkAttached(true);
00272 }
00273
00275
00276
00277
00278
00279
00280
00281
00282 void MediaSMB::releaseFrom( bool eject )
00283 {
00284 Mount mount;
00285 mount.umount(attachPoint().asString());
00286 }
00287
00288
00290
00291
00292
00293
00294
00295
00296 void MediaSMB::getFile (const Pathname & filename) const
00297 {
00298 MediaHandler::getFile( filename );
00299 }
00300
00302
00303
00304
00305
00306
00307
00308 void MediaSMB::getDir( const Pathname & dirname, bool recurse_r ) const
00309 {
00310 MediaHandler::getDir( dirname, recurse_r );
00311 }
00312
00314
00315
00316
00317
00318
00319
00320
00321 void MediaSMB::getDirInfo( std::list<std::string> & retlist,
00322 const Pathname & dirname, bool dots ) const
00323 {
00324 MediaHandler::getDirInfo( retlist, dirname, dots );
00325 }
00326
00328
00329
00330
00331
00332
00333
00334
00335 void MediaSMB::getDirInfo( filesystem::DirContent & retlist,
00336 const Pathname & dirname, bool dots ) const
00337 {
00338 MediaHandler::getDirInfo( retlist, dirname, dots );
00339 }
00340
00341 }
00342 }