[gnome-disk-utility/wip/iscsi] iscsi: add connection configuration dialog



commit d44a6ab6990d8f75cf7457ecaa7b196d1352e802
Author: David Zeuthen <davidz redhat com>
Date:   Wed Feb 29 15:26:48 2012 -0500

    iscsi: add connection configuration dialog
    
    Signed-off-by: David Zeuthen <davidz redhat com>

 data/ui/Makefile.am                       |    1 +
 data/ui/iscsi-connection-dialog.ui        |  518 +++++++++++++++++++++++++++++
 src/palimpsest/Makefile.am                |    1 +
 src/palimpsest/gduiscsiconnectiondialog.c |  493 +++++++++++++++++++++++++++
 src/palimpsest/gduiscsiconnectiondialog.h |   41 +++
 src/palimpsest/gduwindow.c                |   62 ++++-
 6 files changed, 1115 insertions(+), 1 deletions(-)
---
diff --git a/data/ui/Makefile.am b/data/ui/Makefile.am
index 1b3aec3..0c1b297 100644
--- a/data/ui/Makefile.am
+++ b/data/ui/Makefile.am
@@ -22,6 +22,7 @@ ui_DATA = 				\
 	change-passphrase-dialog.ui	\
 	about-dialog.ui			\
 	app-menu.ui			\
+	iscsi-connection-dialog.ui	\
 	$(NULL)
 
 EXTRA_DIST = 				\
diff --git a/data/ui/iscsi-connection-dialog.ui b/data/ui/iscsi-connection-dialog.ui
new file mode 100644
index 0000000..2742411
--- /dev/null
+++ b/data/ui/iscsi-connection-dialog.ui
@@ -0,0 +1,518 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkDialog" id="iscsi-connection-dialog">
+    <property name="can_focus">False</property>
+    <property name="border_width">5</property>
+    <property name="resizable">False</property>
+    <property name="modal">True</property>
+    <property name="destroy_with_parent">True</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox9">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area9">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="button11">
+                <property name="label">gtk-cancel</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="button12">
+                <property name="label">gtk-ok</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="can_default">True</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box5">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">12</property>
+            <child>
+              <object class="GtkGrid" id="grid6">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="row_spacing">12</property>
+                <property name="column_spacing">12</property>
+                <child>
+                  <object class="GtkLabel" id="label16">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">_Authentication</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">auth-combobox</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label17">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">T_imeout</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">timeout-spinbutton</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">2</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="startup-label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Connect at _Startup</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">automatic-startup-switch</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBoxText" id="auth-combobox">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <items>
+                      <item translatable="yes">None</item>
+                      <item translatable="yes">CHAP</item>
+                      <item translatable="yes">Mutual CHAP</item>
+                    </items>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkHBox" id="hbox1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">12</property>
+                    <child>
+                      <object class="GtkSpinButton" id="timeout-spinbutton">
+                        <property name="numeric">True</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">â</property>
+                        <property name="adjustment">timeout-adjustment</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label19">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">seconds</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">2</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <child>
+                      <object class="GtkSwitch" id="automatic-startup-switch">
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="use_action_appearance">False</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkVBox" id="initiator-auth-vbox">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="spacing">12</property>
+                <child>
+                  <object class="GtkLabel" id="label13">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Initiator Authentication&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkGrid" id="grid5">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_left">12</property>
+                    <property name="row_spacing">12</property>
+                    <property name="column_spacing">12</property>
+                    <child>
+                      <object class="GtkLabel" id="label14">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">_Password</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">initiator-auth-password-entry</property>
+                        <style>
+                          <class name="dim-label"/>
+                        </style>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="initiator-auth-password-entry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="visibility">False</property>
+                        <property name="invisible_char">â</property>
+                        <property name="activates_default">True</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="initiator-auth-show-password-checkbutton">
+                        <property name="label" translatable="yes">Sho_w password</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="use_underline">True</property>
+                        <property name="xalign">0</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">2</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label15">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">_Username</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">initiator-auth-username-entry</property>
+                        <style>
+                          <class name="dim-label"/>
+                        </style>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="initiator-auth-username-entry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">â</property>
+                        <property name="activates_default">True</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkVBox" id="target-auth-vbox">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="spacing">12</property>
+                <child>
+                  <object class="GtkLabel" id="label12">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Target Authentication&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkGrid" id="grid3">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_left">12</property>
+                    <property name="row_spacing">12</property>
+                    <property name="column_spacing">12</property>
+                    <child>
+                      <object class="GtkLabel" id="label10">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Passwo_rd</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">target-auth-password-entry</property>
+                        <style>
+                          <class name="dim-label"/>
+                        </style>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="target-auth-password-entry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="visibility">False</property>
+                        <property name="invisible_char">â</property>
+                        <property name="activates_default">True</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="target-auth-show-password-checkbutton">
+                        <property name="label" translatable="yes">Show passwor_d</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="use_underline">True</property>
+                        <property name="xalign">0</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">2</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label11">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Us_ername</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">target-auth-username-entry</property>
+                        <style>
+                          <class name="dim-label"/>
+                        </style>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="target-auth-username-entry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">â</property>
+                        <property name="activates_default">True</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-6">button11</action-widget>
+      <action-widget response="-5">button12</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkAdjustment" id="timeout-adjustment">
+    <property name="upper">1000000</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+</interface>
diff --git a/src/palimpsest/Makefile.am b/src/palimpsest/Makefile.am
index 703b140..94315d7 100644
--- a/src/palimpsest/Makefile.am
+++ b/src/palimpsest/Makefile.am
@@ -48,6 +48,7 @@ palimpsest_SOURCES = 							\
 	gduestimator.h			gduestimator.c			\
 	gduchangepassphrasedialog.h	gduchangepassphrasedialog.c	\
 	gduiscsipathmodel.h		gduiscsipathmodel.c		\
