1 /****************************************************************************************
2 * Copyright (c) 2006-2007 Maximilian Kossick <maximilian.kossick@googlemail.com> *
3 * Copyright (c) 2011 Peter C. Ndikuwera <pndiku@gmail.com> *
4 * *
5 * This program is free software; you can redistribute it and/or modify it under *
6 * the terms of the GNU General Public License as published by the Free Software *
7 * Foundation; either version 2 of the License, or (at your option) any later *
8 * version. *
9 * *
10 * This program is distributed in the hope that it will be useful, but WITHOUT ANY *
11 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
12 * PARTICULAR PURPOSE. See the GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License along with *
15 * this program. If not, see <http://www.gnu.org/licenses/>. *
16 ****************************************************************************************/
17
18 #define DEBUG_PREFIX "NfsDeviceHandler"
19
20 #include "NfsDeviceHandler.h"
21
22 #include "core/support/Debug.h"
23 #include <core/storage/SqlStorage.h>
24
25 #include <QUrl>
26 #include <QDir>
27 #include <Solid/Device>
28 #include <Solid/StorageAccess>
29 #include <Solid/NetworkShare>
30
NfsDeviceHandler(int deviceId,const QString & server,const QString & share,const QString & mountPoint,const QString & udi)31 NfsDeviceHandler::NfsDeviceHandler( int deviceId, const QString &server, const QString &share, const QString &mountPoint, const QString &udi )
32 : DeviceHandler()
33 , m_deviceID( deviceId )
34 , m_server( server )
35 , m_share( share )
36 , m_mountPoint( mountPoint )
37 , m_udi( udi )
38 {
39 DEBUG_BLOCK
40 }
41
NfsDeviceHandler(int deviceId,const QString & mountPoint,const QString & udi)42 NfsDeviceHandler::NfsDeviceHandler( int deviceId, const QString &mountPoint, const QString &udi )
43 : DeviceHandler()
44 , m_deviceID( deviceId )
45 , m_mountPoint( mountPoint )
46 , m_udi( udi )
47 {
48 DEBUG_BLOCK
49 }
50
~NfsDeviceHandler()51 NfsDeviceHandler::~NfsDeviceHandler()
52 {
53 }
54
55 bool
isAvailable() const56 NfsDeviceHandler::isAvailable() const
57 {
58 return true;
59 }
60
61
62 QString
type() const63 NfsDeviceHandler::type() const
64 {
65 return "nfs";
66 }
67
68 int
getDeviceID()69 NfsDeviceHandler::getDeviceID()
70 {
71 return m_deviceID;
72 }
73
getDevicePath() const74 const QString &NfsDeviceHandler::getDevicePath() const
75 {
76 return m_mountPoint;
77 }
78
getURL(QUrl & absolutePath,const QUrl & relativePath)79 void NfsDeviceHandler::getURL( QUrl &absolutePath, const QUrl &relativePath )
80 {
81 absolutePath.setPath( m_mountPoint );
82 absolutePath = absolutePath.adjusted(QUrl::StripTrailingSlash);
83 absolutePath.setPath(absolutePath.path() + QLatin1Char('/') + ( relativePath.path() ));
84 absolutePath.setPath( QDir::cleanPath(absolutePath.path()) );
85 }
86
getPlayableURL(QUrl & absolutePath,const QUrl & relativePath)87 void NfsDeviceHandler::getPlayableURL( QUrl &absolutePath, const QUrl &relativePath )
88 {
89 getURL( absolutePath, relativePath );
90 }
91
deviceMatchesUdi(const QString & udi) const92 bool NfsDeviceHandler::deviceMatchesUdi( const QString &udi ) const
93 {
94 return m_udi == udi;
95 }
96
97 ///////////////////////////////////////////////////////////////////////////////
98 // class NfsDeviceHandlerFactory
99 ///////////////////////////////////////////////////////////////////////////////
100
type() const101 QString NfsDeviceHandlerFactory::type( ) const
102 {
103 return "nfs";
104 }
105
canCreateFromMedium() const106 bool NfsDeviceHandlerFactory::canCreateFromMedium( ) const
107 {
108 return true;
109 }
110
canCreateFromConfig() const111 bool NfsDeviceHandlerFactory::canCreateFromConfig( ) const
112 {
113 return false;
114 }
115
canHandle(const Solid::Device & device) const116 bool NfsDeviceHandlerFactory::canHandle( const Solid::Device &device ) const
117 {
118 const Solid::NetworkShare *share = device.as<Solid::NetworkShare>();
119 if( !share )
120 {
121 debug() << __PRETTY_FUNCTION__ << device.udi() << "has no NetworkShare interface";
122 return false;
123 }
124 if( share->type() != Solid::NetworkShare::Nfs )
125 {
126 debug() << __PRETTY_FUNCTION__ << device.udi() << "has type" << share->type()
127 << "but nfs type is" << Solid::NetworkShare::Nfs;
128 return false;
129 }
130 const Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
131 if( !access )
132 {
133 debug() << __PRETTY_FUNCTION__ << device.udi() << "has no StorageAccess interface";
134 return false;
135 }
136 if( !access->isAccessible() || access->filePath().isEmpty() )
137 {
138 debug() << __PRETTY_FUNCTION__ << device.udi() << "is not accessible"
139 << "or has empty mount-point";
140 return false;
141 }
142 return true;
143 }
144
~NfsDeviceHandlerFactory()145 NfsDeviceHandlerFactory::~NfsDeviceHandlerFactory( )
146 {
147 }
148
149 DeviceHandler *
createHandler(const KSharedConfigPtr &,QSharedPointer<SqlStorage>) const150 NfsDeviceHandlerFactory::createHandler( const KSharedConfigPtr&, QSharedPointer<SqlStorage> ) const
151 {
152 return nullptr;
153 }
154
155 DeviceHandler *
createHandler(const Solid::Device & device,const QString & udi,QSharedPointer<SqlStorage> s) const156 NfsDeviceHandlerFactory::createHandler( const Solid::Device &device, const QString &udi, QSharedPointer<SqlStorage> s ) const
157 {
158 DEBUG_BLOCK
159 if( !s )
160 {
161 debug() << "!s, returning 0";
162 return nullptr;
163 }
164 if( !canHandle( device ) )
165 return nullptr;
166
167 const Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
168 Q_ASSERT( access ); // canHandle() checks it
169 QString mountPoint = access->filePath();
170
171 const Solid::NetworkShare *netShare = device.as<Solid::NetworkShare>();
172 Q_ASSERT( netShare ); // canHandle() checks it
173 QUrl url = netShare->url(); // nfs://thinkpad/test or nfs://thinkpad/
174 QString server = url.host();
175 QString share = url.path(); // leading slash is preserved for nfs shares
176
177 QStringList ids = s->query( QString( "SELECT id, label, lastmountpoint "
178 "FROM devices WHERE type = 'nfs' "
179 "AND servername = '%1' AND sharename = '%2';" )
180 .arg( s->escape( server ),
181 s->escape( share ) ) );
182 if ( ids.size() == 3 )
183 {
184 debug() << "Found existing NFS config for ID " << ids[0] << " , server " << server << " ,share " << share;
185 s->query( QString( "UPDATE devices SET lastmountpoint = '%2' WHERE "
186 "id = %1;" )
187 .arg( ids[0],
188 s->escape( mountPoint ) ) );
189 return new NfsDeviceHandler( ids[0].toInt(), server, share, mountPoint, udi );
190 }
191 else
192 {
193 int id = s->insert( QString( "INSERT INTO devices"
194 "( type, servername, sharename, lastmountpoint ) "
195 "VALUES ( 'nfs', '%1', '%2', '%3' );" )
196 .arg( s->escape( server ),
197 s->escape( share ),
198 s->escape( mountPoint ) ),
199 "devices" );
200 if ( id == 0 )
201 {
202 warning() << "Inserting into devices failed for type=nfs, server=" << server << ", share=" << share;
203 return nullptr;
204 }
205 debug() << "Created new NFS device with ID " << id << " , server " << server << " ,share " << share;
206 return new NfsDeviceHandler( id, server, share, mountPoint, udi );
207 }
208 }
209