<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -64,6 +64,9 @@ void cb_local_computer()
 {
     Shell *shell = shell_get_main_shell();
 
+    shell_status_update(&quot;Disconnecting...&quot;);
+    remote_disconnect_all();
+
     shell_status_update(&quot;Unloading modules...&quot;);
     module_unload_all();
     </diff>
      <filename>hardinfo2/callbacks.c</filename>
    </modified>
    <modified>
      <diff>@@ -94,6 +94,19 @@ static void host_dialog_destroy(HostDialog *hd);
 static gchar *xmlrpc_server_uri = NULL;
 static SSHConn *ssh_conn = NULL;
 
+void remote_disconnect_all(gboolean ssh)
+{
+    if (ssh &amp;&amp; ssh_conn) {
+        ssh_close(ssh_conn);
+        ssh_conn = NULL; 
+    }
+    
+    if (xmlrpc_server_uri) {
+        g_free(xmlrpc_server_uri);
+        xmlrpc_server_uri = NULL;
+    }
+}
+
 static gboolean remote_version_is_supported()
 {
     gint remote_ver;
@@ -109,10 +122,18 @@ static gboolean remote_version_is_supported()
 	dialog = gtk_message_dialog_new(NULL,
 					GTK_DIALOG_DESTROY_WITH_PARENT,
 					GTK_MESSAGE_ERROR,
-					GTK_BUTTONS_CLOSE,
-					&quot;Remote host didn't respond.&quot;);
+					GTK_BUTTONS_NONE,
+					&quot;Remote host didn't respond. Try again?&quot;);
 
-	gtk_dialog_run(GTK_DIALOG(dialog));
+	gtk_dialog_add_buttons(GTK_DIALOG(dialog),
+			       GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+			       &quot;Try again&quot;, GTK_RESPONSE_ACCEPT, NULL);
+
+	if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+             gtk_widget_destroy(dialog);
+             return remote_version_is_supported();
+	}
+	
 	gtk_widget_destroy(dialog);
 	break;
     case XMLRPC_SERVER_VERSION:
@@ -302,9 +323,9 @@ static gboolean remote_connect_direct(gchar *hostname,
 {
     gboolean retval = FALSE;
     
+    remote_disconnect_all(FALSE);
+
     xmlrpc_init();
-    
-    g_free(xmlrpc_server_uri);
     xmlrpc_server_uri = g_strdup_printf(&quot;http://%s:%d/xmlrpc&quot;, hostname, port);
     
     shell_view_set_enabled(FALSE);
@@ -323,7 +344,7 @@ static gboolean remote_connect_direct(gchar *hostname,
             gtk_widget_destroy(dialog);
 	} else {
 	    retval = TRUE;
-	}
+        }
     }
 
     shell_status_update(&quot;Done.&quot;);
@@ -342,12 +363,9 @@ static void remote_connect_ssh(gchar *hostname,
     SoupURI *uri;
     gchar *struri;
     char buffer[32];
+    gboolean error = FALSE;
     
-    /* establish tunnel */
-    if (ssh_conn) {
-        ssh_close(ssh_conn);
-        ssh_conn = NULL;
-    }
+    remote_disconnect_all(TRUE);
     
     shell_view_set_enabled(FALSE);
     shell_status_update(&quot;Establishing SSH tunnel...&quot;);
@@ -358,6 +376,7 @@ static void remote_connect_ssh(gchar *hostname,
     ssh_response = ssh_new(uri, &amp;ssh_conn, &quot;hardinfo -x&quot;);
     
     if (ssh_response != SSH_CONN_OK) {
+        error = TRUE;
         ssh_close(ssh_conn);
     } else {
         gint res;
@@ -365,32 +384,50 @@ static void remote_connect_ssh(gchar *hostname,
         
         memset(buffer, 0, sizeof(buffer));
         res = ssh_read(ssh_conn-&gt;fd_read, buffer, sizeof(buffer), &amp;bytes_read);
-        if (bytes_read != 0 &amp;&amp; res &gt; 0) {
+        if (bytes_read != 0 &amp;&amp; res == 1) {
             if (strncmp(buffer, &quot;XML-RPC server ready&quot;, 20) == 0) {
-                if (remote_connect_direct(&quot;localhost&quot;, 4343)) {
-                    goto ok;
+                DEBUG(&quot;%s&quot;, buffer);
+                
+                if (remote_connect_direct(&quot;127.0.0.1&quot;, 4343)) {
+                    DEBUG(&quot;connected! :)&quot;);
+                    goto out;
                 }
                 
-                /* TODO FIXME Perhaps the server is already running; try to fix */                
+                DEBUG(&quot;unknown error while trying to connect... wtf?&quot;);
             }
+
+            /* TODO FIXME Perhaps the server is already running; try to fix */                
+            DEBUG(&quot;hardinfo already running there?&quot;);
         }
         
-        ssh_close(ssh_conn);
+        error = TRUE;
     }
     
-    /* TODO FIXME Show exact cause of error. */
-    dialog = gtk_message_dialog_new(NULL,
-                                    GTK_DIALOG_DESTROY_WITH_PARENT,
-                                    GTK_MESSAGE_ERROR,
-                                    GTK_BUTTONS_CLOSE,
-                                    &quot;Cannot establish tunnel.&quot;);
-
-    gtk_dialog_run(GTK_DIALOG(dialog));
-    gtk_widget_destroy(dialog);
-    
-ok:
+out:
+    if (error) {
+        dialog = gtk_message_dialog_new_with_markup(NULL,
+                                                    GTK_DIALOG_DESTROY_WITH_PARENT,
+                                                    GTK_MESSAGE_ERROR,
+                                                    GTK_BUTTONS_CLOSE,
+                                                    &quot;&lt;b&gt;&lt;big&gt;Cannot establish tunnel.&lt;/big&gt;&lt;/b&gt;\n&quot;
+                                                    &quot;&lt;i&gt;%s&lt;/i&gt;\n\n&quot;
+                                                    &quot;Please verify that:\n&quot;
+                                                    &quot;\342\200\242 The hostname &lt;b&gt;%s&lt;/b&gt; is correct;\n&quot;
+                                                    &quot;\342\200\242 There is a SSH server running on port &lt;b&gt;%d&lt;/b&gt;;\n&quot;
+                                                    &quot;\342\200\242 Your username/password combination is correct.&quot;,
+                                                    ssh_response == SSH_CONN_OK ? &quot;&quot; : ssh_conn_errors[ssh_response],
+                                                    hostname, port);
+        gtk_dialog_run(GTK_DIALOG(dialog));
+        gtk_widget_destroy(dialog);
+        
+        ssh_close(ssh_conn);
+        ssh_conn = NULL;
+    }
+
+    soup_uri_free(uri);
     g_free(struri);
     shell_view_set_enabled(TRUE);
+    shell_status_update(&quot;Done.&quot;);
 }                               
 
 void remote_connect_host(gchar *hostname)
@@ -438,6 +475,8 @@ void connect_dialog_show(GtkWidget * parent)
         gchar *hostname = (gchar *)gtk_entry_get_text(GTK_ENTRY(he-&gt;txt_hostname));
         const gint selected_type = gtk_combo_box_get_active(GTK_COMBO_BOX(he-&gt;cmb_type));
         const gint port = (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(he-&gt;txt_port));
+        
+        gtk_widget_set_sensitive(he-&gt;dialog, FALSE);
 
         if (selected_type == 1) {
             gchar *username = (gchar *)gtk_entry_get_text(GTK_ENTRY(he-&gt;txt_ssh_user));</diff>
      <filename>hardinfo2/remote.c</filename>
    </modified>
    <modified>
      <diff>@@ -745,7 +745,9 @@ static gboolean update_field(gpointer data)
     DEBUG(&quot;update_field [%s]&quot;, fu-&gt;field_name);
     
     iter = g_hash_table_lookup(update_tbl, fu-&gt;field_name);
-    g_return_val_if_fail(iter != NULL, FALSE);
+    if (!iter) {
+        return FALSE;
+    }
     
     /* if the entry is still selected, update it */
     if (iter &amp;&amp; fu-&gt;entry-&gt;selected &amp;&amp; fu-&gt;entry-&gt;fieldfunc) {</diff>
      <filename>hardinfo2/shell.c</filename>
    </modified>
    <modified>
      <diff>@@ -32,27 +32,24 @@
 #include &lt;string.h&gt;
 #include &lt;errno.h&gt;
 #include &lt;linux/termios.h&gt;
-
+#include &lt;sys/types.h&gt;
+#include &lt;sys/wait.h&gt;
+       
 #include &quot;ssh-conn.h&quot;
 
-static const char *errors[] = {
+const char *ssh_conn_errors[] = {
     &quot;OK&quot;,
-    &quot;No URI&quot;,
+    &quot;No URI specified&quot;,
     &quot;Unknown protocol&quot;,
     &quot;Unknown error&quot;,
     &quot;Cannot spawn SSH&quot;,
     &quot;Bad parameters&quot;,
-    &quot;Permission denied&quot;,
+    &quot;Permission denied (invalid credentials)&quot;,
     &quot;Host key verification failed&quot;,
     &quot;Connection refused&quot;,
     &quot;Invalid username or password&quot;
 };
 
-const char *ssh_strerror(SSHConnResponse errno)
-{
-    return errors[errno];
-}
-
 int ssh_write(SSHConn * conn,
 	      gconstpointer buffer, gint num_bytes, gint * bytes_written)
 {
@@ -109,7 +106,10 @@ void ssh_close(SSHConn * conn)
     close(conn-&gt;fd_write);
     close(conn-&gt;fd_error);
 
-    soup_uri_free(conn-&gt;uri);
+    if (conn-&gt;uri) {
+        soup_uri_free(conn-&gt;uri);
+    }
+    
     kill(conn-&gt;pid, SIGINT);
 
     if (conn-&gt;askpass_path) {
@@ -227,42 +227,41 @@ SSHConnResponse ssh_new(SoupURI * uri,
     }
 
     connection = g_new0(SSHConn, 1);
+    connection-&gt;exit_status = -1;
 
     DEBUG(&quot;spawning SSH&quot;);
 
     if (!g_spawn_async_with_pipes(NULL, argv, NULL,
 				  G_SPAWN_SEARCH_PATH,
 				  ssh_conn_setup, askpass_path,
-				  (gint *) &amp; connection-&gt;pid,
+				  &amp;connection-&gt;pid,
 				  &amp;connection-&gt;fd_write,
 				  &amp;connection-&gt;fd_read,
 				  &amp;connection-&gt;fd_error, NULL)) {
 	response = SSH_CONN_CANNOT_SPAWN_SSH;
 	goto end;
     }
-
+    
     memset(buffer, 0, sizeof(buffer));
     res = ssh_read(connection-&gt;fd_error, &amp;buffer, sizeof(buffer),
 		   &amp;bytes_read);
     DEBUG(&quot;bytes read: %d, result = %d&quot;, bytes_read, res);
-    if (bytes_read != 0 &amp;&amp; res &gt; 0) {
+    if (bytes_read &gt; 0 &amp;&amp; res == 1) {
 	DEBUG(&quot;Received (error channel): [%s]&quot;, buffer);
 
-	if (g_str_equal(buffer, &quot;Permission denied&quot;)) {
+	if (g_str_has_prefix(buffer, &quot;Permission denied&quot;)) {
 	    response = SSH_CONN_PERMISSION_DENIED;
-	} else if (g_str_equal(buffer, &quot;Host key verification failed&quot;)) {
+	    goto end;
+	} else if (g_str_has_prefix(buffer, &quot;Host key verification failed&quot;)) {
 	    response = SSH_CONN_HOST_KEY_CHECK_FAIL;
 	    goto end;
-	} else if (g_str_equal(buffer, &quot;Connection refused&quot;)) {
+	} else if (g_str_has_prefix(buffer, &quot;Connection refused&quot;)) {
 	    response = SSH_CONN_REFUSED;
 	    goto end;
-	} else if (g_str_has_prefix(buffer, &quot;Host key fingerprint is&quot;)) {
-	    /* ok */
-	} else {
-	    response = SSH_CONN_UNKNOWN_ERROR;
-	    goto end;
 	}
     }
+    
+    DEBUG(&quot;no error detected; ssh conn established&quot;);
 
     connection-&gt;uri = soup_uri_copy(uri);
     response = SSH_CONN_OK;
@@ -280,14 +279,18 @@ SSHConnResponse ssh_new(SoupURI * uri,
     }
 
     if (response != SSH_CONN_OK) {
+        if (connection-&gt;uri) {
+            soup_uri_free(connection-&gt;uri);
+        }
+        
 	g_free(connection);
+
 	*conn_return = NULL;
     } else {
 	*conn_return = connection;
     }
 
-    DEBUG(&quot;response = %d (%s)&quot;,
-	  response, response == SSH_CONN_OK ? &quot;OK&quot; : &quot;Error&quot;);
+    DEBUG(&quot;response = %d (%s)&quot;, response, ssh_conn_errors[response]);
 
     return response;
 }
@@ -309,7 +312,7 @@ int main(int argc, char **argv)
 
     u = soup_uri_new(argv[1]);
     r = ssh_new(u, &amp;c, argv[2]);
-    g_print(&quot;Connection result: %s\n&quot;, errors[r]);
+    g_print(&quot;Connection result: %s\n&quot;, ssh_conn_errors[r]);
 
     if (r == SSH_CONN_OK) {
 	int bytes_read;</diff>
      <filename>hardinfo2/ssh-conn.c</filename>
    </modified>
    <modified>
      <diff>@@ -45,8 +45,10 @@ typedef enum {
 struct _SSHConn {
     SoupURI *uri;
     int fd_read, fd_write, fd_error;
-    pid_t pid;
+    GPid pid;
     gchar *askpass_path;
+    
+    gint exit_status;
 };
 
 SSHConnResponse ssh_new(SoupURI * uri,
@@ -57,6 +59,6 @@ int ssh_write(SSHConn * conn,
 	      gconstpointer buffer, gint num_bytes, gint * bytes_written);
 int ssh_read(gint fd, gpointer buffer, gint num_bytes, gint * bytes_read);
 
-const char *ssh_strerror(SSHConnResponse errno);
+const char *ssh_conn_errors[10];
 
 #endif				/* __SSH_CONN_H__ */</diff>
      <filename>hardinfo2/ssh-conn.h</filename>
    </modified>
    <modified>
      <diff>@@ -589,13 +589,15 @@ static gboolean remove_module_methods(gpointer key, gpointer value, gpointer dat
 static void module_unload(ShellModule * module)
 {
     GSList *entry;
-    gchar *name;
-    
-    name = g_path_get_basename(g_module_name(module-&gt;dll));
-    g_hash_table_foreach_remove(__module_methods, remove_module_methods, name);
     
     if (module-&gt;dll) {
+        gchar *name;
+        
+        name = g_path_get_basename(g_module_name(module-&gt;dll));
+        g_hash_table_foreach_remove(__module_methods, remove_module_methods, name);
+        
     	g_module_close(module-&gt;dll);
+    	g_free(name);
     }
     
     g_free(module-&gt;name);
@@ -610,7 +612,6 @@ static void module_unload(ShellModule * module)
     
     g_slist_free(module-&gt;entries);
     g_free(module);
-    g_free(name);
 }
 
 void module_unload_all(void)</diff>
      <filename>hardinfo2/util.c</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>b2c6231f5c707234772660a515e0daf19c710510</id>
    </parent>
  </parents>
  <author>
    <name>Leandro A. F. Pereira</name>
    <email>leandro@hardinfo.org</email>
  </author>
  <url>http://github.com/lpereira/hardinfo/commit/fea14ed5d2088500649c1a1350a407922bac253c</url>
  <id>fea14ed5d2088500649c1a1350a407922bac253c</id>
  <committed-date>2009-05-17T08:54:26-07:00</committed-date>
  <authored-date>2009-05-17T08:54:26-07:00</authored-date>
  <message>More Remote mode fixes</message>
  <tree>f99a8bcfec4012cff9b415a75e0ab409f3f88a1f</tree>
  <committer>
    <name>Leandro A. F. Pereira</name>
    <email>leandro@hardinfo.org</email>
  </committer>
</commit>
