diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/configure.ac rhythmbox-0.12.1/configure.ac
--- rhythmbox-0.12.1-vanilla/configure.ac	2009-04-28 03:39:43.000000000 -0400
+++ rhythmbox-0.12.1/configure.ac	2009-08-10 20:50:45.000000000 -0400
@@ -211,11 +211,6 @@
 RHYTHMBOX_CFLAGS="$RHYTHMBOX_CFLAGS $GSTREAMER_0_10_CFLAGS"
 RHYTHMBOX_LIBS="$RHYTHMBOX_LIBS $GSTREAMER_0_10_LIBS"
 
-dnl DAAP (iTunes Music Shares)
-AC_ARG_ENABLE(daap,
-	      AC_HELP_STRING([--disable-daap],
-			     [Disable Digital Audio Access Protocol (music sharing) in rhythmbox]))
-
 AC_ARG_WITH(mdns,
    AC_HELP_STRING([--with-mdns=auto|avahi],
    [Select the mDNS/DNS-SD implementation to use (default auto)]),,
@@ -288,22 +283,6 @@
     AC_SUBST(NOTIFY_LIBS)
 fi
 
-dnl daap support
-if test "x$enable_daap" != "xno"; then
-	if test x"$have_mdns" = xno; then
-		if test "x$enable_daap" = "xyes"; then
-			AC_MSG_ERROR([DAAP support explicitly requested, but no mDNS implementation found.  Install Avahi])
-		fi
-		enable_daap=no
-	else
-		AC_DEFINE(WITH_DAAP_SUPPORT, 1, [Define if DAAP should be enabled])
-		enable_daap="yes"
-		AC_SUBST(MDNS_CFLAGS)
-		AC_SUBST(MDNS_LIBS)
-	fi
-fi
-AM_CONDITIONAL(USE_DAAP, test "x$enable_daap" != "xno")
-
 AC_CHECK_LIB(z, uncompress)
 
 dnl check for libgstcdda, needed to list the audio tracks
@@ -751,6 +730,23 @@
 
 AM_CONDITIONAL([ENABLE_BROWSER_PLUGIN], test x$enable_browser_plugin = xyes)
 
+
+dnl ================================================================
+dnl Use libdmapsharing for DAAP?
+dnl ================================================================
+PKG_CHECK_MODULES(DMAPSHARING, libdmapsharing-1.9,
+  enable_libdmapsharing=yes,
+  enable_libdmapsharing=no)
+
+if test x"$enable_libdmapsharing" = "xyes"; then
+  AC_DEFINE(HAVE_LIBDMAPSHARING, 1, [Define if libdmapsharing support is enabled])
+fi
+
+AM_CONDITIONAL(USE_LIBDMAPSHARING, test x"$enable_libdmapsharing" = "xyes")
+
+AC_SUBST(DMAPSHARING_CFLAGS)
+AC_SUBST(DMAPSHARING_LIBS)
+
 dnl ================================================================
 dnl end-game
 dnl ================================================================
@@ -886,7 +882,7 @@
 else
 	AC_MSG_NOTICE([   CD burning support disabled])
 fi
-if test x"$enable_daap" = xyes; then
+if test x"$enable_libdmapsharing" = xyes; then
 	AC_MSG_NOTICE([** DAAP (music sharing) support is enabled])
 else
 	AC_MSG_NOTICE([   DAAP (music sharing) support is disabled])
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/Makefile.am rhythmbox-0.12.1/plugins/daap/Makefile.am
--- rhythmbox-0.12.1-vanilla/plugins/daap/Makefile.am	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/Makefile.am	2009-08-15 18:13:26.000000000 -0400
@@ -6,32 +6,28 @@
 libdaap_la_SOURCES = \
 	rb-daap-plugin.c			\
 	rb-daap-plugin.h			\
-	rb-daap-source.c			\
-	rb-daap-source.h			\
+	rb-daap-record.c			\
+	rb-daap-record.h			\
+	rb-daap-record-factory.c		\
+	rb-daap-record-factory.h		\
 	rb-daap-sharing.c			\
 	rb-daap-sharing.h			\
-	rb-daap-share.c				\
-	rb-daap-share.h				\
-	rb-daap-structure.c			\
-	rb-daap-structure.h 			\
-	rb-daap-mdns-publisher.h		\
-	rb-daap-mdns-browser.h			\
-	rb-daap-connection.c			\
-	rb-daap-connection.h			\
-	rb-daap-hash.c				\
-	rb-daap-hash.h				\
+	rb-daap-source.c			\
+	rb-daap-source.h			\
 	rb-daap-src.c				\
 	rb-daap-src.h				\
 	rb-daap-dialog.c			\
 	rb-daap-dialog.h			\
-	rb-daap-mdns-avahi.c			\
-	rb-daap-mdns-avahi.h			\
-	rb-daap-mdns-publisher-avahi.c		\
-	rb-daap-mdns-browser-avahi.c		\
+	rb-dmap-db-adapter.c			\
+	rb-dmap-db-adapter.h			\
+	rb-dmap-container-db.c			\
+	rb-dmap-container-db.h			\
 	$(NULL)
 
 libdaap_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
 libdaap_la_LIBADD = 					\
+	$(GLIB_LIBS)					\
+	$(DMAPSHARING_LIBS)				\
 	$(DBUS_LIBS)					\
 	$(MDNS_LIBS)
 
@@ -56,6 +52,8 @@
 	-DPIXMAP_DIR=\""$(datadir)/pixmaps"\"		\
 	-DSHARE_DIR=\"$(pkgdatadir)\"                   \
 	-DDATADIR=\""$(datadir)"\"			\
+	$(GLIB_CFLAGS)					\
+	$(DMAPSHARING_CFLAGS)				\
 	$(MDNS_CFLAGS)					\
 	$(RHYTHMBOX_CFLAGS)				\
 	$(DBUS_CFLAGS)					\
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-connection.c rhythmbox-0.12.1/plugins/daap/rb-daap-connection.c
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-connection.c	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-connection.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1876 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- *  Implementation of DAAP (iTunes Music Sharing) hashing, parsing, connection
- *
- *  Copyright (C) 2004-2005 Charles Schmidt <cschmidt2@emich.edu>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The Rhythmbox authors hereby grant permission for non-GPL compatible
- *  GStreamer plugins to be used and distributed together with GStreamer
- *  and Rhythmbox. This permission is above and beyond the permissions granted
- *  by the GPL license by which Rhythmbox is covered. If you modify this code
- *  you may extend this exception to your version of the code, but you are not
- *  obligated to do so. If you do not wish to do so, delete this exception
- *  statement from your version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <math.h>
-#ifdef HAVE_LIBZ
-#include <zlib.h>
-#endif
-
-#include <glib/gi18n.h>
-#include <gdk/gdk.h>
-
-#include <libsoup/soup.h>
-
-#include "rb-daap-hash.h"
-#include "rb-daap-connection.h"
-#include "rb-daap-structure.h"
-#include "rb-marshal.h"
-
-#include "rb-debug.h"
-#include "rb-util.h"
-
-#define RB_DAAP_USER_AGENT "iTunes/4.6 (Windows; N)"
-
-#define ITUNES_7_SERVER "iTunes/7"
-
-static void      rb_daap_connection_dispose      (GObject *obj);
-static void      rb_daap_connection_set_property (GObject *object,
-						  guint prop_id,
-						  const GValue *value,
-						  GParamSpec *pspec);
-static void      rb_daap_connection_get_property (GObject *object,
-						  guint prop_id,
-						  GValue *value,
-						  GParamSpec *pspec);
-
-static gboolean rb_daap_connection_do_something  (RBDAAPConnection *connection);
-static void     rb_daap_connection_state_done    (RBDAAPConnection *connection,
-						  gboolean           result);
-
-static gboolean emit_progress_idle (RBDAAPConnection *connection);
-
-G_DEFINE_TYPE (RBDAAPConnection, rb_daap_connection, G_TYPE_OBJECT)
-
-#define RB_DAAP_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_DAAP_CONNECTION, RBDAAPConnectionPrivate))
-
-typedef void (* RBDAAPResponseHandler) (RBDAAPConnection *connection,
-					guint status,
-					GNode *structure);
-
-struct RBDAAPConnectionPrivate {
-	char *name;
-	gboolean password_protected;
-	char *username;
-	char *password;
-	char *host;
-	guint port;
-
-	gboolean is_connected;
-	gboolean is_connecting;
-
-	SoupSession *session;
-	SoupURI *base_uri;
-	gchar *daap_base_uri;
-
-	gdouble daap_version;
-	guint32 session_id;
-	gint revision_number;
-
-	gint request_id;
-	gint database_id;
-
-	guint reading_playlist;
-	GSList *playlists;
-	GHashTable *item_id_to_uri;
-
-	RhythmDB *db;
-	RhythmDBEntryType db_type;
-
-	RBDAAPConnectionState state;
-	RBDAAPResponseHandler response_handler;
-	gboolean use_response_handler_thread;
-	float progress;
-
-	guint emit_progress_id;
-	guint do_something_id;
-
-	gboolean result;
-	char *last_error_message;
-};
-
-enum {
-	PROP_0,
-	PROP_DB,
-	PROP_NAME,
-	PROP_ENTRY_TYPE,
-	PROP_PASSWORD_PROTECTED,
-	PROP_HOST,
-	PROP_PORT,
-};
-
-enum {
-	AUTHENTICATE,
-	CONNECTING,
-	CONNECTED,
-	DISCONNECTED,
-	OPERATION_DONE,
-	LAST_SIGNAL
-};
-
-static guint signals [LAST_SIGNAL] = { 0, };
-
-static void
-rb_daap_connection_finalize (GObject *object)
-{
-	RBDAAPConnection *connection;
-
-	g_return_if_fail (object != NULL);
-	g_return_if_fail (RB_IS_DAAP_CONNECTION (object));
-
-	connection = RB_DAAP_CONNECTION (object);
-
-	g_return_if_fail (connection->priv != NULL);
-
-	rb_debug ("Finalize");
-
-	G_OBJECT_CLASS (rb_daap_connection_parent_class)->finalize (object);
-}
-
-static void
-rb_daap_connection_class_init (RBDAAPConnectionClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-	object_class->finalize	   = rb_daap_connection_finalize;
-	object_class->dispose       = rb_daap_connection_dispose;
-	object_class->set_property = rb_daap_connection_set_property;
-	object_class->get_property = rb_daap_connection_get_property;
-
-	g_type_class_add_private (klass, sizeof (RBDAAPConnectionPrivate));
-
-	g_object_class_install_property (object_class,
-					 PROP_DB,
-					 g_param_spec_object ("db",
-							      "RhythmDB",
-							      "RhythmDB object",
-							      RHYTHMDB_TYPE,
-							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-	g_object_class_install_property (object_class,
-					 PROP_ENTRY_TYPE,
-					 g_param_spec_boxed ("entry-type",
-							     "entry type",
-							     "RhythmDBEntryType",
-							     RHYTHMDB_TYPE_ENTRY_TYPE,
-							     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
-	g_object_class_install_property (object_class,
-					 PROP_PASSWORD_PROTECTED,
-					 g_param_spec_boolean ("password-protected",
-							       "password protected",
-							       "connection is password protected",
-							       FALSE,
-							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-	g_object_class_install_property (object_class,
-					 PROP_NAME,
-					 g_param_spec_string ("name",
-						 	      "connection name",
-							      "connection name",
-							      NULL,
-							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-	g_object_class_install_property (object_class,
-					 PROP_HOST,
-					 g_param_spec_string ("host",
-						 	      "host",
-							      "host",
-							      NULL,
-							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-	g_object_class_install_property (object_class,
-					 PROP_PORT,
-					 g_param_spec_uint ("port",
-							    "port",
-							    "port",
-							    0, G_MAXINT, 0,
-							    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
-	signals [AUTHENTICATE] = g_signal_new ("authenticate",
-					       G_TYPE_FROM_CLASS (object_class),
-					       G_SIGNAL_RUN_LAST,
-					       G_STRUCT_OFFSET (RBDAAPConnectionClass, authenticate),
-					       NULL,
-					       NULL,
-					       rb_marshal_STRING__STRING,
-					       G_TYPE_STRING,
-					       1, G_TYPE_STRING);
-	signals [CONNECTING] = g_signal_new ("connecting",
-					     G_TYPE_FROM_CLASS (object_class),
-					     G_SIGNAL_RUN_LAST,
-					     G_STRUCT_OFFSET (RBDAAPConnectionClass, connecting),
-					     NULL,
-					     NULL,
-					     rb_marshal_VOID__ULONG_FLOAT,
-					     G_TYPE_NONE,
-					     2, G_TYPE_ULONG, G_TYPE_FLOAT);
-	signals [CONNECTED] = g_signal_new ("connected",
-					    G_TYPE_FROM_CLASS (object_class),
-					    G_SIGNAL_RUN_LAST,
-					    G_STRUCT_OFFSET (RBDAAPConnectionClass, connected),
-					    NULL,
-					    NULL,
-					    g_cclosure_marshal_VOID__VOID,
-					       G_TYPE_NONE,
-					    0);
-	signals [DISCONNECTED] = g_signal_new ("disconnected",
-					       G_TYPE_FROM_CLASS (object_class),
-					       G_SIGNAL_RUN_LAST,
-					       G_STRUCT_OFFSET (RBDAAPConnectionClass, disconnected),
-					       NULL,
-					       NULL,
-					       g_cclosure_marshal_VOID__VOID,
-					       G_TYPE_NONE,
-					       0);
-	signals [OPERATION_DONE] = g_signal_new ("operation-done",
-						 G_TYPE_FROM_CLASS (object_class),
-						 G_SIGNAL_RUN_FIRST,
-						 G_STRUCT_OFFSET (RBDAAPConnectionClass, operation_done),
-						 NULL,
-						 NULL,
-						 g_cclosure_marshal_VOID__VOID,
-						 G_TYPE_NONE,
-						 0);
-}
-
-static void
-rb_daap_connection_init (RBDAAPConnection *connection)
-{
-	connection->priv = RB_DAAP_CONNECTION_GET_PRIVATE (connection);
-
-	connection->priv->username = g_strdup_printf ("Rhythmbox_%s", VERSION);
-	connection->priv->db_type = RHYTHMDB_ENTRY_TYPE_INVALID;
-}
-
-static char *
-connection_get_password (RBDAAPConnection *connection)
-{
-	char *password = NULL;;
-
-	GDK_THREADS_ENTER ();
-	g_signal_emit (connection,
-		       signals [AUTHENTICATE],
-		       0,
-		       connection->priv->name,
-		       &password);
-	GDK_THREADS_LEAVE ();
-
-	return password;
-}
-
-static void
-connection_connected (RBDAAPConnection *connection)
-{
-	rb_debug ("Emitting connected");
-
-	connection->priv->is_connected = TRUE;
-
-	GDK_THREADS_ENTER ();
-	g_signal_emit (connection,
-		       signals [CONNECTED],
-		       0);
-	GDK_THREADS_LEAVE ();
-}
-
-static void
-connection_disconnected (RBDAAPConnection *connection)
-{
-	rb_debug ("Emitting disconnected");
-
-	connection->priv->is_connected = FALSE;
-
-	GDK_THREADS_ENTER ();
-	g_signal_emit (connection,
-		       signals [DISCONNECTED],
-		       0);
-	GDK_THREADS_LEAVE ();
-}
-
-static void
-connection_operation_done (RBDAAPConnection *connection)
-{
-	rb_debug ("Emitting operation done");
-
-	GDK_THREADS_ENTER ();
-	g_signal_emit (connection,
-		       signals [OPERATION_DONE],
-		       0);
-	GDK_THREADS_LEAVE ();
-}
-
-static SoupMessage *
-build_message (RBDAAPConnection *connection,
-	       const char       *path,
-	       gboolean          need_hash,
-	       gdouble           version,
-	       gint              req_id,
-	       gboolean          send_close)
-{
-	RBDAAPConnectionPrivate *priv = connection->priv;
-	SoupMessage *message = NULL;
-	SoupURI *uri = NULL;
-
-	uri = soup_uri_new_with_base (priv->base_uri, path);
-	if (uri == NULL) {
-		return NULL;
-	}
-
-	message = soup_message_new_from_uri (SOUP_METHOD_GET, uri);
-
-	soup_message_headers_append (message->request_headers, "Client-DAAP-Version", 		"3.0");
-	soup_message_headers_append (message->request_headers, "Accept-Language", 		"en-us, en;q=5.0");
-#ifdef HAVE_LIBZ
-	soup_message_headers_append (message->request_headers, "Accept-Encoding",		"gzip");
-#endif
-	soup_message_headers_append (message->request_headers, "Client-DAAP-Access-Index", 	"2");
-
-	if (priv->password_protected) {
-		char *h;
-		char *user_pass;
-		char *token;
-
-		user_pass = g_strdup_printf ("%s:%s", priv->username, priv->password);
-		token = g_base64_encode ((guchar *)user_pass, strlen (user_pass));
-		h = g_strdup_printf ("Basic %s", token);
-
-		g_free (token);
-		g_free (user_pass);
-
-		soup_message_headers_append (message->request_headers, "Authorization", h);
-		g_free (h);
-	}
-
-	if (need_hash) {
-		gchar hash[33] = {0};
-		gchar *no_daap_path = (gchar *)path;
-
-		if (g_ascii_strncasecmp (path, "daap://", 7) == 0) {
-			no_daap_path = strstr (path, "/data");
-		}
-
-		rb_daap_hash_generate ((short)floor (version), (const guchar*)no_daap_path, 2, (guchar*)hash, req_id);
-
-		soup_message_headers_append (message->request_headers, "Client-DAAP-Validation", hash);
-	}
-	if (send_close) {
-		soup_message_headers_append (message->request_headers, "Connection", "close");
-	}
-
-	soup_uri_free (uri);
-
-	return message;
-}
-
-#ifdef HAVE_LIBZ
-static void
-*g_zalloc_wrapper (voidpf opaque, uInt items, uInt size)
-{
-	if ((items != 0) && (size >= G_MAXUINT/items)) {
-		return Z_NULL;
-	}
-	if ((size != 0) && (items >= G_MAXUINT/size)) {
-		return Z_NULL;
-	}
-	return g_malloc0 (items * size);
-}
-
-static void
-g_zfree_wrapper (voidpf opaque, voidpf address)
-{
-	g_free (address);
-}
-#endif
-
-static void
-connection_set_error_message (RBDAAPConnection *connection,
-			      const char       *message)
-{
-	/* FIXME: obtain a lock */
-	g_free (connection->priv->last_error_message);
-	if (message != NULL) {
-		connection->priv->last_error_message = g_strdup (message);
-	} else {
-		connection->priv->last_error_message = NULL;
-	}
-}
-
-typedef struct {
-	SoupMessage *message;
-	int status;
-	RBDAAPConnection *connection;
-} DAAPResponseData;
-
-static void
-actual_http_response_handler (DAAPResponseData *data)
-{
-	RBDAAPConnectionPrivate *priv;
-	GNode *structure;
-	char *new_response = NULL;
-	const char *response;
-	const char *encoding_header;
-	char *message_path;
-	int response_length;
-	gboolean compatible_server = TRUE;
-
-	priv = data->connection->priv;
-	structure = NULL;
-	encoding_header = NULL;
-	response = data->message->response_body->data;
-	response_length = data->message->response_body->length;
-
-	message_path = soup_uri_to_string (soup_message_get_uri (data->message), FALSE);
-
-	rb_debug ("Received response from %s: %d, %s\n",
-		  message_path,
-		  data->message->status_code,
-		  data->message->reason_phrase);
-
-	if (data->message->response_headers) {
-		const char *server;
-
-		encoding_header = soup_message_headers_get (data->message->response_headers, "Content-Encoding");
-
-		server = soup_message_headers_get (data->message->response_headers, "DAAP-Server");
-		if (server != NULL && strstr (server, ITUNES_7_SERVER) != NULL) {
-			rb_debug ("giving up.  we can't talk to %s", server);
-			compatible_server = FALSE;
-		}
-	}
-
-	if (SOUP_STATUS_IS_SUCCESSFUL (data->status) && encoding_header && strcmp (encoding_header, "gzip") == 0) {
-#ifdef HAVE_LIBZ
-		z_stream stream;
-		unsigned int factor = 4;
-		unsigned int unc_size = response_length * factor;
-
-		stream.next_in = (unsigned char *)response;
-		stream.avail_in = response_length;
-		stream.total_in = 0;
-
-		new_response = g_malloc (unc_size + 1);
-		stream.next_out = (unsigned char *)new_response;
-		stream.avail_out = unc_size;
-		stream.total_out = 0;
-		stream.zalloc = g_zalloc_wrapper;
-		stream.zfree = g_zfree_wrapper;
-		stream.opaque = NULL;
-
-		rb_profile_start ("decompressing DAAP response");
-
-		if (inflateInit2 (&stream, 32 /* auto-detect */ + 15 /* max */ ) != Z_OK) {
-			inflateEnd (&stream);
-			g_free (new_response);
-			rb_debug ("Unable to decompress response from %s",
-				  message_path);
-			data->status = SOUP_STATUS_MALFORMED;
-			rb_profile_end ("decompressing DAAP response (failed)");
-		} else {
-			do {
-				int z_res;
-
-				rb_profile_start ("attempting inflate");
-				z_res = inflate (&stream, Z_FINISH);
-				if (z_res == Z_STREAM_END) {
-					rb_profile_end ("attempting inflate (done)");
-					break;
-				}
-				if ((z_res != Z_OK && z_res != Z_BUF_ERROR) || stream.avail_out != 0 || unc_size > 40*1000*1000) {
-					inflateEnd (&stream);
-					g_free (new_response);
-					new_response = NULL;
-					rb_profile_end ("attempting inflate (error)");
-					break;
-				}
-
-				factor *= 4;
-				unc_size = (response_length * factor);
-				/* unc_size can't grow bigger than 40MB, so
-				 * unc_size can't overflow, and this realloc
-				 * call is safe
-				 */
-				new_response = g_realloc (new_response, unc_size + 1);
-				stream.next_out = (unsigned char *)(new_response + stream.total_out);
-				stream.avail_out = unc_size - stream.total_out;
-				rb_profile_end ("attempting inflate (incomplete)");
-			} while (1);
-		}
-		rb_profile_end ("decompressing DAAP response (successful)");
-
-		if (new_response) {
-			response = new_response;
-			response_length = stream.total_out;
-		}
-#else
-		rb_debug ("Received compressed response from %s but can't handle it",
-			  message_path);
-		data->status = SOUP_STATUS_MALFORMED;
-#endif
-	}
-
-	if (compatible_server == FALSE) {
-		/* leaving structure == NULL here causes the connection process
-		 * to fail at the first step.
-		 */
-		connection_set_error_message (data->connection,
-					      _("Rhythmbox is not able to connect to iTunes 7 shares"));
-	} else if (SOUP_STATUS_IS_SUCCESSFUL (data->status)) {
-		RBDAAPItem *item;
-
-		if (!rb_is_main_thread ()) {
-			priv->progress = -1.0f;
-			if (priv->emit_progress_id != 0) {
-				g_source_remove (priv->emit_progress_id);
-			}
-			priv->emit_progress_id = g_idle_add ((GSourceFunc) emit_progress_idle, data->connection);
-		}
-		rb_profile_start ("parsing DAAP response");
-		structure = rb_daap_structure_parse (response, response_length);
-		if (structure == NULL) {
-			rb_debug ("No daap structure returned from %s",
-				  message_path);
-
-			data->status = SOUP_STATUS_MALFORMED;
-			rb_profile_end ("parsing DAAP response (failed)");
-		} else {
-			int dmap_status = 0;
-			item = rb_daap_structure_find_item (structure, RB_DAAP_CC_MSTT);
-			if (item)
-				dmap_status = g_value_get_int (&(item->content));
-
-			if (dmap_status != 200) {
-				rb_debug ("Error, dmap.status is not 200 in response from %s",
-					  message_path);
-
-				data->status = SOUP_STATUS_MALFORMED;
-			}
-			rb_profile_end ("parsing DAAP response (successful)");
-		}
-		if (! rb_is_main_thread ()) {
-			priv->progress = 1.0f;
-			if (priv->emit_progress_id != 0) {
-				g_source_remove (priv->emit_progress_id);
-			}
-			priv->emit_progress_id = g_idle_add ((GSourceFunc) emit_progress_idle, data->connection);
-		}
-	} else {
-		rb_debug ("Error getting %s: %d, %s\n",
-			  message_path,
-			  data->message->status_code,
-			  data->message->reason_phrase);
-		connection_set_error_message (data->connection, data->message->reason_phrase);
-	}
-
-	if (priv->response_handler) {
-		RBDAAPResponseHandler h = priv->response_handler;
-		priv->response_handler = NULL;
-		(*h) (data->connection, data->status, structure);
-	}
-
-	if (structure) {
-		rb_daap_structure_destroy (structure);
-	}
-
-	g_free (new_response);
-	g_free (message_path);
-	g_object_unref (G_OBJECT (data->connection));
-	g_object_unref (G_OBJECT (data->message));
-	g_free (data);
-}
-
-static void
-http_response_handler (SoupSession      *session,
-		       SoupMessage      *message,
-		       RBDAAPConnection *connection)
-{
-	DAAPResponseData *data;
-	int response_length;
-
-	if (message->status_code == SOUP_STATUS_CANCELLED) {
-		rb_debug ("Message cancelled");
-		return;
-	}
-
-	data = g_new0 (DAAPResponseData, 1);
-	data->status = message->status_code;
-	response_length = message->response_body->length;
-
-	g_object_ref (G_OBJECT (connection));
-	data->connection = connection;
-
-	g_object_ref (G_OBJECT (message));
-	data->message = message;
-
-	if (response_length >= G_MAXUINT/4 - 1) {
-		/* If response_length is too big,
-		 * the g_malloc (unc_size + 1) below would overflow
-		 */
-		data->status = SOUP_STATUS_MALFORMED;
-	}
-
-	/* to avoid blocking the UI, handle big responses in a separate thread */
-	if (SOUP_STATUS_IS_SUCCESSFUL (data->status) && connection->priv->use_response_handler_thread) {
-		GError *error = NULL;
-		rb_debug ("creating thread to handle daap response");
-		g_thread_create ((GThreadFunc) actual_http_response_handler,
-				 data,
-				 FALSE,
-				 &error);
-		if (error) {
-			g_warning ("fuck");
-		}
-	} else {
-		actual_http_response_handler (data);
-	}
-}
-
-static gboolean
-http_get (RBDAAPConnection     *connection,
-	  const char           *path,
-	  gboolean              need_hash,
-	  gdouble               version,
-	  gint                  req_id,
-	  gboolean              send_close,
-	  RBDAAPResponseHandler handler,
-	  gboolean              use_thread)
-{
-	RBDAAPConnectionPrivate *priv = connection->priv;
-	SoupMessage *message;
-
-	message = build_message (connection, path, need_hash, version, req_id, send_close);
-	if (message == NULL) {
-		rb_debug ("Error building message for http://%s:%d/%s",
-			  priv->base_uri->host,
-			  priv->base_uri->port,
-			  path);
-		return FALSE;
-	}
-
-	priv->use_response_handler_thread = use_thread;
-	priv->response_handler = handler;
-	soup_session_queue_message (priv->session, message,
-				    (SoupSessionCallback) http_response_handler,
-				    connection);
-	rb_debug ("Queued message for http://%s:%d/%s",
-		  priv->base_uri->host,
-		  priv->base_uri->port,
-		  path);
-	return TRUE;
-}
-
-static void
-entry_set_string_prop (RhythmDB        *db,
-		       RhythmDBEntry   *entry,
-		       RhythmDBPropType propid,
-		       const char      *str)
-{
-	GValue value = {0,};
-	const gchar *tmp;
-
-	if (str == NULL || *str == '\0' || !g_utf8_validate (str, -1, NULL)) {
-		tmp = _("Unknown");
-	} else {
-		tmp = str;
-	}
-
-	g_value_init (&value, G_TYPE_STRING);
-	g_value_set_string (&value, tmp);
-	rhythmdb_entry_set (RHYTHMDB (db), entry, propid, &value);
-	g_value_unset (&value);
-}
-
-static gboolean
-emit_progress_idle (RBDAAPConnection *connection)
-{
-	rb_debug ("Emitting progress");
-
-	GDK_THREADS_ENTER ();
-	g_signal_emit (G_OBJECT (connection), signals[CONNECTING], 0,
-		       connection->priv->state,
-		       connection->priv->progress);
-	connection->priv->emit_progress_id = 0;
-	GDK_THREADS_LEAVE ();
-	return FALSE;
-}
-
-static void
-handle_server_info (RBDAAPConnection *connection,
-		    guint             status,
-		    GNode            *structure)
-{
-	RBDAAPConnectionPrivate *priv = connection->priv;
-	RBDAAPItem *item = NULL;
-
-	if (!SOUP_STATUS_IS_SUCCESSFUL (status) || structure == NULL) {
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	/* get the daap version number */
-	item = rb_daap_structure_find_item (structure, RB_DAAP_CC_APRO);
-	if (item == NULL) {
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	priv->daap_version = g_value_get_double (&(item->content));
-	rb_daap_connection_state_done (connection, TRUE);
-}
-
-static void
-handle_login (RBDAAPConnection *connection,
-	      guint             status,
-	      GNode            *structure)
-{
-	RBDAAPConnectionPrivate *priv = connection->priv;
-	RBDAAPItem *item = NULL;
-
-	if (status == SOUP_STATUS_UNAUTHORIZED || status == SOUP_STATUS_FORBIDDEN) {
-		rb_debug ("Incorrect password");
-		priv->state = DAAP_GET_PASSWORD;
-		if (priv->do_something_id != 0) {
-			g_source_remove (priv->do_something_id);
-		}
-		priv->do_something_id = g_idle_add ((GSourceFunc) rb_daap_connection_do_something, connection);
-		return;
-	}
-
-	if (structure == NULL || SOUP_STATUS_IS_SUCCESSFUL (status) == FALSE) {
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	item = rb_daap_structure_find_item (structure, RB_DAAP_CC_MLID);
-	if (item == NULL) {
-		rb_debug ("Could not find daap.sessionid item in /login");
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	priv->session_id = (guint32) g_value_get_int (&(item->content));
-
-	connection_connected (connection);
-
-	rb_daap_connection_state_done (connection, TRUE);
-}
-
-static void
-handle_update (RBDAAPConnection *connection,
-	       guint             status,
-	       GNode            *structure)
-{
-	RBDAAPConnectionPrivate *priv = connection->priv;
-	RBDAAPItem *item;
-
-	if (structure == NULL || SOUP_STATUS_IS_SUCCESSFUL (status) == FALSE) {
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	/* get a revision number */
-	item = rb_daap_structure_find_item (structure, RB_DAAP_CC_MUSR);
-	if (item == NULL) {
-		rb_debug ("Could not find daap.serverrevision item in /update");
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	priv->revision_number = g_value_get_int (&(item->content));
-	rb_daap_connection_state_done (connection, TRUE);
-}
-
-static void
-handle_database_info (RBDAAPConnection *connection,
-		      guint             status,
-		      GNode            *structure)
-{
-	RBDAAPConnectionPrivate *priv = connection->priv;
-	RBDAAPItem *item = NULL;
-	GNode *listing_node;
-	gint n_databases = 0;
-
-	/* get a list of databases, there should be only 1 */
-
-	if (structure == NULL || SOUP_STATUS_IS_SUCCESSFUL (status) == FALSE) {
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	item = rb_daap_structure_find_item (structure, RB_DAAP_CC_MRCO);
-	if (item == NULL) {
-		rb_debug ("Could not find dmap.returnedcount item in /databases");
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	n_databases = g_value_get_int (&(item->content));
-	if (n_databases != 1) {
-		rb_debug ("Host seems to have more than 1 database, how strange\n");
-	}
-
-	listing_node = rb_daap_structure_find_node (structure, RB_DAAP_CC_MLCL);
-	if (listing_node == NULL) {
-		rb_debug ("Could not find dmap.listing item in /databases");
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	item = rb_daap_structure_find_item (listing_node->children, RB_DAAP_CC_MIID);
-	if (item == NULL) {
-		rb_debug ("Could not find dmap.itemid item in /databases");
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	priv->database_id = g_value_get_int (&(item->content));
-	rb_daap_connection_state_done (connection, TRUE);
-}
-
-static void
-handle_song_listing (RBDAAPConnection *connection,
-		     guint             status,
-		     GNode            *structure)
-{
-	RBDAAPConnectionPrivate *priv = connection->priv;
-	RBDAAPItem *item = NULL;
-	GNode *listing_node;
-	gint returned_count;
-	gint i;
-	GNode *n;
-	gint specified_total_count;
-	gboolean update_type;
-	gint commit_batch;
-
-	/* get the songs */
-
-	if (structure == NULL || SOUP_STATUS_IS_SUCCESSFUL (status) == FALSE) {
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	item = rb_daap_structure_find_item (structure, RB_DAAP_CC_MRCO);
-	if (item == NULL) {
-		rb_debug ("Could not find dmap.returnedcount item in /databases/%d/items",
-			  priv->database_id);
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-	returned_count = g_value_get_int (&(item->content));
-	if (returned_count > 20) {
-		commit_batch = returned_count / 20;
-	} else {
-		commit_batch = 1;
-	}
-
-	item = rb_daap_structure_find_item (structure, RB_DAAP_CC_MTCO);
-	if (item == NULL) {
-		rb_debug ("Could not find dmap.specifiedtotalcount item in /databases/%d/items",
-			  priv->database_id);
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-	specified_total_count = g_value_get_int (&(item->content));
-
-	item = rb_daap_structure_find_item (structure, RB_DAAP_CC_MUTY);
-	if (item == NULL) {
-		rb_debug ("Could not find dmap.updatetype item in /databases/%d/items",
-			  priv->database_id);
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-	update_type = g_value_get_char (&(item->content));
-
-	listing_node = rb_daap_structure_find_node (structure, RB_DAAP_CC_MLCL);
-	if (listing_node == NULL) {
-		rb_debug ("Could not find dmap.listing item in /databases/%d/items",
-			  priv->database_id);
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	priv->item_id_to_uri = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)rb_refstring_unref);
-
-	rb_profile_start ("handling song listing");
-	priv->progress = 0.0f;
-	if (priv->emit_progress_id != 0) {
-		g_source_remove (priv->emit_progress_id);
-	}
-	connection->priv->emit_progress_id = g_idle_add ((GSourceFunc) emit_progress_idle, connection);
-
-	for (i = 0, n = listing_node->children; n; i++, n = n->next) {
-		GNode *n2;
-		RhythmDBEntry *entry = NULL;
-		GValue value = {0,};
-		gchar *uri = NULL;
-		gint item_id = 0;
-		const gchar *title = NULL;
-		const gchar *album = NULL;
-		const gchar *artist = NULL;
-		const gchar *format = NULL;
-		const gchar *genre = NULL;
-		const gchar *streamURI = NULL;
-		gint length = 0;
-		gint track_number = 0;
-		gint disc_number = 0;
-		gint year = 0;
-		gint size = 0;
-		gint bitrate = 0;
-
-		for (n2 = n->children; n2; n2 = n2->next) {
-			RBDAAPItem *meta_item;
-
-			meta_item = n2->data;
-
-			switch (meta_item->content_code) {
-				case RB_DAAP_CC_MIID:
-					item_id = g_value_get_int (&(meta_item->content));
-					break;
-				case RB_DAAP_CC_MINM:
-					title = g_value_get_string (&(meta_item->content));
-					break;
-				case RB_DAAP_CC_ASAL:
-					album = g_value_get_string (&(meta_item->content));
-					break;
-				case RB_DAAP_CC_ASAR:
-					artist = g_value_get_string (&(meta_item->content));
-					break;
-				case RB_DAAP_CC_ASFM:
-					format = g_value_get_string (&(meta_item->content));
-					break;
-				case RB_DAAP_CC_ASGN:
-					genre = g_value_get_string (&(meta_item->content));
-					break;
-				case RB_DAAP_CC_ASTM:
-					length = g_value_get_int (&(meta_item->content));
-					break;
-				case RB_DAAP_CC_ASTN:
-					track_number = g_value_get_int (&(meta_item->content));
-					break;
-				case RB_DAAP_CC_ASDN:
-					disc_number = g_value_get_int (&(meta_item->content));
-					break;
-				case RB_DAAP_CC_ASYR:
-					year = g_value_get_int (&(meta_item->content));
-					break;
-				case RB_DAAP_CC_ASSZ:
-					size = g_value_get_int (&(meta_item->content));
-					break;
-				case RB_DAAP_CC_ASBR:
-					bitrate = g_value_get_int (&(meta_item->content));
-					break;
-				case RB_DAAP_CC_ASUL:
-					streamURI = g_value_get_string (&(meta_item->content));
-					break;
-				default:
-					break;
-			}
-		}
-
-		/*if (connection->daap_version == 3.0) {*/
-			uri = g_strdup_printf ("%s/databases/%d/items/%d.%s?session-id=%u",
-					       priv->daap_base_uri,
-					       priv->database_id,
-					       item_id, format,
-					       priv->session_id);
-		/*} else {*/
-		/* uri should be
-		 * "/databases/%d/items/%d.%s?session-id=%u&revision-id=%d";
-		 * but its not going to work cause the other parts of the code
-		 * depend on the uri to have the ip address so that the
-		 * RBDAAPSource can be found to ++request_id
-		 * maybe just /dont/ support older itunes.  doesn't seem
-		 * unreasonable to me, honestly
-		 */
-		/*}*/
-		entry = rhythmdb_entry_new (priv->db, priv->db_type, uri);
-		if (entry == NULL) {
-			rb_debug ("cannot create entry for daap track %s", uri);
-			continue;
-		}
-		g_hash_table_insert (priv->item_id_to_uri, GINT_TO_POINTER (item_id), rb_refstring_new (uri));
-		g_free (uri);
-
-		/* year */
-		if (year != 0) {
-			GDate *date;
-			gulong julian;
-
-			/* create dummy date with given year */
-			date = g_date_new_dmy (1, G_DATE_JANUARY, year);
-			julian = g_date_get_julian (date);
-			g_date_free (date);
-
-			g_value_init (&value, G_TYPE_ULONG);
-			g_value_set_ulong (&value,julian);
-			rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_DATE, &value);
-			g_value_unset (&value);
-		}
-
-		/* track number */
-		g_value_init (&value, G_TYPE_ULONG);
-		g_value_set_ulong (&value,(gulong)track_number);
-		rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_TRACK_NUMBER, &value);
-		g_value_unset (&value);
-
-		/* disc number */
-		g_value_init (&value, G_TYPE_ULONG);
-		g_value_set_ulong (&value,(gulong)disc_number);
-		rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_DISC_NUMBER, &value);
-		g_value_unset (&value);
-
-		/* bitrate */
-		g_value_init (&value, G_TYPE_ULONG);
-		g_value_set_ulong (&value,(gulong)bitrate);
-		rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_BITRATE, &value);
-		g_value_unset (&value);
-
-		/* length */
-		g_value_init (&value, G_TYPE_ULONG);
-		g_value_set_ulong (&value,(gulong)length / 1000);
-		rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_DURATION, &value);
-		g_value_unset (&value);
-
-		/* file size */
-		g_value_init (&value, G_TYPE_UINT64);
-		g_value_set_uint64(&value,(gint64)size);
-		rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_FILE_SIZE, &value);
-		g_value_unset (&value);
-
-		/* title */
-		entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_TITLE, title);
-
-		/* album */
-		entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_ALBUM, album);
-
-		/* artist */
-		entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_ARTIST, artist);
-
-		/* genre */
-		entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_GENRE, genre);
-
-		/* stream URI property is stored as a mountpoint for get_playback_uri */
-		if (streamURI && *streamURI != '\0') {
-			entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_MOUNTPOINT, streamURI);
-		}
-
-		if (i % commit_batch == 0) {
-			connection->priv->progress = ((float)i / (float)returned_count);
-			if (priv->emit_progress_id != 0) {
-				g_source_remove (connection->priv->emit_progress_id);
-			}
-			connection->priv->emit_progress_id = g_idle_add ((GSourceFunc) emit_progress_idle, connection);
-			rhythmdb_commit (priv->db);
-		}
-	}
-	rhythmdb_commit (priv->db);
-	rb_profile_end ("handling song listing");
-
-	rb_daap_connection_state_done (connection, TRUE);
-}
-
-static int
-compare_playlists_by_name(gconstpointer a, gconstpointer b)
-{
-	const RBDAAPPlaylist *playlist1 = a;
-	const RBDAAPPlaylist *playlist2 = b;
-
-	return strcmp(playlist1->name, playlist2->name);
-}
-
-/* FIXME
- * what we really should do is only get a list of playlists and their ids
- * then when they are clicked on ('activate'd) by the user, get a list of
- * the files that are actually in them.  This will speed up initial daap
- * connection times and reduce memory consumption.
- */
-
-static void
-handle_playlists (RBDAAPConnection *connection,
-		  guint             status,
-		  GNode            *structure)
-{
-	RBDAAPConnectionPrivate *priv = connection->priv;
-	GNode *listing_node;
-	gint i;
-	GNode *n;
-
-	if (structure == NULL || SOUP_STATUS_IS_SUCCESSFUL (status) == FALSE) {
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	listing_node = rb_daap_structure_find_node (structure, RB_DAAP_CC_MLCL);
-	if (listing_node == NULL) {
-		rb_debug ("Could not find dmap.listing item in /databases/%d/containers",
-			  priv->database_id);
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	for (i = 0, n = listing_node->children; n; n = n->next, i++) {
-		RBDAAPItem *item;
-		gint id;
-		gchar *name;
-		RBDAAPPlaylist *playlist;
-
-		item = rb_daap_structure_find_item (n, RB_DAAP_CC_ABPL);
-		if (item != NULL) {
-			continue;
-		}
-
-		item = rb_daap_structure_find_item (n, RB_DAAP_CC_MIID);
-		if (item == NULL) {
-			rb_debug ("Could not find dmap.itemid item in /databases/%d/containers",
-				  priv->database_id);
-			continue;
-		}
-		id = g_value_get_int (&(item->content));
-
-		item = rb_daap_structure_find_item (n, RB_DAAP_CC_MINM);
-		if (item == NULL) {
-			rb_debug ("Could not find dmap.itemname item in /databases/%d/containers",
-				  priv->database_id);
-			continue;
-		}
-		name = g_value_dup_string (&(item->content));
-
-		playlist = g_new0 (RBDAAPPlaylist, 1);
-		playlist->id = id;
-		playlist->name = name;
-		rb_debug ("Got playlist %p: name %s, id %d", playlist, playlist->name, playlist->id);
-
-		priv->playlists = g_slist_prepend (priv->playlists, playlist);
-	}
-
-	/* Sort the playlists into lexical order. Established DAAP clients already
-	 * do this leading to an absence of sorting functionality in DAAP servers. */
-	priv->playlists = g_slist_sort (priv->playlists, compare_playlists_by_name);
-
-	rb_daap_connection_state_done (connection, TRUE);
-}
-
-static void
-handle_playlist_entries (RBDAAPConnection *connection,
-			 guint             status,
-			 GNode            *structure)
-{
-	RBDAAPConnectionPrivate *priv = connection->priv;
-	RBDAAPPlaylist *playlist;
-	GNode *listing_node;
-	GNode *node;
-	gint i;
-	GList *playlist_uris = NULL;
-
-	if (structure == NULL || SOUP_STATUS_IS_SUCCESSFUL (status) == FALSE) {
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	playlist = (RBDAAPPlaylist *)g_slist_nth_data (priv->playlists, priv->reading_playlist);
-	g_assert (playlist);
-
-	listing_node = rb_daap_structure_find_node (structure, RB_DAAP_CC_MLCL);
-	if (listing_node == NULL) {
-		rb_debug ("Could not find dmap.listing item in /databases/%d/containers/%d/items",
-			  priv->database_id, playlist->id);
-		rb_daap_connection_state_done (connection, FALSE);
-		return;
-	}
-
-	rb_profile_start ("handling playlist entries");
-	for (i = 0, node = listing_node->children; node; node = node->next, i++) {
-		RBRefString *item_uri;
-		gint playlist_item_id;
-		RBDAAPItem *item;
-
-		item = rb_daap_structure_find_item (node, RB_DAAP_CC_MIID);
-		if (item == NULL) {
-			rb_debug ("Could not find dmap.itemid item in /databases/%d/containers/%d/items",
-				  priv->database_id, playlist->id);
-			continue;
-		}
-		playlist_item_id = g_value_get_int (&(item->content));
-
-		item_uri = g_hash_table_lookup (priv->item_id_to_uri, GINT_TO_POINTER (playlist_item_id));
-		if (item_uri == NULL) {
-			rb_debug ("Entry %d in playlist %s doesn't exist in the database\n",
-				  playlist_item_id, playlist->name);
-			continue;
-		}
-
-		playlist_uris = g_list_prepend (playlist_uris, rb_refstring_ref (item_uri));
-	}
-	rb_profile_end ("handling playlist entries");
-
-	playlist->uris = g_list_reverse (playlist_uris);
-	rb_daap_connection_state_done (connection, TRUE);
-}
-
-static void
-handle_logout (RBDAAPConnection *connection,
-	       guint             status,
-	       GNode            *structure)
-{
-	connection_disconnected (connection);
-
-	/* is there any point handling errors here? */
-	rb_daap_connection_state_done (connection, TRUE);
-}
-
-RBDAAPConnection *
-rb_daap_connection_new (const char       *name,
-			const char       *host,
-			int               port,
-			gboolean          password_protected,
-			RhythmDB         *db,
-			RhythmDBEntryType type)
-{
-	return g_object_new (RB_TYPE_DAAP_CONNECTION,
-			     "name", name,
-			     "entry-type", type,
-			     "password-protected", password_protected,
-			     "db", db,
-			     "host", host,
-			     "port", port,
-			     NULL);
-}
-
-gboolean
-rb_daap_connection_is_connected (RBDAAPConnection *connection)
-{
-	g_return_val_if_fail (RB_IS_DAAP_CONNECTION (connection), FALSE);
-
-	return connection->priv->is_connected;
-}
-
-typedef struct {
-	RBDAAPConnection        *connection;
-	RBDAAPConnectionCallback callback;
-	gpointer                 data;
-	GDestroyNotify           destroy;
-} ConnectionResponseData;
-
-static void
-connection_response_data_free (gpointer data)
-{
-	ConnectionResponseData *rdata = data;
-
-	g_object_unref (rdata->connection);
-	g_free (rdata);
-}
-
-static void
-connected_cb (RBDAAPConnection       *connection,
-	      ConnectionResponseData *rdata)
-{
-	gboolean result;
-
-	rb_debug ("Connected callback");
-
-	connection->priv->is_connecting = FALSE;
-
-	g_signal_handlers_disconnect_by_func (connection,
-					      G_CALLBACK (connected_cb),
-					      rdata);
-
-	/* if connected then we succeeded */
-	result = rb_daap_connection_is_connected (connection);
-
-	if (rdata->callback) {
-		rdata->callback (rdata->connection,
-				 result,
-				 rdata->connection->priv->last_error_message,
-				 rdata->data);
-	}
-
-	if (rdata->destroy) {
-		rdata->destroy (rdata);
-	}
-}
-
-void
-rb_daap_connection_connect (RBDAAPConnection        *connection,
-			    RBDAAPConnectionCallback callback,
-			    gpointer                 user_data)
-{
-	ConnectionResponseData *rdata;
-	char                   *path;
-
-	g_return_if_fail (RB_IS_DAAP_CONNECTION (connection));
-	g_return_if_fail (connection->priv->state == DAAP_GET_INFO);
-
-	rb_debug ("Creating new DAAP connection to %s:%d", connection->priv->host, connection->priv->port);
-
-	connection->priv->session = soup_session_async_new ();
-
-	path = g_strdup_printf ("http://%s:%d", connection->priv->host, connection->priv->port);
-	connection->priv->base_uri = soup_uri_new (path);
-	g_free (path);
-
-	if (connection->priv->base_uri == NULL) {
-		rb_debug ("Error parsing http://%s:%d", connection->priv->host, connection->priv->port);
-		/* FIXME: do callback */
-		return;
-	}
-
-	connection->priv->daap_base_uri = g_strdup_printf ("daap://%s:%d", connection->priv->host, connection->priv->port);
-
-	rdata = g_new (ConnectionResponseData, 1);
-	rdata->connection = g_object_ref (connection);
-	rdata->callback = callback;
-	rdata->data = user_data;
-	rdata->destroy = connection_response_data_free;
-	g_signal_connect (connection, "operation-done", G_CALLBACK (connected_cb), rdata);
-
-	if (connection->priv->do_something_id != 0) {
-		g_source_remove (connection->priv->do_something_id);
-	}
-
-	connection->priv->is_connecting = TRUE;
-	connection->priv->do_something_id = g_idle_add ((GSourceFunc) rb_daap_connection_do_something, connection);
-}
-
-static void
-disconnected_cb (RBDAAPConnection       *connection,
-		 ConnectionResponseData *rdata)
-{
-	gboolean result;
-
-	rb_debug ("Disconnected callback");
-
-	g_signal_handlers_disconnect_by_func (connection,
-					      G_CALLBACK (disconnected_cb),
-					      rdata);
-
-	/* if not connected then we succeeded */
-	result = ! rb_daap_connection_is_connected (connection);
-
-	if (rdata->callback) {
-		rdata->callback (rdata->connection,
-				 result,
-				 rdata->connection->priv->last_error_message,
-				 rdata->data);
-	}
-
-	if (rdata->destroy) {
-		rdata->destroy (rdata);
-	}
-}
-
-static void
-rb_daap_connection_finish (RBDAAPConnection *connection)
-{
-	g_return_if_fail (RB_IS_DAAP_CONNECTION (connection));
-
-	rb_debug ("DAAP finish");
-	connection->priv->state = DAAP_DONE;
-	connection->priv->progress = 1.0f;
-
-	connection_operation_done (connection);
-}
-
-void
-rb_daap_connection_disconnect (RBDAAPConnection        *connection,
-			       RBDAAPConnectionCallback callback,
-			       gpointer                 user_data)
-{
-	RBDAAPConnectionPrivate *priv = connection->priv;
-	ConnectionResponseData  *rdata;
-
-	g_return_if_fail (RB_IS_DAAP_CONNECTION (connection));
-
-	rb_debug ("Disconnecting");
-
-	if (connection->priv->is_connecting) {
-		/* this is a special case where the async connection
-		   hasn't returned yet so we need to force the connection
-		   to finish */
-		priv->state = DAAP_DONE;
-		GDK_THREADS_LEAVE ();
-		rb_daap_connection_finish (connection);
-		GDK_THREADS_ENTER ();
-	}
-
-	rdata = g_new (ConnectionResponseData, 1);
-	rdata->connection = g_object_ref (connection);
-	rdata->callback = callback;
-	rdata->data = user_data;
-	rdata->destroy = connection_response_data_free;
-
-	g_signal_connect (connection, "operation-done", G_CALLBACK (disconnected_cb), rdata);
-
-	if (priv->do_something_id != 0) {
-		g_source_remove (priv->do_something_id);
-	}
-
-	if (! connection->priv->is_connected) {
-		priv->state = DAAP_DONE;
-		GDK_THREADS_LEAVE ();
-		rb_daap_connection_finish (connection);
-		GDK_THREADS_ENTER ();
-	} else {
-		priv->state = DAAP_LOGOUT;
-
-		priv->do_something_id = g_idle_add ((GSourceFunc) rb_daap_connection_do_something, connection);
-	}
-}
-
-static void
-rb_daap_connection_state_done (RBDAAPConnection *connection,
-			       gboolean          result)
-{
-	RBDAAPConnectionPrivate *priv = connection->priv;
-
-	rb_debug ("Transitioning to next state from %d", priv->state);
-
-	if (result == FALSE) {
-		priv->state = DAAP_DONE;
-		priv->result = FALSE;
-	} else {
-		switch (priv->state) {
-		case DAAP_GET_PLAYLISTS:
-			if (priv->playlists == NULL)
-				priv->state = DAAP_DONE;
-			else
-				priv->state = DAAP_GET_PLAYLIST_ENTRIES;
-			break;
-		case DAAP_GET_PLAYLIST_ENTRIES:
-			/* keep reading playlists until we've got them all */
-			if (++priv->reading_playlist >= g_slist_length (priv->playlists))
-				priv->state = DAAP_DONE;
-			break;
-
-		case DAAP_LOGOUT:
-			priv->state = DAAP_DONE;
-			break;
-
-		case DAAP_DONE:
-			/* uhh.. */
-			rb_debug ("This should never happen.");
-			break;
-
-		default:
-			/* in most states, we just move on to the next */
-			if (priv->state > DAAP_DONE) {
-				rb_debug ("This should REALLY never happen.");
-				return;
-			}
-			priv->state++;
-			break;
-		}
-
-		priv->progress = 1.0f;
-		if (connection->priv->emit_progress_id != 0) {
-			g_source_remove (connection->priv->emit_progress_id);
-		}
-		connection->priv->emit_progress_id = g_idle_add ((GSourceFunc) emit_progress_idle, connection);
-	}
-
-	if (priv->do_something_id != 0) {
-		g_source_remove (priv->do_something_id);
-	}
-	priv->do_something_id = g_idle_add ((GSourceFunc) rb_daap_connection_do_something, connection);
-}
-
-static gboolean
-rb_daap_connection_do_something (RBDAAPConnection *connection)
-{
-	RBDAAPConnectionPrivate *priv = connection->priv;
-	char *path;
-
-	rb_debug ("Doing something for state: %d", priv->state);
-
-	priv->do_something_id = 0;
-
-	switch (priv->state) {
-	case DAAP_GET_INFO:
-		rb_debug ("Getting DAAP server info");
-		if (! http_get (connection, "/server-info", FALSE, 0.0, 0, FALSE,
-				(RBDAAPResponseHandler) handle_server_info, FALSE)) {
-			rb_debug ("Could not get DAAP connection info");
-			rb_daap_connection_state_done (connection, FALSE);
-		}
-		break;
-
-	case DAAP_GET_PASSWORD:
-		if (priv->password_protected) {
-			/* FIXME this bit is still synchronous */
-			rb_debug ("Need a password for %s", priv->name);
-			g_free (priv->password);
-			priv->password = connection_get_password (connection);
-
-			if (priv->password == NULL || priv->password[0] == '\0') {
-				rb_debug ("Password entry cancelled");
-				priv->result = FALSE;
-				priv->state = DAAP_DONE;
-				rb_daap_connection_do_something (connection);
-				return FALSE;
-			}
-
-			/* If the share went away while we were asking for the password,
-			 * don't bother trying to log in.
-			 */
-			if (priv->state != DAAP_GET_PASSWORD) {
-				return FALSE;
-			}
-		}
-
-		/* otherwise, fall through */
-		priv->state = DAAP_LOGIN;
-
-	case DAAP_LOGIN:
-		rb_debug ("Logging into DAAP server");
-		if (! http_get (connection, "/login", FALSE, 0.0, 0, FALSE,
-			       (RBDAAPResponseHandler) handle_login, FALSE)) {
-			rb_debug ("Could not login to DAAP server");
-			/* FIXME: set state back to GET_PASSWORD to try again */
-			rb_daap_connection_state_done (connection, FALSE);
-		}
-
-		break;
-
-	case DAAP_GET_REVISION_NUMBER:
-		rb_debug ("Getting DAAP server database revision number");
-		path = g_strdup_printf ("/update?session-id=%u&revision-number=1", priv->session_id);
-		if (! http_get (connection, path, TRUE, priv->daap_version, 0, FALSE,
-			       (RBDAAPResponseHandler) handle_update, FALSE)) {
-			rb_debug ("Could not get server database revision number");
-			rb_daap_connection_state_done (connection, FALSE);
-		}
-		g_free (path);
-		break;
-
-	case DAAP_GET_DB_INFO:
-		rb_debug ("Getting DAAP database info");
-		path = g_strdup_printf ("/databases?session-id=%u&revision-number=%d",
-					priv->session_id, priv->revision_number);
-		if (! http_get (connection, path, TRUE, priv->daap_version, 0, FALSE,
-			       (RBDAAPResponseHandler) handle_database_info, FALSE)) {
-			rb_debug ("Could not get DAAP database info");
-			rb_daap_connection_state_done (connection, FALSE);
-		}
-		g_free (path);
-		break;
-
-	case DAAP_GET_SONGS:
-		rb_debug ("Getting DAAP song listing");
-		path = g_strdup_printf ("/databases/%i/items?session-id=%u&revision-number=%i"
-				        "&meta=dmap.itemid,dmap.itemname,daap.songalbum,"
-					"daap.songartist,daap.daap.songgenre,daap.songsize,"
-					"daap.songtime,daap.songtrackcount,daap.songtracknumber,"
-					"daap.songyear,daap.songformat,daap.songgenre,"
-					"daap.songbitrate,daap.songdiscnumber,daap.songdataurl",
-					priv->database_id,
-					priv->session_id,
-					priv->revision_number);
-		if (! http_get (connection, path, TRUE, priv->daap_version, 0, FALSE,
-			       (RBDAAPResponseHandler) handle_song_listing, TRUE)) {
-			rb_debug ("Could not get DAAP song listing");
-			rb_daap_connection_state_done (connection, FALSE);
-		}
-		g_free (path);
-		break;
-
-	case DAAP_GET_PLAYLISTS:
-		rb_debug ("Getting DAAP playlists");
-		path = g_strdup_printf ("/databases/%d/containers?session-id=%u&revision-number=%d",
-					priv->database_id,
-					priv->session_id,
-					priv->revision_number);
-		if (! http_get (connection, path, TRUE, priv->daap_version, 0, FALSE,
-			       (RBDAAPResponseHandler) handle_playlists, TRUE)) {
-			rb_debug ("Could not get DAAP playlists");
-			rb_daap_connection_state_done (connection, FALSE);
-		}
-		g_free (path);
-		break;
-
-	case DAAP_GET_PLAYLIST_ENTRIES:
-		{
-			RBDAAPPlaylist *playlist =
-				(RBDAAPPlaylist *) g_slist_nth_data (priv->playlists,
-								     priv->reading_playlist);
-			g_assert (playlist);
-			rb_debug ("Reading DAAP playlist %d entries", priv->reading_playlist);
-			path = g_strdup_printf ("/databases/%d/containers/%d/items?session-id=%u&revision-number=%d&meta=dmap.itemid",
-						priv->database_id,
-						playlist->id,
-						priv->session_id, priv->revision_number);
-			if (! http_get (connection, path, TRUE, priv->daap_version, 0, FALSE,
-				       (RBDAAPResponseHandler) handle_playlist_entries, TRUE)) {
-				rb_debug ("Could not get entries for DAAP playlist %d",
-					  priv->reading_playlist);
-				rb_daap_connection_state_done (connection, FALSE);
-			}
-			g_free (path);
-		}
-		break;
-
-	case DAAP_LOGOUT:
-		rb_debug ("Logging out of DAAP server");
-		path = g_strdup_printf ("/logout?session-id=%u", priv->session_id);
-		if (! http_get (connection, path, TRUE, priv->daap_version, 0, FALSE,
-			       (RBDAAPResponseHandler) handle_logout, FALSE)) {
-			rb_debug ("Could not log out of DAAP server");
-			rb_daap_connection_state_done (connection, FALSE);
-		}
-
-		g_free (path);
-		break;
-
-	case DAAP_DONE:
-		rb_debug ("DAAP done");
-
-		rb_daap_connection_finish (connection);
-
-		break;
-	}
-
-	return FALSE;
-}
-
-char *
-rb_daap_connection_get_headers (RBDAAPConnection *connection,
-				const gchar *uri,
-				gint64 bytes)
-{
-	RBDAAPConnectionPrivate *priv = connection->priv;
-	GString *headers;
-	char hash[33] = {0};
-	char *norb_daap_uri = (char *)uri;
-	char *s;
-
-	priv->request_id++;
-
-	if (g_ascii_strncasecmp (uri, "daap://", 7) == 0) {
-		norb_daap_uri = strstr (uri, "/data");
-	}
-
-	rb_daap_hash_generate ((short)floorf (priv->daap_version),
-			       (const guchar*)norb_daap_uri, 2,
-			       (guchar*)hash,
-			       priv->request_id);
-
-	headers = g_string_new ("Accept: */*\r\n"
-				"Cache-Control: no-cache\r\n"
-				"User-Agent: " RB_DAAP_USER_AGENT "\r\n"
-				"Accept-Language: en-us, en;q=5.0\r\n"
-				"Client-DAAP-Access-Index: 2\r\n"
-				"Client-DAAP-Version: 3.0\r\n");
-	g_string_append_printf (headers,
-				"Client-DAAP-Validation: %s\r\n"
-				"Client-DAAP-Request-ID: %d\r\n"
-				"Connection: close\r\n",
-				hash, priv->request_id);
-
-	if (priv->password_protected) {
-		char *user_pass;
-		char *token;
-
-		user_pass = g_strdup_printf ("%s:%s", priv->username, priv->password);
-		token = g_base64_encode ((guchar *)user_pass, strlen (user_pass));
-		g_string_append_printf (headers, "Authentication: Basic %s\r\n", token);
-		g_free (token);
-		g_free (user_pass);
-	}
-
-	if (bytes != 0) {
-		g_string_append_printf (headers,"Range: bytes=%"G_GINT64_FORMAT"-\r\n", bytes);
-	}
-
-	s = headers->str;
-	g_string_free (headers, FALSE);
-
-	return s;
-}
-
-GSList *
-rb_daap_connection_get_playlists (RBDAAPConnection *connection)
-{
-	return connection->priv->playlists;
-}
-
-static void
-rb_daap_connection_dispose (GObject *object)
-{
-	RBDAAPConnectionPrivate *priv = RB_DAAP_CONNECTION (object)->priv;
-	GSList *l;
-
-	rb_debug ("DAAP connection dispose");
-
-	if (priv->emit_progress_id != 0) {
-		g_source_remove (priv->emit_progress_id);
-		priv->emit_progress_id = 0;
-	}
-
-	if (priv->do_something_id != 0) {
-		g_source_remove (priv->do_something_id);
-		priv->do_something_id = 0;
-	}
-
-	if (priv->name) {
-		g_free (priv->name);
-		priv->name = NULL;
-	}
-
-	if (priv->username) {
-		g_free (priv->username);
-		priv->username = NULL;
-	}
-
-	if (priv->password) {
-		g_free (priv->password);
-		priv->password = NULL;
-	}
-
-	if (priv->host) {
-		g_free (priv->host);
-		priv->host = NULL;
-	}
-
-	if (priv->playlists) {
-		for (l = priv->playlists; l; l = l->next) {
-			RBDAAPPlaylist *playlist = l->data;
-
-			g_list_foreach (playlist->uris, (GFunc)rb_refstring_unref, NULL);
-			g_list_free (playlist->uris);
-			g_free (playlist->name);
-			g_free (playlist);
-			l->data = NULL;
-		}
-		g_slist_free (priv->playlists);
-		priv->playlists = NULL;
-	}
-
-	if (priv->item_id_to_uri) {
-		g_hash_table_destroy (priv->item_id_to_uri);
-		priv->item_id_to_uri = NULL;
-	}
-
-	if (priv->session) {
-		rb_debug ("Aborting all pending requests");
-		soup_session_abort (priv->session);
-		g_object_unref (G_OBJECT (priv->session));
-		priv->session = NULL;
-	}
-
-	if (priv->base_uri) {
-		soup_uri_free (priv->base_uri);
-		priv->base_uri = NULL;
-	}
-
-	if (priv->daap_base_uri) {
-		g_free (priv->daap_base_uri);
-		priv->daap_base_uri = NULL;
-	}
-
-	if (priv->db) {
-		g_object_unref (G_OBJECT (priv->db));
-		priv->db = NULL;
-	}
-
-	if (priv->last_error_message != NULL) {
-		g_free (priv->last_error_message);
-		priv->last_error_message = NULL;
-	}
-
-	G_OBJECT_CLASS (rb_daap_connection_parent_class)->dispose (object);
-}
-
-static void
-rb_daap_connection_set_property (GObject *object,
-				 guint prop_id,
-				 const GValue *value,
-				 GParamSpec *pspec)
-{
-	RBDAAPConnectionPrivate *priv = RB_DAAP_CONNECTION (object)->priv;
-
-	switch (prop_id) {
-	case PROP_NAME:
-		g_free (priv->name);
-		priv->name = g_value_dup_string (value);
-		break;
-	case PROP_DB:
-		if (priv->db != NULL) {
-			g_object_unref (priv->db);
-		}
-		priv->db = RHYTHMDB (g_value_dup_object (value));
-		break;
-	case PROP_PASSWORD_PROTECTED:
-		priv->password_protected = g_value_get_boolean (value);
-		break;
-	case PROP_ENTRY_TYPE:
-		priv->db_type = g_value_get_boxed (value);
-		break;
-	case PROP_HOST:
-		g_free (priv->host);
-		priv->host = g_value_dup_string (value);
-		break;
-	case PROP_PORT:
-		priv->port = g_value_get_uint (value);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-static void
-rb_daap_connection_get_property (GObject *object,
-				 guint prop_id,
-				 GValue *value,
-				 GParamSpec *pspec)
-{
-	RBDAAPConnectionPrivate *priv = RB_DAAP_CONNECTION (object)->priv;
-
-	switch (prop_id) {
-	case PROP_DB:
-		g_value_set_object (value, priv->db);
-		break;
-	case PROP_NAME:
-		g_value_set_string (value, priv->name);
-		break;
-	case PROP_ENTRY_TYPE:
-		g_value_set_boxed (value, priv->db_type);
-		break;
-	case PROP_PASSWORD_PROTECTED:
-		g_value_set_boolean (value, priv->password_protected);
-		break;
-	case PROP_HOST:
-		g_value_set_string (value, priv->host);
-		break;
-	case PROP_PORT:
-		g_value_set_uint (value, priv->port);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-connection.h rhythmbox-0.12.1/plugins/daap/rb-daap-connection.h
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-connection.h	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-connection.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,120 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- *  Header for DAAP (iTunes Music Sharing) hashing, connection
- *
- *  Copyright (C) 2004-2005 Charles Schmidt <cschmidt2@emich.edu>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The Rhythmbox authors hereby grant permission for non-GPL compatible
- *  GStreamer plugins to be used and distributed together with GStreamer
- *  and Rhythmbox. This permission is above and beyond the permissions granted
- *  by the GPL license by which Rhythmbox is covered. If you modify this code
- *  you may extend this exception to your version of the code, but you are not
- *  obligated to do so. If you do not wish to do so, delete this exception
- *  statement from your version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#ifndef __RB_DAAP_CONNECTION_H
-#define __RB_DAAP_CONNECTION_H
-
-#include <glib.h>
-#include <glib-object.h>
-#include "rhythmdb.h"
-
-G_BEGIN_DECLS
-
-typedef struct {
-	char  *name;
-	int    id;
-	GList *uris;
-} RBDAAPPlaylist;
-
-#define RB_TYPE_DAAP_CONNECTION		(rb_daap_connection_get_type ())
-#define RB_DAAP_CONNECTION(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_DAAP_CONNECTION, RBDAAPConnection))
-#define RB_DAAP_CONNECTION_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_DAAP_CONNECTION, RBDAAPConnectionClass))
-#define RB_IS_DAAP_CONNECTION(o)	(G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_DAAP_CONNECTION))
-#define RB_IS_DAAP_CONNECTION_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_DAAP_CONNECTION))
-#define RB_DAAP_CONNECTION_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_DAAP_CONNECTION, RBDAAPConnectionClass))
-
-typedef struct RBDAAPConnectionPrivate RBDAAPConnectionPrivate;
-
-typedef enum {
-	DAAP_GET_INFO = 0,
-	DAAP_GET_PASSWORD,
-	DAAP_LOGIN,
-	DAAP_GET_REVISION_NUMBER,
-	DAAP_GET_DB_INFO,
-	DAAP_GET_SONGS,
-	DAAP_GET_PLAYLISTS,
-	DAAP_GET_PLAYLIST_ENTRIES,
-	DAAP_LOGOUT,
-	DAAP_DONE
-} RBDAAPConnectionState;
-
-typedef struct {
-	GObject parent;
-	RBDAAPConnectionPrivate *priv;
-} RBDAAPConnection;
-
-typedef struct {
-	GObjectClass parent;
-
-	void   (* connected)      (RBDAAPConnection     *connection);
-	void   (* disconnected)   (RBDAAPConnection     *connection);
-
-	char * (* authenticate)   (RBDAAPConnection     *connection,
-				   const char           *name);
-	void   (* connecting)     (RBDAAPConnection     *connection,
-				   RBDAAPConnectionState state,
-				   float		 progress);
-
-	void   (* operation_done) (RBDAAPConnection     *connection);
-
-} RBDAAPConnectionClass;
-
-/* hmm, maybe should give more error information? */
-typedef gboolean (* RBDAAPConnectionCallback)  (RBDAAPConnection *connection,
-						gboolean          result,
-						const char       *reason,
-						gpointer          user_data);
-
-GType              rb_daap_connection_get_type        (void);
-
-RBDAAPConnection * rb_daap_connection_new             (const char              *name,
-						       const char              *host,
-						       int                      port,
-						       gboolean                 password_protected,
-						       RhythmDB                *db,
-						       RhythmDBEntryType        type);
-
-gboolean           rb_daap_connection_is_connected    (RBDAAPConnection        *connection);
-void               rb_daap_connection_connect         (RBDAAPConnection        *connection,
-						       RBDAAPConnectionCallback callback,
-						       gpointer                 user_data);
-void               rb_daap_connection_disconnect      (RBDAAPConnection        *connection,
-						       RBDAAPConnectionCallback callback,
-						       gpointer                 user_data);
-
-char *             rb_daap_connection_get_headers     (RBDAAPConnection         *connection,
-						       const char               *uri,
-						       gint64                    bytes);
-
-GSList *           rb_daap_connection_get_playlists   (RBDAAPConnection         *connection);
-
-G_END_DECLS
-
-#endif /* __RB_DAAP_CONNECTION_H */
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-hash.c rhythmbox-0.12.1/plugins/daap/rb-daap-hash.c
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-hash.c	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-hash.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,518 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- *  Implementation of DAAP (iTunes Music Sharing) hashing, parsing, connection
- *
- *  Copyright (C) 2004,2005 Charles Schmidt <cschmidt2@emich.edu>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The Rhythmbox authors hereby grant permission for non-GPL compatible
- *  GStreamer plugins to be used and distributed together with GStreamer
- *  and Rhythmbox. This permission is above and beyond the permissions granted
- *  by the GPL license by which Rhythmbox is covered. If you modify this code
- *  you may extend this exception to your version of the code, but you are not
- *  obligated to do so. If you do not wish to do so, delete this exception
- *  statement from your version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <math.h>
-#ifdef HAVE_LIBZ
-#include <zlib.h>
-#endif
-
-#include <glib.h>
-
-#include "rb-daap-hash.h"
-
-/* hashing - based on/copied from libopendaap
- * Copyright (c) 2004 David Hammerton
- */
-
-typedef struct {
-    guint32 buf[4];
-    guint32 bits[2];
-    unsigned char in[64];
-    int version;
-} MD5_CTX;
-
-/*
-* This code implements the MD5 message-digest algorithm.
-* The algorithm is due to Ron Rivest.  This code was
-* written by Colin Plumb in 1993, no copyright is claimed.
-* This code is in the public domain; do with it what you wish.
-*
-* Equivalent code is available from RSA Data Security, Inc.
-* This code has been tested against that, and is equivalent,
-* except that you don't need to include two pages of legalese
-* with every copy.
-*
-* To compute the message digest of a chunk of bytes, declare an MD5Context
-* structure, pass it to OpenDaap_MD5Init, call OpenDaap_MD5Update as needed
-* on buffers full of bytes, and then call OpenDaap_MD5Final, which will fill
-* a supplied 16-byte array with the digest.
-*/
-static void
-MD5Transform (guint32 buf[4],
-	      guint32 const in[16],
-	      gint version);
-/* for some reason we still have to reverse bytes on bigendian machines
- * I don't really know why... but otherwise it fails..
- * Any MD5 gurus out there know why???
- */
-#if 0 //ndef WORDS_BIGENDIAN /* was: HIGHFIRST */
-#define byteReverse(buf, len)     /* Nothing */
-#else
-static void
-byteReverse (unsigned char *buf,
-	     unsigned longs);
-
-#ifndef ASM_MD5
-/*
-* Note: this code is harmless on little-endian machines.
-*/
-static void
-byteReverse (unsigned char *buf,
-	     unsigned longs)
-{
-     guint32 t;
-     do {
-          t = (guint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
-               ((unsigned) buf[1] << 8 | buf[0]);
-          *(guint32 *) buf = t;
-          buf += 4;
-     } while (--longs);
-}
-#endif /* ! ASM_MD5 */
-#endif /* #if 0 */
-
-static void
-OpenDaap_MD5Init (MD5_CTX *ctx,
-		  gint version)
-{
-    memset (ctx, 0, sizeof (MD5_CTX));
-    ctx->buf[0] = 0x67452301;
-    ctx->buf[1] = 0xefcdab89;
-    ctx->buf[2] = 0x98badcfe;
-    ctx->buf[3] = 0x10325476;
-
-    ctx->bits[0] = 0;
-    ctx->bits[1] = 0;
-
-    ctx->version = version;
-}
-
-static void
-OpenDaap_MD5Update (MD5_CTX *ctx,
-		    unsigned char const *buf,
-		    unsigned int len)
-{
-    guint32 t;
-
-    /* Update bitcount */
-
-    t = ctx->bits[0];
-    if ((ctx->bits[0] = t + ((guint32) len << 3)) < t)
-        ctx->bits[1]++;          /* Carry from low to high */
-    ctx->bits[1] += len >> 29;
-
-    t = (t >> 3) & 0x3f;     /* Bytes already in shsInfo->data */
-
-    /* Handle any leading odd-sized chunks */
-
-    if (t) {
-        unsigned char *p = (unsigned char *) ctx->in + t;
-
-        t = 64 - t;
-        if (len < t) {
-            memcpy (p, buf, len);
-            return;
-        }
-        memcpy (p, buf, t);
-        byteReverse (ctx->in, 16);
-        MD5Transform (ctx->buf, (guint32 *) ctx->in, ctx->version);
-        buf += t;
-        len -= t;
-    }
-    /* Process data in 64-byte chunks */
-
-    while (len >= 64) {
-        memcpy (ctx->in, buf, 64);
-        byteReverse (ctx->in, 16);
-        MD5Transform (ctx->buf, (guint32 *) ctx->in, ctx->version);
-        buf += 64;
-        len -= 64;
-    }
-
-    /* Handle any remaining bytes of data. */
-
-    memcpy (ctx->in, buf, len);
-
-}
-
-static void
-OpenDaap_MD5Final (MD5_CTX *ctx,
-		   unsigned char digest[16])
-{
-    unsigned count;
-    unsigned char *p;
-
-    /* Compute number of bytes mod 64 */
-    count = (ctx->bits[0] >> 3) & 0x3F;
-
-    /* Set the first char of padding to 0x80.  This is safe since there is
-    always at least one byte free */
-    p = ctx->in + count;
-    *p++ = 0x80;
-
-    /* Bytes of padding needed to make 64 bytes */
-    count = 64 - 1 - count;
-
-    /* Pad out to 56 mod 64 */
-    if (count < 8) {
-        /* Two lots of padding:  Pad the first block to 64 bytes */
-        memset (p, 0, count);
-        byteReverse (ctx->in, 16);
-        MD5Transform (ctx->buf, (guint32 *) ctx->in, ctx->version);
-
-        /* Now fill the next block with 56 bytes */
-        memset (ctx->in, 0, 56);
-    } else {
-        /* Pad block to 56 bytes */
-        memset (p, 0, count - 8);
-    }
-    byteReverse (ctx->in, 14);
-
-    /* Append length in bits and transform */
-    ((guint32 *) ctx->in)[14] = ctx->bits[0];
-    ((guint32 *) ctx->in)[15] = ctx->bits[1];
-
-    MD5Transform (ctx->buf, (guint32 *) ctx->in, ctx->version);
-    byteReverse ((unsigned char *) ctx->buf, 4);
-    memcpy (digest, ctx->buf, 16);
-    memset (ctx, 0, sizeof(ctx));     /* In case it's sensitive */
-
-    return;
-}
-
-#ifndef ASM_MD5
-
-/* The four core functions - F1 is optimized somewhat */
-
-/* #define F1(x, y, z) (x & y | ~x & z) */
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define MD5STEP(f, w, x, y, z, data, s) \
-( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
-
-/*
-* The core of the MD5 algorithm, this alters an existing MD5 hash to reflect
-* the addition of 16 longwords of new data.  OpenDaap_MD5Update blocks the
-* data and converts bytes into longwords for this routine.
-*/
-static void
-MD5Transform (guint32 buf[4],
-	      guint32 const in[16],
-	      gint version)
-{
-    guint32 a, b, c, d;
-
-    a = buf[0];
-    b = buf[1];
-    c = buf[2];
-    d = buf[3];
-
-    MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
-    MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
-    MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
-    MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
-    MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
-    MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
-    MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
-    MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
-    MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
-    MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
-    MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
-    MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
-    MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
-    MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
-    MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
-    MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
-    MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
-    MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
-    MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
-    MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
-    MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
-    MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
-    MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
-    MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
-    MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
-    MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
-    MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
-
-    if (version == 1)
-    {
-        MD5STEP(F2, b, c, d, a, in[8] + 0x445a14ed, 20);
-    }
-    else
-    {
-        MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
-    }
-    MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
-    MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
-    MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
-    MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
-    MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
-    MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
-    MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
-    MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
-    MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
-    MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
-    MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
-    MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
-    MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
-    MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
-    MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
-    MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
-    MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
-    MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
-    MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
-    MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-
-    MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
-    MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
-    MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
-    MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
-    MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
-    MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
-    MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
-    MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
-    MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
-    MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
-    MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
-    MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
-    MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
-    MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
-    MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
-    MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
-
-    buf[0] += a;
-    buf[1] += b;
-    buf[2] += c;
-    buf[3] += d;
-}
-
-#endif
-
-static int staticHashDone = 0;
-static unsigned char staticHash_42[256*65] = {0};
-static unsigned char staticHash_45[256*65] = {0};
-
-static const char hexchars[] = "0123456789ABCDEF";
-static char ac[] = "Dpqzsjhiu!3114!Bqqmf!Dpnqvufs-!Jod/"; /* +1 */
-static gboolean ac_unfudged = FALSE;
-
-static void
-DigestToString (const unsigned char *digest,
-		char *string)
-{
-    int i;
-    for (i = 0; i < 16; i++)
-    {
-        unsigned char tmp = digest[i];
-        string[i*2+1] = hexchars[tmp & 0x0f];
-        string[i*2] = hexchars[(tmp >> 4) & 0x0f];
-    }
-}
-
-static void
-GenerateStatic_42 ()
-{
-    MD5_CTX ctx;
-    unsigned char *p = staticHash_42;
-    int i;
-    unsigned char buf[16];
-
-    for (i = 0; i < 256; i++)
-    {
-        OpenDaap_MD5Init (&ctx, 0);
-
-#define MD5_STRUPDATE(str) OpenDaap_MD5Update(&ctx, (unsigned char const *)str, strlen(str))
-
-        if ((i & 0x80) != 0)
-            MD5_STRUPDATE("Accept-Language");
-        else
-            MD5_STRUPDATE("user-agent");
-
-        if ((i & 0x40) != 0)
-            MD5_STRUPDATE("max-age");
-        else
-            MD5_STRUPDATE("Authorization");
-
-        if ((i & 0x20) != 0)
-            MD5_STRUPDATE("Client-DAAP-Version");
-        else
-            MD5_STRUPDATE("Accept-Encoding");
-
-        if ((i & 0x10) != 0)
-            MD5_STRUPDATE("daap.protocolversion");
-        else
-            MD5_STRUPDATE("daap.songartist");
-
-        if ((i & 0x08) != 0)
-            MD5_STRUPDATE("daap.songcomposer");
-        else
-            MD5_STRUPDATE("daap.songdatemodified");
-
-        if ((i & 0x04) != 0)
-            MD5_STRUPDATE("daap.songdiscnumber");
-        else
-            MD5_STRUPDATE("daap.songdisabled");
-
-        if ((i & 0x02) != 0)
-            MD5_STRUPDATE("playlist-item-spec");
-        else
-            MD5_STRUPDATE("revision-number");
-
-        if ((i & 0x01) != 0)
-            MD5_STRUPDATE("session-id");
-        else
-            MD5_STRUPDATE("content-codes");
-#undef MD5_STRUPDATE
-
-        OpenDaap_MD5Final (&ctx, buf);
-        DigestToString (buf, (char *)p);
-        p += 65;
-    }
-}
-
-static void GenerateStatic_45()
-{
-    MD5_CTX ctx;
-    unsigned char *p = staticHash_45;
-    int i;
-    unsigned char buf[16];
-
-    for (i = 0; i < 256; i++)
-    {
-        OpenDaap_MD5Init (&ctx, 1);
-
-#define MD5_STRUPDATE(str) OpenDaap_MD5Update(&ctx, (unsigned char const *)str, strlen(str))
-
-        if ((i & 0x40) != 0)
-            MD5_STRUPDATE("eqwsdxcqwesdc");
-        else
-            MD5_STRUPDATE("op[;lm,piojkmn");
-
-        if ((i & 0x20) != 0)
-            MD5_STRUPDATE("876trfvb 34rtgbvc");
-        else
-            MD5_STRUPDATE("=-0ol.,m3ewrdfv");
-
-        if ((i & 0x10) != 0)
-            MD5_STRUPDATE("87654323e4rgbv ");
-        else
-            MD5_STRUPDATE("1535753690868867974342659792");
-
-        if ((i & 0x08) != 0)
-            MD5_STRUPDATE("Song Name");
-        else
-            MD5_STRUPDATE("DAAP-CLIENT-ID:");
-
-        if ((i & 0x04) != 0)
-            MD5_STRUPDATE("111222333444555");
-        else
-            MD5_STRUPDATE("4089961010");
-
-        if ((i & 0x02) != 0)
-            MD5_STRUPDATE("playlist-item-spec");
-        else
-            MD5_STRUPDATE("revision-number");
-
-        if ((i & 0x01) != 0)
-            MD5_STRUPDATE("session-id");
-        else
-            MD5_STRUPDATE("content-codes");
-
-        if ((i & 0x80) != 0)
-            MD5_STRUPDATE("IUYHGFDCXWEDFGHN");
-        else
-            MD5_STRUPDATE("iuytgfdxwerfghjm");
-
-#undef MD5_STRUPDATE
-
-        OpenDaap_MD5Final (&ctx, buf);
-        DigestToString (buf, (char *)p);
-        p += 65;
-    }
-}
-
-void
-rb_daap_hash_generate (short         version_major,
-		       const guchar *url,
-		       guchar        hash_select,
-		       guchar       *out,
-		       gint          request_id)
-{
-    unsigned char buf[16];
-    MD5_CTX ctx;
-    int i;
-
-    unsigned char *hashTable = (version_major == 3) ?
-                      staticHash_45 : staticHash_42;
-
-    if (!staticHashDone)
-    {
-        GenerateStatic_42 ();
-        GenerateStatic_45 ();
-        staticHashDone = 1;
-    }
-
-    OpenDaap_MD5Init (&ctx, (version_major == 3) ? 1 : 0);
-
-    OpenDaap_MD5Update (&ctx, url, strlen ((const gchar*)url));
-    if (ac_unfudged == FALSE) {
-	    for (i = 0; i < strlen (ac); i++) {
-		ac[i] = ac[i]-1;
-	    }
-    	    ac_unfudged = TRUE;
-    }
-    OpenDaap_MD5Update (&ctx, (const guchar*)ac, strlen (ac));
-
-    OpenDaap_MD5Update (&ctx, &hashTable[hash_select * 65], 32);
-
-    if (request_id && version_major == 3)
-    {
-        char scribble[20];
-        sprintf (scribble, "%u", request_id);
-        OpenDaap_MD5Update (&ctx, (const guchar*)scribble, strlen (scribble));
-    }
-
-    OpenDaap_MD5Final (&ctx, buf);
-    DigestToString (buf, (char *)out);
-
-    return;
-}
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-hash.h rhythmbox-0.12.1/plugins/daap/rb-daap-hash.h
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-hash.h	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-hash.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,46 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- *  Header for DAAP (iTunes Music Sharing) hashing, connection
- *
- *  Copyright (C) 2004-2005 Charles Schmidt <cschmidt2@emich.edu>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The Rhythmbox authors hereby grant permission for non-GPL compatible
- *  GStreamer plugins to be used and distributed together with GStreamer
- *  and Rhythmbox. This permission is above and beyond the permissions granted
- *  by the GPL license by which Rhythmbox is covered. If you modify this code
- *  you may extend this exception to your version of the code, but you are not
- *  obligated to do so. If you do not wish to do so, delete this exception
- *  statement from your version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#ifndef __RB_DAAP_HASH_H
-#define __RB_DAAP_HASH_H
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-void rb_daap_hash_generate (short         version_major,
-			    const guchar *url,
-			    guchar        hash_select,
-			    guchar       *out,
-			    gint          request_id);
-
-G_END_DECLS
-
-#endif /* __RB_DAAP_HASH_H */
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-mdns-avahi.c rhythmbox-0.12.1/plugins/daap/rb-daap-mdns-avahi.c
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-mdns-avahi.c	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-mdns-avahi.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,122 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- *  Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The Rhythmbox authors hereby grant permission for non-GPL compatible
- * GStreamer plugins to be used and distributed together with GStreamer
- * and Rhythmbox. This permission is above and beyond the permissions granted
- * by the GPL license by which Rhythmbox is covered. If you modify this code
- * you may extend this exception to your version of the code, but you are not
- * obligated to do so. If you do not wish to do so, delete this exception
- * statement from your version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#include "config.h"
-
-#include <glib.h>
-#include <avahi-glib/glib-malloc.h>
-#include <avahi-glib/glib-watch.h>
-#include <avahi-common/error.h>
-
-#include "rb-daap-mdns-avahi.h"
-
-static AvahiClient *client = NULL;
-static AvahiEntryGroup *entry_group = NULL;
-static gsize client_init = 0;
-
-static void
-client_cb (AvahiClient         *client,
-	   AvahiClientState     state,
-	   gpointer             data)
-{
-	/* FIXME
-	 * check to make sure we're in the _RUNNING state before we publish
-	 * check for COLLISION state and remove published information
-	 */
-
-	/* Called whenever the client or server state changes */
-
-	switch (state) {
-	case AVAHI_CLIENT_S_RUNNING:
-		/* The server has startup successfully and registered its host
-		 * name on the network, so it's time to create our services
-		 */
-
-		break;
-
-	case AVAHI_CLIENT_S_COLLISION:
-
-		 /* Let's drop our registered services. When the server is back
-		  * in AVAHI_SERVER_RUNNING state we will register them
-		  * again with the new host name.
-		  */
-		 if (entry_group) {
-			 avahi_entry_group_reset (entry_group);
-		 }
-		 break;
-
-	case AVAHI_CLIENT_FAILURE:
-		 g_warning ("Client failure: %s\n", avahi_strerror (avahi_client_errno (client)));
-		 break;
-
-	case AVAHI_CLIENT_CONNECTING:
-	case AVAHI_CLIENT_S_REGISTERING:
-	default:
-		break;
-	}
-}
-
-AvahiClient *
-rb_daap_mdns_avahi_get_client (void)
-{
-	if (g_once_init_enter (&client_init)) {
-		AvahiClientFlags flags = 0;
-		AvahiGLibPoll *apoll;
-		int error = 0;
-
-		avahi_set_allocator (avahi_glib_allocator ());
-
-		apoll = avahi_glib_poll_new (NULL, G_PRIORITY_DEFAULT);
-		if (apoll == NULL) {
-			g_warning ("Unable to create AvahiGlibPoll object for mDNS");
-		}
-
-		client = avahi_client_new (avahi_glib_poll_get (apoll),
-					   flags,
-					   (AvahiClientCallback) client_cb,
-					   NULL,
-					   &error);
-		if (error != 0) {
-			g_warning ("Unable to initialize mDNS: %s", avahi_strerror (error));
-		}
-
-		g_once_init_leave (&client_init, 1);
-	}
-
-	return client;
-}
-
-void
-rb_daap_mdns_avahi_set_entry_group (AvahiEntryGroup *eg)
-{
-	if (eg != NULL) {
-		g_assert (entry_group == NULL);
-		g_assert (avahi_entry_group_get_client (eg) == client);
-	}
-	entry_group = eg;
-}
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-mdns-avahi.h rhythmbox-0.12.1/plugins/daap/rb-daap-mdns-avahi.h
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-mdns-avahi.h	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-mdns-avahi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,40 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- *  Copyright (C) 2008 Jonathan Matthew  <jonathan@d14n.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The Rhythmbox authors hereby grant permission for non-GPL compatible
- *  GStreamer plugins to be used and distributed together with GStreamer
- *  and Rhythmbox. This permission is above and beyond the permissions granted
- *  by the GPL license by which Rhythmbox is covered. If you modify this code
- *  you may extend this exception to your version of the code, but you are not
- *  obligated to do so. If you do not wish to do so, delete this exception
- *  statement from your version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#ifndef __RB_DAAP_MDNS_AVAHI_H
-#define __RB_DAAP_MDNS_AVAHI_H
-
-#include <avahi-client/client.h>
-#include <avahi-client/publish.h>
-
-AvahiClient *	rb_daap_mdns_avahi_get_client (void);
-
-void		rb_daap_mdns_avahi_set_entry_group (AvahiEntryGroup *group);
-
-#endif
-
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-mdns-browser-avahi.c rhythmbox-0.12.1/plugins/daap/rb-daap-mdns-browser-avahi.c
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-mdns-browser-avahi.c	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-mdns-browser-avahi.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,405 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- *  Copyright (C) 2005 Charles Schmidt <cschmidt2@emich.edu>
- *  Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The Rhythmbox authors hereby grant permission for non-GPL compatible
- * GStreamer plugins to be used and distributed together with GStreamer
- * and Rhythmbox. This permission is above and beyond the permissions granted
- * by the GPL license by which Rhythmbox is covered. If you modify this code
- * you may extend this exception to your version of the code, but you are not
- * obligated to do so. If you do not wish to do so, delete this exception
- * statement from your version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <glib-object.h>
-
-#include <avahi-client/lookup.h>
-#include <avahi-client/publish.h>
-#include <avahi-client/client.h>
-#include <avahi-common/error.h>
-#include <avahi-glib/glib-malloc.h>
-#include <avahi-glib/glib-watch.h>
-
-#include "rb-daap-mdns-avahi.h"
-#include "rb-daap-mdns-browser.h"
-#include "rb-marshal.h"
-#include "rb-debug.h"
-
-static void	rb_daap_mdns_browser_class_init (RBDaapMdnsBrowserClass *klass);
-static void	rb_daap_mdns_browser_init	(RBDaapMdnsBrowser	*browser);
-static void	rb_daap_mdns_browser_finalize   (GObject	        *object);
-
-#define RB_DAAP_MDNS_BROWSER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_DAAP_MDNS_BROWSER, RBDaapMdnsBrowserPrivate))
-
-struct RBDaapMdnsBrowserPrivate
-{
-	AvahiClient         *client;
-	AvahiServiceBrowser *service_browser;
-
-	GSList              *resolvers;
-};
-
-enum {
-	SERVICE_ADDED,
-	SERVICE_REMOVED,
-	LAST_SIGNAL
-};
-
-enum {
-	PROP_0
-};
-
-static GObjectClass *parent_class = NULL;
-static guint	     signals [LAST_SIGNAL] = { 0, };
-
-G_DEFINE_TYPE (RBDaapMdnsBrowser, rb_daap_mdns_browser, G_TYPE_OBJECT)
-
-static gpointer browser_object = NULL;
-
-GQuark
-rb_daap_mdns_browser_error_quark (void)
-{
-	static GQuark quark = 0;
-	if (!quark)
-		quark = g_quark_from_static_string ("rb_daap_mdns_browser_error");
-
-	return quark;
-}
-
-static void
-resolve_cb (AvahiServiceResolver  *service_resolver,
-	    AvahiIfIndex           interface,
-	    AvahiProtocol          protocol,
-	    AvahiResolverEvent     event,
-	    const char            *service_name,
-	    const char            *type,
-	    const char            *domain,
-	    const char            *host_name,
-	    const AvahiAddress    *address,
-	    uint16_t               port,
-	    AvahiStringList       *text,
-	    AvahiLookupResultFlags flags,
-	    RBDaapMdnsBrowser     *browser)
-{
-	if (event == AVAHI_RESOLVER_FOUND) {
-		char    *name = NULL;
-		char     host [AVAHI_ADDRESS_STR_MAX];
-		gboolean pp = FALSE;
-
-		if (text) {
-			AvahiStringList *l;
-
-			for (l = text; l != NULL; l = l->next) {
-				size_t size;
-				char  *key;
-				char  *value;
-				int    ret;
-
-				ret = avahi_string_list_get_pair (l, &key, &value, &size);
-				if (ret != 0 || key == NULL) {
-					continue;
-				}
-
-				if (strcmp (key, "Password") == 0) {
-					if (size >= 4 && strncmp (value, "true", 4) == 0) {
-						pp = TRUE;
-					}
-				} else if (strcmp (key, "Machine Name") == 0) {
-					name = g_strdup (value);
-				}
-
-				g_free (key);
-				g_free (value);
-			}
-		}
-
-		if (name == NULL) {
-			name = g_strdup (service_name);
-		}
-
-		avahi_address_snprint (host, AVAHI_ADDRESS_STR_MAX, address);
-
-		g_signal_emit (browser,
-			       signals [SERVICE_ADDED],
-			       0,
-			       service_name,
-			       name,
-			       host,
-			       port,
-			       pp);
-
-		g_free (name);
-	}
-
-	browser->priv->resolvers = g_slist_remove (browser->priv->resolvers, service_resolver);
-	avahi_service_resolver_free (service_resolver);
-}
-
-static gboolean
-rb_daap_mdns_browser_resolve (RBDaapMdnsBrowser *browser,
-			      const char        *name)
-{
-	AvahiServiceResolver *service_resolver;
-
-	service_resolver = avahi_service_resolver_new (browser->priv->client,
-						       AVAHI_IF_UNSPEC,
-						       AVAHI_PROTO_INET,
-						       name,
-						       "_daap._tcp",
-						       NULL,
-						       AVAHI_PROTO_UNSPEC,
-						       0,
-						       (AvahiServiceResolverCallback)resolve_cb,
-						       browser);
-	if (service_resolver == NULL) {
-		rb_debug ("Error starting mDNS resolving using AvahiServiceResolver");
-		return FALSE;
-	}
-
-	browser->priv->resolvers = g_slist_prepend (browser->priv->resolvers, service_resolver);
-
-	return TRUE;
-}
-
-static void
-browser_add_service (RBDaapMdnsBrowser *browser,
-		     const char        *service_name)
-{
-	rb_daap_mdns_browser_resolve (browser, service_name);
-}
-
-static void
-browser_remove_service (RBDaapMdnsBrowser *browser,
-			const char        *service_name)
-{
-	g_signal_emit (browser, signals [SERVICE_REMOVED], 0, service_name);
-}
-
-static void
-browse_cb (AvahiServiceBrowser   *service_browser,
-	   AvahiIfIndex           interface,
-	   AvahiProtocol          protocol,
-	   AvahiBrowserEvent      event,
-	   const char            *name,
-	   const char            *type,
-	   const char            *domain,
-	   AvahiLookupResultFlags flags,
-	   RBDaapMdnsBrowser     *browser)
-{
-	gboolean local;
-
-	local = ((flags & AVAHI_LOOKUP_RESULT_OUR_OWN) != 0);
-	if (local) {
-		rb_debug ("Ignoring local service %s", name);
-		return;
-	}
-
-	if (event == AVAHI_BROWSER_NEW) {
-		browser_add_service (browser, name);
-	} else if (event == AVAHI_BROWSER_REMOVE) {
-		browser_remove_service (browser, name);
-	}
-}
-
-gboolean
-rb_daap_mdns_browser_start (RBDaapMdnsBrowser *browser,
-			    GError           **error)
-{
-	if (browser->priv->client == NULL) {
-		g_set_error (error,
-			     RB_DAAP_MDNS_BROWSER_ERROR,
-			     RB_DAAP_MDNS_BROWSER_ERROR_NOT_RUNNING,
-			     "%s",
-			     _("mDNS service is not running"));
-		return FALSE;
-	}
-	if (browser->priv->service_browser != NULL) {
-		g_set_error (error,
-			     RB_DAAP_MDNS_BROWSER_ERROR,
-			     RB_DAAP_MDNS_BROWSER_ERROR_FAILED,
-			     "%s",
-			     _("Browser already active"));
-		return FALSE;
-	}
-
-	browser->priv->service_browser = avahi_service_browser_new (browser->priv->client,
-								    AVAHI_IF_UNSPEC,
-								    AVAHI_PROTO_UNSPEC,
-								    "_daap._tcp",
-								    NULL,
-								    0,
-								    (AvahiServiceBrowserCallback)browse_cb,
-								    browser);
-	if (browser->priv->service_browser == NULL) {
-		rb_debug ("Error starting mDNS discovery using AvahiServiceBrowser");
-		g_set_error (error,
-			     RB_DAAP_MDNS_BROWSER_ERROR,
-			     RB_DAAP_MDNS_BROWSER_ERROR_FAILED,
-			     "%s",
-			     _("Unable to activate browser"));
-
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-gboolean
-rb_daap_mdns_browser_stop (RBDaapMdnsBrowser *browser,
-			   GError           **error)
-{
-	if (browser->priv->client == NULL) {
-		g_set_error (error,
-			     RB_DAAP_MDNS_BROWSER_ERROR,
-			     RB_DAAP_MDNS_BROWSER_ERROR_NOT_RUNNING,
-			     "%s",
-			     _("mDNS service is not running"));
-		return FALSE;
-	}
-	if (browser->priv->service_browser == NULL) {
-		g_set_error (error,
-			     RB_DAAP_MDNS_BROWSER_ERROR,
-			     RB_DAAP_MDNS_BROWSER_ERROR_FAILED,
-			     "%s",
-			     _("Browser is not active"));
-		return FALSE;
-
-	}
-	avahi_service_browser_free (browser->priv->service_browser);
-	browser->priv->service_browser = NULL;
-
-	return TRUE;
-}
-
-static void
-rb_daap_mdns_browser_set_property (GObject      *object,
-				   guint	 prop_id,
-				   const GValue *value,
-				   GParamSpec   *pspec)
-{
-	switch (prop_id) {
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-static void
-rb_daap_mdns_browser_get_property (GObject	 *object,
-				   guint	  prop_id,
-				   GValue	 *value,
-				   GParamSpec	 *pspec)
-{
-	switch (prop_id) {
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-static void
-rb_daap_mdns_browser_class_init (RBDaapMdnsBrowserClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-	parent_class = g_type_class_peek_parent (klass);
-
-	object_class->finalize	   = rb_daap_mdns_browser_finalize;
-	object_class->get_property = rb_daap_mdns_browser_get_property;
-	object_class->set_property = rb_daap_mdns_browser_set_property;
-
-	signals [SERVICE_ADDED] =
-		g_signal_new ("service-added",
-			      G_TYPE_FROM_CLASS (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (RBDaapMdnsBrowserClass, service_added),
-			      NULL,
-			      NULL,
-			      rb_marshal_VOID__STRING_STRING_STRING_UINT_BOOLEAN,
-			      G_TYPE_NONE,
-			      5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_BOOLEAN);
-	signals [SERVICE_REMOVED] =
-		g_signal_new ("service-removed",
-			      G_TYPE_FROM_CLASS (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (RBDaapMdnsBrowserClass, service_removed),
-			      NULL,
-			      NULL,
-			      g_cclosure_marshal_VOID__STRING,
-			      G_TYPE_NONE,
-			      1, G_TYPE_STRING);
-
-	g_type_class_add_private (klass, sizeof (RBDaapMdnsBrowserPrivate));
-}
-
-static void
-rb_daap_mdns_browser_init (RBDaapMdnsBrowser *browser)
-{
-	browser->priv = RB_DAAP_MDNS_BROWSER_GET_PRIVATE (browser);
-
-	browser->priv->client = rb_daap_mdns_avahi_get_client ();
-}
-
-static void
-rb_daap_mdns_browser_finalize (GObject *object)
-{
-	RBDaapMdnsBrowser *browser;
-
-	g_return_if_fail (object != NULL);
-	g_return_if_fail (RB_IS_DAAP_MDNS_BROWSER (object));
-
-	browser = RB_DAAP_MDNS_BROWSER (object);
-
-	g_return_if_fail (browser->priv != NULL);
-
-	if (browser->priv->resolvers) {
-		g_slist_foreach (browser->priv->resolvers,
-				 (GFunc)avahi_service_resolver_free,
-				 NULL);
-		g_slist_free (browser->priv->resolvers);
-	}
-
-	if (browser->priv->service_browser) {
-		avahi_service_browser_free (browser->priv->service_browser);
-	}
-
-	G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-RBDaapMdnsBrowser *
-rb_daap_mdns_browser_new (void)
-{
-	if (browser_object) {
-		g_object_ref (browser_object);
-	} else {
-		browser_object = g_object_new (RB_TYPE_DAAP_MDNS_BROWSER, NULL);
-		g_object_add_weak_pointer (browser_object,
-					   (gpointer *) &browser_object);
-	}
-
-	return RB_DAAP_MDNS_BROWSER (browser_object);
-}
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-mdns-browser.h rhythmbox-0.12.1/plugins/daap/rb-daap-mdns-browser.h
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-mdns-browser.h	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-mdns-browser.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,91 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- *  Header for abstraction of Multicast DNS for DAAP sharing
- *
- *  Copyright (C) 2005 Charles Schmidt <cschmidt2@emich.edu>
- *  Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The Rhythmbox authors hereby grant permission for non-GPL compatible
- *  GStreamer plugins to be used and distributed together with GStreamer
- *  and Rhythmbox. This permission is above and beyond the permissions granted
- *  by the GPL license by which Rhythmbox is covered. If you modify this code
- *  you may extend this exception to your version of the code, but you are not
- *  obligated to do so. If you do not wish to do so, delete this exception
- *  statement from your version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#ifndef __RB_DAAP_MDNS_BROWSER_H
-#define __RB_DAAP_MDNS_BROWSER_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define RB_TYPE_DAAP_MDNS_BROWSER         (rb_daap_mdns_browser_get_type ())
-#define RB_DAAP_MDNS_BROWSER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_DAAP_MDNS_BROWSER, RBDaapMdnsBrowser))
-#define RB_DAAP_MDNS_BROWSER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_DAAP_MDNS_BROWSER, RBDaapMdnsBrowserClass))
-#define RB_IS_DAAP_MDNS_BROWSER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_DAAP_MDNS_BROWSER))
-#define RB_IS_DAAP_MDNS_BROWSER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_DAAP_MDNS_BROWSER))
-#define RB_DAAP_MDNS_BROWSER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_DAAP_MDNS_BROWSER, RBDaapMdnsBrowserClass))
-
-typedef struct RBDaapMdnsBrowserPrivate RBDaapMdnsBrowserPrivate;
-
-typedef struct
-{
-	GObject object;
-
-	RBDaapMdnsBrowserPrivate *priv;
-} RBDaapMdnsBrowser;
-
-typedef struct
-{
-	GObjectClass parent_class;
-
-	void (* service_added)    (RBDaapMdnsBrowser *browser,
-				   const char        *service_name,
-				   const char        *name,
-				   const char        *host,
-				   guint              port,
-				   gboolean           password_protected);
-	void (* service_removed ) (RBDaapMdnsBrowser *browser,
-				   const char        *service_name);
-
-} RBDaapMdnsBrowserClass;
-
-typedef enum
-{
-	RB_DAAP_MDNS_BROWSER_ERROR_NOT_RUNNING,
-	RB_DAAP_MDNS_BROWSER_ERROR_FAILED,
-} RBDaapMdnsBrowserError;
-
-#define RB_DAAP_MDNS_BROWSER_ERROR rb_daap_mdns_browser_error_quark ()
-
-GQuark             rb_daap_mdns_browser_error_quark (void);
-
-GType              rb_daap_mdns_browser_get_type    (void);
-
-RBDaapMdnsBrowser *rb_daap_mdns_browser_new         (void);
-gboolean           rb_daap_mdns_browser_start       (RBDaapMdnsBrowser *browser,
-						     GError           **error);
-gboolean           rb_daap_mdns_browser_stop        (RBDaapMdnsBrowser *browser,
-						     GError           **error);
-
-G_END_DECLS
-
-#endif /* __RB_DAAP_MDNS_BROWSER_H */
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-mdns-publisher-avahi.c rhythmbox-0.12.1/plugins/daap/rb-daap-mdns-publisher-avahi.c
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-mdns-publisher-avahi.c	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-mdns-publisher-avahi.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,423 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- *  Copyright (C) 2005 Charles Schmidt <cschmidt2@emich.edu>
- *  Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The Rhythmbox authors hereby grant permission for non-GPL compatible
- * GStreamer plugins to be used and distributed together with GStreamer
- * and Rhythmbox. This permission is above and beyond the permissions granted
- * by the GPL license by which Rhythmbox is covered. If you modify this code
- * you may extend this exception to your version of the code, but you are not
- * obligated to do so. If you do not wish to do so, delete this exception
- * statement from your version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <glib-object.h>
-
-#include <avahi-client/lookup.h>
-#include <avahi-client/publish.h>
-#include <avahi-client/client.h>
-#include <avahi-common/error.h>
-#include <avahi-glib/glib-malloc.h>
-#include <avahi-glib/glib-watch.h>
-
-#include "rb-daap-mdns-avahi.h"
-#include "rb-daap-mdns-publisher.h"
-#include "rb-debug.h"
-
-static void	rb_daap_mdns_publisher_class_init (RBDaapMdnsPublisherClass *klass);
-static void	rb_daap_mdns_publisher_init	  (RBDaapMdnsPublisher	    *publisher);
-static void	rb_daap_mdns_publisher_finalize   (GObject	            *object);
-
-#define RB_DAAP_MDNS_PUBLISHER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_DAAP_MDNS_PUBLISHER, RBDaapMdnsPublisherPrivate))
-
-struct RBDaapMdnsPublisherPrivate
-{
-	AvahiClient     *client;
-	AvahiEntryGroup *entry_group;
-
-	char            *name;
-	guint            port;
-	gboolean         password_required;
-};
-
-enum {
-	PUBLISHED,
-	NAME_COLLISION,
-	LAST_SIGNAL
-};
-
-enum {
-	PROP_0
-};
-
-static guint	     signals [LAST_SIGNAL] = { 0, };
-
-G_DEFINE_TYPE (RBDaapMdnsPublisher, rb_daap_mdns_publisher, G_TYPE_OBJECT)
-
-static gpointer publisher_object = NULL;
-
-GQuark
-rb_daap_mdns_publisher_error_quark (void)
-{
-	static GQuark quark = 0;
-	if (!quark)
-		quark = g_quark_from_static_string ("rb_daap_mdns_publisher_error");
-
-	return quark;
-}
-
-static void
-entry_group_cb (AvahiEntryGroup     *group,
-		AvahiEntryGroupState state,
-		RBDaapMdnsPublisher *publisher)
-{
-	if (state == AVAHI_ENTRY_GROUP_ESTABLISHED) {
-
-		g_signal_emit (publisher, signals [PUBLISHED], 0, publisher->priv->name);
-
-	} else if (state == AVAHI_ENTRY_GROUP_COLLISION) {
-		g_warning ("MDNS name collision");
-
-		g_signal_emit (publisher, signals [NAME_COLLISION], 0, publisher->priv->name);
-	}
-}
-
-static gboolean
-create_service (RBDaapMdnsPublisher *publisher,
-		GError             **error)
-{
-	int         ret;
-	const char *txt_record;
-
-	if (publisher->priv->entry_group == NULL) {
-		publisher->priv->entry_group = avahi_entry_group_new (publisher->priv->client,
-								      (AvahiEntryGroupCallback)entry_group_cb,
-								      publisher);
-		rb_daap_mdns_avahi_set_entry_group (publisher->priv->entry_group);
-	} else {
-		avahi_entry_group_reset (publisher->priv->entry_group);
-	}
-
-	if (publisher->priv->entry_group == NULL) {
-		rb_debug ("Could not create AvahiEntryGroup for publishing");
-		g_set_error (error,
-			     RB_DAAP_MDNS_PUBLISHER_ERROR,
-			     RB_DAAP_MDNS_PUBLISHER_ERROR_FAILED,
-			     "%s",
-			     _("Could not create AvahiEntryGroup for publishing"));
-		return FALSE;
-	}
-
-#if 0
-	g_message ("Service name:%s port:%u password:%d",
-		   publisher->priv->name,
-		   publisher->priv->port,
-		   publisher->priv->password_required);
-#endif
-
-	if (publisher->priv->password_required) {
-		txt_record = "Password=true";
-	} else {
-		txt_record = "Password=false";
-	}
-
-	ret = avahi_entry_group_add_service (publisher->priv->entry_group,
-					     AVAHI_IF_UNSPEC,
-					     AVAHI_PROTO_UNSPEC,
-					     0,
-					     publisher->priv->name,
-					     "_daap._tcp",
-					     NULL,
-					     NULL,
-					     publisher->priv->port,
-					     txt_record,
-					     NULL);
-
-	if (ret < 0) {
-		g_set_error (error,
-			     RB_DAAP_MDNS_PUBLISHER_ERROR,
-			     RB_DAAP_MDNS_PUBLISHER_ERROR_FAILED,
-			     "%s: %s",
-			     _("Could not add service"),
-			     avahi_strerror (ret));
-		return FALSE;
-	}
-
-	ret = avahi_entry_group_commit (publisher->priv->entry_group);
-
-	if (ret < 0) {
-		g_set_error (error,
-			     RB_DAAP_MDNS_PUBLISHER_ERROR,
-			     RB_DAAP_MDNS_PUBLISHER_ERROR_FAILED,
-			     "%s: %s",
-			     _("Could not commit service"),
-			     avahi_strerror (ret));
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-static gboolean
-refresh_service (RBDaapMdnsPublisher *publisher,
-		 GError             **error)
-{
-	return create_service (publisher, error);
-}
-
-static gboolean
-publisher_set_name_internal (RBDaapMdnsPublisher *publisher,
-			     const char          *name,
-			     GError             **error)
-{
-	g_free (publisher->priv->name);
-	publisher->priv->name = g_strdup (name);
-
-	return TRUE;
-}
-
-gboolean
-rb_daap_mdns_publisher_set_name (RBDaapMdnsPublisher *publisher,
-				 const char          *name,
-				 GError             **error)
-{
-        g_return_val_if_fail (publisher != NULL, FALSE);
-
-	publisher_set_name_internal (publisher, name, error);
-
-	if (publisher->priv->entry_group) {
-		refresh_service (publisher, error);
-	}
-
-	return TRUE;
-}
-
-static gboolean
-publisher_set_port_internal (RBDaapMdnsPublisher *publisher,
-			     guint                port,
-			     GError             **error)
-{
-	publisher->priv->port = port;
-
-	return TRUE;
-}
-
-gboolean
-rb_daap_mdns_publisher_set_port (RBDaapMdnsPublisher *publisher,
-				 guint                port,
-				 GError             **error)
-{
-        g_return_val_if_fail (publisher != NULL, FALSE);
-
-	publisher_set_port_internal (publisher, port, error);
-
-	if (publisher->priv->entry_group) {
-		refresh_service (publisher, error);
-	}
-
-	return TRUE;
-}
-
-static gboolean
-publisher_set_password_required_internal (RBDaapMdnsPublisher *publisher,
-					  gboolean             required,
-					  GError             **error)
-{
-	publisher->priv->password_required = required;
-	return TRUE;
-}
-
-gboolean
-rb_daap_mdns_publisher_set_password_required (RBDaapMdnsPublisher *publisher,
-					      gboolean             required,
-					      GError             **error)
-{
-        g_return_val_if_fail (publisher != NULL, FALSE);
-
-	publisher_set_password_required_internal (publisher, required, error);
-
-	if (publisher->priv->entry_group) {
-		refresh_service (publisher, error);
-	}
-
-	return TRUE;
-}
-
-gboolean
-rb_daap_mdns_publisher_publish (RBDaapMdnsPublisher *publisher,
-				const char          *name,
-				guint                port,
-				gboolean             password_required,
-				GError             **error)
-{
-	if (publisher->priv->client == NULL) {
-                g_set_error (error,
-			     RB_DAAP_MDNS_PUBLISHER_ERROR,
-			     RB_DAAP_MDNS_PUBLISHER_ERROR_NOT_RUNNING,
-                             "%s",
-                             _("The avahi mDNS service is not running"));
-		return FALSE;
-	}
-
-	publisher_set_name_internal (publisher, name, NULL);
-	publisher_set_port_internal (publisher, port, NULL);
-	publisher_set_password_required_internal (publisher, password_required, NULL);
-
-	return create_service (publisher, error);
-}
-
-gboolean
-rb_daap_mdns_publisher_withdraw (RBDaapMdnsPublisher *publisher,
-				 GError             **error)
-{
-	if (publisher->priv->client == NULL) {
-                g_set_error (error,
-			     RB_DAAP_MDNS_PUBLISHER_ERROR,
-			     RB_DAAP_MDNS_PUBLISHER_ERROR_NOT_RUNNING,
-                             "%s",
-                             _("The avahi mDNS service is not running"));
-		return FALSE;
-	}
-
-	if (publisher->priv->entry_group == NULL) {
-                g_set_error (error,
-			     RB_DAAP_MDNS_PUBLISHER_ERROR,
-			     RB_DAAP_MDNS_PUBLISHER_ERROR_FAILED,
-                             "%s",
-                             _("The mDNS service is not published"));
-		return FALSE;
-	}
-
-	avahi_entry_group_reset (publisher->priv->entry_group);
-	avahi_entry_group_free (publisher->priv->entry_group);
-	publisher->priv->entry_group = NULL;
-	rb_daap_mdns_avahi_set_entry_group (NULL);
-
-	return TRUE;
-}
-
-static void
-rb_daap_mdns_publisher_set_property (GObject	  *object,
-				     guint	   prop_id,
-				     const GValue *value,
-				     GParamSpec	  *pspec)
-{
-	switch (prop_id) {
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-static void
-rb_daap_mdns_publisher_get_property (GObject	 *object,
-				     guint	  prop_id,
-				     GValue	 *value,
-				     GParamSpec	 *pspec)
-{
-	switch (prop_id) {
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-static void
-rb_daap_mdns_publisher_class_init (RBDaapMdnsPublisherClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-	object_class->finalize	   = rb_daap_mdns_publisher_finalize;
-	object_class->get_property = rb_daap_mdns_publisher_get_property;
-	object_class->set_property = rb_daap_mdns_publisher_set_property;
-
-	signals [PUBLISHED] =
-		g_signal_new ("published",
-			      G_TYPE_FROM_CLASS (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (RBDaapMdnsPublisherClass, published),
-			      NULL,
-			      NULL,
-			      g_cclosure_marshal_VOID__STRING,
-			      G_TYPE_NONE,
-			      1, G_TYPE_STRING);
-	signals [NAME_COLLISION] =
-		g_signal_new ("name-collision",
-			      G_TYPE_FROM_CLASS (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (RBDaapMdnsPublisherClass, name_collision),
-			      NULL,
-			      NULL,
-			      g_cclosure_marshal_VOID__STRING,
-			      G_TYPE_NONE,
-			      1, G_TYPE_STRING);
-
-	g_type_class_add_private (klass, sizeof (RBDaapMdnsPublisherPrivate));
-}
-
-static void
-rb_daap_mdns_publisher_init (RBDaapMdnsPublisher *publisher)
-{
-	publisher->priv = RB_DAAP_MDNS_PUBLISHER_GET_PRIVATE (publisher);
-
-	publisher->priv->client = rb_daap_mdns_avahi_get_client ();
-}
-
-static void
-rb_daap_mdns_publisher_finalize (GObject *object)
-{
-	RBDaapMdnsPublisher *publisher;
-
-	g_return_if_fail (object != NULL);
-	g_return_if_fail (RB_IS_DAAP_MDNS_PUBLISHER (object));
-
-	publisher = RB_DAAP_MDNS_PUBLISHER (object);
-
-	g_return_if_fail (publisher->priv != NULL);
-
-	if (publisher->priv->entry_group) {
-		avahi_entry_group_free (publisher->priv->entry_group);
-		rb_daap_mdns_avahi_set_entry_group (NULL);
-	}
-
-	g_free (publisher->priv->name);
-
-	G_OBJECT_CLASS (rb_daap_mdns_publisher_parent_class)->finalize (object);
-}
-
-RBDaapMdnsPublisher *
-rb_daap_mdns_publisher_new (void)
-{
-	if (publisher_object) {
-		g_object_ref (publisher_object);
-	} else {
-		publisher_object = g_object_new (RB_TYPE_DAAP_MDNS_PUBLISHER, NULL);
-		g_object_add_weak_pointer (publisher_object,
-					   (gpointer *) &publisher_object);
-	}
-
-	return RB_DAAP_MDNS_PUBLISHER (publisher_object);
-}
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-mdns-publisher.h rhythmbox-0.12.1/plugins/daap/rb-daap-mdns-publisher.h
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-mdns-publisher.h	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-mdns-publisher.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,98 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- *  Header for abstraction of Multicast DNS for DAAP sharing
- *
- *  Copyright (C) 2005 Charles Schmidt <cschmidt2@emich.edu>
- *  Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The Rhythmbox authors hereby grant permission for non-GPL compatible
- *  GStreamer plugins to be used and distributed together with GStreamer
- *  and Rhythmbox. This permission is above and beyond the permissions granted
- *  by the GPL license by which Rhythmbox is covered. If you modify this code
- *  you may extend this exception to your version of the code, but you are not
- *  obligated to do so. If you do not wish to do so, delete this exception
- *  statement from your version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#ifndef __RB_DAAP_MDNS_PUBLISHER_H
-#define __RB_DAAP_MDNS_PUBLISHER_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define RB_TYPE_DAAP_MDNS_PUBLISHER         (rb_daap_mdns_publisher_get_type ())
-#define RB_DAAP_MDNS_PUBLISHER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_DAAP_MDNS_PUBLISHER, RBDaapMdnsPublisher))
-#define RB_DAAP_MDNS_PUBLISHER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_DAAP_MDNS_PUBLISHER, RBDaapMdnsPublisherClass))
-#define RB_IS_DAAP_MDNS_PUBLISHER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_DAAP_MDNS_PUBLISHER))
-#define RB_IS_DAAP_MDNS_PUBLISHER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_DAAP_MDNS_PUBLISHER))
-#define RB_DAAP_MDNS_PUBLISHER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_DAAP_MDNS_PUBLISHER, RBDaapMdnsPublisherClass))
-
-typedef struct RBDaapMdnsPublisherPrivate RBDaapMdnsPublisherPrivate;
-
-typedef struct
-{
-	GObject object;
-
-	RBDaapMdnsPublisherPrivate *priv;
-} RBDaapMdnsPublisher;
-
-typedef struct
-{
-	GObjectClass parent_class;
-
-	void (* published)         (RBDaapMdnsPublisher *publisher,
-				    const char          *name);
-	void (* name_collision)    (RBDaapMdnsPublisher *publisher,
-				    const char          *name);
-} RBDaapMdnsPublisherClass;
-
-typedef enum
-{
-	RB_DAAP_MDNS_PUBLISHER_ERROR_NOT_RUNNING,
-	RB_DAAP_MDNS_PUBLISHER_ERROR_FAILED,
-} RBDaapMdnsPublisherError;
-
-#define RB_DAAP_MDNS_PUBLISHER_ERROR rb_daap_mdns_publisher_error_quark ()
-
-GQuark      rb_daap_mdns_publisher_error_quark                     (void);
-
-GType       rb_daap_mdns_publisher_get_type                        (void);
-
-RBDaapMdnsPublisher *rb_daap_mdns_publisher_new                    (void);
-gboolean             rb_daap_mdns_publisher_publish                (RBDaapMdnsPublisher *publisher,
-								    const char          *name,
-								    guint                port,
-								    gboolean             password_required,
-								    GError             **error);
-gboolean             rb_daap_mdns_publisher_set_name               (RBDaapMdnsPublisher *publisher,
-								    const char          *name,
-								    GError             **error);
-gboolean             rb_daap_mdns_publisher_set_port               (RBDaapMdnsPublisher *publisher,
-								    guint                port,
-								    GError             **error);
-gboolean             rb_daap_mdns_publisher_set_password_required  (RBDaapMdnsPublisher *publisher,
-								    gboolean             required,
-								    GError             **error);
-gboolean             rb_daap_mdns_publisher_withdraw               (RBDaapMdnsPublisher *publisher,
-								    GError             **error);
-
-G_END_DECLS
-
-#endif /* __RB_DAAP_MDNS_PUBLISHER_H */
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-plugin.c rhythmbox-0.12.1/plugins/daap/rb-daap-plugin.c
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-plugin.c	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-plugin.c	2009-08-11 23:24:57.000000000 -0400
@@ -53,7 +53,7 @@
 #include "rb-daap-src.h"
 #include "rb-uri-dialog.h"
 
-#include "rb-daap-mdns-browser.h"
+#include <libdmapsharing/dmap.h>
 
 /* preferences */
 #define CONF_DAAP_PREFIX  	CONF_PREFIX "/plugins/daap"
@@ -74,7 +74,7 @@
 	GtkActionGroup *daap_action_group;
 	guint daap_ui_merge_id;
 
-	RBDaapMdnsBrowser *mdns_browser;
+	DMAPMdnsBrowser *mdns_browser;
 
 	GHashTable *source_lookup;
 
@@ -447,33 +447,33 @@
 }
 
 static void
-mdns_service_added (RBDaapMdnsBrowser *browser,
-		    const char        *service_name,
-		    const char        *name,
-		    const char        *host,
-		    guint              port,
-		    gboolean           password_protected,
-		    RBDaapPlugin      *plugin)
+mdns_service_added (DMAPMdnsBrowser *browser,
+		    DMAPMdnsBrowserService *service,
+		    RBDaapPlugin	*plugin)
 {
 	RBSource *source;
 
 	rb_debug ("New service: %s name=%s host=%s port=%u password=%d",
-		   service_name, name, host, port, password_protected);
+		   service->service_name,
+		   service->name,
+		   service->host,
+		   service->port,
+		   service->password_protected);
 
 	GDK_THREADS_ENTER ();
 
-	source = find_source_by_service_name (plugin, service_name);
+	source = find_source_by_service_name (plugin, service->service_name);
 
 	if (source == NULL) {
-		source = rb_daap_source_new (plugin->priv->shell, RB_PLUGIN (plugin), service_name, name, host, port, password_protected);
-		g_hash_table_insert (plugin->priv->source_lookup, g_strdup (service_name), source);
+		source = rb_daap_source_new (plugin->priv->shell, RB_PLUGIN (plugin), service->service_name, service->name, service->host, service->port, service->password_protected);
+		g_hash_table_insert (plugin->priv->source_lookup, g_strdup (service->service_name), source);
 		rb_shell_append_source (plugin->priv->shell, source, NULL);
 	} else {
 		g_object_set (G_OBJECT (source),
-			      "name", name,
-			      "host", host,
-			      "port", port,
-			      "password-protected", password_protected,
+			      "name", service->name,
+			      "host", service->host,
+			      "port", service->port,
+			      "password-protected", service->password_protected,
 			      NULL);
 	}
 
@@ -481,7 +481,7 @@
 }
 
 static void
-mdns_service_removed (RBDaapMdnsBrowser *browser,
+mdns_service_removed (DMAPMdnsBrowser *browser,
 		      const char        *service_name,
 		      RBDaapPlugin	*plugin)
 {
@@ -522,7 +522,7 @@
 		return;
 	}
 
-	plugin->priv->mdns_browser = rb_daap_mdns_browser_new ();
+	plugin->priv->mdns_browser = dmap_mdns_browser_new (DMAP_MDNS_BROWSER_SERVICE_TYPE_DAAP);
 	if (plugin->priv->mdns_browser == NULL) {
 		g_warning ("Unable to start mDNS browsing");
 		return;
@@ -540,7 +540,7 @@
 				 0);
 
 	error = NULL;
-	rb_daap_mdns_browser_start (plugin->priv->mdns_browser, &error);
+	dmap_mdns_browser_start (plugin->priv->mdns_browser, &error);
 	if (error != NULL) {
 		g_warning ("Unable to start mDNS browsing: %s", error->message);
 		g_error_free (error);
@@ -570,7 +570,7 @@
 	g_signal_handlers_disconnect_by_func (plugin->priv->mdns_browser, mdns_service_removed, plugin);
 
 	error = NULL;
-	rb_daap_mdns_browser_stop (plugin->priv->mdns_browser, &error);
+	dmap_mdns_browser_stop (plugin->priv->mdns_browser, &error);
 	if (error != NULL) {
 		g_warning ("Unable to stop mDNS browsing: %s", error->message);
 		g_error_free (error);
@@ -634,12 +634,13 @@
 
 	if (status == SOUP_STATUS_OK) {
 		rb_debug ("adding manually specified DAAP share at %s", data->location);
+		DMAPMdnsBrowserService service;
+		service.name = data->service_name;
+		service.host = data->location;
+		service.port = soup_address_get_port (addr);
+		service.password_protected = FALSE;
 		mdns_service_added (NULL,
-				    data->service_name,
-				    data->location,
-				    soup_address_get_physical (addr),
-				    soup_address_get_port (addr),
-				    FALSE,
+				    &service,
 				    data->plugin);
 	} else {
 		rb_debug ("unable to resolve DAAP share address %s",
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-record.c rhythmbox-0.12.1/plugins/daap/rb-daap-record.c
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-record.c	1969-12-31 19:00:00.000000000 -0500
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-record.c	2009-08-18 19:58:10.000000000 -0400
@@ -0,0 +1,378 @@
+/*
+ *  Database record class for DAAP sharing
+ *
+ *  Copyright (C) 2008 W. Michael Petullo <mike@flyn.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "rhythmdb.h"
+#include "rb-daap-record.h"
+
+struct RBDAAPRecordPrivate {
+	guint64 filesize;
+	char *location;
+	char *format;	 /* Format, possibly after transcoding. */
+	char *real_format;
+	char *title;
+	char *album;
+	char *artist;
+	char *genre;
+	gboolean has_video;
+	gint rating;
+	gint32 duration;
+	gint32 track;
+	gint32 year;
+	gint32 firstseen;
+	gint32 mtime;
+	gint32 disc;
+	gint32 bitrate;
+};
+
+enum {
+	PROP_0,
+	PROP_LOCATION,
+	PROP_TITLE,
+	PROP_RATING,
+	PROP_FILESIZE,
+	PROP_ALBUM,
+	PROP_ARTIST,
+	PROP_GENRE,
+	PROP_FORMAT,
+	PROP_DURATION,
+	PROP_TRACK,
+	PROP_YEAR,
+	PROP_FIRSTSEEN,
+	PROP_MTIME,
+	PROP_DISC,
+	PROP_BITRATE,
+	PROP_HAS_VIDEO,
+	PROP_REAL_FORMAT
+};
+
+static void
+rb_daap_record_set_property (GObject *object,
+				guint prop_id,
+				const GValue *value,
+				GParamSpec *pspec)
+{
+	RBDAAPRecord *record = RB_DAAP_RECORD (object);
+	GObject *obj;
+
+	switch (prop_id) {
+		case PROP_LOCATION:
+			g_free (record->priv->location);
+			record->priv->location = g_value_dup_string (value);
+			break;
+		case PROP_TITLE:
+			g_free (record->priv->title);
+			record->priv->title = g_value_dup_string (value);
+			break;
+		case PROP_ALBUM:
+			g_free (record->priv->album);
+			record->priv->album = g_value_dup_string (value);
+			break;
+		case PROP_ARTIST:
+			g_free (record->priv->artist);
+			record->priv->artist = g_value_dup_string (value);
+			break;
+		case PROP_GENRE:
+			g_free (record->priv->genre);
+			record->priv->genre = g_value_dup_string (value);
+			break;
+		case PROP_FORMAT:
+			g_free (record->priv->format);
+			record->priv->format = g_value_dup_string (value);
+			break;
+		case PROP_RATING:
+			record->priv->rating = g_value_get_int (value);
+			break;
+		case PROP_FILESIZE:
+			record->priv->filesize = g_value_get_uint64 (value);
+			break;
+		case PROP_DURATION:
+			record->priv->duration = g_value_get_int (value);
+			break;
+		case PROP_TRACK:
+			record->priv->track = g_value_get_int (value);
+			break;
+		case PROP_YEAR:
+			record->priv->year = g_value_get_int (value);
+			break;
+		case PROP_FIRSTSEEN:
+			record->priv->firstseen = g_value_get_int (value);
+			break;
+		case PROP_MTIME:
+			record->priv->mtime = g_value_get_int (value);
+			break;
+		case PROP_DISC:
+			record->priv->disc = g_value_get_int (value);
+			break;
+		case PROP_BITRATE:
+			record->priv->bitrate = g_value_get_long (value);
+			break;
+		case PROP_HAS_VIDEO:
+			record->priv->has_video = g_value_get_boolean (value);
+			break;
+		case PROP_REAL_FORMAT:
+			g_free (record->priv->real_format);
+			record->priv->real_format = g_value_dup_string (value);
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+	}
+}
+
+static void
+rb_daap_record_get_property (GObject *object,
+				guint prop_id,
+				GValue *value,
+				GParamSpec *pspec)
+{
+	RBDAAPRecord *record = RB_DAAP_RECORD (object);
+
+	switch (prop_id) {
+		case PROP_LOCATION:
+			g_value_set_string (value, record->priv->location);
+			break;
+		case PROP_TITLE:
+			g_value_set_string (value, record->priv->title);
+			break;
+		case PROP_ALBUM:
+			g_value_set_string (value, record->priv->album);
+			break;
+		case PROP_ARTIST:
+			g_value_set_string (value, record->priv->artist);
+			break;
+		case PROP_GENRE:
+			g_value_set_string (value, record->priv->genre);
+			break;
+		case PROP_FORMAT:
+			g_value_set_string (value, record->priv->format);
+			break;
+		case PROP_RATING:
+			g_value_set_int (value, record->priv->rating);
+			break;
+		case PROP_FILESIZE:
+			g_value_set_uint64 (value, record->priv->filesize);
+			break;
+		case PROP_DURATION:
+			g_value_set_int (value, record->priv->duration);
+			break;
+		case PROP_TRACK:
+			g_value_set_int (value, record->priv->track);
+			break;
+		case PROP_YEAR:
+			g_value_set_int (value, record->priv->year);
+			break;
+		case PROP_FIRSTSEEN:
+			g_value_set_int (value, record->priv->firstseen);
+			break;
+		case PROP_MTIME:
+			g_value_set_int (value, record->priv->mtime);
+			break;
+		case PROP_DISC:
+			g_value_set_int (value, record->priv->disc);
+			break;
+		case PROP_BITRATE:
+			g_value_set_long (value, record->priv->bitrate);
+			break;
+		case PROP_HAS_VIDEO:
+			g_value_set_boolean (value, record->priv->has_video);
+			break;
+		case PROP_REAL_FORMAT:
+			g_value_set_string (value, record->priv->real_format);
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+	}
+}
+
+gboolean rb_daap_record_itunes_compat (DAAPRecord *record)
+{
+	const gchar *format = RB_DAAP_RECORD (record)->priv->real_format;
+
+	if (! strcmp (format, "mp3"))
+		return TRUE;
+	else
+		return FALSE;
+}
+
+GInputStream *rb_daap_record_read (DAAPRecord *record, GError **error)
+{
+	GFile *file;
+	GInputStream *fnval = NULL;
+
+	file = g_file_new_for_uri (RB_DAAP_RECORD (record)->priv->location);
+	fnval = G_INPUT_STREAM (g_file_read (file, NULL, error));
+
+	return fnval;
+}
+
+static void rb_daap_record_init (RBDAAPRecord *record)
+{
+	record->priv = RB_DAAP_RECORD_GET_PRIVATE (record);
+}
+
+static void rb_daap_record_finalize (GObject *object);
+
+static void rb_daap_record_class_init (RBDAAPRecordClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (RBDAAPRecordPrivate));
+
+	gobject_class->set_property = rb_daap_record_set_property;	
+	gobject_class->get_property = rb_daap_record_get_property;	
+	gobject_class->finalize     = rb_daap_record_finalize;	
+
+	g_object_class_override_property (gobject_class, PROP_LOCATION, "location");
+	g_object_class_override_property (gobject_class, PROP_TITLE, "title");
+	g_object_class_override_property (gobject_class, PROP_ALBUM, "album");
+	g_object_class_override_property (gobject_class, PROP_ARTIST, "artist");
+	g_object_class_override_property (gobject_class, PROP_GENRE, "genre");
+	g_object_class_override_property (gobject_class, PROP_FORMAT, "format");
+	g_object_class_override_property (gobject_class, PROP_RATING, "rating");
+	g_object_class_override_property (gobject_class, PROP_FILESIZE, "filesize");
+	g_object_class_override_property (gobject_class, PROP_DURATION, "duration");
+	g_object_class_override_property (gobject_class, PROP_TRACK, "track");
+	g_object_class_override_property (gobject_class, PROP_YEAR, "year");
+	g_object_class_override_property (gobject_class, PROP_FIRSTSEEN, "firstseen");
+	g_object_class_override_property (gobject_class, PROP_MTIME, "mtime");
+	g_object_class_override_property (gobject_class, PROP_DISC, "disc");
+	g_object_class_override_property (gobject_class, PROP_BITRATE, "bitrate");
+	g_object_class_override_property (gobject_class, PROP_HAS_VIDEO, "has-video");
+
+	g_object_class_install_property (gobject_class, PROP_REAL_FORMAT,
+	                        g_param_spec_string ("real-format",
+			     "Real format of song data",
+			     "Real format of song data",
+			       NULL,
+			    G_PARAM_READWRITE));
+}
+
+static void rb_daap_record_daap_iface_init (gpointer iface, gpointer data)
+{
+	DAAPRecordInterface *daap_record = iface;
+
+	g_assert (G_TYPE_FROM_INTERFACE (daap_record) == TYPE_DAAP_RECORD);
+
+	daap_record->itunes_compat = rb_daap_record_itunes_compat;
+	daap_record->read = rb_daap_record_read;
+}
+
+static void rb_daap_record_dmap_iface_init (gpointer iface, gpointer data)
+{
+	DMAPRecordInterface *dmap_record = iface;
+
+	g_assert (G_TYPE_FROM_INTERFACE (dmap_record) == TYPE_DMAP_RECORD);
+}
+
+G_DEFINE_TYPE_WITH_CODE (RBDAAPRecord, rb_daap_record, G_TYPE_OBJECT, 
+			 G_IMPLEMENT_INTERFACE (TYPE_DAAP_RECORD, rb_daap_record_daap_iface_init)
+			 G_IMPLEMENT_INTERFACE (TYPE_DMAP_RECORD, rb_daap_record_dmap_iface_init))
+
+static void rb_daap_record_finalize (GObject *object)
+{
+	RBDAAPRecord *record = RB_DAAP_RECORD (object);
+
+        g_free (record->priv->location);
+	g_free (record->priv->title);
+	g_free (record->priv->format);
+	g_free (record->priv->album);
+	g_free (record->priv->artist);
+	g_free (record->priv->genre);
+	g_free (record->priv->real_format);
+
+	G_OBJECT_CLASS (rb_daap_record_parent_class)->finalize (object);
+}
+
+
+RBDAAPRecord *rb_daap_record_new (RhythmDBEntry *entry)
+{
+	RBDAAPRecord *record = NULL;
+	record = RB_DAAP_RECORD (g_object_new (TYPE_RB_DAAP_RECORD, NULL));
+
+	/* FIXME: when browsing, entry will be NULL because we will pull
+	 * the metadata from the DAAP query. When sharing entry will point
+	 * to an existing entry from the Rhythmbox DB. Where should this
+	 * differentiation be handled?
+	 */
+	if (entry) {
+		gchar *ext;
+
+		record->priv->filesize = rhythmdb_entry_get_uint64 
+						(entry, RHYTHMDB_PROP_FILE_SIZE);
+
+		record->priv->location = g_strdup (rhythmdb_entry_get_string
+						(entry, RHYTHMDB_PROP_LOCATION));
+
+		record->priv->title    = g_strdup (rhythmdb_entry_get_string
+						(entry, RHYTHMDB_PROP_TITLE));
+
+		record->priv->artist   = g_strdup (rhythmdb_entry_get_string
+						(entry, RHYTHMDB_PROP_ARTIST));
+
+		record->priv->album    = g_strdup (rhythmdb_entry_get_string
+						(entry, RHYTHMDB_PROP_ALBUM));
+
+		record->priv->genre    = g_strdup (rhythmdb_entry_get_string
+						(entry, RHYTHMDB_PROP_GENRE));
+
+		/* FIXME: Support transcoding: */
+		/* FIXME: we should use RHYTHMDB_PROP_MIMETYPE instead */
+		ext = strrchr (record->priv->location, '.');
+		if (ext == NULL) {
+			ext = "mp3";
+		} else {
+			ext++;
+		}
+		record->priv->real_format = g_strdup (ext);
+		record->priv->format = g_strdup (record->priv->real_format);
+
+		record->priv->track    = rhythmdb_entry_get_ulong
+						(entry, RHYTHMDB_PROP_TRACK_NUMBER);
+
+		record->priv->duration = rhythmdb_entry_get_ulong
+						(entry, RHYTHMDB_PROP_DURATION);
+
+		/* FIXME: */
+		record->priv->rating = 0;
+
+		/* FIXME: */
+		record->priv->year = 0;
+
+		record->priv->firstseen = rhythmdb_entry_get_ulong
+						(entry, RHYTHMDB_PROP_FIRST_SEEN);
+
+		record->priv->mtime     = rhythmdb_entry_get_ulong
+						(entry, RHYTHMDB_PROP_MTIME);
+
+		record->priv->disc      = rhythmdb_entry_get_ulong
+						(entry, RHYTHMDB_PROP_DISC_NUMBER);
+
+		record->priv->bitrate   = rhythmdb_entry_get_ulong
+						(entry, RHYTHMDB_PROP_BITRATE);
+	}
+
+	return record;
+}
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-record-factory.c rhythmbox-0.12.1/plugins/daap/rb-daap-record-factory.c
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-record-factory.c	1969-12-31 19:00:00.000000000 -0500
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-record-factory.c	2009-08-11 23:24:57.000000000 -0400
@@ -0,0 +1,69 @@
+/*
+ * DAAPRecord factory class
+ *
+ * Copyright (C) 2008 W. Michael Petullo <mike@flyn.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "rhythmdb.h"
+#include "rb-daap-record-factory.h"
+#include "rb-daap-record.h"
+
+DMAPRecord *
+rb_daap_record_factory_create  (DMAPRecordFactory *factory,
+				   const char *path)
+{
+	DAAPRecord *record;
+
+	/* FIXME: dumb cast: */
+	record = DAAP_RECORD (rb_daap_record_new ((RhythmDBEntry *) path));
+
+	return (DMAP_RECORD (record));
+}
+
+static void
+rb_daap_record_factory_init (RBDAAPRecordFactory *factory)
+{
+}
+
+static void
+rb_daap_record_factory_class_init (RBDAAPRecordFactoryClass *klass)
+{
+}
+
+static void
+rb_daap_record_factory_interface_init (gpointer iface, gpointer data)
+{
+	DMAPRecordFactoryInterface *factory = iface;
+
+	g_assert (G_TYPE_FROM_INTERFACE (factory) == TYPE_DMAP_RECORD_FACTORY);
+
+	factory->create = rb_daap_record_factory_create;
+}
+
+G_DEFINE_TYPE_WITH_CODE (RBDAAPRecordFactory, rb_daap_record_factory, G_TYPE_OBJECT, 
+			 G_IMPLEMENT_INTERFACE (TYPE_DMAP_RECORD_FACTORY,
+					        rb_daap_record_factory_interface_init))
+
+RBDAAPRecordFactory *
+rb_daap_record_factory_new (void)
+{
+	RBDAAPRecordFactory *factory;
+
+	factory = RB_DAAP_RECORD_FACTORY (g_object_new (TYPE_RB_DAAP_RECORD_FACTORY, NULL));
+
+	return factory;
+}
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-record-factory.h rhythmbox-0.12.1/plugins/daap/rb-daap-record-factory.h
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-record-factory.h	1969-12-31 19:00:00.000000000 -0500
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-record-factory.h	2009-08-11 23:24:57.000000000 -0400
@@ -0,0 +1,58 @@
+/*
+ * RBDAAPRecord factory class
+ *
+ * Copyright (C) 2008 W. Michael Petullo <mike@flyn.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __RB_DAAP_RECORD_FACTORY
+#define __RB_DAAP_RECORD_FACTORY
+
+#include <libdmapsharing/dmap.h>
+
+G_BEGIN_DECLS
+
+#define TYPE_RB_DAAP_RECORD_FACTORY         (rb_daap_record_factory_get_type ())
+#define RB_DAAP_RECORD_FACTORY(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), \
+				               TYPE_RB_DAAP_RECORD_FACTORY, RBDAAPRecordFactory))
+#define RB_DAAP_RECORD_FACTORY_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), \
+				               TYPE_RB_DAAP_RECORD_FACTORY, RBDAAPRecordFactoryClass))
+#define IS_RB_DAAP_RECORD_FACTORY(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), \
+				               TYPE_RB_DAAP_RECORD_FACTORY))
+#define IS_RB_DAAP_RECORD_FACTORY_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), \
+				               TYPE_RB_DAAP_RECORD_FACTORY_CLASS))
+#define RB_DAAP_RECORD_FACTORY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), \
+				               TYPE_RB_DAAP_RECORD_FACTORY, RBDAAPRecordFactoryClass))
+
+typedef struct RBDAAPRecordFactoryPrivate RBDAAPRecordFactoryPrivate;
+
+typedef struct {
+	GObject parent;
+} RBDAAPRecordFactory;
+
+typedef struct {
+	GObjectClass parent;
+} RBDAAPRecordFactoryClass;
+
+GType                  rb_daap_record_factory_get_type (void);
+
+RBDAAPRecordFactory *rb_daap_record_factory_new      (void);
+
+DMAPRecord            *rb_daap_record_factory_create   (DMAPRecordFactory *factory, const char *path);
+
+#endif /* __RB_DAAP_RECORD_FACTORY */
+
+G_END_DECLS
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-record.h rhythmbox-0.12.1/plugins/daap/rb-daap-record.h
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-record.h	1969-12-31 19:00:00.000000000 -0500
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-record.h	2009-08-11 23:24:57.000000000 -0400
@@ -0,0 +1,63 @@
+/*
+ *  Database record class for DAAP sharing
+ *
+ *  Copyright (C) 2008 W. Michael Petullo <mike@flyn.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __RB_DAAP_RECORD
+#define __RB_DAAP_RECORD
+
+#include <libdmapsharing/dmap.h>
+
+G_BEGIN_DECLS
+
+#define TYPE_RB_DAAP_RECORD         (rb_daap_record_get_type ())
+#define RB_DAAP_RECORD(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TYPE_RB_DAAP_RECORD, RBDAAPRecord))
+#define RB_DAAP_RECORD_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), TYPE_RB_DAAP_RECORD, RBDAAPRecordClass))
+#define IS_RB_DAAP_RECORD(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TYPE_RB_DAAP_RECORD))
+#define IS_RB_DAAP_RECORD_CLASS (k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_RB_DAAP_RECORD_CLASS))
+#define RB_DAAP_RECORD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_RB_DAAP_RECORD, RBDAAPRecordClass))
+#define RB_DAAP_RECORD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_RB_DAAP_RECORD, RBDAAPRecordPrivate))
+
+typedef struct RBDAAPRecordPrivate RBDAAPRecordPrivate;
+
+typedef struct {
+	GObject parent;
+	RBDAAPRecordPrivate *priv;
+} RBDAAPRecord;
+
+typedef struct {
+	GObjectClass parent;
+} RBDAAPRecordClass;
+
+GType rb_daap_record_get_type (void);
+
+RBDAAPRecord *rb_daap_record_new (RhythmDBEntry *entry);
+
+gint          rb_daap_record_get_id          (DAAPRecord *record);
+
+gboolean      rb_daap_record_itunes_compat   (DAAPRecord *record);
+
+void          rb_daap_record_set_transcode_format (DAAPRecord *record,
+						      const gint format);
+
+GInputStream *rb_daap_record_read            (DAAPRecord *record,
+						 GError **err);
+
+#endif /* __RB_DAAP_RECORD */
+
+G_END_DECLS
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-share.c rhythmbox-0.12.1/plugins/daap/rb-daap-share.c
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-share.c	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-share.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1773 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- *  Implmentation of DAAP (iTunes Music Sharing) sharing
- *
- *  Copyright (C) 2005 Charles Schmidt <cschmidt2@emich.edu>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The Rhythmbox authors hereby grant permission for non-GPL compatible
- *  GStreamer plugins to be used and distributed together with GStreamer
- *  and Rhythmbox. This permission is above and beyond the permissions granted
- *  by the GPL license by which Rhythmbox is covered. If you modify this code
- *  you may extend this exception to your version of the code, but you are not
- *  obligated to do so. If you do not wish to do so, delete this exception
- *  statement from your version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#include "config.h"
-
-#include <time.h>
-#include <string.h>
-
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-#include <libsoup/soup.h>
-#include <libsoup/soup-address.h>
-#include <libsoup/soup-message.h>
-#include <libsoup/soup-uri.h>
-#include <libsoup/soup-server.h>
-
-#include "rb-daap-share.h"
-#include "rb-daap-structure.h"
-#include "rb-daap-mdns-publisher.h"
-#include "rb-daap-dialog.h"
-
-#include "rb-playlist-source.h"
-#include "rb-debug.h"
-#include "eel-gconf-extensions.h"
-#include "rb-file-helpers.h"
-
-static void rb_daap_share_set_property  (GObject *object,
-					 guint prop_id,
-					 const GValue *value,
-					 GParamSpec *pspec);
-static void rb_daap_share_get_property  (GObject *object,
-					 guint prop_id,
-					 GValue *value,
-				 	 GParamSpec *pspec);
-static void rb_daap_share_dispose	(GObject *object);
-static void rb_daap_share_maybe_restart (RBDAAPShare *share);
-static gboolean rb_daap_share_publish_start (RBDAAPShare *share);
-static gboolean rb_daap_share_publish_stop  (RBDAAPShare *share);
-static gboolean rb_daap_share_server_start  (RBDAAPShare *share);
-static gboolean rb_daap_share_server_stop   (RBDAAPShare *share);
-static void rb_daap_share_playlist_created (RBPlaylistManager *mgr,
-					    RBSource *playlist,
-					    RBDAAPShare *share);
-static void rb_daap_share_process_playlist (RBSource *playlist,
-					    RBDAAPShare *share);
-static void rb_daap_share_playlist_destroyed (RBDAAPShare *share,
-					      RBSource *source);
-static void rb_daap_share_forget_playlist (gpointer data,
-					   RBDAAPShare *share);
-
-#define STANDARD_DAAP_PORT 3689
-
-/* HTTP chunk size used to send files to clients */
-#define DAAP_SHARE_CHUNK_SIZE	16384
-
-typedef enum {
-	RB_DAAP_SHARE_AUTH_METHOD_NONE              = 0,
-	RB_DAAP_SHARE_AUTH_METHOD_NAME_AND_PASSWORD = 1,
-	RB_DAAP_SHARE_AUTH_METHOD_PASSWORD          = 2
-} RBDAAPShareAuthMethod;
-
-struct RBDAAPSharePrivate {
-	gchar *name;
-	guint port;
-	char *password;
-	RBDAAPShareAuthMethod auth_method;
-
-	/* mdns/dns-sd publishing things */
-	gboolean server_active;
-	gboolean published;
-	RBDaapMdnsPublisher *publisher;
-
-	/* http server things */
-	SoupServer *server;
-	guint revision_number;
-
-	GHashTable *session_ids;
-
-	/* db things */
-	RhythmDB *db;
-	RhythmDBEntryType entry_type;
-	gulong entry_added_id;
-	gulong entry_deleted_id;
-	gulong entry_changed_id;
-
-	/* playlist things */
-	RBPlaylistManager *playlist_manager;
-	guint next_playlist_id;
-	GList *playlist_ids;	/* contains RBPlaylistIDs */
-};
-
-#define RB_DAAP_SHARE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_DAAP_SHARE, RBDAAPSharePrivate))
-
-typedef struct {
-	RBSource *source;
-	gint32 id;
-} RBPlaylistID;
-
-enum {
-	PROP_0,
-	PROP_NAME,
-	PROP_PASSWORD,
-	PROP_DB,
-	PROP_PLAYLIST_MANAGER,
-	PROP_ENTRY_TYPE
-};
-
-G_DEFINE_TYPE (RBDAAPShare, rb_daap_share, G_TYPE_OBJECT)
-
-static void
-rb_daap_share_class_init (RBDAAPShareClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-	object_class->get_property = rb_daap_share_get_property;
-	object_class->set_property = rb_daap_share_set_property;
-	object_class->dispose = rb_daap_share_dispose;
-
-	g_object_class_install_property (object_class,
-					 PROP_NAME,
-					 g_param_spec_string ("name",
-						 	      "Name",
-							      "Share Name",
-							      NULL,
-							      G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_PASSWORD,
-					 g_param_spec_string ("password",
-							      "Authentication password",
-							      "Authentication password",
-							      NULL,
-							      G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_DB,
-					 g_param_spec_object ("db",
-							      "RhythmDB",
-							      "RhythmDB object",
-							      RHYTHMDB_TYPE,
-							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-	g_object_class_install_property (object_class,
-					 PROP_PLAYLIST_MANAGER,
-					 g_param_spec_object ("playlist-manager",
-							      "Playlist Manager",
-							      "Playlist manager object",
-							      RB_TYPE_PLAYLIST_MANAGER,
-							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-	g_object_class_install_property (object_class,
-					 PROP_ENTRY_TYPE,
-					 g_param_spec_boxed ("entry-type",
-							     "Entry type",
-							     "Type of entries to be shared",
-							     RHYTHMDB_TYPE_ENTRY_TYPE,
-							     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
-	g_type_class_add_private (klass, sizeof (RBDAAPSharePrivate));
-}
-
-static void
-rb_daap_share_set_name (RBDAAPShare *share,
-			const char  *name)
-{
-	GError *error;
-	gboolean res;
-
-	g_return_if_fail (share != NULL);
-
-	g_free (share->priv->name);
-	share->priv->name = g_strdup (name);
-
-	error = NULL;
-	res = rb_daap_mdns_publisher_set_name (share->priv->publisher, name, &error);
-	if (error != NULL) {
-		g_warning ("Unable to change MDNS service name: %s", error->message);
-		g_error_free (error);
-	}
-}
-
-static void
-published_cb (RBDaapMdnsPublisher *publisher,
-	      const char          *name,
-	      RBDAAPShare         *share)
-{
-	if (share->priv->name == NULL || name == NULL) {
-		return;
-	}
-
-	if (strcmp (name, share->priv->name) == 0) {
-		rb_debug ("mDNS publish successful");
-		share->priv->published = TRUE;
-	}
-}
-
-static void
-name_collision_cb (RBDaapMdnsPublisher *publisher,
-		   const char          *name,
-		   RBDAAPShare         *share)
-{
-	char *new_name;
-
-	if (share->priv->name == NULL || name == NULL) {
-		return;
-	}
-
-	if (strcmp (name, share->priv->name) == 0) {
-		rb_debug ("Duplicate share name on mDNS");
-
-		GDK_THREADS_ENTER ();
-		new_name = rb_daap_collision_dialog_new_run (NULL, share->priv->name);
-		GDK_THREADS_LEAVE ();
-
-		rb_daap_share_set_name (share, new_name);
-		g_free (new_name);
-	}
-
-	return;
-}
-
-static void
-rb_daap_share_init (RBDAAPShare *share)
-{
-	share->priv = RB_DAAP_SHARE_GET_PRIVATE (share);
-
-	share->priv->revision_number = 5;
-
-	share->priv->auth_method = RB_DAAP_SHARE_AUTH_METHOD_NONE;
-	share->priv->publisher = rb_daap_mdns_publisher_new ();
-	g_signal_connect_object (share->priv->publisher,
-				 "published",
-				 G_CALLBACK (published_cb),
-				 share, 0);
-	g_signal_connect_object (share->priv->publisher,
-				 "name-collision",
-				 G_CALLBACK (name_collision_cb),
-				 share, 0);
-
-}
-
-static void
-rb_daap_share_set_password (RBDAAPShare *share,
-			    const char  *password)
-{
-	g_return_if_fail (share != NULL);
-
-	if (share->priv->password && password &&
-	    strcmp (password, share->priv->password) == 0) {
-		return;
-	}
-
-	g_free (share->priv->password);
-	share->priv->password = g_strdup (password);
-	if (password != NULL) {
-		share->priv->auth_method = RB_DAAP_SHARE_AUTH_METHOD_PASSWORD;
-	} else {
-		share->priv->auth_method = RB_DAAP_SHARE_AUTH_METHOD_NONE;
-	}
-
-	rb_daap_share_maybe_restart (share);
-}
-
-static void
-rb_daap_share_set_db (RBDAAPShare *share,
-		      RhythmDB    *db)
-{
-	if (share->priv->db != NULL) {
-		g_object_unref (share->priv->db);
-	}
-
-	share->priv->db = db;
-
-	if (share->priv->db != NULL) {
-		g_object_ref (share->priv->db);
-	}
-}
-
-static void
-rb_daap_share_set_playlist_manager (RBDAAPShare       *share,
-				    RBPlaylistManager *playlist_manager)
-{
-	GList *playlists;
-
-	g_return_if_fail (share != NULL);
-
-	if (share->priv->playlist_manager != NULL) {
-		g_object_unref (share->priv->playlist_manager);
-		g_signal_handlers_disconnect_by_func (share->priv->playlist_manager,
-						      G_CALLBACK (rb_daap_share_playlist_created),
-						      share);
-	}
-
-	share->priv->playlist_manager = playlist_manager;
-
-	if (share->priv->playlist_manager != NULL) {
-		g_object_ref (share->priv->playlist_manager);
-
-		g_signal_connect_object (G_OBJECT (share->priv->playlist_manager),
-					 "playlist_added",
-					 G_CALLBACK (rb_daap_share_playlist_created),
-					 share, 0);
-
-		/* Currently, there are no playlists when this object is created, but in
-		 * case it changes..
-		 */
-		playlists = rb_playlist_manager_get_playlists (share->priv->playlist_manager);
-		g_list_foreach (playlists, (GFunc) rb_daap_share_process_playlist, share);
-		g_list_free (playlists);
-	}
-}
-
-static void
-rb_daap_share_set_property (GObject *object,
-			    guint prop_id,
-			    const GValue *value,
-			    GParamSpec *pspec)
-{
-	RBDAAPShare *share = RB_DAAP_SHARE (object);
-
-	switch (prop_id) {
-	case PROP_NAME:
-		rb_daap_share_set_name (share, g_value_get_string (value));
-		break;
-	case PROP_PASSWORD:
-		rb_daap_share_set_password (share, g_value_get_string (value));
-		break;
-	case PROP_DB:
-		rb_daap_share_set_db (share, g_value_get_object (value));
-		break;
-	case PROP_PLAYLIST_MANAGER:
-		rb_daap_share_set_playlist_manager (share, g_value_get_object (value));
-		break;
-	case PROP_ENTRY_TYPE:
-		share->priv->entry_type = g_value_get_boxed (value);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-static void
-rb_daap_share_get_property (GObject *object,
-			    guint prop_id,
-			    GValue *value,
-			    GParamSpec *pspec)
-{
-	RBDAAPShare *share = RB_DAAP_SHARE (object);
-
-	switch (prop_id) {
-	case PROP_NAME:
-		g_value_set_string (value, share->priv->name);
-		break;
-	case PROP_PASSWORD:
-		g_value_set_string (value, share->priv->password);
-		break;
-	case PROP_DB:
-		g_value_set_object (value, share->priv->db);
-		break;
-	case PROP_PLAYLIST_MANAGER:
-		g_value_set_object (value, share->priv->playlist_manager);
-		break;
-	case PROP_ENTRY_TYPE:
-		g_value_set_boxed (value, share->priv->entry_type);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-static gint
-_find_by_id (gconstpointer a, gconstpointer b)
-{
-	RBPlaylistID *ai = (RBPlaylistID *)a;
-	gint bv = GPOINTER_TO_INT (b);
-	return (ai->id - bv);
-}
-
-static gint
-_find_by_source (gconstpointer a, gconstpointer b)
-{
-	RBPlaylistID *ai = (RBPlaylistID *)a;
-	RBSource *bs = (RBSource *)b;
-	return (ai->source - bs);
-}
-
-static void
-rb_daap_share_playlist_created (RBPlaylistManager *manager,
-				RBSource *source,
-				RBDAAPShare *share)
-{
-	rb_daap_share_process_playlist (source, share);
-}
-
-static void
-rb_daap_share_process_playlist (RBSource *source,
-				RBDAAPShare *share)
-{
-	RBPlaylistID *id;
-
-	/* make sure we're not going insane.. */
-	g_assert (g_list_find_custom (share->priv->playlist_ids,
-				      source,
-				      _find_by_source) == NULL);
-
-	g_object_weak_ref (G_OBJECT (source),
-			   (GWeakNotify) rb_daap_share_playlist_destroyed,
-			   share);
-	id = g_new0 (RBPlaylistID, 1);
-	id->source = source;
-	id->id = share->priv->next_playlist_id++;
-	share->priv->playlist_ids = g_list_append (share->priv->playlist_ids, id);
-
-	/* if we knew how to send updates to clients, we'd probably do something here */
-}
-
-static void
-rb_daap_share_playlist_destroyed (RBDAAPShare *share,
-				  RBSource *source)
-{
-	GList *id;
-
-	id = g_list_find_custom (share->priv->playlist_ids, source, _find_by_source);
-	if (!id)
-		return;
-
-	share->priv->playlist_ids = g_list_remove_link (share->priv->playlist_ids, id);
-	g_free (id->data);
-	g_list_free_1 (id);
-}
-
-static void
-rb_daap_share_forget_playlist (gpointer data,
-			       RBDAAPShare *share)
-{
-	RBPlaylistID *id = (RBPlaylistID *)data;
-	g_object_weak_unref (G_OBJECT (id->source),
-			     (GWeakNotify) rb_daap_share_playlist_destroyed,
-			     share);
-}
-
-static void
-rb_daap_share_dispose (GObject *object)
-{
-	RBDAAPShare *share = RB_DAAP_SHARE (object);
-
-	if (share->priv->published) {
-		rb_daap_share_publish_stop (share);
-	}
-
-	if (share->priv->server_active) {
-		rb_daap_share_server_stop (share);
-	}
-
-	g_free (share->priv->name);
-	g_object_unref (share->priv->db);
-	g_object_unref (share->priv->playlist_manager);
-
-	g_list_foreach (share->priv->playlist_ids, (GFunc) rb_daap_share_forget_playlist, share);
-	g_list_foreach (share->priv->playlist_ids, (GFunc) g_free, NULL);
-	g_list_free (share->priv->playlist_ids);
-
-	if (share->priv->publisher) {
-		g_object_unref (share->priv->publisher);
-	}
-
-	G_OBJECT_CLASS (rb_daap_share_parent_class)->dispose (object);
-}
-
-RBDAAPShare *
-rb_daap_share_new (const char *name,
-		   const char *password,
-		   RhythmDB *db,
-		   RhythmDBEntryType entry_type,
-		   RBPlaylistManager *playlist_manager)
-{
-	RBDAAPShare *share;
-
-	share = RB_DAAP_SHARE (g_object_new (RB_TYPE_DAAP_SHARE,
-					     "name", name,
-					     "password", password,
-					     "db", db,
-					     "playlist-manager", playlist_manager,
-					     "entry-type", entry_type,
-					     NULL));
-
-	rb_daap_share_server_start (share);
-	rb_daap_share_publish_start (share);
-
-	return share;
-}
-
-static void
-message_add_standard_headers (SoupMessage *message)
-{
-	soup_message_headers_append (message->response_headers, "DAAP-Server", "Rhythmbox " VERSION);
-
-	soup_message_headers_append (message->response_headers, "Content-Type", "application/x-dmap-tagged");
-}
-
-static void
-message_set_from_rb_daap_structure (SoupMessage *message,
-				    GNode *structure)
-{
-	gchar *resp;
-	guint length;
-
-	resp = rb_daap_structure_serialize (structure, &length);
-
-	if (resp == NULL) {
-		rb_debug ("serialize gave us null?\n");
-		return;
-	}
-
-	soup_message_set_response (message, "application/x-dmap-tagged", SOUP_MEMORY_TAKE, resp, length);
-
-	message_add_standard_headers (message);
-
-	soup_message_set_status (message, SOUP_STATUS_OK);
-}
-
-#define DMAP_STATUS_OK 200
-
-#define DMAP_VERSION 2.0
-#define DAAP_VERSION 3.0
-#define DMAP_TIMEOUT 1800
-
-static void
-server_info_cb (SoupServer        *server,
-		SoupMessage       *message,
-		const char        *path,
-		GHashTable        *query,
-		SoupClientContext *context,
-		RBDAAPShare       *share)
-{
-/* MSRV	server info response
- * 	MSTT status
- * 	MPRO dmap version
- * 	APRO daap version
- * 	MINM name
- * 	MSAU authentication method
- * 	MSLR login required
- * 	MSTM timeout interval
- * 	MSAL supports auto logout
- * 	MSUP supports update
- * 	MSPI supports persistent ids
- * 	MSEX supports extensions
- * 	MSBR supports browse
- * 	MSQY supports query
- * 	MSIX supports index
- * 	MSRS supports resolve
- * 	MSDC databases count
- */
-	GNode *msrv;
-
-	msrv = rb_daap_structure_add (NULL, RB_DAAP_CC_MSRV);
-	rb_daap_structure_add (msrv, RB_DAAP_CC_MSTT, (gint32) DMAP_STATUS_OK);
-	rb_daap_structure_add (msrv, RB_DAAP_CC_MPRO, (gdouble) DMAP_VERSION);
-	rb_daap_structure_add (msrv, RB_DAAP_CC_APRO, (gdouble) DAAP_VERSION);
-	/* 2/3 is for itunes 4.8 (at least).  its determined by the
-	 * Client-DAAP-Version header sent, but if we decide not to support
-	 * older versions..? anyway
-	 *
-	 * 1.0 is 1/1
-	 * 2.0 is 1/2
-	 * 3.0 is 2/3
-	 */
-	rb_daap_structure_add (msrv, RB_DAAP_CC_MINM, share->priv->name);
-	rb_daap_structure_add (msrv, RB_DAAP_CC_MSAU, share->priv->auth_method);
-	/* authentication method
-	 * 0 is nothing
-	 * 1 is name & password
-	 * 2 is password only
-	 */
-	rb_daap_structure_add (msrv, RB_DAAP_CC_MSLR, 0);
-	rb_daap_structure_add (msrv, RB_DAAP_CC_MSTM, (gint32) DMAP_TIMEOUT);
-	rb_daap_structure_add (msrv, RB_DAAP_CC_MSAL, (gchar) 0);
-	rb_daap_structure_add (msrv, RB_DAAP_CC_MSUP, (gchar) 0);
-	rb_daap_structure_add (msrv, RB_DAAP_CC_MSPI, (gchar) 0);
-	rb_daap_structure_add (msrv, RB_DAAP_CC_MSEX, (gchar) 0);
-	rb_daap_structure_add (msrv, RB_DAAP_CC_MSBR, (gchar) 0);
-	rb_daap_structure_add (msrv, RB_DAAP_CC_MSQY, (gchar) 0);
-	rb_daap_structure_add (msrv, RB_DAAP_CC_MSIX, (gchar) 0);
-	rb_daap_structure_add (msrv, RB_DAAP_CC_MSRS, (gchar) 0);
-	rb_daap_structure_add (msrv, RB_DAAP_CC_MSDC, (gint32) 1);
-
-	message_set_from_rb_daap_structure (message, msrv);
-	rb_daap_structure_destroy (msrv);
-}
-
-static void
-content_codes_cb (SoupServer        *server,
-		  SoupMessage       *message,
-		  const char        *path,
-		  GHashTable        *query,
-		  SoupClientContext *context,
-		  RBDAAPShare       *share)
-{
-/* MCCR content codes response
- * 	MSTT status
- * 	MDCL dictionary
- * 		MCNM content codes number
- * 		MCNA content codes name
- * 		MCTY content codes type
- * 	MDCL dictionary
- * 	...
- */
-	const RBDAAPContentCodeDefinition *defs;
-	guint num_defs = 0;
-	guint i;
-	GNode *mccr;
-
-	defs = rb_daap_content_codes (&num_defs);
-
-	mccr = rb_daap_structure_add (NULL, RB_DAAP_CC_MCCR);
-	rb_daap_structure_add (mccr, RB_DAAP_CC_MSTT, (gint32) DMAP_STATUS_OK);
-
-	for (i = 0; i < num_defs; i++) {
-		GNode *mdcl;
-
-		mdcl = rb_daap_structure_add (mccr, RB_DAAP_CC_MDCL);
-		rb_daap_structure_add (mdcl, RB_DAAP_CC_MCNM, rb_daap_content_code_string_as_int32(defs[i].string));
-		rb_daap_structure_add (mdcl, RB_DAAP_CC_MCNA, defs[i].name);
-		rb_daap_structure_add (mdcl, RB_DAAP_CC_MCTY, (gint32) defs[i].type);
-	}
-
-	message_set_from_rb_daap_structure (message, mccr);
-	rb_daap_structure_destroy (mccr);
-}
-
-static gboolean
-get_session_id (GHashTable *query,
-		guint32    *id)
-{
-	char *session_id_str;
-	guint32 session_id;
-
-	session_id_str = g_hash_table_lookup (query, "session-id");
-	if (session_id_str == NULL) {
-		rb_debug ("session id not found");
-		return FALSE;
-	}
-
-	session_id = (guint32) strtoul (session_id_str, NULL, 10);
-	if (id != NULL) {
-		*id = session_id;
-	}
-	return TRUE;
-}
-
-static gboolean
-get_revision_number (GHashTable *query,
-		     guint *number)
-{
-	char *revision_number_str;
-	guint revision_number;
-
-	revision_number_str = g_hash_table_lookup (query, "revision-number");
-	if (revision_number_str == NULL) {
-		rb_debug ("client asked for an update without a revision number?!?");
-		return FALSE;
-	}
-
-	revision_number = strtoul (revision_number_str, NULL, 10);
-	if (number != NULL) {
-		*number = revision_number;
-	}
-	return TRUE;
-}
-
-static gboolean
-session_id_validate (RBDAAPShare       *share,
-		     SoupClientContext *context,
-		     SoupMessage       *message,
-		     GHashTable        *query,
-		     guint32           *id)
-{
-	guint32     session_id;
-	gboolean    res;
-	const char *addr;
-	const char *remote_address;
-
-	if (id) {
-		*id = 0;
-	}
-
-	res = get_session_id (query, &session_id);
-	if (! res) {
-		rb_debug ("Validation failed: Unable to parse session id from message");
-		return FALSE;
-	}
-
-	/* check hash for remote address */
-	addr = g_hash_table_lookup (share->priv->session_ids, GUINT_TO_POINTER (session_id));
-	if (addr == NULL) {
-		rb_debug ("Validation failed: Unable to lookup session id %u", session_id);
-		return FALSE;
-	}
-
-	remote_address = soup_client_context_get_host (context);
-	rb_debug ("Validating session id %u from %s matches %s",
-		  session_id, remote_address, addr);
-	if (remote_address == NULL || strcmp (addr, remote_address) != 0) {
-		rb_debug ("Validation failed: Remote address does not match stored address");
-		return FALSE;
-	}
-
-	if (id) {
-		*id = session_id;
-	}
-
-	return TRUE;
-}
-
-static guint32
-session_id_generate (RBDAAPShare       *share,
-		     SoupClientContext *context)
-{
-	guint32 id;
-
-	id = g_random_int ();
-
-	return id;
-}
-
-static guint32
-session_id_create (RBDAAPShare       *share,
-		   SoupClientContext *context)
-{
-	guint32     id;
-	const char *addr;
-	char       *remote_address;
-
-	do {
-		/* create a unique session id */
-		id = session_id_generate (share, context);
-		rb_debug ("Generated session id %u", id);
-
-		/* if already used, try again */
-		addr = g_hash_table_lookup (share->priv->session_ids, GUINT_TO_POINTER (id));
-	} while	(addr != NULL);
-
-	/* store session id and remote address */
-	remote_address = g_strdup (soup_client_context_get_host (context));
-	g_hash_table_insert (share->priv->session_ids, GUINT_TO_POINTER (id), remote_address);
-
-	return id;
-}
-
-static void
-session_id_remove (RBDAAPShare       *share,
-		   SoupClientContext *context,
-		   guint32            id)
-{
-	g_hash_table_remove (share->priv->session_ids, GUINT_TO_POINTER (id));
-}
-
-static void
-login_cb (SoupServer        *server,
-	  SoupMessage       *message,
-	  const char        *path,
-	  GHashTable        *query,
-	  SoupClientContext *context,
-	  RBDAAPShare       *share)
-{
-/* MLOG login response
- * 	MSTT status
- * 	MLID session id
- */
-	GNode *mlog;
-	guint32 session_id;
-
-	session_id = session_id_create (share, context);
-
-	rb_debug ("Handling login session id %u", session_id);
-
-	mlog = rb_daap_structure_add (NULL, RB_DAAP_CC_MLOG);
-	rb_daap_structure_add (mlog, RB_DAAP_CC_MSTT, (gint32) DMAP_STATUS_OK);
-	rb_daap_structure_add (mlog, RB_DAAP_CC_MLID, session_id);
-
-	message_set_from_rb_daap_structure (message, mlog);
-	rb_daap_structure_destroy (mlog);
-}
-
-static void
-logout_cb (SoupServer        *server,
-	   SoupMessage       *message,
-	   const char        *path,
-	   GHashTable        *query,
-	   SoupClientContext *context,
-	   RBDAAPShare       *share)
-{
-	int     status;
-	guint32 id;
-
-	if (session_id_validate (share, context, message, query, &id)) {
-		rb_debug ("Handling logout session id %u", id);
-		session_id_remove (share, context, id);
-
-		status = SOUP_STATUS_NO_CONTENT;
-	} else {
-		status = SOUP_STATUS_FORBIDDEN;
-	}
-
-	soup_message_set_status (message, status);
-}
-
-static void
-update_cb (SoupServer        *server,
-	   SoupMessage       *message,
-	   const char        *path,
-	   GHashTable        *query,
-	   SoupClientContext *context,
-	   RBDAAPShare       *share)
-{
-	guint    revision_number;
-	gboolean res;
-
-	res = get_revision_number (query, &revision_number);
-
-	if (res && revision_number != share->priv->revision_number) {
-		/* MUPD update response
-		 * 	MSTT status
-		 * 	MUSR server revision
-		 */
-		GNode *mupd;
-
-		mupd = rb_daap_structure_add (NULL, RB_DAAP_CC_MUPD);
-		rb_daap_structure_add (mupd, RB_DAAP_CC_MSTT, (gint32) DMAP_STATUS_OK);
-		rb_daap_structure_add (mupd, RB_DAAP_CC_MUSR, (gint32) share->priv->revision_number);
-
-		message_set_from_rb_daap_structure (message, mupd);
-		rb_daap_structure_destroy (mupd);
-	} else {
-		/* FIXME: This seems like a bug. It just leaks the
-		 * message (and socket) without ever replying.
-		 */
-		g_object_ref (message);
-		soup_server_pause_message (server, message);
-	}
-}
-
-typedef enum {
-	ITEM_ID = 0,
-	ITEM_NAME,
-	ITEM_KIND,
-	PERSISTENT_ID,
-	CONTAINER_ITEM_ID,
-	SONG_ALBUM,
-	SONG_GROUPING,
-	SONG_ARTIST,
-	SONG_BITRATE,
-	SONG_BPM,
-	SONG_COMMENT,
-	SONG_COMPILATION,
-	SONG_COMPOSER,
-	SONG_DATA_KIND,
-	SONG_DATA_URL,
-	SONG_DATE_ADDED,
-	SONG_DATE_MODIFIED,
-	SONG_DISC_COUNT,
-	SONG_DISC_NUMBER,
-	SONG_DISABLED,
-	SONG_EQ_PRESET,
-	SONG_FORMAT,
-	SONG_GENRE,
-	SONG_DESCRIPTION,
-	SONG_RELATIVE_VOLUME,
-	SONG_SAMPLE_RATE,
-	SONG_SIZE,
-	SONG_START_TIME,
-	SONG_STOP_TIME,
-	SONG_TIME,
-	SONG_TRACK_COUNT,
-	SONG_TRACK_NUMBER,
-	SONG_USER_RATING,
-	SONG_YEAR
-} DAAPMetaData;
-
-struct DAAPMetaDataMap {
-	gchar *tag;
-	DAAPMetaData md;
-};
-
-struct DAAPMetaDataMap meta_data_map[] = {
-	{"dmap.itemid",			ITEM_ID},
-    	{"dmap.itemname",		ITEM_NAME},
-    	{"dmap.itemkind",		ITEM_KIND},
-    	{"dmap.persistentid",		PERSISTENT_ID},
-	{"dmap.containeritemid",	CONTAINER_ITEM_ID},
-    	{"daap.songalbum",		SONG_ALBUM},
-    	{"daap.songartist",		SONG_ARTIST},
-    	{"daap.songbitrate",		SONG_BITRATE},
-    	{"daap.songbeatsperminute",	SONG_BPM},
-    	{"daap.songcomment",		SONG_COMMENT},
-    	{"daap.songcompilation",	SONG_COMPILATION},
-    	{"daap.songcomposer",		SONG_COMPOSER},
-    	{"daap.songdatakind",		SONG_DATA_KIND},
-    	{"daap.songdataurl",		SONG_DATA_URL},
-    	{"daap.songdateadded",		SONG_DATE_ADDED},
-    	{"daap.songdatemodified",	SONG_DATE_MODIFIED},
-    	{"daap.songdescription",	SONG_DESCRIPTION},
-    	{"daap.songdisabled",		SONG_DISABLED},
-    	{"daap.songdisccount",		SONG_DISC_COUNT},
-    	{"daap.songdiscnumber",		SONG_DISC_NUMBER},
-    	{"daap.songeqpreset",		SONG_EQ_PRESET},
-    	{"daap.songformat",		SONG_FORMAT},
-    	{"daap.songgenre",		SONG_GENRE},
-    	{"daap.songgrouping",		SONG_GROUPING},
-    	{"daap.songrelativevolume",	SONG_RELATIVE_VOLUME},
-    	{"daap.songsamplerate",		SONG_SAMPLE_RATE},
-    	{"daap.songsize",		SONG_SIZE},
-    	{"daap.songstarttime",		SONG_START_TIME},
-    	{"daap.songstoptime",		SONG_STOP_TIME},
-   	{"daap.songtime",		SONG_TIME},
-    	{"daap.songtrackcount",		SONG_TRACK_COUNT},
-    	{"daap.songtracknumber",	SONG_TRACK_NUMBER},
-    	{"daap.songuserrating",		SONG_USER_RATING},
-    	{"daap.songyear",		SONG_YEAR}};
-
-typedef unsigned long long bitwise;
-
-struct MLCL_Bits {
-	GNode *mlcl;
-	bitwise bits;
-	gpointer pointer;
-};
-
-static gboolean
-client_requested (bitwise bits,
-		  gint field)
-{
-	return 0 != (bits & (((bitwise) 1) << field));
-}
-
-#define DMAP_ITEM_KIND_AUDIO 2
-#define DAAP_SONG_DATA_KIND_NONE 0
-
-static void
-add_entry_to_mlcl (RhythmDBEntry *entry,
-		   struct MLCL_Bits *mb)
-{
-	GNode *mlit;
-	gint id;
-
-	if (rhythmdb_entry_get_boolean (entry, RHYTHMDB_PROP_HIDDEN))
-		return;
-
-	id = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_ENTRY_ID);
-	mlit = rb_daap_structure_add (mb->mlcl, RB_DAAP_CC_MLIT);
-
-	if (client_requested (mb->bits, ITEM_KIND))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MIKD, (gchar) DMAP_ITEM_KIND_AUDIO);
-	if (client_requested (mb->bits, ITEM_ID))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MIID, (gint32) id);
-	if (client_requested (mb->bits, ITEM_NAME))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MINM, rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE));
-	if (client_requested (mb->bits, PERSISTENT_ID))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MPER, (gint64) id);
-	if (client_requested (mb->bits, CONTAINER_ITEM_ID))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MCTI, (gint32) id);
-	if (client_requested (mb->bits, SONG_DATA_KIND))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASDK, (gchar) DAAP_SONG_DATA_KIND_NONE);
-	if (client_requested (mb->bits, SONG_DATA_URL))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASUL, "");
-	if (client_requested (mb->bits, SONG_ALBUM))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASAL, rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM));
-	if (client_requested (mb->bits, SONG_GROUPING))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_AGRP, "");
-	if (client_requested (mb->bits, SONG_ARTIST))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASAR, rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST));
-	if (client_requested (mb->bits, SONG_BITRATE)) {
-		gulong bitrate = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_BITRATE);
-		if (bitrate != 0)
-			rb_daap_structure_add (mlit, RB_DAAP_CC_ASBR, (gint32) bitrate);
-	}
-	if (client_requested (mb->bits, SONG_BPM))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASBT, (gint32) 0);
-	if (client_requested (mb->bits, SONG_COMMENT))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASCM, "");
-	if (client_requested (mb->bits, SONG_COMPILATION))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASCO, (gchar) FALSE);
-	if (client_requested (mb->bits, SONG_COMPOSER))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASCP, "");
-	if (client_requested (mb->bits, SONG_DATE_ADDED))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASDA, (gint32) rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_FIRST_SEEN));
-	if (client_requested (mb->bits, SONG_DATE_MODIFIED))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASDM, (gint32) rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_MTIME));
-	if (client_requested (mb->bits, SONG_DISC_COUNT))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASDC, (gint32) 0);
-	if (client_requested (mb->bits, SONG_DISC_NUMBER))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASDN, (gint32) rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DISC_NUMBER));
-	if (client_requested (mb->bits, SONG_DISABLED))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASDB, (gchar) FALSE);
-	if (client_requested (mb->bits, SONG_EQ_PRESET))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASEQ, "");
-	if (client_requested (mb->bits, SONG_FORMAT)) {
-		const gchar *filename;
-		gchar *ext;
-
-		filename = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
-		ext = strrchr (filename, '.');
-		if (ext == NULL) {
-			/* FIXME we should use RHYTHMDB_PROP_MIMETYPE instead */
-			ext = "mp3";
-			rb_daap_structure_add (mlit, RB_DAAP_CC_ASFM, ext);
-		} else {
-			ext++;
-			rb_daap_structure_add (mlit, RB_DAAP_CC_ASFM, ext);
-		}
-	}
-	if (client_requested (mb->bits, SONG_GENRE))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASGN, rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_GENRE));
-	if (client_requested (mb->bits, SONG_DESCRIPTION))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASDT, "");
-	if (client_requested (mb->bits, SONG_RELATIVE_VOLUME))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASRV, 0);
-	if (client_requested (mb->bits, SONG_SAMPLE_RATE))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASSR, 0);
-	if (client_requested (mb->bits, SONG_SIZE))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASSZ, (gint32) rhythmdb_entry_get_uint64 (entry, RHYTHMDB_PROP_FILE_SIZE));
-	if (client_requested (mb->bits, SONG_START_TIME))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASST, 0);
-	if (client_requested (mb->bits, SONG_STOP_TIME))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASSP, 0);
-	if (client_requested (mb->bits, SONG_TIME))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASTM, (gint32) (1000 * rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DURATION)));
-	if (client_requested (mb->bits, SONG_TRACK_COUNT))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASTC, 0);
-	if (client_requested (mb->bits, SONG_TRACK_NUMBER))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASTN, (gint32) rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_TRACK_NUMBER));
-	if (client_requested (mb->bits, SONG_USER_RATING))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASUR, 0); /* FIXME */
-	if (client_requested (mb->bits, SONG_YEAR))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ASYR, (gint32) rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_YEAR));
-
-	return;
-}
-
-static void
-add_playlist_to_mlcl (RBPlaylistID *playlist_id,
-		      GNode *mlcl)
-{
- /* 	MLIT listing item
- * 		MIID item id
- * 		MPER persistent item id
- * 		MINM item name
- * 		MIMC item count
- */
-	GNode *mlit;
-	gchar *name;
-	guint num_songs;
-	RhythmDBQueryModel *model;
-
-	g_object_get (playlist_id->source,
-		      "name", &name,
-		      "query-model", &model,
-		      NULL);
-
-	num_songs = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL);
-	g_object_unref (model);
-
-	mlit = rb_daap_structure_add (mlcl, RB_DAAP_CC_MLIT);
-	rb_daap_structure_add (mlit, RB_DAAP_CC_MIID, playlist_id->id);
-	/* we don't have a persistant ID for playlists, unfortunately */
-	rb_daap_structure_add (mlit, RB_DAAP_CC_MPER, (gint64) playlist_id->id);
-	rb_daap_structure_add (mlit, RB_DAAP_CC_MINM, name);
-	rb_daap_structure_add (mlit, RB_DAAP_CC_MIMC, (gint32) num_songs);
-
-	g_free (name);
-
-	return;
-}
-
-static gboolean
-add_playlist_entry_to_mlcl (GtkTreeModel *model,
-			    GtkTreePath *path,
-			    GtkTreeIter *iter,
-			    struct MLCL_Bits *mb)
-{
-	GNode *mlit;
-	RhythmDBEntry *entry;
-	gint id;
-
-	mlit = rb_daap_structure_add (mb->mlcl, RB_DAAP_CC_MLIT);
-
-	gtk_tree_model_get (model, iter, 0, &entry, -1);
-
-	id = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_ENTRY_ID);
-
-	if (client_requested (mb->bits, ITEM_KIND))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MIKD, (gchar) DMAP_ITEM_KIND_AUDIO);
-	if (client_requested (mb->bits, ITEM_ID))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MIID, (gint32) id);
-	if (client_requested (mb->bits, CONTAINER_ITEM_ID))
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MCTI, (gint32) id);
-
-	rhythmdb_entry_unref (entry);
-
-	return FALSE;
-}
-
-static bitwise
-parse_meta_str (const char *attrs)
-{
-	gchar **attrsv;
-	guint i;
-	bitwise bits = 0;
-	
-	attrsv = g_strsplit (attrs, ",", -1);
-
-	for (i = 0; attrsv[i]; i++) {
-		guint j;
-
-		for (j = 0; j < G_N_ELEMENTS (meta_data_map); j++) {
-			if (strcmp (meta_data_map[j].tag, attrsv[i]) == 0) {
-				bits |= (((bitwise) 1) << meta_data_map[j].md);
-			}
-		}
-	}
-	
-	g_strfreev (attrsv);
-
-	return bits;
-}
-
-static bitwise
-parse_meta (GHashTable *query)
-{
-	const gchar *attrs;
-
-	attrs = g_hash_table_lookup (query, "meta");
-	if (attrs == NULL) {
-		return 0;
-	}
-	return parse_meta_str (attrs);
-}
-
-static void
-write_next_chunk (SoupMessage *message, GInputStream *instream)
-{
-	gssize read_size;
-	GError *error = NULL;
-	gchar *chunk = g_malloc (DAAP_SHARE_CHUNK_SIZE);
-
-	read_size = g_input_stream_read (instream, chunk, DAAP_SHARE_CHUNK_SIZE, NULL, &error);
-	if (read_size > 0) {
-		soup_message_body_append (message->response_body, SOUP_MEMORY_TAKE, chunk, read_size);
-	} else {
-		if (error != NULL) {
-			rb_debug ("error reading from input stream: %s", error->message);
-			g_error_free (error);
-		}
-		g_free (chunk);
-		soup_message_body_complete (message->response_body);
-	}
-}
-
-static void
-chunked_message_finished (SoupMessage *message, GInputStream *instream)
-{
-	rb_debug ("finished sending chunked file");
-	g_input_stream_close (instream, NULL, NULL);
-}
-
-static void
-send_chunked_file (SoupMessage *message, RhythmDBEntry *entry, guint64 file_size, guint64 offset)
-{
-	GFile *file;
-	GInputStream *stream;
-	const char *location;
-	GError *error = NULL;
-
-	location = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
-
-	rb_debug ("sending %s chunked from offset %" G_GUINT64_FORMAT, location, offset);
-	file = g_file_new_for_uri (location);
-	stream = G_INPUT_STREAM (g_file_read (file, NULL, &error));
-	if (error != NULL) {
-		rb_debug ("couldn't open %s: %s", location, error->message);
-		g_error_free (error);
-		soup_message_set_status (message, SOUP_STATUS_INTERNAL_SERVER_ERROR);
-		return;
-	}
-
-	if (offset != 0) {
-		if (g_seekable_seek (G_SEEKABLE (stream), offset, G_SEEK_SET, NULL, &error) == FALSE) {
-			g_warning ("error seeking: %s", error->message);
-			g_input_stream_close (stream, NULL, NULL);
-			soup_message_set_status (message, SOUP_STATUS_INTERNAL_SERVER_ERROR);
-			return;
-		}
-		file_size -= offset;
-	}
-
-	soup_message_headers_set_encoding (message->response_headers, SOUP_ENCODING_CHUNKED);
-
-	g_signal_connect (message, "wrote_chunk", G_CALLBACK (write_next_chunk), stream);
-	g_signal_connect (message, "finished", G_CALLBACK (chunked_message_finished), stream);
-	write_next_chunk (message, stream);
-}
-
-static void
-mapped_file_message_finished (SoupMessage *message, GMappedFile *file)
-{
-	rb_debug ("finished sending mmapped file");
-	g_mapped_file_free (file);
-}
-
-static void
-send_mapped_file (SoupMessage *message, RhythmDBEntry *entry, guint64 file_size, guint64 offset)
-{
-	GFile *file;
-	GMappedFile *mapped_file;
-	char *path;
-	GError *error = NULL;
-
-	file = g_file_new_for_uri (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
-	path = g_file_get_path (file);
-	if (path == NULL) {
-		rb_debug ("couldn't send %s mmapped: couldn't get path", path);
-		soup_message_set_status (message, SOUP_STATUS_INTERNAL_SERVER_ERROR);
-		g_object_unref (file);
-		return;
-	}
-	g_object_unref (file);
-	rb_debug ("sending file %s mmapped, from offset %" G_GUINT64_FORMAT, path, offset);
-
-	mapped_file = g_mapped_file_new (path, FALSE, &error);
-	if (mapped_file == NULL) {
-		g_warning ("Unable to map file %s: %s", path, error->message);
-		soup_message_set_status (message, SOUP_STATUS_INTERNAL_SERVER_ERROR);
-	} else {
-		soup_message_set_response (message, "application/x-dmap-tagged",
-					   SOUP_MEMORY_TEMPORARY,
-					   g_mapped_file_get_contents (mapped_file) + offset,
-					   file_size);
-
-		g_signal_connect (message,
-				  "finished",
-				  G_CALLBACK (mapped_file_message_finished),
-				  mapped_file);
-	}
-	g_free (path);
-}
-
-static void
-databases_cb (SoupServer        *server,
-	      SoupMessage       *message,
-	      const char        *path,
-	      GHashTable        *query,
-	      SoupClientContext *context,
-	      RBDAAPShare       *share)
-
-{
-	const char *rest_of_path;
-	/*guint revision_number;*/
-
-	if (! session_id_validate (share, context, message, query, NULL)) {
-		soup_message_set_status (message, SOUP_STATUS_FORBIDDEN);
-		return;
-	}
-
-	rest_of_path = strchr (path + 1, '/');
-
-	if (rest_of_path == NULL) {
-	/* AVDB server databases
-	 * 	MSTT status
-	 * 	MUTY update type
-	 * 	MTCO specified total count
-	 * 	MRCO returned count
-	 * 	MLCL listing
-	 * 		MLIT listing item
-	 * 			MIID item id
-	 * 			MPER persistent id
-	 * 			MINM item name
-	 * 			MIMC item count
-	 * 			MCTC container count
-	 */
-		GNode *avdb;
-		GNode *mlcl;
-		GNode *mlit;
-
-		avdb = rb_daap_structure_add (NULL, RB_DAAP_CC_AVDB);
-		rb_daap_structure_add (avdb, RB_DAAP_CC_MSTT, (gint32) DMAP_STATUS_OK);
-		rb_daap_structure_add (avdb, RB_DAAP_CC_MUTY, 0);
-		rb_daap_structure_add (avdb, RB_DAAP_CC_MTCO, (gint32) 1);
-		rb_daap_structure_add (avdb, RB_DAAP_CC_MRCO, (gint32) 1);
-		mlcl = rb_daap_structure_add (avdb, RB_DAAP_CC_MLCL);
-		mlit = rb_daap_structure_add (mlcl, RB_DAAP_CC_MLIT);
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MIID, (gint32) 1);
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MPER, (gint64) 1);
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MINM, share->priv->name);
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MIMC, (gint32) rhythmdb_entry_count_by_type (share->priv->db, share->priv->entry_type));
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MCTC, (gint32) 1);
-
-		message_set_from_rb_daap_structure (message, avdb);
-		rb_daap_structure_destroy (avdb);
-	} else if (g_ascii_strcasecmp ("/1/items", rest_of_path) == 0) {
-	/* ADBS database songs
-	 * 	MSTT status
-	 * 	MUTY update type
-	 * 	MTCO specified total count
-	 * 	MRCO returned count
-	 * 	MLCL listing
-	 * 		MLIT
-	 * 			attrs
-	 * 		MLIT
-	 * 		...
-	 */
-		GNode *adbs;
-		gint32 num_songs = rhythmdb_entry_count_by_type (share->priv->db, share->priv->entry_type);
-		struct MLCL_Bits mb = {NULL,0};
-
-		mb.bits = parse_meta (query);
-
-		adbs = rb_daap_structure_add (NULL, RB_DAAP_CC_ADBS);
-		rb_daap_structure_add (adbs, RB_DAAP_CC_MSTT, (gint32) DMAP_STATUS_OK);
-		rb_daap_structure_add (adbs, RB_DAAP_CC_MUTY, 0);
-		rb_daap_structure_add (adbs, RB_DAAP_CC_MTCO, (gint32) num_songs);
-		rb_daap_structure_add (adbs, RB_DAAP_CC_MRCO, (gint32) num_songs);
-		mb.mlcl = rb_daap_structure_add (adbs, RB_DAAP_CC_MLCL);
-
-		rhythmdb_entry_foreach_by_type (share->priv->db, share->priv->entry_type, (GFunc) add_entry_to_mlcl, &mb);
-
-		message_set_from_rb_daap_structure (message, adbs);
-		rb_daap_structure_destroy (adbs);
-		adbs = NULL;
-	} else if (g_ascii_strcasecmp ("/1/containers", rest_of_path) == 0) {
-	/* APLY database playlists
-	 * 	MSTT status
-	 * 	MUTY update type
-	 * 	MTCO specified total count
-	 * 	MRCO returned count
-	 * 	MLCL listing
-	 * 		MLIT listing item
-	 * 			MIID item id
-	 * 			MPER persistent item id
-	 * 			MINM item name
-	 * 			MIMC item count
-	 * 			ABPL baseplaylist (only for base)
-	 * 		MLIT
-	 * 		...
-	 */
-		GNode *aply;
-		GNode *mlcl;
-		GNode *mlit;
-
-		aply = rb_daap_structure_add (NULL, RB_DAAP_CC_APLY);
-		rb_daap_structure_add (aply, RB_DAAP_CC_MSTT, (gint32) DMAP_STATUS_OK);
-		rb_daap_structure_add (aply, RB_DAAP_CC_MUTY, 0);
-		rb_daap_structure_add (aply, RB_DAAP_CC_MTCO, (gint32) 1);
-		rb_daap_structure_add (aply, RB_DAAP_CC_MRCO, (gint32) 1);
-		mlcl = rb_daap_structure_add (aply, RB_DAAP_CC_MLCL);
-		mlit = rb_daap_structure_add (mlcl, RB_DAAP_CC_MLIT);
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MIID, (gint32) 1);
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MPER, (gint64) 1);
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MINM, share->priv->name);
-		rb_daap_structure_add (mlit, RB_DAAP_CC_MIMC, (gint32) rhythmdb_entry_count_by_type (share->priv->db, share->priv->entry_type));
-		rb_daap_structure_add (mlit, RB_DAAP_CC_ABPL, (gchar) 1); /* base playlist */
-
-		g_list_foreach (share->priv->playlist_ids, (GFunc) add_playlist_to_mlcl, mlcl);
-
-		message_set_from_rb_daap_structure (message, aply);
-		rb_daap_structure_destroy (aply);
-
-	} else if (g_ascii_strncasecmp ("/1/containers/", rest_of_path, 14) == 0) {
-	/* APSO playlist songs
-	 * 	MSTT status
-	 * 	MUTY update type
-	 * 	MTCO specified total count
-	 * 	MRCO returned count
-	 * 	MLCL listing
-	 * 		MLIT listing item
-	 * 			MIKD item kind
-	 * 			MIID item id
-	 * 			MCTI container item id
-	 * 		MLIT
-	 * 		...
-	 */
-		GNode *apso;
-		struct MLCL_Bits mb = {NULL,0};
-		gint pl_id = atoi (rest_of_path + 14);
-
-		mb.bits = parse_meta (query);
-
-		apso = rb_daap_structure_add (NULL, RB_DAAP_CC_APSO);
-		rb_daap_structure_add (apso, RB_DAAP_CC_MSTT, (gint32) DMAP_STATUS_OK);
-		rb_daap_structure_add (apso, RB_DAAP_CC_MUTY, 0);
-
-		if (pl_id == 1) {
-			gint32 num_songs = (gint32) rhythmdb_entry_count_by_type (share->priv->db, share->priv->entry_type);
-			rb_daap_structure_add (apso, RB_DAAP_CC_MTCO, (gint32) num_songs);
-			rb_daap_structure_add (apso, RB_DAAP_CC_MRCO, (gint32) num_songs);
-			mb.mlcl = rb_daap_structure_add (apso, RB_DAAP_CC_MLCL);
-
-			rhythmdb_entry_foreach_by_type (share->priv->db,
-							share->priv->entry_type,
-							(GFunc) add_entry_to_mlcl,
-							&mb);
-		} else {
-			RBPlaylistID *id;
-			GList *idl;
-			guint num_songs;
-			RhythmDBQueryModel *model;
-
-			idl = g_list_find_custom (share->priv->playlist_ids,
-						  GINT_TO_POINTER (pl_id),
-						  _find_by_id);
-			if (idl == NULL) {
-				soup_message_set_status (message, SOUP_STATUS_NOT_FOUND);
-				return;
-			}
-			id = (RBPlaylistID *)idl->data;
-
-			mb.mlcl = rb_daap_structure_add (apso, RB_DAAP_CC_MLCL);
-
-			g_object_get (id->source, "base-query-model", &model, NULL);
-			num_songs = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL);
-
-			rb_daap_structure_add (apso, RB_DAAP_CC_MTCO, (gint32) num_songs);
-			rb_daap_structure_add (apso, RB_DAAP_CC_MRCO, (gint32) num_songs);
-
-			gtk_tree_model_foreach (GTK_TREE_MODEL (model), (GtkTreeModelForeachFunc) add_playlist_entry_to_mlcl, &mb);
-			g_object_unref (model);
-		}
-
-		message_set_from_rb_daap_structure (message, apso);
-		rb_daap_structure_destroy (apso);
-	} else if (g_ascii_strncasecmp ("/1/items/", rest_of_path, 9) == 0) {
-	/* just the file :) */
-		const gchar *id_str;
-		gint id;
-		RhythmDBEntry *entry;
-		const gchar *location;
-		const gchar *range_header;
-		guint64 file_size;
-		guint64 offset = 0;
-
-		id_str = rest_of_path + 9;
-		id = atoi (id_str);
-
-		entry = rhythmdb_entry_lookup_by_id (share->priv->db, id);
-		location = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
-		file_size = rhythmdb_entry_get_uint64 (entry, RHYTHMDB_PROP_FILE_SIZE);
-
-		message_add_standard_headers (message);
-		soup_message_headers_append (message->response_headers, "Accept-Ranges", "bytes");
-
-		range_header = soup_message_headers_get (message->request_headers, "Range");
-		if (range_header) {
-			const gchar *s;
-			gchar *content_range;
-
-			s = range_header + 6; /* bytes= */
-			offset = atoll (s);
-
-			content_range = g_strdup_printf ("bytes %" G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, offset, file_size, file_size);
-			soup_message_headers_append (message->response_headers, "Content-Range", content_range);
-			g_free (content_range);
-
-			soup_message_set_status (message, SOUP_STATUS_PARTIAL_CONTENT);
-			file_size -= offset;
-		} else {
-			soup_message_set_status (message, SOUP_STATUS_OK);
-		}
-
-		/* don't use chunked transfers if we can send the file mmapped,
-		 * as itunes clients can't seek properly when we do.
-		 */
-		if (rb_uri_is_local (location)) {
-			send_mapped_file (message, entry, file_size, offset);
-		} else {
-			send_chunked_file (message, entry, file_size, offset);
-		}
-	} else {
-		rb_debug ("unhandled: %s\n", path);
-	}
-}
-
-static void
-db_entry_added_cb (RhythmDB *db,
-		   RhythmDBEntry *entry,
-		   RBDAAPShare *share)
-{
-	/* TODO: update our db version number? */
-}
-
-static void
-add_db_entry (RhythmDBEntry *entry,
-	      RBDAAPShare *share)
-{
-	db_entry_added_cb (share->priv->db, entry, share);
-}
-
-static void
-db_entry_deleted_cb (RhythmDB *db,
-		     RhythmDBEntry *entry,
-		     RBDAAPShare *share)
-{
-	/* TODO: update our db version number? */
-}
-
-static void
-db_entry_changed_cb (RhythmDB *db,
-		     RhythmDBEntry *entry,
-		     GSList *changes,
-		     RBDAAPShare *share)
-{
-	if (rhythmdb_entry_get_boolean (entry, RHYTHMDB_PROP_HIDDEN)) {
-		db_entry_deleted_cb (db, entry, share);
-	} else {
-		db_entry_added_cb (db, entry, share);
-	}
-}
-
-static gboolean
-soup_auth_filter (SoupAuthDomain *auth_domain,
-		  SoupMessage    *msg,
-		  gpointer        user_data)
-{
-	const char *path;
-
-	path = soup_message_get_uri (msg)->path;
-	if (g_str_has_prefix (path, "/databases/")) {
-		/* Subdirectories of /databases don't actually require
-		 * authentication
-		 */
-		return FALSE;
-	} else {
-		/* Everything else in auth_domain's paths, including
-		 * /databases itself, does require auth.
-		 */
-		return TRUE;
-	}
-}
-
-static gboolean
-soup_auth_callback (SoupAuthDomain *auth_domain,
-		    SoupMessage    *msg,
-		    const char     *username,
-		    gpointer        password,
-		    RBDAAPShare    *share)
-{
-	gboolean    allowed;
-	const char *path;
-
-	path = soup_message_get_uri (msg)->path;
-	rb_debug ("Auth request for %s, user %s", path, username);
-
-	allowed = !strcmp (password, share->priv->password);
-	rb_debug ("Auth request: %s", allowed ? "ALLOWED" : "DENIED");
-
-	return allowed;
-}
-
-static gboolean
-rb_daap_share_server_start (RBDAAPShare *share)
-{
-	int                   port = STANDARD_DAAP_PORT;
-	gboolean              password_required;
-
-	share->priv->server = soup_server_new (SOUP_SERVER_PORT, port, NULL);
-	if (share->priv->server == NULL) {
-		rb_debug ("Unable to start music sharing server on port %d, trying any open port", port);
-		share->priv->server = soup_server_new (SOUP_SERVER_PORT, SOUP_ADDRESS_ANY_PORT, NULL);
-
-		if (share->priv->server == NULL) {
-			g_warning ("Unable to start music sharing server");
-			return FALSE;
-		}
-	}
-
-	share->priv->port = (guint)soup_server_get_port (share->priv->server);
-	rb_debug ("Started DAAP server on port %u", share->priv->port);
-
-	password_required = (share->priv->auth_method != RB_DAAP_SHARE_AUTH_METHOD_NONE);
-
-	if (password_required) {
-		SoupAuthDomain *auth_domain;
-
-		auth_domain = soup_auth_domain_basic_new (SOUP_AUTH_DOMAIN_REALM, "Music Sharing",
-							  SOUP_AUTH_DOMAIN_ADD_PATH, "/login",
-							  SOUP_AUTH_DOMAIN_ADD_PATH, "/update",
-							  SOUP_AUTH_DOMAIN_ADD_PATH, "/database",
-							  SOUP_AUTH_DOMAIN_FILTER, soup_auth_filter,
-							  NULL);
-		soup_auth_domain_basic_set_auth_callback (auth_domain,
-							  (SoupAuthDomainBasicAuthCallback)soup_auth_callback,
-							  g_object_ref (share),
-							  g_object_unref);
-		soup_server_add_auth_domain (share->priv->server, auth_domain);
-	}
-
-	soup_server_add_handler (share->priv->server, "/server-info",
-				 (SoupServerCallback) server_info_cb,
-				 share, NULL);
-	soup_server_add_handler (share->priv->server, "/content-codes",
-				 (SoupServerCallback) content_codes_cb,
-				 share, NULL);
-	soup_server_add_handler (share->priv->server, "/login",
-				 (SoupServerCallback) login_cb,
-				 share, NULL);
-	soup_server_add_handler (share->priv->server, "/logout",
-				 (SoupServerCallback) logout_cb,
-				 share, NULL);
-	soup_server_add_handler (share->priv->server, "/update",
-				 (SoupServerCallback) update_cb,
-				 share, NULL);
-	soup_server_add_handler (share->priv->server, "/databases",
-				 (SoupServerCallback) databases_cb,
-				 share, NULL);
-	soup_server_run_async (share->priv->server);
-
-	/* using direct since there is no g_uint_hash or g_uint_equal */
-	share->priv->session_ids = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
-
-	share->priv->next_playlist_id = 2;		/* 1 already used */
-
-	rhythmdb_entry_foreach (share->priv->db, (GFunc)add_db_entry, share);
-
-	share->priv->entry_added_id = g_signal_connect (G_OBJECT (share->priv->db),
-							"entry-added",
-							G_CALLBACK (db_entry_added_cb),
-							share);
-	share->priv->entry_deleted_id = g_signal_connect (G_OBJECT (share->priv->db),
-							  "entry-deleted",
-							  G_CALLBACK (db_entry_deleted_cb),
-							  share);
-	share->priv->entry_changed_id = g_signal_connect (G_OBJECT (share->priv->db),
-							  "entry-changed",
-							  G_CALLBACK (db_entry_changed_cb),
-							  share);
-
-	share->priv->server_active = TRUE;
-
-	return TRUE;
-}
-
-static gboolean
-rb_daap_share_server_stop (RBDAAPShare *share)
-{
-	rb_debug ("Stopping music sharing server on port %d", share->priv->port);
-
-	if (share->priv->server) {
-		soup_server_quit (share->priv->server);
-		g_object_unref (share->priv->server);
-		share->priv->server = NULL;
-	}
-
-	if (share->priv->session_ids) {
-		g_hash_table_destroy (share->priv->session_ids);
-		share->priv->session_ids = NULL;
-	}
-
-	if (share->priv->entry_added_id != 0) {
-		g_signal_handler_disconnect (share->priv->db, share->priv->entry_added_id);
-		share->priv->entry_added_id = 0;
-	}
-
-	if (share->priv->entry_deleted_id != 0) {
-		g_signal_handler_disconnect (share->priv->db, share->priv->entry_deleted_id);
-		share->priv->entry_deleted_id = 0;
-	}
-
-	if (share->priv->entry_changed_id != 0) {
-		g_signal_handler_disconnect (share->priv->db, share->priv->entry_changed_id);
-		share->priv->entry_changed_id = 0;
-	}
-
-	share->priv->server_active = FALSE;
-
-	return TRUE;
-}
-
-static gboolean
-rb_daap_share_publish_start (RBDAAPShare *share)
-{
-	GError  *error;
-	gboolean res;
-	gboolean password_required;
-
-	password_required = (share->priv->auth_method != RB_DAAP_SHARE_AUTH_METHOD_NONE);
-
-	error = NULL;
-	res = rb_daap_mdns_publisher_publish (share->priv->publisher,
-					      share->priv->name,
-					      share->priv->port,
-					      password_required,
-					      &error);
-
-	if (res == FALSE) {
-		if (error != NULL) {
-			g_warning ("Unable to notify network of music sharing: %s", error->message);
-			g_error_free (error);
-		} else {
-			g_warning ("Unable to notify network of music sharing");
-		}
-		return FALSE;
-	} else {
-		rb_debug ("Published DAAP server information to mdns");
-	}
-
-	return TRUE;
-}
-
-static gboolean
-rb_daap_share_publish_stop (RBDAAPShare *share)
-{
-	if (share->priv->publisher) {
-		gboolean res;
-		GError  *error;
-		error = NULL;
-		res = rb_daap_mdns_publisher_withdraw (share->priv->publisher, &error);
-		if (error != NULL) {
-			g_warning ("Unable to withdraw music sharing service: %s", error->message);
-			g_error_free (error);
-		}
-		return res;
-	}
-
-	share->priv->published = FALSE;
-	return TRUE;
-}
-
-static void
-rb_daap_share_restart (RBDAAPShare *share)
-{
-	gboolean res;
-
-	rb_daap_share_server_stop (share);
-	res = rb_daap_share_server_start (share);
-	if (res) {
-		/* To update information just publish again */
-		rb_daap_share_publish_start (share);
-	} else {
-		rb_daap_share_publish_stop (share);
-	}
-}
-
-static void
-rb_daap_share_maybe_restart (RBDAAPShare *share)
-{
-	if (share->priv->published) {
-		rb_daap_share_restart (share);
-	}
-}
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-share.h rhythmbox-0.12.1/plugins/daap/rb-daap-share.h
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-share.h	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-share.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,68 +0,0 @@
-/*
- *  Header for DAAP (iTunes Music Sharing) sharing
- *
- *  Copyright (C) 2005 Charles Schmidt <cschmidt2@emich.edu>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The Rhythmbox authors hereby grant permission for non-GPL compatible
- *  GStreamer plugins to be used and distributed together with GStreamer
- *  and Rhythmbox. This permission is above and beyond the permissions granted
- *  by the GPL license by which Rhythmbox is covered. If you modify this code
- *  you may extend this exception to your version of the code, but you are not
- *  obligated to do so. If you do not wish to do so, delete this exception
- *  statement from your version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#ifndef __RB_DAAP_SHARE_H
-#define __RB_DAAP_SHARE_H
-
-#include <glib-object.h>
-#include "rhythmdb.h"
-#include "rb-playlist-manager.h"
-
-G_BEGIN_DECLS
-
-#define RB_TYPE_DAAP_SHARE         (rb_daap_share_get_type ())
-#define RB_DAAP_SHARE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_DAAP_SHARE, RBDAAPShare))
-#define RB_DAAP_SHARE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_DAAP_SHARE, RBDAAPShareClass))
-#define RB_IS_DAAP_SHARE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_DAAP_SHARE))
-#define RB_IS_DAAP_SHARE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_DAAP_SHARE))
-#define RB_DAAP_SHARE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_DAAP_SHARE, RBDAAPShareClass))
-
-typedef struct RBDAAPSharePrivate RBDAAPSharePrivate;
-
-typedef struct {
-	GObject parent;
-
-	RBDAAPSharePrivate *priv;
-} RBDAAPShare;
-
-typedef struct {
-	GObjectClass parent;
-} RBDAAPShareClass;
-
-GType         rb_daap_share_get_type (void);
-
-RBDAAPShare * rb_daap_share_new      (const char *name,
-                                      const char *password,
-                                      RhythmDB *db,
-				      RhythmDBEntryType entry_type,
-                                      RBPlaylistManager *playlist_manager);
-
-#endif /* __RB_DAAP_SHARE_H */
-
-G_END_DECLS
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-sharing.c rhythmbox-0.12.1/plugins/daap/rb-daap-sharing.c
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-sharing.c	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-sharing.c	2009-08-15 18:16:18.000000000 -0400
@@ -36,14 +36,16 @@
 #include <glib/gprintf.h>
 
 #include "rb-daap-sharing.h"
