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 "NfsDeviceHandler"
0019  
0020 #include "NfsDeviceHandler.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 NfsDeviceHandler::NfsDeviceHandler( 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 NfsDeviceHandler::NfsDeviceHandler( 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 NfsDeviceHandler::~NfsDeviceHandler()
0052 {
0053 }
0054 
0055 bool
0056 NfsDeviceHandler::isAvailable() const
0057 {
0058     return true;
0059 }
0060 
0061 
0062 QString
0063 NfsDeviceHandler::type() const
0064 {
0065     return "nfs";
0066 }
0067 
0068 int
0069 NfsDeviceHandler::getDeviceID()
0070 {
0071     return m_deviceID;
0072 }
0073 
0074 const QString &NfsDeviceHandler::getDevicePath() const
0075 {
0076     return m_mountPoint;
0077 }
0078 
0079 void NfsDeviceHandler::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 NfsDeviceHandler::getPlayableURL( QUrl &absolutePath, const QUrl &relativePath )
0088 {
0089     getURL( absolutePath, relativePath );
0090 }
0091 
0092 bool NfsDeviceHandler::deviceMatchesUdi( const QString &udi ) const
0093 {
0094   return m_udi == udi;
0095 }
0096 
0097 ///////////////////////////////////////////////////////////////////////////////
0098 // class NfsDeviceHandlerFactory
0099 ///////////////////////////////////////////////////////////////////////////////
0100 
0101 QString NfsDeviceHandlerFactory::type( ) const
0102 {
0103     return "nfs";
0104 }
0105 
0106 bool NfsDeviceHandlerFactory::canCreateFromMedium( ) const
0107 {
0108     return true;
0109 }
0110 
0111 bool NfsDeviceHandlerFactory::canCreateFromConfig( ) const
0112 {
0113     return false;
0114 }
0115 
0116 bool NfsDeviceHandlerFactory::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::Nfs )
0125     {
0126         debug() << __PRETTY_FUNCTION__ << device.udi() << "has type" << share->type()
0127                 << "but nfs type is" << Solid::NetworkShare::Nfs;
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 NfsDeviceHandlerFactory::~NfsDeviceHandlerFactory( )
0146 {
0147 }
0148 
0149 DeviceHandler *
0150 NfsDeviceHandlerFactory::createHandler( const KSharedConfigPtr&, QSharedPointer<SqlStorage> ) const
0151 {
0152     return nullptr;
0153 }
0154 
0155 DeviceHandler *
0156 NfsDeviceHandlerFactory::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(); // nfs://thinkpad/test or nfs://thinkpad/
0174     QString server = url.host();
0175     QString share = url.path(); // leading slash is preserved for nfs shares
0176 
0177     QStringList ids = s->query( QString( "SELECT id, label, lastmountpoint "
0178                                          "FROM devices WHERE type = 'nfs' "
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 NFS 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 NfsDeviceHandler( 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 ( 'nfs', '%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=nfs, server=" << server << ", share=" << share;
0203             return nullptr;
0204         }
0205         debug() << "Created new NFS device with ID " << id << " , server " << server << " ,share " << share;
0206         return new NfsDeviceHandler( id, server, share, mountPoint, udi );
0207     }
0208 }