diff src/scrobbler/scrobbler.c @ 2441:166397a7efe1

Fixes for scrobbler plugin - skipped tracks, inappropriate scrobbling, re-tabs (Bugzilla #200)
author CJ Kucera <pez@apocalyptech.com>
date Sat, 08 Mar 2008 09:57:38 +0100
parents 447dce6f59f3
children 1286f65395d7
line wrap: on
line diff
--- a/src/scrobbler/scrobbler.c	Fri Mar 07 15:56:40 2008 -0600
+++ b/src/scrobbler/scrobbler.c	Sat Mar 08 09:57:38 2008 +0100
@@ -20,33 +20,33 @@
 #define SCROBBLER_HS_WAIT 1800
 #define SCROBBLER_SB_WAIT 10
 #define SCROBBLER_VERSION "1.2"
-#define SCROBBLER_IMPLEMENTATION "0.2"		/* This is the implementation, not the player version. */
+#define SCROBBLER_IMPLEMENTATION "0.2"      /* This is the implementation, not the player version. */
 #define SCROBBLER_SB_MAXLEN 1024
 #define CACHE_SIZE 1024
 
 /* Scrobblerbackend for xmms plugin, first draft */
 
-static int	sc_hs_status,
-		sc_hs_timeout,
-		sc_hs_errors,
-		sc_sb_errors,
-		sc_bad_users,
-		sc_submit_interval,
-		sc_submit_timeout,
-		sc_srv_res_size,
-		sc_giveup,
-		sc_major_error_present;
+static int  sc_hs_status,
+        sc_hs_timeout,
+        sc_hs_errors,
+        sc_sb_errors,
+        sc_bad_users,
+        sc_submit_interval,
+        sc_submit_timeout,
+        sc_srv_res_size,
+        sc_giveup,
+        sc_major_error_present;
 
-static char 	*sc_submit_url,	/* queue */
-		*sc_np_url,	/* np */
-		*sc_session_id,
-		*sc_username = NULL,
-		*sc_password = NULL,
-		*sc_challenge_hash,
-		sc_response_hash[65535],
-		*sc_srv_res,
-		sc_curl_errbuf[CURL_ERROR_SIZE],
-		*sc_major_error;
+static char     *sc_submit_url, /* queue */
+        *sc_np_url, /* np */
+        *sc_session_id,
+        *sc_username = NULL,
+        *sc_password = NULL,
+        *sc_challenge_hash,
+        sc_response_hash[65535],
+        *sc_srv_res,
+        sc_curl_errbuf[CURL_ERROR_SIZE],
+        *sc_major_error;
 
 static void dump_queue();
 
@@ -59,24 +59,17 @@
 #define I_ALBUM(i) i->album
 
 typedef struct {
-	char *artist, *title, *album;
-	int utctime, track, len;
-	int timeplayed;
-	int numtries;
-	void *next;
+    char *artist, *title, *album;
+    int utctime, track, len;
+    int timeplayed;
+    int numtries;
+    void *next;
 } item_t;
 
 static item_t *q_queue = NULL;
 static item_t *q_queue_last = NULL;
 static int q_nitems;
-
-/* isn't there better way for that? --desowin */
-gboolean sc_timeout(gpointer data) {
-    if (q_queue_last && audacious_drct_get_playing())
-        q_queue_last->timeplayed+=1;
-
-    return TRUE;
-}
+static item_t *np_item = NULL;
 
 gchar *
 xmms_urldecode_plain(const gchar * encoded_path)
@@ -118,518 +111,563 @@
 
 static void q_item_free(item_t *item)
 {
-	if (item == NULL)
-		return;
-	curl_free(item->artist);
-	curl_free(item->title);
-	curl_free(item->album);
-	free(item);
+    if (item == NULL)
+        return;
+    curl_free(item->artist);
+    curl_free(item->title);
+    curl_free(item->album);
+    free(item);
+}
+
+static item_t *q_additem(item_t *newitem)
+{
+    pdebug(fmt_vastr("Adding %s - %s to the queue", newitem->artist, newitem->title), DEBUG);
+
+    q_nitems++;
+    newitem->next = NULL;
+    if (q_queue_last == NULL)
+    {
+        q_queue = q_queue_last = newitem;
+    }
+    else
+    {
+        q_queue_last->next = newitem;
+        q_queue_last = newitem;
+    }
+    return newitem;
+}
+
+static item_t *create_item(Tuple *tuple, int len)
+{
+    item_t *item;
+    const gchar *album;
+
+    item = malloc(sizeof(item_t));
+
+    item->artist = fmt_escape(aud_tuple_get_string(tuple, FIELD_ARTIST, NULL));
+    item->title = fmt_escape(aud_tuple_get_string(tuple, FIELD_TITLE, NULL));
+    item->len = len;
+    item->track = aud_tuple_get_int(tuple, FIELD_TRACK_NUMBER, NULL);
+    item->timeplayed = 0;
+    item->utctime = time(NULL);
+
+    album = aud_tuple_get_string(tuple, FIELD_ALBUM, NULL);
+    if (album)
+        item->album = fmt_escape((char*) album);
+    else
+        item->album = fmt_escape("");
+
+    item->next = NULL;
+
+    return item;
 }
 
 static item_t *q_put(Tuple *tuple, int t, int len)
 {
-	item_t *item;
-	const gchar *album;
-
-	item = malloc(sizeof(item_t));
+    item_t *item;
 
-	item->artist = fmt_escape(aud_tuple_get_string(tuple, FIELD_ARTIST, NULL));
-	item->title = fmt_escape(aud_tuple_get_string(tuple, FIELD_TITLE, NULL));
-	item->len = len;
-	item->track = aud_tuple_get_int(tuple, FIELD_TRACK_NUMBER, NULL);
-        if (t == -1) { /* now playing song */
-            item->timeplayed = 0;
-            item->utctime = time(NULL);
-        } else { /* item from queue */
-            item->timeplayed = len;
-            item->utctime = t;
-        }
+    item = create_item(tuple, len);
+    item->timeplayed = len;
+    item->utctime = t;
+
+    return q_additem(item);
+}
 
-	album = aud_tuple_get_string(tuple, FIELD_ALBUM, NULL);
-	if (album)
-		item->album = fmt_escape((char*) album);
-	else
-		item->album = fmt_escape("");
-
-	q_nitems++;
-
-	item->next = NULL;
+static item_t *set_np(Tuple *tuple, int len)
+{
+    q_item_free(np_item);
+    np_item = create_item(tuple, len);
 
-	if(q_queue_last == NULL)
-		q_queue = q_queue_last = item;
-	else
-	{
-        	q_queue_last->next = item;
-		q_queue_last = item;
-	}
+    pdebug(fmt_vastr("Tracking now-playing track: %s - %s", np_item->artist, np_item->title), DEBUG);
 
-	return item;
+    return np_item;
 }
 
 #if 0
 static item_t *q_peek(void)
 {
-	if (q_nitems == 0)
-		return NULL;
-	return q_queue;
+    if (q_nitems == 0)
+        return NULL;
+    return q_queue;
 }
 #endif
 
 static item_t *q_peekall(int rewind)
 {
-	static item_t *citem = NULL;
-	item_t *temp_item;
+    static item_t *citem = NULL;
+    item_t *temp_item;
 
-	if (rewind) {
-		citem = q_queue;
-		return NULL;
-	}
+    if (rewind) {
+        citem = q_queue;
+        return NULL;
+    }
 
-	temp_item = citem;
+    temp_item = citem;
 
-	if(citem != NULL)
-		citem = citem->next;
+    if(citem != NULL)
+        citem = citem->next;
 
-	return temp_item;
+    return temp_item;
 }
 
 static int q_get(void)
 {
-	item_t *item;
+    item_t *item;
 
-	if (q_nitems == 0)
-		return 0;
-	
-	item = q_queue;
+    if (q_nitems == 0)
+        return 0;
+    
+    item = q_queue;
 
-	if(item == NULL)
-		return 0;
+    if(item == NULL)
+        return 0;
 
-	q_nitems--;
-	q_queue = q_queue->next;
+    q_nitems--;
+    q_queue = q_queue->next;
 
-	q_item_free(item);
+    pdebug(fmt_vastr("Removing %s - %s from queue", item->artist, item->title), DEBUG);
+
+    q_item_free(item);
 
-	if (q_nitems == 0)
-	{
-		q_queue_last = NULL;
-		return 0;
-	}
+    if (q_nitems == 0)
+    {
+        q_queue_last = NULL;
+        return 0;
+    }
 
-	return -1;
+    return -1;
 }
 
 static void q_free(void)
 {
-	while (q_get());
+    while (q_get());
 }
 
 static int q_len(void)
 {
-	return q_nitems;
+    return q_nitems;
+}
+
+/* isn't there better way for that? --desowin */
+gboolean sc_timeout(gpointer data) {
+    if (np_item)
+    {
+        if (audacious_drct_get_playing() && !audacious_drct_get_paused())
+            np_item->timeplayed+=1;
+
+        /*
+         * Check our now-playing track to see if it should go into the queue
+         */
+        if (((np_item->timeplayed >= (np_item->len / 2)) ||
+            (np_item->timeplayed >= 240)))
+        {
+            q_additem(np_item);
+            np_item = NULL;
+            dump_queue();
+        }
+    }
+
+    return TRUE;
 }
 
 /* Error functions */
 
 static void sc_throw_error(char *errortxt)
 {
-	sc_major_error_present = 1;
-	if(sc_major_error == NULL)
-		sc_major_error = strdup(errortxt);
+    sc_major_error_present = 1;
+    if(sc_major_error == NULL)
+        sc_major_error = strdup(errortxt);
 
-	return;
+    return;
 }
 
 int sc_catch_error(void)
 {
-	return sc_major_error_present;
+    return sc_major_error_present;
 }
 
 char *sc_fetch_error(void)
 {
-	return sc_major_error;
+    return sc_major_error;
 }
 
 void sc_clear_error(void)
 {
-	sc_major_error_present = 0;
-	if(sc_major_error != NULL)
-		free(sc_major_error);
-	sc_major_error = NULL;
+    sc_major_error_present = 0;
+    if(sc_major_error != NULL)
+        free(sc_major_error);
+    sc_major_error = NULL;
 
-	return;
+    return;
 }
 
 static size_t sc_store_res(void *ptr, size_t size,
-		size_t nmemb,
-		void *stream __attribute__((unused)))
+        size_t nmemb,
+        void *stream __attribute__((unused)))
 {
-	int len = size * nmemb;
+    int len = size * nmemb;
 
-	sc_srv_res = realloc(sc_srv_res, sc_srv_res_size + len + 1);
-	memcpy(sc_srv_res + sc_srv_res_size,
-			ptr, len);
-	sc_srv_res_size += len;
-	return len;
+    sc_srv_res = realloc(sc_srv_res, sc_srv_res_size + len + 1);
+    memcpy(sc_srv_res + sc_srv_res_size,
+            ptr, len);
+    sc_srv_res_size += len;
+    return len;
 }
 
 static void sc_free_res(void)
 {
-	if(sc_srv_res != NULL)
-		free(sc_srv_res);
-	sc_srv_res = NULL;
-	sc_srv_res_size = 0;
+    if(sc_srv_res != NULL)
+        free(sc_srv_res);
+    sc_srv_res = NULL;
+    sc_srv_res_size = 0;
 }
 
 static int sc_parse_hs_res(void)
 {
-	char *interval;
+    char *interval;
 
-	if (!sc_srv_res_size) {
-		pdebug("No reply from server", DEBUG);
-		return -1;
-	}
-	*(sc_srv_res + sc_srv_res_size) = 0;
+    if (!sc_srv_res_size) {
+        pdebug("No reply from server", DEBUG);
+        return -1;
+    }
+    *(sc_srv_res + sc_srv_res_size) = 0;
 
-	if (!strncmp(sc_srv_res, "OK\n", 3)) {
-		gchar *scratch = g_strdup(sc_srv_res);
-		gchar **split = g_strsplit(scratch, "\n", 5);
+    if (!strncmp(sc_srv_res, "OK\n", 3)) {
+        gchar *scratch = g_strdup(sc_srv_res);
+        gchar **split = g_strsplit(scratch, "\n", 5);
 
-		g_free(scratch);
+        g_free(scratch);
 
-		sc_session_id = g_strdup(split[1]);
-		sc_np_url = g_strdup(split[2]);
-		sc_submit_url = g_strdup(split[3]);
+        sc_session_id = g_strdup(split[1]);
+        sc_np_url = g_strdup(split[2]);
+        sc_submit_url = g_strdup(split[3]);
 
-		g_strfreev(split);
-		return 0;
-	}
-	if (!strncmp(sc_srv_res, "FAILED ", 7)) {
-		interval = strstr(sc_srv_res, "INTERVAL");
+        g_strfreev(split);
+        return 0;
+    }
+    if (!strncmp(sc_srv_res, "FAILED ", 7)) {
+        interval = strstr(sc_srv_res, "INTERVAL");
 
-		/* Throwing a major error, just in case */
-		/* sc_throw_error(fmt_vastr("%s", sc_srv_res));
-		   sc_hs_errors++; */
-		pdebug(fmt_vastr("error: %s", sc_srv_res), DEBUG);
+        /* Throwing a major error, just in case */
+        /* sc_throw_error(fmt_vastr("%s", sc_srv_res));
+           sc_hs_errors++; */
+        pdebug(fmt_vastr("error: %s", sc_srv_res), DEBUG);
 
-		return -1;
-	}
+        return -1;
+    }
 
-	if (!strncmp(sc_srv_res, "UPDATE ", 7)) {
-		interval = strstr(sc_srv_res, "INTERVAL");
-		if(!interval)
-		{
-			pdebug("missing INTERVAL", DEBUG);
-		}
-		else
-		{
-			*(interval - 1) = 0;
-			sc_submit_interval = strtol(interval + 8, NULL, 10);
-		}
+    if (!strncmp(sc_srv_res, "UPDATE ", 7)) {
+        interval = strstr(sc_srv_res, "INTERVAL");
+        if(!interval)
+        {
+            pdebug("missing INTERVAL", DEBUG);
+        }
+        else
+        {
+            *(interval - 1) = 0;
+            sc_submit_interval = strtol(interval + 8, NULL, 10);
+        }
 
-		sc_submit_url = strchr(strchr(sc_srv_res, '\n') + 1, '\n') + 1;
-		*(sc_submit_url - 1) = 0;
-		sc_submit_url = strdup(sc_submit_url);
-		sc_challenge_hash = strchr(sc_srv_res, '\n') + 1;
-		*(sc_challenge_hash - 1) = 0;
-		sc_challenge_hash = strdup(sc_challenge_hash);
+        sc_submit_url = strchr(strchr(sc_srv_res, '\n') + 1, '\n') + 1;
+        *(sc_submit_url - 1) = 0;
+        sc_submit_url = strdup(sc_submit_url);
+        sc_challenge_hash = strchr(sc_srv_res, '\n') + 1;
+        *(sc_challenge_hash - 1) = 0;
+        sc_challenge_hash = strdup(sc_challenge_hash);
 
-		/* Throwing major error. Need to alert client to update. */
-		sc_throw_error(fmt_vastr("Please update Audacious.\n"
-			"Update available at: http://audacious-media-player.org"));
-		pdebug(fmt_vastr("update client: %s", sc_srv_res + 7), DEBUG);
+        /* Throwing major error. Need to alert client to update. */
+        sc_throw_error(fmt_vastr("Please update Audacious.\n"
+            "Update available at: http://audacious-media-player.org"));
+        pdebug(fmt_vastr("update client: %s", sc_srv_res + 7), DEBUG);
 
-		/*
-		 * Russ isn't clear on whether we can submit with a not-updated
-		 * client.  Neither is RJ.  I use what we did before.
-		 */
-		sc_giveup = -1;
-		return -1;
-	}
-	if (!strncmp(sc_srv_res, "UPTODATE\n", 9)) {
-		sc_bad_users = 0;
+        /*
+         * Russ isn't clear on whether we can submit with a not-updated
+         * client.  Neither is RJ.  I use what we did before.
+         */
+        sc_giveup = -1;
+        return -1;
+    }
+    if (!strncmp(sc_srv_res, "UPTODATE\n", 9)) {
+        sc_bad_users = 0;
 
-		interval = strstr(sc_srv_res, "INTERVAL");
-		if (!interval) {
-			pdebug("missing INTERVAL", DEBUG);
-			/*
-			 * This is probably a bad thing, but Russ seems to
-			 * think its OK to assume that an UPTODATE response
-			 * may not have an INTERVAL...  We return -1 anyway.
-			 */
-			return -1;
-		}
-		else
-		{
-			*(interval - 1) = 0;
-			sc_submit_interval = strtol(interval + 8, NULL, 10);
-		}
+        interval = strstr(sc_srv_res, "INTERVAL");
+        if (!interval) {
+            pdebug("missing INTERVAL", DEBUG);
+            /*
+             * This is probably a bad thing, but Russ seems to
+             * think its OK to assume that an UPTODATE response
+             * may not have an INTERVAL...  We return -1 anyway.
+             */
+            return -1;
+        }
+        else
+        {
+            *(interval - 1) = 0;
+            sc_submit_interval = strtol(interval + 8, NULL, 10);
+        }
 
-		sc_submit_url = strchr(strchr(sc_srv_res, '\n') + 1, '\n') + 1;
-		*(sc_submit_url - 1) = 0;
-		sc_submit_url = strdup(sc_submit_url);
-		sc_challenge_hash = strchr(sc_srv_res, '\n') + 1;
-		*(sc_challenge_hash - 1) = 0;
-		sc_challenge_hash = strdup(sc_challenge_hash);
+        sc_submit_url = strchr(strchr(sc_srv_res, '\n') + 1, '\n') + 1;
+        *(sc_submit_url - 1) = 0;
+        sc_submit_url = strdup(sc_submit_url);
+        sc_challenge_hash = strchr(sc_srv_res, '\n') + 1;
+        *(sc_challenge_hash - 1) = 0;
+        sc_challenge_hash = strdup(sc_challenge_hash);
 
-		return 0;
-	}
-	if(!strncmp(sc_srv_res, "BADAUTH", 7)) {
-		/* Throwing major error. */
-		sc_throw_error("Incorrect username/password.\n"
-				"Please fix in configuration.");
-		pdebug("incorrect username/password", DEBUG);
+        return 0;
+    }
+    if(!strncmp(sc_srv_res, "BADAUTH", 7)) {
+        /* Throwing major error. */
+        sc_throw_error("Incorrect username/password.\n"
+                "Please fix in configuration.");
+        pdebug("incorrect username/password", DEBUG);
 
-		interval = strstr(sc_srv_res, "INTERVAL");
-		if(!interval)
-		{
-			pdebug("missing INTERVAL", DEBUG);
-		}
-		else
-		{
-			*(interval - 1) = 0;
-			sc_submit_interval = strtol(interval + 8, NULL, 10);
-		}
+        interval = strstr(sc_srv_res, "INTERVAL");
+        if(!interval)
+        {
+            pdebug("missing INTERVAL", DEBUG);
+        }
+        else
+        {
+            *(interval - 1) = 0;
+            sc_submit_interval = strtol(interval + 8, NULL, 10);
+        }
 
-		return -1;
-	}
+        return -1;
+    }
 
-	pdebug(fmt_vastr("unknown server-reply '%s'", sc_srv_res), DEBUG);
-	return -1;
+    pdebug(fmt_vastr("unknown server-reply '%s'", sc_srv_res), DEBUG);
+    return -1;
 }
 
 static unsigned char *md5_string(char *pass, int len)
 {
-	md5_state_t md5state;
-	static unsigned char md5pword[16];
-		
-	md5_init(&md5state);
-	md5_append(&md5state, (unsigned const char *)pass, len);
-	md5_finish(&md5state, md5pword);
+    md5_state_t md5state;
+    static unsigned char md5pword[16];
+        
+    md5_init(&md5state);
+    md5_append(&md5state, (unsigned const char *)pass, len);
+    md5_finish(&md5state, md5pword);
 
-	return md5pword;
+    return md5pword;
 }
 
 static void hexify(char *pass, int len)
 {
-	char *bp = sc_response_hash;
-	char hexchars[] = "0123456789abcdef";
-	int i;
+    char *bp = sc_response_hash;
+    char hexchars[] = "0123456789abcdef";
+    int i;
 
-	memset(sc_response_hash, 0, sizeof(sc_response_hash));
-	
-	for(i = 0; i < len; i++) {
-		*(bp++) = hexchars[(pass[i] >> 4) & 0x0f];
-		*(bp++) = hexchars[pass[i] & 0x0f];
-	}
-	*bp = 0;
+    memset(sc_response_hash, 0, sizeof(sc_response_hash));
+    
+    for(i = 0; i < len; i++) {
+        *(bp++) = hexchars[(pass[i] >> 4) & 0x0f];
+        *(bp++) = hexchars[pass[i] & 0x0f];
+    }
+    *bp = 0;
 
-	return;
+    return;
 }
 
 static int sc_handshake(void)
 {
-	int status;
-	char buf[65535];
-	CURL *curl;
-	time_t ts = time(NULL);
-	char *auth_tmp;
-	char *auth;
+    int status;
+    char buf[65535];
+    CURL *curl;
+    time_t ts = time(NULL);
+    char *auth_tmp;
+    char *auth;
 
-	auth_tmp = g_strdup_printf("%s%ld", sc_password, ts);
-	auth = (char *)md5_string(auth_tmp, strlen(auth_tmp));
-	g_free(auth_tmp);
-	hexify(auth, strlen(auth));
-	auth_tmp = g_strdup(sc_response_hash);
+    auth_tmp = g_strdup_printf("%s%ld", sc_password, ts);
+    auth = (char *)md5_string(auth_tmp, strlen(auth_tmp));
+    g_free(auth_tmp);
+    hexify(auth, strlen(auth));
+    auth_tmp = g_strdup(sc_response_hash);
 
-	g_snprintf(buf, sizeof(buf), "%s/?hs=true&p=%s&c=%s&v=%s&u=%s&t=%ld&a=%s",
-			SCROBBLER_HS_URL, SCROBBLER_VERSION,
-			SCROBBLER_CLI_ID, SCROBBLER_IMPLEMENTATION, sc_username, time(NULL),
-			auth_tmp);
-	g_free(auth_tmp);
+    g_snprintf(buf, sizeof(buf), "%s/?hs=true&p=%s&c=%s&v=%s&u=%s&t=%ld&a=%s",
+            SCROBBLER_HS_URL, SCROBBLER_VERSION,
+            SCROBBLER_CLI_ID, SCROBBLER_IMPLEMENTATION, sc_username, time(NULL),
+            auth_tmp);
+    g_free(auth_tmp);
 
-	curl = curl_easy_init();
-	curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
-	curl_easy_setopt(curl, CURLOPT_URL, buf);
-	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, 
-			sc_store_res);
-	memset(sc_curl_errbuf, 0, sizeof(sc_curl_errbuf));
-	curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, sc_curl_errbuf);
-	curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
-	curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
-	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, SC_CURL_TIMEOUT);
-	status = curl_easy_perform(curl);
-	curl_easy_cleanup(curl);
+    curl = curl_easy_init();
+    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
+    curl_easy_setopt(curl, CURLOPT_URL, buf);
+    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, 
+            sc_store_res);
+    memset(sc_curl_errbuf, 0, sizeof(sc_curl_errbuf));
+    curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, sc_curl_errbuf);
+    curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
+    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, SC_CURL_TIMEOUT);
+    status = curl_easy_perform(curl);
+    curl_easy_cleanup(curl);
 
