Somebody claiming to be Max Kellermann wrote: > On 2009/04/07 01:39, Stephen Paul Weber <singpol...@singpolyma.net> wrote: > > Yes, this is exactly the functionality I had in mind :) > > Be sure that old configuration files continue to work.
Attached please find 5 patch files, each the output of a git show for 5 commits that progressively implement this feature :) -- Stephen Paul Weber, @singpolyma Please see <http://singpolyma.net> for how I prefer to be contacted. nerve perfume pogo.
commit 4134470abcc4d23e6c971056826036461882c4eb Author: Stephen Paul Weber <singpol...@singpolyma.net> Date: Tue Apr 7 10:52:34 2009 -0400 Don't assume last.fm AS_HOST + config parsing In fact, don't assume global state for username/password either. A lot of changes to as.c, conn.c, conn.h just to allow a pointer to a struct containing the state instead of assuming global. This patch still just uses the first as_host from the list. file.h and file.c have been modified to actually parse the new config file format and create a linked list of as_hosts. There is a memory leak in the config parser: the linked list is not freed. Since we need it all in memory until shutting down, this is likely not a problem, but a comment reminder has been added. diff --git a/src/as.c b/src/as.c index 545189c..c2fe75d 100644 --- a/src/as.c +++ b/src/as.c @@ -45,8 +45,6 @@ #define MAX_VAR_SIZE 8192 #define MAX_TIMESTAMP_SIZE 64 -#define AS_HOST "http://post.audioscrobbler.com/" - /* don't submit more than this amount of songs in a batch. */ #define MAX_SUBMIT_COUNT 10 @@ -128,13 +126,13 @@ add_var_i(GString * s, const char *key, signed char idx, const char *val) } static void -as_schedule_handshake(void); +as_schedule_handshake(struct config_as_host *as_host); static void -as_submit(void); +as_submit(struct config_as_host *as_host); static void -as_schedule_submit(void); +as_schedule_submit(struct config_as_host *as_host); static void as_increase_interval(void) { @@ -217,7 +215,7 @@ static void as_song_cleanup(struct song *s, int free_struct) free(s); } -static void as_handshake_callback(size_t length, const char *response) +static void as_handshake_callback(size_t length, const char *response, void *as_host) { as_handshaking state = AS_COMMAND; char *newline; @@ -230,7 +228,7 @@ static void as_handshake_callback(size_t length, const char *response) if (!length) { g_warning("handshake timed out\n"); as_increase_interval(); - as_schedule_handshake(); + as_schedule_handshake(as_host); return; } @@ -242,7 +240,7 @@ static void as_handshake_callback(size_t length, const char *response) if (!ret) { g_free(next); as_increase_interval(); - as_schedule_handshake(); + as_schedule_handshake(as_host); return; } @@ -268,7 +266,7 @@ static void as_handshake_callback(size_t length, const char *response) /* handshake was successful: see if we have songs to submit */ - as_submit(); + as_submit(as_host); return; } @@ -279,7 +277,7 @@ static void as_handshake_callback(size_t length, const char *response) } as_increase_interval(); - as_schedule_handshake(); + as_schedule_handshake(as_host); } static void as_queue_remove_oldest(unsigned count) @@ -292,7 +290,7 @@ static void as_queue_remove_oldest(unsigned count) } } -static void as_submit_callback(size_t length, const char *response) +static void as_submit_callback(size_t length, const char *response, void *as_host) { char *newline; @@ -303,7 +301,7 @@ static void as_submit_callback(size_t length, const char *response) g_submit_pending = 0; g_warning("submit timed out\n"); as_increase_interval(); - as_schedule_submit(); + as_schedule_submit(as_host); return; } @@ -329,15 +327,15 @@ static void as_submit_callback(size_t length, const char *response) /* submit the next chunk (if there is some left) */ - as_submit(); + as_submit(as_host); break; case AS_SUBMIT_FAILED: as_increase_interval(); - as_schedule_submit(); + as_schedule_submit(as_host); break; case AS_SUBMIT_HANDSHAKE: g_state = AS_NOTHING; - as_schedule_handshake(); + as_schedule_handshake(as_host); break; } } @@ -403,7 +401,7 @@ static char *as_md5(const char *password, const char *timestamp) return result; } -static void as_handshake(void) +static void as_handshake(struct config_as_host *as_host) { GString *url; char *timestr, *md5; @@ -411,15 +409,15 @@ static void as_handshake(void) g_state = AS_HANDSHAKING; timestr = as_timestamp(); - md5 = as_md5(file_config.password, timestr); + md5 = as_md5(as_host->password, timestr); /* construct the handshake url. */ - url = g_string_new(AS_HOST); + url = g_string_new(as_host->url); first_var(url, "hs", "true"); add_var(url, "p", "1.2"); add_var(url, "c", AS_CLIENT_ID); add_var(url, "v", AS_CLIENT_VERSION); - add_var(url, "u", file_config.username); + add_var(url, "u", as_host->username); add_var(url, "t", timestr); add_var(url, "a", md5); @@ -428,42 +426,42 @@ static void as_handshake(void) // notice ("handshake url:\n%s", url); - if (!conn_initiate(url->str, &as_handshake_callback, NULL)) { + if (!conn_initiate(url->str, &as_handshake_callback, NULL, as_host)) { g_warning("something went wrong when trying to connect, " "probably a bug\n"); g_state = AS_NOTHING; as_increase_interval(); - as_schedule_handshake(); + as_schedule_handshake(as_host); } g_string_free(url, true); } static gboolean -as_handshake_timer(G_GNUC_UNUSED gpointer data) +as_handshake_timer(gpointer data) { assert(g_state == AS_NOTHING); as_handshake_id = 0; - as_handshake(); + as_handshake(data); return false; } static void -as_schedule_handshake(void) +as_schedule_handshake(struct config_as_host *as_host) { assert(g_state == AS_NOTHING); assert(as_handshake_id == 0); as_handshake_id = g_timeout_add_seconds(g_interval, - as_handshake_timer, NULL); + as_handshake_timer, as_host); } static void as_send_now_playing(const char *artist, const char *track, - const char *album, const char *mbid, const int length) + const char *album, const char *mbid, const int length, struct config_as_host *as_host) { GString *post_data; char len[MAX_VAR_SIZE]; @@ -487,12 +485,12 @@ as_send_now_playing(const char *artist, const char *track, g_message("sending 'now playing' notification\n"); if (!conn_initiate(g_nowplay_url, as_submit_callback, - post_data->str)) { + post_data->str, as_host)) { g_warning("failed to POST to %s\n", g_nowplay_url); g_state = AS_READY; as_increase_interval(); - as_schedule_submit(); + as_schedule_submit(as_host); } g_string_free(post_data, true); @@ -511,10 +509,10 @@ as_now_playing(const char *artist, const char *track, g_now_playing.length = length; if (g_state == AS_READY && as_submit_id == 0) - as_schedule_submit(); + as_schedule_submit(&file_config.as_hosts); /* TODO: actually iterate over all hosts */ } -static void as_submit(void) +static void as_submit(struct config_as_host *as_host) { //MAX_SUBMIT_COUNT unsigned count = 0; @@ -532,7 +530,8 @@ static void as_submit(void) g_now_playing.track, g_now_playing.album, g_now_playing.mbid, - g_now_playing.length); + g_now_playing.length, + as_host); } return; @@ -570,13 +569,13 @@ static void as_submit(void) g_submit_pending = count; if (!conn_initiate(g_submit_url, &as_submit_callback, - post_data->str)) { + post_data->str, as_host)) { g_warning("something went wrong when trying to connect," " probably a bug\n"); g_state = AS_READY; as_increase_interval(); - as_schedule_submit(); + as_schedule_submit(as_host); } g_string_free(post_data, true); @@ -624,7 +623,7 @@ as_songchange(const char *file, const char *artist, const char *track, g_queue_push_tail(queue, current); if (g_state == AS_READY && as_submit_id == 0) - as_schedule_submit(); + as_schedule_submit(&file_config.as_hosts); /* TODO: actually iterate over all hosts */ return g_queue_get_length(queue); } @@ -646,29 +645,29 @@ void as_init(void) conn_setup(); - as_schedule_handshake(); + as_schedule_handshake(&file_config.as_hosts); /* TODO: actually handshake all the hosts */ } static gboolean -as_submit_timer(G_GNUC_UNUSED gpointer data) +as_submit_timer(gpointer data) { assert(g_state == AS_READY); as_submit_id = 0; - as_submit(); + as_submit(data); return false; } static void -as_schedule_submit(void) +as_schedule_submit(struct config_as_host *as_host) { assert(as_submit_id == 0); assert(!g_queue_is_empty(queue) || (g_now_playing.artist != NULL && g_now_playing.track != NULL)); as_submit_id = g_timeout_add_seconds(g_interval, - as_submit_timer, NULL); + as_submit_timer, as_host); } void as_save_cache(void) diff --git a/src/conn.c b/src/conn.c index c8510e4..e87a998 100644 --- a/src/conn.c +++ b/src/conn.c @@ -48,9 +48,9 @@ static struct global g; static void #ifdef HAVE_SOUP_24 conn_callback(G_GNUC_UNUSED SoupSession * session, - SoupMessage * msg, G_GNUC_UNUSED gpointer data) + SoupMessage * msg, gpointer data) #else -conn_callback(SoupMessage * msg, G_GNUC_UNUSED gpointer data) +conn_callback(SoupMessage * msg, gpointer data) #endif { assert(g.pending); @@ -60,12 +60,12 @@ conn_callback(SoupMessage * msg, G_GNUC_UNUSED gpointer data) if (SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) { #ifdef HAVE_SOUP_24 g.callback(msg->response_body->length, - msg->response_body->data); + msg->response_body->data, data); #else - g.callback(msg->response.length, msg->response.body); + g.callback(msg->response.length, msg->response.body, data); #endif } else - g.callback(0, NULL); + g.callback(0, NULL, NULL); } void conn_setup(void) @@ -81,7 +81,7 @@ void conn_setup(void) } int -conn_initiate(char *url, callback_t * callback, char *post_data) +conn_initiate(char *url, callback_t * callback, char *post_data, void *data) { SoupMessage *msg; @@ -125,7 +125,7 @@ conn_initiate(char *url, callback_t * callback, char *post_data) soup_message_set_flags(msg, SOUP_MESSAGE_NO_REDIRECT); g.pending = true; - soup_session_queue_message(g.session, msg, conn_callback, NULL); + soup_session_queue_message(g.session, msg, conn_callback, data); return CONN_OK; } diff --git a/src/conn.h b/src/conn.h index ffea739..918e925 100644 --- a/src/conn.h +++ b/src/conn.h @@ -24,7 +24,7 @@ #include <stdbool.h> #include <stddef.h> -typedef void callback_t(size_t, const char *); +typedef void callback_t(size_t, const char *, void *); #define CONN_FAIL 0 #define CONN_OK 1 @@ -35,7 +35,7 @@ typedef void callback_t(size_t, const char *); void conn_setup(void); void conn_cleanup(void); -int conn_initiate(char *url, callback_t * callback, char *post_data); +int conn_initiate(char *url, callback_t * callback, char *post_data, void *data); bool conn_pending(void); #endif /* CONN_H */ diff --git a/src/file.c b/src/file.c index a2b0434..c6c3575 100644 --- a/src/file.c +++ b/src/file.c @@ -49,6 +49,8 @@ #define FILE_DEFAULT_PORT 6600 #define FILE_DEFAULT_HOST "localhost" +#define AS_HOST "http://post.audioscrobbler.com/" + struct config file_config = { .loc = file_unknown, }; @@ -193,9 +195,17 @@ load_config_file(const char *path) { bool ret; char *data1, *data2; + char **groups; + struct config_as_host *current_host = &file_config.as_hosts; + int i = -1; GKeyFile *file; GError *error = NULL; + /* initialize host, in case there are none */ + current_host->url = NULL; + current_host->username = NULL; + current_host->password = NULL; + ret = g_file_get_contents(path, &data1, NULL, &error); if (!ret) g_error("%s\n", error->message); @@ -216,8 +226,6 @@ load_config_file(const char *path) load_string(file, "pidfile", &file_config.pidfile); load_string(file, "daemon_user", &file_config.daemon_user); - load_string(file, "username", &file_config.username); - load_string(file, "password", &file_config.password); load_string(file, "log", &file_config.log); load_string(file, "cache", &file_config.cache); load_string(file, "host", &file_config.host); @@ -228,6 +236,37 @@ load_config_file(const char *path) &file_config.cache_interval); load_integer(file, "verbose", &file_config.verbose); + groups = g_key_file_get_groups(file, NULL); + while(groups[++i]) { + /* Use default host for mpdscribble group, for backward compatability */ + if(strcmp(groups[i], "mpdscribble") == 0) { + current_host->url = strdup(AS_HOST); + } else { + current_host->url = strdup(groups[i]); + } + + current_host->username = g_key_file_get_string(file, groups[i], "username", &error); + if (error != NULL) + g_error("%s\n", error->message); + if(current_host->username) + current_host->username = strdup(current_host->username); + + current_host->password = g_key_file_get_string(file, groups[i], "password", &error); + if (error != NULL) + g_error("%s\n", error->message); + if(current_host->password) + current_host->password = strdup(current_host->password); + + /* Only allocate a next element if there are more groups */ + if(groups[i+1]) { + current_host->next = malloc(sizeof *current_host->next); + current_host = current_host->next; + } else { + current_host->next = NULL; + } + } + g_strfreev(groups); + g_key_file_free(file); } @@ -257,11 +296,11 @@ int file_read_config(int argc, char **argv) if (!file_config.conf) g_error("cannot find configuration file\n"); - if (file_config.username == NULL || *file_config.username == 0) + if (file_config.as_hosts.username == NULL || *file_config.as_hosts.username == 0) g_error("no audioscrobbler username specified in %s\n", file_config.conf); - if (file_config.password == NULL || *file_config.password == 0) + if (file_config.as_hosts.password == NULL || *file_config.as_hosts.password == 0) g_error("no audioscrobbler password specified in %s\n", file_config.conf); @@ -291,10 +330,9 @@ int file_read_config(int argc, char **argv) void file_cleanup(void) { - g_free(file_config.username); - g_free(file_config.password); g_free(file_config.host); g_free(file_config.log); g_free(file_config.conf); g_free(file_config.cache); + /* XXX: Free linked list */ } diff --git a/src/file.h b/src/file.h index c750c43..25df572 100644 --- a/src/file.h +++ b/src/file.h @@ -24,6 +24,13 @@ enum file_location { file_etc, file_home, file_unknown, }; +struct config_as_host { + char *url; + char *username; + char *password; + struct config_as_host *next; /* Linked list if more than one */ +}; + struct config { /** don't daemonize the mpdscribble process */ gboolean no_daemon; @@ -32,8 +39,6 @@ struct config { char *daemon_user; - char *username; - char *password; char *log; char *cache; char *conf; @@ -44,6 +49,8 @@ struct config { int cache_interval; int verbose; enum file_location loc; + + struct config_as_host as_hosts; }; extern struct config file_config;
commit d41bd4d4d8b71eb139e892ec3661985f28a62cdf Author: Stephen Paul Weber <singpol...@singpolyma.net> Date: Tue Apr 7 11:19:57 2009 -0400 Global state now in struct. All global state crap is now passed around in the as_host struct. diff --git a/src/as.c b/src/as.c index c2fe75d..036e274 100644 --- a/src/as.c +++ b/src/as.c @@ -53,14 +53,6 @@ static const char BADSESSION[] = "BADSESSION"; static const char FAILED[] = "FAILED"; typedef enum { - AS_NOTHING, - AS_HANDSHAKING, - AS_READY, - AS_SUBMITTING, - AS_BADAUTH, -} as_state; - -typedef enum { AS_COMMAND, AS_SESSION, AS_NOWPLAY, @@ -73,19 +65,11 @@ typedef enum { AS_SUBMIT_HANDSHAKE, } as_submitting; -static char *g_session = NULL; -static char *g_nowplay_url = NULL; -static char *g_submit_url = NULL; -static char *g_md5_response = NULL; -static int g_interval = 1; -static as_state g_state = AS_NOTHING; static struct song g_now_playing; static GQueue *queue; static unsigned g_submit_pending; -static guint as_handshake_id, as_submit_id; - static void add_var_internal(GString * s, char sep, const char *key, signed char idx, const char *val) @@ -134,17 +118,17 @@ as_submit(struct config_as_host *as_host); static void as_schedule_submit(struct config_as_host *as_host); -static void as_increase_interval(void) +static void as_increase_interval(struct config_as_host *as_host) { - if (g_interval < 60) - g_interval = 60; + if (as_host->g_interval < 60) + as_host->g_interval = 60; else - g_interval <<= 1; + as_host->g_interval <<= 1; - if (g_interval > 60 * 60 * 2) - g_interval = 60 * 60 * 2; + if (as_host->g_interval > 60 * 60 * 2) + as_host->g_interval = 60 * 60 * 2; - g_warning("waiting %i seconds before trying again\n", g_interval); + g_warning("waiting %i seconds before trying again\n", as_host->g_interval); } static int as_parse_submit_response(const char *line, size_t length) @@ -173,7 +157,7 @@ static int as_parse_submit_response(const char *line, size_t length) } static bool -as_parse_handshake_response(const char *line) +as_parse_handshake_response(const char *line, struct config_as_host *as_host) { static const char *BANNED = "BANNED"; static const char *BADAUTH = "BADAUTH"; @@ -186,15 +170,15 @@ as_parse_handshake_response(const char *line) return true; } else if (!strncmp(line, BANNED, strlen(BANNED))) { g_warning("handshake failed, we're banned (%s)\n", line); - g_state = AS_BADAUTH; + as_host->g_state = AS_BADAUTH; } else if (!strncmp(line, BADAUTH, strlen(BADAUTH))) { g_warning("handshake failed, username or password incorrect (%s)\n", line); - g_state = AS_BADAUTH; + as_host->g_state = AS_BADAUTH; } else if (!strncmp(line, BADTIME, strlen(BADTIME))) { g_warning("handshake failed, clock not synchronized (%s)\n", line); - g_state = AS_BADAUTH; + as_host->g_state = AS_BADAUTH; } else if (!strncmp(line, FAILED, strlen(FAILED))) { g_warning("handshake failed (%s)\n", line); } else { @@ -215,19 +199,20 @@ static void as_song_cleanup(struct song *s, int free_struct) free(s); } -static void as_handshake_callback(size_t length, const char *response, void *as_host) +static void as_handshake_callback(size_t length, const char *response, void *data) { as_handshaking state = AS_COMMAND; char *newline; char *next; bool ret; + struct config_as_host *as_host = data; - assert(g_state == AS_HANDSHAKING); - g_state = AS_NOTHING; + assert(as_host->g_state == AS_HANDSHAKING); + as_host->g_state = AS_NOTHING; if (!length) { g_warning("handshake timed out\n"); - as_increase_interval(); + as_increase_interval(data); as_schedule_handshake(as_host); return; } @@ -236,10 +221,10 @@ static void as_handshake_callback(size_t length, const char *response, void *as_ next = g_strndup(response, newline - response); switch (state) { case AS_COMMAND: - ret = as_parse_handshake_response(next); + ret = as_parse_handshake_response(next, as_host); if (!ret) { g_free(next); - as_increase_interval(); + as_increase_interval(data); as_schedule_handshake(as_host); return; } @@ -247,22 +232,22 @@ static void as_handshake_callback(size_t length, const char *response, void *as_ state = AS_SESSION; break; case AS_SESSION: - g_session = next; + as_host->g_session = next; next = NULL; - g_debug("session: %s\n", g_session); + g_debug("session: %s\n", as_host->g_session); state = AS_NOWPLAY; break; case AS_NOWPLAY: - g_nowplay_url = next; + as_host->g_nowplay_url = next; next = NULL; - g_debug("now playing url: %s\n", g_nowplay_url); + g_debug("now playing url: %s\n", as_host->g_nowplay_url); state = AS_SUBMIT; break; case AS_SUBMIT: - g_submit_url = next; - g_debug("submit url: %s\n", g_submit_url); - g_state = AS_READY; - g_interval = 1; + as_host->g_submit_url = next; + g_debug("submit url: %s\n", as_host->g_submit_url); + as_host->g_state = AS_READY; + as_host->g_interval = 1; /* handshake was successful: see if we have songs to submit */ @@ -276,7 +261,7 @@ static void as_handshake_callback(size_t length, const char *response, void *as_ } - as_increase_interval(); + as_increase_interval(as_host); as_schedule_handshake(as_host); } @@ -290,17 +275,18 @@ static void as_queue_remove_oldest(unsigned count) } } -static void as_submit_callback(size_t length, const char *response, void *as_host) +static void as_submit_callback(size_t length, const char *response, void *data) { char *newline; + struct config_as_host *as_host = data; - assert(g_state == AS_SUBMITTING); - g_state = AS_READY; + assert(as_host->g_state == AS_SUBMITTING); + as_host->g_state = AS_READY; if (!length) { g_submit_pending = 0; g_warning("submit timed out\n"); - as_increase_interval(); + as_increase_interval(as_host); as_schedule_submit(as_host); return; } @@ -311,7 +297,7 @@ static void as_submit_callback(size_t length, const char *response, void *as_hos switch (as_parse_submit_response(response, length)) { case AS_SUBMIT_OK: - g_interval = 1; + as_host->g_interval = 1; /* submission was accepted, so clean up the cache. */ if (g_submit_pending > 0) { @@ -330,11 +316,11 @@ static void as_submit_callback(size_t length, const char *response, void *as_hos as_submit(as_host); break; case AS_SUBMIT_FAILED: - as_increase_interval(); + as_increase_interval(as_host); as_schedule_submit(as_host); break; case AS_SUBMIT_HANDSHAKE: - g_state = AS_NOTHING; + as_host->g_state = AS_NOTHING; as_schedule_handshake(as_host); break; } @@ -406,7 +392,7 @@ static void as_handshake(struct config_as_host *as_host) GString *url; char *timestr, *md5; - g_state = AS_HANDSHAKING; + as_host->g_state = AS_HANDSHAKING; timestr = as_timestamp(); md5 = as_md5(as_host->password, timestr); @@ -430,8 +416,8 @@ static void as_handshake(struct config_as_host *as_host) g_warning("something went wrong when trying to connect, " "probably a bug\n"); - g_state = AS_NOTHING; - as_increase_interval(); + as_host->g_state = AS_NOTHING; + as_increase_interval(as_host); as_schedule_handshake(as_host); } @@ -441,9 +427,9 @@ static void as_handshake(struct config_as_host *as_host) static gboolean as_handshake_timer(gpointer data) { - assert(g_state == AS_NOTHING); + assert(as_host->g_state == AS_NOTHING); - as_handshake_id = 0; + ((struct config_as_host*)data)->as_handshake_id = 0; as_handshake(data); return false; @@ -452,10 +438,10 @@ as_handshake_timer(gpointer data) static void as_schedule_handshake(struct config_as_host *as_host) { - assert(g_state == AS_NOTHING); - assert(as_handshake_id == 0); + assert(as_host->g_state == AS_NOTHING); + assert(as_host->as_handshake_id == 0); - as_handshake_id = g_timeout_add_seconds(g_interval, + as_host->as_handshake_id = g_timeout_add_seconds(as_host->g_interval, as_handshake_timer, as_host); } @@ -466,15 +452,15 @@ as_send_now_playing(const char *artist, const char *track, GString *post_data; char len[MAX_VAR_SIZE]; - assert(g_state == AS_READY); - assert(as_submit_id == 0); + assert(as_host->g_state == AS_READY); + assert(as_host->as_submit_id == 0); - g_state = AS_SUBMITTING; + as_host->g_state = AS_SUBMITTING; snprintf(len, MAX_VAR_SIZE, "%i", length); post_data = g_string_new(NULL); - add_var(post_data, "s", g_session); + add_var(post_data, "s", as_host->g_session); add_var(post_data, "a", artist); add_var(post_data, "t", track); add_var(post_data, "b", album); @@ -484,12 +470,12 @@ as_send_now_playing(const char *artist, const char *track, g_message("sending 'now playing' notification\n"); - if (!conn_initiate(g_nowplay_url, as_submit_callback, + if (!conn_initiate(as_host->g_nowplay_url, as_submit_callback, post_data->str, as_host)) { - g_warning("failed to POST to %s\n", g_nowplay_url); + g_warning("failed to POST to %s\n", as_host->g_nowplay_url); - g_state = AS_READY; - as_increase_interval(); + as_host->g_state = AS_READY; + as_increase_interval(as_host); as_schedule_submit(as_host); } @@ -508,8 +494,9 @@ as_now_playing(const char *artist, const char *track, g_now_playing.mbid = g_strdup(mbid); g_now_playing.length = length; - if (g_state == AS_READY && as_submit_id == 0) - as_schedule_submit(&file_config.as_hosts); /* TODO: actually iterate over all hosts */ + struct config_as_host *as_host = &file_config.as_hosts; + if (as_host->g_state == AS_READY && as_host->as_submit_id == 0) + as_schedule_submit(as_host); /* TODO: actually iterate over all hosts */ } static void as_submit(struct config_as_host *as_host) @@ -519,8 +506,8 @@ static void as_submit(struct config_as_host *as_host) GString *post_data; char len[MAX_VAR_SIZE]; - assert(g_state == AS_READY); - assert(as_submit_id == 0); + assert(as_host->g_state == AS_READY); + assert(as_host->as_submit_id == 0); if (g_queue_is_empty(queue)) { /* the submission queue is empty. See if a "now playing" song is @@ -537,11 +524,11 @@ static void as_submit(struct config_as_host *as_host) return; } - g_state = AS_SUBMITTING; + as_host->g_state = AS_SUBMITTING; /* construct the handshake url. */ post_data = g_string_new(NULL); - add_var(post_data, "s", g_session); + add_var(post_data, "s", as_host->g_session); for (GList *list = g_queue_peek_head_link(queue); list != NULL && count < MAX_SUBMIT_COUNT; @@ -565,16 +552,16 @@ static void as_submit(struct config_as_host *as_host) g_message("submitting %i song%s\n", count, count == 1 ? "" : "s"); g_debug("post data: %s\n", post_data->str); - g_debug("url: %s\n", g_submit_url); + g_debug("url: %s\n", as_host->g_submit_url); g_submit_pending = count; - if (!conn_initiate(g_submit_url, &as_submit_callback, + if (!conn_initiate(as_host->g_submit_url, &as_submit_callback, post_data->str, as_host)) { g_warning("something went wrong when trying to connect," " probably a bug\n"); - g_state = AS_READY; - as_increase_interval(); + as_host->g_state = AS_READY; + as_increase_interval(as_host); as_schedule_submit(as_host); } @@ -622,8 +609,9 @@ as_songchange(const char *file, const char *artist, const char *track, g_queue_push_tail(queue, current); - if (g_state == AS_READY && as_submit_id == 0) - as_schedule_submit(&file_config.as_hosts); /* TODO: actually iterate over all hosts */ + struct config_as_host *as_host = &file_config.as_hosts; + if (as_host->g_state == AS_READY && as_host->as_submit_id == 0) + as_schedule_submit(as_host); /* TODO: actually iterate over all hosts */ return g_queue_get_length(queue); } @@ -632,8 +620,6 @@ void as_init(void) { guint queue_length; - assert(g_state == AS_NOTHING); - g_message("starting mpdscribble (" AS_CLIENT_ID " " AS_CLIENT_VERSION ")\n"); queue = g_queue_new(); @@ -645,15 +631,20 @@ void as_init(void) conn_setup(); + file_config.as_hosts.g_session = NULL; + file_config.as_hosts.g_nowplay_url = NULL; + file_config.as_hosts.g_submit_url = NULL; /* XXX: this needs to get freed in file.c */ + file_config.as_hosts.g_interval = 1; + file_config.as_hosts.g_state = AS_NOTHING; as_schedule_handshake(&file_config.as_hosts); /* TODO: actually handshake all the hosts */ } static gboolean as_submit_timer(gpointer data) { - assert(g_state == AS_READY); + assert(((struct config_as_host *)data)->g_state == AS_READY); - as_submit_id = 0; + ((struct config_as_host *)data)->as_submit_id = 0; as_submit(data); return false; @@ -662,11 +653,11 @@ as_submit_timer(gpointer data) static void as_schedule_submit(struct config_as_host *as_host) { - assert(as_submit_id == 0); + assert(as_host->as_submit_id == 0); assert(!g_queue_is_empty(queue) || (g_now_playing.artist != NULL && g_now_playing.track != NULL)); - as_submit_id = g_timeout_add_seconds(g_interval, + as_host->as_submit_id = g_timeout_add_seconds(as_host->g_interval, as_submit_timer, as_host); } @@ -695,8 +686,5 @@ void as_cleanup(void) g_queue_foreach(queue, free_queue_song, NULL); g_queue_free(queue); - g_free(g_submit_url); - g_free(g_md5_response); - conn_cleanup(); } diff --git a/src/file.h b/src/file.h index 25df572..c0a54e5 100644 --- a/src/file.h +++ b/src/file.h @@ -24,11 +24,27 @@ enum file_location { file_etc, file_home, file_unknown, }; +typedef enum { + AS_NOTHING, + AS_HANDSHAKING, + AS_READY, + AS_SUBMITTING, + AS_BADAUTH, +} as_state; + struct config_as_host { char *url; char *username; char *password; struct config_as_host *next; /* Linked list if more than one */ + /* state stuff to get passed along in as.c */ + guint as_handshake_id; + guint as_submit_id; + char *g_session; + char *g_nowplay_url; + char *g_submit_url; + int g_interval; + as_state g_state; }; struct config {
commit 44dceb50ccc6cd307ba3dc5881224d418f585bcd Author: Stephen Paul Weber <singpol...@singpolyma.net> Date: Tue Apr 7 11:27:24 2009 -0400 Actually handshake and submit for all server. Replace code that took first element of linked list with do...while loops. diff --git a/src/as.c b/src/as.c index 036e274..0444341 100644 --- a/src/as.c +++ b/src/as.c @@ -486,6 +486,7 @@ void as_now_playing(const char *artist, const char *track, const char *album, const char *mbid, const int length) { + struct config_as_host *current_host = &file_config.as_hosts; as_song_cleanup(&g_now_playing, false); g_now_playing.artist = g_strdup(artist); @@ -494,9 +495,10 @@ as_now_playing(const char *artist, const char *track, g_now_playing.mbid = g_strdup(mbid); g_now_playing.length = length; - struct config_as_host *as_host = &file_config.as_hosts; - if (as_host->g_state == AS_READY && as_host->as_submit_id == 0) - as_schedule_submit(as_host); /* TODO: actually iterate over all hosts */ + do { + if (current_host->g_state == AS_READY && current_host->as_submit_id == 0) + as_schedule_submit(current_host); + } while((current_host = current_host->next)); } static void as_submit(struct config_as_host *as_host) @@ -574,6 +576,7 @@ as_songchange(const char *file, const char *artist, const char *track, const char *time2) { struct song *current; + struct config_as_host *current_host = &file_config.as_hosts; /* from the 1.2 protocol draft: @@ -609,9 +612,10 @@ as_songchange(const char *file, const char *artist, const char *track, g_queue_push_tail(queue, current); - struct config_as_host *as_host = &file_config.as_hosts; - if (as_host->g_state == AS_READY && as_host->as_submit_id == 0) - as_schedule_submit(as_host); /* TODO: actually iterate over all hosts */ + do { + if (current_host->g_state == AS_READY && current_host->as_submit_id == 0) + as_schedule_submit(current_host); + } while((current_host = current_host->next)); return g_queue_get_length(queue); } @@ -619,6 +623,7 @@ as_songchange(const char *file, const char *artist, const char *track, void as_init(void) { guint queue_length; + struct config_as_host *current_host = &file_config.as_hosts; g_message("starting mpdscribble (" AS_CLIENT_ID " " AS_CLIENT_VERSION ")\n"); @@ -631,12 +636,14 @@ void as_init(void) conn_setup(); - file_config.as_hosts.g_session = NULL; - file_config.as_hosts.g_nowplay_url = NULL; - file_config.as_hosts.g_submit_url = NULL; /* XXX: this needs to get freed in file.c */ - file_config.as_hosts.g_interval = 1; - file_config.as_hosts.g_state = AS_NOTHING; - as_schedule_handshake(&file_config.as_hosts); /* TODO: actually handshake all the hosts */ + do { + current_host->g_session = NULL; + current_host->g_nowplay_url = NULL; + current_host->g_submit_url = NULL; /* XXX: this needs to get freed in file.c */ + current_host->g_interval = 1; + current_host->g_state = AS_NOTHING; + as_schedule_handshake(current_host); + } while((current_host = current_host->next)); } static gboolean
commit 4086d7ad39dc179c33478ddd320313d45fd54141 Author: Stephen Paul Weber <singpol...@singpolyma.net> Date: Tue Apr 7 12:09:53 2009 -0400 Plug memory leak diff --git a/src/file.c b/src/file.c index c6c3575..ac4fae5 100644 --- a/src/file.c +++ b/src/file.c @@ -328,11 +328,32 @@ int file_read_config(int argc, char **argv) return 1; } +void free_as_host(struct config_as_host *current_host) +{ + if(current_host->url) + free(current_host->url); + if(current_host->username) + free(current_host->username); + if(current_host->password) + free(current_host->password); + if(current_host->g_session) + g_free(current_host->g_session); + if(current_host->g_nowplay_url) + g_free(current_host->g_nowplay_url); + if(current_host->g_submit_url) + g_free(current_host->g_submit_url); + if(current_host->next) { + free_as_host(current_host->next); + free(current_host->next); + } +} + void file_cleanup(void) { g_free(file_config.host); g_free(file_config.log); g_free(file_config.conf); g_free(file_config.cache); - /* XXX: Free linked list */ + + free_as_host(&file_config.as_hosts); }
commit 2c6cd95a7e8a168d85892fd45bcee4d9ada658cc Author: Stephen Paul Weber <singpol...@singpolyma.net> Date: Tue Apr 7 12:10:17 2009 -0400 Better logging, initialize all values diff --git a/src/as.c b/src/as.c index 0444341..0fb4959 100644 --- a/src/as.c +++ b/src/as.c @@ -166,7 +166,7 @@ as_parse_handshake_response(const char *line, struct config_as_host *as_host) /* FIXME: some code duplication between this and as_parse_submit_response. */ if (!strncmp(line, OK, strlen(OK))) { - g_message("handshake ok\n"); + g_message("handshake ok for '%s'\n", as_host->url); return true; } else if (!strncmp(line, BANNED, strlen(BANNED))) { g_warning("handshake failed, we're banned (%s)\n", line); @@ -468,7 +468,7 @@ as_send_now_playing(const char *artist, const char *track, add_var(post_data, "n", ""); add_var(post_data, "m", mbid); - g_message("sending 'now playing' notification\n"); + g_message("sending 'now playing' notification to '%s'\n", as_host->url); if (!conn_initiate(as_host->g_nowplay_url, as_submit_callback, post_data->str, as_host)) { @@ -639,9 +639,11 @@ void as_init(void) do { current_host->g_session = NULL; current_host->g_nowplay_url = NULL; - current_host->g_submit_url = NULL; /* XXX: this needs to get freed in file.c */ + current_host->g_submit_url = NULL; current_host->g_interval = 1; current_host->g_state = AS_NOTHING; + current_host->as_submit_id = 0; + current_host->as_handshake_id = 0; as_schedule_handshake(current_host); } while((current_host = current_host->next)); }
signature.asc
Description: Digital signature
------------------------------------------------------------------------------ This SF.net email is sponsored by: High Quality Requirements in a Collaborative Environment. Download a free trial of Rational Requirements Composer Now! http://p.sf.net/sfu/www-ibm-com
_______________________________________________ Musicpd-dev-team mailing list Musicpd-dev-team@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/musicpd-dev-team