aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hardinfo2/callbacks.c3
-rw-r--r--hardinfo2/remote.c93
-rw-r--r--hardinfo2/shell.c4
-rw-r--r--hardinfo2/ssh-conn.c51
-rw-r--r--hardinfo2/ssh-conn.h6
-rw-r--r--hardinfo2/util.c11
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)