-	sc_hs_timeout = time(NULL) + SCROBBLER_HS_WAIT;
+    sc_hs_timeout = time(NULL) + SCROBBLER_HS_WAIT;
 
-	if (status) {
-		pdebug(sc_curl_errbuf, DEBUG);
-		sc_hs_errors++;
-		sc_free_res();
-		return -1;
-	}
+    if (status) {
+        pdebug(sc_curl_errbuf, DEBUG);
+        sc_hs_errors++;
+        sc_free_res();
+        return -1;
+    }
 
-	if (sc_parse_hs_res()) {
-		sc_hs_errors++;
-		sc_free_res();
-		return -1;
-	}
+    if (sc_parse_hs_res()) {
+        sc_hs_errors++;
+        sc_free_res();
+        return -1;
+    }
 
-	if (sc_challenge_hash != NULL) {
-		md5_state_t md5state;
-		unsigned char md5pword[16];
-		
-		md5_init(&md5state);
-		/*pdebug(fmt_vastr("Pass Hash: %s", sc_password), DEBUG);*/
-		md5_append(&md5state, (unsigned const char *)sc_password,
-				strlen(sc_password));
-		/*pdebug(fmt_vastr("Challenge Hash: %s", sc_challenge_hash), DEBUG);*/
-		md5_append(&md5state, (unsigned const char *)sc_challenge_hash,
-				strlen(sc_challenge_hash));
-		md5_finish(&md5state, md5pword);
-		hexify((char*)md5pword, sizeof(md5pword));
-		/*pdebug(fmt_vastr("Response Hash: %s", sc_response_hash), DEBUG);*/
-	}
+    if (sc_challenge_hash != NULL) {
+        md5_state_t md5state;
+        unsigned char md5pword[16];
+        
+        md5_init(&md5state);
+        /*pdebug(fmt_vastr("Pass Hash: %s", sc_password), DEBUG);*/
+        md5_append(&md5state, (unsigned const char *)sc_password,
+                strlen(sc_password));
+        /*pdebug(fmt_vastr("Challenge Hash: %s", sc_challenge_hash), DEBUG);*/
+        md5_append(&md5state, (unsigned const char *)sc_challenge_hash,
+                strlen(sc_challenge_hash));
+        md5_finish(&md5state, md5pword);
+        hexify((char*)md5pword, sizeof(md5pword));
+        /*pdebug(fmt_vastr("Response Hash: %s", sc_response_hash), DEBUG);*/
+    }
 
