summaryrefslogtreecommitdiffstats
path: root/kioslave/media
diff options
context:
space:
mode:
Diffstat (limited to 'kioslave/media')
-rw-r--r--kioslave/media/kfile-plugin/kfile_media.desktop2
-rw-r--r--kioslave/media/kfile-plugin/kfilemediaplugin.cpp10
-rw-r--r--kioslave/media/libmediacommon/medium.cpp29
-rw-r--r--kioslave/media/libmediacommon/medium.h12
-rw-r--r--kioslave/media/libmediacommon/notifieropenaction.cpp2
-rw-r--r--kioslave/media/libmediacommon/notifiersettings.cpp12
-rw-r--r--kioslave/media/mediaimpl.cpp7
-rw-r--r--kioslave/media/mediamanager/halbackend.cpp505
-rw-r--r--kioslave/media/mediamanager/halbackend.h3
-rw-r--r--kioslave/media/mediamanager/medialist.cpp15
-rw-r--r--kioslave/media/mediamanager/medialist.h1
-rw-r--r--kioslave/media/mediamanager/mediamanager.cpp22
-rw-r--r--kioslave/media/mediamanager/mediamanager.h2
-rw-r--r--kioslave/media/medianotifier/medianotifier.cpp80
-rw-r--r--kioslave/media/medianotifier/medianotifier.h9
-rw-r--r--kioslave/media/mimetypes/Makefile.am10
-rw-r--r--kioslave/media/mimetypes/cdrom_mounted_decrypted.desktop11
-rw-r--r--kioslave/media/mimetypes/cdrom_unmounted_decrypted.desktop11
-rw-r--r--kioslave/media/mimetypes/cdrom_unmounted_encrypted.desktop11
-rw-r--r--kioslave/media/mimetypes/cdwriter_mounted_decrypted.desktop11
-rw-r--r--kioslave/media/mimetypes/cdwriter_unmounted_decrypted.desktop11
-rw-r--r--kioslave/media/mimetypes/cdwriter_unmounted_encrypted.desktop11
-rw-r--r--kioslave/media/mimetypes/dvd_mounted_decrypted.desktop11
-rw-r--r--kioslave/media/mimetypes/dvd_unmounted_decrypted.desktop11
-rw-r--r--kioslave/media/mimetypes/dvd_unmounted_encrypted.desktop11
-rw-r--r--kioslave/media/mimetypes/hdd_mounted_decrypted.desktop11
-rw-r--r--kioslave/media/mimetypes/hdd_unmounted_decrypted.desktop11
-rw-r--r--kioslave/media/mimetypes/hdd_unmounted_encrypted.desktop11
-rw-r--r--kioslave/media/mimetypes/removable_mounted_decrypted.desktop11
-rw-r--r--kioslave/media/mimetypes/removable_unmounted_decrypted.desktop11
-rw-r--r--kioslave/media/mimetypes/removable_unmounted_encrypted.desktop11
-rw-r--r--kioslave/media/mounthelper/Makefile.am4
-rw-r--r--kioslave/media/mounthelper/decryptdialog.ui201
-rw-r--r--kioslave/media/mounthelper/dialog.cpp68
-rw-r--r--kioslave/media/mounthelper/dialog.h61
-rw-r--r--kioslave/media/mounthelper/kio_media_mounthelper.cpp89
-rw-r--r--kioslave/media/mounthelper/kio_media_mounthelper.h10
-rw-r--r--kioslave/media/propsdlgplugin/media_propsdlgplugin.desktop2
-rw-r--r--kioslave/media/services/Makefile.am2
-rw-r--r--kioslave/media/services/media_decrypt.desktop9
-rw-r--r--kioslave/media/services/media_eject.desktop2
-rw-r--r--kioslave/media/services/media_mount.desktop2
-rw-r--r--kioslave/media/services/media_safelyremove.desktop2
-rw-r--r--kioslave/media/services/media_unmount.desktop2
44 files changed, 1282 insertions, 58 deletions
diff --git a/kioslave/media/kfile-plugin/kfile_media.desktop b/kioslave/media/kfile-plugin/kfile_media.desktop
index 474ab12b2..c29d590e3 100644
--- a/kioslave/media/kfile-plugin/kfile_media.desktop
+++ b/kioslave/media/kfile-plugin/kfile_media.desktop
@@ -72,4 +72,4 @@ Name[zh_CN]=介质信息
Name[zh_TW]=媒體資訊
ServiceTypes=KFilePlugin
X-KDE-Library=kfile_media
-MimeType=media/audiocd;media/hdd_mounted;media/blankcd;media/hdd_unmounted;media/blankdvd;media/cdrom_mounted;media/cdrom_unmounted;media/cdwriter_mounted;media/nfs_mounted;media/cdwriter_unmounted;media/nfs_unmounted;media/removable_mounted;media/dvd_mounted;media/removable_unmounted;media/dvd_unmounted;media/smb_mounted;media/dvdvideo;media/smb_unmounted;media/floppy5_mounted;media/svcd;media/floppy5_unmounted;media/vcd;media/floppy_mounted;media/zip_mounted;media/floppy_unmounted;media/zip_unmounted;media/gphoto2camera;media/camera_mounted;media/camera_unmounted
+MimeType=media/audiocd;media/hdd_mounted;media/hdd_mounted_decrypted;media/blankcd;media/hdd_unmounted;media/hdd_unmounted_decrypted;media/blankdvd;media/cdrom_mounted;media/cdrom_mounted_decrypted;media/cdrom_unmounted;media/cdrom_unmounted_decrypted;media/cdwriter_mounted;media/cdwriter_mounted_decrypted;media/nfs_mounted;media/cdwriter_unmounted;media/cdwriter_unmounted_decrypted;media/nfs_unmounted;media/removable_mounted;media/removable_mounted_decrypted;media/dvd_mounted;media/dvd_mounted_decrypted;media/removable_unmounted;media/removable_unmounted_decrypted;media/dvd_unmounted;media/dvd_unmounted_decrypted;media/smb_mounted;media/dvdvideo;media/smb_unmounted;media/floppy5_mounted;media/svcd;media/floppy5_unmounted;media/vcd;media/floppy_mounted;media/zip_mounted;media/floppy_unmounted;media/zip_unmounted;media/gphoto2camera;media/camera_mounted;media/camera_unmounted
diff --git a/kioslave/media/kfile-plugin/kfilemediaplugin.cpp b/kioslave/media/kfile-plugin/kfilemediaplugin.cpp
index c91dbf21a..37aa7d61f 100644
--- a/kioslave/media/kfile-plugin/kfilemediaplugin.cpp
+++ b/kioslave/media/kfile-plugin/kfilemediaplugin.cpp
@@ -47,19 +47,29 @@ KFileMediaPlugin::KFileMediaPlugin(QObject *parent, const char *name,
{
addMimeType( "media/audiocd" );
addMimeType( "media/hdd_mounted" );
+ addMimeType( "media/hdd_mounted_decrypted" );
addMimeType( "media/blankcd" );
addMimeType( "media/hdd_unmounted" );
+ addMimeType( "media/hdd_unmounted_decrypted" );
addMimeType( "media/blankdvd" );
addMimeType( "media/cdrom_mounted" );
+ addMimeType( "media/cdrom_mounted_decrypted" );
addMimeType( "media/cdrom_unmounted" );
+ addMimeType( "media/cdrom_unmounted_decrypted" );
addMimeType( "media/cdwriter_mounted" );
+ addMimeType( "media/cdwriter_mounted_decrypted" );
addMimeType( "media/nfs_mounted" );
addMimeType( "media/cdwriter_unmounted" );
+ addMimeType( "media/cdwriter_unmounted_decrypted" );
addMimeType( "media/nfs_unmounted" );
addMimeType( "media/removable_mounted" );
+ addMimeType( "media/removable_mounted_decrypted" );
addMimeType( "media/dvd_mounted" );
+ addMimeType( "media/dvd_mounted_decrypted" );
addMimeType( "media/removable_unmounted" );
+ addMimeType( "media/removable_unmounted_decrypted" );
addMimeType( "media/dvd_unmounted" );
+ addMimeType( "media/dvd_unmounted_decrypted" );
addMimeType( "media/smb_mounted" );
addMimeType( "media/dvdvideo" );
addMimeType( "media/smb_unmounted" );
diff --git a/kioslave/media/libmediacommon/medium.cpp b/kioslave/media/libmediacommon/medium.cpp
index 5767a6c9a..4cba32aeb 100644
--- a/kioslave/media/libmediacommon/medium.cpp
+++ b/kioslave/media/libmediacommon/medium.cpp
@@ -38,6 +38,8 @@ Medium::Medium(const QString &id, const QString &name)
m_properties+= QString::null; /* BASE_URL */
m_properties+= QString::null; /* MIME_TYPE */
m_properties+= QString::null; /* ICON_NAME */
+ m_properties+= "false"; /* ENCRYPTED */
+ m_properties+= QString::null; /* CLEAR_DEVICE_UDI */
loadUserLabel();
@@ -59,6 +61,8 @@ Medium::Medium()
m_properties+= QString::null; /* BASE_URL */
m_properties+= QString::null; /* MIME_TYPE */
m_properties+= QString::null; /* ICON_NAME */
+ m_properties+= QString::null; /* ENCRYPTED */
+ m_properties+= QString::null; /* CLEAR_DEVICE_UDI */
m_halmounted = false;
}
@@ -82,6 +86,8 @@ const Medium Medium::create(const QStringList &properties)
m.m_properties[BASE_URL] = properties[BASE_URL];
m.m_properties[MIME_TYPE] = properties[MIME_TYPE];
m.m_properties[ICON_NAME] = properties[ICON_NAME];
+ m.m_properties[ENCRYPTED] = properties[ENCRYPTED];
+ m.m_properties[CLEAR_DEVICE_UDI] = properties[CLEAR_DEVICE_UDI];
}
return m;
@@ -123,6 +129,11 @@ void Medium::setLabel(const QString &label)
m_properties[LABEL] = label;
}
+void Medium::setEncrypted(bool state)
+{
+ m_properties[ENCRYPTED] = ( state ? "true" : "false" );
+}
+
void Medium::setUserLabel(const QString &label)
{
KConfig cfg("mediamanagerrc");
@@ -185,6 +196,19 @@ void Medium::mountableState(const QString &deviceNode,
m_properties[MOUNTED] = ( mounted ? "true" : "false" );
}
+void Medium::mountableState(const QString &deviceNode,
+ const QString &clearDeviceUdi,
+ const QString &mountPoint,
+ const QString &fsType, bool mounted)
+{
+ m_properties[MOUNTABLE] = "true";
+ m_properties[DEVICE_NODE] = deviceNode;
+ m_properties[CLEAR_DEVICE_UDI] = clearDeviceUdi;
+ m_properties[MOUNT_POINT] = mountPoint;
+ m_properties[FS_TYPE] = fsType;
+ m_properties[MOUNTED] = ( mounted ? "true" : "false" );
+}
+
void Medium::unmountableState(const QString &baseURL)
{
m_properties[MOUNTABLE] = "false";
@@ -206,6 +230,11 @@ bool Medium::needMounting() const
return isMountable() && !isMounted();
}
+bool Medium::needDecryption() const
+{
+ return isEncrypted() && clearDeviceUdi().isEmpty();
+}
+
KURL Medium::prettyBaseURL() const
{
if ( !baseURL().isEmpty() )
diff --git a/kioslave/media/libmediacommon/medium.h b/kioslave/media/libmediacommon/medium.h
index f94545e8e..543bdf596 100644
--- a/kioslave/media/libmediacommon/medium.h
+++ b/kioslave/media/libmediacommon/medium.h
@@ -41,7 +41,9 @@ public:
static const uint BASE_URL = 9;
static const uint MIME_TYPE = 10;
static const uint ICON_NAME = 11;
- static const uint PROPERTIES_COUNT = 12;
+ static const uint ENCRYPTED = 12;
+ static const uint CLEAR_DEVICE_UDI = 13;
+ static const uint PROPERTIES_COUNT = 14;
static const QString SEPARATOR;
Medium(const QString &id, const QString &name);
@@ -62,19 +64,27 @@ public:
QString baseURL() const { return m_properties[BASE_URL]; }
QString mimeType() const { return m_properties[MIME_TYPE]; }
QString iconName() const { return m_properties[ICON_NAME]; }
+ bool isEncrypted() const { return m_properties[ENCRYPTED]=="true"; };
+ QString clearDeviceUdi() const { return m_properties[CLEAR_DEVICE_UDI]; };
bool needMounting() const;
+ bool needDecryption() const;
KURL prettyBaseURL() const;
QString prettyLabel() const;
void setName(const QString &name);
void setLabel(const QString &label);
void setUserLabel(const QString &label);
+ void setEncrypted(bool state);
bool mountableState(bool mounted);
void mountableState(const QString &deviceNode,
const QString &mountPoint,
const QString &fsType, bool mounted);
+ void mountableState(const QString &deviceNode,
+ const QString &clearDeviceUdi,
+ const QString &mountPoint,
+ const QString &fsType, bool mounted);
void unmountableState(const QString &baseURL = QString::null);
void setMimeType(const QString &mimeType);
diff --git a/kioslave/media/libmediacommon/notifieropenaction.cpp b/kioslave/media/libmediacommon/notifieropenaction.cpp
index 82db14b97..2cf664cc6 100644
--- a/kioslave/media/libmediacommon/notifieropenaction.cpp
+++ b/kioslave/media/libmediacommon/notifieropenaction.cpp
@@ -40,6 +40,6 @@ void NotifierOpenAction::execute(KFileItem &medium)
bool NotifierOpenAction::supportsMimetype( const QString &mimetype ) const
{
- return !mimetype.contains( "blank" );
+ return !mimetype.contains( "blank" ) && !mimetype.contains( "encrypted" );
}
diff --git a/kioslave/media/libmediacommon/notifiersettings.cpp b/kioslave/media/libmediacommon/notifiersettings.cpp
index c7ad616a5..c7ba40e85 100644
--- a/kioslave/media/libmediacommon/notifiersettings.cpp
+++ b/kioslave/media/libmediacommon/notifiersettings.cpp
@@ -32,16 +32,28 @@
NotifierSettings::NotifierSettings()
{
m_supportedMimetypes.append( "media/removable_unmounted" );
+ m_supportedMimetypes.append( "media/removable_unmounted_encrypted" );
+ m_supportedMimetypes.append( "media/removable_unmounted_decrypted" );
m_supportedMimetypes.append( "media/removable_mounted" );
+ m_supportedMimetypes.append( "media/removable_mounted_decrypted" );
m_supportedMimetypes.append( "media/camera_unmounted" );
m_supportedMimetypes.append( "media/camera_mounted" );
m_supportedMimetypes.append( "media/gphoto2camera" );
m_supportedMimetypes.append( "media/cdrom_unmounted" );
+ m_supportedMimetypes.append( "media/cdrom_unmounted_encrypted" );
+ m_supportedMimetypes.append( "media/cdrom_unmounted_decrypted" );
m_supportedMimetypes.append( "media/cdrom_mounted" );
+ m_supportedMimetypes.append( "media/cdrom_mounted_decrypted" );
m_supportedMimetypes.append( "media/dvd_unmounted" );
+ m_supportedMimetypes.append( "media/dvd_unmounted_encrypted" );
+ m_supportedMimetypes.append( "media/dvd_unmounted_decrypted" );
m_supportedMimetypes.append( "media/dvd_mounted" );
+ m_supportedMimetypes.append( "media/dvd_mounted_decrypted" );
m_supportedMimetypes.append( "media/cdwriter_unmounted" );
+ m_supportedMimetypes.append( "media/cdwriter_unmounted_encrypted" );
+ m_supportedMimetypes.append( "media/cdwriter_unmounted_decrypted" );
m_supportedMimetypes.append( "media/cdwriter_mounted" );
+ m_supportedMimetypes.append( "media/cdwriter_mounted_decrypted" );
m_supportedMimetypes.append( "media/blankcd" );
m_supportedMimetypes.append( "media/blankdvd" );
m_supportedMimetypes.append( "media/audiocd" );
diff --git a/kioslave/media/mediaimpl.cpp b/kioslave/media/mediaimpl.cpp
index 741227cdb..516bcdb01 100644
--- a/kioslave/media/mediaimpl.cpp
+++ b/kioslave/media/mediaimpl.cpp
@@ -226,6 +226,13 @@ bool MediaImpl::ensureMediumMounted(Medium &medium)
m_lastErrorMessage = i18n("No such medium.");
return false;
}
+
+ if ( medium.isEncrypted() && medium.clearDeviceUdi().isEmpty() )
+ {
+ m_lastErrorCode = KIO::ERR_COULD_NOT_MOUNT;
+ m_lastErrorMessage = i18n("The drive is encrypted.");
+ return false;
+ }
if ( medium.needMounting() )
{
diff --git a/kioslave/media/mediamanager/halbackend.cpp b/kioslave/media/mediamanager/halbackend.cpp
index 65c796605..4d6d9b19d 100644
--- a/kioslave/media/mediamanager/halbackend.cpp
+++ b/kioslave/media/mediamanager/halbackend.cpp
@@ -20,8 +20,10 @@
#include "linuxcdpolling.h"
#include <stdlib.h>
+#include <locale.h>
#include <kapplication.h>
+#include <kmessagebox.h>
#include <qeventloop.h>
#include <qfile.h>
#include <klocale.h>
@@ -33,9 +35,17 @@
#include <kmountpoint.h>
#include <kmessagebox.h>
#include <kio/job.h>
+#include <kstandarddirs.h>
+#include <kprocess.h>
-#define MOUNT_SUFFIX (libhal_volume_is_mounted(halVolume) ? QString("_mounted") : QString("_unmounted"))
-#define MOUNT_ICON_SUFFIX (libhal_volume_is_mounted(halVolume) ? QString("_mount") : QString("_unmount"))
+#define MOUNT_SUFFIX ( \
+ (medium->isMounted() ? QString("_mounted") : QString("_unmounted")) + \
+ (medium->isEncrypted() ? (halClearVolume ? "_decrypted" : "_encrypted") : "" ) \
+ )
+#define MOUNT_ICON_SUFFIX ( \
+ (medium->isMounted() ? QString("_mount") : QString("_unmount")) + \
+ (medium->isEncrypted() ? (halClearVolume ? "_decrypt" : "_encrypt") : "" ) \
+ )
/* Static instance of this class, for static HAL callbacks */
static HALBackend* s_HALBackend;
@@ -211,8 +221,15 @@ void HALBackend::AddDevice(const char *udi, bool allowNotification)
/* Add volume block devices */
if (libhal_device_query_capability(m_halContext, udi, "volume", NULL))
{
- /* We only list volume that have a filesystem or volume that have an audio track*/
- if ( libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") != "filesystem" &&
+ /* We only list volumes that...
+ * - are encrypted with LUKS or
+ * - have a filesystem or
+ * - have an audio track
+ */
+ if ( ( libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") != "crypto" ||
+ libhal_device_get_property_QString(m_halContext, udi, "volume.fstype") != "crypto_LUKS"
+ ) &&
+ libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") != "filesystem" &&
!libhal_device_get_property_bool(m_halContext, udi, "volume.disc.has_audio", NULL) &&
!libhal_device_get_property_bool(m_halContext, udi, "volume.disc.is_blank", NULL) )
return;
@@ -232,6 +249,21 @@ void HALBackend::AddDevice(const char *udi, bool allowNotification)
/** @todo check exclusion list **/
+ /* Special handling for clear crypto volumes */
+ LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, udi);
+ if (!halVolume)
+ return;
+ const char* backingVolumeUdi = libhal_volume_crypto_get_backing_volume_udi(halVolume);
+ if ( backingVolumeUdi != NULL )
+ {
+ /* The crypto drive was unlocked and may now be mounted... */
+ kdDebug(1219) << "HALBackend::AddDevice : ClearVolume appeared for " << backingVolumeUdi << endl;
+ ResetProperties(backingVolumeUdi, allowNotification);
+ libhal_volume_free(halVolume);
+ return;
+ }
+ libhal_volume_free(halVolume);
+
/* Create medium */
Medium* medium = new Medium(udi, "");
setVolumeProperties(medium);
@@ -247,6 +279,11 @@ void HALBackend::AddDevice(const char *udi, bool allowNotification)
return;
}
}
+
+ // instert medium into list
+ m_mediaList.addMedium(medium, allowNotification);
+
+ // finally check for automount
QMap<QString,QString> options = MediaManagerUtils::splitOptions(mountoptions(udi));
kdDebug() << "automount " << options["automount"] << endl;
if (options["automount"] == "true" && allowNotification ) {
@@ -254,7 +291,6 @@ void HALBackend::AddDevice(const char *udi, bool allowNotification)
if (!error.isEmpty())
kdDebug() << "error " << error << endl;
}
- m_mediaList.addMedium(medium, allowNotification);
return;
}
@@ -295,11 +331,18 @@ void HALBackend::AddDevice(const char *udi, bool allowNotification)
void HALBackend::RemoveDevice(const char *udi)
{
- m_mediaList.removeMedium(udi, true);
+ const Medium *medium = m_mediaList.findByClearUdi(udi);
+ if (medium) {
+ ResetProperties(medium->id().ascii());
+ } else {
+ m_mediaList.removeMedium(udi, true);
+ }
}
void HALBackend::ModifyDevice(const char *udi, const char* key)
{
+ kdDebug(1219) << "HALBackend::ModifyDevice for '" << udi << "' on '" << key << "'\n";
+
const char* mediumUdi = findMediumUdiFromUdi(udi);
if (!mediumUdi)
return;
@@ -381,6 +424,18 @@ const char* HALBackend::findMediumUdiFromUdi(const char* udi)
if (libhal_device_property_exists(m_halContext, udi, "info.capabilities", NULL))
if (libhal_device_query_capability(m_halContext, udi, "volume", NULL))
{
+ /* check if this belongs to an encrypted volume */
+ LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, udi);
+ if (!halVolume) return NULL;
+ const char* backingUdi = libhal_volume_crypto_get_backing_volume_udi(halVolume);
+ if (backingUdi != NULL) {
+ const char* result = findMediumUdiFromUdi(backingUdi);
+ libhal_volume_free(halVolume);
+ return result;
+ }
+ libhal_volume_free(halVolume);
+
+ /* this is a volume whose drive is registered */
QString driveUdi = libhal_device_get_property_QString(m_halContext, udi, "block.storage_device");
return findMediumUdiFromUdi(driveUdi.ascii());
}
@@ -445,11 +500,47 @@ void HALBackend::setVolumeProperties(Medium* medium)
medium->setName(
generateName(libhal_volume_get_device_file(halVolume)) );
- medium->mountableState(
- libhal_volume_get_device_file(halVolume), /* Device node */
- libhal_volume_get_mount_point(halVolume), /* Mount point */
- libhal_volume_get_fstype(halVolume), /* Filesystem type */
- libhal_volume_is_mounted(halVolume) ); /* Mounted ? */
+ LibHalVolume* halClearVolume = NULL;
+ if ( libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") == "crypto" )
+ {
+ kdDebug(1219) << "HALBackend::setVolumeProperties : crypto volume" << endl;
+
+ medium->setEncrypted(true);
+ char* clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume);
+ QString clearUdiString;
+ if (clearUdi != NULL) {
+ kdDebug(1219) << "HALBackend::setVolumeProperties : crypto clear volume avail - " << clearUdi << endl;
+ halClearVolume = libhal_volume_from_udi(m_halContext, clearUdi);
+ // ignore if halClearVolume is NULL -> just not decrypted in this case
+ clearUdiString = clearUdi;
+ libhal_free_string(clearUdi);
+ }
+
+ if (halClearVolume)
+ medium->mountableState(
+ libhal_volume_get_device_file(halVolume), /* Device node */
+ clearUdiString,
+ libhal_volume_get_mount_point(halClearVolume), /* Mount point */
+ libhal_volume_get_fstype(halClearVolume), /* Filesystem type */
+ libhal_volume_is_mounted(halClearVolume) ); /* Mounted ? */
+ else
+ medium->mountableState(
+ libhal_volume_get_device_file(halVolume), /* Device node */
+ QString::null,
+ QString::null, /* Mount point */
+ QString::null, /* Filesystem type */
+ false ); /* Mounted ? */
+ }
+ else
+ {
+ kdDebug(1219) << "HALBackend::setVolumeProperties : normal volume" << endl;
+ medium->mountableState(
+ libhal_volume_get_device_file(halVolume), /* Device node */
+ libhal_volume_get_mount_point(halVolume), /* Mount point */
+ libhal_volume_get_fstype(halVolume), /* Filesystem type */
+ libhal_volume_is_mounted(halVolume) ); /* Mounted ? */
+ }
+
char* name = libhal_volume_policy_compute_display_name(halDrive, halVolume, m_halStoragePolicy);
QString volume_name = QString::fromUtf8(name);
@@ -777,13 +868,35 @@ void HALBackend::hal_device_condition(LibHalContext *ctx, const char *udi,
QStringList HALBackend::mountoptions(const QString &name)
{
const Medium* medium = m_mediaList.findById(name);
- if (medium && !isInFstab(medium).isNull())
+ if (!medium)
+ return QStringList(); // we don't know about that one
+ if (!isInFstab(medium).isNull())
return QStringList(); // not handled by HAL - fstab entry
+ QString volume_udi = name;
+ if (medium->isEncrypted()) {
+ // see if we have a clear volume
+ LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, medium->id().latin1());
+ if (halVolume) {
+ char* clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume);
+ if (clearUdi != NULL) {
+ volume_udi = clearUdi;
+ libhal_free_string(clearUdi);
+ } else {
+ // if not decrypted yet then no mountoptions
+ return QStringList();
+ }
+ libhal_volume_free(halVolume);
+ } else {
+ // strange...
+ return QStringList();
+ }
+ }
+
KConfig config("mediamanagerrc");
config.setGroup(name);
- char ** array = libhal_device_get_property_strlist(m_halContext, name.latin1(), "volume.mount.valid_options", NULL);
+ char ** array = libhal_device_get_property_strlist(m_halContext, volume_udi.latin1(), "volume.mount.valid_options", NULL);
QMap<QString,bool> valids;
for (int index = 0; array && array[index]; ++index) {
@@ -797,11 +910,11 @@ QStringList HALBackend::mountoptions(const QString &name)
QStringList result;
QString tmp;
- QString fstype = libhal_device_get_property_QString(m_halContext, name.latin1(), "volume.fstype");
+ QString fstype = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.fstype");
if (fstype.isNull())
- fstype = libhal_device_get_property_QString(m_halContext, name.latin1(), "volume.policy.mount_filesystem");
+ fstype = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.policy.mount_filesystem");
- QString drive_udi = libhal_device_get_property_QString(m_halContext, name.latin1(), "block.storage_device");
+ QString drive_udi = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "block.storage_device");
bool removable = false;
if ( !drive_udi.isNull() )
@@ -812,11 +925,11 @@ QStringList HALBackend::mountoptions(const QString &name)
bool value = config.readBoolEntry("automount", false);
config.setGroup(name);
- if (libhal_device_get_property_bool(m_halContext, name.latin1(), "volume.disc.is_blank", NULL)
- || libhal_device_get_property_bool(m_halContext, name.latin1(), "volume.disc.is_vcd", NULL)
- || libhal_device_get_property_bool(m_halContext, name.latin1(), "volume.disc.is_svcd", NULL)
- || libhal_device_get_property_bool(m_halContext, name.latin1(), "volume.disc.is_videodvd", NULL)
- || libhal_device_get_property_bool(m_halContext, name.latin1(), "volume.disc.has_audio", NULL))
+ if (libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_blank", NULL)
+ || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_vcd", NULL)
+ || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_svcd", NULL)
+ || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_videodvd", NULL)
+ || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.has_audio", NULL))
value = false;
result << QString("automount=%1").arg(value ? "true" : "false");
@@ -898,9 +1011,9 @@ QStringList HALBackend::mountoptions(const QString &name)
result << tmp;
}
- QString mount_point = libhal_device_get_property_QString(m_halContext, name.latin1(), "volume.mount_point");
+ QString mount_point = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.mount_point");
if (mount_point.isEmpty())
- mount_point = libhal_device_get_property_QString(m_halContext, name.latin1(), "volume.policy.desired_mount_point");
+ mount_point = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.policy.desired_mount_point");
mount_point = config.readEntry("mountpoint", mount_point);
@@ -958,6 +1071,120 @@ bool HALBackend::setMountoptions(const QString &name, const QStringList &options
return true;
}
+QString startKdeSudoProcess(const QString& kdesudoPath, const QString& command,
+ const QString& dialogCaption, const QString& dialogComment)
+{
+ KProcess kdesudoProcess;
+
+ kdesudoProcess << kdesudoPath
+ << "-d"
+ << "--noignorebutton"
+ << "--caption" << dialogCaption
+ << "--comment" << dialogComment
+ << "-c" << command;
+
+ // @todo handle kdesudo output
+ kdesudoProcess.start(KProcess::Block);
+
+ return QString();
+}
+
+QString startKdeSuProcess(const QString& kdesuPath, const QString& command,
+ const QString& dialogCaption)
+{
+ KProcess kdesuProcess;
+
+ kdesuProcess << kdesuPath
+ << "-d"
+ << "--noignorebutton"
+ << "--caption" << dialogCaption
+ << "-c" << command;
+
+ // @todo handle kdesu output
+ kdesuProcess.start(KProcess::Block);
+
+ return QString();
+}
+
+QString startPrivilegedProcess(const QString& command, const QString& dialogCaption, const QString& dialogComment)
+{
+ QString error;
+
+ QString kdesudoPath = KStandardDirs::findExe("kdesudo");
+
+ if (!kdesudoPath.isEmpty())
+ error = startKdeSudoProcess(kdesudoPath, command, dialogCaption, dialogComment);
+ else {
+ QString kdesuPath = KStandardDirs::findExe("kdesu");
+
+ if (!kdesuPath.isEmpty())
+ error = startKdeSuProcess(kdesuPath, command, dialogCaption);
+ }
+
+ return error;
+}
+
+QString privilegedMount(const char* udi, const char* mountPoint, const char** options, int numberOfOptions)
+{
+ QString error;
+
+ kdDebug() << "run privileged mount for " << udi << endl;
+
+ QString dbusSendPath = KStandardDirs::findExe("dbus-send");
+
+ // @todo return error message
+ if (dbusSendPath.isEmpty())
+ return QString();
+
+ QString mountOptions;
+ QTextOStream optionsStream(&mountOptions);
+ for (int optionIndex = 0; optionIndex < numberOfOptions; optionIndex++) {
+ optionsStream << options[optionIndex];
+ if (optionIndex < numberOfOptions - 1)
+ optionsStream << ",";
+ }
+
+ QString command;
+ QTextOStream(&command) << dbusSendPath
+ << " --system --print-reply --dest=org.freedesktop.Hal " << udi
+ << " org.freedesktop.Hal.Device.Volume.Mount string:" << mountPoint
+ << " string: array:string:" << mountOptions;
+
+ kdDebug() << "command: " << command << endl;
+
+ error = startPrivilegedProcess(command,
+ i18n("Authenticate"),
+ i18n("<big><b>System policy prevents mounting internal media</b></big><br/>Authentication is required to perform this action. Please enter your password to verify."));
+
+ return error;
+}
+
+QString privilegedUnmount(const char* udi)
+{
+ QString error;
+
+ kdDebug() << "run privileged unmount for " << udi << endl;
+
+ QString dbusSendPath = KStandardDirs::findExe("dbus-send");
+
+ // @todo return error message
+ if (dbusSendPath.isEmpty())
+ return QString();
+
+ QString command;
+ QTextOStream(&command) << dbusSendPath
+ << " --system --print-reply --dest=org.freedesktop.Hal " << udi
+ << " org.freedesktop.Hal.Device.Volume.Unmount array:string:force";
+
+ kdDebug() << "command: " << command << endl;
+
+ error = startPrivilegedProcess(command,
+ i18n("Authenticate"),
+ i18n("<big><b>System policy prevents unmounting media mounted by other users</b></big><br/>Authentication is required to perform this action. Please enter your password to verify."));
+
+ return error;
+}
+
static QString mount_priv(const char *udi, const char *mount_point, const char **poptions, int noptions,
DBusConnection *dbus_connection)
{
@@ -992,6 +1219,8 @@ static QString mount_priv(const char *udi, const char *mount_point, const char *
qerror = i18n("Invalid filesystem type");
else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.Volume.PermissionDenied"))
qerror = i18n("Permissions denied");
+ else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.PermissionDeniedByPolicy"))
+ qerror = privilegedMount(udi, mount_point, poptions, noptions);
else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.Volume.AlreadyMounted"))
qerror = i18n("Device is already mounted.");
else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.Volume.InvalidMountpoint") && strlen(mount_point)) {
@@ -1050,6 +1279,41 @@ QString HALBackend::listUsingProcesses(const Medium* medium)
}
}
+QString HALBackend::killUsingProcesses(const Medium* medium)
+{
+ QString proclist, fullmsg;
+ QString cmdline = QString("/usr/bin/env fuser -vmk %1 2>&1").arg(KProcess::quote(medium->mountPoint()));
+ FILE *fuser = popen(cmdline.latin1(), "r");
+
+ uint counter = 0;
+ if (fuser) {
+ proclist += "<pre>";
+ QTextIStream is(fuser);
+ QString tmp;
+ while (!is.atEnd()) {
+ tmp = is.readLine();
+ tmp = QStyleSheet::escape(tmp) + "\n";
+
+ proclist += tmp;
+ if (counter++ > 10)
+ {
+ proclist += "...";
+ break;
+ }
+ }
+ proclist += "</pre>";
+ (void)pclose( fuser );
+ }
+ if (counter) {
+ fullmsg = i18n("Programs that were still using the device "
+ "have been forcibly terminated. They are listed below.");
+ fullmsg += "<br>" + proclist;
+ return fullmsg;
+ } else {
+ return QString::null;
+ }
+}
+
void HALBackend::slotResult(KIO::Job *job)
{
kdDebug() << "slotResult " << mount_jobs[job] << endl;
@@ -1148,7 +1412,7 @@ QString HALBackend::mount(const Medium *medium)
if (valids["flush"] == "true")
soptions << "flush";
- if (valids["uid"] == "true")
+ if ((valids["uid"] == "true") && (medium->fsType() != "ntfs"))
{
soptions << QString("uid=%1").arg(getuid());
}
@@ -1168,6 +1432,13 @@ QString HALBackend::mount(const Medium *medium)
if (valids["sync"] == "true")
soptions << "sync";
+ if (medium->fsType() == "ntfs") {
+ QString fsLocale("locale=");
+ fsLocale += setlocale(LC_ALL, "");
+
+ soptions << fsLocale;
+ }
+
QString mount_point = valids["mountpoint"];
if (mount_point.startsWith("/media/"))
mount_point = mount_point.mid(7);
@@ -1199,7 +1470,24 @@ QString HALBackend::mount(const Medium *medium)
options[noptions] = (*it).latin1();
options[noptions] = NULL;
- QString qerror = mount_priv(medium->id().latin1(), mount_point.utf8(), options, noptions, dbus_connection);
+ QString qerror = i18n("Cannot mount encrypted drives!");
+
+ if (!medium->isEncrypted()) {
+ // normal volume
+ qerror = mount_priv(medium->id().latin1(), mount_point.utf8(), options, noptions, dbus_connection);
+ } else {
+ // see if we have a clear volume
+ LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, medium->id().latin1());
+ if (halVolume) {
+ char* clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume);
+ if (clearUdi != NULL) {
+ qerror = mount_priv(clearUdi, mount_point.utf8(), options, noptions, dbus_connection);
+ libhal_free_string(clearUdi);
+ }
+ libhal_volume_free(halVolume);
+ }
+ }
+
if (!qerror.isEmpty()) {
kdError() << "mounting " << medium->id() << " returned " << qerror << endl;
return qerror;
@@ -1266,8 +1554,26 @@ QString HALBackend::unmount(const QString &_udi)
DBusMessage *dmesg, *reply;
DBusError error;
const char *options[2];
+ QString udi = QString::null;
+
+ if (!medium->isEncrypted()) {
+ // normal volume
+ udi = medium->id();
+ } else {
+ // see if we have a clear volume
+ LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, medium->id().latin1());
+ if (halVolume) {
+ char *clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume);
+ udi = clearUdi;
+ libhal_free_string(clearUdi);
+ libhal_volume_free(halVolume);
+ }
+ }
+ if (udi.isNull()) {
+ kdDebug() << "unmount failed: no udi" << endl;
+ return i18n("Internal Error");
+ }
- const char *udi = medium->id().latin1();
kdDebug() << "unmounting " << udi << "..." << endl;
dbus_error_init(&error);
@@ -1278,7 +1584,7 @@ QString HALBackend::unmount(const QString &_udi)
return false;
}
- if (!(dmesg = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ if (!(dmesg = dbus_message_new_method_call ("org.freedesktop.Hal", udi.latin1(),
"org.freedesktop.Hal.Device.Volume",
"Unmount"))) {
kdDebug() << "unmount failed for " << udi << ": could not create dbus message\n";
@@ -1296,11 +1602,25 @@ QString HALBackend::unmount(const QString &_udi)
return i18n("Internal Error");
}
+ char thisunmounthasfailed = 0;
dbus_error_init (&error);
if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, dmesg, -1, &error)))
{
- QString qerror, reason;
+ thisunmounthasfailed = 1;
+ QString qerror, reason, origqerror;
+ if (!strcmp(error.name, "org.freedesktop.Hal.Device.PermissionDeniedByPolicy")) {
+ qerror = privilegedUnmount(udi.latin1());
+
+ if (qerror.isEmpty()) {
+ dbus_message_unref(dmesg);
+ dbus_error_free(&error);
+ return QString();
+ }
+
+ // @todo handle unmount error message
+ }
+
kdDebug() << "unmount failed for " << udi << ": " << error.name << " " << error.message << endl;
qerror = "<qt>";
qerror += "<p>" + i18n("Unfortunately, the device <b>%1</b> (%2) named <b>'%3'</b> and "
@@ -1312,6 +1632,7 @@ QString HALBackend::unmount(const QString &_udi)
qerror += "<p>" + i18n("Unmounting failed due to the following error:") + "</p>";
if (!strcmp(error.name, "org.freedesktop.Hal.Device.Volume.Busy")) {
reason = i18n("Device is Busy:");
+ thisunmounthasfailed = 2;
} else if (!strcmp(error.name, "org.freedesktop.Hal.Device.Volume.NotMounted")) {
// this is faking. The error is that the device wasn't mounted by hal (but by the system)
reason = i18n("Permissions denied");
@@ -1319,16 +1640,29 @@ QString HALBackend::unmount(const QString &_udi)
reason = error.message;
}
qerror += "<p><b>" + reason + "</b></p>";
+ origqerror = qerror;
// Include list of processes (if any) using the device in the error message
reason = listUsingProcesses(medium);
if (!reason.isEmpty()) {
qerror += reason;
+ if (thisunmounthasfailed == 2) { // Failed as BUSY
+ if (KMessageBox::warningYesNo(0, i18n("%1<p><b>Would you like to forcibly terminate these processes?</b><br><i>All unsaved data would be lost</i>").arg(qerror)) == KMessageBox::Yes) {
+ qerror = origqerror;
+ reason = killUsingProcesses(medium);
+ qerror = HALBackend::unmount(udi);
+ if (qerror.isNull()) {
+ thisunmounthasfailed = 0;
+ }
+ }
+ }
}
- dbus_message_unref (dmesg);
- dbus_error_free (&error);
- return qerror;
+ if (thisunmounthasfailed != 0) {
+ dbus_message_unref (dmesg);
+ dbus_error_free (&error);
+ return qerror;
+ }
}
kdDebug() << "unmount queued for " << udi << endl;
@@ -1337,8 +1671,117 @@ QString HALBackend::unmount(const QString &_udi)
dbus_message_unref (reply);
medium->setHalMounted(false);
+ ResetProperties(medium->id().latin1());
+
+ while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ;
+
+ return QString();
+}
+
+QString HALBackend::decrypt(const QString &_udi, const QString &password)
+{
+ const Medium* medium = m_mediaList.findById(_udi);
+ if (!medium)
+ return i18n("No such medium: %1").arg(_udi);
+
+ if (!medium->isEncrypted() || !medium->clearDeviceUdi().isNull())
+ return QString();
+
+ const char *udi = medium->id().latin1();
+ DBusMessage *msg = NULL;
+ DBusMessage *reply = NULL;
+ DBusError error;
+
+ kdDebug() << "Setting up " << udi << " for crypto\n" <<endl;
+
+ msg = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device.Volume.Crypto",
+ "Setup");
+ if (msg == NULL) {
+ kdDebug() << "decrypt failed for " << udi << ": could not create dbus message\n";
+ return i18n("Internal Error");
+ }
+
+ QCString pwdUtf8 = password.utf8();
+ const char *pwd_utf8 = pwdUtf8;
+ if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &pwd_utf8, DBUS_TYPE_INVALID)) {
+ kdDebug() << "decrypt failed for " << udi << ": could not append args to dbus message\n";
+ dbus_message_unref (msg);
+ return i18n("Internal Error");
+ }
+
+ dbus_error_init (&error);
+ if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, msg, -1, &error)) ||
+ dbus_error_is_set (&error))
+ {
+ QString qerror = i18n("Internal Error");
+ kdDebug() << "decrypt failed for " << udi << ": " << error.name << " " << error.message << endl;
+ if (strcmp (error.name, "org.freedesktop.Hal.Device.Volume.Crypto.SetupPasswordError") == 0) {
+ qerror = i18n("Wrong password");
+ }
+ dbus_error_free (&error);
+ dbus_message_unref (msg);
+ while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ;
+ return qerror;
+ }
+
+ dbus_message_unref (msg);
+ dbus_message_unref (reply);
+
+ while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ;
+
+ return QString();
+}
+
+QString HALBackend::undecrypt(const QString &_udi)
+{
+ const Medium* medium = m_mediaList.findById(_udi);
+ if (!medium)
+ return i18n("No such medium: %1").arg(_udi);
+
+ if (!medium->isEncrypted() || medium->clearDeviceUdi().isNull())
+ return QString();
+
+ const char *udi = medium->id().latin1();
+ DBusMessage *msg = NULL;
+ DBusMessage *reply = NULL;
+ DBusError error;
+
+ kdDebug() << "Tear down " << udi << "\n" <<endl;
+
+ msg = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device.Volume.Crypto",
+ "Teardown");
+ if (msg == NULL) {
+ kdDebug() << "teardown failed for " << udi << ": could not create dbus message\n";
+ return i18n("Internal Error");
+ }
+
+ if (!dbus_message_append_args (msg, DBUS_TYPE_INVALID)) {
+ kdDebug() << "teardown failed for " << udi << ": could not append args to dbus message\n";
+ dbus_message_unref (msg);
+ return i18n("Internal Error");
+ }
+
+ dbus_error_init (&error);
+ if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, msg, -1, &error)) ||
+ dbus_error_is_set (&error))
+ {
+ QString qerror = i18n("Internal Error");
+ kdDebug() << "teardown failed for " << udi << ": " << error.name << " " << error.message << endl;
+ dbus_error_free (&error);
+ dbus_message_unref (msg);
+ while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ;
+ return qerror;
+ }
+
+ dbus_message_unref (msg);
+ dbus_message_unref (reply);
+
ResetProperties(udi);
+ while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ;
+
return QString();
}
diff --git a/kioslave/media/mediamanager/halbackend.h b/kioslave/media/mediamanager/halbackend.h
index 31c682374..c5bdd532c 100644
--- a/kioslave/media/mediamanager/halbackend.h
+++ b/kioslave/media/mediamanager/halbackend.h
@@ -85,6 +85,8 @@ public:
QString mount(const QString &id);
QString mount(const Medium *medium);
QString unmount(const QString &id);
+ QString decrypt(const QString &id, const QString &password);
+ QString undecrypt(const QString &id);
private:
/**
@@ -143,6 +145,7 @@ private:
QString generateName(const QString &devNode);
static QString isInFstab(const Medium *medium);
static QString listUsingProcesses(const Medium *medium);
+ static QString killUsingProcesses(const Medium *medium);
private slots:
void slotResult(KIO::Job *job);
diff --git a/kioslave/media/mediamanager/medialist.cpp b/kioslave/media/mediamanager/medialist.cpp
index fed6091fb..974eddbf6 100644
--- a/kioslave/media/mediamanager/medialist.cpp
+++ b/kioslave/media/mediamanager/medialist.cpp
@@ -52,6 +52,18 @@ const Medium *MediaList::findByName(const QString &name) const
return m_nameMap[name];
}
+const Medium *MediaList::findByClearUdi(const QString &name)
+{
+ kdDebug(1219) << "MediaList::findByClearUdi(" << name << ")" << endl;
+
+ Medium *medium;
+ for (medium = m_media.first(); medium; medium = m_media.next()) {
+ if (medium->clearDeviceUdi() == name) return medium;
+ }
+
+ return 0L;
+}
+
QString MediaList::addMedium(Medium *medium, bool allowNotification)
{
@@ -121,11 +133,12 @@ bool MediaList::changeMediumState(const Medium &medium, bool allowNotification)
if ( medium.isMountable() )
{
QString device_node = medium.deviceNode();
+ QString clear_device_udi = medium.clearDeviceUdi();
QString mount_point = medium.mountPoint();
QString fs_type = medium.fsType();
bool mounted = medium.isMounted();
- m->mountableState( device_node, mount_point,
+ m->mountableState( device_node, clear_device_udi, mount_point,
fs_type, mounted );
}
else
diff --git a/kioslave/media/mediamanager/medialist.h b/kioslave/media/mediamanager/medialist.h
index 590491b0c..4de333875 100644
--- a/kioslave/media/mediamanager/medialist.h
+++ b/kioslave/media/mediamanager/medialist.h
@@ -34,6 +34,7 @@ public:
const QPtrList<Medium> list() const;
const Medium *findById(const QString &id) const;
const Medium *findByName(const QString &name) const;
+ const Medium *findByClearUdi(const QString &name);
public:
QString addMedium(Medium *medium, bool allowNotification = true);
diff --git a/kioslave/media/mediamanager/mediamanager.cpp b/kioslave/media/mediamanager/mediamanager.cpp
index ad8f1b447..f1569e817 100644
--- a/kioslave/media/mediamanager/mediamanager.cpp
+++ b/kioslave/media/mediamanager/mediamanager.cpp
@@ -232,6 +232,28 @@ QString MediaManager::unmount(const QString &name)
#endif
}
+QString MediaManager::decrypt(const QString &name, const QString &password)
+{
+#ifdef COMPILE_HALBACKEND
+ if (!m_halbackend)
+ return i18n("Feature only available with HAL");
+ return m_halbackend->decrypt(name, password);
+#else
+ return i18n("Feature only available with HAL");
+#endif
+}
+
+QString MediaManager::undecrypt(const QString &name)
+{
+#ifdef COMPILE_HALBACKEND
+ if (!m_halbackend)
+ return i18n("Feature only available with HAL");
+ return m_halbackend->undecrypt(name);
+#else
+ return i18n("Feature only available with HAL");
+#endif
+}
+
QString MediaManager::nameForLabel(const QString &label)
{
const QPtrList<Medium> media = m_mediaList.list();
diff --git a/kioslave/media/mediamanager/mediamanager.h b/kioslave/media/mediamanager/mediamanager.h
index 1e5aa1d84..36942362d 100644
--- a/kioslave/media/mediamanager/mediamanager.h
+++ b/kioslave/media/mediamanager/mediamanager.h
@@ -47,6 +47,8 @@ k_dcop:
QString mount(const QString &uid);
QString unmount(const QString &uid);
+ QString decrypt(const QString &uid, const QString &password);
+ QString undecrypt(const QString &uid);
QString nameForLabel(const QString &label);
ASYNC setUserLabel(const QString &name, const QString &label);
diff --git a/kioslave/media/medianotifier/medianotifier.cpp b/kioslave/media/medianotifier/medianotifier.cpp
index 98a474ba7..ce39215d9 100644
--- a/kioslave/media/medianotifier/medianotifier.cpp
+++ b/kioslave/media/medianotifier/medianotifier.cpp
@@ -19,8 +19,12 @@
#include "medianotifier.h"
+#include <sys/vfs.h>
+
#include <qfile.h>
#include <qfileinfo.h>
+#include <qdir.h>
+#include <qcheckbox.h>
#include <kapplication.h>
#include <kglobal.h>
@@ -44,6 +48,11 @@ MediaNotifier::MediaNotifier(const QCString &name) : KDEDModule(name)
connectDCOPSignal( "kded", "mediamanager", "mediumChanged(QString, bool)",
"onMediumChange(QString, bool)", true );
+
+ m_freeTimer = new QTimer( this );
+ connect( m_freeTimer, SIGNAL( timeout() ), SLOT( checkFreeDiskSpace() ) );
+ m_freeTimer->start( 1000*6*2 /* 20 minutes */ );
+ m_freeDialog = 0;
}
MediaNotifier::~MediaNotifier()
@@ -103,12 +112,12 @@ bool MediaNotifier::autostart( const KFileItem &medium )
{
QString mimetype = medium.mimetype();
- bool is_cdrom = mimetype.startsWith( "cd" ) || mimetype.startsWith( "dvd" );
- bool is_mounted = mimetype.endsWith( "_mounted" );
+ bool is_cdrom = mimetype.startsWith( "media/cd" ) || mimetype.startsWith( "media/dvd" );
+ bool is_mounted = mimetype.contains( "_mounted" );
// We autorun only on CD/DVD or removable disks (USB, Firewire)
if ( !( is_cdrom || is_mounted )
- && mimetype!="media/removable_mounted" )
+ && !mimetype.startsWith("media/removable_mounted") )
{
return false;
}
@@ -309,4 +318,69 @@ extern "C"
}
}
+void MediaNotifier::checkFreeDiskSpace()
+{
+ struct statfs sfs;
+ long total, avail;
+ if ( m_freeDialog )
+ return;
+
+ if ( statfs( QFile::encodeName( QDir::homeDirPath() ), &sfs ) == 0 )
+ {
+ total = sfs.f_blocks;
+ avail = ( getuid() ? sfs.f_bavail : sfs.f_bfree );
+
+ if (avail < 0 || total <= 0)
+ return; // we better do not say anything about it
+
+ int freeperc = static_cast<int>(100 * double(avail) / total);
+
+ if ( freeperc < 5 && KMessageBox::shouldBeShownContinue( "dontagainfreespace" ) ) // free disk space dropped under a limit
+ {
+ m_freeDialog= new KDialogBase(
+ i18n( "Low Disk Space" ),
+ KDialogBase::Yes | KDialogBase::No,
+ KDialogBase::Yes, KDialogBase::No,
+ 0, "warningYesNo", false, true,
+ i18n( "Start Konqueror" ), KStdGuiItem::cancel());
+
+ QString text = i18n( "You are running low on disk space on your home partition (currently %1% free), would you like to "
+ "run Konqueror to free some disk space and fix the problem?" ).arg( freeperc );
+ bool checkboxResult = false;
+ KMessageBox::createKMessageBox(m_freeDialog, QMessageBox::Warning, text, QStringList(),
+ i18n("Do not ask again"),
+ &checkboxResult, KMessageBox::Notify | KMessageBox::NoExec);
+ m_freeDialog->show();
+ connect( m_freeDialog, SIGNAL( yesClicked() ), SLOT( slotFreeContinue() ) );
+ connect( m_freeDialog, SIGNAL( noClicked() ), SLOT( slotFreeCancel() ) );
+ }
+ }
+}
+
+void MediaNotifier::slotFreeContinue()
+{
+ slotFreeFinished( KMessageBox::Continue );
+}
+
+void MediaNotifier::slotFreeCancel()
+{
+ slotFreeFinished( KMessageBox::Cancel );
+}
+
+void MediaNotifier::slotFreeFinished( KMessageBox::ButtonCode res )
+{
+ QCheckBox *checkbox = ::qt_cast<QCheckBox*>( m_freeDialog->child( 0, "QCheckBox" ) );
+ if ( checkbox && checkbox->isChecked() )
+ KMessageBox::saveDontShowAgainYesNo("dontagainfreespace", res);
+ m_freeDialog->delayedDestruct();
+ m_freeDialog = 0;
+
+ if ( res == KMessageBox::Continue ) // start Konqi
+ {
+ ( void ) new KRun( KURL::fromPathOrURL( QDir::homeDirPath() ) );
+ }
+ else // people don't want to be bothered, at least stop the timer; there's no way to save the dontshowagain entry in this case
+ m_freeTimer->stop();
+}
+
#include "medianotifier.moc"
diff --git a/kioslave/media/medianotifier/medianotifier.h b/kioslave/media/medianotifier/medianotifier.h
index c3e4b9bf9..e070ac7ac 100644
--- a/kioslave/media/medianotifier/medianotifier.h
+++ b/kioslave/media/medianotifier/medianotifier.h
@@ -23,10 +23,13 @@
#include <kdedmodule.h>
#include <kfileitem.h>
#include <kio/job.h>
+#include <kmessagebox.h>
#include <qstring.h>
#include <qmap.h>
+class KDialogBase;
+
class MediaNotifier: public KDEDModule
{
Q_OBJECT
@@ -41,6 +44,10 @@ k_dcop:
private slots:
void slotStatResult( KIO::Job *job );
+ void checkFreeDiskSpace();
+ void slotFreeFinished( KMessageBox::ButtonCode );
+ void slotFreeContinue();
+ void slotFreeCancel();
private:
bool autostart( const KFileItem &medium );
@@ -52,6 +59,8 @@ private:
const QString &autoopenFile );
QMap<KIO::Job*,bool> m_allowNotificationMap;
+ QTimer * m_freeTimer;
+ KDialogBase * m_freeDialog;
};
#endif
diff --git a/kioslave/media/mimetypes/Makefile.am b/kioslave/media/mimetypes/Makefile.am
index 25c718035..cdb66a1ac 100644
--- a/kioslave/media/mimetypes/Makefile.am
+++ b/kioslave/media/mimetypes/Makefile.am
@@ -4,10 +4,20 @@ mimetype_DATA = floppy_mounted.desktop floppy_unmounted.desktop \
floppy5_unmounted.desktop floppy5_mounted.desktop \
zip_mounted.desktop zip_unmounted.desktop \
hdd_mounted.desktop hdd_unmounted.desktop \
+ hdd_mounted_decrypted.desktop hdd_unmounted_encrypted.desktop \
+ hdd_unmounted_decrypted.desktop \
removable_mounted.desktop removable_unmounted.desktop \
+ removable_mounted_decrypted.desktop removable_unmounted_encrypted.desktop \
+ removable_unmounted_decrypted.desktop \
cdrom_mounted.desktop cdrom_unmounted.desktop \
+ cdrom_mounted_decrypted.desktop cdrom_unmounted_encrypted.desktop \
+ cdrom_unmounted_decrypted.desktop \
dvd_mounted.desktop dvd_unmounted.desktop \
+ dvd_mounted_decrypted.desktop dvd_unmounted_encrypted.desktop \
+ dvd_unmounted_decrypted.desktop \
cdwriter_mounted.desktop cdwriter_unmounted.desktop \
+ cdwriter_mounted_decrypted.desktop cdwriter_unmounted_encrypted.desktop \
+ cdwriter_unmounted_decrypted.desktop \
smb_mounted.desktop smb_unmounted.desktop \
nfs_mounted.desktop nfs_unmounted.desktop \
audiocd.desktop \
diff --git a/kioslave/media/mimetypes/cdrom_mounted_decrypted.desktop b/kioslave/media/mimetypes/cdrom_mounted_decrypted.desktop
new file mode 100644
index 000000000..2729ff4f5
--- /dev/null
+++ b/kioslave/media/mimetypes/cdrom_mounted_decrypted.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Icon=cdrom_mount_decrypt
+Type=MimeType
+MimeType=media/cdrom_mounted_decrypted
+Comment=Mounted Decrypted CD-ROM
+Comment[de]=Eingebundene, entschlüsselte CD-ROM
+Patterns=
+
+X-KDE-AutoEmbed=true
+X-KDE-IsAlso=inode/directory
diff --git a/kioslave/media/mimetypes/cdrom_unmounted_decrypted.desktop b/kioslave/media/mimetypes/cdrom_unmounted_decrypted.desktop
new file mode 100644
index 000000000..d6b2be0c2
--- /dev/null
+++ b/kioslave/media/mimetypes/cdrom_unmounted_decrypted.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Icon=cdrom_unmount_decrypt
+Type=MimeType
+MimeType=media/cdrom_unmounted_decrypted
+Comment=Unmounted Decrypted CD-ROM
+Comment[de]=Nicht eingebundene, entschlüsselte CD-ROM
+Patterns=
+
+X-KDE-AutoEmbed=true
+X-KDE-IsAlso=inode/directory
diff --git a/kioslave/media/mimetypes/cdrom_unmounted_encrypted.desktop b/kioslave/media/mimetypes/cdrom_unmounted_encrypted.desktop
new file mode 100644
index 000000000..95fa31b3b
--- /dev/null
+++ b/kioslave/media/mimetypes/cdrom_unmounted_encrypted.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Icon=cdrom_unmount_encrypt
+Type=MimeType
+MimeType=media/cdrom_unmounted_encrypted
+Comment=Unmounted Encrypted CD-ROM
+Comment[de]=Nicht eingebundene, verschlüsselte CD-ROM
+Patterns=
+
+X-KDE-AutoEmbed=true
+X-KDE-IsAlso=inode/directory
diff --git a/kioslave/media/mimetypes/cdwriter_mounted_decrypted.desktop b/kioslave/media/mimetypes/cdwriter_mounted_decrypted.desktop
new file mode 100644
index 000000000..b831be152
--- /dev/null
+++ b/kioslave/media/mimetypes/cdwriter_mounted_decrypted.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Icon=cdwriter_mount_decrypt
+Type=MimeType
+MimeType=media/cdwriter_mounted_decrypted
+Comment=Mounted Decrypted CD Writer
+Comment[de]=Eingebundener, entschlüsselter CD-Brenner
+Patterns=
+
+X-KDE-AutoEmbed=true
+X-KDE-IsAlso=inode/directory
diff --git a/kioslave/media/mimetypes/cdwriter_unmounted_decrypted.desktop b/kioslave/media/mimetypes/cdwriter_unmounted_decrypted.desktop
new file mode 100644
index 000000000..48f49ccb4
--- /dev/null
+++ b/kioslave/media/mimetypes/cdwriter_unmounted_decrypted.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Icon=cdwriter_unmount_decrypt
+Type=MimeType
+MimeType=media/cdwriter_unmounted_decrypted
+Comment=Unmounted Decrypted CD Writer
+Comment[de]=Nicht eingebundener, entschlüsselter CD-Brenner
+Patterns=
+
+X-KDE-AutoEmbed=true
+X-KDE-IsAlso=inode/directory
diff --git a/kioslave/media/mimetypes/cdwriter_unmounted_encrypted.desktop b/kioslave/media/mimetypes/cdwriter_unmounted_encrypted.desktop
new file mode 100644
index 000000000..c31e66089
--- /dev/null
+++ b/kioslave/media/mimetypes/cdwriter_unmounted_encrypted.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Icon=cdwriter_unmount_encrypt
+Type=MimeType
+MimeType=media/cdwriter_unmounted_encrypted
+Comment=Unmounted Encrypted CD Writer
+Comment[de]=Nicht eingebundener, entschlüsselter CD-Brenner
+Patterns=
+
+X-KDE-AutoEmbed=true
+X-KDE-IsAlso=inode/directory
diff --git a/kioslave/media/mimetypes/dvd_mounted_decrypted.desktop b/kioslave/media/mimetypes/dvd_mounted_decrypted.desktop
new file mode 100644
index 000000000..22a90b52d
--- /dev/null
+++ b/kioslave/media/mimetypes/dvd_mounted_decrypted.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Icon=dvd_mount_decrypt
+Type=MimeType
+MimeType=media/dvd_mounted_decrypted
+Comment=Mounted Decrypted DVD
+Comment[de]=Eingebundene, entschlüsselte DVD
+Patterns=
+
+X-KDE-AutoEmbed=true
+X-KDE-IsAlso=inode/directory
diff --git a/kioslave/media/mimetypes/dvd_unmounted_decrypted.desktop b/kioslave/media/mimetypes/dvd_unmounted_decrypted.desktop
new file mode 100644
index 000000000..129f3f177
--- /dev/null
+++ b/kioslave/media/mimetypes/dvd_unmounted_decrypted.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Icon=dvd_unmount_decrypt
+Type=MimeType
+MimeType=media/dvd_unmounted_decrypted
+Comment=Unmounted Decrypted DVD
+Comment[de]=Nicht eingebundene, entschlüsselte DVD
+Patterns=
+
+X-KDE-AutoEmbed=true
+X-KDE-IsAlso=inode/directory
diff --git a/kioslave/media/mimetypes/dvd_unmounted_encrypted.desktop b/kioslave/media/mimetypes/dvd_unmounted_encrypted.desktop
new file mode 100644
index 000000000..23d2353b5
--- /dev/null
+++ b/kioslave/media/mimetypes/dvd_unmounted_encrypted.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Icon=dvd_unmount_encrypt
+Type=MimeType
+MimeType=media/dvd_unmounted_encrypted
+Comment=Unmounted Encrypted DVD
+Comment[de]=Nicht eingebundene, verschlüsselte DVD
+Patterns=
+
+X-KDE-AutoEmbed=true
+X-KDE-IsAlso=inode/directory
diff --git a/kioslave/media/mimetypes/hdd_mounted_decrypted.desktop b/kioslave/media/mimetypes/hdd_mounted_decrypted.desktop
new file mode 100644
index 000000000..f4b1c1749
--- /dev/null
+++ b/kioslave/media/mimetypes/hdd_mounted_decrypted.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Icon=hdd_mount_decrypt
+Type=MimeType
+MimeType=media/hdd_mounted_decrypted
+Comment=Mounted Decrypted Hard Disk Volume
+Comment[de]=Eingebundene, entschlüsselte Festplattenpartition
+Patterns=
+
+X-KDE-AutoEmbed=true
+X-KDE-IsAlso=inode/directory
diff --git a/kioslave/media/mimetypes/hdd_unmounted_decrypted.desktop b/kioslave/media/mimetypes/hdd_unmounted_decrypted.desktop
new file mode 100644
index 000000000..f41411314
--- /dev/null
+++ b/kioslave/media/mimetypes/hdd_unmounted_decrypted.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Icon=hdd_unmount_decrypt
+Type=MimeType
+MimeType=media/hdd_unmounted_decrypted
+Comment=Unmounted Decrypted Hard Disk Volume
+Comment[de]=Nicht eingebundene, entschlüsselte Festplattenpartition
+Patterns=
+
+X-KDE-AutoEmbed=true
+X-KDE-IsAlso=inode/directory
diff --git a/kioslave/media/mimetypes/hdd_unmounted_encrypted.desktop b/kioslave/media/mimetypes/hdd_unmounted_encrypted.desktop
new file mode 100644
index 000000000..60e277811
--- /dev/null
+++ b/kioslave/media/mimetypes/hdd_unmounted_encrypted.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Icon=hdd_unmount_encrypt
+Type=MimeType
+MimeType=media/hdd_unmounted_encrypted
+Comment=Unmounted Encrypted Hard Disk Volume
+Comment[de]=Nicht eingebundene, verschlüsselte Festplattenpartition
+Patterns=
+
+X-KDE-AutoEmbed=true
+X-KDE-IsAlso=inode/directory
diff --git a/kioslave/media/mimetypes/removable_mounted_decrypted.desktop b/kioslave/media/mimetypes/removable_mounted_decrypted.desktop
new file mode 100644
index 000000000..6a025119d
--- /dev/null
+++ b/kioslave/media/mimetypes/removable_mounted_decrypted.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Icon=usbpendrive_mount_decrypt
+Type=MimeType
+MimeType=media/removable_mounted_decrypted
+Comment=Mounted Decrypted Removable Medium
+Comment[de]=Eingebundenes, entschlüsseltes Wechsellaufwerk
+Patterns=
+
+X-KDE-AutoEmbed=true
+X-KDE-IsAlso=inode/directory
diff --git a/kioslave/media/mimetypes/removable_unmounted_decrypted.desktop b/kioslave/media/mimetypes/removable_unmounted_decrypted.desktop
new file mode 100644
index 000000000..fe3ecd6a8
--- /dev/null
+++ b/kioslave/media/mimetypes/removable_unmounted_decrypted.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Icon=usbpendrive_unmount_decrypt
+Type=MimeType
+MimeType=media/removable_unmounted_decrypted
+Comment=Unmounted Decrypted Removable Medium
+Comment[de]=Nicht eingebundenes, entschlüsseltes Wechsellaufwerk
+Patterns=
+
+X-KDE-AutoEmbed=true
+X-KDE-IsAlso=inode/directory
diff --git a/kioslave/media/mimetypes/removable_unmounted_encrypted.desktop b/kioslave/media/mimetypes/removable_unmounted_encrypted.desktop
new file mode 100644
index 000000000..e2949bfed
--- /dev/null
+++ b/kioslave/media/mimetypes/removable_unmounted_encrypted.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Icon=usbpendrive_unmount_encrypt
+Type=MimeType
+MimeType=media/removable_unmounted_encrypted
+Comment=Unmounted Encrypted Removable Medium
+Comment[de]=Nicht eingebundenes, verschlüsseltes Wechsellaufwerk
+Patterns=
+
+X-KDE-AutoEmbed=true
+X-KDE-IsAlso=inode/directory
diff --git a/kioslave/media/mounthelper/Makefile.am b/kioslave/media/mounthelper/Makefile.am
index 9080ba81a..9c03ba688 100644
--- a/kioslave/media/mounthelper/Makefile.am
+++ b/kioslave/media/mounthelper/Makefile.am
@@ -3,10 +3,10 @@ bin_PROGRAMS = kio_media_mounthelper
INCLUDES = -I$(srcdir)/../libmediacommon $(all_includes)
AM_LDFLAGS = $(all_libraries)
-kio_media_mounthelper_SOURCES = kio_media_mounthelper.cpp
+kio_media_mounthelper_SOURCES = kio_media_mounthelper.cpp decryptdialog.ui dialog.cpp
kio_media_mounthelper_LDFLAGS = $(KDE_RPATH) $(all_libraries)
-kio_media_mounthelper_LDADD = ../libmediacommon/libmediacommon.la $(LIB_KIO)
+kio_media_mounthelper_LDADD = ../libmediacommon/libmediacommon.la $(LIB_KIO) $(LIB_KDEUI)
METASOURCES = AUTO
diff --git a/kioslave/media/mounthelper/decryptdialog.ui b/kioslave/media/mounthelper/decryptdialog.ui
new file mode 100644
index 000000000..15790c8ef
--- /dev/null
+++ b/kioslave/media/mounthelper/decryptdialog.ui
@@ -0,0 +1,201 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>DecryptDialog</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>DecryptDialog</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>207</width>
+ <height>172</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>Decrypting Storage Device</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>encryptedIcon</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>48</width>
+ <height>48</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ <property name="alignment">
+ <set>AlignTop</set>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>31</width>
+ <height>41</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>descLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;&lt;b&gt;%1&lt;/b&gt; is an encrypted storage device.&lt;/p&gt;
+&lt;p&gt;Please enter the password to decrypt the storage device.&lt;/p&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignTop</set>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Password:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>passwordEdit</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>passwordEdit</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="echoMode">
+ <enum>Password</enum>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QGroupBox" row="2" column="0">
+ <property name="name">
+ <cstring>errorBox</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Error</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>errorLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignTop</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kioslave/media/mounthelper/dialog.cpp b/kioslave/media/mounthelper/dialog.cpp
new file mode 100644
index 000000000..74bcfb388
--- /dev/null
+++ b/kioslave/media/mounthelper/dialog.cpp
@@ -0,0 +1,68 @@
+/* This file is part of the KDE project
+ * Copyright (C) 2007 Jan Klötzke <jan kloetzke at freenet de>
+ *
+ * Based on kryptomedia- Another KDE cryto media application.
+ * Copyright (C) 2006 Daniel Gollub <dgollub@suse.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "dialog.h"
+
+Dialog::Dialog(QString url, QString iconName) :
+ KDialogBase(NULL, "Dialog", true, "Decrypt Storage Device", (Cancel|User1), User1, false, KGuiItem(i18n("Decrypt"), "decrypted" ))
+{
+ decryptDialog = new DecryptDialog(this);
+
+ decryptDialog->errorBox->hide();
+ decryptDialog->descLabel->setText(decryptDialog->descLabel->text().arg(url));
+ decryptDialog->descLabel->adjustSize();
+ decryptDialog->adjustSize();
+
+ enableButton( User1, false );
+
+ QPixmap pixmap = KGlobal::iconLoader()->loadIcon(iconName, KIcon::NoGroup, KIcon::SizeLarge);
+ decryptDialog->encryptedIcon->setPixmap( pixmap );
+
+ connect(decryptDialog->passwordEdit, SIGNAL (textChanged(const QString &)), this, SLOT (slotPasswordChanged(const QString &)));
+
+ setMainWidget(decryptDialog);
+}
+
+Dialog::~Dialog()
+{
+ delete decryptDialog;
+}
+
+QString Dialog::getPassword()
+{
+ return decryptDialog->passwordEdit->text();
+}
+
+void Dialog::slotDialogError(QString errorMsg)
+{
+ kdDebug() << __func__ << "(" << errorMsg << " )" << endl;
+
+ decryptDialog->errorLabel->setText(QString("<b>%1</b>").arg(errorMsg));
+ decryptDialog->errorBox->show();
+}
+
+void Dialog::slotPasswordChanged(const QString &text)
+{
+ enableButton( User1, !text.isEmpty() );
+}
+
+#include "dialog.moc"
diff --git a/kioslave/media/mounthelper/dialog.h b/kioslave/media/mounthelper/dialog.h
new file mode 100644
index 000000000..1f544c370
--- /dev/null
+++ b/kioslave/media/mounthelper/dialog.h
@@ -0,0 +1,61 @@
+/* This file is part of the KDE project
+ * Copyright (C) 2007 Jan Klötzke <jan kloetzke at freenet de>
+ *
+ * Based on kryptomedia- Another KDE cryto media application.
+ * Copyright (C) 2006 Daniel Gollub <dgollub@suse.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef DIALOG_H_
+#define DIALOG_H_
+
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kdialogbase.h>
+#include <kiconloader.h>
+
+#include <qlineedit.h>
+#include <qlabel.h>
+#include <qgroupbox.h>
+
+#include "decryptdialog.h"
+
+class KryptoMedia;
+
+class Dialog : public KDialogBase
+{
+
+Q_OBJECT
+
+public:
+ Dialog(QString url, QString iconName);
+ ~Dialog();
+
+ QString getPassword();
+
+public slots:
+ void slotDialogError(QString errorMsg);
+ void slotPasswordChanged(const QString &text);
+
+private:
+ DecryptDialog *decryptDialog;
+};
+
+#endif // DIALOG_H_
+
diff --git a/kioslave/media/mounthelper/kio_media_mounthelper.cpp b/kioslave/media/mounthelper/kio_media_mounthelper.cpp
index 12743847f..5dae9e0d3 100644
--- a/kioslave/media/mounthelper/kio_media_mounthelper.cpp
+++ b/kioslave/media/mounthelper/kio_media_mounthelper.cpp
@@ -32,7 +32,9 @@
#include <kglobal.h>
#include <kprocess.h>
#include <kstartupinfo.h>
+#include <kmimetype.h>
+#include "dialog.h"
#include "kio_media_mounthelper.h"
const Medium MountHelper::findMedium(const KURL &url)
@@ -63,7 +65,7 @@ MountHelper::MountHelper() : KApplication()
{
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
- m_errorStr = "";
+ m_errorStr = QString::null;
KURL url(args->url(0));
const Medium medium = findMedium(url);
@@ -89,7 +91,37 @@ MountHelper::MountHelper() : KApplication()
m_isCdrom = medium.mimeType().find("dvd")!=-1
|| medium.mimeType().find("cd")!=-1;
- if (args->isSet("u"))
+ if (args->isSet("d"))
+ {
+ if (!medium.isEncrypted())
+ {
+ m_errorStr = i18n("%1 is not an encrypted media.").arg(url.prettyURL());
+ QTimer::singleShot(0, this, SLOT(error()) );
+ return;
+ }
+ if (!medium.needDecryption())
+ {
+ m_errorStr = i18n("%1 is already decrypted.").arg(url.prettyURL());
+ QTimer::singleShot(0, this, SLOT(error()) );
+ return;
+ }
+
+ QString iconName = medium.iconName();
+ if (iconName.isEmpty())
+ {
+ QString mime = medium.mimeType();
+ iconName = KMimeType::mimeType(mime)->icon(mime, false);
+ }
+
+ m_mediumId = medium.id();
+ dialog = new Dialog(url.prettyURL(), iconName);
+ dialog->show();
+
+ connect(dialog, SIGNAL (user1Clicked()), this, SLOT (slotSendPassword()));
+ connect(dialog, SIGNAL (cancelClicked()), this, SLOT (slotCancel()));
+ connect(this, SIGNAL (signalPasswordError(QString)), dialog, SLOT (slotDialogError(QString)));
+ }
+ else if (args->isSet("u"))
{
DCOPRef mediamanager("kded", "mediamanager");
DCOPReply reply = mediamanager.call( "unmount", medium.id());
@@ -103,6 +135,8 @@ MountHelper::MountHelper() : KApplication()
}
else if (args->isSet("s") || args->isSet("e"))
{
+ DCOPRef mediamanager("kded", "mediamanager");
+
/*
* We want to call mediamanager unmount before invoking eject. That's
* because unmount would provide an informative error message in case of
@@ -114,17 +148,24 @@ MountHelper::MountHelper() : KApplication()
*/
if (medium.isMounted())
{
- DCOPRef mediamanager("kded", "mediamanager");
DCOPReply reply = mediamanager.call( "unmount", medium.id());
if (reply.isValid())
reply.get(m_errorStr);
- if (m_errorStr.isNull())
- invokeEject(device, true);
- else
- error();
- m_device = device;
- } else
- invokeEject(device, true);
+ }
+
+ /* If this is a decrypted volume and there is no error yet
+ * we try to teardown the decryption */
+ if (m_errorStr.isNull() && medium.isEncrypted() && !medium.clearDeviceUdi().isNull())
+ {
+ DCOPReply reply = mediamanager.call( "undecrypt", medium.id());
+ if (reply.isValid())
+ reply.get(m_errorStr);
+ }
+
+ if (m_errorStr.isNull())
+ invokeEject(device, true);
+ else
+ error();
}
else
{
@@ -167,7 +208,9 @@ void MountHelper::ejectFinished(KProcess* proc)
else
m_errorStr = i18n("The device was successfully unmounted, but could not be ejected");
}
- QTimer::singleShot(0, this, SLOT(error()));
+//X Comment this because the error is useless as long as the unmount is successfull.
+//X QTimer::singleShot(0, this, SLOT(error()));
+ ::exit(0);
}
}
@@ -177,8 +220,32 @@ void MountHelper::error()
::exit(1);
}
+void MountHelper::slotSendPassword()
+{
+ DCOPRef mediamanager("kded", "mediamanager");
+
+ DCOPReply reply = mediamanager.call( "decrypt", m_mediumId, dialog->getPassword() );
+ if (!reply.isValid()) {
+ m_errorStr = i18n("The KDE mediamanager is not running.");
+ error();
+ } else {
+ QString errorMsg = reply;
+ if (errorMsg.isNull()) {
+ exit(0);
+ } else {
+ emit signalPasswordError(errorMsg);
+ }
+ }
+}
+
+void MountHelper::slotCancel()
+{
+ exit(0);
+}
+
static KCmdLineOptions options[] =
{
+ { "d", I18N_NOOP("Decrypt given URL"), 0 },
{ "u", I18N_NOOP("Unmount given URL"), 0 },
{ "m", I18N_NOOP("Mount given URL (default)"), 0 },
{ "e", I18N_NOOP("Eject given URL via kdeeject"), 0},
diff --git a/kioslave/media/mounthelper/kio_media_mounthelper.h b/kioslave/media/mounthelper/kio_media_mounthelper.h
index 478d802f9..ed5884d4f 100644
--- a/kioslave/media/mounthelper/kio_media_mounthelper.h
+++ b/kioslave/media/mounthelper/kio_media_mounthelper.h
@@ -28,6 +28,8 @@
#include "medium.h"
+class Dialog;
+
class MountHelper : public KApplication
{
Q_OBJECT
@@ -38,12 +40,18 @@ private:
const Medium findMedium(const KURL &url);
void invokeEject(const QString &device, bool quiet=false);
QString m_errorStr;
- QString m_device;
bool m_isCdrom;
+ QString m_mediumId;
+ Dialog *dialog;
private slots:
+ void slotSendPassword();
+ void slotCancel();
void ejectFinished(KProcess* proc);
void error();
+
+signals:
+ void signalPasswordError(QString errorMsg);
};
#endif
diff --git a/kioslave/media/propsdlgplugin/media_propsdlgplugin.desktop b/kioslave/media/propsdlgplugin/media_propsdlgplugin.desktop
index c0cdcbbba..d5e13eda5 100644
--- a/kioslave/media/propsdlgplugin/media_propsdlgplugin.desktop
+++ b/kioslave/media/propsdlgplugin/media_propsdlgplugin.desktop
@@ -99,4 +99,4 @@ Comment[wa]=Tchôke-divins di dvize di prôpietés Konqueror po-z apontyî l' du
Comment[zh_CN]=配置挂载行为的 Konqueror 属性对话框插件
Comment[zh_TW]=Konqueror 內容對話框外掛程式,用於設定掛載的行為
X-KDE-Library=media_propsdlgplugin
-ServiceTypes=KPropsDlg/Plugin,media/audiocd,media/hdd_mounted,media/hdd_unmounted,media/cdrom_mounted,media/cdrom_unmounted,media/cdwriter_mounted,media/nfs_mounted,media/cdwriter_unmounted,media/nfs_unmounted,media/removable_mounted,media/dvd_mounted,media/removable_unmounted,media/dvd_unmounted,media/smb_mounted,media/dvdvideo,media/smb_unmounted,media/floppy5_mounted,media/floppy5_unmounted,media/floppy_mounted,media/zip_mounted,media/floppy_unmounted,media/zip_unmounted,media/camera_mounted,media/camera_unmounted
+ServiceTypes=KPropsDlg/Plugin,media/audiocd,media/hdd_mounted,media/hdd_unmounted,media/hdd_mounted_decrypted,media/hdd_unmounted_decrypted,media/cdrom_mounted,media/cdrom_unmounted,media/cdrom_mounted_decrypted,media/cdrom_unmounted_decrypted,media/cdwriter_mounted,media/cdwriter_mounted_decrypted,media/nfs_mounted,media/cdwriter_unmounted,media/cdwriter_unmounted_decrypted,media/nfs_unmounted,media/removable_mounted,media/removable_mounted_decrypted,media/dvd_mounted,media/dvd_mounted_decrypted,media/removable_unmounted,media/removable_unmounted_decrypted,media/dvd_unmounted,media/dvd_unmounted_decrypted,media/smb_mounted,media/dvdvideo,media/smb_unmounted,media/floppy5_mounted,media/floppy5_unmounted,media/floppy_mounted,media/zip_mounted,media/floppy_unmounted,media/zip_unmounted,media/camera_mounted,media/camera_unmounted
diff --git a/kioslave/media/services/Makefile.am b/kioslave/media/services/Makefile.am
index dded3c403..c744934f2 100644
--- a/kioslave/media/services/Makefile.am
+++ b/kioslave/media/services/Makefile.am
@@ -1,3 +1,3 @@
servicesdir = $(kde_datadir)/konqueror/servicemenus
-services_DATA = media_mount.desktop media_unmount.desktop media_eject.desktop media_safelyremove.desktop
+services_DATA = media_decrypt.desktop media_mount.desktop media_unmount.desktop media_eject.desktop media_safelyremove.desktop
diff --git a/kioslave/media/services/media_decrypt.desktop b/kioslave/media/services/media_decrypt.desktop
new file mode 100644
index 000000000..dd8dadc39
--- /dev/null
+++ b/kioslave/media/services/media_decrypt.desktop
@@ -0,0 +1,9 @@
+[Desktop Action Decrypt]
+Exec=kio_media_mounthelper -d %u
+Icon=decrypted
+Name=Decrypt
+Name[de]=Entschlüsseln
+
+[Desktop Entry]
+Actions=Decrypt
+ServiceTypes=media/removable_unmounted_encrypted,media/hdd_unmounted_encrypted,media/cdrom_unmounted_encrypted,media/cdwriter_unmounted_encrypted,media/dvd_unmounted_encrypted
diff --git a/kioslave/media/services/media_eject.desktop b/kioslave/media/services/media_eject.desktop
index 1ecd29fa8..f5ab3582e 100644
--- a/kioslave/media/services/media_eject.desktop
+++ b/kioslave/media/services/media_eject.desktop
@@ -1,5 +1,5 @@
[Desktop Entry]
-ServiceTypes=media/cdrom_mounted,media/cdrom_unmounted,media/cdwriter_mounted,media/cdwriter_unmounted,media/dvd_mounted,media/dvd_unmounted,media/audiocd,media/blankcd,media/blankdvd,media/dvdvideo,media/svcd,media/vcd
+ServiceTypes=media/cdrom_mounted,media/cdrom_unmounted,media/cdrom_mounted_decrypted,media/cdrom_unmounted_decrypted,media/cdrom_unmounted_encrypted,media/cdwriter_mounted,media/cdwriter_unmounted,media/cdwriter_mounted_decrypted,media/cdwriter_unmounted_decrypted,media/cdwriter_unmounted_encrypted,media/dvd_mounted,media/dvd_unmounted,media/dvd_mounted_decrypted,media/dvd_unmounted_decrypted,media/dvd_unmounted_encrypted,media/audiocd,media/blankcd,media/blankdvd,media/dvdvideo,media/svcd,media/vcd
Actions=MediaEject;
X-KDE-Priority=TopLevel
X-KDE-MediaNotifierHide=true
diff --git a/kioslave/media/services/media_mount.desktop b/kioslave/media/services/media_mount.desktop
index 1779d2208..b2166f8ea 100644
--- a/kioslave/media/services/media_mount.desktop
+++ b/kioslave/media/services/media_mount.desktop
@@ -1,5 +1,5 @@
[Desktop Entry]
-ServiceTypes=media/cdrom_unmounted,media/cdwriter_unmounted,media/dvd_unmounted,media/floppy5_unmounted,media/floppy_unmounted,media/hdd_unmounted,media/nfs_unmounted,media/removable_unmounted,media/smb_unmounted,media/zip_unmounted,media/camera_unmounted
+ServiceTypes=media/cdrom_unmounted,media/cdrom_unmounted_decrypted,media/cdwriter_unmounted,media/cdwriter_unmounted_decrypted,media/dvd_unmounted,media/dvd_unmounted_decrypted,media/floppy5_unmounted,media/floppy_unmounted,media/hdd_unmounted,media/hdd_unmounted_decrypted,media/nfs_unmounted,media/removable_unmounted,media/removable_unmounted_decrypted,media/smb_unmounted,media/zip_unmounted,media/camera_unmounted
Actions=MediaMount;
X-KDE-Priority=TopLevel
X-KDE-MediaNotifierHide=true
diff --git a/kioslave/media/services/media_safelyremove.desktop b/kioslave/media/services/media_safelyremove.desktop
index 298a5f2e5..ce92f348c 100644
--- a/kioslave/media/services/media_safelyremove.desktop
+++ b/kioslave/media/services/media_safelyremove.desktop
@@ -1,5 +1,5 @@
[Desktop Entry]
-ServiceTypes=media/removable_mounted,media/removable_unmounted,media/camera_mounted,media/camera_unmounted
+ServiceTypes=media/removable_mounted,media/removable_mounted_decrypted,media/removable_unmounted,media/removable_unmounted_decrypted,media/camera_mounted,media/camera_unmounted
Actions=MediaSafelyRemove;
X-KDE-Priority=TopLevel
X-KDE-MediaNotifierHide=true
diff --git a/kioslave/media/services/media_unmount.desktop b/kioslave/media/services/media_unmount.desktop
index 537750095..5877e484e 100644
--- a/kioslave/media/services/media_unmount.desktop
+++ b/kioslave/media/services/media_unmount.desktop
@@ -1,5 +1,5 @@
[Desktop Entry]
-ServiceTypes=media/cdrom_mounted,media/cdwriter_mounted,media/dvd_mounted,media/floppy5_mounted,media/floppy_mounted,media/hdd_mounted,media/nfs_mounted,media/smb_mounted,media/zip_mounted,media/vcd,media/svcd,media/dvdvideo
+ServiceTypes=media/cdrom_mounted,media/cdrom_mounted_decrypted,media/cdwriter_mounted,media/cdwriter_mounted_decrypted,media/dvd_mounted,media/dvd_mounted_decrypted,media/floppy5_mounted,media/floppy_mounted,media/hdd_mounted,media/hdd_mounted_decrypted,media/nfs_mounted,media/smb_mounted,media/zip_mounted,media/vcd,media/svcd,media/dvdvideo
Actions=MediaUnmount;
X-KDE-Priority=TopLevel
X-KDE-MediaNotifierHide=true