diff options
| -rw-r--r-- | commands.c | 27 | ||||
| -rw-r--r-- | server_communication.c | 105 | ||||
| -rw-r--r-- | server_communication.h | 2 | 
3 files changed, 134 insertions, 0 deletions
| @@ -175,6 +175,31 @@ static void commands_exit(GSocketConnection *connection, const gchar *cmd, GErro  	g_socket_close(socket, NULL);  } +static void commands_get(GSocketConnection *connection, const gchar *cmd, GError **error) { +	gchar **data = g_strsplit(cmd, " ", 5); + +	if(g_strv_length(data) != 5) { +		g_strfreev(data); +		*error = g_error_new(commands_quark(), 0, "syntax: get TYPE LOCALFILE REMOTEHOST REMOTEFILE"); +		return; +	} + +	struct server *server = NULL; + +	for(GSList *node = servers; node; node = g_slist_next(node)) { +		struct server *temp = node->data; +		if(g_strcasecmp(temp->host, data[3]) == 0) { +			server = temp; +			break; +		} +	} + + +	server_get(server, data[1], data[2], data[4]); + +	g_strfreev(data); +} +  void commands_handle(GSocketConnection *connection, const gchar *cmd, GError **error) {  	g_debug(cmd);  	if(g_strncasecmp(cmd, "ping", 4) == 0) { @@ -185,6 +210,8 @@ void commands_handle(GSocketConnection *connection, const gchar *cmd, GError **e  		commands_find(connection, cmd, error);  	} else if(g_strncasecmp(cmd, "exit", 4) == 0) {  		commands_exit(connection, cmd, error); +	} else if(g_strncasecmp(cmd, "get", 3) == 0) { +		commands_get(connection, cmd, error);  	} else {  		g_debug("unknown command");  		*error = g_error_new(commands_quark(), 0, "unknown command %s", cmd); diff --git a/server_communication.c b/server_communication.c index cc37cde..ffe6942 100644 --- a/server_communication.c +++ b/server_communication.c @@ -110,3 +110,108 @@ gchar **server_list(struct server *server, const gchar *directory) {  	return data;  } + +/* TODO: remove temporary function */ +static GSocket *server_connect_port(struct server *server, gushort port) { +	GError *error = NULL, *conn_error = NULL; +	GSocketConnectable *addr; +	GSocketAddressEnumerator *enumerator; +	GSocketAddress *sockaddr; +	GSocketConnection *conn = NULL; +	GSocketClient *client; + +	addr = g_network_address_new(server->host, port); +	enumerator = g_socket_connectable_enumerate(addr); +	g_object_unref(addr); + +	client = g_socket_client_new(); + +	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); +		} +		return NULL; +	} + +	if(conn == NULL) { +		g_warning(conn_error->message); +		g_error_free(conn_error); +		return NULL; +	} + +	GSocket *socket = g_socket_connection_get_socket(conn); + +	g_debug("connected"); + +	return socket; +} + +gboolean server_get(struct server *server, const gchar *type, +		const gchar *localfile, const gchar *remotefile) { +	GError *error = NULL; +	GSocket *socket = server_connect_port(server, 8000); + +	if(socket == NULL) { +		return FALSE; +	} + +	gchar *cmd = g_strdup_printf("GET /get_%s %s HTTP/1.1\r\n\r\n", type, remotefile); + +	g_socket_send(socket, cmd, strlen(cmd), NULL, NULL); + +	GSocketConnection *connection = g_socket_connection_factory_create_connection(socket); +	GDataInputStream *input = g_data_input_stream_new(g_io_stream_get_input_stream((GIOStream*)connection)); +	g_data_input_stream_set_newline_type(input, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); + +	gchar *line = NULL; +	gsize size; + +	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); +		return FALSE; +	} + +	GFile *file = g_file_new_for_path(localfile); +	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); + +	g_object_unref(input); +	g_object_unref(output); +	g_object_unref(file); + +	if(error != NULL) { +		g_warning(error->message); +		g_error_free(error); +		return FALSE; +	} + +	g_object_unref(connection); + +	return TRUE; +} diff --git a/server_communication.h b/server_communication.h index 7d7bc7c..ecf1fdb 100644 --- a/server_communication.h +++ b/server_communication.h @@ -8,5 +8,7 @@  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_get(struct server *server, const gchar *type, +		const gchar *localfile, const gchar *remotefile);  #endif | 
