diff options
| -rw-r--r-- | commands.c | 56 | ||||
| -rw-r--r-- | main.c | 3 | ||||
| -rw-r--r-- | server.c | 57 | ||||
| -rw-r--r-- | server.h | 9 | ||||
| -rw-r--r-- | server_commands.c | 73 | ||||
| -rw-r--r-- | server_commands.h | 9 | 
6 files changed, 152 insertions, 55 deletions
| @@ -22,58 +22,6 @@ static void send_404(GSocketConnection *connection) {  	}  } -static void commands_list(GSocketConnection *connection, const gchar *cmd) { -	GError *error = NULL; -	gchar **data = g_strsplit(cmd, " ", 2); -	for(gint i = 0; data[i]; i++) { -		g_debug("\tdata[%d] = %s", i, data[i]); -	} -	g_assert(data[0] != NULL && data[1] != NULL); - -	gchar *dirname = g_strdup(data[1]); -	g_strfreev(data); - -	struct directory *directory = music_find_dir(dirname); -	if(directory == NULL) { -		g_warning("couldn't find directory %s", dirname); -		send_404(connection); -		return; -	} - -	GString *list_string = g_string_new(NULL); - -	for(GSList *node = directory->sub; node; node = g_slist_next(node)) { -		struct directory *d = node->data; -		gchar *name = g_path_get_basename(d->path); -		g_string_append_printf(list_string, "%s\n", name); -		g_free(name); -	} - -	for(GSList *node = directory->files; node; node = g_slist_next(node)) { -		struct file *f = node->data; -		g_string_append_printf(list_string, "%s\n", f->name); -	} - -	GString *string = g_string_new(NULL); - -	g_string_append(string, "HTTP/1.1 200 OK\r\n"); -	g_string_append(string, "content-type: text/plain\r\n"); -	g_string_append_printf(string, "content-length: %lu\r\n", list_string->len); -	g_string_append(string, "\r\n"); -	g_string_append(string, list_string->str); - -	g_string_free(list_string, TRUE); - -	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); -} -  static void commands_get_raw(GSocketConnection *connection, const gchar *cmd) {  	GError *error = NULL;  	gchar **data = g_strsplit(cmd, " ", 2); @@ -225,9 +173,7 @@ commands_get_mp3_free_path:  void commands_handle(GSocketConnection *connection, const gchar *cmd) {  	g_debug("handling command string %s", cmd); -	if(g_ascii_strncasecmp(cmd, "/list", 5) == 0) { -		commands_list(connection, cmd); -	} else if(g_ascii_strncasecmp(cmd, "/get_raw", 8) == 0) { +	if(g_ascii_strncasecmp(cmd, "/get_raw", 8) == 0) {  		commands_get_raw(connection, cmd);  	} else if(g_ascii_strncasecmp(cmd, "/get_mp3", 8) == 0) {  		commands_get_mp3(connection, cmd); @@ -1,5 +1,6 @@  #include "music.h"  #include "httpd.h" +#include "server.h"  #include <glib.h>  #include <glib-object.h> @@ -19,6 +20,7 @@ int main(int argc, char **argv) {  	music_init(argv[1]);  	music_scan_root(); +	server_start();  	httpd_start();  	signal(SIGINT, sig_handler); @@ -28,6 +30,7 @@ int main(int argc, char **argv) {  	g_main_loop_unref(main_loop);  	httpd_stop(); +	server_stop();  	music_free();  	return 0; diff --git a/server.c b/server.c new file mode 100644 index 0000000..1015572 --- /dev/null +++ b/server.c @@ -0,0 +1,57 @@ +#include "server_commands.h" + +#include <gio/gio.h> + +static GSocketService *ss = NULL; + +static gboolean service_incoming(GSocketService *service, +		GSocketConnection *connection, GObject *source_object, +		gpointer user_data) { +	GError *error = NULL; +	GSocket *socket = g_socket_connection_get_socket(connection); +	gchar buffer[0x400]; + +	while(g_socket_is_connected(socket) == TRUE) { +		gssize size = g_socket_receive(socket, buffer, 0x400, NULL, &error); + +		if(size < 0) { +			g_warning(error->message); +			return FALSE; +		} else if(size == 0) { +			break; +		} + +		g_debug("size == %d", size); +		g_debug(buffer); + +		gchar *pos = g_strstr_len(buffer, size, "\r"); +		if(pos == NULL) { +			pos = g_strstr_len(buffer, size, "\n"); +		} +		if(pos == NULL) { +			g_warning("EOL not found"); +			return FALSE; +		} +		*pos = '\0'; + +		server_commands_handle(connection, buffer); +	} + +	return FALSE; +} + +gboolean server_start() { +	ss = g_threaded_socket_service_new(10); + +	g_socket_listener_add_inet_port((GSocketListener*)ss, 7681, NULL, NULL); + +	g_signal_connect(ss, "incoming", (GCallback)service_incoming, NULL); +	g_socket_service_start(ss); + +	return TRUE; +} + +void server_stop() { +	g_socket_service_stop(ss); +	g_object_unref(ss); +} diff --git a/server.h b/server.h new file mode 100644 index 0000000..690b9c0 --- /dev/null +++ b/server.h @@ -0,0 +1,9 @@ +#ifndef _SERVER_H_ +#define _SERVER_H_ + +#include <glib.h> + +gboolean server_start(); +void server_stop(); + +#endif diff --git a/server_commands.c b/server_commands.c new file mode 100644 index 0000000..4442a1b --- /dev/null +++ b/server_commands.c @@ -0,0 +1,73 @@ +#include "server_commands.h" +#include "music.h" + +static void send_404(GSocketConnection *connection) { +	GError *error = NULL; +	GString *string = g_string_new(NULL); +	g_string_append(string, "HTTP/1.1 404 Not Found\r\n"); +	g_string_append(string, "\r\n"); + +	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); +	} +} + +static void commands_list(GSocketConnection *connection, const gchar *cmd) { +	GError *error = NULL; +	gchar **data = g_strsplit(cmd, " ", 2); +	for(gint i = 0; data[i]; i++) { +		g_debug("\tdata[%d] = %s", i, data[i]); +	} +	g_assert(data[0] != NULL); + +	gchar *dirname; +	if(data[1] != NULL) { +		dirname = g_strdup(data[1]); +	} else { +		dirname = "/"; +	} + +	g_strfreev(data); + +	struct directory *directory = music_find_dir(dirname); +	if(directory == NULL) { +		g_warning("couldn't find directory %s", dirname); +		send_404(connection); +		return; +	} + +	GString *string = g_string_new(NULL); + +	for(GSList *node = directory->sub; node; node = g_slist_next(node)) { +		struct directory *d = node->data; +		gchar *name = g_path_get_basename(d->path); +		g_string_append_printf(string, "%s\n", name); +		g_free(name); +	} + +	for(GSList *node = directory->files; node; node = g_slist_next(node)) { +		struct file *f = node->data; +		g_string_append_printf(string, "%s\n", f->name); +	} + +	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 server_commands_handle(GSocketConnection *connection, const gchar *cmd) { +	g_debug(cmd); +	if(g_strncasecmp(cmd, "list", 4) == 0) { +		commands_list(connection, cmd); +	} else { +		g_debug("unknown command"); +	} +} diff --git a/server_commands.h b/server_commands.h new file mode 100644 index 0000000..3a073b3 --- /dev/null +++ b/server_commands.h @@ -0,0 +1,9 @@ +#ifndef _SERVER_COMMANDS_H_ +#define _SERVER_COMMANDS_H_ + +#include <glib.h> +#include <gio/gio.h> + +void server_commands_handle(GSocketConnection *connection, const gchar *cmd); + +#endif | 
