diff options
| -rw-r--r-- | hardinfo2/callbacks.c | 3 | ||||
| -rw-r--r-- | hardinfo2/remote.c | 93 | ||||
| -rw-r--r-- | hardinfo2/shell.c | 4 | ||||
| -rw-r--r-- | hardinfo2/ssh-conn.c | 51 | ||||
| -rw-r--r-- | hardinfo2/ssh-conn.h | 6 | ||||
| -rw-r--r-- | hardinfo2/util.c | 11 | 
6 files changed, 109 insertions, 59 deletions
diff --git a/hardinfo2/callbacks.c b/hardinfo2/callbacks.c index e19e7df8..289a2807 100644 --- a/hardinfo2/callbacks.c +++ b/hardinfo2/callbacks.c @@ -64,6 +64,9 @@ void cb_local_computer()  {      Shell *shell = shell_get_main_shell(); +    shell_status_update("Disconnecting..."); +    remote_disconnect_all(); +      shell_status_update("Unloading modules...");      module_unload_all(); diff --git a/hardinfo2/remote.c b/hardinfo2/remote.c index 1ce74abb..b8fea323 100644 --- a/hardinfo2/remote.c +++ b/hardinfo2/remote.c @@ -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 && 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, -					"Remote host didn't respond."); +					GTK_BUTTONS_NONE, +					"Remote host didn't respond. Try again?"); -	gtk_dialog_run(GTK_DIALOG(dialog)); +	gtk_dialog_add_buttons(GTK_DIALOG(dialog), +			       GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, +			       "Try again", 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("http://%s:%d/xmlrpc", 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("Done."); @@ -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("Establishing SSH tunnel..."); @@ -358,6 +376,7 @@ static void remote_connect_ssh(gchar *hostname,      ssh_response = ssh_new(uri, &ssh_conn, "hardinfo -x");      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->fd_read, buffer, sizeof(buffer), &bytes_read); -        if (bytes_read != 0 && res > 0) { +        if (bytes_read != 0 && res == 1) {              if (strncmp(buffer, "XML-RPC server ready", 20) == 0) { -                if (remote_connect_direct("localhost", 4343)) { -                    goto ok; +                DEBUG("%s", buffer); +                 +                if (remote_connect_direct("127.0.0.1", 4343)) { +                    DEBUG("connected! :)"); +                    goto out;                  } -                /* TODO FIXME Perhaps the server is already running; try to fix */                 +                DEBUG("unknown error while trying to connect... wtf?");              } + +            /* TODO FIXME Perhaps the server is already running; try to fix */                 +            DEBUG("hardinfo already running there?");          } -        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, -                                    "Cannot establish tunnel."); - -    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, +                                                    "<b><big>Cannot establish tunnel.</big></b>\n" +                                                    "<i>%s</i>\n\n" +                                                    "Please verify that:\n" +                                                    "\342\200\242 The hostname <b>%s</b> is correct;\n" +                                                    "\342\200\242 There is a SSH server running on port <b>%d</b>;\n" +                                                    "\342\200\242 Your username/password combination is correct.", +                                                    ssh_response == SSH_CONN_OK ? "" : 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("Done.");  }                                 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->txt_hostname));          const gint selected_type = gtk_combo_box_get_active(GTK_COMBO_BOX(he->cmb_type));          const gint port = (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(he->txt_port)); +         +        gtk_widget_set_sensitive(he->dialog, FALSE);          if (selected_type == 1) {              gchar *username = (gchar *)gtk_entry_get_text(GTK_ENTRY(he->txt_ssh_user)); diff --git a/hardinfo2/shell.c b/hardinfo2/shell.c index b84446b7..5ecefac6 100644 --- a/hardinfo2/shell.c +++ b/hardinfo2/shell.c @@ -745,7 +745,9 @@ static gboolean update_field(gpointer data)      DEBUG("update_field [%s]", fu->field_name);      iter = g_hash_table_lookup(update_tbl, fu->field_name); -    g_return_val_if_fail(iter != NULL, FALSE); +    if (!iter) { +        return FALSE; +    }      /* if the entry is still selected, update it */      if (iter && fu->entry->selected && fu->entry->fieldfunc) { diff --git a/hardinfo2/ssh-conn.c b/hardinfo2/ssh-conn.c index b5c22eaf..d73c2a57 100644 --- a/hardinfo2/ssh-conn.c +++ b/hardinfo2/ssh-conn.c @@ -32,27 +32,24 @@  #include <string.h>  #include <errno.h>  #include <linux/termios.h> - +#include <sys/types.h> +#include <sys/wait.h> +         #include "ssh-conn.h" -static const char *errors[] = { +const char *ssh_conn_errors[] = {      "OK", -    "No URI", +    "No URI specified",      "Unknown protocol",      "Unknown error",      "Cannot spawn SSH",      "Bad parameters", -    "Permission denied", +    "Permission denied (invalid credentials)",      "Host key verification failed",      "Connection refused",      "Invalid username or password"  }; -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->fd_write);      close(conn->fd_error); -    soup_uri_free(conn->uri); +    if (conn->uri) { +        soup_uri_free(conn->uri); +    } +          kill(conn->pid, SIGINT);      if (conn->askpass_path) { @@ -227,42 +227,41 @@ SSHConnResponse ssh_new(SoupURI * uri,      }      connection = g_new0(SSHConn, 1); +    connection->exit_status = -1;      DEBUG("spawning SSH");      if (!g_spawn_async_with_pipes(NULL, argv, NULL,  				  G_SPAWN_SEARCH_PATH,  				  ssh_conn_setup, askpass_path, -				  (gint *) & connection->pid, +				  &connection->pid,  				  &connection->fd_write,  				  &connection->fd_read,  				  &connection->fd_error, NULL)) {  	response = SSH_CONN_CANNOT_SPAWN_SSH;  	goto end;      } - +          memset(buffer, 0, sizeof(buffer));      res = ssh_read(connection->fd_error, &buffer, sizeof(buffer),  		   &bytes_read);      DEBUG("bytes read: %d, result = %d", bytes_read, res); -    if (bytes_read != 0 && res > 0) { +    if (bytes_read > 0 && res == 1) {  	DEBUG("Received (error channel): [%s]", buffer); -	if (g_str_equal(buffer, "Permission denied")) { +	if (g_str_has_prefix(buffer, "Permission denied")) {  	    response = SSH_CONN_PERMISSION_DENIED; -	} else if (g_str_equal(buffer, "Host key verification failed")) { +	    goto end; +	} else if (g_str_has_prefix(buffer, "Host key verification failed")) {  	    response = SSH_CONN_HOST_KEY_CHECK_FAIL;  	    goto end; -	} else if (g_str_equal(buffer, "Connection refused")) { +	} else if (g_str_has_prefix(buffer, "Connection refused")) {  	    response = SSH_CONN_REFUSED;  	    goto end; -	} else if (g_str_has_prefix(buffer, "Host key fingerprint is")) { -	    /* ok */ -	} else { -	    response = SSH_CONN_UNKNOWN_ERROR; -	    goto end;  	}      } +     +    DEBUG("no error detected; ssh conn established");      connection->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->uri) { +            soup_uri_free(connection->uri); +        } +          	g_free(connection); +  	*conn_return = NULL;      } else {  	*conn_return = connection;      } -    DEBUG("response = %d (%s)", -	  response, response == SSH_CONN_OK ? "OK" : "Error"); +    DEBUG("response = %d (%s)", 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, &c, argv[2]); -    g_print("Connection result: %s\n", errors[r]); +    g_print("Connection result: %s\n", ssh_conn_errors[r]);      if (r == SSH_CONN_OK) {  	int bytes_read; diff --git a/hardinfo2/ssh-conn.h b/hardinfo2/ssh-conn.h index 24e196cd..654f90c3 100644 --- a/hardinfo2/ssh-conn.h +++ b/hardinfo2/ssh-conn.h @@ -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 --git a/hardinfo2/util.c b/hardinfo2/util.c index 3a1409d2..f35f0ac1 100644 --- a/hardinfo2/util.c +++ b/hardinfo2/util.c @@ -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->dll)); -    g_hash_table_foreach_remove(__module_methods, remove_module_methods, name);      if (module->dll) { +        gchar *name; +         +        name = g_path_get_basename(g_module_name(module->dll)); +        g_hash_table_foreach_remove(__module_methods, remove_module_methods, name); +              	g_module_close(module->dll); +    	g_free(name);      }      g_free(module->name); @@ -610,7 +612,6 @@ static void module_unload(ShellModule * module)      g_slist_free(module->entries);      g_free(module); -    g_free(name);  }  void module_unload_all(void)  | 
