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

tdecore

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

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
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • 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.