<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -104,6 +104,8 @@ mkpath(char *path)
 }
 
 int playback(FILE * streamfd) {
+	const char * freetrack = NULL;
+
 	killed = 0;
 	signal(SIGUSR1, sighand);
 
@@ -161,8 +163,10 @@ int playback(FILE * streamfd) {
 		ioctl(data.audiofd, SOUND_PCM_WRITE_BITS, &amp; arg);
 #endif
 
-		if(haskey(&amp; track, &quot;freeTrackURL&quot;) &amp;&amp; haskey(&amp; rc, &quot;download&quot;)) {
-			char *dnam;
+		freetrack = value(&amp; track, &quot;freeTrackURL&quot;);
+
+		if(freetrack &amp;&amp; strlen(freetrack) &gt; 0 &amp;&amp; haskey(&amp; rc, &quot;download&quot;)) {
+			char * dnam;
 			int rv;
 
 			data.path = strdup(meta(value(&amp; rc, &quot;download&quot;), M_RELAXPATH, &amp; track));</diff>
      <filename>source/play.c</filename>
    </modified>
    <modified>
      <diff>@@ -65,109 +65,92 @@ void trim(char* string){
 }
 
 
-int parsexspf(struct playlist * list, const char * xml) {
-	char * ptr;
+int parsexspf(struct playlist * list, char * xml) {
+	char * ptr = xml;
 	unsigned i, tracks = 0;
+	char * track;
 
 	assert(list != NULL);
 	assert(xml != NULL);
 
-	if((ptr = strcasestr(xml, &quot;&lt;title&gt;&quot;)) != NULL) {
-		char * track, * radio = NULL;
+	while((track = strcasestr(ptr, &quot;&lt;track&gt;&quot;)) != NULL) {
+		struct tracknode * node = NULL;
+		char * next = strcasestr(track + 7, &quot;&lt;track&gt;&quot;), * duration;
 
-		radio = strndup(ptr + 7, strcasestr(xml, &quot;&lt;/title&gt;&quot;) - ptr - 7);
-		assert(radio != NULL);
+		const char * tags [] = {
+			&quot;location&quot;, &quot;title&quot;, &quot;album&quot;, &quot;creator&quot;, &quot;duration&quot;, &quot;image&quot;,
+			&quot;lastfm:trackauth&quot;,
+		};
 
-		if(list-&gt;title != NULL) {
-			free(list-&gt;title);
-			list-&gt;title = NULL;
-		}
-
-		decode(radio, &amp; list-&gt;title);
-		unhtml(list-&gt;title);
-		free(radio);
-
-		while((track = strcasestr(ptr, &quot;&lt;track&gt;&quot;)) != NULL) {
-			struct tracknode * node = NULL;
-			char * next = strcasestr(track + 7, &quot;&lt;track&gt;&quot;), * duration;
+		const char * links [] = { &quot;artistpage&quot;, &quot;albumpage&quot;, &quot;trackpage&quot;, &quot;freeTrackURL&quot;, };
 
-			const char * tags [] = {
-				&quot;location&quot;, &quot;title&quot;, &quot;album&quot;, &quot;creator&quot;, &quot;duration&quot;, &quot;image&quot;,
-				&quot;lastfm:trackauth&quot;,
-			};
 
-			const char * links [] = { &quot;artistpage&quot;, &quot;albumpage&quot;, &quot;trackpage&quot;, &quot;freeTrackURL&quot;, };
+		if(next)
+			* (next - 1) = 0;
 
+		node = malloc(sizeof(struct tracknode));
+		assert(node != NULL);
 
-			if(next)
-				* (next - 1) = 0;
+		memset(node, 0, sizeof(struct tracknode));
 
-			node = malloc(sizeof(struct tracknode));
-			assert(node != NULL);
+		for(i = 0; i &lt; (sizeof(tags) / sizeof(char *)); ++i) {
+			char begin[32] = { 0 }, end[32] = { 0 };
 
-			memset(node, 0, sizeof(struct tracknode));
+			sprintf(begin, &quot;&lt;%s&gt;&quot;, tags[i]);
+			sprintf(end, &quot;&lt;/%s&gt;&quot;, tags[i]);
 
-			for(i = 0; i &lt; (sizeof(tags) / sizeof(char *)); ++i) {
-				char begin[32] = { 0 }, end[32] = { 0 };
-
-				sprintf(begin, &quot;&lt;%s&gt;&quot;, tags[i]);
-				sprintf(end, &quot;&lt;/%s&gt;&quot;, tags[i]);
-
-				if((ptr = strcasestr(track, begin)) != NULL) {
-					char * text = strndup(
+			if((ptr = strcasestr(track, begin)) != NULL) {
+				char * text = strndup(
 						ptr + strlen(begin),
 						(strcasestr(ptr, end)) - (ptr + strlen(begin))
-					);
+						);
 
-					assert(text != NULL);
+				assert(text != NULL);
 
-					unhtml(text);
-					set(&amp; node-&gt;track, tags[i], text);
-					free(text);
-				}
+				unhtml(text);
+				set(&amp; node-&gt;track, tags[i], text);
+				free(text);
 			}
+		}
 
-			for(i = 0; i &lt; (sizeof(links) / sizeof(char *)); ++i) {
-				char begin[64] = { 0 };
+		for(i = 0; i &lt; (sizeof(links) / sizeof(char *)); ++i) {
+			char begin[64] = { 0 };
 
-				sprintf(begin, &quot;&lt;link rel=\&quot;http://www.last.fm/%s\&quot;&gt;&quot;, links[i]);
+			sprintf(begin, &quot;&lt;link rel=\&quot;http://www.last.fm/%s\&quot;&gt;&quot;, links[i]);
 
-				if((ptr = strcasestr(track, begin)) != NULL) {
-					char * text = strndup(
+			if((ptr = strcasestr(track, begin)) != NULL) {
+				char * text = strndup(
 						ptr + strlen(begin),
 						(strcasestr(ptr, &quot;&lt;/link&gt;&quot;)) - (ptr + strlen(begin))
-					);
+						);
 
-					assert(text != NULL);
+				assert(text != NULL);
 
-					set(&amp; node-&gt;track, links[i], text);
-					free(text);
-				}
+				set(&amp; node-&gt;track, links[i], text);
+				free(text);
 			}
+		}
 
-			trim(list-&gt;title);
-			set(&amp; node-&gt;track, &quot;station&quot;, list-&gt;title);
-
-			duration = strdup(value(&amp; node-&gt;track, &quot;duration&quot;));
-			if(duration != NULL) {
-				duration[strlen(duration) - 3] = 0;
-				set(&amp; node-&gt;track, &quot;duration&quot;, duration);
-			}
+		trim(list-&gt;title);
+		set(&amp; node-&gt;track, &quot;station&quot;, list-&gt;title);
 
-			push(list, node);
+		duration = strdup(value(&amp; node-&gt;track, &quot;duration&quot;));
+		if(duration != NULL) {
+			duration[strlen(duration) - 3] = 0;
+			set(&amp; node-&gt;track, &quot;duration&quot;, duration);
+		}
 
-			++tracks;
+		push(list, node);
 
-			if(!next)
-				break;
+		++tracks;
 
-			ptr = next;
-		}
+		if(!next)
+			break;
 
-		return !0;
+		ptr = next;
 	}
 
-	return 0;
+	return 1;
 }
 
 </diff>
      <filename>source/playlist.c</filename>
    </modified>
    <modified>
      <diff>@@ -36,7 +36,6 @@ pid_t playfork = 0; /* PID of the decoding &amp; playing process, if running */
 struct playlist playlist;
 char * currentStation = NULL;
 
-
 int authenticate(const char * username, const char * password) {
 	const unsigned char * md5;
 	char hexmd5[32 + 1] = { 0 }, url[512] = { 0 }, ** response;
@@ -93,7 +92,7 @@ int authenticate(const char * username, const char * password) {
 
 
 int station(const char * stationURL) {
-	char url[512] = { 0 }, * encodedURL = NULL, ** response;
+	char url[512] = { 0 }, * encodedURL = NULL, ** response, name[512];
 	unsigned i = 0, retval = !0, regular = !0;
 	const char * fmt;	
 	const char * types[4] = {&quot;play&quot;, &quot;preview&quot;, &quot;track&quot;, &quot;playlist&quot;};
@@ -115,12 +114,22 @@ int station(const char * stationURL) {
 			}
 		}
 
+		/* Do nothing if the station is already played. */
+		else if(currentStation &amp;&amp; !strcmp(currentStation, stationURL)) {
+			return 0;
+		}
+
 		puts(&quot;\rDelayed.&quot;);
 		nextstation = strdup(stationURL);
 
 		return 0;
 	}
 
+	/* Do nothing if the station is already played. */
+	else if(currentStation &amp;&amp; !strcmp(currentStation, stationURL)) {
+		return 0;
+	}
+
 	freelist(&amp; playlist);
 
 	if(!haskey(&amp; data, &quot;session&quot;)) {
@@ -128,7 +137,7 @@ int station(const char * stationURL) {
 		return 0;
 	}
 
-	if(!stationURL)
+	if(!stationURL || !strlen(stationURL))
 		return 0;
 
 	if(!strncasecmp(stationURL, &quot;lastfm://&quot;, 9))
@@ -166,9 +175,18 @@ int station(const char * stationURL) {
 	if(regular) {
 		for(i = 0; response[i]; ++i) {
 			char status[64] = { 0 };
+
 			if(sscanf(response[i], &quot;response=%63[^\r\n]&quot;, status) &gt; 0)
 				if(!strncmp(status, &quot;FAILED&quot;, 6))
 					retval = 0;
+
+			if(sscanf(response[i], &quot;stationname=%127[^\r\n]&quot;, name) &gt; 0) {
+				if(playlist.title != NULL)
+					free(playlist.title);
+
+				decode(name, &amp; playlist.title);
+				unhtml(playlist.title);
+			}
 		}
 
 		purge(response);</diff>
      <filename>source/service.c</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>c5e927fb240dbf3301348dc5192f49835a91aa34</id>
    </parent>
    <parent>
      <id>697122819438677d92233c297a6de9df0218bca1</id>
    </parent>
  </parents>
  <author>
    <name>Jonas Kramer</name>
    <email>jkramer@nex.scrapping.cc</email>
  </author>
  <url>http://github.com/jkramer/shell-fm/commit/3c1a68768d7408dae8cf5adead96ee9d9e6b8bda</url>
  <id>3c1a68768d7408dae8cf5adead96ee9d9e6b8bda</id>
  <committed-date>2009-02-28T04:47:06-08:00</committed-date>
  <authored-date>2009-02-28T04:47:06-08:00</authored-date>
  <message>Merge branch 'master' into dreambox</message>
  <tree>04388b73449d882a8ecdd1077e94eb07fb016f32</tree>
  <committer>
    <name>Jonas Kramer</name>
    <email>jkramer@nex.scrapping.cc</email>
  </committer>
</commit>
