Index: thunar-volman/tvm-camera-device.h =================================================================== --- thunar-volman/tvm-camera-device.h (revision 4898) +++ thunar-volman/tvm-camera-device.h (working copy) @@ -22,7 +22,7 @@ #include -G_BEGIN_DECLS; +G_BEGIN_DECLS gboolean tvm_camera_device_added (TvmPreferences *preferences, LibHalContext *context, @@ -30,6 +30,6 @@ const gchar *capability, GError **error) G_GNUC_INTERNAL; -G_END_DECLS; +G_END_DECLS #endif /* !__TVM_CAMERA_DEVICE_H__ */ Index: thunar-volman/tvm-block-device.h =================================================================== --- thunar-volman/tvm-block-device.h (revision 4898) +++ thunar-volman/tvm-block-device.h (working copy) @@ -22,7 +22,7 @@ #include -G_BEGIN_DECLS; +G_BEGIN_DECLS gboolean tvm_block_device_added (TvmPreferences *preferences, LibHalContext *context, @@ -30,6 +30,6 @@ const gchar *capability, GError **error) G_GNUC_INTERNAL; -G_END_DECLS; +G_END_DECLS #endif /* !__TVM_BLOCK_DEVICE_H__ */ Index: thunar-volman/tvm-input-device.h =================================================================== --- thunar-volman/tvm-input-device.h (revision 4898) +++ thunar-volman/tvm-input-device.h (working copy) @@ -22,7 +22,7 @@ #include -G_BEGIN_DECLS; +G_BEGIN_DECLS gboolean tvm_input_device_added (TvmPreferences *preferences, LibHalContext *context, @@ -30,6 +30,6 @@ const gchar *capability, GError **error) G_GNUC_INTERNAL; -G_END_DECLS; +G_END_DECLS #endif /* !__TVM_INPUT_DEVICE_H__ */ Index: thunar-volman/tvm-preferences-dialog.h =================================================================== --- thunar-volman/tvm-preferences-dialog.h (revision 4898) +++ thunar-volman/tvm-preferences-dialog.h (working copy) @@ -22,7 +22,7 @@ #include -G_BEGIN_DECLS; +G_BEGIN_DECLS typedef struct _TvmPreferencesDialogClass TvmPreferencesDialogClass; typedef struct _TvmPreferencesDialog TvmPreferencesDialog; @@ -38,6 +38,6 @@ GtkWidget *tvm_preferences_dialog_new (void) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -G_END_DECLS; +G_END_DECLS #endif /* !__TVM_PREFERENCES_DIALOG_H__ */ Index: thunar-volman/tvm-device.h =================================================================== --- thunar-volman/tvm-device.h (revision 4898) +++ thunar-volman/tvm-device.h (working copy) @@ -26,7 +26,7 @@ #include -G_BEGIN_DECLS; +G_BEGIN_DECLS /** * TvmDeviceCallback: @@ -53,6 +53,6 @@ const gchar *udi, GError **error) G_GNUC_INTERNAL; -G_END_DECLS; +G_END_DECLS #endif /* !__TVM_DEVICE_H__ */ Index: thunar-volman/tvm-pda-device.h =================================================================== --- thunar-volman/tvm-pda-device.h (revision 4898) +++ thunar-volman/tvm-pda-device.h (working copy) @@ -22,7 +22,7 @@ #include -G_BEGIN_DECLS; +G_BEGIN_DECLS gboolean tvm_pda_device_added (TvmPreferences *preferences, LibHalContext *context, @@ -30,6 +30,6 @@ const gchar *capability, GError **error) G_GNUC_INTERNAL; -G_END_DECLS; +G_END_DECLS #endif /* !__TVM_PDA_DEVICE_H__ */ Index: thunar-volman/tvm-command-entry.h =================================================================== --- thunar-volman/tvm-command-entry.h (revision 4898) +++ thunar-volman/tvm-command-entry.h (working copy) @@ -22,7 +22,7 @@ #include -G_BEGIN_DECLS; +G_BEGIN_DECLS typedef struct _TvmCommandEntryClass TvmCommandEntryClass; typedef struct _TvmCommandEntry TvmCommandEntry; @@ -56,6 +56,6 @@ void tvm_command_entry_set_command (TvmCommandEntry *command_entry, const gchar *command) G_GNUC_INTERNAL; -G_END_DECLS; +G_END_DECLS #endif /* !__TVM_COMMAND_ENTRY_H__ */ Index: thunar-volman/xfce-heading.h =================================================================== --- thunar-volman/xfce-heading.h (revision 4898) +++ thunar-volman/xfce-heading.h (working copy) @@ -23,7 +23,7 @@ #include -G_BEGIN_DECLS; +G_BEGIN_DECLS typedef struct _XfceHeadingPrivate XfceHeadingPrivate; typedef struct _XfceHeadingClass XfceHeadingClass; @@ -77,6 +77,6 @@ void xfce_heading_set_title (XfceHeading *heading, const gchar *title); -G_END_DECLS; +G_END_DECLS #endif /* !__XFCE_HEADING_H__ */ Index: thunar-volman/tvm-crypto-volume.c =================================================================== --- thunar-volman/tvm-crypto-volume.c (revision 0) +++ thunar-volman/tvm-crypto-volume.c (revision 0) @@ -0,0 +1,483 @@ +/* $Id$ */ +/*- + * Copyright (c) 2008 Benedikt Meurer . + * Copyright (c) 2008 Colin Leroy . + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_SYS_WAIT_H +#include +#endif + +#ifdef HAVE_MEMORY_H +#include +#endif +#include +#ifdef HAVE_STRING_H +#include +#endif +#include + +#include +#include +#include +#include + +static void +tvm_crypto_volume_prompt_update_text (GtkEditable *editable, + gchar *new_text, + gint new_text_len, + gint *position, + gpointer data) +{ + gchar **response = (gchar **)data; + if (response == NULL) + return; + g_free(*response); + *response = gtk_editable_get_chars(editable, 0, -1); +} + +typedef struct _CryptoDialogValidate { + GtkWidget *dialog; + gint response; +} CryptoDialogValidate; + +void +tvm_crypto_volume_prompt_validate_text (GtkEntry *entry, + gpointer data) +{ + CryptoDialogValidate *validate_data = (CryptoDialogValidate *)data; + gtk_dialog_response(GTK_DIALOG(validate_data->dialog), validate_data->response); +} + +static void +tvm_crypto_volume_hal_device_removed (LibHalContext *context, + const gchar *udi) +{ + const gchar *dialog_udi; + GtkWidget *dialog = libhal_ctx_get_user_data (context); + + /* check if the active UDI of the dialog was removed */ + dialog_udi = g_object_get_data (G_OBJECT (dialog), "udi"); + if (exo_str_is_equal (dialog_udi, udi)) + { + /* cancel the dialog */ + gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); + } +} + + /** + * tvm_crypto_volume_ask_password: + * @context : a #LibHalContext. + * @udi : the UDI of the device being added, which is watched for removal. + * @icon : the icon or %NULL. + * @title : the prompt title. + * @response_text : the response text. + * @visible : whether text typed should be visible. + * @default_response : Which response to return on Enter. + * @primary_text : the primary prompt text. + * @secondary_text : the secondary prompt text. + * @first_button_text : the first button text. + * @... : %NULL-terminated list of button text, response id pairs. + * + * Return value: the selected response. + **/ +static gint +tvm_crypto_volume_ask_password (LibHalContext *context, + const gchar *udi, + const gchar *icon, + const gchar *title, + gchar **response_text, + gboolean visible, + gint default_response, + const gchar *primary_text, + const gchar *secondary_text, + const gchar *first_button_text, + ...) +{ + GtkWidget *dialog; + GtkWidget *image; + GtkWidget *label; + GtkWidget *hbox; + GtkWidget *vbox; + GtkWidget *entry; + DBusError derror; + va_list args; + gint response; + CryptoDialogValidate validate_data; + + g_return_val_if_fail (exo_hal_udi_validate (udi, -1, NULL), 0); + g_return_val_if_fail (context != NULL, GTK_RESPONSE_CANCEL); + + /* allocate a new dialog */ + dialog = gtk_dialog_new (); + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + g_object_set_data_full (G_OBJECT (dialog), "udi", g_strdup (udi), g_free); + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 6); + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 12); + + /* setup the specified title */ + if (G_LIKELY (title != NULL)) + gtk_window_set_title (GTK_WINDOW (dialog), title); + + /* setup the specified buttons */ + if (G_LIKELY (first_button_text != NULL)) + { + va_start (args, first_button_text); + for (response = va_arg (args, gint); first_button_text != NULL; ) + { + /* insert the button */ + gtk_dialog_add_button (GTK_DIALOG (dialog), first_button_text, response); + first_button_text = va_arg (args, const gchar *); + if (G_UNLIKELY (first_button_text == NULL)) + break; + response = va_arg (args, gint); + } + va_end (args); + } + + /* setup the hbox */ + hbox = gtk_hbox_new (FALSE, 12); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 12); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); + + /* setup the specified icon */ + if (G_LIKELY (icon != NULL)) + { + /* setup an image for the icon */ + image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_DIALOG); + gtk_misc_set_alignment (GTK_MISC (image), 0.0f, 0.0f); + gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); + gtk_widget_show (image); + } + + /* setup the vbox */ + vbox = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); + gtk_widget_show (vbox); + g_object_set_data(G_OBJECT(dialog), "main_vbox", vbox); + + /* setup the primary text */ + label = gtk_label_new (primary_text); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + + /* setup the secondary text */ + if (G_LIKELY (secondary_text != NULL)) + { + label = gtk_label_new (secondary_text); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f); + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + g_object_set_data(G_OBJECT(dialog), "secondary_text", label); + } + + entry = gtk_entry_new(); + gtk_entry_set_visibility(GTK_ENTRY(entry), visible); + gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0); + gtk_widget_show (entry); + g_object_set_data(G_OBJECT(dialog), "pass_entry", entry); + + /* initialize D-Bus error */ + dbus_error_init (&derror); + + /* setup HAL to watch the UDI for removal */ + libhal_ctx_set_user_data (context, dialog); + libhal_ctx_set_device_removed (context, tvm_crypto_volume_hal_device_removed); + libhal_device_property_watch_all (context, &derror); + + /* setup handler for the entered text */ + if (response_text) + *response_text = NULL; + g_signal_connect_after(G_OBJECT(entry), "insert-text", + G_CALLBACK(tvm_crypto_volume_prompt_update_text), + (gpointer) response_text); + validate_data.dialog = dialog; + validate_data.response = default_response; + g_signal_connect(G_OBJECT(entry), "activate", + G_CALLBACK(tvm_crypto_volume_prompt_validate_text), + (gpointer) &validate_data); + + /* run the dialog */ + response = gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy(dialog); + + /* cleanup */ + libhal_ctx_set_device_removed (context, NULL); + libhal_ctx_set_user_data (context, NULL); + dbus_error_free (&derror); + + return response; +} + +static gboolean +progress_pulse(gpointer data) +{ + GtkProgressBar *progress = GTK_PROGRESS_BAR(data); + g_return_val_if_fail(progress != NULL, FALSE); + + gtk_progress_bar_pulse(progress); + + return TRUE; +} + +static void +tvm_crypto_volume_dbus_call_done (DBusPendingCall *call, + void *user_data) +{ + gtk_main_quit(); +} + +static gchar * +tvm_crypto_volume_mount_install_crypto_volume (LibHalContext *context, + const gchar *udi, + LibHalVolume *volume, + const gchar *password, + gboolean *pass_error, + GError **error) +{ + gchar *plain_udi = NULL; + DBusMessage *message = NULL; + DBusMessage *result = NULL; + DBusConnection *dbus_connection = NULL; + DBusPendingCall *call = NULL; + DBusError derror; + dbus_bool_t send_err; + *pass_error = FALSE; + GtkWidget *window = NULL; + GtkWidget *label, *vbox, *hbox; + GtkWidget *wait_progress; + GtkWidget *image; + guint animator_id; + g_clear_error(error); + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_container_set_border_width(GTK_CONTAINER(window), 8); + gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); + gtk_window_set_title(GTK_WINDOW(window), _("Encrypted volume")); + gtk_window_set_modal(GTK_WINDOW(window), TRUE); + gtk_window_set_resizable(GTK_WINDOW(window), FALSE); + + vbox = gtk_vbox_new(FALSE, 6); + hbox = gtk_hbox_new(FALSE, 6); + image = gtk_image_new_from_icon_name ("gtk-dialog-authentication", GTK_ICON_SIZE_DIALOG); + gtk_misc_set_alignment (GTK_MISC (image), 0.0f, 0.0f); + gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); + gtk_widget_show (image); + + label = gtk_label_new(_("Mounting encrypted volume...")); + gtk_label_set_use_markup(GTK_LABEL(label), TRUE); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, FALSE, 0); + + label = gtk_label_new(_("Setting up the crypto layer...")); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, FALSE, 0); + + wait_progress = gtk_progress_bar_new(); + gtk_box_pack_start(GTK_BOX(vbox), wait_progress, TRUE, FALSE, 0); + + gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0); + + gtk_container_add(GTK_CONTAINER(window), hbox); + gtk_widget_show_all(hbox); + animator_id = g_timeout_add(100, progress_pulse, wait_progress); + + gtk_widget_show_now(window); + + message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device.Volume.Crypto", + "Setup"); + + if (G_UNLIKELY (message == NULL)) + { + /* out of memory */ +oom: g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM, g_strerror (ENOMEM)); + goto out; + } + + if (!dbus_message_append_args (message, + DBUS_TYPE_STRING, &password, + DBUS_TYPE_INVALID)) { + dbus_message_unref (message); + goto oom; + } + + dbus_error_init (&derror); + + dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &derror); + if (G_UNLIKELY (dbus_connection == NULL)) + { + /* propagate the error */ + dbus_set_g_error (error, &derror); + goto out; + } + + send_err = dbus_connection_send_with_reply (dbus_connection, message, &call, -1); + if (G_UNLIKELY (send_err == FALSE)) + { + /* release the result */ + dbus_message_unref (message); + goto out; + } + + dbus_pending_call_set_notify(call, tvm_crypto_volume_dbus_call_done, NULL, NULL); + gtk_main(); + + result = dbus_pending_call_steal_reply(call); + /* release the message */ + dbus_message_unref (message); + + /* release the connection */ + dbus_connection_unref (dbus_connection); + + if (G_UNLIKELY (dbus_set_error_from_message(&derror, result))) + { + /* try to translate the error appropriately */ + if (strcmp (derror.name, "org.freedesktop.Hal.Device.Volume.PermissionDenied") == 0) + { + /* TRANSLATORS: The user tried to setup a crypto layer (LUKS-encrpyted volume) but got Permission denied. */ + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("You are not privileged to setup the crypto layer")); + } + else if (strcmp (derror.name, "org.freedesktop.Hal.Device.Volume.Crypto.SetupPasswordError") == 0) + { + /* TRANSLATORS: The user tried to setup a crypto layer (LUKS-encrpyted volume) and typed the wrong password. */ + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Wrong password")); + *pass_error = TRUE; + } + else + { + /* no precise error message, use the HAL one */ + dbus_set_g_error (error, &derror); + } + + /* release the DBus error */ + dbus_error_free (&derror); + dbus_message_unref (result); + plain_udi = NULL; + goto out; + } + else + { + dbus_message_unref (result); + plain_udi = libhal_volume_crypto_get_clear_volume_udi (context, volume); + } + +out: + g_source_remove(animator_id); + gtk_widget_destroy(window); + return plain_udi; +} + +/** + * tvm_crypto_volume_setup: + * @preferences : a #TvmPreferences. + * @context : a #LibHalContext. + * @udi : the HAL volume UDI of the newly added crypto volume. + * @error : return location for errors or %NULL. + * + * Tries to setup the crypto layer for the volume with the + * specified @udi. + * + * Return value: %TRUE if handled, %FALSE if not handled or an + * unrecoverable error occurred. + */ +gboolean +tvm_crypto_volume_setup (TvmPreferences *preferences, + LibHalContext *context, + const gchar *udi, + GError **error) +{ + gchar *password = NULL; + gboolean pass_error = FALSE; + gint num_tries = 0; + gchar *plain_udi = NULL; + LibHalVolume *volume = NULL; + gboolean result = FALSE; + + g_return_val_if_fail (exo_hal_udi_validate (udi, -1, NULL), FALSE); + g_return_val_if_fail (TVM_IS_PREFERENCES (preferences), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail (context != NULL, FALSE); + + volume = libhal_volume_from_udi (context, udi); + g_return_val_if_fail(volume != NULL, FALSE); + plain_udi = libhal_volume_crypto_get_clear_volume_udi (context, volume); + if (plain_udi != NULL) { + libhal_volume_free(volume); + libhal_free_string(plain_udi); + return TRUE; + } + + for (num_tries = 0; num_tries < 3; num_tries++) { + gint response,len; + response = tvm_crypto_volume_ask_password (context, udi, "gtk-dialog-authentication", _("Encrypted volume"), + &password, FALSE, GTK_RESPONSE_OK, + pass_error? _("Wrong password.") + :_("This volume is encrypted."), + _("Please enter your password to decrypt and mount the volume."), + _("Ig_nore"), GTK_RESPONSE_CANCEL, + _("_Mount"), GTK_RESPONSE_OK, + NULL); + if (response == GTK_RESPONSE_CANCEL || response == GTK_RESPONSE_DELETE_EVENT) { + g_clear_error(error); + num_tries = 3; + } else if (password) { + plain_udi = tvm_crypto_volume_mount_install_crypto_volume(context, udi, volume, password, &pass_error, error); + } + if (password) { + len = strlen(password); + memset(password, 0, len); + g_debug("zeroed password %p", password); + g_free(password); + } + if (*error != NULL && !pass_error) { + /* display an error message to the user (exo-mount won't do it as it won't see the clear device */ + GtkWidget *message = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "%s.", _("Failed to setup the encrypted volume")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), "%s.", (*error)->message); + gtk_dialog_run (GTK_DIALOG (message)); + gtk_widget_destroy (message); + break; + } + if (plain_udi != NULL) { + libhal_free_string(plain_udi); + result = TRUE; + break; + } + } + return result; +} + + Index: thunar-volman/tvm-printer-device.h =================================================================== --- thunar-volman/tvm-printer-device.h (revision 4898) +++ thunar-volman/tvm-printer-device.h (working copy) @@ -22,7 +22,7 @@ #include -G_BEGIN_DECLS; +G_BEGIN_DECLS gboolean tvm_printer_device_added (TvmPreferences *preferences, LibHalContext *context, @@ -30,6 +30,6 @@ const gchar *capability, GError **error) G_GNUC_INTERNAL; -G_END_DECLS; +G_END_DECLS #endif /* !__TVM_PRINTER_DEVICE_H__ */ Index: thunar-volman/tvm-crypto-volume.h =================================================================== --- thunar-volman/tvm-crypto-volume.h (revision 0) +++ thunar-volman/tvm-crypto-volume.h (revision 0) @@ -0,0 +1,35 @@ +/* $Id$ */ +/*- + * Copyright (c) 2008 Benedikt Meurer . + * Copyright (c) 2008 Colin Leroy . + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __TVM_CRYPTO_VOLUME_H__ +#define __TVM_CRYPTO_VOLUME_H__ + +#include + +G_BEGIN_DECLS + +gboolean tvm_crypto_volume_setup (TvmPreferences *preferences, + LibHalContext *context, + const gchar *udi, + GError **error) G_GNUC_INTERNAL; + +G_END_DECLS + +#endif /* !__TVM_CRYPTO_VOLUME_H__ */ Index: thunar-volman/xfce-titled-dialog.h =================================================================== --- thunar-volman/xfce-titled-dialog.h (revision 4898) +++ thunar-volman/xfce-titled-dialog.h (working copy) @@ -23,7 +23,7 @@ #include -G_BEGIN_DECLS; +G_BEGIN_DECLS typedef struct _XfceTitledDialogPrivate XfceTitledDialogPrivate; typedef struct _XfceTitledDialogClass XfceTitledDialogClass; @@ -70,6 +70,6 @@ void xfce_titled_dialog_set_subtitle (XfceTitledDialog *titled_dialog, const gchar *subtitle); -G_END_DECLS; +G_END_DECLS #endif /* !__XFCE_TITLED_DIALOG_H__ */ Index: thunar-volman/tvm-preferences.h =================================================================== --- thunar-volman/tvm-preferences.h (revision 4898) +++ thunar-volman/tvm-preferences.h (working copy) @@ -22,7 +22,7 @@ #include -G_BEGIN_DECLS; +G_BEGIN_DECLS typedef struct _TvmPreferencesClass TvmPreferencesClass; typedef struct _TvmPreferences TvmPreferences; @@ -38,6 +38,6 @@ TvmPreferences *tvm_preferences_get (void); -G_END_DECLS; +G_END_DECLS #endif /* !__TVM_PREFERENCES_H__ */ Index: thunar-volman/tvm-pango-extensions.h =================================================================== --- thunar-volman/tvm-pango-extensions.h (revision 4898) +++ thunar-volman/tvm-pango-extensions.h (working copy) @@ -22,7 +22,7 @@ #include -G_BEGIN_DECLS; +G_BEGIN_DECLS PangoAttrList *tvm_pango_attr_list_big (void) G_GNUC_CONST G_GNUC_INTERNAL; PangoAttrList *tvm_pango_attr_list_big_bold (void) G_GNUC_CONST G_GNUC_INTERNAL; @@ -31,6 +31,6 @@ PangoAttrList *tvm_pango_attr_list_small_italic (void) G_GNUC_CONST G_GNUC_INTERNAL; PangoAttrList *tvm_pango_attr_list_underline_single (void) G_GNUC_CONST G_GNUC_INTERNAL; -G_END_DECLS; +G_END_DECLS #endif /* !__TVM_PANGO_EXTENSIONS_H__ */ Index: thunar-volman/tvm-run.h =================================================================== --- thunar-volman/tvm-run.h (revision 4898) +++ thunar-volman/tvm-run.h (working copy) @@ -22,7 +22,7 @@ #include -G_BEGIN_DECLS; +G_BEGIN_DECLS gboolean tvm_run_cdburner (TvmPreferences *preferences, LibHalContext *context, @@ -41,6 +41,6 @@ const gchar *mount_point, GError **error) G_GNUC_INTERNAL; -G_END_DECLS; +G_END_DECLS #endif /* !__TVM_RUN_H__ */ Index: thunar-volman/Makefile.am =================================================================== --- thunar-volman/Makefile.am (revision 4898) +++ thunar-volman/Makefile.am (working copy) @@ -21,6 +21,8 @@ tvm-camera-device.h \ tvm-command-entry.c \ tvm-command-entry.h \ + tvm-crypto-volume.c \ + tvm-crypto-volume.h \ tvm-device.c \ tvm-device.h \ tvm-input-device.c \ Index: thunar-volman/tvm-prompt.h =================================================================== --- thunar-volman/tvm-prompt.h (revision 4898) +++ thunar-volman/tvm-prompt.h (working copy) @@ -22,7 +22,7 @@ #include -G_BEGIN_DECLS; +G_BEGIN_DECLS enum { @@ -46,6 +46,6 @@ const gchar *first_button_text, ...) G_GNUC_INTERNAL G_GNUC_NULL_TERMINATED; -G_END_DECLS; +G_END_DECLS #endif /* !__TVM_PROMPT_H__ */ Index: thunar-volman/tvm-block-device.c =================================================================== --- thunar-volman/tvm-block-device.c (revision 4898) +++ thunar-volman/tvm-block-device.c (working copy) @@ -1,6 +1,6 @@ /* $Id$ */ /*- - * Copyright (c) 2007 Benedikt Meurer . + * Copyright (c) 2007-2008 Benedikt Meurer . * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -42,6 +42,7 @@ #include #include +#include #include #include @@ -609,6 +610,7 @@ gboolean autoplay; gboolean is_cdrom; gboolean has_filesystem; + gboolean has_crypto; gchar *storage_udi; gchar *drive_type; gchar *fsusage; @@ -749,20 +751,30 @@ libhal_free_string (storage_udi); } - /* make sure the volume has a mountable filesystem */ + /* determine the file system usage of the volume */ fsusage = libhal_device_get_property_string (context, udi, "volume.fsusage", NULL); - has_filesystem = (G_LIKELY (fsusage && strcmp (fsusage, "filesystem") == 0)); + has_crypto = (G_UNLIKELY (fsusage != NULL && strcmp (fsusage, "crypto") == 0)); + has_filesystem = (G_LIKELY (fsusage != NULL && strcmp (fsusage, "filesystem") == 0)); libhal_free_string (fsusage); - if (G_UNLIKELY (!has_filesystem)) - return FALSE; - /* check if we should automount drives, otherwise, we're done here */ - g_object_get (G_OBJECT (preferences), "automount-drives", &automount, NULL); - if (G_UNLIKELY (!automount)) - return FALSE; + /* check if we have a crypto volume to setup here */ + if (G_UNLIKELY (has_crypto)) + { + /* try to setup the crypto volume */ + return tvm_crypto_volume_setup (preferences, context, udi, error); + } + else if (G_LIKELY (has_filesystem)) + { + /* check if we should automount drives, otherwise, we're done here */ + g_object_get (G_OBJECT (preferences), "automount-drives", &automount, NULL); + if (G_UNLIKELY (!automount)) + return FALSE; - /* try to mount the block device */ - return tvm_block_device_mount (preferences, context, udi, error); + /* try to mount the block device */ + return tvm_block_device_mount (preferences, context, udi, error); + } + + return FALSE; }