1 /****************************************************************************************
2 * Copyright (c) 2006-2007 Maximilian Kossick <maximilian.kossick@googlemail.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify it under *
5 * the terms of the GNU General Public License as published by the Free Software *
6 * Foundation; either version 2 of the License, or (at your option) any later *
7 * version. *
8 * *
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY *
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
11 * PARTICULAR PURPOSE. See the GNU General Public License for more details. *
12 * *
13 * You should have received a copy of the GNU General Public License along with *
14 * this program. If not, see <http://www.gnu.org/licenses/>. *
15 ****************************************************************************************/
16
17 #define DEBUG_PREFIX "MassStorageDeviceHandler"
18
19 #include "MassStorageDeviceHandler.h"
20
21 #include "core/support/Debug.h"
22 #include <core/storage/SqlStorage.h>
23
24 #include <QUrl>
25 #include <QDir>
26 #include <Solid/Device>
27 #include <Solid/StorageAccess>
28 #include <Solid/StorageVolume>
29
MassStorageDeviceHandler()30 MassStorageDeviceHandler::MassStorageDeviceHandler(): DeviceHandler()
31 {
32 }
33
MassStorageDeviceHandler(int deviceId,const QString & mountPoint,const QString & udi)34 MassStorageDeviceHandler::MassStorageDeviceHandler( int deviceId, const QString &mountPoint, const QString &udi )
35 : DeviceHandler()
36 , m_deviceID( deviceId )
37 , m_mountPoint( mountPoint )
38 , m_udi( udi )
39 {
40 DEBUG_BLOCK
41 }
42
~MassStorageDeviceHandler()43 MassStorageDeviceHandler::~MassStorageDeviceHandler()
44 {
45 }
46
isAvailable() const47 bool MassStorageDeviceHandler::isAvailable() const
48 {
49 return true;
50 }
51
52
type() const53 QString MassStorageDeviceHandler::type() const
54 {
55 return "uuid";
56 }
57
getDeviceID()58 int MassStorageDeviceHandler::getDeviceID()
59 {
60 return m_deviceID;
61 }
62
getDevicePath() const63 const QString &MassStorageDeviceHandler::getDevicePath() const
64 {
65 return m_mountPoint;
66 }
67
getURL(QUrl & absolutePath,const QUrl & relativePath)68 void MassStorageDeviceHandler::getURL( QUrl &absolutePath, const QUrl &relativePath )
69 {
70 absolutePath.setPath( m_mountPoint );
71 absolutePath = absolutePath.adjusted(QUrl::StripTrailingSlash);
72 absolutePath.setPath(absolutePath.path() + QLatin1Char('/') + ( relativePath.path() ));
73 absolutePath.setPath( QDir::cleanPath(absolutePath.path()) );
74 }
75
getPlayableURL(QUrl & absolutePath,const QUrl & relativePath)76 void MassStorageDeviceHandler::getPlayableURL( QUrl &absolutePath, const QUrl &relativePath )
77 {
78 getURL( absolutePath, relativePath );
79 }
80
deviceMatchesUdi(const QString & udi) const81 bool MassStorageDeviceHandler::deviceMatchesUdi( const QString &udi ) const
82 {
83 return m_udi == udi;
84 }
85
86 ///////////////////////////////////////////////////////////////////////////////
87 // class MassStorageDeviceHandlerFactory
88 ///////////////////////////////////////////////////////////////////////////////
89
type() const90 QString MassStorageDeviceHandlerFactory::type( ) const
91 {
92 return "uuid";
93 }
94
canCreateFromMedium() const95 bool MassStorageDeviceHandlerFactory::canCreateFromMedium( ) const
96 {
97 return true;
98 }
99
canCreateFromConfig() const100 bool MassStorageDeviceHandlerFactory::canCreateFromConfig( ) const
101 {
102 return false;
103 }
104
canHandle(const Solid::Device & device) const105 bool MassStorageDeviceHandlerFactory::canHandle( const Solid::Device &device ) const
106 {
107 DEBUG_BLOCK
108 const Solid::StorageVolume *volume = device.as<Solid::StorageVolume>();
109 if( !volume )
110 {
111 debug() << "found no volume";
112 return false;
113 }
114 if( volume->uuid().isEmpty() )
115 debug() << "has empty uuid";
116 if( volume->isIgnored() )
117 debug() << "volume is ignored";
118 if( excludedFilesystem( volume->fsType() ) )
119 debug() << "excluded filesystem of type " << volume->fsType();
120 return volume && !volume->uuid().isEmpty()
121 && !volume->isIgnored() && !excludedFilesystem( volume->fsType() );
122 }
123
~MassStorageDeviceHandlerFactory()124 MassStorageDeviceHandlerFactory::~MassStorageDeviceHandlerFactory( )
125 {
126 }
127
createHandler(const KSharedConfigPtr &,QSharedPointer<SqlStorage>) const128 DeviceHandler * MassStorageDeviceHandlerFactory::createHandler( const KSharedConfigPtr&, QSharedPointer<SqlStorage> ) const
129 {
130 return 0;
131 }
132
createHandler(const Solid::Device & device,const QString & udi,QSharedPointer<SqlStorage> s) const133 DeviceHandler * MassStorageDeviceHandlerFactory::createHandler( const Solid::Device &device, const QString &udi, QSharedPointer<SqlStorage> s ) const
134 {
135 DEBUG_BLOCK
136 if( !s )
137 {
138 debug() << "!s, returning 0";
139 return 0;
140 }
141 const Solid::StorageVolume *volume = device.as<Solid::StorageVolume>();
142 const Solid::StorageAccess *volumeAccess = device.as<Solid::StorageAccess>();
143 if( !volume || !volumeAccess )
144 {
145 debug() << "Volume isn't valid, can't create a handler";
146 return 0;
147 }
148 if( volumeAccess->filePath().isEmpty() )
149 {
150 debug() << "not mounted, can't do anything";
151 return 0; // It's not mounted, we can't do anything.
152 }
153 QStringList ids = s->query( QString( "SELECT id, label, lastmountpoint "
154 "FROM devices WHERE type = 'uuid' "
155 "AND uuid = '%1';" ).arg( volume->uuid() ) );
156 if ( ids.size() == 3 )
157 {
158 debug() << "Found existing UUID config for ID " << ids[0] << " , uuid " << volume->uuid();
159 s->query( QString( "UPDATE devices SET lastmountpoint = '%2' WHERE "
160 "id = %1;" )
161 .arg( ids[0],
162 s->escape( volumeAccess->filePath() ) ) );
163 return new MassStorageDeviceHandler( ids[0].toInt(), volumeAccess->filePath(), udi );
164 }
165 else
166 {
167 const int id = s->insert( QString( "INSERT INTO devices( type, uuid, lastmountpoint ) "
168 "VALUES ( 'uuid', '%1', '%2' );" )
169 .arg( volume->uuid(),
170 s->escape( volumeAccess->filePath() ) ),
171 "devices" );
172 if ( id == 0 )
173 {
174 warning() << "Inserting into devices failed for type=uuid, uuid=" << volume->uuid();
175 return 0;
176 }
177 debug() << "Created new UUID device with ID " << id << " , uuid " << volume->uuid();
178 return new MassStorageDeviceHandler( id, volumeAccess->filePath(), udi );
179 }
180 }
181
182 bool
excludedFilesystem(const QString & fstype) const183 MassStorageDeviceHandlerFactory::excludedFilesystem( const QString &fstype ) const
184 {
185 return fstype.isEmpty() ||
186 fstype.indexOf( "smb" ) != -1 ||
187 fstype.indexOf( "cifs" ) != -1 ||
188 fstype.indexOf( "nfs" ) != -1 ||
189 fstype == "udf" ||
190 fstype == "iso9660" ;
191 }
192