+	gduiscsiconnectiondialog.h	gduiscsiconnectiondialog.c	\
 	$(enum_built_sources)						\
 	$(NULL)
 
diff --git a/src/palimpsest/gduiscsiconnectiondialog.c b/src/palimpsest/gduiscsiconnectiondialog.c
new file mode 100644
index 0000000..cc6c76b
--- /dev/null
+++ b/src/palimpsest/gduiscsiconnectiondialog.c
@@ -0,0 +1,493 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2011 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+
+#include <glib/gi18n.h>
+
+#include "gduapplication.h"
+#include "gduwindow.h"
+#include "gduiscsiconnectiondialog.h"
+#include "gduutils.h"
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+
+typedef struct
+{
+  GduWindow *window;
+  GtkWidget *dialog;
+
+  UDisksiSCSITarget  *target;
+  gchar              *host;
+  gint                port;
+  gint                tpgt;
+  gchar              *interface_name;
+  GVariant           *configuration;
+
+  gint initial_auth_combobox_active;
+
+  GtkWidget *startup_switch;
+  GtkWidget *auth_combobox;
+  GtkWidget *timeout_spinbutton;
+  GtkWidget *auth_vbox;
+  GtkWidget *username_entry;
+  GtkWidget *password_entry;
+  GtkWidget *password_show_checkbutton;
+  GtkWidget *auth_in_vbox;
+  GtkWidget *username_in_entry;
+  GtkWidget *password_in_entry;
+  GtkWidget *password_in_show_checkbutton;
+} DialogData;
+
+static void
+dialog_data_free (DialogData *data)
+{
+  g_object_unref (data->window);
+  gtk_widget_hide (data->dialog);
+  gtk_widget_destroy (data->dialog);
+
+  g_object_unref (data->target);
+  g_free (data->host);
+  g_free (data->interface_name);
+  g_variant_unref (data->configuration);
+
+  g_free (data);
+}
+
+static void
+update (DialogData *data,
+        GtkWidget  *widget)
+{
+  const gchar *startup = NULL;
+  const gchar *auth_method = NULL;
+  const gchar *username = NULL;
+  const gchar *password = NULL;
+  const gchar *username_in = NULL;
+  const gchar *password_in = NULL;
+  const gchar *timeout_str = NULL;
+  gint timeout_val = 0;
+  gboolean startup_automatic = FALSE;
+  gboolean show_auth = FALSE;
+  gboolean show_auth_in = FALSE;
+  gboolean changed = FALSE;
+  gboolean valid = FALSE;
+  gint auth_combobox_active;
+
+  /* Update visibility of authentication sections */
+  auth_combobox_active = gtk_combo_box_get_active (GTK_COMBO_BOX (data->auth_combobox));
+  switch (auth_combobox_active)
+    {
+    case 0: /* None */
+      break;
+
+    case 1: /* CHAP */
+      show_auth = TRUE;
+      break;
+
+    case 2: /* Mutual CHAP */
+      show_auth = TRUE;
+      show_auth_in = TRUE;
+      break;
+    }
+  if (show_auth)
+    gtk_widget_show (data->auth_vbox);
+  else
+    gtk_widget_hide (data->auth_vbox);
+  if (show_auth_in)
+    gtk_widget_show (data->auth_in_vbox);
+  else
+    gtk_widget_hide (data->auth_in_vbox);
+
+  /* compare dialog data to whatever we bootstrapped it with */
+  g_variant_lookup (data->configuration, "node.startup", "&s", &startup);
+  g_variant_lookup (data->configuration, "node.session.auth.authmethod", "&s", &auth_method);
+  g_variant_lookup (data->configuration, "node.session.auth.username", "&s", &username);
+  g_variant_lookup (data->configuration, "node.session.auth.password", "&s", &password);
+  g_variant_lookup (data->configuration, "node.session.auth.username_in", "&s", &username_in);
+  g_variant_lookup (data->configuration, "node.session.auth.password_in", "&s", &password_in);
+  g_variant_lookup (data->configuration, "node.session.timeo.replacement_timeout", "&s", &timeout_str);
+
+  if (g_strcmp0 (startup, "automatic") == 0)
+    startup_automatic = TRUE;
+
+  if (timeout_str != NULL)
+    timeout_val = atoi (timeout_str);
+
+  /* calculate if data in the dialog has changed from the given configuration */
+  if (startup_automatic != gtk_switch_get_active (GTK_SWITCH (data->startup_switch)))
+    changed = TRUE;
+
+  if (timeout_val != gtk_spin_button_get_value (GTK_SPIN_BUTTON (data->timeout_spinbutton)))
+    changed = TRUE;
+
+  switch (auth_combobox_active)
+    {
+    case 0: /* None */
+      if (g_strcmp0 (auth_method, "None") != 0)
+        changed = TRUE;
+      break;
+
+    case 1: /* CHAP */
+      if (g_strcmp0 (auth_method, "CHAP") != 0 ||
+          g_strcmp0 (username, gtk_entry_get_text (GTK_ENTRY (data->username_entry))) != 0 ||
+          g_strcmp0 (password, gtk_entry_get_text (GTK_ENTRY (data->password_entry))) != 0)
+        changed = TRUE;
+      break;
+
+    case 2: /* Mutual CHAP */
+      if (g_strcmp0 (auth_method, "CHAP") != 0 ||
+          g_strcmp0 (username,    gtk_entry_get_text (GTK_ENTRY (data->username_entry))) != 0 ||
+          g_strcmp0 (password,    gtk_entry_get_text (GTK_ENTRY (data->password_entry))) != 0 ||
+          g_strcmp0 (username_in, gtk_entry_get_text (GTK_ENTRY (data->username_in_entry))) != 0 ||
+          g_strcmp0 (password_in, gtk_entry_get_text (GTK_ENTRY (data->password_in_entry))) != 0)
+        changed = TRUE;
+      break;
+    }
+  if (auth_combobox_active != data->initial_auth_combobox_active)
+    changed = TRUE;
+
+  /* validate data */
+  valid = TRUE;
+  switch (auth_combobox_active)
+    {
+    case 1: /* CHAP */
+      if (strlen (gtk_entry_get_text (GTK_ENTRY (data->username_entry))) == 0 ||
+          strlen (gtk_entry_get_text (GTK_ENTRY (data->password_entry))) == 0)
+        valid = FALSE;
+      break;
+
+    case 2: /* Mutal CHAP */
+      if (strlen (gtk_entry_get_text (GTK_ENTRY (data->username_entry))) == 0 ||
+          strlen (gtk_entry_get_text (GTK_ENTRY (data->password_entry))) == 0 ||
+          strlen (gtk_entry_get_text (GTK_ENTRY (data->username_in_entry))) == 0 ||
+          strlen (gtk_entry_get_text (GTK_ENTRY (data->password_in_entry))) == 0)
+        valid = FALSE;
+      break;
+    }
+
+  gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog),
+                                     GTK_RESPONSE_OK,
+                                     changed && valid);
+}
+
+static void
+on_property_changed (GObject     *object,
+                     GParamSpec  *pspec,
+                     gpointer     user_data)
+{
+  DialogData *data = user_data;
+  update (data, GTK_WIDGET (object));
+}
+
+static void
+initial_populate (DialogData *data)
+{
+  const gchar *startup = NULL;
+  const gchar *auth_method = NULL;
+  const gchar *username = NULL;
+  const gchar *password = NULL;
+  const gchar *username_in = NULL;
+  const gchar *password_in = NULL;
+  const gchar *timeout_str = NULL;
+  gint timeout_val = 0;
+  gboolean startup_automatic = FALSE;
+
+  g_variant_lookup (data->configuration, "node.startup", "&s", &startup);
+  g_variant_lookup (data->configuration, "node.session.auth.authmethod", "&s", &auth_method);
+  g_variant_lookup (data->configuration, "node.session.auth.username", "&s", &username);
+  g_variant_lookup (data->configuration, "node.session.auth.password", "&s", &password);
+  g_variant_lookup (data->configuration, "node.session.auth.username_in", "&s", &username_in);
+  g_variant_lookup (data->configuration, "node.session.auth.password_in", "&s", &password_in);
+  g_variant_lookup (data->configuration, "node.session.timeo.replacement_timeout", "&s", &timeout_str);
+
+  if (g_strcmp0 (startup, "automatic") == 0)
+    startup_automatic = TRUE;
+
+  if (timeout_str != NULL)
+    timeout_val = atoi (timeout_str);
+
+  gtk_switch_set_active (GTK_SWITCH (data->startup_switch), startup_automatic);
+  gtk_entry_set_text (GTK_ENTRY (data->username_entry), username);
+  gtk_entry_set_text (GTK_ENTRY (data->password_entry), password);
+  gtk_entry_set_text (GTK_ENTRY (data->username_in_entry), username_in);
+  gtk_entry_set_text (GTK_ENTRY (data->password_in_entry), password_in);
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON (data->timeout_spinbutton), timeout_val);
+
+  if (g_strcmp0 (auth_method, "None") == 0)
+    {
+      data->initial_auth_combobox_active = 0;  /* None */
+    }
+  else if (g_strcmp0 (auth_method, "CHAP") == 0)
+    {
+      if (username_in != NULL && strlen (username_in) > 0)
+        data->initial_auth_combobox_active = 2; /* Mutual CHAP */
+      else
+        data->initial_auth_combobox_active = 1; /* CHAP */
+    }
+  else
+    {
+      g_warning ("No support for auth_method `%s'", auth_method);
+        data->initial_auth_combobox_active = -1; /* No item */
+    }
+  gtk_combo_box_set_active (GTK_COMBO_BOX (data->auth_combobox), data->initial_auth_combobox_active);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void show_no_populate (DialogData *data);
+
+static void
+update_conf_cb (UDisksiSCSITarget *target,
+                GAsyncResult      *res,
+                gpointer           user_data)
+{
+  DialogData *data = user_data;
+  GError *error;
+
+  error = NULL;
+  if (!udisks_iscsi_target_call_update_configuration_finish (target,
+                                                             res,
+                                                             &error))
+    {
+      if (g_error_matches (error, UDISKS_ERROR, UDISKS_ERROR_NOT_AUTHORIZED_DISMISSED))
+        {
+          g_error_free (error);
+          show_no_populate (data);
+          goto out;
+        }
+      gtk_widget_hide (data->dialog);
+      gdu_window_show_error (data->window,
+                             _("Error updating configuration"),
+                             error);
+      g_error_free (error);
+      dialog_data_free (data);
+      goto out;
+    }
+
+  dialog_data_free (data);
+
+ out:
+  ;
+}
+
+
+static void
+show_no_populate (DialogData *data)
+{
+  gint response;
+  response = gtk_dialog_run (GTK_DIALOG (data->dialog));
+  if (response == GTK_RESPONSE_OK)
+    {
+      GVariantBuilder builder;
+      gchar timeout_str[16];
+
+      g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
+
+      snprintf (timeout_str, sizeof timeout_str, "%d",
+                (gint) gtk_spin_button_get_value (GTK_SPIN_BUTTON (data->timeout_spinbutton)));
+      g_variant_builder_add (&builder, "{ss}", "node.session.timeo.replacement_timeout", timeout_str);
+      g_variant_builder_add (&builder, "{ss}", "node.startup",
+                             gtk_switch_get_active (GTK_SWITCH (data->startup_switch)) ? "automatic" : "manual");
+      switch (gtk_combo_box_get_active (GTK_COMBO_BOX (data->auth_combobox)))
+        {
+        case 0: /* None */
+          g_variant_builder_add (&builder, "{ss}", "node.session.auth.authmethod", "None");
+          g_variant_builder_add (&builder, "{ss}", "node.session.auth.username", "");
+          g_variant_builder_add (&builder, "{ss}", "node.session.auth.password", "");
+          g_variant_builder_add (&builder, "{ss}", "node.session.auth.username_in", "");
+          g_variant_builder_add (&builder, "{ss}", "node.session.auth.password_in", "");
+          break;
+
+        case 1: /* CHAP */
+          g_variant_builder_add (&builder, "{ss}", "node.session.auth.authmethod", "CHAP");
+          g_variant_builder_add (&builder, "{ss}", "node.session.auth.username",
+                                 gtk_entry_get_text (GTK_ENTRY (data->username_entry)));
+          g_variant_builder_add (&builder, "{ss}", "node.session.auth.password",
+                                 gtk_entry_get_text (GTK_ENTRY (data->password_entry)));
+          g_variant_builder_add (&builder, "{ss}", "node.session.auth.username_in", "");
+          g_variant_builder_add (&builder, "{ss}", "node.session.auth.password_in", "");
+          break;
+
+        case 2: /* Mutual CHAP */
+          g_variant_builder_add (&builder, "{ss}", "node.session.auth.authmethod", "CHAP");
+          g_variant_builder_add (&builder, "{ss}", "node.session.auth.username",
+                                 gtk_entry_get_text (GTK_ENTRY (data->username_entry)));
+          g_variant_builder_add (&builder, "{ss}", "node.session.auth.password",
+                                 gtk_entry_get_text (GTK_ENTRY (data->password_entry)));
+          g_variant_builder_add (&builder, "{ss}", "node.session.auth.username_in",
+                                 gtk_entry_get_text (GTK_ENTRY (data->username_in_entry)));
+          g_variant_builder_add (&builder, "{ss}", "node.session.auth.password_in",
+                                 gtk_entry_get_text (GTK_ENTRY (data->password_in_entry)));
+          break;
+        }
+
+
+      udisks_iscsi_target_call_update_configuration (data->target,
+                                                     data->host,
+                                                     data->port,
+                                                     data->tpgt,
+                                                     data->interface_name,
+                                                     g_variant_builder_end (&builder),
+                                                     g_variant_new ("a{sv}", NULL), /* options */
+                                                     NULL,  /* GCancellable* */
+                                                     (GAsyncReadyCallback) update_conf_cb,
+                                                     data);
+    }
+  else
+    {
+      dialog_data_free (data);
+    }
+}
+
+static void
+show (DialogData *data)
+{
+  initial_populate (data);
+  update (data, NULL);
+  gtk_widget_show_all (data->dialog);
+  show_no_populate (data);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+get_secret_cb (UDisksiSCSITarget *target,
+               GAsyncResult      *res,
+               gpointer           user_data)
+{
+  DialogData *data = user_data;
+  GError *error;
+  GVariant *configuration;
+
+  configuration = NULL;
+  error = NULL;
+  if (!udisks_iscsi_target_call_get_secret_configuration_finish (target,
+                                                                 &configuration,
+                                                                 res,
+                                                                 &error))
+    {
+      gdu_window_show_error (data->window,
+                             _("Error retrieving configuration data with passwords"),
+                             error);
+      g_error_free (error);
+      dialog_data_free (data);
+      goto out;
+    }
+
+  g_variant_unref (data->configuration);
+  data->configuration = configuration;
+
+  show (data);
+
+ out:
+  ;
+}
+
+void
+gdu_iscsi_connection_dialog_show (GduWindow          *window,
+                                  UDisksiSCSITarget  *target,
+                                  const gchar        *host,
+                                  gint                port,
+                                  gint                tpgt,
+                                  const gchar        *interface_name,
+                                  GVariant           *configuration)
+{
+  GtkBuilder *builder;
+  DialogData *data;
+  const gchar *auth_method;
+
+  data = g_new0 (DialogData, 1);
+
+  data->window = g_object_ref (window);
+  data->target = g_object_ref (target);
+  data->host = g_strdup (host);
+  data->port = port;
+  data->tpgt = tpgt;
+  data->interface_name = g_strdup (interface_name);
+  data->configuration = g_variant_ref (configuration);
+
+  data->dialog = GTK_WIDGET (gdu_application_new_widget (gdu_window_get_application (window),
+                                                         "iscsi-connection-dialog.ui",
+                                                         "iscsi-connection-dialog",
+                                                         &builder));
+
+  data->startup_switch               = GTK_WIDGET (gtk_builder_get_object (builder, "automatic-startup-switch"));
+  data->auth_combobox                = GTK_WIDGET (gtk_builder_get_object (builder, "auth-combobox"));
+  data->timeout_spinbutton           = GTK_WIDGET (gtk_builder_get_object (builder, "timeout-spinbutton"));
+  data->username_entry               = GTK_WIDGET (gtk_builder_get_object (builder, "initiator-auth-username-entry"));
+  data->password_entry               = GTK_WIDGET (gtk_builder_get_object (builder, "initiator-auth-password-entry"));
+  data->username_in_entry            = GTK_WIDGET (gtk_builder_get_object (builder, "target-auth-username-entry"));
+  data->password_in_entry            = GTK_WIDGET (gtk_builder_get_object (builder, "target-auth-password-entry"));
+  data->auth_vbox                    = GTK_WIDGET (gtk_builder_get_object (builder, "initiator-auth-vbox"));
+  data->password_show_checkbutton    = GTK_WIDGET (gtk_builder_get_object (builder, "initiator-auth-show-password-checkbutton"));
+  data->auth_in_vbox                 = GTK_WIDGET (gtk_builder_get_object (builder, "target-auth-vbox"));
+  data->password_in_show_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "target-auth-show-password-checkbutton"));
+
+  g_object_bind_property (data->password_show_checkbutton,
+                          "active",
+                          data->password_entry,
+                          "visibility",
+                          G_BINDING_SYNC_CREATE);
+  g_object_bind_property (data->password_in_show_checkbutton,
+                          "active",
+                          data->password_in_entry,
+                          "visibility",
+                          G_BINDING_SYNC_CREATE);
+
+  g_signal_connect (data->startup_switch, "notify::active", G_CALLBACK (on_property_changed), data);
+  g_signal_connect (data->auth_combobox, "notify::active", G_CALLBACK (on_property_changed), data);
+  g_signal_connect (data->timeout_spinbutton, "notify::value", G_CALLBACK (on_property_changed), data);
+  g_signal_connect (data->username_entry, "notify::text", G_CALLBACK (on_property_changed), data);
+  g_signal_connect (data->password_entry, "notify::text", G_CALLBACK (on_property_changed), data);
+  g_signal_connect (data->username_in_entry, "notify::text", G_CALLBACK (on_property_changed), data);
+  g_signal_connect (data->password_in_entry, "notify::text", G_CALLBACK (on_property_changed), data);
+
+  gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (window));
+  gtk_dialog_set_default_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_OK);
+
+  /* visibility of these depends on auth_combobox value, see update() */
+  gtk_widget_set_no_show_all (data->auth_vbox, TRUE);
+  gtk_widget_set_no_show_all (data->auth_in_vbox, TRUE);
+
+  /* see if we need to retrieve passwords (will cause polkit dialog to be shown) */
+  g_variant_lookup (data->configuration, "node.session.auth.authmethod", "&s", &auth_method);
+  if (g_strcmp0 (auth_method, "None") == 0)
+    {
+      show (data);
+    }
+  else
+    {
+      udisks_iscsi_target_call_get_secret_configuration (data->target,
+                                                         data->host,
+                                                         data->port,
+                                                         data->tpgt,
+                                                         data->interface_name,
+                                                         g_variant_new ("a{sv}", NULL), /* options */
+                                                         NULL,  /* GCancellable* */
+                                                         (GAsyncReadyCallback) get_secret_cb,
+                                                         data);
+    }
+  g_object_unref (builder);
+}
diff --git a/src/palimpsest/gduiscsiconnectiondialog.h b/src/palimpsest/gduiscsiconnectiondialog.h
new file mode 100644
index 0000000..b532b8f
--- /dev/null
+++ b/src/palimpsest/gduiscsiconnectiondialog.h
@@ -0,0 +1,41 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2011 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+#ifndef __GDU_ISCSI_CONNECTION_DIALOG_H_H__
+#define __GDU_ISCSI_CONNECTION_DIALOG_H_H__
+
+#include <gtk/gtk.h>
+#include "gdutypes.h"
+
+G_BEGIN_DECLS
+
+void   gdu_iscsi_connection_dialog_show (GduWindow         *window,
+                                         UDisksiSCSITarget *target,
+                                         const gchar        *host,
+                                         gint                port,
+                                         gint                tpgt,
+                                         const gchar        *interface_name,
+                                         GVariant          *configuration);
+
+G_END_DECLS
+
+#endif /* __GDU_ISCSI_CONNECTION_DIALOG_H__ */
diff --git a/src/palimpsest/gduwindow.c b/src/palimpsest/gduwindow.c
index 6894459..f3ca303 100644
--- a/src/palimpsest/gduwindow.c
+++ b/src/palimpsest/gduwindow.c
@@ -50,6 +50,7 @@
 #include "gdurestorediskimagedialog.h"
 #include "gduchangepassphrasedialog.h"
 #include "gduiscsipathmodel.h"