-	sc_hs_errors = 0;
-	sc_hs_status = 1;
+    sc_hs_errors = 0;
+    sc_hs_status = 1;
 
-	sc_free_res();
+    sc_free_res();
 
-	pdebug(fmt_vastr("submiturl: %s - interval: %d", 
-				sc_submit_url, sc_submit_interval), DEBUG);
+    pdebug(fmt_vastr("submiturl: %s - interval: %d", 
+                sc_submit_url, sc_submit_interval), DEBUG);
 
-	return 0;
+    return 0;
 }
 
 static int sc_parse_sb_res(void)
 {
-	char *ch, *ch2;
+    char *ch, *ch2;
 
-	if (!sc_srv_res_size) {
-		pdebug("No response from server", DEBUG);
-		return -1;
-	}
-	*(sc_srv_res + sc_srv_res_size) = 0;
+    if (!sc_srv_res_size) {
+        pdebug("No response from server", DEBUG);
+        return -1;
+    }
+    *(sc_srv_res + sc_srv_res_size) = 0;
 
-	if (!strncmp(sc_srv_res, "OK", 2)) {
-		if ((ch = strstr(sc_srv_res, "INTERVAL"))) {
-			sc_submit_interval = strtol(ch + 8, NULL, 10);
-			pdebug(fmt_vastr("got new interval: %d",
-						sc_submit_interval), DEBUG);
-		}
+    if (!strncmp(sc_srv_res, "OK", 2)) {
+        if ((ch = strstr(sc_srv_res, "INTERVAL"))) {
+            sc_submit_interval = strtol(ch + 8, NULL, 10);
+            pdebug(fmt_vastr("got new interval: %d",
+                        sc_submit_interval), DEBUG);
+        }
 
-		pdebug(fmt_vastr("submission ok: %s", sc_srv_res), DEBUG);
+        pdebug(fmt_vastr("submission ok: %s", sc_srv_res), DEBUG);
 
-		return 0;
-	}
+        return 0;
+    }
 
-	if (!strncmp(sc_srv_res, "BADAUTH", 7)) {
-		if ((ch = strstr(sc_srv_res, "INTERVAL"))) {
-			sc_submit_interval = strtol(ch + 8, NULL, 10);
-			pdebug(fmt_vastr("got new interval: %d",
-						sc_submit_interval), DEBUG);
-		}
+    if (!strncmp(sc_srv_res, "BADAUTH", 7)) {
+        if ((ch = strstr(sc_srv_res, "INTERVAL"))) {
+            sc_submit_interval = strtol(ch + 8, NULL, 10);
+            pdebug(fmt_vastr("got new interval: %d",
+                        sc_submit_interval), DEBUG);
+        }
 
-		pdebug("incorrect username/password", DEBUG);
+        pdebug("incorrect username/password", DEBUG);
 
-		sc_giveup = 0;
+        sc_giveup = 0;
 
-		/*
-		 * We obviously aren't authenticated.  The server might have
-		 * lost our handshake status though, so let's try
-		 * re-handshaking...  This might not be proper.
-		 * (we don't give up)
-		 */
-		sc_hs_status = 0;
+        /*
+         * We obviously aren't authenticated.  The server might have
+         * lost our handshake status though, so let's try
+         * re-handshaking...  This might not be proper.
+         * (we don't give up)
+         */
+        sc_hs_status = 0;
 
-		if(sc_challenge_hash != NULL)
-			free(sc_challenge_hash);
-		if(sc_submit_url != NULL)
-			free(sc_submit_url);
+        if(sc_challenge_hash != NULL)
+            free(sc_challenge_hash);
+        if(sc_submit_url != NULL)
+            free(sc_submit_url);
 
-		sc_challenge_hash = sc_submit_url = NULL;
-		sc_bad_users++;
+        sc_challenge_hash = sc_submit_url = NULL;
+        sc_bad_users++;
 
-		if(sc_bad_users > 2)
-		{
-			pdebug("3 BADAUTH returns on submission. Halting "
-				"submissions until login fixed.", DEBUG)
-			sc_throw_error("Incorrect username/password.\n"
-				"Please fix in configuration.");
-		}
+        if(sc_bad_users > 2)
+        {
+            pdebug("3 BADAUTH returns on submission. Halting "
+                "submissions until login fixed.", DEBUG)
+            sc_throw_error("Incorrect username/password.\n"
+                "Please fix in configuration.");
+        }
 
-		return -1;
-	}
+        return -1;
+    }
 
-	if (!strncmp(sc_srv_res, "FAILED", 6))  {
-		if ((ch = strstr(sc_srv_res, "INTERVAL"))) {
-			sc_submit_interval = strtol(ch + 8, NULL, 10);
-			pdebug(fmt_vastr("got new interval: %d",
-						sc_submit_interval), DEBUG);
-		}
+    if (!strncmp(sc_srv_res, "FAILED", 6))  {
+        if ((ch = strstr(sc_srv_res, "INTERVAL"))) {
+            sc_submit_interval = strtol(ch + 8, NULL, 10);
+            pdebug(fmt_vastr("got new interval: %d",
+                        sc_submit_interval), DEBUG);
+        }
 
-		/* This could be important. (Such as FAILED - Get new plugin) */
-		/*sc_throw_error(fmt_vastr("%s", sc_srv_res));*/
+        /* This could be important. (Such as FAILED - Get new plugin) */
+        /*sc_throw_error(fmt_vastr("%s", sc_srv_res));*/
 
-		pdebug(sc_srv_res, DEBUG);
+        pdebug(sc_srv_res, DEBUG);
 
-		return -1;
-	}
+        return -1;
+    }
 
-	if (!strncmp(sc_srv_res, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">", 50)) {
-		ch = strstr(sc_srv_res, "<TITLE>");
-		ch2 = strstr(sc_srv_res, "</TITLE>");
-		if (ch != NULL && ch2 != NULL) {
-			ch += strlen("<TITLE>");
-			*ch2 = '\0';
+    if (!strncmp(sc_srv_res, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">", 50)) {
+        ch = strstr(sc_srv_res, "<TITLE>");
+        ch2 = strstr(sc_srv_res, "</TITLE>");
+        if (ch != NULL && ch2 != NULL) {
+            ch += strlen("<TITLE>");
+            *ch2 = '\0';
 
-			pdebug(fmt_vastr("HTTP Error (%d): '%s'",
-					 atoi(ch), ch + 4), DEBUG);
-//			*ch2 = '<'; // needed? --yaz
-		}
+            pdebug(fmt_vastr("HTTP Error (%d): '%s'",
+                     atoi(ch), ch + 4), DEBUG);
+//          *ch2 = '<'; // needed? --yaz
+        }
 
-		return -1;
-	}
+        return -1;
+    }
 
-	pdebug(fmt_vastr("unknown server-reply %s", sc_srv_res), DEBUG);
+    pdebug(fmt_vastr("unknown server-reply %s", sc_srv_res), DEBUG);
 
-	return -1;
+    return -1;
 }
 
 static gchar *sc_itemtag(char c, int n, char *str)
 {
-	static char buf[SCROBBLER_SB_MAXLEN]; 
-	g_snprintf(buf, SCROBBLER_SB_MAXLEN, "&%c[%d]=%s", c, n, str);
-	return buf;
+    static char buf[SCROBBLER_SB_MAXLEN]; 
+    g_snprintf(buf, SCROBBLER_SB_MAXLEN, "&%c[%d]=%s", c, n, str);
+    return buf;
 }
 
 #define cfa(f, l, n, v) \
 curl_formadd(f, l, CURLFORM_COPYNAME, n, \
-		CURLFORM_PTRCONTENTS, v, CURLFORM_END)
+        CURLFORM_PTRCONTENTS, v, CURLFORM_END)
 
 static int sc_generateentry(GString *submission)
 {
-	int i;
-	item_t *item;
+    int i;
+    item_t *item;
 
-	i = 0;
+    i = 0;
 
-	q_peekall(1);
+    q_peekall(1);
 
-	while ((item = q_peekall(0)) && i < 10)
-	{
-		/*
-		 * don't submit queued tracks which don't yet meet audioscrobbler
-		 * requirements...
-		 */
-		if ((item->timeplayed < (item->len / 2)) &&
-		    (item->timeplayed < 240))
-			continue;
+    while ((item = q_peekall(0)) && i < 10)
+    {
+        /*
+         * We assume now that all tracks in the queue should be submitted.
+         * The check occurs in the sc_timeout() function now.
+         */
 
-		if (!item)
-			return i;
+        if (!item)
+            return i;
 
                 g_string_append(submission,sc_itemtag('a',i,I_ARTIST(item)));
                 g_string_append(submission,sc_itemtag('t',i,I_TITLE(item)));
@@ -647,192 +685,197 @@
                 g_free(tmp);
                 g_string_append(submission,sc_itemtag('r',i,""));
 
-		pdebug(fmt_vastr("a[%d]=%s t[%d]=%s l[%d]=%d i[%d]=%d b[%d]=%s",
-				i, I_ARTIST(item),
-				i, I_TITLE(item),
-				i, I_LEN(item),
-				i, I_TIME(item),
-				i, I_ALBUM(item)), DEBUG);
-#ifdef ALLOW_MULTIPLE
-		i++;
-	}
-#endif
+        pdebug(fmt_vastr("a[%d]=%s t[%d]=%s l[%d]=%d i[%d]=%d b[%d]=%s",
+                i, I_ARTIST(item),
+                i, I_TITLE(item),
+                i, I_LEN(item),
+                i, I_TIME(item),
+                i, I_ALBUM(item)), DEBUG);
+        i++;
+    }
 
-	return i;
+    return i;
 }
 
 static int sc_submit_np(Tuple *tuple)
 {
-	CURL *curl;
-	/* struct HttpPost *post = NULL , *last = NULL; */
-	int status;
-	gchar *entry;
+    CURL *curl;
+    /* struct HttpPost *post = NULL , *last = NULL; */
+    int status;
+    gchar *entry;
 
-	curl = curl_easy_init();
-	curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
-	curl_easy_setopt(curl, CURLOPT_URL, sc_np_url);
-	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
-			sc_store_res);
-	curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT);
-	curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
-	/*cfa(&post, &last, "debug", "failed");*/
+    curl = curl_easy_init();
+    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
+    curl_easy_setopt(curl, CURLOPT_URL, sc_np_url);
+    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
+            sc_store_res);
+    curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT);
+    curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+    /*cfa(&post, &last, "debug", "failed");*/
 
         char *field_artist = fmt_escape(aud_tuple_get_string(tuple, FIELD_ARTIST, NULL));
         char *field_title = fmt_escape(aud_tuple_get_string(tuple, FIELD_TITLE, NULL));
         char *field_album = aud_tuple_get_string(tuple, FIELD_ALBUM, NULL) ? fmt_escape(aud_tuple_get_string(tuple, FIELD_ALBUM, NULL)) : fmt_escape("");
