• 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 "kdebug.h"
33 #include "tdelocale.h"
34 #include "tdeglobal.h"
35 #include "kiconloader.h"
36 #include "tdetempfile.h"
37 #include "kstandarddirs.h"
38 
39 #include "tdehardwaredevices.h"
40 
41 #include "config.h"
42 
43 #if defined(WITH_CRYPTSETUP)
44  #ifdef CRYPTSETUP_OLD_API
45  #define class cryptsetup_class
46  #define CRYPT_SLOT_INVALID INVALID
47  #define CRYPT_SLOT_INACTIVE INACTIVE
48  #define CRYPT_SLOT_ACTIVE ACTIVE
49  #define CRYPT_SLOT_BUSY BUSY
50  #define CRYPT_SLOT_ACTIVE_LAST ACTIVE
51  #include <libcryptsetup.h>
52  #undef class
53  #else
54  #include <libcryptsetup.h>
55  #endif
56 #endif
57 
58 // uDisks2 integration
59 #if defined(WITH_UDISKS) || defined(WITH_UDISKS2)
60  #include <tqdbusdata.h>
61  #include <tqdbusmessage.h>
62  #include <tqdbusproxy.h>
63  #include <tqdbusvariant.h>
64  #include <tqdbusconnection.h>
65  #include <tqdbuserror.h>
66  #include <tqdbusdatamap.h>
67  #include <tqdbusobjectpath.h>
68 #endif // defined(WITH_UDISKS) || defined(WITH_UDISKS2)
69 #if defined(WITH_UDISKS)
70  #include "tqdbusdatalist.h"
71 #endif // ddefined(WITH_UDISKS)
72 
73 #if defined(WITH_UDISKS) || defined(WITH_UDISKS2)
74  // Defined in tdehardwaredevices.cpp
75  TQT_DBusData convertDBUSDataToVariantData(TQT_DBusData);
76 #endif // defined(WITH_UDISKS) || defined(WITH_UDISKS2)
77 
78 TDEStorageDevice::TDEStorageDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn) : TDEGenericDevice(dt, dn), m_mediaInserted(true), m_cryptDevice(NULL) {
79  m_diskType = TDEDiskDeviceType::Null;
80  m_diskStatus = TDEDiskDeviceStatus::Null;
81 }
82 
83 TDEStorageDevice::~TDEStorageDevice() {
84 #if defined(WITH_CRYPTSETUP)
85  if (m_cryptDevice) {
86  crypt_free(m_cryptDevice);
87  m_cryptDevice = NULL;
88  }
89 #endif
90 }
91 
92 TDEDiskDeviceType::TDEDiskDeviceType TDEStorageDevice::diskType() {
93  return m_diskType;
94 }
95 
96 void TDEStorageDevice::internalGetLUKSKeySlotStatus() {
97 #if defined(WITH_CRYPTSETUP)
98  unsigned int i;
99  crypt_keyslot_info keyslot_status;
100  TDELUKSKeySlotStatus::TDELUKSKeySlotStatus tde_keyslot_status;
101 
102  m_cryptKeyslotStatus.clear();
103  for (i = 0; i < m_cryptKeySlotCount; i++) {
104  keyslot_status = crypt_keyslot_status(m_cryptDevice, i);
105  tde_keyslot_status = TDELUKSKeySlotStatus::Invalid;
106  if (keyslot_status == CRYPT_SLOT_INACTIVE) {
107  tde_keyslot_status = TDELUKSKeySlotStatus::Inactive;
108  }
109  else if (keyslot_status == CRYPT_SLOT_ACTIVE) {
110  tde_keyslot_status = TDELUKSKeySlotStatus::Active;
111  }
112  else if (keyslot_status == CRYPT_SLOT_ACTIVE_LAST) {
113  tde_keyslot_status = TDELUKSKeySlotStatus::Active | TDELUKSKeySlotStatus::Last;
114  }
115  m_cryptKeyslotStatus.append(tde_keyslot_status);
116  }
117 #endif
118 }
119 
120 void TDEStorageDevice::internalInitializeLUKSIfNeeded() {
121 #if defined(WITH_CRYPTSETUP)
122  int ret;
123 
124  if (m_diskType & TDEDiskDeviceType::LUKS) {
125  if (!m_cryptDevice) {
126  TQString node = deviceNode();
127  if (node != "") {
128  ret = crypt_init(&m_cryptDevice, node.ascii());
129  if (ret == 0) {
130  ret = crypt_load(m_cryptDevice, NULL, NULL);
131  if (ret == 0) {
132  int keyslot_count;
133 #if defined(CRYPTSETUP_OLD_API) || !defined(HAVE_CRYPTSETUP_GET_TYPE)
134  kdWarning() << "TDEStorageDevice: The version of libcryptsetup that TDE was compiled against was too old! Most LUKS features will not function" << endl;
135  m_cryptDeviceType = TQString::null;
136  keyslot_count = 0;
137 #else
138  m_cryptDeviceType = crypt_get_type(m_cryptDevice);
139  keyslot_count = crypt_keyslot_max(m_cryptDeviceType.ascii());
140 #endif
141  if (keyslot_count < 0) {
142  m_cryptKeySlotCount = 0;
143  }
144  else {
145  m_cryptKeySlotCount = keyslot_count;
146  }
147  internalGetLUKSKeySlotStatus();
148  }
149  }
150  else {
151  m_cryptDevice = NULL;
152  }
153  }
154  }
155  }
156  else {
157  if (m_cryptDevice) {
158  crypt_free(m_cryptDevice);
159  m_cryptDevice = NULL;
160  }
161  }
162 #endif
163 }
164 
165 void TDEStorageDevice::cryptSetOperationsUnlockPassword(TQByteArray password) {
166 #if defined(WITH_CRYPTSETUP)
167  crypt_memory_lock(NULL, 1);
168  m_cryptDevicePassword = password;
169 #endif
170 }
171 
172 void TDEStorageDevice::cryptClearOperationsUnlockPassword() {
173  m_cryptDevicePassword.fill(0);
174  m_cryptDevicePassword.resize(0);
175 #if defined(WITH_CRYPTSETUP)
176  crypt_memory_lock(NULL, 0);
177 #endif
178 }
179 
180 bool TDEStorageDevice::cryptOperationsUnlockPasswordSet() {
181  if (m_cryptDevicePassword.size() > 0) {
182  return true;
183  }
184  else {
185  return false;
186  }
187 }
188 
189 TDELUKSResult::TDELUKSResult TDEStorageDevice::cryptCheckKey(unsigned int keyslot) {
190 #if defined(WITH_CRYPTSETUP)
191  int ret;
192 
193  if (m_cryptDevice) {
194  if (keyslot < m_cryptKeySlotCount) {
195  ret = crypt_activate_by_passphrase(m_cryptDevice, NULL, keyslot, m_cryptDevicePassword.data(), m_cryptDevicePassword.size(), 0);
196  if (ret < 0) {
197  return TDELUKSResult::KeyslotOpFailed;
198  }
199  else {
200  return TDELUKSResult::Success;
201  }
202  }
203  else {
204  return TDELUKSResult::InvalidKeyslot;
205  }
206  }
207  else {
208  return TDELUKSResult::LUKSNotFound;
209  }
210 #else
211  return TDELUKSResult::LUKSNotSupported;
212 #endif
213 }
214 
215 TDELUKSResult::TDELUKSResult TDEStorageDevice::cryptAddKey(unsigned int keyslot, TQByteArray password) {
216 #if defined(WITH_CRYPTSETUP)
217  int ret;
218 
219  if (m_cryptDevice) {
220  if (keyslot < m_cryptKeySlotCount) {
221  ret = crypt_keyslot_add_by_passphrase(m_cryptDevice, keyslot, m_cryptDevicePassword.data(), m_cryptDevicePassword.size(), password.data(), password.size());
222  if (ret < 0) {
223  return TDELUKSResult::KeyslotOpFailed;
224  }
225  else {
226  internalGetLUKSKeySlotStatus();
227  return TDELUKSResult::Success;
228  }
229  }
230  else {
231  return TDELUKSResult::InvalidKeyslot;
232  }
233  }
234  else {
235  return TDELUKSResult::LUKSNotFound;
236  }
237 #else
238  return TDELUKSResult::LUKSNotSupported;
239 #endif
240 }
241 
242 TDELUKSResult::TDELUKSResult TDEStorageDevice::cryptDelKey(unsigned int keyslot) {
243 #if defined(WITH_CRYPTSETUP)
244  int ret;
245 
246  if (m_cryptDevice) {
247  if (keyslot < m_cryptKeySlotCount) {
248  ret = crypt_keyslot_destroy(m_cryptDevice, keyslot);
249  if (ret < 0) {
250  return TDELUKSResult::KeyslotOpFailed;
251  }
252  else {
253  internalGetLUKSKeySlotStatus();
254  return TDELUKSResult::Success;
255  }
256  }
257  else {
258  return TDELUKSResult::InvalidKeyslot;
259  }
260  }
261  else {
262  return TDELUKSResult::LUKSNotFound;
263  }
264 #else
265  return TDELUKSResult::LUKSNotSupported;
266 #endif
267 }
268 
269 unsigned int TDEStorageDevice::cryptKeySlotCount() {
270  return m_cryptKeySlotCount;
271 }
272 
273 TDELUKSKeySlotStatusList TDEStorageDevice::cryptKeySlotStatus() {
274  return m_cryptKeyslotStatus;
275 }
276 
277 TQString TDEStorageDevice::cryptKeySlotFriendlyName(TDELUKSKeySlotStatus::TDELUKSKeySlotStatus status) {
278  if (status & TDELUKSKeySlotStatus::Inactive) {
279  return i18n("Inactive");
280  }
281  else if (status & TDELUKSKeySlotStatus::Active) {
282  return i18n("Active");
283  }
284  else {
285  return i18n("Unknown");
286  }
287 }
288 
289 void TDEStorageDevice::internalSetDeviceNode(TQString sn) {
290  TDEGenericDevice::internalSetDeviceNode(sn);
291  internalInitializeLUKSIfNeeded();
292 }
293 
294 void TDEStorageDevice::internalSetDiskType(TDEDiskDeviceType::TDEDiskDeviceType dt) {
295  m_diskType = dt;
296  internalInitializeLUKSIfNeeded();
297 }
298 
299 bool TDEStorageDevice::isDiskOfType(TDEDiskDeviceType::TDEDiskDeviceType tf) {
300  return ((m_diskType&tf)!=TDEDiskDeviceType::Null);
301 }
302 
303 TDEDiskDeviceStatus::TDEDiskDeviceStatus TDEStorageDevice::diskStatus() {
304  return m_diskStatus;
305 }
306 
307 void TDEStorageDevice::internalSetDiskStatus(TDEDiskDeviceStatus::TDEDiskDeviceStatus st) {
308  m_diskStatus = st;
309 }
310 
311 bool TDEStorageDevice::checkDiskStatus(TDEDiskDeviceStatus::TDEDiskDeviceStatus sf) {
312  return ((m_diskStatus&sf)!=(TDEDiskDeviceStatus::TDEDiskDeviceStatus)0);
313 }
314 
315 bool TDEStorageDevice::lockDriveMedia(bool lock) {
316  int fd = open(deviceNode().ascii(), O_RDWR | O_NONBLOCK);
317  if (fd < 0) {
318  return false;
319  }
320  if (ioctl(fd, CDROM_LOCKDOOR, (lock)?1:0) != 0) {
321  close(fd);
322  return false;
323  }
324  else {
325  close(fd);
326  return true;
327  }
328 }
329 
330 bool ejectDriveUDisks(TDEStorageDevice* sdevice) {
331 #ifdef WITH_UDISKS
332  TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
333  if (dbusConn.isConnected()) {
334  TQString blockDeviceString = sdevice->deviceNode();
335  blockDeviceString.replace("/dev/", "");
336  blockDeviceString = "/org/freedesktop/UDisks/devices/" + blockDeviceString;
337 
338  // Eject the drive!
339  TQT_DBusError error;
340  TQT_DBusProxy driveControl("org.freedesktop.UDisks", blockDeviceString, "org.freedesktop.UDisks.Device", dbusConn);
341  if (driveControl.canSend()) {
342  TQValueList<TQT_DBusData> params;
343  TQT_DBusDataList options;
344  params << TQT_DBusData::fromList(options);
345  TQT_DBusMessage reply = driveControl.sendWithReply("DriveEject", params, &error);
346  if (error.isValid()) {
347  // Error!
348  printf("[ERROR][tdehwlib] ejectDriveUDisks: %s\n", error.name().ascii()); fflush(stdout);
349  return FALSE;
350  }
351  else {
352  return TRUE;
353  }
354  }
355  }
356 #endif // WITH_UDISKS
357  return FALSE;
358 }
359 
360 bool ejectDriveUDisks2(TDEStorageDevice* sdevice) {
361 #ifdef WITH_UDISKS2
362  TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
363  if (dbusConn.isConnected()) {
364  TQString blockDeviceString = sdevice->deviceNode();
365  blockDeviceString.replace("/dev/", "");
366  blockDeviceString = "/org/freedesktop/UDisks2/block_devices/" + blockDeviceString;
367  TQT_DBusProxy hardwareControl("org.freedesktop.UDisks2", blockDeviceString, "org.freedesktop.DBus.Properties", dbusConn);
368  if (hardwareControl.canSend()) {
369  // get associated udisks2 drive path
370  TQT_DBusError error;
371  TQValueList<TQT_DBusData> params;
372  params << TQT_DBusData::fromString("org.freedesktop.UDisks2.Block") << TQT_DBusData::fromString("Drive");
373  TQT_DBusMessage reply = hardwareControl.sendWithReply("Get", params, &error);
374  if (error.isValid()) {
375  // Error!
376  printf("[ERROR][tdehwlib] ejectDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout);
377  return FALSE;
378  }
379  else {
380  if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1) {
381  TQT_DBusObjectPath driveObjectPath = reply[0].toVariant().value.toObjectPath();
382  if (!driveObjectPath.isValid()) {
383  return FALSE;
384  }
385 
386  error = TQT_DBusError();
387  TQT_DBusProxy driveInformation("org.freedesktop.UDisks2", driveObjectPath, "org.freedesktop.DBus.Properties", dbusConn);
388  // can eject?
389  TQValueList<TQT_DBusData> params;
390  params << TQT_DBusData::fromString("org.freedesktop.UDisks2.Drive") << TQT_DBusData::fromString("Ejectable");
391  TQT_DBusMessage reply = driveInformation.sendWithReply("Get", params, &error);
392  if (error.isValid()) {
393  // Error!
394  printf("[ERROR][tdehwlib] ejectDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout);
395  return FALSE;
396  }
397  if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1) {
398  bool ejectable = reply[0].toVariant().value.toBool();
399  if (!ejectable) {
400  return FALSE;
401  }
402 
403  // Eject the drive!
404  TQT_DBusProxy driveControl("org.freedesktop.UDisks2", driveObjectPath, "org.freedesktop.UDisks2.Drive", dbusConn);
405  TQValueList<TQT_DBusData> params;
406  TQT_DBusDataMap<TQString> options(TQT_DBusData::Variant);
407  params << TQT_DBusData::fromStringKeyMap(options);
408  TQT_DBusMessage reply = driveControl.sendWithReply("Eject", params, &error);
409  if (error.isValid()) {
410  // Error!
411  printf("[ERROR][tdehwlib] ejectDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout);
412  return FALSE;
413  }
414  else {
415  return TRUE;
416  }
417  }
418  }
419  }
420  }
421  }
422 #endif // WITH_UDISKS2
423  return FALSE;
424 }
425 
426 int mountDriveUDisks(TQString deviceNode, TQString fileSystemType, TQStringList mountOptions, TQString* errStr = NULL) {
427 #ifdef WITH_UDISKS
428  TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
429  if (dbusConn.isConnected()) {
430  TQString blockDeviceString = deviceNode;
431  blockDeviceString.replace("/dev/", "");
432  blockDeviceString = "/org/freedesktop/UDisks/devices/" + blockDeviceString;
433 
434  // Mount the drive!
435  TQT_DBusError error;
436  TQT_DBusProxy driveControl("org.freedesktop.UDisks", blockDeviceString, "org.freedesktop.UDisks.Device", dbusConn);
437  if (driveControl.canSend()) {
438  TQValueList<TQT_DBusData> params;
439  params << TQT_DBusData::fromString(fileSystemType);
440  params << TQT_DBusData::fromList(TQT_DBusDataList(mountOptions));
441  TQT_DBusMessage reply = driveControl.sendWithReply("FilesystemMount", params, &error);
442  if (error.isValid()) {
443  // Error!
444  if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") {
445  // Service not installed or unavailable
446  return -2;
447  }
448  if (errStr) {
449  *errStr = error.name() + ": " + error.message();
450  }
451  else {
452  printf("[ERROR][tdehwlib] mountDriveUDisks: %s\n", error.name().ascii()); fflush(stdout);
453  }
454  return -1;
455  }
456  else {
457  return 0;
458  }
459  }
460  else {
461  return -2;
462  }
463  }
464 #endif // WITH_UDISKS
465  return -2;
466 }
467 
468 int mountDriveUDisks2(TQString deviceNode, TQString fileSystemType, TQString mountOptions, TQString* errStr = NULL) {
469 #ifdef WITH_UDISKS2
470  TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
471  if (dbusConn.isConnected()) {
472  TQString blockDeviceString = deviceNode;
473  blockDeviceString.replace("/dev/", "");
474  blockDeviceString = "/org/freedesktop/UDisks2/block_devices/" + blockDeviceString;
475 
476  // Mount the drive!
477  TQT_DBusError error;
478  TQT_DBusProxy driveControl("org.freedesktop.UDisks2", blockDeviceString, "org.freedesktop.UDisks2.Filesystem", dbusConn);
479  if (driveControl.canSend()) {
480  TQValueList<TQT_DBusData> params;
481  TQMap<TQString, TQT_DBusData> optionsMap;
482  if (fileSystemType != "") {
483  optionsMap["fstype"] = convertDBUSDataToVariantData(TQT_DBusData::fromString(fileSystemType));
484  }
485  optionsMap["options"] = convertDBUSDataToVariantData(TQT_DBusData::fromString(mountOptions));
486  params << TQT_DBusData::fromStringKeyMap(TQT_DBusDataMap<TQString>(optionsMap));
487  TQT_DBusMessage reply = driveControl.sendWithReply("Mount", params, &error);
488  if (error.isValid()) {
489  // Error!
490  if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") {
491  // Service not installed or unavailable
492  return -2;
493  }
494  if (errStr) {
495  *errStr = error.name() + ": " + error.message();
496  }
497  else {
498  printf("[ERROR][tdehwlib] mountDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout);
499  }
500  return -1;
501  }
502  else {
503  return 0;
504  }
505  }
506  else {
507  return -2;
508  }
509  }
510 #endif // WITH_UDISKS2
511  return -2;
512 }
513 
514 int unMountDriveUDisks(TQString deviceNode, TQStringList unMountOptions, TQString* errStr = NULL) {
515 #ifdef WITH_UDISKS
516  TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
517  if (dbusConn.isConnected()) {
518  TQString blockDeviceString = deviceNode;
519  blockDeviceString.replace("/dev/", "");
520  blockDeviceString = "/org/freedesktop/UDisks/devices/" + blockDeviceString;
521 
522  // Mount the drive!
523  TQT_DBusError error;
524  TQT_DBusProxy driveControl("org.freedesktop.UDisks", blockDeviceString, "org.freedesktop.UDisks.Device", dbusConn);
525  if (driveControl.canSend()) {
526  TQValueList<TQT_DBusData> params;
527  params << TQT_DBusData::fromList(TQT_DBusDataList(unMountOptions));
528  TQT_DBusMessage reply = driveControl.sendWithReply("FilesystemUnmount", params, &error);
529  if (error.isValid()) {
530  // Error!
531  if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") {
532  // Service not installed or unavailable
533  return -2;
534  }
535  if (errStr) {
536  *errStr = error.name() + ": " + error.message();
537  }
538  else {
539  printf("[ERROR][tdehwlib] unMountDriveUDisks: %s\n", error.name().ascii()); fflush(stdout);
540  }
541  return -1;
542  }
543  else {
544  return 0;
545  }
546  }
547  else {
548  return -2;
549  }
550  }
551 #endif // WITH_UDISKS
552  return -2;
553 }
554 
555 int unMountDriveUDisks2(TQString deviceNode, TQString unMountOptions, TQString* errStr = NULL) {
556 #ifdef WITH_UDISKS2
557  TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
558  if (dbusConn.isConnected()) {
559  TQString blockDeviceString = deviceNode;
560  blockDeviceString.replace("/dev/", "");
561  blockDeviceString = "/org/freedesktop/UDisks2/block_devices/" + blockDeviceString;
562 
563  // Mount the drive!
564  TQT_DBusError error;
565  TQT_DBusProxy driveControl("org.freedesktop.UDisks2", blockDeviceString, "org.freedesktop.UDisks2.Filesystem", dbusConn);
566  if (driveControl.canSend()) {
567  TQValueList<TQT_DBusData> params;
568  TQMap<TQString, TQT_DBusData> optionsMap;
569  optionsMap["options"] = convertDBUSDataToVariantData(TQT_DBusData::fromString(unMountOptions));
570  params << TQT_DBusData::fromStringKeyMap(TQT_DBusDataMap<TQString>(optionsMap));
571  TQT_DBusMessage reply = driveControl.sendWithReply("Unmount", params, &error);
572  if (error.isValid()) {
573  // Error!
574  if (error.name() == "org.freedesktop.DBus.Error.ServiceUnknown") {
575  // Service not installed or unavailable
576  return -2;
577  }
578  if (errStr) {
579  *errStr = error.name() + ": " + error.message();
580  }
581  else {
582  printf("[ERROR][tdehwlib] unMountDriveUDisks2: %s\n", error.name().ascii()); fflush(stdout);
583  }
584  return -1;
585  }
586  else {
587  return 0;
588  }
589  }
590  else {
591  return -2;
592  }
593  }
594 #endif // WITH_UDISKS2
595  return -2;
596 }
597 
598 bool TDEStorageDevice::ejectDrive() {
599 #ifdef WITH_UDISKS2
600  if (!(TDEGlobal::dirs()->findExe("udisksctl").isEmpty())) {
601  if (ejectDriveUDisks2(this)) {
602  return TRUE;
603  }
604  else {
605  printf("[tdehwlib] Failed to eject drive '%s' via udisks2, falling back to alternate mechanism\n", deviceNode().ascii());
606  fflush(stdout);
607  }
608  }
609 #endif // WITH_UDISKS2
610 
611 #ifdef WITH_UDISKS
612  if (!(TDEGlobal::dirs()->findExe("udisks").isEmpty())) {
613  if (ejectDriveUDisks(this)) {
614  return TRUE;
615  }
616  else {
617  printf("[tdehwlib] Failed to eject drive '%s' via udisks, falling back to alternate mechanism\n", deviceNode().ascii());
618  fflush(stdout);
619  }
620  }
621 #endif // WITH_UDISKS
622 
623  if (!(TDEGlobal::dirs()->findExe("eject").isEmpty())) {
624  TQString command = TQString("eject -v '%1' 2>&1").arg(deviceNode());
625 
626  FILE *exepipe = popen(command.ascii(), "r");
627  if (exepipe) {
628  TQString eject_output;
629  TQTextStream ts(exepipe, IO_ReadOnly);
630  eject_output = ts.read();
631  int retcode = pclose(exepipe);
632  if (retcode == 0) {
633  return TRUE;
634  }
635  }
636  printf("[tdehwlib] Failed to eject drive '%s' via 'eject' command\n", deviceNode().ascii());
637  fflush(stdout);
638  }
639 
640  return FALSE;
641 }
642 
643 bool TDEStorageDevice::ejectDriveMedia() {
644  int fd = open(deviceNode().ascii(), O_RDWR | O_NONBLOCK);
645  if (fd < 0) {
646  return false;
647  }
648  if (ioctl(fd, CDROMEJECT) != 0) {
649  close(fd);
650  return false;
651  }
652  else {
653  close(fd);
654  return true;
655  }
656 }
657 
658 TQString TDEStorageDevice::diskLabel() {
659  return m_diskName;
660 }
661 
662 void TDEStorageDevice::internalSetDiskLabel(TQString dn) {
663  m_diskName = dn;
664 }
665 
666 bool TDEStorageDevice::mediaInserted() {
667  return m_mediaInserted;
668 }
669 
670 void TDEStorageDevice::internalSetMediaInserted(bool inserted) {
671  m_mediaInserted = inserted;
672 }
673 
674 TQString TDEStorageDevice::fileSystemName() {
675  return m_fileSystemName;
676 }
677 
678 void TDEStorageDevice::internalSetFileSystemName(TQString fn) {
679  m_fileSystemName = fn;
680 }
681 
682 TQString TDEStorageDevice::fileSystemUsage() {
683  return m_fileSystemUsage;
684 }
685 
686 void TDEStorageDevice::internalSetFileSystemUsage(TQString fu) {
687  m_fileSystemUsage = fu;
688 }
689 
690 TQString TDEStorageDevice::diskUUID() {
691  return m_diskUUID;
692 }
693 
694 void TDEStorageDevice::internalSetDiskUUID(TQString id) {
695  m_diskUUID = id;
696 }
697 
698 TQStringList TDEStorageDevice::holdingDevices() {
699  return m_holdingDevices;
700 }
701 
702 void TDEStorageDevice::internalSetHoldingDevices(TQStringList hd) {
703  m_holdingDevices = hd;
704 }
705 
706 TQStringList TDEStorageDevice::slaveDevices() {
707  return m_slaveDevices;
708 }
709 
710 void TDEStorageDevice::internalSetSlaveDevices(TQStringList sd) {
711  m_slaveDevices = sd;
712 }
713 
714 TQString decodeHexEncoding(TQString str) {
715  TQRegExp hexEncRegExp("\\\\x[0-9A-Fa-f]{1,2}");
716  hexEncRegExp.setMinimal(false);
717  hexEncRegExp.setCaseSensitive(true);
718  int s = -1;
719 
720  while((s = hexEncRegExp.search(str, s+1))>=0){
721  str.replace(s, hexEncRegExp.cap(0).length(), TQChar((char)strtol(hexEncRegExp.cap(0).mid(2).ascii(), NULL, 16)));
722  }
723 
724  return str;
725 }
726 
727 TQString TDEStorageDevice::friendlyName() {
728  // Return the actual storage device name
729  TQString devicevendorid = vendorEncoded();
730  TQString devicemodelid = modelEncoded();
731 
732  devicevendorid = decodeHexEncoding(devicevendorid);
733  devicemodelid = decodeHexEncoding(devicemodelid);
734 
735  devicevendorid = devicevendorid.stripWhiteSpace();
736  devicemodelid = devicemodelid.stripWhiteSpace();
737  devicevendorid = devicevendorid.simplifyWhiteSpace();
738  devicemodelid = devicemodelid.simplifyWhiteSpace();
739 
740  TQString devicename = devicevendorid + " " + devicemodelid;
741 
742  devicename = devicename.stripWhiteSpace();
743  devicename = devicename.simplifyWhiteSpace();
744 
745  if (devicename != "") {
746  return devicename;
747  }
748 
749  if (isDiskOfType(TDEDiskDeviceType::Camera)) {
750  return TDEGenericDevice::friendlyName();
751  }
752 
753  if (isDiskOfType(TDEDiskDeviceType::Floppy)) {
754  return friendlyDeviceType();
755  }
756 
757  TQString label = diskLabel();
758  if (label.isNull()) {
759  if (deviceSize() > 0) {
760  if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) {
761  label = i18n("%1 Removable Device").arg(deviceFriendlySize());
762  }
763  else {
764  label = i18n("%1 Fixed Storage Device").arg(deviceFriendlySize());
765  }
766  }
767  }
768 
769  if (!label.isNull()) {
770  return label;
771  }
772 
773  return friendlyDeviceType();
774 }
775 
776 TQString TDEStorageDevice::detailedFriendlyName() {
777  return TQString("%1 [%2]").arg(friendlyName()).arg(deviceNode());
778 }
779 
780 TQString TDEStorageDevice::friendlyDeviceType() {
781  TQString ret = i18n("Hard Disk Drive");
782 
783  // Keep this in sync with TDEStorageDevice::icon(TDEIcon::StdSizes size) below
784  if (isDiskOfType(TDEDiskDeviceType::Floppy)) {
785  ret = i18n("Floppy Drive");
786  }
787  if (isDiskOfType(TDEDiskDeviceType::Optical)) {
788  ret = i18n("Optical Drive");
789  }
790  if (isDiskOfType(TDEDiskDeviceType::CDROM)) {
791  ret = i18n("CDROM Drive");
792  }
793  if (isDiskOfType(TDEDiskDeviceType::CDRW)) {
794  ret = i18n("CDRW Drive");
795  }
796  if (isDiskOfType(TDEDiskDeviceType::DVDROM)) {
797  ret = i18n("DVD Drive");
798  }
799  if (isDiskOfType(TDEDiskDeviceType::DVDRW)) {
800  ret = i18n("DVDRW Drive");
801  }
802  if (isDiskOfType(TDEDiskDeviceType::DVDRAM)) {
803  ret = i18n("DVDRAM Drive");
804  }
805  if (isDiskOfType(TDEDiskDeviceType::Zip)) {
806  ret = i18n("Zip Drive");
807  }
808  if (isDiskOfType(TDEDiskDeviceType::Tape)) {
809  ret = i18n("Tape Drive");
810  }
811  if (isDiskOfType(TDEDiskDeviceType::Camera)) {
812  ret = i18n("Digital Camera");
813  }
814 
815  if (isDiskOfType(TDEDiskDeviceType::HDD)) {
816  ret = i18n("Hard Disk Drive");
817  if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) {
818  ret = i18n("Removable Storage");
819  }
820  if (isDiskOfType(TDEDiskDeviceType::CompactFlash)) {
821  ret = i18n("Compact Flash");
822  }
823  if (isDiskOfType(TDEDiskDeviceType::MemoryStick)) {
824  ret = i18n("Memory Stick");
825  }
826  if (isDiskOfType(TDEDiskDeviceType::SmartMedia)) {
827  ret = i18n("Smart Media");
828  }
829  if (isDiskOfType(TDEDiskDeviceType::SDMMC)) {
830  ret = i18n("Secure Digital");
831  }
832  }
833 
834  if (isDiskOfType(TDEDiskDeviceType::RAM)) {
835  ret = i18n("Random Access Memory");
836  }
837  if (isDiskOfType(TDEDiskDeviceType::Loop)) {
838  ret = i18n("Loop Device");
839  }
840 
841  return ret;
842 }
843 
844 TQPixmap TDEStorageDevice::icon(TDEIcon::StdSizes size) {
845  TQString mountString;
846  if (mountPath() != TQString::null) {
847  mountString = "-mounted";
848  }
849 
850  TQPixmap ret = DesktopIcon("drive-harddisk" + mountString, size);
851 
852  if (isDiskOfType(TDEDiskDeviceType::Floppy)) {
853  ret = DesktopIcon("media-floppy-3_5" + mountString, size);
854  }
855  if (isDiskOfType(TDEDiskDeviceType::Optical)) {
856  ret = DesktopIcon("media-optical-cdrom" + mountString, size);
857  }
858  if (isDiskOfType(TDEDiskDeviceType::CDROM)) {
859  ret = DesktopIcon("media-optical-cdrom" + mountString, size);
860  }
861  if (isDiskOfType(TDEDiskDeviceType::CDRW)) {
862  ret = DesktopIcon("media-optical-cdwriter" + mountString, size);
863  }
864  if (isDiskOfType(TDEDiskDeviceType::DVDROM)) {
865  ret = DesktopIcon("media-optical-dvd" + mountString, size);
866  }
867  if (isDiskOfType(TDEDiskDeviceType::DVDRW)) {
868  ret = DesktopIcon("media-optical-dvd" + mountString, size);
869  }
870  if (isDiskOfType(TDEDiskDeviceType::DVDRAM)) {
871  ret = DesktopIcon("media-optical-dvd" + mountString, size);
872  }
873  if (isDiskOfType(TDEDiskDeviceType::Zip)) {
874  ret = DesktopIcon("media-floppy-zip" + mountString, size);
875  }
876  if (isDiskOfType(TDEDiskDeviceType::Tape)) {
877  ret = DesktopIcon("media-tape" + mountString, size);
878  }
879  if (isDiskOfType(TDEDiskDeviceType::Camera)) {
880  ret = DesktopIcon("camera" + TQString((mountPath() != TQString::null) ? "_mount" : "_umount"), size);
881  }
882 
883  if (isDiskOfType(TDEDiskDeviceType::HDD)) {
884  ret = DesktopIcon("drive-harddisk" + mountString, size);
885  if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) {
886  ret = DesktopIcon("media-flash-usb" + mountString, size);
887  }
888  if (isDiskOfType(TDEDiskDeviceType::CompactFlash)) {
889  ret = DesktopIcon("media-flash-compact_flash" + mountString, size);
890  }
891  if (isDiskOfType(TDEDiskDeviceType::MemoryStick)) {
892  ret = DesktopIcon("media-flash-memory_stick" + mountString, size);
893  }
894  if (isDiskOfType(TDEDiskDeviceType::SmartMedia)) {
895  ret = DesktopIcon("media-flash-smart_media" + mountString, size);
896  }
897  if (isDiskOfType(TDEDiskDeviceType::SDMMC)) {
898  ret = DesktopIcon("media-flash-sd_mmc" + mountString, size);
899  }
900  }
901 
902  if (isDiskOfType(TDEDiskDeviceType::RAM)) {
903  ret = DesktopIcon("memory" + mountString, size);
904  }
905  if (isDiskOfType(TDEDiskDeviceType::Loop)) {
906  ret = DesktopIcon("blockdevice" + mountString, size);
907  }
908 
909  return ret;
910 }
911 
912 unsigned long long TDEStorageDevice::deviceSize() {
913  TQString bsnodename = systemPath();
914  // 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
915  // appears to only ever report the device size in 512 byte units. This does not appear to be documented anywhere!
916  TQString blocksize = "512";
917 
918  TQString dsnodename = systemPath();
919  dsnodename.append("/size");
920  TQFile dsfile( dsnodename );
921  TQString devicesize;
922  if ( dsfile.open( IO_ReadOnly ) ) {
923  TQTextStream stream( &dsfile );
924  devicesize = stream.readLine();
925  dsfile.close();
926  }
927 
928  return ((unsigned long long)blocksize.toULong()*(unsigned long long)devicesize.toULong());
929 }
930 
931 TQString TDEStorageDevice::deviceFriendlySize() {
932  return TDEHardwareDevices::bytesToFriendlySizeString(deviceSize());
933 }
934 
935 TQString TDEStorageDevice::mountPath() {
936  // See if this device node is mounted
937  // This requires parsing /proc/mounts, looking for deviceNode()
938 
939  // The Device Mapper throws a monkey wrench into this
940  // It likes to advertise mounts as /dev/mapper/<something>,
941  // where <something> is listed in <system path>/dm/name
942 
943  // First, ensure that all device information (mainly holders/slaves) is accurate
944  TDEGlobal::hardwareDevices()->rescanDeviceInformation(this);
945 
946  TQString dmnodename = systemPath();
947  dmnodename.append("/dm/name");
948  TQFile namefile( dmnodename );
949  TQString dmaltname;
950  if ( namefile.open( IO_ReadOnly ) ) {
951  TQTextStream stream( &namefile );
952  dmaltname = stream.readLine();
953  namefile.close();
954  }
955  if (!dmaltname.isNull()) {
956  dmaltname.prepend("/dev/mapper/");
957  }
958 
959  TQStringList lines;
960  TQFile file( "/proc/mounts" );
961  if ( file.open( IO_ReadOnly ) ) {
962  TQTextStream stream( &file );
963  TQString line;
964  while ( !stream.atEnd() ) {
965  line = stream.readLine();
966  TQStringList mountInfo = TQStringList::split(" ", line, true);
967  TQString testNode = *mountInfo.at(0);
968  // Check for match
969  if ((testNode == deviceNode()) || (testNode == dmaltname) || (testNode == ("/dev/disk/by-uuid/" + diskUUID()))) {
970  TQString ret = *mountInfo.at(1);
971  ret.replace("\\040", " ");
972  return ret;
973  }
974  lines += line;
975  }
976  file.close();
977  }
978 
979  // While this device is not directly mounted, it could concievably be mounted via the Device Mapper
980  // If so, try to retrieve the mount path...
981  TQStringList slaveDeviceList = holdingDevices();
982  for ( TQStringList::Iterator slavedevit = slaveDeviceList.begin(); slavedevit != slaveDeviceList.end(); ++slavedevit ) {
983  // Try to locate this device path in the TDE device tree
984  TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices();
985  TDEGenericDevice *hwdevice = hwdevices->findBySystemPath(*slavedevit);
986  if ((hwdevice) && (hwdevice->type() == TDEGenericDeviceType::Disk)) {
987  TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
988  return sdevice->mountPath();
989  }
990  }
991 
992  return TQString::null;
993 }
994 
995 TQString TDEStorageDevice::mountDevice(TQString mediaName, TDEStorageMountOptions mountOptions, TQString* errRet, int* retcode) {
996  int internal_retcode;
997  if (!retcode) {
998  retcode = &internal_retcode;
999  }
1000 
1001  TQString ret = mountPath();
1002 
1003  // Device is already mounted
1004  if (!ret.isNull()) {
1005  return ret;
1006  }
1007 
1008  TQString command;
1009  TQString devNode = deviceNode();
1010  devNode.replace("'", "'\\''");
1011  mediaName.replace("'", "'\\''");
1012 
1013 #if defined(WITH_UDEVIL) || defined(WITH_UDISKS2) || defined(WITH_UDISKS)
1014  // Prepare filesystem options for mount
1015  TQStringList udisksOptions;
1016  TQString optionString;
1017 
1018  if (mountOptions["ro"] == "true") {
1019  udisksOptions.append("ro");
1020  }
1021 
1022  if (mountOptions["atime"] != "true") {
1023  udisksOptions.append("noatime");
1024  }
1025 
1026  if (mountOptions["sync"] == "true") {
1027  udisksOptions.append("sync");
1028  }
1029 
1030  if( (mountOptions["filesystem"] == "fat")
1031  || (mountOptions["filesystem"] == "vfat")
1032  || (mountOptions["filesystem"] == "msdos")
1033  || (mountOptions["filesystem"] == "umsdos")
1034  ) {
1035  if (mountOptions.contains("shortname")) {
1036  udisksOptions.append(TQString("shortname=%1").arg(mountOptions["shortname"]));
1037  }
1038  }
1039 
1040  if( (mountOptions["filesystem"] == "jfs")) {
1041  if (mountOptions["utf8"] == "true") {
1042  // udisks/udisks2 for now does not support option iocharset= for jfs
1043  // udisksOptions.append("iocharset=utf8");
1044  }
1045  }
1046 
1047  if( (mountOptions["filesystem"] == "ntfs-3g") ) {
1048  if (mountOptions.contains("locale")) {
1049  udisksOptions.append(TQString("locale=%1").arg(mountOptions["locale"]));
1050  }
1051  }
1052 
1053  if( (mountOptions["filesystem"] == "ext3")
1054  || (mountOptions["filesystem"] == "ext4")
1055  ) {
1056  if (mountOptions.contains("journaling")) {
1057  // udisks/udisks2 for now does not support option data= for ext3/ext4
1058  // udisksOptions.append(TQString("data=%1").arg(mountOptions["journaling"]));
1059  }
1060  }
1061 
1062  for (TQStringList::Iterator it = udisksOptions.begin(); it != udisksOptions.end(); ++it) {
1063  optionString.append(",");
1064  optionString.append(*it);
1065  }
1066 
1067  if (!optionString.isEmpty()) {
1068  optionString.remove(0, 1);
1069  }
1070 #endif // defined(WITH_UDEVIL) || defined(WITH_UDISKS2) || defined(WITH_UDISKS)
1071 
1072 #ifdef WITH_UDEVIL
1073  if(command.isEmpty()) {
1074  // Use 'udevil' command, if available
1075  TQString udevilProg = TDEGlobal::dirs()->findExe("udevil");
1076  if (!udevilProg.isEmpty()) {
1077 
1078  TQString fileSystemType;
1079  if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) {
1080  fileSystemType = TQString("-t %1").arg(mountOptions["filesystem"]);
1081  }
1082 
1083  TQString mountpoint;
1084  if (mountOptions.contains("mountpoint")
1085  && !mountOptions["mountpoint"].isEmpty()
1086  && (mountOptions["mountpoint"] != "/media/")) {
1087  mountpoint = mountOptions["mountpoint"];
1088  mountpoint.replace("'", "'\\''");
1089  }
1090  else {
1091  mountpoint = TQString("/media/%1").arg(mediaName);
1092  }
1093 
1094  command = TQString("udevil mount %1 -o '%2' '%3' '%4' 2>&1").arg(fileSystemType).arg(optionString).arg(devNode).arg(mountpoint);
1095  }
1096  }
1097 #endif // WITH_UDEVIL
1098 
1099 #ifdef WITH_UDISKS2
1100  if(command.isEmpty()) {
1101  // Try to use UDISKS v2 via DBUS, if available
1102  TQString errorString;
1103  TQString fileSystemType;
1104 
1105  if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) {
1106  fileSystemType = mountOptions["filesystem"];
1107  }
1108 
1109  int uDisks2Ret = mountDriveUDisks2(devNode, fileSystemType, optionString, &errorString);
1110  if (uDisks2Ret == 0) {
1111  // Update internal mount data
1112  TDEGlobal::hardwareDevices()->processModifiedMounts();
1113 
1114  ret = mountPath();
1115  return ret;
1116  }
1117  else if (uDisks2Ret == -1) {
1118  if (errRet) {
1119  *errRet = errorString;
1120  }
1121 
1122  // Update internal mount data
1123  TDEGlobal::hardwareDevices()->processModifiedMounts();
1124 
1125  ret = mountPath();
1126  return ret;
1127  }
1128  else {
1129  // The UDISKS v2 DBUS service was either not available or was unusable; try another method...
1130  command = TQString::null;
1131  }
1132  }
1133 #endif // WITH_UDISKS2
1134 
1135 #ifdef WITH_UDISKS
1136  if(command.isEmpty()) {
1137  // Try to use UDISKS v1 via DBUS, if available
1138  TQString errorString;
1139  TQString fileSystemType;
1140 
1141  if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) {
1142  fileSystemType = mountOptions["filesystem"];
1143  }
1144 
1145  int uDisksRet = mountDriveUDisks(devNode, fileSystemType, udisksOptions, &errorString);
1146  if (uDisksRet == 0) {
1147  // Update internal mount data
1148  TDEGlobal::hardwareDevices()->processModifiedMounts();
1149 
1150  ret = mountPath();
1151  return ret;
1152  }
1153  else if (uDisksRet == -1) {
1154  if (errRet) {
1155  *errRet = errorString;
1156  }
1157 
1158  // Update internal mount data
1159  TDEGlobal::hardwareDevices()->processModifiedMounts();
1160 
1161  ret = mountPath();
1162  return ret;
1163  }
1164  else {
1165  // The UDISKS v1 DBUS service was either not available or was unusable; try another method...
1166  command = TQString::null;
1167  }
1168  }
1169 #endif // WITH_UDISKS
1170 
1171  if(command.isEmpty()) {
1172  // Use 'pmount' command, if available
1173  TQString pmountProg = TDEGlobal::dirs()->findExe("pmount");
1174  if (!pmountProg.isEmpty()) {
1175  // Create dummy password file
1176  KTempFile passwordFile(TQString::null, "tmp", 0600);
1177  passwordFile.setAutoDelete(true);
1178 
1179  TQString optionString;
1180  if (mountOptions["ro"] == "true") {
1181  optionString.append(" -r");
1182  }
1183 
1184  if (mountOptions["atime"] != "true") {
1185  optionString.append(" -A");
1186  }
1187 
1188  if (mountOptions["utf8"] == "true") {
1189  optionString.append(" -c utf8");
1190  }
1191 
1192  if (mountOptions["sync"] == "true") {
1193  optionString.append(" -s");
1194  }
1195 
1196  if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) {
1197  optionString.append(TQString(" -t %1").arg(mountOptions["filesystem"]));
1198  }
1199 
1200  if (mountOptions.contains("locale")) {
1201  optionString.append(TQString(" -c %1").arg(mountOptions["locale"]));
1202  }
1203 
1204  TQString mountpoint;
1205  if (mountOptions.contains("mountpoint")
1206  && !mountOptions["mountpoint"].isEmpty()
1207  && (mountOptions["mountpoint"] != "/media/")) {
1208  mountpoint = mountOptions["mountpoint"];
1209  mountpoint.replace("'", "'\\''");
1210  }
1211  else {
1212  mountpoint = mediaName;
1213  }
1214 
1215  TQString passFileName = passwordFile.name();
1216  passFileName.replace("'", "'\\''");
1217 
1218  command = TQString("pmount -p '%1' %2 '%3' '%4' 2>&1").arg(passFileName).arg(optionString).arg(devNode).arg(mountpoint);
1219  }
1220  }
1221 
1222  if(command.isEmpty()) {
1223  if (errRet) {
1224  *errRet = i18n("No supported mounting methods were detected on your system");
1225  }
1226  return ret;
1227  }
1228 
1229  FILE *exepipe = popen(command.local8Bit(), "r");
1230  if (exepipe) {
1231  TQString mount_output;
1232  TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly);
1233  mount_output = ts->read();
1234  delete ts;
1235  *retcode = pclose(exepipe);
1236  if (errRet) {
1237  *errRet = mount_output;
1238  }
1239  }
1240 
1241  // Update internal mount data
1242  TDEGlobal::hardwareDevices()->processModifiedMounts();
1243 
1244  ret = mountPath();
1245 
1246  return ret;
1247 }
1248 
1249 TQString TDEStorageDevice::mountEncryptedDevice(TQString passphrase, TQString mediaName, TDEStorageMountOptions mountOptions, TQString* errRet, int* retcode) {
1250  int internal_retcode;
1251  if (!retcode) {
1252  retcode = &internal_retcode;
1253  }
1254 
1255  TQString ret = mountPath();
1256 
1257  if (!ret.isNull()) {
1258  return ret;
1259  }
1260 
1261  // Create dummy password file
1262  KTempFile passwordFile(TQString::null, "tmp", 0600);
1263  passwordFile.setAutoDelete(true);
1264  TQFile* pwFile = passwordFile.file();
1265  if (!pwFile) {
1266  return TQString::null;
1267  }
1268 
1269  pwFile->writeBlock(passphrase.ascii(), passphrase.length());
1270  pwFile->flush();
1271 
1272  TQString optionString;
1273  if (mountOptions["ro"] == "true") {
1274  optionString.append(" -r");
1275  }
1276 
1277  if (mountOptions["atime"] != "true") {
1278  optionString.append(" -A");
1279  }
1280 
1281  if (mountOptions["utf8"] == "true") {
1282  optionString.append(" -c utf8");
1283  }
1284 
1285  if (mountOptions["sync"] == "true") {
1286  optionString.append(" -s");
1287  }
1288 
1289  if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) {
1290  optionString.append(TQString(" -t %1").arg(mountOptions["filesystem"]));
1291  }
1292 
1293  if (mountOptions.contains("locale")) {
1294  optionString.append(TQString(" -c %1").arg(mountOptions["locale"]));
1295  }
1296 
1297  TQString passFileName = passwordFile.name();
1298  TQString devNode = deviceNode();
1299  passFileName.replace("'", "'\\''");
1300  devNode.replace("'", "'\\''");
1301  mediaName.replace("'", "'\\''");
1302  TQString command = TQString("pmount -p '%1' %2 '%3' '%4' 2>&1").arg(passFileName).arg(optionString).arg(devNode).arg(mediaName);
1303 
1304  FILE *exepipe = popen(command.local8Bit(), "r");
1305  if (exepipe) {
1306  TQString mount_output;
1307  TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly);
1308  mount_output = ts->read();
1309  delete ts;
1310  *retcode = pclose(exepipe);
1311  if (errRet) {
1312  *errRet = mount_output;
1313  }
1314  }
1315 
1316  // Update internal mount data
1317  TDEGlobal::hardwareDevices()->processModifiedMounts();
1318 
1319  ret = mountPath();
1320 
1321  return ret;
1322 }
1323 
1324 bool TDEStorageDevice::unmountDevice(TQString* errRet, int* retcode) {
1325  int internal_retcode;
1326  if (!retcode) {
1327  retcode = &internal_retcode;
1328  }
1329 
1330  TQString mountpoint = mountPath();
1331  TQString devNode = deviceNode();
1332 
1333  if (mountpoint.isNull()) {
1334  return true;
1335  }
1336 
1337  mountpoint.replace("'", "'\\''");
1338 
1339  TQString command;
1340 
1341 #ifdef WITH_UDEVIL
1342  if(command.isEmpty() &&
1343  !(TDEGlobal::dirs()->findExe("udevil").isEmpty())) {
1344  command = TQString("udevil umount '%1' 2>&1").arg(mountpoint);
1345  }
1346 #endif // WITH_UDEVIL
1347 
1348 #ifdef WITH_UDISKS2
1349  if(command.isEmpty()) {
1350  // Try to use UDISKS v2 via DBUS, if available
1351  TQString errorString;
1352  int unMountUDisks2Ret = unMountDriveUDisks2(devNode, TQString::null, &errorString);
1353  if (unMountUDisks2Ret == 0) {
1354  // Update internal mount data
1355  TDEGlobal::hardwareDevices()->processModifiedMounts();
1356 
1357  return true;
1358  }
1359  else if (unMountUDisks2Ret == -1) {
1360  if (errRet) {
1361  *errRet = errorString;
1362  }
1363 
1364  // Update internal mount data
1365  TDEGlobal::hardwareDevices()->processModifiedMounts();
1366 
1367  return false;
1368  }
1369  else {
1370  // The UDISKS v2 DBUS service was either not available or was unusable; try another method...
1371  command = TQString::null;
1372  }
1373  }
1374 #endif // WITH_UDISKS2
1375 
1376 #ifdef WITH_UDISKS
1377  if(command.isEmpty()) {
1378  // Try to use UDISKS v1 via DBUS, if available
1379  TQString errorString;
1380  int unMountUDisksRet = unMountDriveUDisks(devNode, TQStringList(), &errorString);
1381  if (unMountUDisksRet == 0) {
1382  // Update internal mount data
1383  TDEGlobal::hardwareDevices()->processModifiedMounts();
1384 
1385  return true;
1386  }
1387  else if (unMountUDisksRet == -1) {
1388  if (errRet) {
1389  *errRet = errorString;
1390  }
1391 
1392  // Update internal mount data
1393  TDEGlobal::hardwareDevices()->processModifiedMounts();
1394 
1395  return false;
1396  }
1397  else {
1398  // The UDISKS v1 DBUS service was either not available or was unusable; try another method...
1399  command = TQString::null;
1400  }
1401  }
1402 #endif // WITH_UDISKS
1403 
1404  if(command.isEmpty() &&
1405  !(TDEGlobal::dirs()->findExe("pumount").isEmpty())) {
1406  command = TQString("pumount '%1' 2>&1").arg(mountpoint);
1407  }
1408 
1409  if(command.isEmpty()) {
1410  if (errRet) {
1411  *errRet = i18n("No supported unmounting methods were detected on your system");
1412  }
1413  return true;
1414  }
1415 
1416  FILE *exepipe = popen(command.local8Bit(), "r");
1417  if (exepipe) {
1418  TQString umount_output;
1419  TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly);
1420  umount_output = ts->read();
1421  delete ts;
1422  *retcode = pclose(exepipe);
1423  if (*retcode == 0) {
1424  // Update internal mount data
1425  TDEGlobal::hardwareDevices()->processModifiedMounts();
1426 
1427  return true;
1428  }
1429  else {
1430  if (errRet) {
1431  *errRet = umount_output;
1432  }
1433  }
1434  }
1435 
1436  // Update internal mount data
1437  TDEGlobal::hardwareDevices()->processModifiedMounts();
1438 
1439  return false;
1440 }
1441 
1442 TQString TDEStorageDevice::determineFileSystemType(TQString path) {
1443  TQStringList mountTable;
1444  TQString prevPath = path;
1445  dev_t prevDev = 0;
1446  int pos;
1447  struct stat directory_info;
1448  if (path.startsWith("/")) {
1449  stat(path.local8Bit(), &directory_info);
1450  prevDev = directory_info.st_dev;
1451  // Walk the directory tree up to the root, checking for any change in st_dev
1452  // If a change is found, the previous value of path is the mount point itself
1453  while (path != "/") {
1454  pos = path.findRev("/", -1, TRUE);
1455  if (pos < 0) {
1456  break;
1457  }
1458  path = path.mid(0, pos);
1459  if (path == "") {
1460  path = "/";
1461  }
1462  stat(path.local8Bit(), &directory_info);
1463  if (directory_info.st_dev != prevDev) {
1464  break;
1465  }
1466  prevPath = path;
1467  prevDev = directory_info.st_dev;
1468  }
1469  }
1470 
1471  // Read in mount table
1472  mountTable.clear();
1473  TQFile file( "/proc/mounts" );
1474  if ( file.open( IO_ReadOnly ) ) {
1475  TQTextStream stream( &file );
1476  while ( !stream.atEnd() ) {
1477  mountTable.append(stream.readLine());
1478  }
1479  file.close();
1480  }
1481 
1482  // Parse mount table
1483  TQStringList::Iterator it;
1484  for ( it = mountTable.begin(); it != mountTable.end(); ++it ) {
1485  TQStringList mountInfo = TQStringList::split(" ", (*it), true);
1486  if ((*mountInfo.at(1)) == prevPath) {
1487  return (*mountInfo.at(2));
1488  }
1489  }
1490 
1491  // Unknown file system type
1492  return TQString::null;
1493 }
1494 
1495 #include "tdestoragedevice.moc"
TDEIconLoader::DesktopIcon
TQPixmap DesktopIcon(const TQString &name, int size=0, int state=TDEIcon::DefaultState, TDEInstance *instance=TDEGlobal::instance())
Definition: kiconloader.cpp:1297
TDELocale::i18n
TQString i18n(const char *text)
Definition: tdelocale.cpp:1977
TDEGlobal::hardwareDevices
static TDEHardwareDevices * hardwareDevices()
Returns a TDEHardwareDevices object.
TDEGlobal::dirs
static TDEStandardDirs * dirs()
Returns the application standard dirs object.
Definition: tdeglobal.cpp:58
tdelocale.h
TDEIcon::StdSizes
StdSizes
These are the standard sizes for icons.
Definition: kicontheme.h:112
TDEGlobal::kdWarning
kdbgstream kdWarning(int area=0)
Definition: kdebug.cpp:370
TDEStandardDirs::findExe
static TQString findExe(const TQString &appname, const TQString &pathstr=TQString::null, bool ignoreExecBit=false)
Finds the executable in the system path.
Definition: kstandarddirs.cpp:932
KStdAction::open
TDEAction * open(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)
KTempFile
The KTempFile class creates and opens a unique file for temporary use.
Definition: tdetempfile.h:55
KStdAction::close
TDEAction * close(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)
TDEStdAccel::label
TQString label(StdAccel id)
Returns a localized label for user-visible display.
Definition: tdestdaccel.cpp:156
TDEGlobal::endl
kdbgstream & endl(kdbgstream &s)
Definition: kdebug.h:430

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.8
This website is maintained by Timothy Pearson.