+#include "gduiscsiconnectiondialog.h"
 
 /* Keep in sync with tabs in palimpsest.ui file */
 typedef enum
@@ -113,6 +114,7 @@ struct _GduWindow
   GtkWidget *iscsitab_toolbar;
   GtkWidget *iscsitab_connections_treeview;
   GtkWidget *iscsitab_connection_switch;
+  GtkWidget *iscsitab_configure_toolbutton;
 
   GtkWidget *generic_drive_menu;
   GtkWidget *generic_drive_menu_item_view_smart;
@@ -174,6 +176,7 @@ static const struct {
   {G_STRUCT_OFFSET (GduWindow, iscsitab_toolbar), "iscsitab-toolbar"},
   {G_STRUCT_OFFSET (GduWindow, iscsitab_connections_treeview), "iscsitab-connections-treeview"},
   {G_STRUCT_OFFSET (GduWindow, iscsitab_connection_switch), "iscsitab-connection-switch"},
+  {G_STRUCT_OFFSET (GduWindow, iscsitab_configure_toolbutton), "iscsitab-configure-toolbutton"},
 
   {G_STRUCT_OFFSET (GduWindow, generic_drive_menu), "generic-drive-menu"},
   {G_STRUCT_OFFSET (GduWindow, generic_drive_menu_item_create_disk_image), "generic-drive-menu-item-create-disk-image"},
@@ -250,6 +253,9 @@ static void setup_iscsi_target_page (GduWindow *window, UDisksObject *object);
 static void update_iscsi_target_page (GduWindow *window);
 static void teardown_iscsi_target_page (GduWindow *window);
 
+static void on_iscsitab_configure_toolbutton_clicked (GtkToolButton *button,
+                                                      gpointer       user_data);
+
 static void on_volume_grid_changed (GduVolumeGrid  *grid,
                                     gpointer        user_data);
 
@@ -1151,6 +1157,12 @@ gdu_window_constructed (GObject *object)
                     G_CALLBACK (on_generic_menu_item_restore_volume_image),
                     window);
 
