• 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 "tdestandarddirs.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
56TDEStorageDevice::TDEStorageDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn) : TDEGenericDevice(dt, dn), m_mediaInserted(true), m_cryptDevice(NULL), m_cryptKeySlotCount(0) {
57 m_diskType = TDEDiskDeviceType::Null;
58 m_diskStatus = TDEDiskDeviceStatus::Null;
59}
60
61TDEStorageDevice::~TDEStorageDevice() {
62#if defined(WITH_CRYPTSETUP)
63 if (m_cryptDevice) {
64 crypt_free(m_cryptDevice);
65 m_cryptDevice = NULL;
66 }
67#endif
68}
69
70TQString TDEStorageDevice::mappedName() {
71 return m_mappedName;
72}
73
74void 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
90TDEDiskDeviceType::TDEDiskDeviceType TDEStorageDevice::diskType() {
91 return m_diskType;
92}
93
94void 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
118void 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
163void TDEStorageDevice::cryptSetOperationsUnlockPassword(TQByteArray password) {
164#if defined(WITH_CRYPTSETUP)
165 crypt_memory_lock(NULL, 1);
166 m_cryptDevicePassword = password;
167#endif
168}
169
170void 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
178bool TDEStorageDevice::cryptOperationsUnlockPasswordSet() {
179 if (m_cryptDevicePassword.size() > 0) {
180 return true;
181 }
182 else {
183 return false;
184 }
185}
186
187TDELUKSResult::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
213TDELUKSResult::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
240TDELUKSResult::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
267unsigned int TDEStorageDevice::cryptKeySlotCount() {
268 return m_cryptKeySlotCount;
269}
270
271TDELUKSKeySlotStatusList TDEStorageDevice::cryptKeySlotStatus() {
272 return m_cryptKeyslotStatus;
273}
274
275TQString 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
287void TDEStorageDevice::internalSetDeviceNode(TQString dn) {
288 TDEGenericDevice::internalSetDeviceNode(dn);
289 internalInitializeLUKSIfNeeded();
290}
291
292void TDEStorageDevice::internalSetDiskType(TDEDiskDeviceType::TDEDiskDeviceType dt) {
293 m_diskType = dt;
294 internalInitializeLUKSIfNeeded();
295}
296
297bool TDEStorageDevice::isDiskOfType(TDEDiskDeviceType::TDEDiskDeviceType tf) {
298 return ((m_diskType&tf)!=TDEDiskDeviceType::Null);
299}
300
301TDEDiskDeviceStatus::TDEDiskDeviceStatus TDEStorageDevice::diskStatus() {
302 return m_diskStatus;
303}
304
305void TDEStorageDevice::internalSetDiskStatus(TDEDiskDeviceStatus::TDEDiskDeviceStatus st) {
306 m_diskStatus = st;
307}
308
309bool TDEStorageDevice::checkDiskStatus(TDEDiskDeviceStatus::TDEDiskDeviceStatus sf) {
310 return ((m_diskStatus&sf)!=(TDEDiskDeviceStatus::TDEDiskDeviceStatus)0);
311}
312
313bool 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
328TQStringVariantMap 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
390bool 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
405TQString TDEStorageDevice::diskLabel() {
406 return m_diskName;
407}
408
409void TDEStorageDevice::internalSetDiskLabel(TQString dn) {
410 m_diskName = dn;
411}
412
413bool TDEStorageDevice::mediaInserted() {
414 return m_mediaInserted;
415}
416
417void TDEStorageDevice::internalSetMediaInserted(bool inserted) {
418 m_mediaInserted = inserted;
419}
420
421TQString TDEStorageDevice::fileSystemName() {
422 return m_fileSystemName;
423}
424
425void TDEStorageDevice::internalSetFileSystemName(TQString fn) {
426 m_fileSystemName = fn;
427}
428
429TQString TDEStorageDevice::fileSystemUsage() {
430 return m_fileSystemUsage;
431}
432
433void TDEStorageDevice::internalSetFileSystemUsage(TQString fu) {
434 m_fileSystemUsage = fu;
435}
436
437TQString TDEStorageDevice::diskUUID() {
438 return m_diskUUID;
439}
440
441void TDEStorageDevice::internalSetDiskUUID(TQString id) {
442 m_diskUUID = id;
443}
444
445TQStringList TDEStorageDevice::holdingDevices() {
446 return m_holdingDevices;
447}
448
449void TDEStorageDevice::internalSetHoldingDevices(TQStringList hd) {
450 m_holdingDevices = hd;
451}
452
453TQStringList TDEStorageDevice::slaveDevices() {
454 return m_slaveDevices;
455}
456
457void TDEStorageDevice::internalSetSlaveDevices(TQStringList sd) {
458 m_slaveDevices = sd;
459}
460
461TQString 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
474TQString 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
523TQString TDEStorageDevice::detailedFriendlyName() {
524 return TQString("%1 [%2]").arg(friendlyName()).arg(deviceNode());
525}
526
527TQString 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
591TQPixmap 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
662unsigned 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
681TQString TDEStorageDevice::deviceFriendlySize() {
682 return TDEHardwareDevices::bytesToFriendlySizeString(deviceSize());
683}
684
685TQString TDEStorageDevice::mountPath()
686{
687 return m_mountPath;
688}
689
690void 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
726TQStringVariantMap 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
929TQStringVariantMap 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
1024TQStringVariantMap 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
1089TQStringVariantMap 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: tdestandarddirs.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.4
This website is maintained by Timothy Pearson.