-	entry = g_strdup_printf("s=%s&a=%s&t=%s&b=%s&l=%d&n=%d&m=", sc_session_id,
-		field_artist,
-		field_title,
-		field_album,
-		aud_tuple_get_int(tuple, FIELD_LENGTH, NULL) / 1000,
-		aud_tuple_get_int(tuple, FIELD_TRACK_NUMBER, NULL));
+    entry = g_strdup_printf("s=%s&a=%s&t=%s&b=%s&l=%d&n=%d&m=", sc_session_id,
+        field_artist,
+        field_title,
+        field_album,
+        aud_tuple_get_int(tuple, FIELD_LENGTH, NULL) / 1000,
+        aud_tuple_get_int(tuple, FIELD_TRACK_NUMBER, NULL));
         curl_free(field_artist);
         curl_free(field_title);
         curl_free(field_album);
 
-	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (char *) entry);
-	memset(sc_curl_errbuf, 0, sizeof(sc_curl_errbuf));
-	curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, sc_curl_errbuf);
-	curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
-	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, SC_CURL_TIMEOUT);
-	curl_easy_setopt(curl, CURLOPT_TIMEOUT, SCROBBLER_SB_WAIT);
+    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (char *) entry);
+    memset(sc_curl_errbuf, 0, sizeof(sc_curl_errbuf));
+    curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, sc_curl_errbuf);
+    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
+    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, SC_CURL_TIMEOUT);
+    curl_easy_setopt(curl, CURLOPT_TIMEOUT, SCROBBLER_SB_WAIT);
 
