From ff98a0702c71e1b729ed227b202ec40edb7b2d9c Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Sat, 4 Sep 2010 15:07:02 +0200 Subject: Added proper error handling to server communication. --- commands.c | 12 +++++--- server_communication.c | 83 +++++++++++++++++++++----------------------------- server_communication.h | 8 ++--- 3 files changed, 45 insertions(+), 58 deletions(-) diff --git a/commands.c b/commands.c index d182996..81650ee 100644 --- a/commands.c +++ b/commands.c @@ -46,9 +46,8 @@ static void list_remote(GString *string, gchar *remotename, gchar *dirname, GErr return; } - gchar **data = server_list(server, dirname); + gchar **data = server_list(server, dirname, error); if(data == NULL) { - *error = g_error_new(commands_quark(), 0, "couldn't retrieve list"); return; } @@ -148,8 +147,11 @@ static void commands_find(GSocketConnection *connection, const gchar *cmd, GErro for(GSList *node = servers; node; node = g_slist_next(node)) { struct server *server = node->data; g_debug("fetching data from server %s", server->host); - gchar **temp = server_find(server, data[1], data[2]); + gchar **temp = server_find(server, data[1], data[2], error); if(temp == NULL) { + g_warning((*error)->message); + g_error_free(*error); + *error = NULL; continue; } for(gint i = 0; i < g_strv_length(temp); i++) { @@ -186,7 +188,7 @@ static void commands_get(GSocketConnection *connection, const gchar *cmd, GError if(g_strv_length(data) != 5) { g_strfreev(data); - *error = g_error_new(commands_quark(), 0, "syntax: get TYPE LOCALFILE REMOTEHOST REMOTEFILE"); + *error = g_error_new(commands_quark(), 0, "syntax: get TYPE LOCALFILE REMOTENAME REMOTEFILE"); return; } @@ -203,7 +205,7 @@ static void commands_get(GSocketConnection *connection, const gchar *cmd, GError gchar *localfile = g_uri_unescape_string(data[2], NULL); gchar *remotefile = g_uri_unescape_string(data[4], NULL); - server_get(server, data[1], localfile, remotefile); + server_get(server, data[1], localfile, remotefile, error); g_free(localfile); g_free(remotefile); diff --git a/server_communication.c b/server_communication.c index e8ab7b8..72e3386 100644 --- a/server_communication.c +++ b/server_communication.c @@ -9,8 +9,8 @@ enum connection_type { SERVER_CONNECTION_TYPE_COMMAND, }; -static GSocket *server_connect(struct server *server, const enum connection_type type) { - GError *error = NULL, *conn_error = NULL; +static GSocket *server_connect(struct server *server, const enum connection_type type, GError **error) { + GError *conn_error = NULL; GSocketConnectable *addr; GSocketAddressEnumerator *enumerator; GSocketAddress *sockaddr; @@ -33,46 +33,38 @@ static GSocket *server_connect(struct server *server, const enum connection_type client = g_socket_client_new(); - while(conn == NULL && (sockaddr = g_socket_address_enumerator_next(enumerator, NULL, &error))) { + while(conn == NULL && (sockaddr = g_socket_address_enumerator_next(enumerator, NULL, error))) { conn = g_socket_client_connect(client, (GSocketConnectable*)sockaddr, NULL, &conn_error); g_object_unref(sockaddr); } - if(sockaddr == NULL) { - if(error != NULL) { - g_warning(error->message); - g_error_free(error); - } else { - g_warning("server_connect: no connectable addresses found for host %s", - server->host); + if(conn != NULL) { + if(conn_error != NULL) { + g_error_free(conn_error); + } + return g_socket_connection_get_socket(conn); + } else if(*error != NULL) { + if(conn_error != NULL) { + g_error_free(conn_error); } return NULL; - } - - if(conn == NULL) { - g_warning(conn_error->message); - g_error_free(conn_error); + } else { + g_propagate_error(error, conn_error); return NULL; } - - GSocket *socket = g_socket_connection_get_socket(conn); - - g_debug("connected"); - - return socket; } -static GSocket *server_connect_http(struct server *server) { - return server_connect(server, SERVER_CONNECTION_TYPE_HTTP); +static GSocket *server_connect_http(struct server *server, GError **error) { + return server_connect(server, SERVER_CONNECTION_TYPE_HTTP, error); } -static GSocket *server_connect_command(struct server *server) { - return server_connect(server, SERVER_CONNECTION_TYPE_COMMAND); +static GSocket *server_connect_command(struct server *server, GError **error) { + return server_connect(server, SERVER_CONNECTION_TYPE_COMMAND, error); } -gboolean server_ping(struct server *server) { +gboolean server_ping(struct server *server, GError **error) { GTimer *timer = g_timer_new(); - GSocket *socket = server_connect_command(server); + GSocket *socket = server_connect_command(server, error); if(socket == NULL) { return FALSE; @@ -94,8 +86,8 @@ gboolean server_ping(struct server *server) { return result; } -static gchar **server_get_stringlist(struct server *server, const gchar *cmd) { - GSocket *socket = server_connect_command(server); +static gchar **server_get_stringlist(struct server *server, const gchar *cmd, GError **error) { + GSocket *socket = server_connect_command(server, error); if(socket == NULL) { return NULL; @@ -118,26 +110,25 @@ static gchar **server_get_stringlist(struct server *server, const gchar *cmd) { return data; } -gchar **server_find(struct server *server, const gchar *type, const gchar *str) { +gchar **server_find(struct server *server, const gchar *type, const gchar *str, GError **error) { gchar *cmd = g_strdup_printf("findl %s %s\nexit\n", type, str); - gchar **data = server_get_stringlist(server, cmd); + gchar **data = server_get_stringlist(server, cmd, error); g_free(cmd); return data; } -gchar **server_list(struct server *server, const gchar *directory) { +gchar **server_list(struct server *server, const gchar *directory, GError **error) { gchar *cmd = g_strdup_printf("list %s\nexit\n", directory); - gchar **data = server_get_stringlist(server, cmd); + gchar **data = server_get_stringlist(server, cmd, error); g_free(cmd); return data; } gboolean server_get(struct server *server, const gchar *type, - const gchar *localfile, const gchar *remotefile) { - GError *error = NULL; - GSocket *socket = server_connect_http(server); + const gchar *localfile, const gchar *remotefile, GError **error) { + GSocket *socket = server_connect_http(server, error); if(socket == NULL) { return FALSE; @@ -154,43 +145,37 @@ gboolean server_get(struct server *server, const gchar *type, gchar *line = NULL; gsize size; - while((line = g_data_input_stream_read_line(input, &size, NULL, &error)) != NULL) { + while((line = g_data_input_stream_read_line(input, &size, NULL, error)) != NULL) { g_debug(line); if(size == 0) { break; } } - if(error != NULL) { - g_warning(error->message); - g_error_free(error); + if(*error != NULL) { return FALSE; } GFile *file = g_file_new_for_path(localfile); - GFileOutputStream *output = g_file_replace(file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error); + GFileOutputStream *output = g_file_replace(file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error); if(output == NULL) { - g_warning(error->message); - g_error_free(error); return FALSE; } g_output_stream_splice((GOutputStream*)output, (GInputStream*)input, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, - NULL, &error); + NULL, error); g_object_unref(input); g_object_unref(output); g_object_unref(file); + g_object_unref(connection); + g_object_unref(socket); - if(error != NULL) { - g_warning(error->message); - g_error_free(error); + if(*error != NULL) { return FALSE; } - g_object_unref(connection); - return TRUE; } diff --git a/server_communication.h b/server_communication.h index ecf1fdb..023ebd1 100644 --- a/server_communication.h +++ b/server_communication.h @@ -5,10 +5,10 @@ #include -gboolean server_ping(struct server *server); -gchar **server_find(struct server *server, const gchar *type, const gchar *str); -gchar **server_list(struct server *server, const gchar *directory); +gboolean server_ping(struct server *server, GError **error); +gchar **server_find(struct server *server, const gchar *type, const gchar *str, GError **error); +gchar **server_list(struct server *server, const gchar *directory, GError **error); gboolean server_get(struct server *server, const gchar *type, - const gchar *localfile, const gchar *remotefile); + const gchar *localfile, const gchar *remotefile, GError **error); #endif -- cgit v1.2.3