File indexing completed on 2025-02-23 04:27:37
0001 /**************************************************************************************** 0002 * Copyright (c) 2006-2007 Maximilian Kossick <maximilian.kossick@googlemail.com> * 0003 * Copyright (c) 2011 Peter C. Ndikuwera <pndiku@gmail.com> * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify it under * 0006 * the terms of the GNU General Public License as published by the Free Software * 0007 * Foundation; either version 2 of the License, or (at your option) any later * 0008 * version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0011 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0012 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License along with * 0015 * this program. If not, see <http://www.gnu.org/licenses/>. * 0016 ****************************************************************************************/ 0017 0018 #define DEBUG_PREFIX "SmbDeviceHandler" 0019 0020 #include "SmbDeviceHandler.h" 0021 0022 #include "core/support/Debug.h" 0023 #include <core/storage/SqlStorage.h> 0024 0025 #include <QUrl> 0026 #include <QDir> 0027 #include <Solid/Device> 0028 #include <Solid/StorageAccess> 0029 #include <Solid/NetworkShare> 0030 0031 SmbDeviceHandler::SmbDeviceHandler( int deviceId, const QString &server, const QString &share, const QString &mountPoint, const QString &udi ) 0032 : DeviceHandler() 0033 , m_deviceID( deviceId ) 0034 , m_server( server ) 0035 , m_share( share ) 0036 , m_mountPoint( mountPoint ) 0037 , m_udi( udi ) 0038 { 0039 DEBUG_BLOCK 0040 } 0041 0042 SmbDeviceHandler::SmbDeviceHandler( int deviceId, const QString &mountPoint, const QString &udi ) 0043 : DeviceHandler() 0044 , m_deviceID( deviceId ) 0045 , m_mountPoint( mountPoint ) 0046 , m_udi( udi ) 0047 { 0048 DEBUG_BLOCK 0049 } 0050 0051 SmbDeviceHandler::~SmbDeviceHandler() 0052 { 0053 } 0054 0055 bool 0056 SmbDeviceHandler::isAvailable() const 0057 { 0058 return true; 0059 } 0060 0061 0062 QString 0063 SmbDeviceHandler::type() const 0064 { 0065 return "smb"; 0066 } 0067 0068 int 0069 SmbDeviceHandler::getDeviceID() 0070 { 0071 return m_deviceID; 0072 } 0073 0074 const QString &SmbDeviceHandler::getDevicePath() const 0075 { 0076 return m_mountPoint; 0077 } 0078 0079 void SmbDeviceHandler::getURL( QUrl &absolutePath, const QUrl &relativePath ) 0080 { 0081 absolutePath.setPath( m_mountPoint ); 0082 absolutePath = absolutePath.adjusted(QUrl::StripTrailingSlash); 0083 absolutePath.setPath(absolutePath.path() + QLatin1Char('/') + ( relativePath.path() )); 0084 absolutePath.setPath( QDir::cleanPath(absolutePath.path()) ); 0085 } 0086 0087 void SmbDeviceHandler::getPlayableURL( QUrl &absolutePath, const QUrl &relativePath ) 0088 { 0089 getURL( absolutePath, relativePath ); 0090 } 0091 0092 bool SmbDeviceHandler::deviceMatchesUdi( const QString &udi ) const 0093 { 0094 return m_udi == udi; 0095 } 0096 0097 /////////////////////////////////////////////////////////////////////////////// 0098 // class SmbDeviceHandlerFactory 0099 /////////////////////////////////////////////////////////////////////////////// 0100 0101 QString SmbDeviceHandlerFactory::type( ) const 0102 { 0103 return "smb"; 0104 } 0105 0106 bool SmbDeviceHandlerFactory::canCreateFromMedium( ) const 0107 { 0108 return true; 0109 } 0110 0111 bool SmbDeviceHandlerFactory::canCreateFromConfig( ) const 0112 { 0113 return false; 0114 } 0115 0116 bool SmbDeviceHandlerFactory::canHandle( const Solid::Device &device ) const 0117 { 0118 const Solid::NetworkShare *share = device.as<Solid::NetworkShare>(); 0119 if( !share ) 0120 { 0121 debug() << __PRETTY_FUNCTION__ << device.udi() << "has no NetworkShare interface"; 0122 return false; 0123 } 0124 if( share->type() != Solid::NetworkShare::Cifs ) 0125 { 0126 debug() << __PRETTY_FUNCTION__ << device.udi() << "has type" << share->type() 0127 << "but smbfs/cifs type is" << Solid::NetworkShare::Cifs; 0128 return false; 0129 } 0130 const Solid::StorageAccess *access = device.as<Solid::StorageAccess>(); 0131 if( !access ) 0132 { 0133 debug() << __PRETTY_FUNCTION__ << device.udi() << "has no StorageAccess interface"; 0134 return false; 0135 } 0136 if( !access->isAccessible() || access->filePath().isEmpty() ) 0137 { 0138 debug() << __PRETTY_FUNCTION__ << device.udi() << "is not accessible" 0139 << "or has empty mount-point"; 0140 return false; 0141 } 0142 return true; 0143 } 0144 0145 SmbDeviceHandlerFactory::~SmbDeviceHandlerFactory( ) 0146 { 0147 } 0148 0149 DeviceHandler * 0150 SmbDeviceHandlerFactory::createHandler( const KSharedConfigPtr&, QSharedPointer<SqlStorage> ) const 0151 { 0152 return nullptr; 0153 } 0154 0155 DeviceHandler * 0156 SmbDeviceHandlerFactory::createHandler( const Solid::Device &device, const QString &udi, QSharedPointer<SqlStorage> s ) const 0157 { 0158 DEBUG_BLOCK 0159 if( !s ) 0160 { 0161 debug() << "!s, returning 0"; 0162 return nullptr; 0163 } 0164 if( !canHandle( device ) ) 0165 return nullptr; 0166 0167 const Solid::StorageAccess *access = device.as<Solid::StorageAccess>(); 0168 Q_ASSERT( access ); // canHandle() checks it 0169 QString mountPoint = access->filePath(); 0170 0171 const Solid::NetworkShare *netShare = device.as<Solid::NetworkShare>(); 0172 Q_ASSERT( netShare ); // canHandle() checks it 0173 QUrl url = netShare->url(); // smb://testanot/share2 0174 QString server = url.host(); 0175 QString share = url.path().mid( 1 ); // strip leading slash, not usual in smb shares 0176 0177 QStringList ids = s->query( QString( "SELECT id, label, lastmountpoint " 0178 "FROM devices WHERE type = 'smb' " 0179 "AND servername = '%1' AND sharename = '%2';" ) 0180 .arg( s->escape( server ), 0181 s->escape( share ) ) ); 0182 if ( ids.size() == 3 ) 0183 { 0184 debug() << "Found existing SMB config for ID " << ids[0] << " , server " << server << " ,share " << share; 0185 s->query( QString( "UPDATE devices SET lastmountpoint = '%2' WHERE " 0186 "id = %1;" ) 0187 .arg( ids[0], 0188 s->escape( mountPoint ) ) ); 0189 return new SmbDeviceHandler( ids[0].toInt(), server, share, mountPoint, udi ); 0190 } 0191 else 0192 { 0193 int id = s->insert( QString( "INSERT INTO devices" 0194 "( type, servername, sharename, lastmountpoint ) " 0195 "VALUES ( 'smb', '%1', '%2', '%3' );" ) 0196 .arg( s->escape( server ), 0197 s->escape( share ), 0198 s->escape( mountPoint ) ), 0199 "devices" ); 0200 if ( id == 0 ) 0201 { 0202 warning() << "Inserting into devices failed for type=smb, server=" << server << ", share=" << share; 0203 return nullptr; 0204 } 0205 debug() << "Created new SMB device with ID " << id << " , server " << server << " ,share " << share; 0206 return new SmbDeviceHandler( id, server, share, mountPoint, udi ); 0207 } 0208 }