-	status = curl_easy_perform(curl);
-	curl_easy_cleanup(curl);
+    status = curl_easy_perform(curl);
+    curl_easy_cleanup(curl);
 
-	g_free(entry);
+    g_free(entry);
 
-	if (status) {
-		pdebug(sc_curl_errbuf, DEBUG);
-		sc_sb_errors++;
-		sc_free_res();
-		return -1;
-	}
+    if (status) {
+        pdebug(sc_curl_errbuf, DEBUG);
+        sc_sb_errors++;
+        sc_free_res();
+        return -1;
+    }
 
-	if (sc_parse_sb_res()) {
-		sc_sb_errors++;
-		sc_free_res();
-		pdebug(fmt_vastr("Retrying in %d secs, %d elements in queue",
-					sc_submit_interval, q_len()), DEBUG);
-		return -1;
-	}
-	sc_free_res();
-	return 0;
+    if (sc_parse_sb_res()) {
+        sc_sb_errors++;
+        sc_free_res();
+        pdebug(fmt_vastr("Retrying in %d secs, %d elements in queue",
+                    sc_submit_interval, q_len()), DEBUG);
+        return -1;
+    }
+    sc_free_res();
+    return 0;
 }
 
 static int sc_submitentry(gchar *entry)
 {
-	CURL *curl;
-	/* struct HttpPost *post = NULL , *last = NULL; */
-	int status;
+    CURL *curl;
+    /* struct HttpPost *post = NULL , *last = NULL; */
+    int status;
         GString *submission;
 
-	curl = curl_easy_init();
-	curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
-	curl_easy_setopt(curl, CURLOPT_URL, sc_submit_url);
-	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
-			sc_store_res);
-	curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT);
-	curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
-	/*cfa(&post, &last, "debug", "failed");*/
+    curl = curl_easy_init();
+    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
+    curl_easy_setopt(curl, CURLOPT_URL, sc_submit_url);
+    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
+            sc_store_res);
+    curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT);
+    curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+    /*cfa(&post, &last, "debug", "failed");*/
 
