Commits

Anonymous committed c62d630

remove deprecated package cmus and tigervnc

Comments (0)

Files changed (12)

media-sound/cmus/ChangeLog

-# ChangeLog for media-sound/cmus
-# Copyright 1999-2009 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/media-sound/cmus/ChangeLog,v 1.30 2009/09/25 11:21:35 maekke Exp $
-
-  25 Sep 2009; Markus Meier <maekke@gentoo.org> cmus-2.2.0-r2.ebuild:
-  amd64 stable, bug #281605
-
-  16 Aug 2009; Christian Faulhammer <fauli@gentoo.org> cmus-2.2.0-r2.ebuild:
-  stable x86, bug 281605
-
-*cmus-2.2.0-r2 (26 Jul 2009)
-
-  26 Jul 2009; Samuli Suominen <ssuominen@gentoo.org> +cmus-2.2.0-r2.ebuild,
-  +files/cmus-2.2.0-libmpcdecsv7.patch:
-  Use transition package media-libs/libmpcdecsv7 instead of
-  media-libs/libmpcdec for Musepack support.
-
-  13 Jul 2009; Samuli Suominen <ssuominen@gentoo.org> cmus-2.2.0-r1.ebuild:
-  Remove USE mp3 since we have USE mad which is correct.
-
-  10 Jul 2009; Samuli Suominen <ssuominen@gentoo.org> cmus-2.2.0-r1.ebuild:
-  >= libmp4v2 1.9.0 changed include location; change it inside ebuild.
-
-  21 May 2009; Samuli Suominen <ssuominen@gentoo.org> cmus-2.2.0-r1.ebuild:
-  Remove arts support wrt #270575.
-
-  13 May 2009; Markus Meier <maekke@gentoo.org> cmus-2.2.0-r1.ebuild:
-  amd64 stable, bug #250474
-
-  12 May 2009; Christian Faulhammer <fauli@gentoo.org> cmus-2.2.0-r1.ebuild:
-  stable x86, security bug 250474
-
-*cmus-2.2.0-r1 (12 May 2009)
-
-  12 May 2009; Samuli Suominen <ssuominen@gentoo.org> +cmus-2.2.0-r1.ebuild,
-  +files/cmus-2.2.0-symlink_attack.patch:
-  CVE-2008-5375, symlink attack wrt #250474.
-
-  25 Oct 2008; Pieter Van den Abeele <pvdabeel@gentoo.org> cmus-2.2.0.ebuild:
-  Keyworded ~ppc. Closes bug #235775
-
-  22 Jul 2008; Alexis Ballier <aballier@gentoo.org> cmus-2.2.0.ebuild:
-  keyword ~x86-fbsd thanks to Davide Italiano <dav_it@gentoo.org>, bug
-  #232401
-
-  21 Jul 2008; Christian Faulhammer <opfer@gentoo.org> metadata.xml:
-  sound will maintain this
-
-  28 Apr 2008; Christian Faulhammer <opfer@gentoo.org>
-  +files/cmus-2.2.0-new-ffmpeg.patch, cmus-2.2.0.ebuild:
-  make it work with some newer versions of ffmpeg, see bug 218105; patch
-  provided by Ben de Groot <yngwin AT gentoo DOT org>
-
-  14 Oct 2007; Christian Faulhammer <opfer@gentoo.org> cmus-2.2.0.ebuild:
-  new HOMEPAGE value and new download location
-
-  22 Sep 2007; Christian Faulhammer <opfer@gentoo.org>
-  -files/cmus-2.1.0-faad-2.0.patch, -cmus-2.1.0-r1.ebuild:
-  clean up
-
-  22 Sep 2007; Christoph Mende <angelos@gentoo.org> cmus-2.2.0.ebuild:
-  Stable on amd64 wrt bug #193205
-
-  20 Sep 2007; Christian Faulhammer <opfer@gentoo.org> cmus-2.2.0.ebuild:
-  stable x86, bug 193205
-
-  01 Aug 2007; Christian Faulhammer <opfer@gentoo.org> cmus-2.2.0.ebuild:
-  put the correct entries in RDEPEND and not DEPEND
-
-*cmus-2.2.0 (30 Jul 2007)
-
-  30 Jul 2007; Christian Faulhammer <opfer@gentoo.org> metadata.xml,
-  +cmus-2.2.0.ebuild:
-  version bump with new features:
-  support for WMA (USE=wma) and wavpack (USE=wavpack)
-  several bugs fixed (partly been patched already in 2.1.0-r1)
-  install support script for net-im/pidgin (USE=pidgin)
-  install command completion for Zshell (USE=zsh-completion)
-  some rework on the ebuild itself
-
-  01 Jun 2007; Christian Faulhammer <opfer@gentoo.org> -cmus-2.1.0.ebuild,
-  cmus-2.1.0-r1.ebuild:
-  Add examples USE flag and clean up
-
-  31 May 2007; Daniel Gryniewicz <dang@gentoo.org> cmus-2.1.0-r1.ebuild:
-  Marked stable on amd64 for bug #180295
-
-  31 May 2007; Christian Faulhammer <opfer@gentoo.org> cmus-2.1.0-r1.ebuild:
-  fixed installation of example file, reported by Jonas Pedersen in bug 180295
-
-  30 May 2007; Christian Faulhammer <opfer@gentoo.org> cmus-2.1.0-r1.ebuild:
-  stable x86, bug 180295
-
-*cmus-2.1.0-r1 (14 Feb 2007)
-
-  14 Feb 2007; Christian Faulhammer <opfer@gentoo.org>
-  +files/cmus-2.1.0-faad-2.0.patch, +cmus-2.1.0-r1.ebuild:
-  add a patch from cmus mailing list that allows building against
-  media-libs/faad2 2.0, so now I can provide aac and mp4 USE flags
-
-  29 Jan 2007; Christian Faulhammer <opfer@gentoo.org> -cmus-2.0.4.ebuild:
-  clean up
-
-  25 Jan 2007; Steve Dibb <beandog@gentoo.org> cmus-2.1.0.ebuild:
-  Add ~amd64, bug 162375
-
-  25 Jan 2007; Christian Faulhammer <opfer@gentoo.org> cmus-2.1.0.ebuild:
-  added multilib capabilities, so amd64 can keyword this; thanks to beandog
-  for pointing out
-
-*cmus-2.1.0 (03 Jan 2007)
-
-  03 Jan 2007; Christian Faulhammer <opfer@gentoo.org> +cmus-2.1.0.ebuild:
-  version bump, added mikmod support via mikmod USE flac; support for flac 1.1.3
-
-  11 Dec 2006; Christian Faulhammer <opfer@gentoo.org> cmus-2.0.4.ebuild:
-  corrected flac dependency
-
-*cmus-2.0.4 (08 Nov 2006)
-
-  08 Nov 2006; Christian Faulhammer <opfer@gentoo.org> +metadata.xml,
-  +cmus-2.0.4.ebuild:
-  initial import. A nice console player with support for many formats via
-  plugins. See bug #88025, thanks to Timo Hirvonen <tihirvon@ee.oulu.fi> and
-  Nikolai Weibull <now@bitwi.se>.
-

media-sound/cmus/Manifest

-AUX audioscrobbler.patch 72439 RMD160 fc4269394d1e35e2d8c6b5b05a3db69bedf928ea SHA1 62ce8694c86a3e14e265f8b686956b2c1aca21f4 SHA256 34dc7259a91c25c6e6d17ffd8682ba96e724af304bd9dae3b3e2a88b4f608269
-AUX ffmpeg.patch 394 RMD160 b15ff19da7f65fba12ba2d8b8c88cb9abfc085a9 SHA1 720b90e263d33e7c5f52649fdaef1aa4b404d456 SHA256 4dca75866cf6ee1596f7702ddaabbd548d87732d8bcc2c380cbea7a901828874
-AUX libmpcdecsv7.patch 887 RMD160 1f82f712f16435e7d067217d73e3baccbaede131 SHA1 e9f67e7af0c7d3cfe3abfb310e0b56ed89b9f6b3 SHA256 f67f0797e53fdce3013240320a73a89201871bc226b71958b0d5ff8883ece522
-AUX mp4.patch 633 RMD160 4bc9935b2fe6c7140e16112ae5676492912dca78 SHA1 1233b6229946146755e353563fd52945f9b4ef4d SHA256 98edc1021d7ba9339a4e628f346b7982a21f827095aabf8d19be4018b9148f94
-AUX symlink_attack.patch 454 RMD160 324ba71f1fe66547f0c1ecfadd6a4253e47c3758 SHA1 41429212ae9e9738f19fc0211b1b6707c89a8d22 SHA256 11bee0e06b9e71bfb5649ebaf6ad1bdf5479b5e347a78a5f0138ce0955209d0d
-EBUILD cmus-9999.ebuild 3253 RMD160 e7901231e53eae12691ce7e96949cd0315a0546e SHA1 7d1e5fbd0c965ece9f3c8d81b51dfa78118a4d4c SHA256 4a4365878675583d5bbabfb70e301238bd2809f7c2da9493a4b6f80fa1ca91a5
-MISC ChangeLog 4801 RMD160 bde8dc3fa625ffb447a0ba5da2b1bdd47145a8e3 SHA1 29ac83678748cd25ef56de9753ab69b08d25d407 SHA256 21ee512bf7a48d6d24fa53df4fbf90fac15e0ba72e12d1529c268ac7a5bb8d8c
-MISC metadata.xml 393 RMD160 c267194299466d8685e762e14ad84e41a48accc6 SHA1 3b0b7bdc883c25319b866d768b80027032ec2cdd SHA256 c23322916957a25e9d0e817556ceca1aab4d87cfb7f972e264d391e46d9c504e

media-sound/cmus/cmus-2.2.2-r2.ebuild