-#include "rb-daap-share.h"
+#include "rb-dmap-db-adapter.h"
 #include "rb-debug.h"
 #include "rb-dialog.h"
 #include "rb-playlist-manager.h"
 #include "eel-gconf-extensions.h"
 #include "rb-preferences.h"
 
-static RBDAAPShare *share = NULL;
+#include <libdmapsharing/dmap.h>
+
+static DAAPShare *share = NULL;
 static guint enable_sharing_notify_id = EEL_GCONF_UNDEFINED_CONNECTION;
 static guint require_password_notify_id = EEL_GCONF_UNDEFINED_CONNECTION;
 static guint share_name_notify_id = EEL_GCONF_UNDEFINED_CONNECTION;
@@ -65,7 +67,9 @@
 static void
 create_share (RBShell *shell)
 {
-	RhythmDB *db;
+	RhythmDB *rdb;
+	DMAPDb *db;
+	DMAPContainerDb *container_db;
 	RBPlaylistManager *playlist_manager;
 	char *name;
 	char *password;
@@ -81,8 +85,11 @@
 	}
 
 	g_object_get (shell,
-		      "db", &db,
+		      "db", &rdb,
 		      "playlist-manager", &playlist_manager, NULL);
+	/* FIXME: NULL for sharing entry type for browsing */
+	db = DMAP_DB (rb_dmap_db_adapter_new (rdb, NULL));
+	container_db = DMAP_CONTAINER_DB (rb_dmap_container_db_new ());
 
 	require_password = eel_gconf_get_boolean (CONF_DAAP_REQUIRE_PASSWORD);
 	if (require_password) {
@@ -91,9 +98,9 @@
 		password = NULL;
 	}
 