-	/*pdebug(fmt_vastr("Response Hash: %s", sc_response_hash), DEBUG);*/
+    /*pdebug(fmt_vastr("Response Hash: %s", sc_response_hash), DEBUG);*/
         submission = g_string_new("s=");
         g_string_append(submission, (gchar *)sc_session_id);
-	g_string_append(submission, entry);
+    g_string_append(submission, entry);
 
-	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (char *)submission->str);
-	memset(sc_curl_errbuf, 0, sizeof(sc_curl_errbuf));
-	curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, sc_curl_errbuf);
-	curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
-	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, SC_CURL_TIMEOUT);
-	curl_easy_setopt(curl, CURLOPT_TIMEOUT, SCROBBLER_SB_WAIT);
+    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (char *)submission->str);
+    memset(sc_curl_errbuf, 0, sizeof(sc_curl_errbuf));
+    curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, sc_curl_errbuf);
+    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
+    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, SC_CURL_TIMEOUT);
+    curl_easy_setopt(curl, CURLOPT_TIMEOUT, SCROBBLER_SB_WAIT);
 
-	status = curl_easy_perform(curl);
+    status = curl_easy_perform(curl);
 
-	curl_easy_cleanup(curl);
+    curl_easy_cleanup(curl);
         g_string_free(submission, TRUE);
 