-# Copyright 1999-2009 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/media-sound/cmus/cmus-2.2.0-r2.ebuild,v 1.4 2009/09/25 11:21:35 maekke Exp $
-
-EAPI=2
-inherit eutils multilib
-
-DESCRIPTION="A ncurses based music player with plugin support for many formats"
-HOMEPAGE="http://cmus.sourceforge.net/"
-SRC_URI="http://files.stu-cn.de/${P}.tar.bz2"
-
-LICENSE="GPL-2"
-SLOT="0"
-KEYWORDS="amd64 ~ppc x86 ~x86-fbsd"
-IUSE="aac alsa ao debug examples flac mad mikmod modplug mp4 musepack \
-	oss pidgin unicode vorbis wavpack wma zsh-completion"
-
-DEPEND="sys-libs/ncurses[unicode?]
-	aac? ( media-libs/faad2 )
-	alsa? ( >=media-libs/alsa-lib-1.0.11 )
-	ao? (  media-libs/libao )
-	flac? ( media-libs/flac )
-	mad? ( >=media-libs/libmad-0.14 )
-	mikmod? ( media-libs/libmikmod )
-	modplug? ( >=media-libs/libmodplug-0.7 )
-	mp4? ( >=media-libs/libmp4v2-1.9 )
-	musepack? ( media-libs/libmpcdecsv7 )
-	vorbis? ( >=media-libs/libvorbis-1.0 )
-	wavpack? ( media-sound/wavpack )
-	wma? ( >=media-video/ffmpeg-0.4.9_p20080326 )"
-RDEPEND="${DEPEND}
-	zsh-completion? ( app-shells/zsh )
-	pidgin? ( net-im/pidgin
-		dev-python/dbus-python )"
-
-my_config() {
-	local value
-	use ${1} && value=y || value=n
-	myconf="${myconf} ${2}=${value}"
-}
-
-src_prepare() {
-	epatch "${FILESDIR}"/symlink_attack.patch \
-		"${FILESDIR}"/audioscrobbler.patch \
-		"${FILESDIR}"/mp4.patch \
-		"${FILESDIR}"/libmpcdecsv7.patch
-
-}
-
-src_configure() {
-	local debuglevel=1 myconf="CONFIG_SUN=n"
-
-	use debug && debuglevel=2
-
-	my_config aac CONFIG_AAC
-	my_config ao CONFIG_AO
-	my_config alsa CONFIG_ALSA
-	my_config flac CONFIG_FLAC
-	my_config mad CONFIG_MAD
-	my_config mikmod CONFIG_MIKMOD
-	my_config mp4 CONFIG_MP4
-	my_config modplug CONFIG_MODPLUG
-	my_config musepack CONFIG_MPC
-	my_config oss CONFIG_OSS
-	my_config vorbis CONFIG_VORBIS
-	my_config wavpack CONFIG_WAVPACK
-	my_config wma CONFIG_FFMPEG
-
-	# econf doesn't work, because configure wants "prefix" (and similar) without dashes
-	./configure prefix=/usr ${myconf} exampledir=/usr/share/doc/${PF}/examples \
-		libdir=/usr/$(get_libdir) DEBUG=${debuglevel} || die "configure failed"
-}
-
-src_install() {
-	emake DESTDIR="${D}" install || die "emake install failed"
-	dodoc AUTHORS README
-	use examples || rm -rf "${D}/usr/share/doc/${PF}/examples/"
-
-	if use zsh-completion; then
-		insinto /usr/share/zsh/site-functions
-		doins contrib/_cmus
-	fi
-
-	if use pidgin; then
-		sed -i -e "s:/usr/local/bin/python:/usr/bin/python:" contrib/cmus-updatepidgin.py
-		newbin contrib/cmus-updatepidgin.py cmus-updatepidgin
-	fi
-}

media-sound/cmus/cmus-9999.ebuild

-# Copyright 1999-2009 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/media-sound/cmus/cmus-2.2.0-r2.ebuild,v 1.4 2009/09/25 11:21:35 maekke Exp $
-
-EAPI=2
-inherit eutils multilib git
-
-DESCRIPTION="A ncurses based music player with plugin support for many formats"
-HOMEPAGE="http://cmus.sourceforge.net/"
-SRC_URI=""
-EGIT_BRANCH="master"
-EGIT_REPO_URI="git://gitorious.org/cmus/cmus.git"
-
-#MY_PV="9999"
-#MY_P="${PN}-${MY_PV}"
-#S="${WORKDIR}/${MY_P}"
-#S="${WORKDIR}/cmus-9999"
-
-LICENSE="GPL-2"
-SLOT="0"
-KEYWORDS="amd64 ~ppc x86 ~x86-fbsd"
-IUSE="aac alsa ao debug examples flac mad mikmod modplug mp4 musepack \
-	oss pidgin unicode vorbis wavpack wma zsh-completion"
-
-DEPEND="sys-libs/ncurses[unicode?]
-	aac? ( media-libs/faad2 )
-	alsa? ( >=media-libs/alsa-lib-1.0.11 )
-	ao? (  media-libs/libao )
-	flac? ( media-libs/flac )
-	mad? ( >=media-libs/libmad-0.14 )
-	mikmod? ( media-libs/libmikmod )
-	modplug? ( >=media-libs/libmodplug-0.7 )
-	mp4? ( >=media-libs/libmp4v2-1.9 )
-	musepack? ( media-libs/libmpcdecsv7 )
-	vorbis? ( >=media-libs/libvorbis-1.0 )
-	wavpack? ( media-sound/wavpack )
-	wma? ( >=media-video/ffmpeg-0.4.9_p20080326 )"
-RDEPEND="${DEPEND}
-	zsh-completion? ( app-shells/zsh )
-	pidgin? ( net-im/pidgin
-		dev-python/dbus-python )"
-
-my_config() {
-	local value
-	use ${1} && value=y || value=n
-	myconf="${myconf} ${2}=${value}"
-}
-
-src_unpack() {
-	git_src_unpack ${A}
-	echo ${WORKDIR}
-	cd "/var/tmp/portage/media-sound/cmus-9999/work/"
-	#epatch "${FILESDIR}"/symlink_attack.patch \
-	#	   "${FILESDIR}"/audioscrobbler.patch \
-	#	   "${FILESDIR}"/mp4.patch \
-	#	   "${FILESDIR}"/ffmpeg.patch \
-	#	   "${FILESDIR}"/libmpcdecsv7.patch
-	#epatch "${FILESDIR}"/symlink_attack.patch \
-	epatch "${FILESDIR}"/ffmpeg.patch #\
-#		   "${FILESDIR}"/libmpcdecsv7.patch
-	#epatch "${FILESDIR}"/mp4.patch \
-	#epatch "${FILESDIR}"/ffmpeg.patch \
-	#	"${FILESDIR}"/libmpcdecsv7.patch
-}
-
-#src_prepare() {
-#	cd "${S}"
-#	epatch "${FILESDIR}"/symlink_attack.patch \
-##		"${FILESDIR}"/audioscrobbler.patch \
-#		"${FILESDIR}"/mp4.patch \
-#		"${FILESDIR}"/libmpcdecsv7.patch
-#}
-
-src_configure() {
-	local debuglevel=1 myconf="CONFIG_SUN=n"
-
-	use debug && debuglevel=2
-
-	my_config aac CONFIG_AAC
-	my_config ao CONFIG_AO
-	my_config alsa CONFIG_ALSA
-	my_config flac CONFIG_FLAC
-	my_config mad CONFIG_MAD
-	my_config mikmod CONFIG_MIKMOD
-	my_config mp4 CONFIG_MP4
-	my_config modplug CONFIG_MODPLUG
-	my_config musepack CONFIG_MPC
-	my_config oss CONFIG_OSS
-	my_config vorbis CONFIG_VORBIS
-	my_config wavpack CONFIG_WAVPACK
-	my_config wma CONFIG_FFMPEG
-
-	# econf doesn't work, because configure wants "prefix" (and similar) without dashes
-	./configure prefix=/usr ${myconf} exampledir=/usr/share/doc/${PF}/examples \
-		libdir=/usr/$(get_libdir) DEBUG=${debuglevel} || die "configure failed"
-}
-
-src_install() {
-	emake DESTDIR="${D}" install || die "emake install failed"
-	dodoc AUTHORS README
-	use examples || rm -rf "${D}/usr/share/doc/${PF}/examples/"
-
-	if use zsh-completion; then
-		insinto /usr/share/zsh/site-functions
-		doins contrib/_cmus
-	fi
-
-	if use pidgin; then
-		sed -i -e "s:/usr/local/bin/python:/usr/bin/python:" contrib/cmus-updatepidgin.py
-		newbin contrib/cmus-updatepidgin.py cmus-updatepidgin
-	fi
-}

media-sound/cmus/files/audioscrobbler.patch