+  /* iSCSI toolbar */
+  g_signal_connect (window->iscsitab_configure_toolbutton,
+                    "clicked",
+                    G_CALLBACK (on_iscsitab_configure_toolbutton_clicked),
+                    window);
+
   g_idle_add (on_constructed_in_idle, g_object_ref (window));
 }
 
@@ -2454,7 +2466,7 @@ update_iscsi_connection_details (GduWindow *window)
   GtkTreeSelection *selection;
   GtkTreeModel *model;
   GtkTreeIter iter;
-  GVariant *configuration;
+  GVariant *configuration = NULL;
   const gchar *node_startup = NULL;
   const gchar *startup = NULL;
   const gchar *timeout_str = NULL;
@@ -2520,6 +2532,8 @@ out:
               auth, SET_MARKUP_FLAGS_HYPHEN_IF_EMPTY);
   g_free (timeout);
   g_free (auth);
+  if (configuration != NULL)
+    g_variant_unref (configuration);
 }
 
 static void
@@ -2743,6 +2757,52 @@ iscsi_target_connection_switch_on_notify_active (GObject     *object,
   ;
 }
 
+static void
+on_iscsitab_configure_toolbutton_clicked (GtkToolButton *button,
+                                          gpointer       user_data)
+{
+  GduWindow *window = GDU_WINDOW (user_data);
+  UDisksiSCSITarget *target;
+  GtkTreeSelection *selection;
+  GtkTreeModel *model;
+  GtkTreeIter iter;
+  gchar *address = NULL;
+  gint port;
+  gint tpgt;
+  gchar *interface_name = NULL;
+  GVariant *configuration = NULL;
+
+  target = udisks_object_peek_iscsi_target (window->current_object);
+  if (target == NULL)
+    {
+      g_warning ("Expected selected object to be an iSCSI target");
+      goto out;
+    }
+
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->iscsitab_connections_treeview));
+  if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+    {
+      g_warning ("No iSCSI connection selected");
+      goto out;
+    }
+
+  gtk_tree_model_get (model, &iter,
+                      GDU_ISCSI_PATH_MODEL_COLUMN_PORTAL_ADDRESS, &address,
+                      GDU_ISCSI_PATH_MODEL_COLUMN_PORTAL_PORT, &port,
+                      GDU_ISCSI_PATH_MODEL_COLUMN_TPGT, &tpgt,
+                      GDU_ISCSI_PATH_MODEL_COLUMN_INTERFACE, &interface_name,
+                      GDU_ISCSI_PATH_MODEL_COLUMN_CONFIGURATION, &configuration,
+                      -1);
+
+  gdu_iscsi_connection_dialog_show (window, target, address, port, tpgt, interface_name, configuration);
+
+ out:
+  g_free (address);
+  g_free (interface_name);
+  if (configuration != NULL)
+    g_variant_unref (configuration);
+}
+
 /* ---------------------------------------------------------------------------------------------------- */
 
 /* TODO: right now we show a MessageDialog but we could do things like an InfoBar etc */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]