-	if (status) {
-		pdebug(sc_curl_errbuf, DEBUG);
-		sc_sb_errors++;
-		sc_free_res();
-		return -1;
-	}
+    if (status) {
+        pdebug(sc_curl_errbuf, DEBUG);
+        sc_sb_errors++;
+        sc_free_res();
+        return -1;
+    }
 
-	if (sc_parse_sb_res()) {
-		sc_sb_errors++;
-		sc_free_res();
-		pdebug(fmt_vastr("Retrying in %d secs, %d elements in queue",
-					sc_submit_interval, q_len()), DEBUG);
-		return -1;
-	}
-	sc_free_res();
-	return 0;
+    if (sc_parse_sb_res()) {
+        sc_sb_errors++;
+        sc_free_res();
+        pdebug(fmt_vastr("Retrying in %d secs, %d elements in queue",
+                    sc_submit_interval, q_len()), DEBUG);
+        return -1;
+    }
+    sc_free_res();
+    return 0;
 }
 
 static void sc_handlequeue(GMutex *mutex)
 {
-	GString *submitentry;
-	int nsubmit;
-	int wait;
+    GString *submitentry;
+    int nsubmit;
+    int wait;
+    int i;
 
-	if(sc_submit_timeout < time(NULL) && sc_bad_users < 3)
-	{
-		submitentry = g_string_new("");
+    if(sc_submit_timeout < time(NULL) && sc_bad_users < 3)
+    {
+        submitentry = g_string_new("");
 
-		g_mutex_lock(mutex);
+        g_mutex_lock(mutex);
+
+        nsubmit = sc_generateentry(submitentry);
+
+        g_mutex_unlock(mutex);
 
-		nsubmit = sc_generateentry(submitentry);
-
-		g_mutex_unlock(mutex);
+        if (nsubmit > 0)
+        {
+            pdebug(fmt_vastr("Number submitting: %d", nsubmit), DEBUG);
+            pdebug(fmt_vastr("Submission: %s", submitentry->str), DEBUG);
 
-		if (nsubmit > 0)
-		{
-			pdebug(fmt_vastr("Number submitting: %d", nsubmit), DEBUG);
-			pdebug(fmt_vastr("Submission: %s", submitentry->str), DEBUG);
+            if(!sc_submitentry(submitentry->str))
+            {
+                g_mutex_lock(mutex);
 
-			if(!sc_submitentry(submitentry->str))
-			{
-				g_mutex_lock(mutex);
+                pdebug(fmt_vastr("Clearing out %d item(s) from the queue", nsubmit), DEBUG);
+                for (i=0; i<nsubmit; i++)
+                {
+                    q_get();
+                }
 
-#ifdef ALLOW_MULTIPLE
-				q_free();
-#else
-				q_get();
-#endif
-				/*
-				 * This should make sure that the queue doesn't
-				 * get submitted multiple times on a nasty
-				 * segfault...
-				 */
-				dump_queue();
+                /*
+                 * This should make sure that the queue doesn't
+                 * get submitted multiple times on a nasty
+                 * segfault...
+                 */
+                dump_queue();
+
+                g_mutex_unlock(mutex);
 
-				g_mutex_unlock(mutex);
+                sc_sb_errors = 0;
+            }
+            if(sc_sb_errors)
+            {
+                /* Dump queue */
+                g_mutex_lock(mutex);
+                dump_queue();
+                g_mutex_unlock(mutex);
 
-				sc_sb_errors = 0;
-			}
-			if(sc_sb_errors)
-			{
-				if(sc_sb_errors < 5)
-					/* Retry after 1 min */
-					wait = 60;
-				else
-					wait = /* sc_submit_interval + */
-						( ((sc_sb_errors - 5) < 7) ?
-						(60 << (sc_sb_errors-5)) :
-						7200 );
-				
-				sc_submit_timeout = time(NULL) + wait;
+                if(sc_sb_errors < 5)
+                    /* Retry after 1 min */
+                    wait = 60;
+                else
+                    wait = /* sc_submit_interval + */
+                        ( ((sc_sb_errors - 5) < 7) ?
+                        (60 << (sc_sb_errors-5)) :
+                        7200 );
+                
+                sc_submit_timeout = time(NULL) + wait;
 
-				pdebug(fmt_vastr("Error while submitting. "
-					"Retrying after %d seconds.", wait),
-					DEBUG);
-			}
-		}
+                pdebug(fmt_vastr("Error while submitting. "
+                    "Retrying after %d seconds.", wait),
+                    DEBUG);
+            }
+        }
 
-		g_string_free(submitentry, TRUE);
-	}
+        g_string_free(submitentry, TRUE);
+    }
 }
 
 static void read_cache(void)