-diff -ur cmus-9999.orig/Makefile cmus-9999/Makefile
-index 25dba2a..5d3e9fa 100644
---- cmus-9999.orig/Makefile
-+++ cmus-9999/Makefile
-@@ -9,8 +9,8 @@ CFLAGS += -D_FILE_OFFSET_BITS=64
- 
- CMUS_LIBS = $(PTHREAD_LIBS) $(NCURSES_LIBS) $(ICONV_LIBS) $(DL_LIBS) -lm $(COMPAT_LIBS)
- 
--input.o main.o ui_curses.o pulse.lo: .version
--input.o main.o ui_curses.o pulse.lo: CFLAGS += -DVERSION=\"$(VERSION)\"
-+as.o input.o main.o ui_curses.o pulse.lo: .version
-+as.o input.o main.o ui_curses.o pulse.lo: CFLAGS += -DVERSION=\"$(VERSION)\"
- main.o server.o: CFLAGS += -DDEFAULT_PORT=3000
- 
- .version: Makefile
-@@ -19,14 +19,14 @@ main.o server.o: CFLAGS += -DDEFAULT_PORT=3000
-
- # programs {{{
- cmus-y := \
--	ape.o browser.o buffer.o cache.o cmdline.o cmus.o command_mode.o comment.o \
-+	ape.o as.o browser.o buffer.o cache.o cmdline.o cmus.o command_mode.o comment.o \
- 	debug.o editable.o expr.o filters.o \
- 	format_print.o gbuf.o glob.o help.o history.o http.o id3.o input.o job.o \
--	keys.o keyval.o lib.o load_dir.o locking.o mergesort.o misc.o options.o \
-+	keys.o keyval.o lib.o load_dir.o locking.o network.o md5.o mergesort.o misc.o options.o \
- 	output.o pcm.o pl.o play_queue.o player.o \
- 	read_wrapper.o server.o search.o \
--	search_mode.o spawn.o tabexp.o tabexp_file.o \
--	track.o track_info.o tree.o uchar.o ui_curses.o \
-+	search_mode.o spawn.o strlib.o tabexp.o tabexp_file.o \
-+	track.o track_info.o tree.o uchar.o ui_curses.o window.o \
- 	utf8_encode.lo window.o worker.o xstrjoin.o
-
- $(cmus-y): CFLAGS += $(PTHREAD_CFLAGS) $(NCURSES_CFLAGS) $(ICONV_CFLAGS) $(DL_CFLAGS)
-diff -ur cmus-9999.orig/as.c cmus-9999/as.c
-new file mode 100644
-index 0000000..3d87d38
---- /dev/null
-+++ cmus-9999/as.c
-@@ -0,0 +1,930 @@
-+/*
-+ * Copyright 2004-2006 Timo Hirvonen
-+ *
-+ * as.[ch] by Frank Terbeck <ft@bewatermyfriend.org>
-+ * and Clay Barnes <clay@hci-matters.com>
-+ *
-+ * 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.
-+ */
-+
-+/*
-+ * see as.h and http://www.audioscrobbler.net
-+ */
-+
-+#include <pthread.h>
-+#include <time.h>
-+
-+#include "as.h"
-+#include "cmus.h"
-+#include "debug.h"
-+#include "list.h"
-+#include "locking.h"
-+#include "md5.h"
-+#include "network.h"
-+#include "player.h"
-+#include "strlib.h"
-+#include "utils.h"
-+
-+struct as_authinfo as_authinfo;
-+struct as_hsinfo as_hsinfo;
-+const char *as_numbers[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
-+time_t as_lasttimestamp = 0;
-+int as_enable = 0;
-+int running = 0;
-+
-+static pthread_mutex_t as_mutex = CMUS_MUTEX_INITIALIZER;
-+static pthread_t as_thread;
-+static LIST_HEAD(as_queue_head);
-+
-+static unsigned int as_count_entries(void)
-+{ /*{{{*/
-+	/* make sure as_lock() was called. */
-+	struct as_queue *entry;
-+	int count=0;
-+	list_for_each_entry(entry, &as_queue_head, node) {
-+		++count;
-+	}
-+	return(count);
-+} /*}}}*/
-+
-+static struct as_queue *as_get_last_entry(void)
-+{ /*{{{*/
-+	/* make sure as_lock() was called. */
-+	struct as_queue *entry;
-+	list_for_each_entry(entry, &as_queue_head, node) { }
-+	return(entry);
-+} /*}}}*/
-+
-+static void as_urlencode(string_t *str)
-+{ /*{{{*/
-+	const char *transtab[] =
-+	{ /*{{{*/
-+		" ",	"%20", /* 00 01 */
-+		"!",    "%21", /* 02 03 */
-+		"\"",	"%22", /* 04 05 */
-+		"#",	"%23", /* 06 07 */
-+		"%",	"%25", /* 08 09 */
-+		"&",	"%26", /* 10 11 */
-+		"'",	"%27", /* 12 13 */
-+		"(",	"%28", /* 14 15 */
-+		")",	"%29", /* 16 17 */
-+		"*",	"%2A", /* 18 19 */
-+		"-",    "%2D", /* 20 21 */
-+		"/",	"%2F", /* 22 23 */
-+		":",	"%3A", /* 24 25 */
-+		";",	"%3B", /* 26 27 */
-+		"<",	"%3C", /* 28 29 */
-+		"=",	"%3D", /* 30 31 */
-+		">",	"%3E", /* 32 33 */
-+		"?",	"%3F", /* 34 35 */
-+		"@",	"%40", /* 36 37 */
-+		"[",	"%5B", /* 38 39 */
-+		"\\",	"%5C", /* 40 41 */
-+		"]",	"%5D", /* 42 43 */
-+		"^",	"%5E", /* 44 45 */
-+		"`",	"%60", /* 46 47 */
-+		"{",	"%7B", /* 48 49 */
-+		"|",	"%7C", /* 50 51 */
-+		"}",	"%7D", /* 52 53 */
-+		"~",	"%7E", /* 54 55 */
-+	}; /*}}}*/
-+	int i, e, idx=-1;
-+	for (i=0; i<=str->len-1; ++i) {
-+		if (mustquote(str->s[i])) {
-+			for (e=0; e<=55; e+=2) {
-+				if (transtab[e][0] == str->s[i]) {
-+					idx=e+1;
-+					break;
-+				}
-+			}
-+			if (idx >= 0)
-+				str_nreplace(str, i, 1, transtab[idx], 3);
-+		}
-+	}
-+} /*}}}*/
-+
-+static void as_update_timestamp(void)
-+{ /*{{{*/
-+	as_lasttimestamp=time(NULL);
-+} /*}}}*/
-+
-+static void as_handshake(void)
-+{ /*{{{*/
-+	int sockfd;
-+	unsigned long int idx, odx;
-+	char buf[AS_BUFSIZE+1];
-+	ssize_t n;
-+	string_t msg, tmp;
-+
-+	/* no authentication values set, don't do anything */
-+	if (as_authinfo.user[0] == '\0' || as_authinfo.pass[0] == '\0')
-+		return;
-+
-+	/* prepare handshake request */
-+	str_init(&msg);
-+	str_init(&tmp);
-+	str_ncat(&msg, "GET ", 4); str_scat(&msg, AS_HS_URI);
-+	str_ncat(&msg, "&p=", 3);  str_scat(&msg, AS_PROTO);
-+	str_ncat(&msg, "&c=", 3);  str_ncat(&msg, AS_CLIENT_ID, 3);
-+	str_ncat(&msg, "&v=", 3);  str_scat(&msg, VERSION);         /* cmus' Version, that is */
-+	as_lock();
-+	str_scat(&tmp, as_authinfo.user);
-+	as_unlock();
-+	as_urlencode(&tmp);
-+	str_ncat(&msg, "&u=", 3);  str_cat(&msg, &tmp);
-+	str_ncat(&msg, " HTTP/1.1\r\nHost: ", 17); str_scat(&msg, AS_HOSTNAME);
-+	str_ncat(&msg, "\r\nConnection: CLOSE\r\n\r\n", 23);
-+
-+	/* connect() */
-+	if ( (sockfd = tcp_connect(AS_HOSTNAME, AS_HOSTPORT)) < 0 ) {
-+		d_print("tcp_connect() failed!\n");
-+		as_hsinfo.failed++;
-+		goto cleanup;
-+	}
-+
-+	/* submit our handshake request */
-+	xwriten(sockfd, msg.s, msg.len);
-+
-+	msg.s[0] = '\0';
-+	msg.len  = 0;
-+
-+	/* read server's response */
-+	for (;;) {
-+		if ( (n = xreadn(sockfd, buf, AS_BUFSIZE) ) <= 0)
-+			break;
-+		buf[n] = '\0';
-+		str_ncat(&msg, buf, n);
-+	}
-+	xclose(sockfd);
-+
-+#ifdef AS_HEAVY_DEBUG
-+	d_print("Serverreply:\n\"%s\"\n", msg.s);
-+#endif
-+
-+	/* parse the response we read */
-+	as_lock();
-+	if (str_ngetidx(&msg, 0, "\r\n\r\n", 4, &idx)) {
-+		str_nreplace(&msg, 0, idx+4, "", 0);
-+	}
-+	else {
-+		d_print("broken reply, couldn't find end of headers (\\r\\n\\r\\n)\n");
-+		as_hsinfo.failed++;
-+		goto cleanup;
-+	}
-+
-+	/*
-+	 * UPTODATE/UPDATE/FAILED/BADUSER
-+	 */
-+	idx=odx=0;
-+	if (!str_ngetidx(&msg, odx, "\n", 1, &idx)) {
-+		d_print("Broken input: \"%s\"\n", msg.s);
-+		as_hsinfo.failed++;
-+		goto cleanup;
-+	}
-+	str_ncpy(&tmp, msg.s+odx, idx-odx);
-+	if      (str_ngetidx(&tmp, 0, "UPTODATE", 8, NULL)) {
-+		d_print("received UPTODATE, good.\n");
-+	}
-+	else if (str_ngetidx(&tmp, 0, "UPDATE", 6, NULL)) {
-+		d_print("received UPDATE, get a new client, baby.\n");
-+	}
-+	else if (str_ngetidx(&tmp, 0, "FAILED", 6, NULL)) {
-+		d_print("received FAILED, crap :-/\n");
-+		as_hsinfo.failed++;
-+		goto cleanup;
-+	}
-+	else if (str_ngetidx(&tmp, 0, "BADUSER", 7, NULL)) {
-+		d_print("received BADUSER, err, check as_user setting.\n");
-+		as_hsinfo.failed++;
-+		goto cleanup;
-+	}
-+	else {
-+		d_print("Unknown response: \"%s\"\n", tmp.s);
-+		as_hsinfo.failed++;
-+		goto cleanup;
-+	}
-+
-+	/*
-+	 * -challenge-
-+	 */
-+	odx=idx+1;
-+	if (!str_ngetidx(&msg, odx, "\n", 1, &idx)) {
-+		d_print("Broken input: \"%s\"\n", msg.s);
-+		as_hsinfo.failed++;
-+		goto cleanup;
-+	}
-+	str_ncpy(&tmp, msg.s+odx, idx-odx);
-+	str_cpy(&(as_hsinfo.challenge), &tmp);
-+
-+	/*
-+	 * -url-to-submit-script
-+	 */
-+	odx=idx+1;
-+	if (!str_ngetidx(&msg, odx, "\n", 1, &idx)) {
-+		d_print("Broken input: \"%s\"\n", msg.s);
-+		as_hsinfo.failed++;
-+		goto cleanup;
-+	}
-+	str_ncpy(&tmp, msg.s+odx, idx-odx);
-+	odx=idx+1;
-+	if (str_ngetidx(&tmp, 0, "://", 3, &idx)) {
-+		if (idx+3 <= tmp.len)
-+			str_nreplace(&tmp, 0, idx+3, "", 0);
-+	}
-+	else
-+		d_print("hrm, no service mnemonic? (%s)\n)", tmp.s);
-+
-+	if (str_ngetidx(&tmp, 0, "/", 1, &idx) && (idx <= tmp.len)) {
-+		str_ncpy(&as_hsinfo.path, tmp.s+idx, tmp.len-idx);
-+		str_nreplace(&tmp, idx, tmp.len-idx, "", 0);
-+	}
-+	else {
-+		d_print("um, no path? (%s)\n", tmp.s);
-+		as_hsinfo.failed++;
-+	}
-+
-+	if (str_ngetidx(&tmp, 0, ":", 1, &idx)) {
-+		strncpy(as_hsinfo.port, tmp.s+idx+1, (tmp.len-idx < AS_MAXTMPLEN ? tmp.len-idx : AS_MAXTMPLEN));
-+		as_hsinfo.port[(tmp.len-idx < AS_MAXTMPLEN ? tmp.len-idx : AS_MAXTMPLEN)] = '\0';
-+	}
-+	else {
-+		d_print("well, no port definition? That, would be okay, default: 80. (%s)", tmp.s);
-+		as_hsinfo.port[0] = '8'; as_hsinfo.port[1] = '0'; as_hsinfo.port[2] = '\0';
-+	}
-+	str_ncpy(&(as_hsinfo.host), tmp.s, idx);
-+
-+#ifdef AS_HEAVY_DEBUG
-+	d_print("debug as_hsinfo:\n\thost: \"%s\"\n\tpath: \"%s\"\n\tport: \"%s\"\n",
-+			as_hsinfo.host.s, as_hsinfo.path.s, as_hsinfo.port);
-+#endif
-+
-+	/*
-+	 * -INTERVAL-
-+	 */
-+	odx=idx+1;
-+	if (!str_ngetidx(&msg, odx, "\n", 1, &idx)) {
-+		d_print("Broken input: \"%s\"\n", msg.s);
-+		goto cleanup;
-+	}
-+	str_ncpy(&tmp, msg.s+odx, idx-odx);
-+	if (str_ngetidx(&tmp, 0, "INTERVAL ", 9, NULL)) {
-+		as_hsinfo.interval=atoi(tmp.s+9);
-+		d_print("Our Interval is: %d\n", (int)as_hsinfo.interval);
-+	}
-+
-+	/* handshake suceeded, all values set. */
-+	as_hsinfo.need_handshake=0;
-+
-+cleanup:
-+	as_unlock();
-+	str_free(&tmp);
-+	str_free(&msg);
-+} /*}}}*/
-+
-+static int as_submit_allowed(void)
-+{ /*{{{*/
-+	/*
-+	 * honor INTERVAL response from the server
-+	 */
-+	const time_t now = time(NULL);
-+	time_t at;
-+	as_lock();
-+	at = as_hsinfo.interval + as_lasttimestamp;
-+	as_unlock();
-+	if (now >= at)
-+		return(1);
-+	return(0);
-+} /*}}}*/
-+
-+static int as_submit_forced(void)
-+{ /*{{{*/
-+	/*
-+	 * queue maximum is 10, so we force submission at 8 entries
-+	 */
-+	unsigned int n;
-+	as_lock();
-+	n = as_count_entries();
-+	as_unlock();
-+	if (n >= AS_FORCE_SUBMIT)
-+		return(1);
-+	return(0);
-+} /*}}}*/
-+
-+static void as_del_queue(struct list_head *item)
-+{ /*{{{*/
-+	/* make sure as_lock() was called. */
-+	struct as_queue *tmp;
-+
-+	tmp=list_entry(item, struct as_queue, node);
-+	d_print("     string: %s\n",  tmp->s.s);
-+	d_print("     NEEDRN: %d\n",  tmp->needrenumber);
-+	d_print("     SUBMIT: %d\n",  tmp->sc);
-+	d_print("     num   : %d\n",  tmp->num);
-+	str_free(&(tmp->s));
-+	list_del(item);
-+	free(tmp);
-+} /*}}}*/
-+
-+static void as_destroy_queue(int scmask)
-+{ /*{{{*/
-+	/* make sure as_lock() was called. */
-+	struct as_queue *pos, *tmp;
-+
-+	list_for_each_entry_safe(pos, tmp, &as_queue_head, node) {
-+		if (pos->sc & scmask)
-+			as_del_queue(&(pos->node));
-+	}
-+} /*}}}*/
-+
-+static void as_renumberentry(string_t *entry, unsigned short int num)
-+{ /*{{{*/
-+	unsigned long idx, odx = 0;
-+	while (str_ngetidx(entry, odx, "]=", 2, &idx)) {
-+		if (idx > 0) {
-+			d_print("replacing %c with %c\n", entry->s[idx-1], as_numbers[num][0]);
-+			entry->s[idx-1] = as_numbers[num][0];
-+		}
-+		odx=idx+2;
-+	}
-+} /*}}}*/
-+
-+static unsigned short int as_uint2string(unsigned int integer, char *str)
-+{ /*{{{*/
-+	unsigned short int dn, i, digit;
-+	unsigned int tmp;
-+
-+	if (integer >= 0 && integer <= 9) {
-+		dn=1;
-+		str[0] = as_numbers[integer][0];
-+		str[1] = '\0';
-+	}
-+	else {
-+		dn=0;
-+		tmp=integer;
-+		while (tmp) {
-+			++dn;
-+			tmp/=10;
-+		}
-+	}
-+	for (i=dn; i > 0 ; --i) {
-+		digit=integer%10;
-+		integer/=10;
-+		str[i-1] = as_numbers[digit][0];
-+	}
-+	str[dn] = '\0';
-+	return(dn);
-+} /*}}}*/
-+
-+static void as_digest2hex(unsigned char *hex, const unsigned char *digest)
-+{ /*{{{*/
-+	char hc[] = "0123456789abcdef";
-+	unsigned int i, e=0;
-+
-+	memset(hex, 0, 33*sizeof(unsigned char));
-+
-+	for(i = 0; i < 16; i++) {
-+		hex[e++] = hc[(digest[i] >> 4) & 0x0f];
-+		hex[e++] = hc[ digest[i]       & 0x0f];
-+	}
-+	hex[32] = '\0';
-+} /*}}}*/
-+
-+static void as_submit(void)
-+{ /*{{{*/
-+	string_t msg_header, msg_content, stmp, msg;
-+	struct as_queue *entry;
-+	unsigned char digest[16], tmp[65], md5response[33];
-+	char i2s[AS_MAXTMPLEN];
-+	char buf[AS_BUFSIZE];
-+	unsigned long int idx, odx, submissions=0;
-+	ssize_t n;
-+	int sockfd;
-+	int testval;
-+	int ign=0;
-+
-+	/*
-+	 * we need authentication setup, data to submit in our queue
-+	 * and the handshake must have taken place already. abort otherwise.
-+	 */
-+	as_lock();
-+	testval = (as_authinfo.user[0] == '\0' || as_authinfo.pass[0] == '\0'
-+		   || as_hsinfo.need_handshake == 1 || list_empty(&as_queue_head));
-+	as_unlock();
-+	if (testval)
-+		return;
-+
-+	/*
-+	 * creating the md5response described in the protocol v1.1 definition
-+	 *   - create md5 checksum of $as_pass and covert it to hex
-+	 *   - append the md5challenge received in handshake to the just created string
-+	 *   - create md5 checksum of the concatenated string and convert it to hex.
-+	 * That's it.
-+	 */
-+	as_lock();
-+	md5_csum(as_authinfo.pass, strlen(as_authinfo.pass), digest);
-+	as_digest2hex(tmp, digest);
-+	strncpy(tmp+32, as_hsinfo.challenge.s, 32);
-+	tmp[64] = '\0';
-+	md5_csum(tmp, 64, digest);
-+	as_digest2hex(md5response, digest);
-+
-+	str_init(&msg_header);
-+	str_init(&msg_content);
-+	str_init(&stmp);
-+	str_init(&msg);
-+	/*
-+	 * assemble our payload
-+	 */
-+	str_ncat(&msg_content, "u=",    2); str_scat(&msg_content, as_authinfo.user);
-+	str_ncat(&msg_content, "&s=",   3); str_scat(&msg_content, md5response);
-+	list_for_each_entry(entry, &as_queue_head, node) {
-+		if (ign && entry->sc == AS_SC_DO_SUBMIT) {
-+			entry->num-=ign;
-+			entry->needrenumber=1;
-+		}
-+		if (entry->needrenumber) {
-+			as_renumberentry(&(entry->s), entry->num);
-+			entry->needrenumber=0;
-+		}
-+		if (entry->sc == AS_SC_DO_SUBMIT) {
-+			str_cat(&msg_content, &(entry->s));
-+			entry->sc = AS_SC_SUBMITTED;
-+			++submissions;
-+			d_print("scrobbling: \"%s\"\n", entry->s.s);
-+		}
-+		else {
-+			++ign;
-+			d_print("ignoring: \"%s\"\n", entry->s.s);
-+		}
-+	}
-+	if (!submissions) {
-+		/* no submissions, eh? */
-+		as_unlock();
-+		goto cleanup;
-+	}
-+	as_uint2string(msg_content.len, i2s); /* note the length of our payload for later use */
-+	str_ncat(&msg_content, "\n", 1);
-+
-+	/* create http/1.1 header for our submission */
-+	str_ncat(&msg_header, "POST ", 5);  str_cat(&msg_header, &(as_hsinfo.path)); str_ncat(&msg_header, " HTTP/1.1\r\n", 11);
-+	str_ncat(&msg_header, "Host: ", 6); str_cat(&msg_header, &(as_hsinfo.host)); str_ncat(&msg_header, "\r\n", 2);
-+	str_ncat(&msg_header, AS_UASTRING, AS_UASTRINGLEN);
-+	str_ncat(&msg_header, "Pragma: no-cache", 16);
-+	str_ncat(&msg_header, "\r\nContent-Type: application/x-www-form-urlencoded", 49);
-+	str_ncat(&msg_header, "\r\nContent-Length: ", 18); str_scat(&msg_header, i2s);
-+	str_ncat(&msg_header, "\r\nConnection: CLOSE\r\n\r\n", 23);
-+
-+	/* turn payload's special chars to utf8 */
-+	/*str_lat1_to_utf8(&msg, &msg_content);
-+	str_cpy(&msg_content, &msg);*/
-+
-+#ifdef AS_HEAVY_DEBUG
-+	d_print("POSTING: \"%s%s\"\n", msg_header.s, msg_content.s);
-+#endif
-+
-+	as_unlock();
-+
-+	/*
-+	 * connect to the server we got in the handshake
-+	 */
-+	if ( (sockfd = tcp_connect(as_hsinfo.host.s, as_hsinfo.port)) < 0 ) {
-+		d_print("tcp_connect() failed!\n");
-+		as_lock();
-+		as_hsinfo.failed++;
-+		as_unlock();
-+		goto cleanup;
-+	}
-+
-+	/*
-+	 * send our submission to the server
-+	 */
-+	str_cpy(&msg, &msg_header);
-+	str_cat(&msg, &msg_content);
-+	xwriten(sockfd, msg.s, msg.len);
-+	str_free(&msg);
-+
-+	msg_content.s[0] = '\0';
-+	msg_content.len  = 0;
-+
-+	/* read response to our submission */
-+	for (;;) {
-+		if ( (n = xreadn(sockfd, buf, AS_BUFSIZE) ) <= 0)
-+			break;
-+		buf[n] = '\0';
-+		str_ncat(&msg_content, buf, n);
-+	}
-+	xclose(sockfd);
-+
-+#ifdef AS_HEAVY_DEBUG
-+	d_print("Serverreply:\n\"%s\"\n", msg_content.s);
-+#endif
-+
-+	/* parse the response */
-+	as_lock();
-+	if (str_ngetidx(&msg_content, 0, "\r\n\r\n", 4, &idx)) {
-+		str_nreplace(&msg_content, 0, idx+4, "", 0);
-+	}
-+	else {
-+		d_print("broken reply, couldn't find end of headers (\\r\\n\\r\\n)\n");
-+		as_hsinfo.failed++;
-+		as_unlock();
-+		goto cleanup;
-+	}
-+	odx=0;
-+	if (!str_ngetidx(&msg_content, odx, "\n", 1, &idx)) {
-+		d_print("Broken input: \"%s\"\n", msg_content.s);
-+		as_hsinfo.failed++;
-+		as_unlock();
-+		goto cleanup;
-+	}
-+	str_ncpy(&stmp, msg_content.s+odx, idx-odx);
-+
-+	/* OK/FAILED/BADAUTH */
-+	if      (str_ngetidx(&stmp, 0, "OK", 2, NULL)) {
-+		d_print("received an OK, good.\n");
-+	}
-+	else if (str_ngetidx(&stmp, 0, "FAILED", 6, NULL)) {
-+		stmp.s[idx] = '\0';
-+		d_print("received FAILED (%s)\n", stmp.s+odx);
-+		as_hsinfo.failed++;
-+		as_unlock();
-+		goto cleanup;
-+	}
-+	else if (str_ngetidx(&stmp, 0, "BADAUTH", 7, NULL)) {
-+		d_print("received BADUSER, err, check as_user setting.\n");
-+		as_hsinfo.failed++;
-+		as_unlock();
-+		goto cleanup;
-+	}
-+	else {
-+		d_print("Unknown response: \"%s\"\n", stmp.s);
-+		as_hsinfo.failed++;
-+		as_unlock();
-+		goto cleanup;
-+	}
-+
-+	/* INTERVAL is optional here. */
-+	odx=idx+1;
-+	if (str_ngetidx(&msg_content, odx, "\n", 1, &idx)) {
-+		str_ncpy(&stmp, msg_content.s+odx, idx-odx);
-+		if (str_ngetidx(&stmp, 0, "INTERVAL ", 9, NULL)) {
-+			as_hsinfo.interval=atoi(stmp.s+9);
-+			d_print("Our Interval is: %d\n", (int)as_hsinfo.interval);
-+		}
-+	}
-+	as_unlock();
-+
-+	/*
-+	 * submission suceeded
-+	 * destroy the part of the queue, that holds these
-+	 */
-+	as_destroy_queue(AS_SC_SUBMITTED);
-+cleanup:
-+	if (as_hsinfo.failed) {
-+		/* resetting AS_SC_SUBMITTED, because something went wrong */
-+		list_for_each_entry(entry, &as_queue_head, node) {
-+			if (entry->sc == AS_SC_SUBMITTED)
-+				entry->sc = AS_SC_DO_SUBMIT;
-+		}
-+	}
-+	str_free(&msg);
-+	str_free(&stmp);
-+	str_free(&msg_header);
-+	str_free(&msg_content);
-+} /*}}}*/
-+
-+static void as_gettimestring(char *str, int maxlen)
-+{ /*{{{*/
-+	const time_t now = time(NULL);
-+	const struct tm *timeinfo = gmtime(&now);
-+	strftime(str, maxlen, "%Y%%2d%m%%2d%d%%20%H%%3a%M%%3a%S", timeinfo);
-+} /*}}}*/
-+
-+static void as_add_queue(string_t *trackartist,
-+			 string_t *trackalbum,
-+			 string_t *trackname,
-+			 int tracklen, int submissioncode)
-+{ /*{{{*/
-+	/*
-+	 * Description:
-+	 *  This adds a track to the submission-queue.
-+	 *  Only 10 Tracks are allowed to be submitted at once.
-+	 *  So, if we run past this limit, delete this first item of the list
-+	 *  and append this track to the end of the list.
-+	 */
-+	struct as_queue *ptr, *tmp;
-+	char tmpstr[AS_MAXTMPLEN+1];
-+	int tmplen;
-+	int queue_size;
-+
-+	d_print("adding track to as_queue:\n");
-+	d_print("     Artist: %s\n",  trackartist->s);
-+	d_print("     Album : %s\n",  trackalbum->s);
-+	d_print("     Name  : %s\n",  trackname->s);
-+	d_print("     Length: %d\n",  tracklen);
-+
-+	if (!(ptr=malloc(sizeof(struct as_queue)))) {
-+		d_print("uark! out of memory? I give up.");
-+		return;
-+	}
-+
-+	as_lock();
-+
-+	if (list_empty(&as_queue_head)) {
-+		ptr->num=0;
-+		list_add_tail(&(ptr->node), &as_queue_head);
-+	}
-+	else {
-+		/* let's find our place in the queue */
-+		queue_size=as_count_entries();
-+		tmp = as_get_last_entry();
-+		if (queue_size >= AS_QUEUE_MAX) {
-+			as_del_queue(as_queue_head.next);
-+			ptr->num=AS_QUEUE_MAX;
-+			list_add_tail(&(ptr->node), &as_queue_head);
-+			list_for_each_entry(tmp, &as_queue_head, node) {
-+				tmp->num--;
-+				tmp->needrenumber=1;
-+			}
-+		}
-+		else {
-+			list_add_tail(&(ptr->node), &as_queue_head);
-+			ptr->num=queue_size;
-+		}
-+	}
-+
-+	str_init(&(ptr->s));
-+	ptr->sc=submissioncode;
-+	ptr->needrenumber=0;
-+	ptr->len=tracklen;
-+	/* set up the request string */
-+	as_urlencode(trackartist);
-+	as_urlencode(trackalbum);
-+	as_urlencode(trackname);
-+	as_addtag(ptr->s, trackartist, "&a[");
-+	as_addtag(ptr->s, trackname,   "&t[");
-+	as_addtag(ptr->s, trackalbum,  "&b[");
-+	/*
-+	 * MusicBrainz ID, I'm just sending an empty one, because the
-+	 * protocol definition says "don't skip it"
-+	 */
-+	str_readya(&(ptr->s), 6);
-+	str_ncat(  &(ptr->s), "&m[", 3);
-+	str_ncat(  &(ptr->s), as_numbers[ptr->num], 1);
-+	str_ncat(  &(ptr->s), "]=", 2);
-+	tmplen = as_uint2string(ptr->len, tmpstr);
-+	as_addntag(ptr->s, tmpstr, tmplen, "&l[");
-+	as_gettimestring(tmpstr, AS_MAXTMPLEN);
-+	as_addntag(ptr->s, tmpstr, AS_MAXTMPLEN-1, "&i[");
-+	as_unlock();
-+} /*}}}*/
-+
-+void as_hook(enum as_actions action)
-+{ /*{{{*/
-+	/*
-+	 * When do we need to call as_hook()?
-+	 *  + stop
-+	 *  + seek
-+	 *  + next
-+	 *  + prev
-+	 *  + automatic song change
-+	 *
-+	 * What do we need to know?
-+	 *  + track length
-+	 *  + track position (we query player_info for that)
-+	 *  + the action that called us
-+	 *  + track name
-+	 *  + artist
-+	 *  + album
-+	 */
-+	static int lastwasinvalid   = 0; /* these 2 static ints are there */
-+	static int alreadysubmitted = 0; /* to handle AS_SEEK properly.   */
-+	int trackpos, tracklen;
-+	int testval;
-+	const char *tmp;
-+	string_t trackartist, trackalbum, trackname;
-+
-+#ifdef AS_HEAVY_DEBUG
-+	d_print("-- ping -----------------HOOOOK!1!!-------------------------------------\n");
-+#endif
-+
-+	as_lock();
-+	testval=running;
-+	as_unlock();
-+	if (!testval)
-+		return;
-+
-+	if (lastwasinvalid) {
-+		/*
-+		 * last was invalid; if something else than SEEK
-+		 * was done, this would submit the invalid track, so we
-+		 * reset lastwasinvalid here and return.
-+		 *
-+		 * if SEEK was invoked again, we just return, because
-+		 * the track was marked as invalid before.
-+		 */
-+		if (action != AS_SEEK)
-+			lastwasinvalid = 0;
-+		return;
-+	}
-+	if (alreadysubmitted) {
-+		if (action != AS_SEEK)
-+			alreadysubmitted = 0;
-+		return;
-+	}
-+
-+	player_info_lock();
-+	trackpos=player_info.pos;
-+
-+	if (player_info.ti == NULL) {
-+		player_info_unlock();
-+		return;
-+	}
-+
-+	tracklen=player_info.ti->duration;
-+
-+	if (tracklen < AS_TRACK_MINLEN) { /* track is not long enough */
-+		player_info_unlock();
-+		return;
-+	}
-+	if (trackpos < AS_TRACK_MINSECS && (tracklen/2 > trackpos)) { /* track did not play long enough */
-+		/*
-+		 * if we were called in NEXT, PREV, STOP or *_ENTER
-+		 * we already did skip to the next track (or stopped),
-+		 * which means, we don't need to save this one for later review.
-+		 * So, we return.
-+		 */
-+		player_info_unlock();
-+		if (action != AS_SEEK)
-+			return;
-+
-+		lastwasinvalid = 1;
-+		return;
-+	}
-+
-+	str_init(&trackartist);
-+	str_init(&trackalbum);
-+	str_init(&trackname);
-+	tmp=keyvals_get_val(player_info.ti->comments, "artist");
-+	str_scpy(&trackartist, tmp);
-+	tmp=keyvals_get_val(player_info.ti->comments, "album");
-+	str_scpy(&trackalbum, tmp);
-+	tmp=keyvals_get_val(player_info.ti->comments, "title");
-+	str_scpy(&trackname, tmp);
-+	player_info_unlock();
-+
-+	if (trackartist.len == 0 || trackalbum.len == 0 || trackname.len == 0) {
-+		/* One of the tags we must supply is empty */
-+		return;
-+	}
-+
-+	as_add_queue(&trackartist, &trackalbum, &trackname, tracklen, AS_SC_DO_SUBMIT);
-+
-+	if (action == AS_SEEK)
-+		alreadysubmitted = 1;
-+
-+	str_free(&trackartist);
-+	str_free(&trackalbum);
-+	str_free(&trackname);
-+} /*}}}*/
-+
-+static void as_sleep(void)
-+{ /*{{{*/
-+	struct timespec r;
-+	r.tv_sec=AS_SLEEPSEC;
-+	r.tv_nsec=AS_SLEEPNANO;
-+	nanosleep(&r, NULL);
-+} /*}}}*/
-+
-+void *as_loop(void *arg)
-+{ /*{{{*/
-+	/*
-+	 * main audio scrobbler loop
-+	 *  Here, all communication is done.
-+	 *  Needed information is provided by *as_queue,
-+	 *  which is filled by as_hook()
-+	 *
-+	 *  TODO: AS_SC_DONT_SUBMIT cases must be handled (eg. the user used seek on a track before it fitted our needs).
-+	 */
-+	static int last_as_state=0;
-+	int testval;
-+	struct as_queue *e;
-+
-+	for (;;) {
-+#ifdef AS_HEAVY_DEBUG
-+		d_print("-- ping ----------------------------------------------------------------\n");
-+#endif
-+		as_update_timestamp();
-+		as_lock();
-+		testval = list_empty(&as_queue_head);
-+		as_unlock();
-+		if (testval) {
-+			/* nothing to submit */
-+			if (!running) {
-+				/*
-+				 * running isn't set,
-+				 * seems like the user switched us off
-+				 */
-+				return(NULL);
-+			}
-+			as_sleep();
-+		}
-+		else {
-+			as_lock();
-+			list_for_each_entry(e, &as_queue_head, node) {
-+				d_print("--DEBUG--\n");
-+				d_print("     Number: %d\n",   e->num);
-+				d_print("     SCode : %d\n",   e->sc);
-+				d_print("     Length: %d\n",   e->len);
-+				d_print("     NEEDRN: %d\n",   e->needrenumber);
-+				d_print("     string: %s\n\n", e->s.s);
-+			}
-+			as_unlock();
-+			as_sleep();
-+			as_lock();
-+			testval = as_hsinfo.need_handshake;
-+			as_unlock();
-+			if (testval) {
-+				as_handshake();
-+			}
-+			as_lock();
-+			testval = as_hsinfo.need_handshake;
-+			as_unlock();
-+			if (!testval) {
-+				/*
-+				 * we are enabled, got data to submit and don't need to handshake.
-+				 * check, if we may (or need to force to) submit our data,
-+				 * and do so, if needed.
-+				 *
-+				 * XXX: as_submit_allowed() and as_submit_forced() do locking on their own.
-+				 */
-+				if (as_submit_allowed() || as_submit_forced()) {
-+					as_submit();
-+				}
-+			}
-+		}
-+
-+		as_lock();
-+		if (!as_enable && !last_as_state) {
-+			/*
-+			 * user didn't enable us in the first place.
-+			 * so, set running to 0 and rerun loop, so we can exit
-+			 */
-+			running=0;
-+		}
-+		else if (!as_enable && last_as_state) {
-+			/* as_enable was on before, so terminate session */
-+			running=0;
-+			last_as_state=0;
-+		}
-+		else if (!last_as_state && as_enable) {
-+			/* (re)start as session */
-+			running=1;
-+			as_hsinfo.need_handshake=1;
-+			last_as_state=1;
-+		}
-+		as_unlock();
-+	}
-+} /*}}}*/
-+
-+void as_init(void)
-+{ /*{{{*/
-+	int rc;
-+	as_lock();
-+	running=1;
-+	str_init(&(as_hsinfo.challenge));
-+	str_init(&(as_hsinfo.host));
-+	str_init(&(as_hsinfo.path));
-+	as_hsinfo.need_handshake = 1;
-+	as_hsinfo.interval = 0;
-+	as_hsinfo.failed = 0;
-+	as_lasttimestamp = 0;
-+	as_unlock();
-+	rc = pthread_create(&as_thread, NULL, as_loop, NULL);
-+	BUG_ON(rc);
-+} /*}}}*/
-+
-+void as_exit(void)
-+{ /*{{{*/
-+	as_lock();
-+	running = 0;
-+	as_destroy_queue(AS_SC_ALL);
-+	str_free(&(as_hsinfo.challenge));
-+	str_free(&(as_hsinfo.host));
-+	str_free(&(as_hsinfo.path));
-+	as_unlock();
-+	pthread_join(as_thread, NULL);
-+} /*}}}*/
-diff -ur cmus-9999.orig/as.h cmus-9999/as.h
-new file mode 100644
-index 0000000..e1dc638
---- /dev/null
-+++ cmus-9999/as.h
-@@ -0,0 +1,210 @@
-+/*
-+ * Copyright 2004-2006 Timo Hirvonen
-+ *
-+ * as.[ch] by Frank Terbeck <ft@bewatermyfriend.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 x__AS_H
-+#define x__AS_H
-+
-+/*
-+ * audioscrobbler code for cmus {{{
-+ *   (read: get cmus properly working with http://last.fm/
-+ *
-+ * When are songs submitted?
-+ *  + Each song should be posted to the server when it is 50%
-+ *    or 240 seconds complete, whichever comes first.
-+ *
-+ *  + If a user seeks (i.e. manually changes position) within a song
-+ *    before the song is due to be submitted, do not submit that song.
-+ *
-+ *  + Songs with a duration of less than 30 seconds should not be
-+ *    submitted (so, we don't do that).
-+ *
-+ *  + Do not try to guess info from the filename - if there are no
-+ *    tags, don't submit the file (okeydoke, herman).
-+ *
-+ *  + If a MusicBrainz ID is present in the file (as defined here),
-+ *    then you should send it (whatever that is...[1]).
-+ *
-+ *  + If a user is playing a stream instead of a regular file, do
-+ *    not submit that stream/song.
-+ *
-+ *********************************************************************
-+ *
-+ * [1] About musicbrainz.org:
-+ *      I don't know what that is, nor do I care. Feel free to
-+ *      implement support for it, if you need it desperately.
-+ *}}}
-+ */
-+
-+#include "list.h"
-+#include "options.h"
-+#include "strlib.h"
-+#include "track_info.h"
-+
-+/* #defines */
-+
-+/* We are currently testing things, so "tst" is okay. */
-+#define AS_UASTRING        "User-Agent: AudioScrobbler/1.1 cmus-scrobbler code v0.01\r\n"
-+#define AS_UASTRINGLEN       58
-+#define AS_CLIENT_ID       "tst"
-+#define AS_PROTO           "1.1"
-+
-+#define AS_HOSTNAME        "post.audioscrobbler.com"
-+#define AS_HOSTPORT        "80"
-+#define AS_HS_URI          "/?hs=true"
-+
-+#define AS_BUFSIZE         4096
-+
-+/* AS_QUEUE_MAX must of an element of [1..10] */
-+#define AS_QUEUE_MAX         10
-+
-+/*
-+ * AS_FORCE_SUBMIT:
-+ * if our queue holds this many entries, force submission,
-+ * no matter what the last INTERVAL response said.
-+ */
-+#define AS_FORCE_SUBMIT       8
-+
-+/* AS_DO_SUBMIT marks a track for submission */
-+#define AS_SC_DO_SUBMIT       1
-+
-+/* AS_DONT_SUBMIT is used if seek was used at the beginning of a track */
-+#define AS_SC_DONT_SUBMIT     2
-+
-+/* AS_SC_SUBMITTED marks tracks, that where included in a submission msg */
-+#define AS_SC_SUBMITTED       4
-+
-+/* AS_SC_ALL is the same as ORing together all other AS_SC_* macros */
-+#define AS_SC_ALL            15
-+
-+/* The minimum length of a track to be considered for submission */
-+#define AS_TRACK_MINLEN      30
-+
-+/* A track must have run 50% of its time or AS_TRACK_MINSECS seconds */
-+#define AS_TRACK_MINSECS    240
-+
-+/* AS_SLEEP* sets up the resolution of as_loop() */
-+#define AS_SLEEPSEC           5
-+#define AS_SLEEPNANO          0
-+
-+/*
-+ * for temporary static strings, that need to be long enough
-+ * to hold an url_encoded time string (25+1); this is used for
-+ * strings that are converted integers.
-+ */
-+#define AS_MAXTMPLEN         30
-+
-+/* data types */
-+enum as_actions {
-+	AS_AUTONEXT=1,
-+	AS_SEEK,
-+	AS_NEXT,
-+	AS_PREV,
-+	AS_STOP,
-+	AS_TREE_ENTER,
-+	AS_SORTED_ENTER,
-+	AS_PL_ENTER
-+};
-+
-+struct as_queue {
-+	struct list_head node;
-+	string_t s;
-+	unsigned int len;
-+	unsigned short int sc;           /* AS_SC_* */
-+	unsigned short int needrenumber; /* we must renumber 'string_t s'  */
-+	unsigned short int num;          /* number of the current entry    */
-+};
-+
-+struct as_hsinfo {
-+	unsigned int need_handshake;
-+	unsigned int failed;
-+	time_t       interval;
-+	string_t challenge;
-+	string_t host;
-+	string_t path;
-+	char     port[AS_MAXTMPLEN+1];   /* yes, port as a string. tcp_connect expects its port as char[] */
-+};
-+
-+struct as_authinfo {
-+	char user[OPTION_MAX_SIZE];
-+	char pass[OPTION_MAX_SIZE];
-+};
-+
-+/* function prototypes */
-+void as_hook(enum as_actions action);
-+void *as_loop(void *arg);
-+void as_exit(void);
-+void as_init(void);
-+
-+/* macros */
-+#define as_addtag(dest, src, tag)			\
-+	str_readya(&(dest), 6);				\
-+	str_ncat(  &(dest), tag, 3);			\
-+	str_ncat(  &(dest), as_numbers[ptr->num], 1);	\
-+	str_ncat(  &(dest), "]=", 2);			\
-+	str_readya(&(dest), src->len);			\
-+	str_cat(   &(dest), src)
-+
-+#define as_addntag(dest, src, len, tag)			\
-+	str_readya(&(dest), 6);				\
-+	str_ncat(  &(dest), tag, 3);			\
-+	str_ncat(  &(dest), as_numbers[ptr->num], 1);	\
-+	str_ncat(  &(dest), "]=", 2);			\
-+	str_readya(&(dest), len);			\
-+	str_ncat(  &(dest), src, len)
-+
-+#define mustquote(c) \
-+	c == ' '  || \
-+	c == '!'  || \
-+	c == '\"' || \
-+	c == '#'  || \
-+	c == '%'  || \
-+	c == '&'  || \
-+	c == '\'' || \
-+	c == '('  || \
-+	c == ')'  || \
-+	c == '*'  || \
-+	c == '-'  || \
-+	c == '/'  || \
-+	c == ':'  || \
-+	c == ';'  || \
-+	c == '<'  || \
-+	c == '='  || \
-+	c == '>'  || \
-+	c == '?'  || \
-+	c == '@'  || \
-+	c == '['  || \
-+	c == '\\' || \
-+	c == ']'  || \
-+	c == '^'  || \
-+	c == '`'  || \
-+	c == '{'  || \
-+	c == '|'  || \
-+	c == '}'  || \
-+	c == '~'
-+
-+#define as_lock()   cmus_mutex_lock(&as_mutex)
-+#define as_unlock() cmus_mutex_unlock(&as_mutex)
-+
-+/* exported variables */
-+extern int as_enable;
-+extern struct as_authinfo as_authinfo;
-+
-+#endif /* x__AS_H */
-diff -ur cmus-9999.orig/cmus.c cmus-9999/cmus.c
-index a2d9dac..e309647 100644
---- cmus-9999.orig/cmus.c
-+++ cmus-9999/cmus.c
-@@ -14,6 +14,7 @@
- #include "xmalloc.h"
- #include "xstrjoin.h"
- #include "debug.h"
-+#include "as.h"
- #include "load_dir.h"
- #include "ui_curses.h"
- 
-diff -ur cmus-9999.orig/command_mode.c cmus-9999/command_mode.c
-index e30d65b..91f7168 100644
---- cmus-9999.orig/command_mode.c
-+++ cmus-9999/command_mode.c
-@@ -45,6 +45,7 @@
- #include "list.h"
- #include "debug.h"
- #include "load_dir.h"
-+#include "as.h"
- #include "config/datadir.h"
- #include "help.h"
- 
-@@ -463,6 +464,8 @@ static void cmd_seek(char *arg)
- 	int relative = 0;
- 	int seek = 0, sign = 1, count;
- 
-+	as_hook(AS_SEEK);
-+
- 	switch (*arg) {
- 	case '-':
- 		sign = -1;
-@@ -1213,6 +1216,7 @@ static void cmd_view(char *arg)
- 
- static void cmd_p_next(char *arg)
- {
-+	as_hook(AS_NEXT);
- 	cmus_next();
- }
- 
-@@ -1232,11 +1236,13 @@ static void cmd_p_play(char *arg)
- 
- static void cmd_p_prev(char *arg)
- {
-+	as_hook(AS_PREV);
- 	cmus_prev();
- }
- 
- static void cmd_p_stop(char *arg)
- {
-+	as_hook(AS_STOP);
- 	player_stop();
- }
- 
-diff -ur cmus-9999.orig/lib.c cmus-9999/lib.c
-index 1da10b0..2be090e 100644
---- cmus-9999.orig/lib.c
-+++ cmus-9999/lib.c
-@@ -8,6 +8,7 @@
- #include "options.h"
- #include "xmalloc.h"
- #include "debug.h"
-+#include "as.h"
- 
- #include <pthread.h>
- #include <string.h>
-@@ -358,6 +359,7 @@ struct track_info *sorted_set_selected(void)
- 	if (list_empty(&lib_editable.head))
- 		return NULL;
- 
-+	as_hook(AS_SORTED_ENTER);
- 	window_get_sel(lib_editable.win, &sel);
- 	return lib_set_track(iter_to_sorted_track(&sel));
- }
-diff -ur cmus-9999.orig/md5.c cmus-9999/md5.c
-new file mode 100644
-index 0000000..5b31899
---- /dev/null
-+++ cmus-9999/md5.c
-@@ -0,0 +1,408 @@
-+/*
-+ *  RFC 1321 compliant MD5 implementation
-+ *
-+ *  Copyright (C) 2003-2006  Christophe Devine
-+ *
-+ *  This library is free software; you can redistribute it and/or
-+ *  modify it under the terms of the GNU Lesser General Public
-+ *  License, version 2.1 as published by the Free Software Foundation.
-+ *
-+ *  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 Street, Fifth Floor, Boston,
-+ *  MA  02110-1301  USA
-+ */
-+/*
-+ *  The MD5 algorithm was designed by Ron Rivest in 1991.
-+ *
-+ *  http://www.ietf.org/rfc/rfc1321.txt
-+ */
-+
-+#ifndef _CRT_SECURE_NO_DEPRECATE
-+#define _CRT_SECURE_NO_DEPRECATE 1
-+#endif
-+
-+#include <string.h>
-+#include <stdio.h>
-+
-+#include "md5.h"
-+
-+/* 
-+ * 32-bit integer manipulation macros (little endian)
-+ */
-+#ifndef GET_UINT32_LE
-+#define GET_UINT32_LE(n,b,i)                    \
-+{                                               \
-+    (n) = ( (ulong) (b)[(i)    ]       )        \
-+        | ( (ulong) (b)[(i) + 1] <<  8 )        \
-+        | ( (ulong) (b)[(i) + 2] << 16 )        \
-+        | ( (ulong) (b)[(i) + 3] << 24 );       \
-+}
-+#endif
-+#ifndef PUT_UINT32_LE
-+#define PUT_UINT32_LE(n,b,i)                    \
-+{                                               \
-+    (b)[(i)    ] = (uchar) ( (n)       );       \
-+    (b)[(i) + 1] = (uchar) ( (n) >>  8 );       \
-+    (b)[(i) + 2] = (uchar) ( (n) >> 16 );       \
-+    (b)[(i) + 3] = (uchar) ( (n) >> 24 );       \
-+}
-+#endif
-+
-+/*
-+ * Core MD5 functions
-+ */
-+void md5_starts( md5_context *ctx )
-+{
-+    ctx->total[0] = 0;
-+    ctx->total[1] = 0;
-+
-+    ctx->state[0] = 0x67452301;
-+    ctx->state[1] = 0xEFCDAB89;
-+    ctx->state[2] = 0x98BADCFE;
-+    ctx->state[3] = 0x10325476;
-+}
-+
-+static void md5_process( md5_context *ctx, uchar data[64] )
-+{
-+    ulong X[16], A, B, C, D;
-+
-+    GET_UINT32_LE( X[0],  data,  0 );
-+    GET_UINT32_LE( X[1],  data,  4 );
-+    GET_UINT32_LE( X[2],  data,  8 );
-+    GET_UINT32_LE( X[3],  data, 12 );
-+    GET_UINT32_LE( X[4],  data, 16 );
-+    GET_UINT32_LE( X[5],  data, 20 );
-+    GET_UINT32_LE( X[6],  data, 24 );
-+    GET_UINT32_LE( X[7],  data, 28 );
-+    GET_UINT32_LE( X[8],  data, 32 );
-+    GET_UINT32_LE( X[9],  data, 36 );
-+    GET_UINT32_LE( X[10], data, 40 );
-+    GET_UINT32_LE( X[11], data, 44 );
-+    GET_UINT32_LE( X[12], data, 48 );
-+    GET_UINT32_LE( X[13], data, 52 );
-+    GET_UINT32_LE( X[14], data, 56 );
-+    GET_UINT32_LE( X[15], data, 60 );
-+
-+#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
-+
-+#define P(a,b,c,d,k,s,t)                                \
-+{                                                       \
-+    a += F(b,c,d) + X[k] + t; a = S(a,s) + b;           \
-+}
-+
-+    A = ctx->state[0];
-+    B = ctx->state[1];
-+    C = ctx->state[2];
-+    D = ctx->state[3];
-+
-+#define F(x,y,z) (z ^ (x & (y ^ z)))
-+
-+    P( A, B, C, D,  0,  7, 0xD76AA478 );
-+    P( D, A, B, C,  1, 12, 0xE8C7B756 );
-+    P( C, D, A, B,  2, 17, 0x242070DB );
-+    P( B, C, D, A,  3, 22, 0xC1BDCEEE );
-+    P( A, B, C, D,  4,  7, 0xF57C0FAF );
-+    P( D, A, B, C,  5, 12, 0x4787C62A );
-+    P( C, D, A, B,  6, 17, 0xA8304613 );
-+    P( B, C, D, A,  7, 22, 0xFD469501 );
-+    P( A, B, C, D,  8,  7, 0x698098D8 );
-+    P( D, A, B, C,  9, 12, 0x8B44F7AF );
-+    P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
-+    P( B, C, D, A, 11, 22, 0x895CD7BE );
-+    P( A, B, C, D, 12,  7, 0x6B901122 );
-+    P( D, A, B, C, 13, 12, 0xFD987193 );
-+    P( C, D, A, B, 14, 17, 0xA679438E );
-+    P( B, C, D, A, 15, 22, 0x49B40821 );
-+
-+#undef F
-+
-+#define F(x,y,z) (y ^ (z & (x ^ y)))
-+
-+    P( A, B, C, D,  1,  5, 0xF61E2562 );
-+    P( D, A, B, C,  6,  9, 0xC040B340 );
-+    P( C, D, A, B, 11, 14, 0x265E5A51 );
-+    P( B, C, D, A,  0, 20, 0xE9B6C7AA );
-+    P( A, B, C, D,  5,  5, 0xD62F105D );
-+    P( D, A, B, C, 10,  9, 0x02441453 );
-+    P( C, D, A, B, 15, 14, 0xD8A1E681 );
-+    P( B, C, D, A,  4, 20, 0xE7D3FBC8 );
-+    P( A, B, C, D,  9,  5, 0x21E1CDE6 );
-+    P( D, A, B, C, 14,  9, 0xC33707D6 );
-+    P( C, D, A, B,  3, 14, 0xF4D50D87 );
-+    P( B, C, D, A,  8, 20, 0x455A14ED );
-+    P( A, B, C, D, 13,  5, 0xA9E3E905 );
-+    P( D, A, B, C,  2,  9, 0xFCEFA3F8 );
-+    P( C, D, A, B,  7, 14, 0x676F02D9 );
-+    P( B, C, D, A, 12, 20, 0x8D2A4C8A );
-+
-+#undef F
-+    
-+#define F(x,y,z) (x ^ y ^ z)
-+
-+    P( A, B, C, D,  5,  4, 0xFFFA3942 );
-+    P( D, A, B, C,  8, 11, 0x8771F681 );
-+    P( C, D, A, B, 11, 16, 0x6D9D6122 );
-+    P( B, C, D, A, 14, 23, 0xFDE5380C );
-+    P( A, B, C, D,  1,  4, 0xA4BEEA44 );
-+    P( D, A, B, C,  4, 11, 0x4BDECFA9 );
-+    P( C, D, A, B,  7, 16, 0xF6BB4B60 );
-+    P( B, C, D, A, 10, 23, 0xBEBFBC70 );
-+    P( A, B, C, D, 13,  4, 0x289B7EC6 );
-+    P( D, A, B, C,  0, 11, 0xEAA127FA );
-+    P( C, D, A, B,  3, 16, 0xD4EF3085 );
-+    P( B, C, D, A,  6, 23, 0x04881D05 );
-+    P( A, B, C, D,  9,  4, 0xD9D4D039 );
-+    P( D, A, B, C, 12, 11, 0xE6DB99E5 );
-+    P( C, D, A, B, 15, 16, 0x1FA27CF8 );
-+    P( B, C, D, A,  2, 23, 0xC4AC5665 );
-+
-+#undef F
-+
-+#define F(x,y,z) (y ^ (x | ~z))
-+
-+    P( A, B, C, D,  0,  6, 0xF4292244 );
-+    P( D, A, B, C,  7, 10, 0x432AFF97 );
-+    P( C, D, A, B, 14, 15, 0xAB9423A7 );
-+    P( B, C, D, A,  5, 21, 0xFC93A039 );
-+    P( A, B, C, D, 12,  6, 0x655B59C3 );
-+    P( D, A, B, C,  3, 10, 0x8F0CCC92 );
-+    P( C, D, A, B, 10, 15, 0xFFEFF47D );
-+    P( B, C, D, A,  1, 21, 0x85845DD1 );
-+    P( A, B, C, D,  8,  6, 0x6FA87E4F );
-+    P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
-+    P( C, D, A, B,  6, 15, 0xA3014314 );
-+    P( B, C, D, A, 13, 21, 0x4E0811A1 );
-+    P( A, B, C, D,  4,  6, 0xF7537E82 );
-+    P( D, A, B, C, 11, 10, 0xBD3AF235 );
-+    P( C, D, A, B,  2, 15, 0x2AD7D2BB );
-+    P( B, C, D, A,  9, 21, 0xEB86D391 );
-+
-+#undef F
-+
-+    ctx->state[0] += A;
-+    ctx->state[1] += B;
-+    ctx->state[2] += C;
-+    ctx->state[3] += D;
-+}
-+
-+void md5_update( md5_context *ctx, uchar *input, uint length )
-+{
-+    ulong left, fill;
-+
-+    if( ! length ) return;
-+
-+    left = ctx->total[0] & 0x3F;
-+    fill = 64 - left;
-+
-+    ctx->total[0] += length;
-+    ctx->total[0] &= 0xFFFFFFFF;
-+
-+    if( ctx->total[0] < length )
-+        ctx->total[1]++;
-+
-+    if( left && length >= fill )
-+    {
-+        memcpy( (void *) (ctx->buffer + left),
-+                (void *) input, fill );
-+        md5_process( ctx, ctx->buffer );
-+        length -= fill;
-+        input  += fill;
-+        left = 0;
-+    }
-+
-+    while( length >= 64 )
-+    {
-+        md5_process( ctx, input );
-+        length -= 64;
-+        input  += 64;
-+    }
-+
-+    if( length )
-+    {
-+        memcpy( (void *) (ctx->buffer + left),
-+                (void *) input, length );
-+    }
-+}
-+
-+static uchar md5_padding[64] =
-+{
-+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-+};
-+
-+void md5_finish( md5_context *ctx, uchar digest[16] )
-+{
-+    ulong last, padn;
-+    ulong high, low;
-+    uchar msglen[8];
-+
-+    high = ( ctx->total[0] >> 29 )
-+         | ( ctx->total[1] <<  3 );
-+    low  = ( ctx->total[0] <<  3 );
-+
-+    PUT_UINT32_LE( low,  msglen, 0 );
-+    PUT_UINT32_LE( high, msglen, 4 );
-+
-+    last = ctx->total[0] & 0x3F;
-+    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
-+
-+    md5_update( ctx, md5_padding, padn );
-+    md5_update( ctx, msglen, 8 );
-+
-+    PUT_UINT32_LE( ctx->state[0], digest,  0 );
-+    PUT_UINT32_LE( ctx->state[1], digest,  4 );
-+    PUT_UINT32_LE( ctx->state[2], digest,  8 );
-+    PUT_UINT32_LE( ctx->state[3], digest, 12 );
-+}
-+
-+/*
-+ * Output MD5(file contents), returns 0 if successful.
-+ */
-+int md5_file( char *filename, uchar digest[16] )
-+{
-+    FILE *f;
-+    size_t n;
-+    md5_context ctx;
-+    uchar buf[1024];
-+
-+    if( ( f = fopen( filename, "rb" ) ) == NULL )
-+        return( 1 );
-+
-+    md5_starts( &ctx );
-+
-+    while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
-+        md5_update( &ctx, buf, (uint) n );
-+
-+    md5_finish( &ctx, digest );
-+
-+    fclose( f );
-+    return( 0 );
-+}
-+
-+/*
-+ * Output MD5(buf)
-+ */
-+void md5_csum( uchar *buf, uint buflen, uchar digest[16] )
-+{
-+    md5_context ctx;
-+
-+    md5_starts( &ctx );
-+    md5_update( &ctx, buf, buflen );
-+    md5_finish( &ctx, digest );
-+}
-+
-+/*
-+ * Output HMAC-MD5(key,buf)
-+ */
-+void md5_hmac( uchar *key, uint keylen, uchar *buf, uint buflen,
-+               uchar digest[16] )
-+{
-+    uint i;
-+    md5_context ctx;
-+    uchar k_ipad[64];
-+    uchar k_opad[64];
-+    uchar tmpbuf[16];
-+
-+    memset( k_ipad, 0x36, 64 );
-+    memset( k_opad, 0x5C, 64 );
-+
-+    for( i = 0; i < keylen; i++ )
-+    {
-+        if( i >= 64 ) break;
-+
-+        k_ipad[i] ^= key[i];
-+        k_opad[i] ^= key[i];
-+    }
-+
-+    md5_starts( &ctx );
-+    md5_update( &ctx, k_ipad, 64 );
-+    md5_update( &ctx, buf, buflen );
-+    md5_finish( &ctx, tmpbuf );
-+
-+    md5_starts( &ctx );
-+    md5_update( &ctx, k_opad, 64 );
-+    md5_update( &ctx, tmpbuf, 16 );
-+    md5_finish( &ctx, digest );
-+
-+    memset( k_ipad, 0, 64 );
-+    memset( k_opad, 0, 64 );
-+    memset( tmpbuf, 0, 16 );
-+    memset( &ctx, 0, sizeof( md5_context ) );
-+}
-+
-+#ifdef SELF_TEST
-+/* 
-+ * RFC 1321 test vectors
-+ */
-+static char *md5_test_str[7] =
-+{
-+    "",
-+    "a",
-+    "abc",
-+    "message digest",
-+    "abcdefghijklmnopqrstuvwxyz",
-+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
-+    "12345678901234567890123456789012345678901234567890123456789012" \
-+        "345678901234567890"
-+};
-+
-+static uchar md5_test_sum[7][16] =
-+{
-+    { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
-+      0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
-+    { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
-+      0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
-+    { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
-+      0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
-+    { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
-+      0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
-+    { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
-+      0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
-+    { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
-+      0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
-+    { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
-+      0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
-+};
-+
-+/*
-+ * Checkup routine
-+ */
-+int md5_self_test( void )
-+{
-+    int i;
-+    uchar md5sum[16];
-+
-+    for( i = 0; i < 7; i++ )
-+    {
-+        printf( "  MD5 test #%d: ", i + 1 );
-+
-+        md5_csum( (uchar *) md5_test_str[i],
-+                    strlen( md5_test_str[i] ), md5sum );
-+
-+        if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
-+        {
-+            printf( "failed\n" );
-+            return( 1 );
-+        }
-+
-+        printf( "passed\n" );
-+    }
-+
-+    printf( "\n" );
-+    return( 0 );
-+}
-+#else
-+int md5_self_test( void )
-+{
-+    printf( "MD5 self-test not available\n\n" );
-+    return( 1 );
-+}
-+#endif
-diff -ur cmus-9999.orig/md5.h cmus-9999/md5.h
-new file mode 100644
-index 0000000..cefa7c4
---- /dev/null
-+++ cmus-9999/md5.h
-@@ -0,0 +1,57 @@
-+#ifndef _MD5_H
-+#define _MD5_H
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#ifndef _STD_TYPES
-+#define _STD_TYPES
-+
-+#define uchar   unsigned char
-+#define uint    unsigned int
-+#define ulong   unsigned long int
-+
-+#endif
-+
-+typedef struct
-+{
-+    ulong total[2];
-+    ulong state[4];
-+    uchar buffer[64];
-+}
-+md5_context;
-+
-+/*
-+ * Core MD5 functions