From 12077e596832cd5908a1c97caa017bb5198fc024 Mon Sep 17 00:00:00 2001
From: Jon Bergli Heier <snakebite@jvnv.net>
Date: Thu, 26 Aug 2010 21:37:18 +0200
Subject: Search in added servers when searching from the control service using
 'find'.

---
 control_commands.c     | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
 server_communication.c | 17 +++++++--------
 server_communication.h |  1 +
 3 files changed, 68 insertions(+), 9 deletions(-)

diff --git a/control_commands.c b/control_commands.c
index 61477ac..f8f3a54 100644
--- a/control_commands.c
+++ b/control_commands.c
@@ -1,5 +1,7 @@
 #include "control_commands.h"
 #include "servers.h"
+#include "music.h"
+#include "server_communication.h"
 
 #include <glib.h>
 #include <string.h>
@@ -14,9 +16,66 @@ static void list_servers(GSocketConnection *connection, const gchar *cmd) {
 	}
 }
 
+static void commands_find(GSocketConnection *connection, const gchar *cmd) {
+	GError *error = NULL;
+	gchar **data = g_strsplit(cmd, " ", 3);
+
+	if(g_strv_length(data) != 3) {
+		const gchar *buf = "syntax: find (artist) search\n";
+		GSocket *socket = g_socket_connection_get_socket(connection);
+		g_socket_send(socket, buf, strlen(buf), NULL, NULL);
+		return;
+	}
+
+	GSList *list = NULL;
+	g_debug("strlen(%s) == %d", data[1], strlen(data[1]));
+	if(g_ascii_strcasecmp(data[1], "artist") == 0) {
+		g_debug("artist search");
+		list = music_find_artist(data[2]);
+	} else {
+		g_debug("unknown search");
+	}
+
+	GString *string = g_string_new(NULL);
+	for(GSList *node = list; node; node = g_slist_next(node)) {
+		struct file *f = node->data;
+		gchar *relpath = g_build_filename(f->parent->path +
+				strlen(music_root->path), f->name, NULL);
+		g_string_append_printf(string, "%s\n", relpath);
+		g_free(relpath);
+	}
+	g_slist_free(list);
+
+	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]);
+		if(temp == NULL) {
+			continue;
+		}
+		for(gint i = 1; i < g_strv_length(temp); i++) {
+			if(strlen(temp[i]) == 0) {
+				break;
+			}
+			g_string_append_printf(string, "%s:%s\n", server->host, temp[i]);
+		}
+		g_strfreev(temp);
+	}
+
+	GOutputStream *os = g_io_stream_get_output_stream((GIOStream*)connection);
+	if(g_output_stream_write_all(os, string->str, string->len, NULL, NULL,
+				&error) == FALSE) {
+		g_warning(error->message);
+		g_error_free(error);
+	}
+	g_string_free(string, TRUE);
+}
+
 void control_commands_handle(GSocketConnection *connection, const gchar *cmd) {
 	if(g_strcmp0(cmd, "servers") == 0) {
 		list_servers(connection, cmd);
+	} else if(g_strncasecmp(cmd, "find", 4) == 0) {
+		commands_find(connection, cmd);
 	} else {
 		g_debug("unknown command");
 		gchar *buf = g_strdup_printf("error: unknown command %s\n", cmd);
diff --git a/server_communication.c b/server_communication.c
index 007b599..f331a35 100644
--- a/server_communication.c
+++ b/server_communication.c
@@ -1,4 +1,5 @@
 #include "server_communication.h"
+#include "music.h"
 
 #include <gio/gio.h>
 #include <string.h>
@@ -70,7 +71,7 @@ gboolean server_ping(struct server *server) {
 	return result;
 }
 
-GSList *server_find(struct server *server, const gchar *type, const gchar *str) {
+gchar **server_find(struct server *server, const gchar *type, const gchar *str) {
 	GSocket *socket = server_connect(server);
 
 	if(socket == NULL) {
@@ -81,18 +82,16 @@ GSList *server_find(struct server *server, const gchar *type, const gchar *str)
 	g_snprintf(buffer, 0x400, "find %s %s\nexit\n", type, str);
 	g_socket_send(socket, buffer, strlen(buffer), NULL, NULL);
 
-	GSList *list = NULL;
 	gssize size;
+	GString *string = g_string_new(NULL);
 	while((size = g_socket_receive(socket, buffer, 0x400, NULL, NULL)) > 0) {
-		if(buffer[size - 1] == '\n') {
-			buffer[size - 1] = '\0';
-		}
-		g_debug("got %s", buffer);
+		g_string_append_len(string, buffer, size);
 	}
 
-	g_debug("closed: %d", size);
-
 	g_socket_close(socket, NULL);
 
-	return NULL;
+	gchar **data = g_strsplit(string->str, "\n", 0);
+	g_string_free(string, TRUE);
+
+	return data;
 }
diff --git a/server_communication.h b/server_communication.h
index 552d12e..b154701 100644
--- a/server_communication.h
+++ b/server_communication.h
@@ -6,5 +6,6 @@
 #include <glib.h>
 
 gboolean server_ping(struct server *server);
+gchar **server_find(struct server *server, const gchar *type, const gchar *str);
 
 #endif
-- 
cgit v1.2.3