• 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 #include "tdehardwaredevices.h"
39 #include "disksHelper.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_INACTIVE SLOT_INACTIVE
47  #define CRYPT_SLOT_ACTIVE SLOT_ACTIVE
48  #define CRYPT_SLOT_ACTIVE_LAST SLOT_ACTIVE_LAST
49  #include <libcryptsetup.h>
50  #undef class
51  #else
52  #include <libcryptsetup.h>
53  #endif
54 #endif
55 
56 TDEStorageDevice::TDEStorageDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn) : TDEGenericDevice(dt, dn), m_mediaInserted(true), m_cryptDevice(NULL) {
57  m_diskType = TDEDiskDeviceType::Null;
58  m_diskStatus = TDEDiskDeviceStatus::Null;
59 }
60 
61 TDEStorageDevice::~TDEStorageDevice() {
62 #if defined(WITH_CRYPTSETUP)
63  if (m_cryptDevice) {
64  crypt_free(m_cryptDevice);
65  m_cryptDevice = NULL;
66  }
67 #endif
68 }
69 
70 TQString TDEStorageDevice::mappedName() {
71  return m_mappedName;
72 }
73 
74 void TDEStorageDevice::internalUpdateMappedName() {
75  // Get the device mapped name if present
76  m_mappedName = TQString::null;
77  TQString dmnodename = systemPath();
78  dmnodename.append("/dm/name");
79  TQFile dmnamefile(dmnodename);
80  if (dmnamefile.open(IO_ReadOnly)) {
81  TQTextStream stream(&dmnamefile);
82  m_mappedName = stream.readLine();
83  dmnamefile.close();
84  }
85  if (!m_mappedName.isEmpty()) {
86  m_mappedName.prepend("/dev/mapper/");
87  }
88 }
89 
90 TDEDiskDeviceType::TDEDiskDeviceType TDEStorageDevice::diskType() {
91  return m_diskType;
92 }
93 
94 void TDEStorageDevice::internalGetLUKSKeySlotStatus() {
95 #if defined(WITH_CRYPTSETUP)
96  unsigned int i;
97  crypt_keyslot_info keyslot_status;
98  TDELUKSKeySlotStatus::TDELUKSKeySlotStatus tde_keyslot_status;
99 
100  m_cryptKeyslotStatus.clear();
101  for (i = 0; i < m_cryptKeySlotCount; i++) {
102  keyslot_status = crypt_keyslot_status(m_cryptDevice, i);
103  tde_keyslot_status = TDELUKSKeySlotStatus::Invalid;
104  if (keyslot_status == CRYPT_SLOT_INACTIVE) {
105  tde_keyslot_status = TDELUKSKeySlotStatus::Inactive;
106  }
107  else if (keyslot_status == CRYPT_SLOT_ACTIVE) {
108  tde_keyslot_status = TDELUKSKeySlotStatus::Active;
109  }
110  else if (keyslot_status == CRYPT_SLOT_ACTIVE_LAST) {
111  tde_keyslot_status = TDELUKSKeySlotStatus::Active | TDELUKSKeySlotStatus::Last;
112  }
113  m_cryptKeyslotStatus.append(tde_keyslot_status);
114  }
115 #endif
116 }
117 
118 void TDEStorageDevice::internalInitializeLUKSIfNeeded() {
119 #if defined(WITH_CRYPTSETUP)
120  int ret;
121 
122  if (m_diskType & TDEDiskDeviceType::LUKS) {
123  if (!m_cryptDevice) {
124  TQString node = deviceNode();
125  if (node != "") {
126  ret = crypt_init(&m_cryptDevice, node.ascii());
127  if (ret == 0) {
128  ret = crypt_load(m_cryptDevice, NULL, NULL);
129  if (ret == 0) {
130  int keyslot_count;
131 #if defined(CRYPTSETUP_OLD_API) || !defined(HAVE_CRYPTSETUP_GET_TYPE)
132  kdWarning() << "TDEStorageDevice: The version of libcryptsetup that TDE was compiled against was too old! Most LUKS features will not function" << endl;
133  m_cryptDeviceType = TQString::null;
134  keyslot_count = 0;
135 #else
136  m_cryptDeviceType = crypt_get_type(m_cryptDevice);
137  keyslot_count = crypt_keyslot_max(m_cryptDeviceType.ascii());
138 #endif
139  if (keyslot_count < 0) {
140  m_cryptKeySlotCount = 0;
141  }
142  else {
143  m_cryptKeySlotCount = keyslot_count;
144  }
145  internalGetLUKSKeySlotStatus();
146  }
147  }
148  else {
149  m_cryptDevice = NULL;
150  }
151  }
152  }
153  }
154  else {
155  if (m_cryptDevice) {
156  crypt_free(m_cryptDevice);
157  m_cryptDevice = NULL;
158  }
159  }
160 #endif
161 }
162 
163 void TDEStorageDevice::cryptSetOperationsUnlockPassword(TQByteArray password) {
164 #if defined(WITH_CRYPTSETUP)
165  crypt_memory_lock(NULL, 1);
166  m_cryptDevicePassword = password;
167 #endif
168 }
169 
170 void TDEStorageDevice::cryptClearOperationsUnlockPassword() {
171  m_cryptDevicePassword.fill(0);
172  m_cryptDevicePassword.resize(0);
173 #if defined(WITH_CRYPTSETUP)
174  crypt_memory_lock(NULL, 0);
175 #endif
176 }
177 
178 bool TDEStorageDevice::cryptOperationsUnlockPasswordSet() {
179  if (m_cryptDevicePassword.size() > 0) {
180  return true;
181  }
182  else {
183  return false;
184  }
185 }
186 
187 TDELUKSResult::TDELUKSResult TDEStorageDevice::cryptCheckKey(unsigned int keyslot) {
188 #if defined(WITH_CRYPTSETUP)
189  int ret;
190 
191  if (m_cryptDevice) {
192  if (keyslot < m_cryptKeySlotCount) {
193  ret = crypt_activate_by_passphrase(m_cryptDevice, NULL, keyslot, m_cryptDevicePassword.data(), m_cryptDevicePassword.size(), 0);
194  if (ret < 0) {
195  return TDELUKSResult::KeyslotOpFailed;
196  }
197  else {
198  return TDELUKSResult::Success;
199  }
200  }
201  else {
202  return TDELUKSResult::InvalidKeyslot;
203  }
204  }
205  else {
206  return TDELUKSResult::LUKSNotFound;
207  }
208 #else
209  return TDELUKSResult::LUKSNotSupported;
210 #endif
211 }
212 
213 TDELUKSResult::TDELUKSResult TDEStorageDevice::cryptAddKey(unsigned int keyslot, TQByteArray password) {
214 #if defined(WITH_CRYPTSETUP)
215  int ret;
216 
217  if (m_cryptDevice) {
218  if (keyslot < m_cryptKeySlotCount) {
219  ret = crypt_keyslot_add_by_passphrase(m_cryptDevice, keyslot, m_cryptDevicePassword.data(), m_cryptDevicePassword.size(), password.data(), password.size());
220  if (ret < 0) {
221  return TDELUKSResult::KeyslotOpFailed;
222  }
223  else {
224  internalGetLUKSKeySlotStatus();
225  return TDELUKSResult::Success;
226  }
227  }
228  else {
229  return TDELUKSResult::InvalidKeyslot;
230  }
231  }
232  else {
233  return TDELUKSResult::LUKSNotFound;
234  }
235 #else
236  return TDELUKSResult::LUKSNotSupported;
237 #endif
238 }
239 
240 TDELUKSResult::TDELUKSResult TDEStorageDevice::cryptDelKey(unsigned int keyslot) {
241 #if defined(WITH_CRYPTSETUP)
242  int ret;
243 
244  if (m_cryptDevice) {
245  if (keyslot < m_cryptKeySlotCount) {
246  ret = crypt_keyslot_destroy(m_cryptDevice, keyslot);
247  if (ret < 0) {
248  return TDELUKSResult::KeyslotOpFailed;
249  }
250  else {
251  internalGetLUKSKeySlotStatus();
252  return TDELUKSResult::Success;
253  }
254  }
255  else {
256  return TDELUKSResult::InvalidKeyslot;
257  }
258  }
259  else {
260  return TDELUKSResult::LUKSNotFound;
261  }
262 #else
263  return TDELUKSResult::LUKSNotSupported;
264 #endif
265 }
266 
267 unsigned int TDEStorageDevice::cryptKeySlotCount() {
268  return m_cryptKeySlotCount;
269 }
270 
271 TDELUKSKeySlotStatusList TDEStorageDevice::cryptKeySlotStatus() {
272  return m_cryptKeyslotStatus;
273 }
274 
275 TQString TDEStorageDevice::cryptKeySlotFriendlyName(TDELUKSKeySlotStatus::TDELUKSKeySlotStatus status) {
276  if (status & TDELUKSKeySlotStatus::Inactive) {
277  return i18n("Inactive");
278  }
279  else if (status & TDELUKSKeySlotStatus::Active) {
280  return i18n("Active");
281  }
282  else {
283  return i18n("Unknown");
284  }
285 }
286 
287 void TDEStorageDevice::internalSetDeviceNode(TQString dn) {
288  TDEGenericDevice::internalSetDeviceNode(dn);
289  internalInitializeLUKSIfNeeded();
290 }
291 
292 void TDEStorageDevice::internalSetDiskType(TDEDiskDeviceType::TDEDiskDeviceType dt) {
293  m_diskType = dt;
294  internalInitializeLUKSIfNeeded();
295 }
296 
297 bool TDEStorageDevice::isDiskOfType(TDEDiskDeviceType::TDEDiskDeviceType tf) {
298  return ((m_diskType&tf)!=TDEDiskDeviceType::Null);
299 }
300 
301 TDEDiskDeviceStatus::TDEDiskDeviceStatus TDEStorageDevice::diskStatus() {
302  return m_diskStatus;
303 }
304 
305 void TDEStorageDevice::internalSetDiskStatus(TDEDiskDeviceStatus::TDEDiskDeviceStatus st) {
306  m_diskStatus = st;
307 }
308 
309 bool TDEStorageDevice::checkDiskStatus(TDEDiskDeviceStatus::TDEDiskDeviceStatus sf) {
310  return ((m_diskStatus&sf)!=(TDEDiskDeviceStatus::TDEDiskDeviceStatus)0);
311 }
312 
313 bool TDEStorageDevice::lockDriveMedia(bool lock) {
314  int fd = open(deviceNode().ascii(), O_RDWR | O_NONBLOCK);
315  if (fd < 0) {
316  return false;
317  }
318  if (ioctl(fd, CDROM_LOCKDOOR, (lock)?1:0) != 0) {
319  close(fd);
320  return false;
321  }
322  else {
323  close(fd);
324  return true;
325  }
326 }
327 
328 TQStringVariantMap TDEStorageDevice::ejectDrive() {
329  TQStringVariantMap result;
330  TQStringVariantMap ejectResult;
331 
332  // If the device is mounted, try unmounting it first
333  if (!mountPath().isEmpty()) {
334  unmountDevice();
335  }
336 
337 #ifdef WITH_UDISKS2
338  if (!(TDEGlobal::dirs()->findExe("udisksctl").isEmpty())) {
339  ejectResult = udisks2EjectDrive(this);
340  if (ejectResult["result"].toBool()) {
341  result["result"] = true;
342  return result;
343  }
344  else {
345  result["errStr"] = ejectResult["errStr"];
346  result["result"] = false;
347  return result;
348  }
349  }
350 #endif
351 #ifdef WITH_UDISKS
352  if (!(TDEGlobal::dirs()->findExe("udisks").isEmpty())) {
353  ejectResult = udisksEjectDrive(this);
354  if (ejectResult["result"].toBool()) {
355  result["result"] = true;
356  return result;
357  }
358  else {
359  result["errStr"] = ejectResult["errStr"];
360  result["result"] = false;
361  return result;
362  }
363  }
364 #endif
365 
366  if (!(TDEGlobal::dirs()->findExe("eject").isEmpty())) {
367  TQString command = TQString("eject -v '%1' 2>&1").arg(deviceNode());
368 
369  FILE *exepipe = popen(command.ascii(), "r");
370  if (exepipe) {
371  TQString eject_output;
372  TQTextStream ts(exepipe, IO_ReadOnly);
373  eject_output = ts.read();
374  int retcode = pclose(exepipe);
375  if (retcode == 0) {
376  result["result"] = true;
377  return result;
378  }
379  else {
380  result["errStr"] = eject_output;
381  result["retCode"] = retcode;
382  }
383  }
384  }
385 
386  result["result"] = false;
387  return result;
388 }
389 
390 bool TDEStorageDevice::ejectDriveMedia() {
391  int fd = open(deviceNode().ascii(), O_RDWR | O_NONBLOCK);
392  if (fd < 0) {
393  return false;
394  }
395  if (ioctl(fd, CDROMEJECT) != 0) {
396  close(fd);
397  return false;
398  }
399  else {
400  close(fd);
401  return true;
402  }
403 }
404 
405 TQString TDEStorageDevice::diskLabel() {
406  return m_diskName;
407 }
408 
409 void TDEStorageDevice::internalSetDiskLabel(TQString dn) {
410  m_diskName = dn;
411 }
412 
413 bool TDEStorageDevice::mediaInserted() {
414  return m_mediaInserted;
415 }
416 
417 void TDEStorageDevice::internalSetMediaInserted(bool inserted) {
418  m_mediaInserted = inserted;
419 }
420 
421 TQString TDEStorageDevice::fileSystemName() {
422  return m_fileSystemName;
423 }
424 
425 void TDEStorageDevice::internalSetFileSystemName(TQString fn) {
426  m_fileSystemName = fn;
427 }
428 
429 TQString TDEStorageDevice::fileSystemUsage() {
430  return m_fileSystemUsage;
431 }
432 
433 void TDEStorageDevice::internalSetFileSystemUsage(TQString fu) {
434  m_fileSystemUsage = fu;
435 }
436 
437 TQString TDEStorageDevice::diskUUID() {
438  return m_diskUUID;
439 }
440 
441 void TDEStorageDevice::internalSetDiskUUID(TQString id) {
442  m_diskUUID = id;
443 }
444 
445 TQStringList TDEStorageDevice::holdingDevices() {
446  return m_holdingDevices;
447 }
448 
449 void TDEStorageDevice::internalSetHoldingDevices(TQStringList hd) {
450  m_holdingDevices = hd;
451 }
452 
453 TQStringList TDEStorageDevice::slaveDevices() {
454  return m_slaveDevices;
455 }
456 
457 void TDEStorageDevice::internalSetSlaveDevices(TQStringList sd) {
458  m_slaveDevices = sd;
459 }
460 
461 TQString decodeHexEncoding(TQString str) {
462  TQRegExp hexEncRegExp("\\\\x[0-9A-Fa-f]{1,2}");
463  hexEncRegExp.setMinimal(false);
464  hexEncRegExp.setCaseSensitive(true);
465  int s = -1;
466 
467  while((s = hexEncRegExp.search(str, s+1))>=0){
468  str.replace(s, hexEncRegExp.cap(0).length(), TQChar((char)strtol(hexEncRegExp.cap(0).mid(2).ascii(), NULL, 16)));
469  }
470 
471  return str;
472 }
473 
474 TQString TDEStorageDevice::friendlyName() {
475  // Return the actual storage device name
476  TQString devicevendorid = vendorEncoded();
477  TQString devicemodelid = modelEncoded();
478 
479  devicevendorid = decodeHexEncoding(devicevendorid);
480  devicemodelid = decodeHexEncoding(devicemodelid);
481 
482  devicevendorid = devicevendorid.stripWhiteSpace();
483  devicemodelid = devicemodelid.stripWhiteSpace();
484  devicevendorid = devicevendorid.simplifyWhiteSpace();
485  devicemodelid = devicemodelid.simplifyWhiteSpace();
486 
487  TQString devicename = devicevendorid + " " + devicemodelid;
488 
489  devicename = devicename.stripWhiteSpace();
490  devicename = devicename.simplifyWhiteSpace();
491 
492  if (devicename != "") {
493  return devicename;
494  }
495 
496  if (isDiskOfType(TDEDiskDeviceType::Camera)) {
497  return TDEGenericDevice::friendlyName();
498  }
499 
500  if (isDiskOfType(TDEDiskDeviceType::Floppy)) {
501  return friendlyDeviceType();
502  }
503 
504  TQString label = diskLabel();
505  if (label.isNull()) {
506  if (deviceSize() > 0) {
507  if (checkDiskStatus(TDEDiskDeviceStatus::Removable)) {
508  label = i18n("%1 Removable Device").arg(deviceFriendlySize());
509  }
510  else {
511  label = i18n("%1 Fixed Storage Device").arg(deviceFriendlySize());
512  }
513  }
514  }
515 
516  if (!label.isNull()) {
517  return label;
518  }
519 
520  return friendlyDeviceType();
521 }
522 
523 TQString TDEStorageDevice::detailedFriendlyName() {
524  return TQString("%1 [%2]").arg(friendlyName()).arg(deviceNode());
525 }
526 
527 TQString TDEStorageDevice::friendlyDeviceType() {
528  TQString ret = i18n("Hard Disk Drive");
529 
530  // Keep this in sync with TDEStorageDevice::icon(TDEIcon::StdSizes size) below
531  if (isDiskOfType(TDEDiskDeviceType::Floppy)) {
532  ret = i18n("Floppy Drive");
533  }
534  if (isDiskOfType(TDEDiskDeviceType::Optical)) {
535  ret = i18n("Optical Drive");
536  }
537  if (isDiskOfType(TDEDiskDeviceType::CDROM)) {
538  ret = i18n("CDROM Drive");
539  }
540  if (isDiskOfType(TDEDiskDeviceType::CDRW)) {
541  ret = i18n("CDRW Drive");
542  }
543  if (isDiskOfType(TDEDiskDeviceType::DVDROM)) {
544  ret = i18n("DVD Drive");
545  }
546  if (isDiskOfType(TDEDiskDeviceType::DVDRW)) {
547  ret = i18n("DVDRW Drive");
548  }
549  if (isDiskOfType(TDEDiskDeviceType::DVDRAM)) {
550  ret = i18n("DVDRAM Drive");
551  }
552  if (isDiskOfType(TDEDiskDeviceType::Zip)) {
553  ret = i18n("Zip Drive");
554  }
555  if (isDiskOfType(TDEDiskDeviceType::Tape)) {
556  ret = i18n("Tape Drive");
557  }
558  if (isDiskOfType(TDEDiskDeviceType::Camera)) {
559  ret = i18n("Digital Camera");
560  }
561 
562  if (isDiskOfType(TDEDiskDeviceType::HDD)) {
563  ret = i18n("Hard Disk Drive");
564  if (checkDiskStatus(TDEDiskDeviceStatus::Removable)) {
565  ret = i18n("Removable Storage");
566  }
567  if (isDiskOfType(TDEDiskDeviceType::CompactFlash)) {
568  ret = i18n("Compact Flash");
569  }
570  if (isDiskOfType(TDEDiskDeviceType::MemoryStick)) {
571  ret = i18n("Memory Stick");
572  }
573  if (isDiskOfType(TDEDiskDeviceType::SmartMedia)) {
574  ret = i18n("Smart Media");
575  }
576  if (isDiskOfType(TDEDiskDeviceType::SDMMC)) {
577  ret = i18n("Secure Digital");
578  }
579  }
580 
581  if (isDiskOfType(TDEDiskDeviceType::RAM)) {
582  ret = i18n("Random Access Memory");
583  }
584  if (isDiskOfType(TDEDiskDeviceType::Loop)) {
585  ret = i18n("Loop Device");
586  }
587 
588  return ret;
589 }
590 
591 TQPixmap TDEStorageDevice::icon(TDEIcon::StdSizes size) {
592  TQString mountString;
593  if (mountPath() != TQString::null) {
594  mountString = "-mounted";
595  }
596  else {
597  mountString = "-unmounted";
598  }
599 
600  TQPixmap ret = DesktopIcon("drive-harddisk" + mountString, size);
601 
602  if (isDiskOfType(TDEDiskDeviceType::Floppy)) {
603  ret = DesktopIcon("media-floppy-3_5" + mountString, size);
604  }
605  if (isDiskOfType(TDEDiskDeviceType::Optical)) {
606  ret = DesktopIcon("media-optical-cdrom" + mountString, size);
607  }
608  if (isDiskOfType(TDEDiskDeviceType::CDROM)) {
609  ret = DesktopIcon("media-optical-cdrom" + mountString, size);
610  }
611  if (isDiskOfType(TDEDiskDeviceType::CDRW)) {
612  ret = DesktopIcon("cd-rw" + mountString, size);
613  }
614  if (isDiskOfType(TDEDiskDeviceType::DVDROM)) {
615  ret = DesktopIcon("media-optical-dvd" + mountString, size);
616  }
617  if (isDiskOfType(TDEDiskDeviceType::DVDRW)) {
618  ret = DesktopIcon("media-optical-dvd" + mountString, size);
619  }
620  if (isDiskOfType(TDEDiskDeviceType::DVDRAM)) {
621  ret = DesktopIcon("media-optical-dvd" + mountString, size);
622  }
623  if (isDiskOfType(TDEDiskDeviceType::Zip)) {
624  ret = DesktopIcon("media-floppy-zip" + mountString, size);
625  }
626  if (isDiskOfType(TDEDiskDeviceType::Tape)) {
627  ret = DesktopIcon("media-tape" + mountString, size);
628  }
629  if (isDiskOfType(TDEDiskDeviceType::Camera)) {
630  ret = DesktopIcon("camera" + mountString, size);
631  }
632 
633  if (isDiskOfType(TDEDiskDeviceType::HDD)) {
634  ret = DesktopIcon("drive-harddisk" + mountString, size);
635  if (checkDiskStatus(TDEDiskDeviceStatus::Removable)) {
636  ret = DesktopIcon("media-flash-usb" + mountString, size);
637  }
638  if (isDiskOfType(TDEDiskDeviceType::CompactFlash)) {
639  ret = DesktopIcon("media-flash-compact_flash" + mountString, size);
640  }
641  if (isDiskOfType(TDEDiskDeviceType::MemoryStick)) {
642  ret = DesktopIcon("media-flash-memory_stick" + mountString, size);
643  }
644  if (isDiskOfType(TDEDiskDeviceType::SmartMedia)) {
645  ret = DesktopIcon("media-flash-smart_media" + mountString, size);
646  }
647  if (isDiskOfType(TDEDiskDeviceType::SDMMC)) {
648  ret = DesktopIcon("media-flash-sd_mmc" + mountString, size);
649  }
650  }
651 
652  if (isDiskOfType(TDEDiskDeviceType::RAM)) {
653  ret = DesktopIcon("memory", size); // FIXME there is only a single icon available for this device
654  }
655  if (isDiskOfType(TDEDiskDeviceType::Loop)) {
656  ret = DesktopIcon("blockdevice", size); // FIXME there is only a single icon available for this device
657  }
658 
659  return ret;
660 }
661 
662 unsigned long long TDEStorageDevice::deviceSize() {
663  TQString bsnodename = systemPath();
664  // 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
665  // appears to only ever report the device size in 512 byte units. This does not appear to be documented anywhere!
666  TQString blocksize = "512";
667 
668  TQString dsnodename = systemPath();
669  dsnodename.append("/size");
670  TQFile dsfile( dsnodename );
671  TQString devicesize;
672  if ( dsfile.open( IO_ReadOnly ) ) {
673  TQTextStream stream( &dsfile );
674  devicesize = stream.readLine();
675  dsfile.close();
676  }
677 
678  return ((unsigned long long)blocksize.toULong()*(unsigned long long)devicesize.toULong());
679 }
680 
681 TQString TDEStorageDevice::deviceFriendlySize() {
682  return TDEHardwareDevices::bytesToFriendlySizeString(deviceSize());
683 }
684 
685 TQString TDEStorageDevice::mountPath()
686 {
687  return m_mountPath;
688 }
689 
690 void TDEStorageDevice::internalUpdateMountPath()
691 {
692  // See if this device node is mounted
693  // This requires parsing /proc/mounts, looking for deviceNode()
694 
695  // The Device Mapper throws a monkey wrench into this
696  // It likes to advertise mounts as /dev/mapper/<something>,
697  // where <something> is listed in <system path>/dm/name
698 
699  // Assumed all device information (mainly holders/slaves) is accurate
700  // prior to the call
701 
702  m_mountPath = TQString::null;
703 
704  TQStringList lines;
705  TQFile file( "/proc/mounts" );
706  if ( file.open( IO_ReadOnly ) ) {
707  TQTextStream stream( &file );
708  TQString line;
709  while ( !stream.atEnd() ) {
710  line = stream.readLine();
711  TQStringList mountInfo = TQStringList::split(" ", line, true);
712  TQString testNode = *mountInfo.at(0);
713  // Check for match
714  if ((testNode == deviceNode()) || (testNode == mappedName()) || (testNode == ("/dev/disk/by-uuid/" + diskUUID()))) {
715  m_mountPath = *mountInfo.at(1);
716  m_mountPath.replace("\\040", " ");
717  file.close();
718  return;
719  }
720  lines += line;
721  }
722  file.close();
723  }
724 }
725 
726 TQStringVariantMap TDEStorageDevice::mountDevice(TQString mediaName, TDEStorageMountOptions mountOptions) {
727  TQStringVariantMap result;
728 
729  // Check if device is already mounted
730  TQString mountpath = mountPath();
731  if (!mountpath.isEmpty()) {
732  result["mountPath"] = mountpath;
733  result["result"] = true;
734  return result;
735  }
736 
737  TQString devNode = deviceNode();
738  devNode.replace("'", "'\\''");
739  mediaName.replace("'", "'\\''");
740  TQString command = TQString::null;
741 
742 #if defined(WITH_UDISKS2) || defined(WITH_UDISKS) || defined(WITH_UDEVIL)
743  // Prepare filesystem options for mount
744  TQStringList udisksOptions;
745  if (mountOptions["ro"] == "true") {
746  udisksOptions.append("ro");
747  }
748 
749  if (mountOptions["atime"] != "true") {
750  udisksOptions.append("noatime");
751  }
752 
753  if (mountOptions["sync"] == "true") {
754  udisksOptions.append("sync");
755  }
756 
757  if ((mountOptions["filesystem"] == "fat") || (mountOptions["filesystem"] == "vfat") ||
758  (mountOptions["filesystem"] == "msdos") || (mountOptions["filesystem"] == "umsdos")) {
759  if (mountOptions.contains("shortname")) {
760  udisksOptions.append(TQString("shortname=%1").arg(mountOptions["shortname"]));
761  }
762  }
763 
764  if ((mountOptions["filesystem"] == "jfs")) {
765  if (mountOptions["utf8"] == "true") {
766  // udisks/udisks2 for now does not support option iocharset= for jfs
767  // udisksOptions.append("iocharset=utf8");
768  }
769  }
770 
771  if ((mountOptions["filesystem"] == "ntfs-3g")) {
772  if (mountOptions.contains("locale")) {
773  udisksOptions.append(TQString("locale=%1").arg(mountOptions["locale"]));
774  }
775  }
776 
777  if ((mountOptions["filesystem"] == "ext3") || (mountOptions["filesystem"] == "ext4")) {
778  if (mountOptions.contains("journaling")) {
779  // udisks/udisks2 for now does not support option data= for ext3/ext4
780  // udisksOptions.append(TQString("data=%1").arg(mountOptions["journaling"]));
781  }
782  }
783 
784  TQString optionString;
785  for (TQStringList::Iterator it = udisksOptions.begin(); it != udisksOptions.end(); ++it) {
786  optionString.append(",");
787  optionString.append(*it);
788  }
789 
790  if (!optionString.isEmpty()) {
791  optionString.remove(0, 1);
792  }
793 
794  TQString fileSystemType;
795  if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) {
796  fileSystemType = mountOptions["filesystem"];
797  }
798 
799  TQStringVariantMap mountResult;
800 #endif
801 
802 #if defined(WITH_UDISKS2)
803  // Try to use UDISKS v2 via DBUS, if available
804  mountResult = udisks2MountDrive(devNode, fileSystemType, optionString);
805  if (mountResult["result"].toBool()) {
806  // Update internal mount data
807  TDEGlobal::hardwareDevices()->processModifiedMounts();
808  result["mountPath"] = mountPath();
809  result["result"] = true;
810  return result;
811  }
812  else if (mountResult["retcode"].toInt() == -1) {
813  // Update internal mount data
814  TDEGlobal::hardwareDevices()->processModifiedMounts();
815  result["errStr"] = mountResult["errStr"];
816  result["result"] = false;
817  return result;
818  }
819 #endif
820 
821 #if defined(WITH_UDISKS)
822  // The UDISKS v2 DBUS service was either not available or was unusable
823  // Try to use UDISKS v1 via DBUS, if available
824  mountResult = udisksMountDrive(devNode, fileSystemType, udisksOptions);
825  if (mountResult["result"].toBool()) {
826  // Update internal mount data
827  TDEGlobal::hardwareDevices()->processModifiedMounts();
828  result["mountPath"] = mountPath();
829  result["result"] = true;
830  return result;
831  }
832  else if (mountResult["retcode"].toInt() == -1) {
833  // Update internal mount data
834  TDEGlobal::hardwareDevices()->processModifiedMounts();
835  result["errStr"] = mountResult["errStr"];
836  result["result"] = false;
837  return result;
838  }
839 #endif
840 
841 #if defined(WITH_UDEVIL)
842  // The UDISKS v1 DBUS service was either not available or was unusable
843  // Use 'udevil' command, if available
844  if (!TDEGlobal::dirs()->findExe("udevil").isEmpty()) {
845  if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) {
846  fileSystemType = TQString("-t %1").arg(mountOptions["filesystem"]);
847  }
848  TQString mountpoint;
849  if (mountOptions.contains("mountpoint") && !mountOptions["mountpoint"].isEmpty() &&
850  (mountOptions["mountpoint"] != "/media/")) {
851  mountpoint = mountOptions["mountpoint"];
852  mountpoint.replace("'", "'\\''");
853  }
854  else {
855  mountpoint = TQString("/media/%1").arg(mediaName);
856  }
857  command = TQString("udevil mount %1 -o '%2' '%3' '%4' 2>&1")
858  .arg(fileSystemType).arg(optionString).arg(devNode).arg(mountpoint);
859  }
860 #endif
861 
862  // If no other method was found, use 'pmount' command if available
863  if(command.isEmpty()) {
864  if (!TDEGlobal::dirs()->findExe("pmount").isEmpty()) {
865  TQString optionString;
866  if (mountOptions["ro"] == "true") {
867  optionString.append(" -r");
868  }
869 
870  if (mountOptions["atime"] != "true") {
871  optionString.append(" -A");
872  }
873 
874  if (mountOptions["utf8"] == "true") {
875  optionString.append(" -c utf8");
876  }
877 
878  if (mountOptions["sync"] == "true") {
879  optionString.append(" -s");
880  }
881 
882  if (mountOptions.contains("filesystem") && !mountOptions["filesystem"].isEmpty()) {
883  optionString.append(TQString(" -t %1").arg(mountOptions["filesystem"]));
884  }
885 
886  if (mountOptions.contains("locale")) {
887  optionString.append(TQString(" -c %1").arg(mountOptions["locale"]));
888  }
889 
890  TQString mountpoint;
891  if (mountOptions.contains("mountpoint") && !mountOptions["mountpoint"].isEmpty() &&
892  (mountOptions["mountpoint"] != "/media/")) {
893  mountpoint = mountOptions["mountpoint"];
894  mountpoint.replace("'", "'\\''");
895  }
896  else {
897  mountpoint = mediaName;
898  }
899 
900  // %1 (option string) without quotes, otherwise pmount fails
901  command = TQString("pmount %1 '%2' '%3' 2>&1")
902  .arg(optionString).arg(devNode).arg(mountpoint);
903  }
904  }
905 
906  if(command.isEmpty()) {
907  result["errStr"] = i18n("No supported mounting methods were detected on your system");
908  result["result"] = false;
909  return result;
910  }
911 
912  FILE *exepipe = popen(command.local8Bit(), "r");
913  if (exepipe) {
914  TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly);
915  TQString mount_output = ts->read();
916  delete ts;
917  int retcode = pclose(exepipe);
918  result["errStr"] = mount_output;
919  result["retCode"] = retcode;
920  }
921 
922  // Update internal mount data
923  TDEGlobal::hardwareDevices()->processModifiedMounts();
924  result["mountPath"] = mountPath();
925  result["result"] = !mountPath().isEmpty();
926  return result;
927 }
928 
929 TQStringVariantMap TDEStorageDevice::unmountDevice() {
930  TQStringVariantMap result;
931 
932  // Check if device is already unmounted
933  TQString mountpath = mountPath();
934  if (mountpath.isEmpty()) {
935  result["result"] = true;
936  return result;
937  }
938 
939  mountpath.replace("'", "'\\''");
940  TQString devNode = deviceNode();
941  TQString command = TQString::null;
942  TQStringVariantMap unmountResult;
943 
944 #if defined(WITH_UDISKS2)
945  // Try to use UDISKS v2 via DBUS, if available
946  unmountResult = udisks2UnmountDrive(devNode, TQString::null);
947  if (unmountResult["result"].toBool()) {
948  // Update internal mount data
949  TDEGlobal::hardwareDevices()->processModifiedMounts();
950  result["result"] = true;
951  return result;
952  }
953  else if (unmountResult["retcode"].toInt() == -1) {
954  // Update internal mount data
955  TDEGlobal::hardwareDevices()->processModifiedMounts();
956  result["errStr"] = unmountResult["errStr"];
957  result["result"] = false;
958  return result;
959  }
960 #endif
961 
962 #if defined(WITH_UDISKS)
963  // The UDISKS v2 DBUS service was either not available or was unusable
964  // Try to use UDISKS v1 via DBUS, if available
965  unmountResult = udisksUnmountDrive(devNode, TQStringList());
966  if (unmountResult["result"].toBool()) {
967  // Update internal mount data
968  TDEGlobal::hardwareDevices()->processModifiedMounts();
969  result["result"] = true;
970  return result;
971  }
972  else if (unmountResult["retcode"].toInt() == -1) {
973  // Update internal mount data
974  TDEGlobal::hardwareDevices()->processModifiedMounts();
975  result["errStr"] = unmountResult["errStr"];
976  result["result"] = false;
977  return result;
978  }
979 #endif
980 
981 #if defined(WITH_UDEVIL)
982  // The UDISKS v1 DBUS service was either not available or was unusable
983  // Use 'udevil' command, if available
984  if (!TDEGlobal::dirs()->findExe("udevil").isEmpty()) {
985  command = TQString("udevil umount '%1' 2>&1").arg(mountpath);
986  }
987 #endif
988 
989  // If no other method was found, use 'pmount' command if available
990  if(command.isEmpty() && !TDEGlobal::dirs()->findExe("pumount").isEmpty()) {
991  command = TQString("pumount '%1' 2>&1").arg(mountpath);
992  }
993 
994  if(command.isEmpty()) {
995  result["errStr"] = i18n("No supported unmounting methods were detected on your system");
996  result["result"] = false;
997  return result;
998  }
999 
1000  FILE *exepipe = popen(command.local8Bit(), "r");
1001  if (exepipe) {
1002  TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly);
1003  TQString umount_output = ts->read();
1004  delete ts;
1005  int retcode = pclose(exepipe);
1006  if (retcode == 0) {
1007  // Update internal mount data
1008  TDEGlobal::hardwareDevices()->processModifiedMounts();
1009  result["result"] = true;
1010  return result;
1011  }
1012  else {
1013  result["errStr"] = umount_output;
1014  result["retCode"] = retcode;
1015  }
1016  }
1017 
1018  // Update internal mount data
1019  TDEGlobal::hardwareDevices()->processModifiedMounts();
1020  result["result"] = false;
1021  return result;
1022 }
1023 
1024 TQStringVariantMap TDEStorageDevice::unlockDevice(const TQString &passphrase)
1025 {
1026  TQStringVariantMap result;
1027 
1028  TQString devNode = deviceNode();
1029  devNode.replace("'", "'\\''");
1030 
1031  TQStringVariantMap unlockResult;
1032 
1033 #if defined(WITH_UDISKS2)
1034  // Try to use UDISKS v2 via DBUS, if available
1035  unlockResult = udisks2UnlockDrive(devNode, passphrase);
1036  if (unlockResult["result"].toBool()) {
1037  result["unlockedDevice"] = unlockResult["unlockedDevice"];
1038  result["result"] = true;
1039  return result;
1040  }
1041  else if (unlockResult["retcode"].toInt() == -1) {
1042  result["errStr"] = unlockResult["errStr"];
1043  result["result"] = false;
1044  return result;
1045  }
1046 #endif
1047 
1048  // If no other method was found, use 'pmount' command if available
1049  if (!TDEGlobal::dirs()->findExe("pmount").isEmpty()) {
1050  // Create dummy password file
1051  KTempFile passwordFile(TQString::null, "tmp", 0600);
1052  passwordFile.setAutoDelete(true);
1053  TQFile *pwFile = passwordFile.file();
1054  if (!pwFile) {
1055  result["errStr"] = i18n("Cannot create temporary password file");
1056  result["result"] = false;
1057  return result;
1058  }
1059  pwFile->writeBlock(passphrase.local8Bit(), passphrase.length());
1060  pwFile->flush();
1061  TQString passFileName = passwordFile.name();
1062  passFileName.replace("'", "'\\''");
1063 
1064  TQString command = TQString("pmount -p '%1' '%2'").arg(passFileName).arg(devNode);
1065  FILE *exepipe = popen(command.local8Bit(), "r");
1066  if (exepipe) {
1067  TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly);
1068  TQString unlock_output = ts->read();
1069  delete ts;
1070  int retcode = pclose(exepipe);
1071  if (retcode == 0) {
1072  result["result"] = true;
1073  }
1074  else {
1075  result["errStr"] = unlock_output;
1076  result["retCode"] = retcode;
1077  result["result"] = false;
1078  }
1079  return result;
1080  }
1081  }
1082 
1083  // No supported methods found for unlocking the device
1084  result["errStr"] = i18n("No supported unlocking methods were detected on your system.");
1085  result["result"] = false;
1086  return result;
1087 }
1088 
1089 TQStringVariantMap TDEStorageDevice::lockDevice()
1090 {
1091  TQStringVariantMap result;
1092 
1093  TQString devNode = deviceNode();
1094  devNode.replace("'", "'\\''");
1095 
1096  TQStringVariantMap lockResult;
1097 
1098 #if defined(WITH_UDISKS2)
1099  // Try to use UDISKS v2 via DBUS, if available
1100  lockResult = udisks2LockDrive(devNode);
1101  if (lockResult["result"].toBool()) {
1102  result["result"] = true;
1103  return result;
1104  }
1105  else if (lockResult["retcode"].toInt() == -1) {
1106  result["errStr"] = lockResult["errStr"];
1107  result["result"] = false;
1108  return result;
1109  }
1110 #endif
1111 
1112  // If no other method was found, use 'pumount' command if available
1113  if (!TDEGlobal::dirs()->findExe("pumount").isEmpty()) {
1114  TQString command = TQString("pumount '%1'").arg(devNode);
1115  FILE *exepipe = popen(command.local8Bit(), "r");
1116  if (exepipe) {
1117  TQTextStream* ts = new TQTextStream(exepipe, IO_ReadOnly);
1118  TQString lock_output = ts->read();
1119  delete ts;
1120  int retcode = pclose(exepipe);
1121  if (retcode == 0) {
1122  result["result"] = true;
1123  }
1124  else {
1125  result["errStr"] = lock_output;
1126  result["retCode"] = retcode;
1127  result["result"] = false;
1128  }
1129  return result;
1130  }
1131  }
1132 
1133  // No supported methods found for locking the device
1134  result["errStr"] = i18n("No supported locking methods were detected on your system.");
1135  result["result"] = false;
1136  return result;
1137 }
1138 
1139 #include "tdestoragedevice.moc"
KTempFile
The KTempFile class creates and opens a unique file for temporary use.
Definition: tdetempfile.h:56
TDEGlobal::dirs
static TDEStandardDirs * dirs()
Returns the application standard dirs object.
Definition: tdeglobal.cpp:58
TDEIconLoader::DesktopIcon
TQPixmap DesktopIcon(const TQString &name, int size=0, int state=TDEIcon::DefaultState, TDEInstance *instance=TDEGlobal::instance())
Load a desktop icon.
Definition: kiconloader.cpp:1297
TDEIcon::StdSizes
StdSizes
These are the standard sizes for icons.
Definition: kicontheme.h:112
TDELocale::i18n
TQString i18n(const char *text)
i18n is the function that does everything you need to translate a string.
Definition: tdelocale.cpp:1976
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
TDEGlobal::kdWarning
kdbgstream kdWarning(int area=0)
Returns a warning stream.
Definition: kdebug.cpp:376
TDEGlobal::endl
kdbgstream & endl(kdbgstream &s)
Prints an "\n".
Definition: kdebug.h:430
KStdAction::close
TDEAction * close(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)
KStdAction::open
TDEAction * open(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
tdelocale.h

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