• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

  • tdecore
  • tdehw
tdestoragedevice.cpp
1 /* This file is part of the TDE libraries
2  Copyright (C) 2012 Timothy Pearson <kb9vqf@pearsoncomputing.net>
3  (C) 2013 Golubev Alexander <fatzer2@gmail.com>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License version 2 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include "tdestoragedevice.h"
21 
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <sys/stat.h>
25 #include <sys/ioctl.h>
26 #include <linux/cdrom.h>
27 
28 #include <tqregexp.h>
29 #include <tqpixmap.h>
30 #include <tqfile.h>
31 
32 #include "tdelocale.h"
33 #include "tdeglobal.h"
34 #include "kiconloader.h"
35 #include "tdetempfile.h"
36 #include "kstandarddirs.h"
37 
38 #include "tdehardwaredevices.h"
39 
40 #include "config.h"
41 
42 // uDisks2 integration
43 #if defined(WITH_UDISKS) || defined(WITH_UDISKS2)
44  #include <tqdbusdata.h>
45  #include <tqdbusmessage.h>
46  #include <tqdbusproxy.h>
47  #include <tqdbusvariant.h>
48  #include <tqdbusconnection.h>
49  #include <tqdbuserror.h>
50  #include <tqdbusdatamap.h>
51  #include <tqdbusobjectpath.h>
52 #endif // defined(WITH_UDISKS) || defined(WITH_UDISKS2)
53 #if defined(WITH_UDISKS)
54  #include "tqdbusdatalist.h"
55 #endif // ddefined(WITH_UDISKS)
56 
57 #if defined(WITH_UDISKS) || defined(WITH_UDISKS2)
58  // Defined in tdehardwaredevices.cpp
59  TQT_DBusData convertDBUSDataToVariantData(TQT_DBusData);
60 #endif // defined(WITH_UDISKS) || defined(WITH_UDISKS2)
61 
62 TDEStorageDevice::TDEStorageDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn) : TDEGenericDevice(dt, dn), m_mediaInserted(true) {
63  m_diskType = TDEDiskDeviceType::Null;
64  m_diskStatus = TDEDiskDeviceStatus::Null;
65 }
66 
67 TDEStorageDevice::~TDEStorageDevice() {
68 }
69 
70 TDEDiskDeviceType::TDEDiskDeviceType TDEStorageDevice::diskType() {
71  return m_diskType;
72 }
73 
74 void TDEStorageDevice::internalSetDiskType(TDEDiskDeviceType::TDEDiskDeviceType dt) {
75  m_diskType = dt;
76 }
77 
78 bool TDEStorageDevice::isDiskOfType(TDEDiskDeviceType::TDEDiskDeviceType tf) {
79  return ((m_diskType&tf)!=TDEDiskDeviceType::Null);
80 }
81 
82 TDEDiskDeviceStatus::TDEDiskDeviceStatus TDEStorageDevice::diskStatus() {
83  return m_diskStatus;
84 }
85 
86 void TDEStorageDevice::internalSetDiskStatus(TDEDiskDeviceStatus::TDEDiskDeviceStatus st) {
87  m_diskStatus = st;
88 }
89 
90 bool TDEStorageDevice::checkDiskStatus(TDEDiskDeviceStatus::TDEDiskDeviceStatus sf) {
91  return ((m_diskStatus&sf)!=(TDEDiskDeviceStatus::TDEDiskDeviceStatus)0);
92 }
93 
94 bool TDEStorageDevice::lockDriveMedia(bool lock) {
95  int fd = open(deviceNode().ascii(), O_RDWR | O_NONBLOCK);
96  if (fd < 0) {
97  return false;
98  }
99  if (ioctl(fd, CDROM_LOCKDOOR, (lock)?1:0) != 0) {
100  close(fd);
101  return false;
102  }
103  else {
104  close(fd);
105  return true;
106  }
107 }
108 
109 bool ejectDriveUDisks(TDEStorageDevice* sdevice) {
110 #ifdef WITH_UDISKS
111  TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
112  if (dbusConn.isConnected()) {
113  TQString blockDeviceString = sdevice->deviceNode();
114  blockDeviceString.replace("/dev/", "");
115  blockDeviceString.replace("-", "_2d");
116  blockDeviceString = "/org/freedesktop/UDisks/devices/" + blockDeviceString;
117 
118  // Eject the drive!
119  TQT_DBusError error;
120  TQT_DBusProxy driveControl("org.freedesktop.UDisks", blockDeviceString, "org.freedesktop.UDisks.Device", dbusConn);
121  if (driveControl.canSend()) {
122  TQValueList<TQT_DBusData> params;
123  TQT_DBusDataList options;
124  params << TQT_DBusData::fromList(options);
125  TQT_DBusMessage reply = driveControl.sendWithReply("DriveEject", params, &error);
126  if (error.isValid()) {
127  // Error!
128  printf("[ERROR][tdehwlib] ejectDriveUDisks: %s\n", error.name().ascii()); fflush(stdout);
129  return FALSE;
130  }
131  else {
132  return TRUE;
133  }
134  }
135  }
136 #endif // WITH_UDISKS
137  return FALSE;
138 }
139 
140 bool ejectDriveUDisks2(TDEStorageDevice* sdevice) {
141 #ifdef WITH_UDISKS2
142  TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
143  if (dbusConn.isConnected()) {
144  TQString blockDeviceString = sdevice->deviceNode();
145  blockDeviceString.replace("/dev/", "");
146  blockDeviceString.replace("-", "_2d");
147  blockDeviceString = "/org/freedesktop/UDisks2/block_devices/" + blockDeviceString;
148  TQT_DBusProxy hardwareControl("org.freedesktop.UDisks2", blockDeviceString, "org.freedesktop.DBus.Properties", dbusConn);
149  if (hardwareControl.canSend()) {
150  // get associated udisks2 drive path
151  TQT_DBusError error;
152  TQValueList<TQT_DBusData> params;
153  params << TQT_DBusData::fromString("org.freedesktop.UDisks2.Block") << TQT_DBusData::fromString("Drive");
154  TQT_DBusMessage reply = hardwareControl.sendWithReply("Get", params, &error);
155  if (error.isValid()) {
156  // Error!
157  printf("[ERROR][tdehwlib] ejectDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout);
158  return FALSE;
159  }
160  else {
161  if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1) {
162  TQT_DBusObjectPath driveObjectPath = reply[0].toVariant().value.toObjectPath();
163  if (!driveObjectPath.isValid()) {
164  return FALSE;
165  }
166 
167  error = TQT_DBusError();
168  TQT_DBusProxy driveInformation("org.freedesktop.UDisks2", driveObjectPath, "org.freedesktop.DBus.Properties", dbusConn);
169  // can eject?
170  TQValueList<TQT_DBusData> params;
171  params << TQT_DBusData::fromString("org.freedesktop.UDisks2.Drive") << TQT_DBusData::fromString("Ejectable");
172  TQT_DBusMessage reply = driveInformation.sendWithReply("Get", params, &error);
173  if (error.isValid()) {
174  // Error!
175  printf("[ERROR][tdehwlib] ejectDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout);
176  return FALSE;
177  }
178  if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1) {
179  bool ejectable = reply[0].toVariant().value.toBool();
180  if (!ejectable) {
181  return FALSE;
182  }
183 
184  // Eject the drive!
185  TQT_DBusProxy driveControl("org.freedesktop.UDisks2", driveObjectPath, "org.freedesktop.UDisks2.Drive", dbusConn);
186  TQValueList<TQT_DBusData> params;
187  TQT_DBusDataMap<TQString> options(TQT_DBusData::Variant);
188  params << TQT_DBusData::fromStringKeyMap(options);
189  TQT_DBusMessage reply = driveControl.sendWithReply("Eject", params, &error);
190  if (error.isValid()) {
191  // Error!
192  printf("[ERROR][tdehwlib] ejectDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout);
193  return FALSE;
194  }
195  else {
196  return TRUE;
197  }
198  }
199  }
200  }
201  }
202  }
203 #endif // WITH_UDISKS2
204  return FALSE;
205 }
206 
207 int mountDriveUDisks(TQString deviceNode, TQString fileSystemType, TQStringList mountOptions, TQString* errStr = NULL) {
208 #ifdef WITH_UDISKS
209  TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
210  if (dbusConn.isConnected()) {
211  TQString blockDeviceString = deviceNode;
212  blockDeviceString.replace("/dev/", "");
213  blockDeviceString.replace("-", "_2d");
214  blockDeviceString = "/org/freedesktop/UDisks/devices/" + blockDeviceString;
215 
216  // Mount the drive!
217  TQT_DBusError error;
218  TQT_DBusProxy driveControl("org.freedesktop.UDisks", blockDeviceString, "org.freedesktop.UDisks.Device", dbusConn);
219  if (driveControl.canSend()) {
220  TQValueList<TQT_DBusData> params;
221  params << TQT_DBusData::fromString(fileSystemType);
222  params << TQT_DBusData::fromList(TQT_DBusDataList(mountOptions));
223  TQT_DBusMessage reply = driveControl.sendWithReply("FilesystemMount", params, &error);
224  if (error.isValid()) {
225  // Error!
226  if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") {
227  // Service not installed or unavailable
228  return -2;
229  }
230  if (errStr) {
231  *errStr = error.name() + ": " + error.message();
232  }
233  else {
234  printf("[ERROR][tdehwlib] mountDriveUDisks: %s\n", error.name().ascii()); fflush(stdout);
235  }
236  return -1;
237  }
238  else {
239  return 0;
240  }
241  }
242  else {
243  return -2;
244  }
245  }
246 #endif // WITH_UDISKS
247  return -2;
248 }
249 
250 int mountDriveUDisks2(TQString deviceNode, TQString fileSystemType, TQString mountOptions, TQString* errStr = NULL) {
251 #ifdef WITH_UDISKS2
252  TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
253  if (dbusConn.isConnected()) {
254  TQString blockDeviceString = deviceNode;
255  blockDeviceString.replace("/dev/", "");
256  blockDeviceString.replace("-", "_2d");
257  blockDeviceString = "/org/freedesktop/UDisks2/block_devices/" + blockDeviceString;
258 
259  // Mount the drive!
260  TQT_DBusError error;
261  TQT_DBusProxy driveControl("org.freedesktop.UDisks2", blockDeviceString, "org.freedesktop.UDisks2.Filesystem", dbusConn);
262  if (driveControl.canSend()) {
263  TQValueList<TQT_DBusData> params;
264  TQMap<TQString, TQT_DBusData> optionsMap;
265  if (fileSystemType != "") {
266  optionsMap["fstype"] = convertDBUSDataToVariantData(TQT_DBusData::fromString(fileSystemType));
267  }
268  optionsMap["options"] = convertDBUSDataToVariantData(TQT_DBusData::fromString(mountOptions));
269  params << TQT_DBusData::fromStringKeyMap(TQT_DBusDataMap<TQString>(optionsMap));
270  TQT_DBusMessage reply = driveControl.sendWithReply("Mount", params, &error);
271  if (error.isValid()) {
272  // Error!
273  if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") {
274  // Service not installed or unavailable
275  return -2;
276  }
277  if (errStr) {
278  *errStr = error.name() + ": " + error.message();
279  }
280  else {
281  printf("[ERROR][tdehwlib] mountDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout);
282  }
283  return -1;
284  }
285  else {
286  return 0;
287  }
288  }
289  else {
290  return -2;
291  }
292  }
293 #endif // WITH_UDISKS2
294  return -2;
295 }
296 
297 int unMountDriveUDisks(TQString deviceNode, TQStringList unMountOptions, TQString* errStr = NULL) {
298 #ifdef WITH_UDISKS
299  TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
300  if (dbusConn.isConnected()) {
301  TQString blockDeviceString = deviceNode;
302  blockDeviceString.replace("/dev/", "");
303  blockDeviceString.replace("-", "_2d");
304  blockDeviceString = "/org/freedesktop/UDisks/devices/" + blockDeviceString;
305 
306  // Mount the drive!
307  TQT_DBusError error;
308  TQT_DBusProxy driveControl("org.freedesktop.UDisks", blockDeviceString, "org.freedesktop.UDisks.Device", dbusConn);
309  if (driveControl.canSend()) {
310  TQValueList<TQT_DBusData> params;
311  params << TQT_DBusData::fromList(TQT_DBusDataList(unMountOptions));
312  TQT_DBusMessage reply = driveControl.sendWithReply("FilesystemUnmount", params, &error);
313  if (error.isValid()) {
314  // Error!
315  if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") {
316  // Service not installed or unavailable
317  return -2;
318  }
319  if (errStr) {
320  *errStr = error.name() + ": " + error.message();
321  }
322  else {
323  printf("[ERROR][tdehwlib] unMountDriveUDisks: %s\n", error.name().ascii()); fflush(stdout);
324  }
325  return -1;
326  }
327  else {
328  return 0;
329  }
330  }
331  else {
332  return -2;
333  }
334  }
335 #endif // WITH_UDISKS
336  return -2;
337 }
338 
339 int unMountDriveUDisks2(TQString deviceNode, TQString unMountOptions, TQString* errStr = NULL) {
340 #ifdef WITH_UDISKS2
341  TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
342  if (dbusConn.isConnected()) {
343  TQString blockDeviceString = deviceNode;
344  blockDeviceString.replace("/dev/", "");
345  blockDeviceString.replace("-", "_2d");
346  blockDeviceString = "/org/freedesktop/UDisks2/block_devices/" + blockDeviceString;
347 
348  // Mount the drive!
349  TQT_DBusError error;
350  TQT_DBusProxy driveControl("org.freedesktop.UDisks2", blockDeviceString, "org.freedesktop.UDisks2.Filesystem", dbusConn);
351  if (driveControl.canSend()) {
352  TQValueList<TQT_DBusData> params;
353  TQMap<TQString, TQT_DBusData> optionsMap;
354  optionsMap["options"] = convertDBUSDataToVariantData(TQT_DBusData::fromString(unMountOptions));
355  params << TQT_DBusData::fromStringKeyMap(TQT_DBusDataMap<TQString>(optionsMap));
356  TQT_DBusMessage reply = driveControl.sendWithReply("Unmount", params, &error);
357  if (error.isValid()) {
358  // Error!
359  if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") {
360  // Service not installed or unavailable
361  return -2;
362  }
363  if (errStr) {
364  *errStr = error.name() + ": " + error.message();
365  }
366  else {
367  printf("[ERROR][tdehwlib] unMountDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout);
368  }
369  return -1;
370  }
371  else {
372  return 0;
373  }
374  }
375  else {
376  return -2;
377  }
378  }
379 #endif // WITH_UDISKS2
380  return -2;
381 }
382 
383 bool TDEStorageDevice::ejectDrive() {
384 #ifdef WITH_UDISKS2
385  if (!(TDEGlobal::dirs()->findExe("udisksctl").isEmpty())) {
386  if (ejectDriveUDisks2(this)) {
387  return TRUE;
388  }
389  else {
390  printf("[tdehwlib] Failed to eject drive '%s' via udisks2, falling back to alternate mechanism\n", deviceNode().ascii());
391  fflush(stdout);
392  }
393  }
394 #endif // WITH_UDISKS2
395 
396 #ifdef WITH_UDISKS
397  if (!(TDEGlobal::dirs()->findExe("udisks").isEmpty())) {
398  if (ejectDriveUDisks(this)) {
399  return TRUE;
400  }
401  else {
402  printf("[tdehwlib] Failed to eject drive '%s' via udisks, falling back to alternate mechanism\n", deviceNode().ascii());
403  fflush(stdout);
404  }
405  }
406 #endif // WITH_UDISKS
407 
408  if (!(TDEGlobal::dirs()->findExe("eject").isEmpty())) {
409  TQString command = TQString("eject -v '%1' 2>&1").arg(deviceNode());
410 
411  FILE *exepipe = popen(command.ascii(), "r");
412  if (exepipe) {
413  TQString eject_output;
414  TQTextStream ts(exepipe, IO_ReadOnly);
415  eject_output = ts.read();
416  int retcode = pclose(exepipe);
417  if (retcode == 0) {
418  return TRUE;
419  }
420  }
421  printf("[tdehwlib] Failed to eject drive '%s' via 'eject' command\n", deviceNode().ascii());
422  fflush(stdout);
423  }
424 
425  return FALSE;
426 }
427 
428 bool TDEStorageDevice::ejectDriveMedia() {
429  int fd = open(deviceNode().ascii(), O_RDWR | O_NONBLOCK);
430  if (fd < 0) {
431  return false;
432  }
433  if (ioctl(fd, CDROMEJECT) != 0) {
434  close(fd);
435  return false;
436  }
437  else {
438  close(fd);
439  return true;
440  }
441 }
442 
443 TQString TDEStorageDevice::diskLabel() {
444  return m_diskName;
445 }
446 
447 void TDEStorageDevice::internalSetDiskLabel(TQString dn) {
448  m_diskName = dn;
449 }
450 
451 bool TDEStorageDevice::mediaInserted() {
452  return m_mediaInserted;
453 }
454 
455 void TDEStorageDevice::internalSetMediaInserted(bool inserted) {
456  m_mediaInserted = inserted;
457 }
458 
459 TQString TDEStorageDevice::fileSystemName() {
460  return m_fileSystemName;
461 }
462 
463 void TDEStorageDevice::internalSetFileSystemName(TQString fn) {
464  m_fileSystemName = fn;
465 }
466 
467 TQString TDEStorageDevice::fileSystemUsage() {
468  return m_fileSystemUsage;
469 }
470 
471 void TDEStorageDevice::internalSetFileSystemUsage(TQString fu) {
472  m_fileSystemUsage = fu;
473 }
474 
475 TQString TDEStorageDevice::diskUUID() {
476  return m_diskUUID;
477 }
478 
479 void TDEStorageDevice::internalSetDiskUUID(TQString id) {
480  m_diskUUID = id;
481 }
482 
483 TQStringList TDEStorageDevice::holdingDevices() {
484  return m_holdingDevices;
485 }
486 
487 void TDEStorageDevice::internalSetHoldingDevices(TQStringList hd) {
488  m_holdingDevices = hd;
489 }
490 
491 TQStringList TDEStorageDevice::slaveDevices() {
492  return m_slaveDevices;
493 }
494 
495 void TDEStorageDevice::internalSetSlaveDevices(TQStringList sd) {
496  m_slaveDevices = sd;
497 }
498 
499 TQString decodeHexEncoding(TQString str) {
500  TQRegExp hexEncRegExp("\\\\x[0-9A-Fa-f]{1,2}");
501  hexEncRegExp.setMinimal(false);
502  hexEncRegExp.setCaseSensitive(true);
503  int s = -1;
504 
505  while((s = hexEncRegExp.search(str, s+1))>=0){
506  str.replace(s, hexEncRegExp.cap(0).length(), TQChar((char)strtol(hexEncRegExp.cap(0).mid(2).ascii(), NULL, 16)));
507  }
508 
509  return str;
510 }
511 
512 TQString TDEStorageDevice::friendlyName() {
513  // Return the actual storage device name
514  TQString devicevendorid = vendorEncoded();
515  TQString devicemodelid = modelEncoded();
516 
517  devicevendorid = decodeHexEncoding(devicevendorid);
518  devicemodelid = decodeHexEncoding(devicemodelid);
519 
520  devicevendorid = devicevendorid.stripWhiteSpace();
521  devicemodelid = devicemodelid.stripWhiteSpace();
522  devicevendorid = devicevendorid.simplifyWhiteSpace();
523  devicemodelid = devicemodelid.simplifyWhiteSpace();
524 
525  TQString devicename = devicevendorid + " " + devicemodelid;
526 
527  devicename = devicename.stripWhiteSpace();
528  devicename = devicename.simplifyWhiteSpace();
529 
530  if (devicename != "") {
531  return devicename;
532  }
533 
534  if (isDiskOfType(TDEDiskDeviceType::Camera)) {
535  return TDEGenericDevice::friendlyName();
536  }
537 
538  if (isDiskOfType(TDEDiskDeviceType::Floppy)) {
539  return friendlyDeviceType();
540  }
541 
542  TQString label = diskLabel();
543  if (label.isNull()) {
544  if (deviceSize() > 0) {
545  if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) {
546  label = i18n("%1 Removable Device").arg(deviceFriendlySize());
547  }
548  else {
549  label = i18n("%1 Fixed Storage Device").arg(deviceFriendlySize());
550  }
551  }
552  }
553 
554  if (!label.isNull()) {
555  return label;
556  }
557 
558  return friendlyDeviceType();
559 }
560 
561 TQString TDEStorageDevice::detailedFriendlyName() {
562  return TQString("%1 [%2]").arg(friendlyName()).arg(deviceNode());
563 }
564 
565 TQString TDEStorageDevice::friendlyDeviceType() {
566  TQString ret = i18n("Hard Disk Drive");
567 
568  // Keep this in sync with TDEStorageDevice::icon(TDEIcon::StdSizes size) below
569  if (isDiskOfType(TDEDiskDeviceType::Floppy)) {
570  ret = i18n("Floppy Drive");
571  }
572  if (isDiskOfType(TDEDiskDeviceType::Optical)) {
573  ret = i18n("Optical Drive");
574  }
575  if (isDiskOfType(TDEDiskDeviceType::CDROM)) {
576  ret = i18n("CDROM Drive");
577  }
578  if (isDiskOfType(TDEDiskDeviceType::CDRW)) {
579  ret = i18n("CDRW Drive");
580  }
581  if (isDiskOfType(TDEDiskDeviceType::DVDROM)) {
582  ret = i18n("DVD Drive");
583  }
584  if (isDiskOfType(TDEDiskDeviceType::DVDRW)) {
585  ret = i18n("DVDRW Drive");
586  }
587  if (isDiskOfType(TDEDiskDeviceType::DVDRAM)) {
588  ret = i18n("DVDRAM Drive");
589  }
590  if (isDiskOfType(TDEDiskDeviceType::Zip)) {
591  ret = i18n("Zip Drive");
592  }
593  if (isDiskOfType(TDEDiskDeviceType::Tape)) {
594  ret = i18n("Tape Drive");
595  }
596  if (isDiskOfType(TDEDiskDeviceType::Camera)) {
597  ret = i18n("Digital Camera");
598  }
599 
600  if (isDiskOfType(TDEDiskDeviceType::HDD)) {
601  ret = i18n("Hard Disk Drive");
602  if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) {
603  ret = i18n("Removable Storage");
604  }
605  if (isDiskOfType(TDEDiskDeviceType::CompactFlash)) {
606  ret = i18n("Compact Flash");
607  }
608  if (isDiskOfType(TDEDiskDeviceType::MemoryStick)) {
609  ret = i18n("Memory Stick");
610  }
611  if (isDiskOfType(TDEDiskDeviceType::SmartMedia)) {
612  ret = i18n("Smart Media");
613  }
614  if (isDiskOfType(TDEDiskDeviceType::SDMMC)) {
615  ret = i18n("Secure Digital");
616  }
617  }
618 
619  if (isDiskOfType(TDEDiskDeviceType::RAM)) {
620  ret = i18n("Random Access Memory");
621  }
622  if (isDiskOfType(TDEDiskDeviceType::Loop)) {
623  ret = i18n("Loop Device");
624  }
625 
626  return ret;
627 }
628 
629 TQPixmap TDEStorageDevice::icon(TDEIcon::StdSizes size) {
630  TQString mountString;
631  if (mountPath() != TQString::null) {
632  mountString = "-mounted";
633  }
634 
635  TQPixmap ret = DesktopIcon("drive-harddisk" + mountString, size);
636 
637  if (isDiskOfType(TDEDiskDeviceType::Floppy)) {
638  ret = DesktopIcon("media-floppy-3_5" + mountString, size);
639  }
640  if (isDiskOfType(TDEDiskDeviceType::Optical)) {
641  ret = DesktopIcon("media-optical-cdrom" + mountString, size);
642  }
643  if (isDiskOfType(TDEDiskDeviceType::CDROM)) {
644  ret = DesktopIcon("media-optical-cdrom" + mountString, size);
645  }
646  if (isDiskOfType(TDEDiskDeviceType::CDRW)) {
647  ret = DesktopIcon("media-optical-cdwriter" + mountString, size);
648  }
649  if (isDiskOfType(TDEDiskDeviceType::DVDROM)) {
650  ret = DesktopIcon("media-optical-dvd" + mountString, size);
651  }
652  if (isDiskOfType(TDEDiskDeviceType::DVDRW)) {
653  ret = DesktopIcon("media-optical-dvd" + mountString, size);
654  }
655  if (isDiskOfType(TDEDiskDeviceType::DVDRAM)) {
656  ret = DesktopIcon("media-optical-dvd" + mountString, size);
657  }
658  if (isDiskOfType(TDEDiskDeviceType::Zip)) {
659  ret = DesktopIcon("media-floppy-zip" + mountString, size);
660  }
661  if (isDiskOfType(TDEDiskDeviceType::Tape)) {
662  ret = DesktopIcon("media-tape" + mountString, size);
663  }
664  if (isDiskOfType(TDEDiskDeviceType::Camera)) {
665  ret = DesktopIcon("camera" + TQString((mountPath() != TQString::null) ? "_mount" : "_umount"), size);
666  }
667 
668  if (isDiskOfType(TDEDiskDeviceType::HDD)) {
669  ret = DesktopIcon("drive-harddisk" + mountString, size);
670  if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) {
671  ret = DesktopIcon("media-flash-usb" + mountString, size);
672  }
673  if (isDiskOfType(TDEDiskDeviceType::CompactFlash)) {
674  ret = DesktopIcon("media-flash-compact_flash" + mountString, size);
675  }
676  if (isDiskOfType(TDEDiskDeviceType::MemoryStick)) {
677  ret = DesktopIcon("media-flash-memory_stick" + mountString, size);
678  }
679  if (isDiskOfType(TDEDiskDeviceType::SmartMedia)) {
680  ret = DesktopIcon("media-flash-smart_media" + mountString, size);
681  }
682  if (isDiskOfType(TDEDiskDeviceType::SDMMC)) {
683  ret = DesktopIcon("media-flash-sd_mmc" + mountString, size);
684  }
685  }
686 
687  if (isDiskOfType(TDEDiskDeviceType::RAM)) {
688  ret = DesktopIcon("memory" + mountString, size);
689  }
690  if (isDiskOfType(TDEDiskDeviceType::Loop)) {
691  ret = DesktopIcon("blockdevice" + mountString, size);
692  }
693 
694  return ret;
695 }
696 
697 unsigned long long TDEStorageDevice::deviceSize() {
698  TQString bsnodename = systemPath();
699  // While at first glance it would seem that checking /queue/physical_block_size would be needed to get an accurate device size, in reality Linux
700  // appears to only ever report the device size in 512 byte units. This does not appear to be documented anywhere!
701  TQString blocksize = "512";
702 
703  TQString dsnodename = systemPath();
704  dsnodename.append("/size");
705  TQFile dsfile( dsnodename );
706  TQString devicesize;
707  if ( dsfile.open( IO_ReadOnly ) ) {
708  TQTextStream stream( &dsfile );
709  devicesize = stream.readLine();
710  dsfile.close();
711  }
712 
713  return ((unsigned long long)blocksize.toULong()*(unsigned long long)devicesize.toULong());
714 }
715 
716 TQString TDEStorageDevice::deviceFriendlySize() {
717  return TDEHardwareDevices::bytesToFriendlySizeString(deviceSize());
718 }
719 
720 TQString TDEStorageDevice::mountPath() {
721  // See if this device node is mounted
722  // This requires parsing /proc/mounts, looking for deviceNode()
723 
724  // The Device Mapper throws a monkey wrench into this
725  // It likes to advertise mounts as /dev/mapper/<something>,
726  // where <something> is listed in <system path>/dm/name
727 
728  // First, ensure that all device information (mainly holders/slaves) is accurate
729  TDEGlobal::hardwareDevices()->rescanDeviceInformation(this);
730 
731  TQString dmnodename = systemPath();
732  dmnodename.append("/dm/name");
733  TQFile namefile( dmnodename );
734  TQString dmaltname;
735  if ( namefile.open( IO_ReadOnly ) ) {
736  TQTextStream stream( &namefile );
737  dmaltname = stream.readLine();
738  namefile.close();
739  }
740  if (!dmaltname.isNull()) {
741  dmaltname.prepend("/dev/mapper/");
742  }
743 
744  TQStringList lines;
745  TQFile file( "/proc/mounts" );
746  if ( file.open( IO_ReadOnly ) ) {
747  TQTextStream stream( &file );
748  TQString line;
749  while ( !stream.atEnd() ) {
750  line = stream.readLine();
751  TQStringList mountInfo = TQStringList::split(" ", line, true);
752  TQString testNode = *mountInfo.at(0);
753  // Check for match
754  if ((testNode == deviceNode()) || (testNode == dmaltname) || (testNode == ("/dev/disk/by-uuid/" + diskUUID()))) {
755  TQString ret = *mountInfo.at(1);
756  ret.replace("\\040", " ");
757  return ret;
758  }
759  lines += line;
760  }
761  file.close();
762  }
763 
764  // While this device is not directly mounted, it could concievably be mounted via the Device Mapper
765  // If so, try to retrieve the mount path...
766  TQStringList slaveDeviceList = holdingDevices();
767  for ( TQStringList::Iterator slavedevit = slaveDeviceList.begin(); slavedevit != slaveDeviceList.end(); ++slavedevit ) {
768  // Try to locate this device path in the TDE device tree
769  TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices();
770  TDEGenericDevice *hwdevice = hwdevices->findBySystemPath(*slavedevit);
771  if ((hwdevice) && (hwdevice->type() == TDEGenericDeviceType::Disk)) {
772  TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
773  return sdevice->mountPath();
774  }
775  }
776 
777  return TQString::null;
778 }
779 
780 TQString TDEStorageDevice::mountDevice(TQString mediaName, TDEStorageMountOptions mountOptions, TQString* errRet, int* retcode) {
781  int internal_retcode;
782  if (!retcode) {
783  retcode = &internal_retcode;
784  }
785 
786  TQString ret = mountPath();
787 
788  // Device is already mounted
789  if (!ret.isNull()) {
790  return ret;
791  }
792 
793  TQString command;
794  TQString devNode = deviceNode();
795  devNode.replace("'", "'\\''");
796  mediaName.replace("'", "'\\''");
797 
798 #if defined(WITH_UDISKS2) || defined(WITH_UDISKS)
799  // Prepare filesystem options for mount
800  TQStringList udisksOptions;
801  TQString optionString;
802 
803  if (mountOptions["ro"] == "true") {
804  udisksOptions.append("ro");
805  }
806 
807  if (mountOptions["atime"] != "true") {
808  udisksOptions.append("noatime");
809  }
810 
811  if (mountOptions["sync"] == "true") {
812  udisksOptions.append("sync");
813  }
814 
815  if( (mountOptions["filesystem"] == "fat")
816  || (mountOptions["filesystem"] == "vfat")
817  || (mountOptions["filesystem"] == "msdos")
818  || (mountOptions["filesystem"] == "umsdos")
819  ) {
820  if (mountOptions.contains("shortname")) {
821  udisksOptions.append(TQString("shortname=%1").arg(mountOptions["shortname"]));
822  }
823  }
824 
825  if( (mountOptions["filesystem"] == "jfs")) {
826  if (mountOptions["utf8"] == "true") {
827  // udisks/udisks2 for now does not support option iocharset= for jfs
828  // udisksOptions.append("iocharset=utf8");
829  }
830  }
831 
832  if( (mountOptions["filesystem"] == "ntfs-3g") ) {
833  if (mountOptions.contains("locale")) {
834  udisksOptions.append(TQString("locale=%1").arg(mountOptions["locale"]));
835  }
836  }
837 
838  if( (mountOptions["filesystem"] == "ext3")
839  || (mountOptions["filesystem"] == "ext4")
840  ) {
841  if (mountOptions.contains("journaling")) {
842  // udisks/udisks2 for now does not support option data= for ext3/ext4
843  // udisksOptions.append(TQString("data=%1").arg(mountOptions["journaling"]));
844  }
845  }
846 
847  for (TQStringList::Iterator it = udisksOptions.begin(); it != udisksOptions.end(); ++it) {
848  optionString.append(",");
849  optionString.append(*it);
850  }
851 
852  if (!optionString.isEmpty()) {
853  optionString.remove(0, 1);
854  }
855 #endif // defined(WITH_UDISKS2) || defined(WITH_UDISKS)
856 
857 #ifdef WITH_UDISKS2
858  if(command.isEmpty()) {
859  // Try to use UDISKS v2 via DBUS, if available
860  TQString errorString;
861  TQString fileSystemType;
862 
863  if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) {
864  fileSystemType = mountOptions["filesystem"];
865  }
866 
867  int uDisks2Ret = mountDriveUDisks2(devNode, fileSystemType, optionString, &errorString);
868  if (uDisks2Ret == 0) {
869  // Update internal mount data
870  TDEGlobal::hardwareDevices()->processModifiedMounts();
871 
872  ret = mountPath();
873  return ret;
874  }
875  else if (uDisks2Ret == -1) {
876  if (errRet) {
877  *errRet = errorString;
878  }
879 
880  // Update internal mount data
881  TDEGlobal::hardwareDevices()->processModifiedMounts();
882 
883  ret = mountPath();
884  return ret;
885  }
886  else {
887  // The UDISKS v2 DBUS service was either not available or was unusable; try another method...
888  command = TQString::null;
889  }
890  }
891 #endif // WITH_UDISKS2
892 
893 #ifdef WITH_UDISKS
894  if(command.isEmpty()) {
895  // Try to use UDISKS v1 via DBUS, if available
896  TQString errorString;
897  TQString fileSystemType;
898 
899  if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) {
900  fileSystemType = mountOptions["filesystem"];
901  }
902 
903  int uDisksRet = mountDriveUDisks(devNode, fileSystemType, udisksOptions, &errorString);
904  if (uDisksRet == 0) {
905  // Update internal mount data
906  TDEGlobal::hardwareDevices()->processModifiedMounts();
907 
908  ret = mountPath();
909  return ret;
910  }
911  else if (uDisksRet == -1) {
912  if (errRet) {
913  *errRet = errorString;
914  }
915 
916  // Update internal mount data
917  TDEGlobal::hardwareDevices()->processModifiedMounts();
918 
919  ret = mountPath();
920  return ret;
921  }
922  else {
923  // The UDISKS v1 DBUS service was either not available or was unusable; try another method...
924  command = TQString::null;
925  }
926  }
927 #endif // WITH_UDISKS
928 
929  if(command.isEmpty()) {
930  // Use 'pmount' command, if available
931  TQString pmountProg = TDEGlobal::dirs()->findExe("pmount");
932  if (!pmountProg.isEmpty()) {
933  // Create dummy password file
934  KTempFile passwordFile(TQString::null, "tmp", 0600);
935  passwordFile.setAutoDelete(true);
936 
937  TQString optionString;
938  if (mountOptions["ro"] == "true") {
939  optionString.append(" -r");
940  }
941 
942  if (mountOptions["atime"] != "true") {
943  optionString.append(" -A");
944  }
945 
946  if (mountOptions["utf8"] == "true") {
947  optionString.append(" -c utf8");
948  }
949 
950  if (mountOptions["sync"] == "true") {
951  optionString.append(" -s");
952  }
953 
954  if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) {
955  optionString.append(TQString(" -t %1").arg(mountOptions["filesystem"]));
956  }
957 
958  if (mountOptions.contains("locale")) {
959  optionString.append(TQString(" -c %1").arg(mountOptions["locale"]));
960  }
961 
962  TQString mountpoint;
963  if (mountOptions.contains("mountpoint")
964  && !mountOptions["mountpoint"].isEmpty()
965  && (mountOptions["mountpoint"] != "/media/")) {
966  mountpoint = mountOptions["mountpoint"];
967  mountpoint.replace("'", "'\\''");
968  }
969  else {
970  mountpoint = mediaName;
971  }
972 
973  TQString passFileName = passwordFile.name();
974  passFileName.replace("'", "'\\''");
975 
976  command = TQString("pmount -p '%1' %2 '%3' '%4' 2>&1").arg(passFileName).arg(optionString).arg(devNode).arg(mountpoint);
977  }
978  }
979 
980  if(command.isEmpty()) {
981  if (errRet) {
982  *errRet = i18n("No supported mounting methods were detected on your system");
983  }
984  return ret;
985  }
986 
987  FILE *exepipe = popen(command.local8Bit(), "r");
988  if (exepipe) {
989  TQString mount_output;
990  TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly);
991  mount_output = ts->read();
992  delete ts;
993  *retcode = pclose(exepipe);
994  if (errRet) {
995  *errRet = mount_output;
996  }
997  }
998 
999  // Update internal mount data
1000  TDEGlobal::hardwareDevices()->processModifiedMounts();
1001 
1002  ret = mountPath();
1003 
1004  return ret;
1005 }
1006 
1007 TQString TDEStorageDevice::mountEncryptedDevice(TQString passphrase, TQString mediaName, TDEStorageMountOptions mountOptions, TQString* errRet, int* retcode) {
1008  int internal_retcode;
1009  if (!retcode) {
1010  retcode = &internal_retcode;
1011  }
1012 
1013  TQString ret = mountPath();
1014 
1015  if (!ret.isNull()) {
1016  return ret;
1017  }
1018 
1019  // Create dummy password file
1020  KTempFile passwordFile(TQString::null, "tmp", 0600);
1021  passwordFile.setAutoDelete(true);
1022  TQFile* pwFile = passwordFile.file();
1023  if (!pwFile) {
1024  return TQString::null;
1025  }
1026 
1027  pwFile->writeBlock(passphrase.ascii(), passphrase.length());
1028  pwFile->flush();
1029 
1030  TQString optionString;
1031  if (mountOptions["ro"] == "true") {
1032  optionString.append(" -r");
1033  }
1034 
1035  if (mountOptions["atime"] != "true") {
1036  optionString.append(" -A");
1037  }
1038 
1039  if (mountOptions["utf8"] == "true") {
1040  optionString.append(" -c utf8");
1041  }
1042 
1043  if (mountOptions["sync"] == "true") {
1044  optionString.append(" -s");
1045  }
1046 
1047  if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) {
1048  optionString.append(TQString(" -t %1").arg(mountOptions["filesystem"]));
1049  }
1050 
1051  if (mountOptions.contains("locale")) {
1052  optionString.append(TQString(" -c %1").arg(mountOptions["locale"]));
1053  }
1054 
1055  TQString passFileName = passwordFile.name();
1056  TQString devNode = deviceNode();
1057  passFileName.replace("'", "'\\''");
1058  devNode.replace("'", "'\\''");
1059  mediaName.replace("'", "'\\''");
1060  TQString command = TQString("pmount -p '%1' %2 '%3' '%4' 2>&1").arg(passFileName).arg(optionString).arg(devNode).arg(mediaName);
1061 
1062  FILE *exepipe = popen(command.local8Bit(), "r");
1063  if (exepipe) {
1064  TQString mount_output;
1065  TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly);
1066  mount_output = ts->read();
1067  delete ts;
1068  *retcode = pclose(exepipe);
1069  if (errRet) {
1070  *errRet = mount_output;
1071  }
1072  }
1073 
1074  // Update internal mount data
1075  TDEGlobal::hardwareDevices()->processModifiedMounts();
1076 
1077  ret = mountPath();
1078 
1079  return ret;
1080 }
1081 
1082 bool TDEStorageDevice::unmountDevice(TQString* errRet, int* retcode) {
1083  int internal_retcode;
1084  if (!retcode) {
1085  retcode = &internal_retcode;
1086  }
1087 
1088  TQString mountpoint = mountPath();
1089  TQString devNode = deviceNode();
1090 
1091  if (mountpoint.isNull()) {
1092  return true;
1093  }
1094 
1095  mountpoint.replace("'", "'\\''");
1096 
1097  TQString command;
1098 
1099 #ifdef WITH_UDISKS2
1100  if(command.isEmpty()) {
1101  // Try to use UDISKS v2 via DBUS, if available
1102  TQString errorString;
1103  int unMountUDisks2Ret = unMountDriveUDisks2(devNode, TQString::null, &errorString);
1104  if (unMountUDisks2Ret == 0) {
1105  // Update internal mount data
1106  TDEGlobal::hardwareDevices()->processModifiedMounts();
1107 
1108  return true;
1109  }
1110  else if (unMountUDisks2Ret == -1) {
1111  if (errRet) {
1112  *errRet = errorString;
1113  }
1114 
1115  // Update internal mount data
1116  TDEGlobal::hardwareDevices()->processModifiedMounts();
1117 
1118  return false;
1119  }
1120  else {
1121  // The UDISKS v2 DBUS service was either not available or was unusable; try another method...
1122  command = TQString::null;
1123  }
1124  }
1125 #endif // WITH_UDISKS2
1126 #ifdef WITH_UDISKS
1127  if(command.isEmpty()) {
1128  // Try to use UDISKS v1 via DBUS, if available
1129  TQString errorString;
1130  int unMountUDisksRet = unMountDriveUDisks(devNode, TQStringList(), &errorString);
1131  if (unMountUDisksRet == 0) {
1132  // Update internal mount data
1133  TDEGlobal::hardwareDevices()->processModifiedMounts();
1134 
1135  return true;
1136  }
1137  else if (unMountUDisksRet == -1) {
1138  if (errRet) {
1139  *errRet = errorString;
1140  }
1141 
1142  // Update internal mount data
1143  TDEGlobal::hardwareDevices()->processModifiedMounts();
1144 
1145  return false;
1146  }
1147  else {
1148  // The UDISKS v1 DBUS service was either not available or was unusable; try another method...
1149  command = TQString::null;
1150  }
1151  }
1152 #endif // WITH_UDISKS
1153  if(command.isEmpty() &&
1154  !(TDEGlobal::dirs()->findExe("pumount").isEmpty())) {
1155  command = TQString("pumount '%1' 2>&1").arg(mountpoint);
1156  }
1157 
1158  if(command.isEmpty()) {
1159  if (errRet) {
1160  *errRet = i18n("No supported unmounting methods were detected on your system");
1161  }
1162  return true;
1163  }
1164 
1165  FILE *exepipe = popen(command.local8Bit(), "r");
1166  if (exepipe) {
1167  TQString umount_output;
1168  TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly);
1169  umount_output = ts->read();
1170  delete ts;
1171  *retcode = pclose(exepipe);
1172  if (*retcode == 0) {
1173  // Update internal mount data
1174  TDEGlobal::hardwareDevices()->processModifiedMounts();
1175 
1176  return true;
1177  }
1178  else {
1179  if (errRet) {
1180  *errRet = umount_output;
1181  }
1182  }
1183  }
1184 
1185  // Update internal mount data
1186  TDEGlobal::hardwareDevices()->processModifiedMounts();
1187 
1188  return false;
1189 }
1190 
1191 TQString TDEStorageDevice::determineFileSystemType(TQString path) {
1192  TQStringList mountTable;
1193  TQString prevPath = path;
1194  dev_t prevDev = 0;
1195  int pos;
1196  struct stat directory_info;
1197  if (path.startsWith("/")) {
1198  stat(path.local8Bit(), &directory_info);
1199  prevDev = directory_info.st_dev;
1200  // Walk the directory tree up to the root, checking for any change in st_dev
1201  // If a change is found, the previous value of path is the mount point itself
1202  while (path != "/") {
1203  pos = path.findRev("/", -1, TRUE);
1204  if (pos < 0) {
1205  break;
1206  }
1207  path = path.mid(0, pos);
1208  if (path == "") {
1209  path = "/";
1210  }
1211  stat(path.local8Bit(), &directory_info);
1212  if (directory_info.st_dev != prevDev) {
1213  break;
1214  }
1215  prevPath = path;
1216  prevDev = directory_info.st_dev;
1217  }
1218  }
1219 
1220  // Read in mount table
1221  mountTable.clear();
1222  TQFile file( "/proc/mounts" );
1223  if ( file.open( IO_ReadOnly ) ) {
1224  TQTextStream stream( &file );
1225  while ( !stream.atEnd() ) {
1226  mountTable.append(stream.readLine());
1227  }
1228  file.close();
1229  }
1230 
1231  // Parse mount table
1232  TQStringList::Iterator it;
1233  for ( it = mountTable.begin(); it != mountTable.end(); ++it ) {
1234  TQStringList mountInfo = TQStringList::split(" ", (*it), true);
1235  if ((*mountInfo.at(1)) == prevPath) {
1236  return (*mountInfo.at(2));
1237  }
1238  }
1239 
1240  // Unknown file system type
1241  return TQString::null;
1242 }
1243 
1244 #include "tdestoragedevice.moc"

tdecore

Skip menu "tdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.8.1.2
This website is maintained by Timothy Pearson.