@@ -872,6 +915,10 @@
             len = atoi(entry[4]);
             t = atoi(entry[6]);
 
+            /*
+             * All entries in the queue should have "L" as the sixth field now, but
+             * we'll continue to check the value anyway, for backwards-compatibility reasons.
+             */
             if (!strncmp(entry[5], "L", 1)) {
                 Tuple *tuple = aud_tuple_new();
                 gchar* string_value;
@@ -938,6 +985,13 @@
 
     q_peekall(1);
 
+    /*
+     * The sixth field used to be "L" for tracks which were valid submissions,
+     * and "S" for tracks which were still playing, and shouldn't be submitted
+     * yet.  We only store valid submissions in the queue, now, but the "L" value
+     * is left in-place for backwards-compatibility reasons.  It should probably
+     * be removed at some point.
+     */
     while ((item = q_peekall(0))) {
         fprintf(fd, "%s\t%s\t%s\t%d\t%d\t%s\t%d\n",
                     I_ARTIST(item),
@@ -945,7 +999,7 @@
                     I_TITLE(item),
                     item->track,
                     I_LEN(item),
-                    ((item->timeplayed > item->len/2) || (item->timeplayed > 240)) ? "L" : "S",
+                    "L",
                     I_TIME(item));
     }
 
@@ -956,51 +1010,51 @@
 
 void sc_cleaner(void)
 {
-	if(sc_submit_url != NULL)
-		free(sc_submit_url);
-	if(sc_username != NULL)
-		free(sc_username);
-	if(sc_password != NULL)
-		free(sc_password);
-	if(sc_challenge_hash != NULL)
-		free(sc_challenge_hash);
-	if(sc_srv_res != NULL)
-		free(sc_srv_res);
-	if(sc_major_error != NULL)
-		free(sc_major_error);
-	dump_queue();
-	q_free();
-	pdebug("scrobbler shutting down", DEBUG);
+    if(sc_submit_url != NULL)
+        free(sc_submit_url);
+    if(sc_username != NULL)
+        free(sc_username);
+    if(sc_password != NULL)
+        free(sc_password);
+    if(sc_challenge_hash != NULL)
+        free(sc_challenge_hash);
+    if(sc_srv_res != NULL)
+        free(sc_srv_res);
+    if(sc_major_error != NULL)
+        free(sc_major_error);
+    dump_queue();
+    q_free();
+    pdebug("scrobbler shutting down", DEBUG);
 }
 
 static void sc_checkhandshake(void)
 {
-	int wait;
+    int wait;
 
-	if (!sc_username || !sc_password)
-		return;
+    if (!sc_username || !sc_password)
+        return;
 
-	if (sc_hs_status)
-		return;
-	if (sc_hs_timeout < time(NULL))
-	{
-		sc_handshake();
+    if (sc_hs_status)
+        return;
+    if (sc_hs_timeout < time(NULL))
+    {
+        sc_handshake();
 
-		if(sc_hs_errors)
-		{
-			if(sc_hs_errors < 5)
-				/* Retry after 60 seconds */
-				wait = 60;
-			else
-				wait = /* sc_submit_interval + */
-					( ((sc_hs_errors - 5) < 7) ?
-					(60 << (sc_hs_errors-5)) :
-					7200 );
-			sc_hs_timeout = time(NULL) + wait;
-			pdebug(fmt_vastr("Error while handshaking. Retrying "
-				"after %d seconds.", wait), DEBUG);
-		}
-	}
+        if(sc_hs_errors)
+        {
+            if(sc_hs_errors < 5)
+                /* Retry after 60 seconds */
+                wait = 60;
+            else
+                wait = /* sc_submit_interval + */
+                    ( ((sc_hs_errors - 5) < 7) ?
+                    (60 << (sc_hs_errors-5)) :
+                    7200 );
+            sc_hs_timeout = time(NULL) + wait;
+            pdebug(fmt_vastr("Error while handshaking. Retrying "
+                "after %d seconds.", wait), DEBUG);
+        }
+    }
 }
 
 /**** Public *****/
@@ -1009,41 +1063,41 @@
 
 void sc_init(char *uname, char *pwd)
 {
-	sc_hs_status = sc_hs_timeout = sc_hs_errors = sc_submit_timeout =
-		sc_srv_res_size = sc_giveup = sc_major_error_present =
-		sc_bad_users = sc_sb_errors = 0;
-	sc_submit_interval = 1;
+    sc_hs_status = sc_hs_timeout = sc_hs_errors = sc_submit_timeout =
+        sc_srv_res_size = sc_giveup = sc_major_error_present =
+        sc_bad_users = sc_sb_errors = 0;
+    sc_submit_interval = 1;
 
-	sc_submit_url = sc_username = sc_password = sc_srv_res =
-		sc_challenge_hash = sc_major_error = NULL;
-	sc_username = strdup(uname);
-	sc_password = strdup(pwd);
-	read_cache();
-	pdebug("scrobbler starting up", DEBUG);
+    sc_submit_url = sc_username = sc_password = sc_srv_res =
+        sc_challenge_hash = sc_major_error = NULL;
+    sc_username = strdup(uname);
+    sc_password = strdup(pwd);
+    read_cache();
+    pdebug("scrobbler starting up", DEBUG);
 }
 
 void sc_addentry(GMutex *mutex, Tuple *tuple, int len)
 {
-	g_mutex_lock(mutex);
+    g_mutex_lock(mutex);
 
-	sc_submit_np(tuple);
-	q_put(tuple, -1, len);
+    sc_submit_np(tuple);
+    set_np(tuple, len);
 
-	/*
-	 * This will help make sure the queue will be saved on a nasty
-	 * segfault...
-	 */
-	dump_queue();
+    /*
+     * This will help make sure the queue will be saved on a nasty
+     * segfault...
+     */
+    dump_queue();
 
-	g_mutex_unlock(mutex);
+    g_mutex_unlock(mutex);
 }
 
 /* Call periodically from the plugin */
 int sc_idle(GMutex *mutex)
 {
-	sc_checkhandshake();
-	if (sc_hs_status)
-		sc_handlequeue(mutex);
+    sc_checkhandshake();
+    if (sc_hs_status)
+        sc_handlequeue(mutex);
 
-	return sc_giveup;
+    return sc_giveup;
 }