-	share = rb_daap_share_new (name, password, db, RHYTHMDB_ENTRY_TYPE_SONG, playlist_manager);
+	share = daap_share_new (name, password, db, container_db, NULL);
 
-	g_object_unref (db);
+	g_object_unref (rdb);
 	g_object_unref (playlist_manager);
 
 	g_free (name);
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-source.c rhythmbox-0.12.1/plugins/daap/rb-daap-source.c
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-source.c	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-source.c	2009-08-11 23:24:57.000000000 -0400
@@ -54,14 +54,15 @@
 #include "rb-dialog.h"
 #include "rb-preferences.h"
 #include "rb-daap-src.h"
+#include "rb-daap-record-factory.h"
 
-#include "rb-daap-connection.h"
-#include "rb-daap-mdns-browser.h"
 #include "rb-daap-dialog.h"
 #include "rb-daap-plugin.h"
 
 #include "rb-static-playlist-source.h"
 
+#include <libdmapsharing/dmap.h>
+
 static void rb_daap_source_dispose (GObject *object);
 static void rb_daap_source_set_property  (GObject *object,
 					  guint prop_id,
@@ -460,7 +461,7 @@
 #endif
 
 static char *
-connection_auth_cb (RBDAAPConnection *connection,
+connection_auth_cb (DAAPConnection   *connection,
 		    const char       *name,
 		    RBDAAPSource     *source)
 {
@@ -508,8 +509,8 @@
 }
 
 static void
-connection_connecting_cb (RBDAAPConnection     *connection,
-			  RBDAAPConnectionState state,
+connection_connecting_cb (DAAPConnection       *connection,
+			  DMAPConnectionState   state,
 			  float		        progress,
 			  RBDAAPSource         *source)
 {
@@ -520,20 +521,20 @@
 	rb_debug ("DAAP connection status: %d/%f", state, progress);
 
 	switch (state) {
-	case DAAP_GET_INFO:
-	case DAAP_GET_PASSWORD:
-	case DAAP_LOGIN:
+	case DMAP_GET_INFO:
+	case DMAP_GET_PASSWORD:
+	case DMAP_LOGIN:
 		source->priv->connection_status = _("Connecting to music share");
 		break;
-	case DAAP_GET_REVISION_NUMBER:
-	case DAAP_GET_DB_INFO:
-	case DAAP_GET_SONGS:
-	case DAAP_GET_PLAYLISTS:
-	case DAAP_GET_PLAYLIST_ENTRIES:
+	case DMAP_GET_REVISION_NUMBER:
+	case DMAP_GET_DB_INFO:
+	case DMAP_GET_SONGS:
+	case DMAP_GET_PLAYLISTS:
+	case DMAP_GET_PLAYLIST_ENTRIES:
 		source->priv->connection_status = _("Retrieving songs from music share");
 		break;
-	case DAAP_LOGOUT:
-	case DAAP_DONE:
+	case DMAP_LOGOUT:
+	case DMAP_DONE:
 		source->priv->connection_status = NULL;
 		break;
 	}
@@ -542,7 +543,7 @@
 
 	rb_source_notify_status_changed (RB_SOURCE (source));
 
-	is_connected = rb_daap_connection_is_connected (connection);
+	is_connected = dmap_connection_is_connected (DMAP_CONNECTION (connection));
 
 	g_object_get (source, "plugin", &plugin, NULL);
 	g_assert (plugin != NULL);
@@ -559,7 +560,7 @@
 }
 
 static void
-connection_disconnected_cb (RBDAAPConnection *connection,
+connection_disconnected_cb (DAAPConnection   *connection,
 			    RBDAAPSource     *source)
 {
 	GdkPixbuf *icon;
@@ -601,7 +602,7 @@
 }
 
 static void
-rb_daap_source_connection_cb (RBDAAPConnection *connection,
+rb_daap_source_connection_cb (DAAPConnection   *connection,
 			      gboolean          result,
 			      const char       *reason,
 			      RBSource         *source)
@@ -632,9 +633,9 @@
 		      "shell", &shell,
 		      "entry-type", &entry_type,
 		      NULL);
-	playlists = rb_daap_connection_get_playlists (RB_DAAP_CONNECTION (daap_source->priv->connection));
+	playlists = dmap_connection_get_playlists (DMAP_CONNECTION (daap_source->priv->connection));
 	for (l = playlists; l != NULL; l = g_slist_next (l)) {
-		RBDAAPPlaylist *playlist = l->data;
+		DMAPPlaylist *playlist = l->data;
 		RBSource *playlist_source;
 		char *sorting_name;
 
@@ -659,7 +660,9 @@
 {
 	RBDAAPSource *daap_source = RB_DAAP_SOURCE (source);
 	RBShell *shell = NULL;
-	RhythmDB *db = NULL;
+	DMAPRecordFactory *factory;
+	RhythmDB *rdb = NULL;
+	DMAPDb *db = NULL;
 	char *name = NULL;
 	RhythmDBEntryType type;
 
@@ -669,17 +672,22 @@
 
 	g_object_get (daap_source,
 		      "shell", &shell,
-		      "entry-type", &type,
 		      "name", &name,
+		      "entry-type", &type,
 		      NULL);
-	g_object_get (shell, "db", &db, NULL);
+	g_object_get (shell, "db", &rdb, NULL);
+	db = DMAP_DB (rb_dmap_db_adapter_new (rdb, type));
+
+	factory = DMAP_RECORD_FACTORY (rb_daap_record_factory_new ());
 
-	daap_source->priv->connection = rb_daap_connection_new (name,
+	/* FIXME: Arg 4 was priv->password_protected, but this is not
+	 * what daap_connection_new expects. */
+	daap_source->priv->connection = daap_connection_new (name,
 								daap_source->priv->host,
 								daap_source->priv->port,
-								daap_source->priv->password_protected,
+								NULL,
 								db,
-								type);
+								factory);
         g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, type);
 	g_object_add_weak_pointer (G_OBJECT (daap_source->priv->connection), (gpointer *)&daap_source->priv->connection);
 
@@ -698,16 +706,16 @@
                           G_CALLBACK (connection_disconnected_cb),
 			  source);
 
-	rb_daap_connection_connect (RB_DAAP_CONNECTION (daap_source->priv->connection),
-				    (RBDAAPConnectionCallback) rb_daap_source_connection_cb,
+	dmap_connection_connect (DMAP_CONNECTION (daap_source->priv->connection),
+				    (DMAPConnectionCallback) rb_daap_source_connection_cb,
 				    source);
 
-	g_object_unref (G_OBJECT (db));
+	g_object_unref (G_OBJECT (rdb));
 	g_object_unref (G_OBJECT (shell));
 }
 
 static void
-rb_daap_source_disconnect_cb (RBDAAPConnection *connection,
+rb_daap_source_disconnect_cb (DAAPConnection   *connection,
 			      gboolean          result,
 			      const char       *reason,
 			      RBSource         *source)
@@ -772,8 +780,8 @@
 
 	/* keep the source alive until the disconnect completes */
 	g_object_ref (daap_source);
-	rb_daap_connection_disconnect (daap_source->priv->connection,
-				       (RBDAAPConnectionCallback) rb_daap_source_disconnect_cb,
+	dmap_connection_disconnect (daap_source->priv->connection,
+				       (DMAPConnectionCallback) rb_daap_source_disconnect_cb,
 				       daap_source);
 
 	/* wait until disconnected */
@@ -804,7 +812,7 @@
 		return NULL;
 	}
 
-	return rb_daap_connection_get_headers (source->priv->connection, uri, bytes);
+	return dmap_connection_get_headers (source->priv->connection, uri, bytes);
 }
 
 static char *
@@ -864,4 +872,3 @@
 
 	return g_strdup (location);
 }
-
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-structure.c rhythmbox-0.12.1/plugins/daap/rb-daap-structure.c
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-structure.c	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-structure.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,749 +0,0 @@
-/*
- *  Header for DAAP (iTunes Music Sharing) structures
- *
- *  Copyright (C) 2004,2005 Charles Schmidt <cschmidt2@emich.edu>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The Rhythmbox authors hereby grant permission for non-GPL compatible
- *  GStreamer plugins to be used and distributed together with GStreamer
- *  and Rhythmbox. This permission is above and beyond the permissions granted
- *  by the GPL license by which Rhythmbox is covered. If you modify this code
- *  you may extend this exception to your version of the code, but you are not
- *  obligated to do so. If you do not wish to do so, delete this exception
- *  statement from your version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#include "config.h"
-
-#include <glib.h>
-#include <glib-object.h>
-#include <gobject/gvaluecollector.h>
-#include "rb-daap-structure.h"
-#include "rb-debug.h"
-
-#include <gst/gstutils.h>
-
-#include <string.h>
-#include <stdarg.h>
-
-#define MAKE_CONTENT_CODE(ch0, ch1, ch2, ch3) \
-    (( (gint32)(gchar)(ch0) | ( (gint32)(gchar)(ch1) << 8 ) | \
-    ( (gint32)(gchar)(ch2) << 16 ) | \
-    ( (gint32)(gchar)(ch3) << 24 ) ))
-
-static const RBDAAPContentCodeDefinition cc_defs[] = {
-	{RB_DAAP_CC_MDCL, MAKE_CONTENT_CODE('m','d','c','l'), "dmap.dictionary", "mdcl", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_MSTT, MAKE_CONTENT_CODE('m','s','t','t'), "dmap.status", "mstt", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_MIID, MAKE_CONTENT_CODE('m','i','i','d'), "dmap.itemid", "miid", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_MINM, MAKE_CONTENT_CODE('m','i','n','m'), "dmap.itemname", "minm", RB_DAAP_TYPE_STRING},
-	{RB_DAAP_CC_MIKD, MAKE_CONTENT_CODE('m','i','k','d'), "dmap.itemkind", "mikd", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_MPER, MAKE_CONTENT_CODE('m','p','e','r'), "dmap.persistentid", "mper", RB_DAAP_TYPE_INT64},
-	{RB_DAAP_CC_MCON, MAKE_CONTENT_CODE('m','c','o','n'), "dmap.container", "mcon", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_MCTI, MAKE_CONTENT_CODE('m','c','t','i'), "dmap.containeritemid", "mcti", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_MPCO, MAKE_CONTENT_CODE('m','p','c','o'), "dmap.parentcontainerid", "mpco", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_MSTS, MAKE_CONTENT_CODE('m','s','t','s'), "dmap.statusstring", "msts", RB_DAAP_TYPE_STRING},
-	{RB_DAAP_CC_MIMC, MAKE_CONTENT_CODE('m','i','m','c'), "dmap.itemcount", "mimc", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_MCTC, MAKE_CONTENT_CODE('m','c','t','c'), "dmap.containercount", "mctc", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_MRCO, MAKE_CONTENT_CODE('m','r','c','o'), "dmap.returnedcount", "mrco", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_MTCO, MAKE_CONTENT_CODE('m','t','c','o'), "dmap.specifiedtotalcount", "mtco", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_MLCL, MAKE_CONTENT_CODE('m','l','c','l'), "dmap.listing", "mlcl", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_MLIT, MAKE_CONTENT_CODE('m','l','i','t'), "dmap.listingitem", "mlit", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_MBCL, MAKE_CONTENT_CODE('m','b','c','l'), "dmap.bag", "mbcl", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_MSRV, MAKE_CONTENT_CODE('m','s','r','v'), "dmap.serverinforesponse", "msrv", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_MSAU, MAKE_CONTENT_CODE('m','s','a','u'), "dmap.authenticationmethod", "msau", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_MSLR, MAKE_CONTENT_CODE('m','s','l','r'), "dmap.loginrequired", "mslr", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_MPRO, MAKE_CONTENT_CODE('m','p','r','o'), "dmap.protocolversion", "mpro", RB_DAAP_TYPE_VERSION},
-	{RB_DAAP_CC_APRO, MAKE_CONTENT_CODE('a','p','r','o'), "daap.protocolversion", "apro", RB_DAAP_TYPE_VERSION},
-	{RB_DAAP_CC_MSAL, MAKE_CONTENT_CODE('m','s','a','l'), "dmap.supportsautologout", "msal", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_MSUP, MAKE_CONTENT_CODE('m','s','u','p'), "dmap.supportsupdate", "msup", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_MSPI, MAKE_CONTENT_CODE('m','s','p','i'), "dmap.supportspersistenids", "mspi", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_MSEX, MAKE_CONTENT_CODE('m','s','e','x'), "dmap.supportsextensions", "msex", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_MSBR, MAKE_CONTENT_CODE('m','s','b','r'), "dmap.supportsbrowse", "msbr", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_MSQY, MAKE_CONTENT_CODE('m','s','q','y'), "dmap.supportsquery", "msqy", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_MSIX, MAKE_CONTENT_CODE('m','s','i','x'), "dmap.supportsindex", "msix", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_MSRS, MAKE_CONTENT_CODE('m','s','r','s'), "dmap.supportsresolve", "msrs", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_MSTM, MAKE_CONTENT_CODE('m','s','t','m'), "dmap.timeoutinterval", "mstm", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_MSDC, MAKE_CONTENT_CODE('m','s','d','c'), "dmap.databasescount", "msdc", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_MCCR, MAKE_CONTENT_CODE('m','c','c','r'), "dmap.contentcodesresponse", "mccr", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_MCNM, MAKE_CONTENT_CODE('m','c','n','m'), "dmap.contentcodesnumber", "mcnm", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_MCNA, MAKE_CONTENT_CODE('m','c','n','a'), "dmap.contentcodesname", "mcna", RB_DAAP_TYPE_STRING},
-	{RB_DAAP_CC_MCTY, MAKE_CONTENT_CODE('m','c','t','y'), "dmap.contentcodestype", "mcty", RB_DAAP_TYPE_SHORT},
-	{RB_DAAP_CC_MLOG, MAKE_CONTENT_CODE('m','l','o','g'), "dmap.loginresponse", "mlog", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_MLID, MAKE_CONTENT_CODE('m','l','i','d'), "dmap.sessionid", "mlid", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_MUPD, MAKE_CONTENT_CODE('m','u','p','d'), "dmap.updateresponse", "mupd", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_MUSR, MAKE_CONTENT_CODE('m','u','s','r'), "dmap.serverrevision", "musr", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_MUTY, MAKE_CONTENT_CODE('m','u','t','y'), "dmap.updatetype", "muty", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_MUDL, MAKE_CONTENT_CODE('m','u','d','l'), "dmap.deletedidlisting", "mudl", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_AVDB, MAKE_CONTENT_CODE('a','v','d','b'), "daap.serverdatabases", "avdb", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_ABRO, MAKE_CONTENT_CODE('a','b','r','o'), "daap.databasebrowse", "abro", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_ABAL, MAKE_CONTENT_CODE('a','b','a','l'), "daap.browsealbumlisting", "abal", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_ABAR, MAKE_CONTENT_CODE('a','b','a','r'), "daap.browseartistlisting", "abar", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_ABCP, MAKE_CONTENT_CODE('a','b','c','p'), "daap.browsecomposerlisting", "abcp", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_ABGN, MAKE_CONTENT_CODE('a','b','g','n'), "daap.browsegenrelisting", "abgn", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_ADBS, MAKE_CONTENT_CODE('a','d','b','s'), "daap.returndatabasesongs", "adbs", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_ASAL, MAKE_CONTENT_CODE('a','s','a','l'), "daap.songalbum", "asal", RB_DAAP_TYPE_STRING},
-	{RB_DAAP_CC_ASAR, MAKE_CONTENT_CODE('a','s','a','r'), "daap.songartist", "asar", RB_DAAP_TYPE_STRING},
-	{RB_DAAP_CC_ASBT, MAKE_CONTENT_CODE('a','s','b','t'), "daap.songsbeatsperminute", "asbt", RB_DAAP_TYPE_SHORT},
-	{RB_DAAP_CC_ASBR, MAKE_CONTENT_CODE('a','s','b','r'), "daap.songbitrate", "asbr", RB_DAAP_TYPE_SHORT},
-	{RB_DAAP_CC_ASCM, MAKE_CONTENT_CODE('a','s','c','m'), "daap.songcomment", "ascm", RB_DAAP_TYPE_STRING},
-	{RB_DAAP_CC_ASCO, MAKE_CONTENT_CODE('a','s','c','o'), "daap.songcompliation", "asco", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_ASDA, MAKE_CONTENT_CODE('a','s','d','a'), "daap.songdateadded", "asda", RB_DAAP_TYPE_DATE},
-	{RB_DAAP_CC_ASDM, MAKE_CONTENT_CODE('a','s','d','m'), "daap.songdatemodified", "asdm", RB_DAAP_TYPE_DATE},
-	{RB_DAAP_CC_ASDC, MAKE_CONTENT_CODE('a','s','d','c'), "daap.songdisccount", "asdc", RB_DAAP_TYPE_SHORT},
-	{RB_DAAP_CC_ASDN, MAKE_CONTENT_CODE('a','s','d','n'), "daap.songdiscnumber", "asdn", RB_DAAP_TYPE_SHORT},
-	{RB_DAAP_CC_ASDB, MAKE_CONTENT_CODE('a','s','d','b'), "daap.songdisabled", "asdb", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_ASEQ, MAKE_CONTENT_CODE('a','s','e','q'), "daap.songeqpreset", "aseq", RB_DAAP_TYPE_STRING},
-	{RB_DAAP_CC_ASFM, MAKE_CONTENT_CODE('a','s','f','m'), "daap.songformat", "asfm", RB_DAAP_TYPE_STRING},
-	{RB_DAAP_CC_ASGN, MAKE_CONTENT_CODE('a','s','g','n'), "daap.songgenre", "asgn", RB_DAAP_TYPE_STRING},
-	{RB_DAAP_CC_ASDT, MAKE_CONTENT_CODE('a','s','d','t'), "daap.songdescription", "asdt", RB_DAAP_TYPE_STRING},
-	{RB_DAAP_CC_ASRV, MAKE_CONTENT_CODE('a','s','r','v'), "daap.songrelativevolume", "asrv", RB_DAAP_TYPE_SIGNED_INT},
-	{RB_DAAP_CC_ASSR, MAKE_CONTENT_CODE('a','s','s','r'), "daap.songsamplerate", "assr", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_ASSZ, MAKE_CONTENT_CODE('a','s','s','z'), "daap.songsize", "assz", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_ASST, MAKE_CONTENT_CODE('a','s','s','t'), "daap.songstarttime", "asst", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_ASSP, MAKE_CONTENT_CODE('a','s','s','p'), "daap.songstoptime", "assp", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_ASTM, MAKE_CONTENT_CODE('a','s','t','m'), "daap.songtime", "astm", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_ASTC, MAKE_CONTENT_CODE('a','s','t','c'), "daap.songtrackcount", "astc", RB_DAAP_TYPE_SHORT},
-	{RB_DAAP_CC_ASTN, MAKE_CONTENT_CODE('a','s','t','n'), "daap.songtracknumber", "astn", RB_DAAP_TYPE_SHORT},
-	{RB_DAAP_CC_ASUR, MAKE_CONTENT_CODE('a','s','u','r'), "daap.songuserrating", "asur", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_ASYR, MAKE_CONTENT_CODE('a','s','y','r'), "daap.songyear", "asyr", RB_DAAP_TYPE_SHORT},
-	{RB_DAAP_CC_ASDK, MAKE_CONTENT_CODE('a','s','d','k'), "daap.songdatakind", "asdk", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_ASUL, MAKE_CONTENT_CODE('a','s','u','l'), "daap.songdataurl", "asul", RB_DAAP_TYPE_STRING},
-	{RB_DAAP_CC_APLY, MAKE_CONTENT_CODE('a','p','l','y'), "daap.databaseplaylists", "aply", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_ABPL, MAKE_CONTENT_CODE('a','b','p','l'), "daap.baseplaylist", "abpl", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_APSO, MAKE_CONTENT_CODE('a','p','s','o'), "daap.playlistsongs", "apso", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_PRSV, MAKE_CONTENT_CODE('p','r','s','v'), "daap.resolve", "prsv", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_ARIF, MAKE_CONTENT_CODE('a','r','i','f'), "daap.resolveinfo", "arif", RB_DAAP_TYPE_CONTAINER},
-	{RB_DAAP_CC_AESV, MAKE_CONTENT_CODE('a','e','S','V'), "com.applie.itunes.music-sharing-version", "aesv", RB_DAAP_TYPE_INT},
-	{RB_DAAP_CC_MSAS, MAKE_CONTENT_CODE('m','s','a','s'), "daap.authentication.schemes", "msas", RB_DAAP_TYPE_BYTE},
-	{RB_DAAP_CC_AGRP, MAKE_CONTENT_CODE('a','g','r','p'), "daap.songgrouping", "agrp", RB_DAAP_TYPE_STRING},
-	{RB_DAAP_CC_ASCP, MAKE_CONTENT_CODE('a','s','c','p'), "daap.songcomposer", "ascp", RB_DAAP_TYPE_STRING},
-	{RB_DAAP_CC_AESP, MAKE_CONTENT_CODE('a','e','S','P'), "com.apple.itunes.smart-playlist", "aesp", RB_DAAP_TYPE_BYTE}
-	};
-
-const gchar *
-rb_daap_content_code_name (RBDAAPContentCode code)
-{
-	return cc_defs[code-1].name;
-}
-
-RBDAAPType
-rb_daap_content_code_rb_daap_type (RBDAAPContentCode code)
-{
-	return cc_defs[code-1].type;
-}
-
-const gchar *
-rb_daap_content_code_string (RBDAAPContentCode code)
-{
-	return cc_defs[code-1].string;
-}
-
-static GType
-rb_daap_content_code_gtype (RBDAAPContentCode code)
-{
-	switch (rb_daap_content_code_rb_daap_type (code)) {
-		case RB_DAAP_TYPE_BYTE:
-		case RB_DAAP_TYPE_SIGNED_INT:
-			return G_TYPE_CHAR;
-		case RB_DAAP_TYPE_SHORT:
-		case RB_DAAP_TYPE_INT:
-		case RB_DAAP_TYPE_DATE:
-			return G_TYPE_INT;
-		case RB_DAAP_TYPE_INT64:
-			return G_TYPE_INT64;
-		case RB_DAAP_TYPE_VERSION:
-			return G_TYPE_DOUBLE;
-		case RB_DAAP_TYPE_STRING:
-			return G_TYPE_STRING;
-		case RB_DAAP_TYPE_CONTAINER:
-		default:
-			return G_TYPE_NONE;
-	}
-}
-
-GNode *
-rb_daap_structure_add (GNode *parent,
-		       RBDAAPContentCode cc,
-		       ...)
-{
-	RBDAAPType rb_daap_type;
-	GType gtype;
-	RBDAAPItem *item;
-	va_list list;
-	GNode *node;
-	gchar *error = NULL;
-
-	va_start (list, cc);
-
-	rb_daap_type = rb_daap_content_code_rb_daap_type (cc);
-	gtype = rb_daap_content_code_gtype (cc);
-
-	item = g_new0(RBDAAPItem, 1);
-	item->content_code = cc;
-
-	if (gtype != G_TYPE_NONE) {
-		g_value_init (&(item->content), gtype);
-	}
-
-	if (rb_daap_type != RB_DAAP_TYPE_STRING && rb_daap_type != RB_DAAP_TYPE_CONTAINER) {
-		G_VALUE_COLLECT (&(item->content), list, G_VALUE_NOCOPY_CONTENTS, &error);
-		if (error) {
-			g_warning ("%s", error);
-			g_free (error);
-		}
-	}
-
-	switch (rb_daap_type) {
-		case RB_DAAP_TYPE_BYTE:
-		case RB_DAAP_TYPE_SIGNED_INT:
-			item->size = 1;
-			break;
-		case RB_DAAP_TYPE_SHORT:
-			item->size = 2;
-			break;
-		case RB_DAAP_TYPE_DATE:
-		case RB_DAAP_TYPE_INT:
-		case RB_DAAP_TYPE_VERSION:
-			item->size = 4;
-			break;
-		case RB_DAAP_TYPE_INT64:
-			item->size = 8;
-			break;
-		case RB_DAAP_TYPE_STRING: {
-			gchar *s = va_arg (list, gchar *);
-
-			g_value_set_string (&(item->content), s);
-
-			/* we dont use G_VALUE_COLLECT for this because we also
-			 * need the length */
-			item->size = strlen (s);
-			break;
-		}
-		case RB_DAAP_TYPE_CONTAINER:
-		default:
-			break;
-	}
-
-	node = g_node_new (item);
-
-	if (parent) {
-		g_node_append (parent, node);
-
-		while (parent) {
-			RBDAAPItem *parent_item = parent->data;
-
-			parent_item->size += (4 + 4 + item->size);
-
-			parent = parent->parent;
-		}
-	}
-
-	return node;
-}
-
-static gboolean
-rb_daap_structure_node_serialize (GNode *node,
-				  GByteArray *array)
-{
-	RBDAAPItem *item = node->data;
-	RBDAAPType rb_daap_type;
-	guint32 size = GINT32_TO_BE (item->size);
-
-	g_byte_array_append (array, (const guint8 *)rb_daap_content_code_string (item->content_code), 4);
-	g_byte_array_append (array, (const guint8 *)&size, 4);
-
-	rb_daap_type = rb_daap_content_code_rb_daap_type (item->content_code);
-
-	switch (rb_daap_type) {
-		case RB_DAAP_TYPE_BYTE:
-		case RB_DAAP_TYPE_SIGNED_INT: {
-			gchar c = g_value_get_char (&(item->content));
-
-			g_byte_array_append (array, (const guint8 *)&c, 1);
-
-			break;
-		}
-		case RB_DAAP_TYPE_SHORT: {
-			gint32 i = g_value_get_int (&(item->content));
-			gint16 s = GINT16_TO_BE ((gint16) i);
-
-			g_byte_array_append (array, (const guint8 *)&s, 2);
-
-			break;
-	        }
-		case RB_DAAP_TYPE_DATE:
-		case RB_DAAP_TYPE_INT: {
-			gint32 i = g_value_get_int (&(item->content));
-			gint32 s = GINT32_TO_BE (i);
-
-			g_byte_array_append (array, (const guint8 *)&s, 4);
-
-			break;
-		}
-		case RB_DAAP_TYPE_VERSION: {
-			gdouble v = g_value_get_double (&(item->content));
-			gint16 major;
-			gint8 minor;
-			gint8 patch = 0;
-
-			major = (gint16)v;
-			minor = (gint8)(v - ((gdouble)major));
-
-			major = GINT16_TO_BE (major);
-
-			g_byte_array_append (array, (const guint8 *)&major, 2);
-			g_byte_array_append (array, (const guint8 *)&minor, 1);
-			g_byte_array_append (array, (const guint8 *)&patch, 1);
-
-			break;
-		}
-		case RB_DAAP_TYPE_INT64: {
-			gint64 i = g_value_get_int64 (&(item->content));
-			gint64 s = GINT64_TO_BE (i);
-
-			g_byte_array_append (array, (const guint8 *)&s, 8);
-
-			break;
-		}
-		case RB_DAAP_TYPE_STRING: {
-			const gchar *s = g_value_get_string (&(item->content));
-
-			g_byte_array_append (array, (const guint8 *)s, strlen (s));
-
-			break;
-		}
-		case RB_DAAP_TYPE_CONTAINER:
-		default:
-			break;
-	}
-
-	return FALSE;
-}
-
-gchar *
-rb_daap_structure_serialize (GNode *structure,
-			     guint *length)
-{
-	GByteArray *array;
-	gchar *data;
-
-	array = g_byte_array_new ();
-
-	if (structure) {
-		g_node_traverse (structure, G_PRE_ORDER, G_TRAVERSE_ALL, -1, (GNodeTraverseFunc)rb_daap_structure_node_serialize, array);
-	}
-
-	data = (gchar *) array->data;
-	*length = array->len;
-	g_byte_array_free (array, FALSE);
-
-	return data;
-}
-
-static RBDAAPContentCode
-rb_daap_buffer_read_content_code (const gchar *buf)
-{
-	gint32 c = MAKE_CONTENT_CODE (buf[0], buf[1], buf[2], buf[3]);
-	guint i;
-
-	for (i = 0; i < G_N_ELEMENTS (cc_defs); i++) {
-		if (cc_defs[i].int_code == c) {
-			return cc_defs[i].code;
-		}
-	}
-
-	return RB_DAAP_CC_INVALID;
-}
-
-#define rb_daap_buffer_read_int8(b)  	GST_READ_UINT8 (b)
-#define rb_daap_buffer_read_int16(b) 	(gint16) GST_READ_UINT16_BE (b)
-#define rb_daap_buffer_read_int32(b) 	(gint32) GST_READ_UINT32_BE (b)
-#define rb_daap_buffer_read_int64(b) 	(gint64) GST_READ_UINT64_BE (b)
-
-static gchar *
-rb_daap_buffer_read_string (const gchar *buf, gssize size)
-{
-	if (g_utf8_validate (buf, size, NULL) == TRUE) {
-		return g_strndup (buf, size);
-	} else {
-		return g_strdup ("");
-	}
-}
-
-//#define PARSE_DEBUG
-#define PARSE_DEBUG_FILE "daapbuffer"
-
-#ifdef PARSE_DEBUG
-#include <unistd.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#endif
-
-static void
-rb_daap_structure_parse_container_buffer (GNode *parent,
-					  const guchar *buf,
-					  gint buf_length)
-{
-	gint l = 0;
-
-	while (l < buf_length) {
-		RBDAAPContentCode cc;
-		gint codesize = 0;
-		RBDAAPItem *item = NULL;
-		GNode *node = NULL;
-		GType gtype;
-
-#ifdef PARSE_DEBUG
-		g_print ("l is %d and buf_length is %d\n", l, buf_length);
-#endif
-
-		/* we need at least 8 bytes, 4 of content_code and 4 of size */
-		if (buf_length - l < 8) {
-#ifdef PARSE_DEBUG
-			g_print ("Malformed response recieved\n");
-#endif
-			return;
-		}
-
-		cc = rb_daap_buffer_read_content_code ((const gchar*)&(buf[l]));
-		if (cc == RB_DAAP_CC_INVALID) {
-#ifdef PARSE_DEBUG
-			g_print ("Invalid content_code recieved\n");
-#endif
-			return;
-		}
-		l += 4;
-
-		codesize = rb_daap_buffer_read_int32(&(buf[l]));
-		/* CCCCSIZECONTENT
-		 * if the buffer length (minus 8 for the content code & size)
-		 * is smaller than the read codesize (ie, someone sent us
-		 * a codesize that is larger than the remaining data)
-		 * then get out before we start processing it
-		 */
-		if (codesize > buf_length - l - 4 || codesize < 0) {
-#ifdef PARSE_DEBUG
-			g_print ("Invalid codesize %d recieved in buf_length %d\n", codesize, buf_length);
-#endif
-			return;
-		}
-		l += 4;
-
-#ifdef PARSE_DEBUG
-		g_print ("content_code = %d, codesize is %d, l is %d\n", cc, codesize, l);
-#endif
-
-		item = g_new0 (RBDAAPItem, 1);
-		item->content_code = cc;
-		node = g_node_new (item);
-		g_node_append (parent, node);
-
-		gtype = rb_daap_content_code_gtype (item->content_code);
-
-		if (gtype != G_TYPE_NONE) {
-			g_value_init (&(item->content), gtype);
-		}
-
-#ifdef PARSE_DEBUG
-		{
-			guint i;
-
-			for (i = 2; i < g_node_depth (node); i++) {
-				g_print ("\t");
-			}
-		}
-#endif
-
-// FIXME USE THE G_TYPE CONVERTOR FUNCTION rb_daap_type_to_gtype
-		switch (rb_daap_content_code_rb_daap_type (item->content_code)) {
-			case RB_DAAP_TYPE_SIGNED_INT:
-			case RB_DAAP_TYPE_BYTE: {
-				gchar c = 0;
-
-				if (codesize == 1) {
-					c = (gchar) rb_daap_buffer_read_int8(&(buf[l]));
-				}
-
-				g_value_set_char (&(item->content), c);
-#ifdef PARSE_DEBUG
-				g_print ("Code: %s, content (%d): \"%c\"\n", rb_daap_content_code_string (item->content_code), codesize, (gchar)c);
-#endif
-
-				break;
-			}
-			case RB_DAAP_TYPE_SHORT: {
-				gint16 s = 0;
-
-				if (codesize == 2) {
-					s = rb_daap_buffer_read_int16(&(buf[l]));
-				}
-
-				g_value_set_int (&(item->content),(gint32)s);
-#ifdef PARSE_DEBUG
-				g_print ("Code: %s, content (%d): %hi\n", rb_daap_content_code_string (item->content_code), codesize, s);
-#endif
-
-				break;
-			}
-			case RB_DAAP_TYPE_DATE:
-			case RB_DAAP_TYPE_INT: {
-				gint32 i = 0;
-
-				if (codesize == 4) {
-					i = rb_daap_buffer_read_int32(&(buf[l]));
-				}
-
-				g_value_set_int (&(item->content), i);
-#ifdef PARSE_DEBUG
-				g_print ("Code: %s, content (%d): %d\n", rb_daap_content_code_string (item->content_code), codesize, i);
-#endif
-				break;
-			}
-			case RB_DAAP_TYPE_INT64: {
-				gint64 i = 0;
-
-				if (codesize == 8) {
-					i = rb_daap_buffer_read_int16(&(buf[l]));
-				}
-
-				g_value_set_int64 (&(item->content), i);
-#ifdef PARSE_DEBUG
-				g_print ("Code: %s, content (%d): %"G_GINT64_FORMAT"\n", rb_daap_content_code_string (item->content_code), codesize, i);
-#endif
-
-				break;
-			}
-			case RB_DAAP_TYPE_STRING: {
-				gchar *s = rb_daap_buffer_read_string ((const gchar*)&(buf[l]), codesize);
-
-				g_value_take_string (&(item->content), s);
-#ifdef PARSE_DEBUG
-				g_print ("Code: %s, content (%d): \"%s\"\n", rb_daap_content_code_string (item->content_code), codesize, s);
-#endif
-
-				break;
-			}
-			case RB_DAAP_TYPE_VERSION: {
-				gint16 major = 0;
-				gint16 minor = 0;
-				gint16 patch = 0;
-				gdouble v = 0;
-
-				if (codesize == 4) {
-					major = rb_daap_buffer_read_int16(&(buf[l]));
-					minor = rb_daap_buffer_read_int8(&(buf[l]) + 2);
-					patch = rb_daap_buffer_read_int8(&(buf[l]) + 3);
-				}
-
-				v = (gdouble)major;
-				v += (gdouble)(minor * 0.1);
-				v += (gdouble)(patch * 0.01);
-
-				g_value_set_double (&(item->content), v);
-#ifdef PARSE_DEBUG
-				g_print ("Code: %s, content: %f\n", rb_daap_content_code_string (item->content_code), v);
-#endif
-
-				break;
-			}
-			case RB_DAAP_TYPE_CONTAINER: {
-#ifdef PARSE_DEBUG
-				g_print ("Code: %s, container\n", rb_daap_content_code_string (item->content_code));
-#endif
-				rb_daap_structure_parse_container_buffer (node,&(buf[l]), codesize);
-				break;
-			}
-		}
-
-		l += codesize;
-	}
-
-	return;
-}
-
-GNode *
-rb_daap_structure_parse (const gchar *buf,
-			 gint buf_length)
-{
-	GNode *root = NULL;
-	GNode *child = NULL;
-
-#ifdef PARSE_DEBUG
-	{
-		int fd;
-
-		fd = open (PARSE_DEBUG_FILE, O_WRONLY | O_CREAT);
-		write (fd, (const void *)buf, (size_t)buf_length);
-		close (fd);
-	}
-#endif
-
-	root = g_node_new (NULL);
-
-	rb_daap_structure_parse_container_buffer (root, (guchar *)buf, buf_length);
-
-	child = root->children;
-	if (child) {
-		g_node_unlink (child);
-	}
-	g_node_destroy (root);
-
-	return child;
-}
-
-struct NodeFinder {
-	RBDAAPContentCode code;
-	GNode *node;
-};
-
-static gboolean
-gnode_find_node (GNode *node,
-		 gpointer data)
-{
-	struct NodeFinder *finder = (struct NodeFinder *)data;
-	RBDAAPItem *item = node->data;
-
-	if (item->content_code == finder->code) {
-		finder->node = node;
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-RBDAAPItem *
-rb_daap_structure_find_item (GNode *structure,
-			     RBDAAPContentCode code)
-{
-	GNode *node = NULL;
-
-	node = rb_daap_structure_find_node (structure, code);
-
-	if (node) {
-		return node->data;
-	}
-
-	return NULL;
-}
-
-GNode *
-rb_daap_structure_find_node (GNode *structure,
-			     RBDAAPContentCode code)
-{
-	struct NodeFinder *finder;
-	GNode *node = NULL;
-
-	finder = g_new0(struct NodeFinder,1);
-	finder->code = code;
-
-	g_node_traverse (structure, G_IN_ORDER, G_TRAVERSE_ALL, -1, gnode_find_node, finder);
-
-	node = finder->node;
-	g_free (finder);
-	finder = NULL;
-
-	return node;
-}
-
-static void
-rb_daap_item_free (RBDAAPItem *item)
-{
-	if (rb_daap_content_code_rb_daap_type (item->content_code) != RB_DAAP_TYPE_CONTAINER) {
-		g_value_unset (&(item->content));
-	}
-
-	g_free (item);
-}
-
-static gboolean
-gnode_free_rb_daap_item (GNode *node,
-			 gpointer data)
-{
-	rb_daap_item_free ((RBDAAPItem *)node->data);
-
-	return FALSE;
-}
-
-void
-rb_daap_structure_destroy (GNode *structure)
-{
-	if (structure) {
-		g_node_traverse (structure, G_IN_ORDER, G_TRAVERSE_ALL, -1, gnode_free_rb_daap_item, NULL);
-
-		g_node_destroy (structure);
-
-		structure = NULL;
-	}
-}
-
-const RBDAAPContentCodeDefinition *
-rb_daap_content_codes (guint *number)
-{
-	*number = G_N_ELEMENTS (cc_defs);
-
-	return cc_defs;
-}
-
-gint32
-rb_daap_content_code_string_as_int32 (const gchar *str)
-{
-	union {
-		gint32 i;
-		gchar str[4];
-	} u;
-
-	strncpy (u.str, str, 4);
-
-	return g_htonl (u.i);
-}
-
-static gboolean
-print_rb_daap_item (GNode *node,
-		    gpointer data)
-{
-	RBDAAPItem *item;
-	const gchar *name;
-	gchar *value;
-	gint i;
-
-	for (i = 1; i < g_node_depth (node); i++) {
-		g_print ("\t");
-	}
-
-	item = node->data;
-
-	name = rb_daap_content_code_name (item->content_code);
-
-	if (G_IS_VALUE (&(item->content))) {
-		value = g_strdup_value_contents (&(item->content));
-	} else {
-		value = g_strdup ("");
-	}
-
-	g_print ("%d, %s = %s (%d)\n", g_node_depth (node), name, value, item->size);
-	g_free (value);
-
-	return FALSE;
-}
-
-void
-rb_daap_structure_print (GNode *structure)
-{
-	if (structure) {
-		g_node_traverse (structure, G_PRE_ORDER, G_TRAVERSE_ALL, -1, (GNodeTraverseFunc)print_rb_daap_item, NULL);
-	}
-}
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-structure.h rhythmbox-0.12.1/plugins/daap/rb-daap-structure.h
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-daap-structure.h	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/daap/rb-daap-structure.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,202 +0,0 @@
-/*
- *  Header for DAAP (iTunes Music Sharing) structures
- *
- *  Copyright (C) 2004,2005 Charles Schmidt <cschmidt2@emich.edu>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The Rhythmbox authors hereby grant permission for non-GPL compatible
- *  GStreamer plugins to be used and distributed together with GStreamer
- *  and Rhythmbox. This permission is above and beyond the permissions granted
- *  by the GPL license by which Rhythmbox is covered. If you modify this code
- *  you may extend this exception to your version of the code, but you are not
- *  obligated to do so. If you do not wish to do so, delete this exception
- *  statement from your version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#ifndef __RB_DAAP_STRUCTURE_H
-#define __RB_DAAP_STRUCTURE_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-typedef enum {
-	RB_DAAP_CC_INVALID = 0,
-	RB_DAAP_CC_MDCL = 1,
-	RB_DAAP_CC_MSTT,
-	RB_DAAP_CC_MIID,
-	RB_DAAP_CC_MINM,
-	RB_DAAP_CC_MIKD,
-	RB_DAAP_CC_MPER,
-	RB_DAAP_CC_MCON,
-	RB_DAAP_CC_MCTI,
-	RB_DAAP_CC_MPCO,
-	RB_DAAP_CC_MSTS, /* 10 */
-	RB_DAAP_CC_MIMC,
-	RB_DAAP_CC_MCTC,
-	RB_DAAP_CC_MRCO,
-	RB_DAAP_CC_MTCO,
-	RB_DAAP_CC_MLCL,
-	RB_DAAP_CC_MLIT,
-	RB_DAAP_CC_MBCL,
-	RB_DAAP_CC_MSRV,
-	RB_DAAP_CC_MSAU,
-	RB_DAAP_CC_MSLR, /* 20 */
-	RB_DAAP_CC_MPRO,
-	RB_DAAP_CC_APRO,
-	RB_DAAP_CC_MSAL,
-	RB_DAAP_CC_MSUP,
-	RB_DAAP_CC_MSPI,
-	RB_DAAP_CC_MSEX,
-	RB_DAAP_CC_MSBR,
-	RB_DAAP_CC_MSQY,
-	RB_DAAP_CC_MSIX,
-	RB_DAAP_CC_MSRS, /* 30 */
-	RB_DAAP_CC_MSTM,
-	RB_DAAP_CC_MSDC,
-	RB_DAAP_CC_MCCR,
-	RB_DAAP_CC_MCNM,
-	RB_DAAP_CC_MCNA,
-	RB_DAAP_CC_MCTY,
-	RB_DAAP_CC_MLOG,
-	RB_DAAP_CC_MLID,
-	RB_DAAP_CC_MUPD,
-	RB_DAAP_CC_MUSR, /* 40 */
-	RB_DAAP_CC_MUTY,
-	RB_DAAP_CC_MUDL,
-	RB_DAAP_CC_AVDB,
-	RB_DAAP_CC_ABRO,
-	RB_DAAP_CC_ABAL,
-	RB_DAAP_CC_ABAR,
-	RB_DAAP_CC_ABCP,
-	RB_DAAP_CC_ABGN,
-	RB_DAAP_CC_ADBS,
-	RB_DAAP_CC_ASAL, /* 50 */
-	RB_DAAP_CC_ASAR,
-	RB_DAAP_CC_ASBT,
-	RB_DAAP_CC_ASBR,
-	RB_DAAP_CC_ASCM,
-	RB_DAAP_CC_ASCO,
-	RB_DAAP_CC_ASDA,
-	RB_DAAP_CC_ASDM,
-	RB_DAAP_CC_ASDC,
-	RB_DAAP_CC_ASDN,
-	RB_DAAP_CC_ASDB, /* 60 */
-	RB_DAAP_CC_ASEQ,
-	RB_DAAP_CC_ASFM,
-	RB_DAAP_CC_ASGN,
-	RB_DAAP_CC_ASDT,
-	RB_DAAP_CC_ASRV,
-	RB_DAAP_CC_ASSR,
-	RB_DAAP_CC_ASSZ,
-	RB_DAAP_CC_ASST,
-	RB_DAAP_CC_ASSP,
-	RB_DAAP_CC_ASTM, /* 70 */
-	RB_DAAP_CC_ASTC,
-	RB_DAAP_CC_ASTN,
-	RB_DAAP_CC_ASUR,
-	RB_DAAP_CC_ASYR,
-	RB_DAAP_CC_ASDK,
-	RB_DAAP_CC_ASUL,
-	RB_DAAP_CC_APLY,
-	RB_DAAP_CC_ABPL,
-	RB_DAAP_CC_APSO,
-	RB_DAAP_CC_PRSV, /* 80 */
-	RB_DAAP_CC_ARIF,
-	RB_DAAP_CC_AESV,
-	RB_DAAP_CC_MSAS,
-	RB_DAAP_CC_AGRP,
-	RB_DAAP_CC_ASCP,
-	RB_DAAP_CC_AESP
-} RBDAAPContentCode;
-
-typedef struct _RBDAAPItem RBDAAPItem;
-
-struct _RBDAAPItem {
-	RBDAAPContentCode content_code;
-	GValue content;
-	guint size;
-};
-
-GNode *
-rb_daap_structure_add (GNode *parent,
-		       RBDAAPContentCode cc,
-		       ...);
-
-gchar *
-rb_daap_structure_serialize (GNode *structure,
-			     guint *length);
-
-GNode *
-rb_daap_structure_parse (const gchar *buf,
-			 gint buf_length);
-
-RBDAAPItem *
-rb_daap_structure_find_item (GNode *structure,
-			     RBDAAPContentCode code);
-
-GNode *
-rb_daap_structure_find_node (GNode *structure,
-			     RBDAAPContentCode code);
-
-void
-rb_daap_structure_print (GNode *structure);
-
-void
-rb_daap_structure_destroy (GNode *structure);
-
-typedef enum {
-	RB_DAAP_TYPE_BYTE = 0x0001,
-	RB_DAAP_TYPE_SIGNED_INT = 0x0002,
-	RB_DAAP_TYPE_SHORT = 0x0003,
-	RB_DAAP_TYPE_INT = 0x0005,
-	RB_DAAP_TYPE_INT64 = 0x0007,
-	RB_DAAP_TYPE_STRING = 0x0009,
-	RB_DAAP_TYPE_DATE = 0x000A,
-	RB_DAAP_TYPE_VERSION = 0x000B,
-	RB_DAAP_TYPE_CONTAINER = 0x000C
-} RBDAAPType;
-
-typedef struct _RBDAAPContentCodeDefinition RBDAAPContentCodeDefinition;
-
-struct _RBDAAPContentCodeDefinition {
-	RBDAAPContentCode code;
-	gint32 int_code;
-	const gchar *name;
-	const gchar *string;
-	RBDAAPType type;
-};
-
-const RBDAAPContentCodeDefinition *
-rb_daap_content_codes (guint *number);
-
-gint32
-rb_daap_content_code_string_as_int32 (const gchar *str);
-
-const gchar *
-rb_daap_content_code_name (RBDAAPContentCode code);
-
-RBDAAPType
-rb_daap_content_code_rb_daap_type (RBDAAPContentCode code);
-
-const gchar *
-rb_daap_content_code_string (RBDAAPContentCode code);
-
-G_END_DECLS
-
-#endif /* __RB_DAAP_STRUCTURE_H */
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-dmap-container-db.c rhythmbox-0.12.1/plugins/daap/rb-dmap-container-db.c
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-dmap-container-db.c	1969-12-31 19:00:00.000000000 -0500
+++ rhythmbox-0.12.1/plugins/daap/rb-dmap-container-db.c	2009-08-15 18:14:56.000000000 -0400
@@ -0,0 +1,101 @@
+/*
+ * Database class for DMAP sharing
+ *
+ * Copyright (C) 2008 W. Michael Petullo <mike@flyn.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <glib/ghash.h>
+
+#include "rb-dmap-container-db.h"
+
+struct RBDMAPContainerDbPrivate {
+	GHashTable *db;
+};
+
+DMAPContainerRecord *
+rb_dmap_container_db_lookup_by_id (DMAPContainerDb *db, gint id)
+{
+	DMAPContainerRecord *record = g_hash_table_lookup (RB_DMAP_CONTAINER_DB (db)->priv->db, &id);
+	g_object_ref (record);
+	return record;
+}
+
+void
+rb_dmap_container_db_foreach (DMAPContainerDb *db,
+				   void (*fn) (DMAPContainerRecord *record,
+					       gpointer data),
+				   gpointer data)
+{
+	/* Don't use g_hash_table_foreach because we
+	 * need values, not key / value pairs. */
+	GList *value = g_hash_table_get_values (RB_DMAP_CONTAINER_DB (db)->priv->db);
+	g_list_foreach (value, (GFunc) fn, data);
+}
+
+gint64
+rb_dmap_container_db_count (DMAPContainerDb *db)
+{
+	return g_hash_table_size (RB_DMAP_CONTAINER_DB (db)->priv->db);
+}
+
+void
+rb_dmap_container_db_add (DMAPContainerDb *db, DMAPContainerRecord *record)
+{
+        gint *id = g_new (gint, 1);
+	*id = dmap_container_record_get_id (record);
+	g_object_ref (record);
+	g_hash_table_insert (RB_DMAP_CONTAINER_DB (db)->priv->db, id, record);
+}
+
+static void
+rb_dmap_container_db_init (RBDMAPContainerDb *db)
+{
+	db->priv = RB_DMAP_CONTAINER_DB_GET_PRIVATE (db);
+	db->priv->db = g_hash_table_new (g_int_hash, g_int_equal);
+}
+
+static void
+rb_dmap_container_db_class_init (RBDMAPContainerDbClass *klass)
+{
+        g_type_class_add_private (klass, sizeof (RBDMAPContainerDbPrivate));
+}
+
+static void
+rb_dmap_container_db_interface_init (gpointer iface, gpointer data)
+{
+	DMAPContainerDbInterface *dmap_container_db = iface;
+
+	g_assert (G_TYPE_FROM_INTERFACE (dmap_container_db) == TYPE_DMAP_CONTAINER_DB);
+
+	dmap_container_db->lookup_by_id = rb_dmap_container_db_lookup_by_id;
+	dmap_container_db->foreach = rb_dmap_container_db_foreach;
+	dmap_container_db->count = rb_dmap_container_db_count;
+}
+
+G_DEFINE_TYPE_WITH_CODE (RBDMAPContainerDb, rb_dmap_container_db, G_TYPE_OBJECT, 
+			 G_IMPLEMENT_INTERFACE (TYPE_DMAP_CONTAINER_DB,
+						rb_dmap_container_db_interface_init))
+
+RBDMAPContainerDb *
+rb_dmap_container_db_new (void)
+{
+	RBDMAPContainerDb *db;
+
+	db = RB_DMAP_CONTAINER_DB (g_object_new (TYPE_RB_DMAP_CONTAINER_DB, NULL));
+
+	return db;
+}
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-dmap-container-db.h rhythmbox-0.12.1/plugins/daap/rb-dmap-container-db.h
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-dmap-container-db.h	1969-12-31 19:00:00.000000000 -0500
+++ rhythmbox-0.12.1/plugins/daap/rb-dmap-container-db.h	2009-08-13 21:25:13.000000000 -0400
@@ -0,0 +1,71 @@
+/*
+ * Database class for DMAP sharing
+ *
+ * Copyright (C) 2008 W. Michael Petullo <mike@flyn.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __RB_DMAP_CONTAINER_DB
+#define __RB_DMAP_CONTAINER_DB
+
+#include <libdmapsharing/dmap.h>
+
+G_BEGIN_DECLS
+
+#define TYPE_RB_DMAP_CONTAINER_DB         (rb_dmap_container_db_get_type ())
+#define RB_DMAP_CONTAINER_DB(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), \
+				   TYPE_RB_DMAP_CONTAINER_DB, RBDMAPContainerDb))
+#define RB_DMAP_CONTAINER_DB_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), \
+				   TYPE_RB_DMAP_CONTAINER_DB, RBDMAPContainerDbClass))
+#define IS_RB_DMAP_CONTAINER_DB(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), \
+				   TYPE_RB_DMAP_CONTAINER_DB))
+#define IS_RB_DMAP_CONTAINER_DB_CLASS (k) (G_TYPE_CHECK_CLASS_TYPE ((k), \
+				   TYPE_RB_DMAP_CONTAINER_DB_CLASS))
+#define RB_DMAP_CONTAINER_DB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), \
+				   TYPE_RB_DMAP_CONTAINER_DB, RBDMAPContainerDbClass))
+#define RB_DMAP_CONTAINER_DB_GET_PRIVATE(o)	     (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+					      TYPE_RB_DMAP_CONTAINER_DB, \
+					      RBDMAPContainerDbPrivate))
+
+typedef struct RBDMAPContainerDbPrivate RBDMAPContainerDbPrivate;
+
+typedef struct {
+	GObject parent;
+	RBDMAPContainerDbPrivate *priv;
+} RBDMAPContainerDb;
+
+typedef struct {
+	GObjectClass parent;
+} RBDMAPContainerDbClass;
+
+RBDMAPContainerDb *rb_dmap_container_db_new             (void);
+
+GType       rb_dmap_container_db_get_type        (void);
+
+DMAPContainerRecord *rb_dmap_container_db_lookup_by_id    (DMAPContainerDb *db, gint id);
+
+void        rb_dmap_container_db_foreach (DMAPContainerDb *db,
+					  void (*fn) (DMAPContainerRecord *record,
+					 	      gpointer data),
+					  gpointer data);
+
+gint64      rb_dmap_container_db_count (DMAPContainerDb *db);
+
+void rb_dmap_container_db_add (DMAPContainerDb *db, DMAPContainerRecord *record);
+
+#endif /* __RB_DMAP_CONTAINER_DB */
+
+G_END_DECLS
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-dmap-db-adapter.c rhythmbox-0.12.1/plugins/daap/rb-dmap-db-adapter.c
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-dmap-db-adapter.c	1969-12-31 19:00:00.000000000 -0500
+++ rhythmbox-0.12.1/plugins/daap/rb-dmap-db-adapter.c	2009-08-15 16:08:13.000000000 -0400
@@ -0,0 +1,268 @@
+/*
+ *  Database class for DMAP sharing
+ *
+ *  Copyright (C) 2008 W. Michael Petullo <mike@flyn.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "rhythmdb.h"
+#include "rb-dmap-db-adapter.h"
+
+#include <glib/gi18n.h>
+#include <libdmapsharing/dmap.h>
+
+struct RBDMAPDbAdapterPrivate {
+	RhythmDB *db;
+	/* FIXME: for sharing this is RHYTHMDB_ENTRY_TYPE_SONG because we
+	* want to share local songs. For browsing this is daap:x:x:x because
+	* we want to add remote media. Does this class need to be split into
+	* two, sharing and browsing? */
+	RhythmDBEntryType type;
+};
+
+typedef struct ForeachAdapterData {
+	gpointer data;
+	GHFunc fn;
+} ForeachAdapterData;
+
+DMAPRecord *rb_dmap_db_adapter_lookup_by_id	(DMAPDb *db, guint id)
+{
+	RhythmDBEntry *entry;
+	DMAPRecord *record;
+
+	g_warning ("(lookup) Identification: %d", id);
+
+	entry = rhythmdb_entry_lookup_by_id (RB_DMAP_DB_ADAPTER (db)->priv->db,
+					     id);
+
+	record = DMAP_RECORD (rb_daap_record_new (entry));
+
+	/* NOTE: do not g_object_ref() because this is just a transient copy
+	 * of the real data that is in the RhythmDB.
+	 */
+
+	return record;
+}
+
+static void foreach_adapter (RhythmDBEntry *entry, gpointer data)
+{
+	ulong id;
+	DMAPRecord *record;
+	ForeachAdapterData *foreach_adapter_data;
+	
+	id = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_ENTRY_ID);
+	foreach_adapter_data = data;
+	record = DMAP_RECORD (rb_daap_record_new (entry));
+
+	g_warning ("(foreach) Identification: %d", id);
+
+	foreach_adapter_data->fn (GUINT_TO_POINTER (id),
+				  record,
+				  foreach_adapter_data->data);
+
+	g_object_unref (record);
+}
+
+void rb_dmap_db_adapter_foreach	(const DMAPDb *db,
+				 void (*fn) (gpointer id,
+					     DMAPRecord *record,
+					     gpointer data),
+				 gpointer data)
+{
+	ForeachAdapterData *foreach_adapter_data;
+
+	foreach_adapter_data = g_new (ForeachAdapterData, 1);
+	foreach_adapter_data->data = data;
+	foreach_adapter_data->fn = (GHFunc) fn;
+
+	rhythmdb_entry_foreach_by_type (RB_DMAP_DB_ADAPTER (db)->priv->db,
+					RHYTHMDB_ENTRY_TYPE_SONG,
+				       (GFunc) foreach_adapter,
+				        foreach_adapter_data);
+
+	g_free (foreach_adapter_data);
+}
+
+gint64 rb_dmap_db_adapter_count (const DMAPDb *db)
+{
+	return rhythmdb_entry_count_by_type (RB_DMAP_DB_ADAPTER (db)->priv->db,
+					     RHYTHMDB_ENTRY_TYPE_SONG);
+}
+
+static void
+entry_set_string_prop (RhythmDB        *db,
+                       RhythmDBEntry   *entry,
+                       RhythmDBPropType propid,
+                       const char      *str)
+{
+        GValue value = {0,};
+        const gchar *tmp;
+
+        if (str == NULL || *str == '\0' || !g_utf8_validate (str, -1, NULL)) {
+                tmp = _("Unknown");
+        } else {
+                tmp = str;
+        }
+
+        g_value_init (&value, G_TYPE_STRING);
+        g_value_set_string (&value, tmp);
+        rhythmdb_entry_set (RHYTHMDB (db), entry, propid, &value);
+        g_value_unset (&value);
+}
+
+gint rb_dmap_db_adapter_add (DMAPDb *db, DMAPRecord *record)
+{
+	gchar *uri = NULL;
+	const gchar *title = NULL;
+	const gchar *album = NULL;
+	const gchar *artist = NULL;
+	const gchar *format = NULL;
+	const gchar *genre = NULL;
+	gint length = 0;
+	gint track = 0;
+	gint disc = 0;
+	gint year = 0;
+	gint filesize = 0;
+	gint bitrate = 0;
+	GValue value = { 0, };
+	RhythmDBEntry *entry = NULL;
+	RBDMAPDbAdapterPrivate *priv = RB_DMAP_DB_ADAPTER (db)->priv;
+
+	/* NOTE: do not g_object_ref() the record because its data will be
+	 * copied into the RhythmDB.
+	 */
+
+	g_object_get (record,
+		     "location", &uri,
+		     "year", &year,
+                     "track", &track,
+                     "disc", &disc,
+                     "bitrate", &bitrate,
+                     "duration", &length,
+                     "filesize", &filesize,
+		     "format", &format,
+                     "title", &title,
+                     "album", &album,
+                     "artist", &artist,
+                     "genre", &genre,
+		      NULL);
+
+	entry = rhythmdb_entry_new (priv->db, priv->type, uri);
+
+	if (entry == NULL) {
+		g_warning ("cannot create entry for daap track %s", uri);
+		return FALSE;
+	}
+
+	/* year */
+	if (year != 0) {
+		GDate *date;
+		gulong julian;
+
+		/* create dummy date with given year */
+		date = g_date_new_dmy (1, G_DATE_JANUARY, year);
+		julian = g_date_get_julian (date);
+		g_date_free (date);
+
+		g_value_init (&value, G_TYPE_ULONG);
+		g_value_set_ulong (&value,julian);
+		rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_DATE, &value);
+		g_value_unset (&value);
+	}
+
+	/* track number */
+	g_value_init (&value, G_TYPE_ULONG);
+	g_value_set_ulong (&value,(gulong)track);
+	rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_TRACK_NUMBER, &value);
+	g_value_unset (&value);
+
+	/* disc number */
+	g_value_init (&value, G_TYPE_ULONG);
+	g_value_set_ulong (&value,(gulong)disc);
+	rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_DISC_NUMBER, &value);
+	g_value_unset (&value);
+
+	/* bitrate */
+	g_value_init (&value, G_TYPE_ULONG);
+	g_value_set_ulong (&value,(gulong)bitrate);
+	rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_BITRATE, &value);
+	g_value_unset (&value);
+
+	/* length */
+	g_value_init (&value, G_TYPE_ULONG);
+	g_value_set_ulong (&value,(gulong)length / 1000);
+	rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_DURATION, &value);
+	g_value_unset (&value);
+
+	/* file size */
+	g_value_init (&value, G_TYPE_UINT64);
+	g_value_set_uint64(&value,(gint64)filesize);
+	rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_FILE_SIZE, &value);
+	g_value_unset (&value);
+
+	/* title */
+	entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_TITLE, title);
+
+	/* album */
+	entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_ALBUM, album);
+
+	/* artist */
+	entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_ARTIST, artist);
+
+	/* genre */
+	entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_GENRE, genre);
+
+	rhythmdb_commit (priv->db);
+}
+
+static void rb_dmap_db_adapter_init (RBDMAPDbAdapter *db)
+{
+	db->priv = RB_DMAP_DB_ADAPTER_GET_PRIVATE (db);
+	db->priv->db = NULL;
+}
+
+static void rb_dmap_db_adapter_class_init (RBDMAPDbAdapterClass *klass)
+{
+	g_type_class_add_private (klass, sizeof (RBDMAPDbAdapterPrivate));
+}
+
+static void rb_dmap_db_adapter_interface_init (gpointer iface, gpointer data)
+{
+	DMAPDbInterface *dmap_db = iface;
+
+	g_assert (G_TYPE_FROM_INTERFACE (dmap_db) == TYPE_DMAP_DB);
+
+	dmap_db->add = rb_dmap_db_adapter_add;
+	dmap_db->lookup_by_id = rb_dmap_db_adapter_lookup_by_id;
+	dmap_db->foreach = rb_dmap_db_adapter_foreach;
+	dmap_db->count = rb_dmap_db_adapter_count;
+}
+
+G_DEFINE_TYPE_WITH_CODE (RBDMAPDbAdapter, rb_dmap_db_adapter, G_TYPE_OBJECT, 
+			 G_IMPLEMENT_INTERFACE (TYPE_DMAP_DB, rb_dmap_db_adapter_interface_init))
+
+RBDMAPDbAdapter *rb_dmap_db_adapter_new (RhythmDB *rdb, RhythmDBEntryType type)
+{
+	RBDMAPDbAdapter *db;
+
+	db = RB_DMAP_DB_ADAPTER (g_object_new (TYPE_RB_DMAP_DB_ADAPTER,
+					       NULL));
+
+	db->priv->db = rdb;
+	db->priv->type = type;
+
+	return db;
+}
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/daap/rb-dmap-db-adapter.h rhythmbox-0.12.1/plugins/daap/rb-dmap-db-adapter.h
--- rhythmbox-0.12.1-vanilla/plugins/daap/rb-dmap-db-adapter.h	1969-12-31 19:00:00.000000000 -0500
+++ rhythmbox-0.12.1/plugins/daap/rb-dmap-db-adapter.h	2009-08-11 23:24:57.000000000 -0400
@@ -0,0 +1,55 @@
+/*
+ *  Database class for DMAP sharing
+ *
+ *  Copyright (C) 2008 W. Michael Petullo <mike@flyn.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __RB_DMAP_DB_ADAPTER
+#define __RB_DMAP_DB_ADAPTER
+
+#include <libdmapsharing/dmap.h>
+
+G_BEGIN_DECLS
+
+#define TYPE_RB_DMAP_DB_ADAPTER         (rb_dmap_db_adapter_get_type ())
+#define RB_DMAP_DB_ADAPTER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TYPE_RB_DMAP_DB_ADAPTER, RBDMAPDbAdapter))
+#define RB_DMAP_DB_ADAPTER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), TYPE_RB_DMAP_DB_ADAPTER, RBDMAPDbAdapterClass))
+#define IS_RB_DMAP_DB_ADAPTER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TYPE_RB_DMAP_DB_ADAPTER))
+#define IS_RB_DMAP_DB_ADAPTER_CLASS (k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_RB_DMAP_DB_ADAPTER_CLASS))
+#define RB_DMAP_DB_ADAPTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_RB_DMAP_DB_ADAPTER, RBDMAPDbAdapterClass))
+#define RB_DMAP_DB_ADAPTER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_RB_DMAP_DB_ADAPTER, RBDMAPDbAdapterPrivate))
+
+typedef struct RBDMAPDbAdapterPrivate RBDMAPDbAdapterPrivate;
+
+typedef struct {
+	GObject parent;
+	RBDMAPDbAdapterPrivate *priv;
+} RBDMAPDbAdapter;
+
+typedef struct {
+	GObjectClass parent;
+} RBDMAPDbAdapterClass;
+
+RBDMAPDbAdapter *rb_dmap_db_adapter_new (RhythmDB *db, RhythmDBEntryType type);
+GType rb_dmap_db_adapter_get_type (void);
+
+DMAPRecord *rb_dmap_db_adapter_lookup_by_id     (DMAPDb *db, guint id);
+gint rb_dmap_db_adapter_add (DMAPDb *db, DMAPRecord *record);
+
+#endif /* _RB_DMAP_DB_ADAPTER */
+
+G_END_DECLS
diff -u --recursive --new-file --exclude Makefile.in --exclude help --exclude doc rhythmbox-0.12.1-vanilla/plugins/Makefile.am rhythmbox-0.12.1/plugins/Makefile.am
--- rhythmbox-0.12.1-vanilla/plugins/Makefile.am	2009-04-20 03:38:14.000000000 -0400
+++ rhythmbox-0.12.1/plugins/Makefile.am	2009-08-10 20:50:45.000000000 -0400
@@ -44,7 +44,7 @@
 endif # HAVE_NAUTILUS_BURN
 endif # HAVE_LIBBRASERO_MEDIA
 
-if USE_DAAP
+if USE_LIBDMAPSHARING
 SUBDIRS += daap
 endif
 
