#include "commands.h" #include "music.h" #include #include #include static void commands_list(GSocketConnection *connection, const gchar *cmd) { 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); g_assert(directory != NULL); GSocket *socket = g_socket_connection_get_socket(connection); for(struct directory *d = directory->sub; d; d = d->next) { gchar *name = g_path_get_basename(d->path); g_socket_send(socket, name, strlen(name), NULL, NULL); g_socket_send(socket, "\n", 1, NULL, NULL); g_free(name); } for(struct file *f = directory->files; f; f = f->next) { g_socket_send(socket, f->name, strlen(f->name), NULL, NULL); g_socket_send(socket, "\n", 1, NULL, NULL); } } static void commands_get_raw(GSocketConnection *connection, const gchar *cmd) { GError *error = NULL; gchar **data = g_strsplit(cmd, " ", 2); g_assert(data[0] != NULL && data[1] != NULL); gchar *path = g_strdup(data[1]); g_strfreev(data); struct file *f = music_find_file(path); if(f == NULL) { g_error("couldn't find %s", path); } GOutputStream *os = g_io_stream_get_output_stream((GIOStream*)connection); GFile *file = g_file_new_for_path(path); GFileInputStream *is = g_file_read(file, NULL, &error); if(is == NULL) { g_error(error->message); } GFileInfo *fi = g_file_query_info(file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, &error); if(fi == NULL) { g_error(error->message); } goffset filesize = g_file_info_get_size(fi); g_object_unref(fi); GString *string = g_string_new(NULL); g_string_append(string, "HTTP/1.1 200 OK\r\n"); g_string_append(string, "content-type: octet-stream\r\n"); g_string_append_printf(string, "content-length: %lu\r\n", filesize); g_string_append(string, "\r\n"); if(g_output_stream_write_all(os, string->str, string->len, NULL, NULL, &error) == FALSE) { g_error(error->message); } g_string_free(string, TRUE); gssize size = g_output_stream_splice(os, (GInputStream*)is, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE || G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, NULL, &error); if(size == -1) { g_warning(error->message); } else { g_debug("wrote %lu bytes of file data", size); } g_object_unref(is); g_object_unref(file); g_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) { commands_get_raw(connection, cmd); } else { g_warning("no command handlers found"); } }