changeset 12496:f9d0ab1474ac

[gaim-migrate @ 14808] removing meanwhile library code from gaim tree, use libmeanwhile-1.0.0 instead if available to enable the sametime plugin. also fixing a status message bug due to unescaped markup committer: Tailor Script <tailor@pidgin.im>
author Christopher O'Brien <siege@pidgin.im>
date Fri, 16 Dec 2005 04:08:05 +0000
parents 39c15b080d49
children 202ce52b77a9
files configure.ac src/protocols/sametime/Makefile.am src/protocols/sametime/Makefile.mingw src/protocols/sametime/meanwhile/.cvsignore src/protocols/sametime/meanwhile/Makefile.am src/protocols/sametime/meanwhile/channel.c src/protocols/sametime/meanwhile/cipher.c src/protocols/sametime/meanwhile/common.c src/protocols/sametime/meanwhile/error.c src/protocols/sametime/meanwhile/message.c src/protocols/sametime/meanwhile/mpi/.cvsignore src/protocols/sametime/meanwhile/mpi/Makefile.am src/protocols/sametime/meanwhile/mpi/logtab.h src/protocols/sametime/meanwhile/mpi/mpi-config.h src/protocols/sametime/meanwhile/mpi/mpi-types.h src/protocols/sametime/meanwhile/mpi/mpi.c src/protocols/sametime/meanwhile/mpi/mpi.h src/protocols/sametime/meanwhile/mw_channel.h src/protocols/sametime/meanwhile/mw_cipher.h src/protocols/sametime/meanwhile/mw_client.h src/protocols/sametime/meanwhile/mw_common.h src/protocols/sametime/meanwhile/mw_debug.c src/protocols/sametime/meanwhile/mw_debug.h src/protocols/sametime/meanwhile/mw_error.h src/protocols/sametime/meanwhile/mw_message.h src/protocols/sametime/meanwhile/mw_service.h src/protocols/sametime/meanwhile/mw_session.h src/protocols/sametime/meanwhile/mw_srvc_aware.h src/protocols/sametime/meanwhile/mw_srvc_conf.h src/protocols/sametime/meanwhile/mw_srvc_ft.h src/protocols/sametime/meanwhile/mw_srvc_im.h src/protocols/sametime/meanwhile/mw_srvc_place.h src/protocols/sametime/meanwhile/mw_srvc_resolve.h src/protocols/sametime/meanwhile/mw_srvc_store.h src/protocols/sametime/meanwhile/mw_st_list.h src/protocols/sametime/meanwhile/mw_util.c src/protocols/sametime/meanwhile/mw_util.h src/protocols/sametime/meanwhile/service.c src/protocols/sametime/meanwhile/session.c src/protocols/sametime/meanwhile/srvc_aware.c src/protocols/sametime/meanwhile/srvc_conf.c src/protocols/sametime/meanwhile/srvc_ft.c src/protocols/sametime/meanwhile/srvc_im.c src/protocols/sametime/meanwhile/srvc_place.c src/protocols/sametime/meanwhile/srvc_resolve.c src/protocols/sametime/meanwhile/srvc_store.c src/protocols/sametime/meanwhile/st_list.c src/protocols/sametime/sametime.c
diffstat 48 files changed, 35 insertions(+), 20929 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac	Fri Dec 16 03:34:01 2005 +0000
+++ b/configure.ac	Fri Dec 16 04:08:05 2005 +0000
@@ -109,6 +109,18 @@
 
 
 dnl #######################################################################
+dnl # Check for Meanwhile headers (for Sametime)
+dnl #######################################################################
+PKG_CHECK_MODULES(MEANWHILE,
+	[meanwhile >= 1.0.0 meanwhile < 2.0.0],
+	[have_meanwhile="yes"],
+	[have_meanwhile="no"])
+AC_SUBST(MEANWHILE_CFLAGS)
+AC_SUBST(MEANWHILE_LIBS)
+
+
+
+dnl #######################################################################
 dnl # Check for Howl headers (for Bonjour)
 dnl #######################################################################
 AC_ARG_WITH(howl-includes, [AC_HELP_STRING([--with-howl-includes=DIR], [Compile the Bonjour plugin against the Howl includes in DIR])], [ac_howl_includes="$withval"], [ac_howl_includes="no"])
@@ -214,6 +226,9 @@
 if test "x$STATIC_PRPLS" = "xall" ; then
 	STATIC_PRPLS="bonjour gg irc jabber msn novell oscar sametime silc simple yahoo zephyr"
 fi
+if test "x$have_meanwhile" != "xyes" ; then
+	STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/sametime//'`
+fi
 if test "x$howlincludes" != "xyes" -o "x$howllibs" != "xyes"; then
 	STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/bonjour//'`
 fi
@@ -257,7 +272,7 @@
 AM_CONDITIONAL(STATIC_MSN, test "x$static_msn" = "xyes")
 AM_CONDITIONAL(STATIC_NOVELL, test "x$static_novell" = "xyes")
 AM_CONDITIONAL(STATIC_OSCAR, test "x$static_oscar" = "xyes")
-AM_CONDITIONAL(STATIC_SAMETIME, test "x$static_sametime" = "xyes")
+AM_CONDITIONAL(STATIC_SAMETIME, test "x$static_sametime" = "xyes" -a "x$have_meanwhile" = "xyes")
 AM_CONDITIONAL(STATIC_SILC, test "x$static_silc" = "xyes" -a "x$silcincludes" = "xyes" -a "x$silcclient" = "xyes")
 AM_CONDITIONAL(STATIC_SIMPLE, test "x$static_simple" = "xyes")
 AM_CONDITIONAL(STATIC_TOC, test "x$static_toc" = "xyes")
@@ -271,6 +286,9 @@
 if test "x$DYNAMIC_PRPLS" = "xall" ; then
 	DYNAMIC_PRPLS="bonjour gg irc jabber msn novell oscar sametime silc simple yahoo zephyr"
 fi
+if test "x$have_meanwhile" != "xyes"; then
+        DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/sametime//'`
+fi
 if test "x$howlincludes" != "xyes" -o "x$howllibs" != "xyes"; then
 	DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/bonjour//'`
 fi
@@ -303,7 +321,7 @@
 AM_CONDITIONAL(DYNAMIC_MSN, test "x$dynamic_msn" = "xyes")
 AM_CONDITIONAL(DYNAMIC_NOVELL, test "x$dynamic_novell" = "xyes")
 AM_CONDITIONAL(DYNAMIC_OSCAR, test "x$dynamic_oscar" = "xyes")
-AM_CONDITIONAL(DYNAMIC_SAMETIME, test "x$dynamic_sametime" = "xyes")
+AM_CONDITIONAL(DYNAMIC_SAMETIME, test "x$dynamic_sametime" = "xyes" -a "x$have_meanwhile" = "xyes")
 AM_CONDITIONAL(DYNAMIC_SILC, test "x$dynamic_silc" = "xyes" -a "x$silcincludes" = "xyes" -a "x$silcclient" = "xyes")
 AM_CONDITIONAL(DYNAMIC_SIMPLE, test "x$dynamic_simple" = "xyes")
 AM_CONDITIONAL(DYNAMIC_TOC, test "x$dynamic_toc" = "xyes")
@@ -1621,8 +1639,6 @@
 		   src/protocols/novell/Makefile
 		   src/protocols/oscar/Makefile
 		   src/protocols/sametime/Makefile
-		   src/protocols/sametime/meanwhile/Makefile
-		   src/protocols/sametime/meanwhile/mpi/Makefile
 		   src/protocols/silc/Makefile
 		   src/protocols/simple/Makefile
 		   src/protocols/toc/Makefile
--- a/src/protocols/sametime/Makefile.am	Fri Dec 16 03:34:01 2005 +0000
+++ b/src/protocols/sametime/Makefile.am	Fri Dec 16 04:08:05 2005 +0000
@@ -1,4 +1,3 @@
-SUBDIRS = meanwhile
 
 EXTRA_DIST = Makefile.mingw
 
@@ -29,17 +28,16 @@
 
 
 libsametime_la_LDFLAGS = -module -avoid-version -no-undefined
-libsametime_la_LIBADD = $(GLIB_LIBS) meanwhile/libmeanwhile.la
+libsametime_la_LIBADD = $(GLIB_LIBS) $(MEANWHILE_LIBS)
 
 
 AM_CFLAGS = \
-	$(GLIB_CFLAGS) \
+	$(GLIB_CFLAGS) $(MEANWHILE_CFLAGS) \
 	$(DEBUG_CFLAGS) \
-	-I$(top_srcdir)/src \
-	-I$(top_srcdir)/src/protocols/sametime/meanwhile
+	-I$(top_srcdir)/src
 
 
 AM_CPPFLAGS = \
-	-DG_LOG_DOMAIN=\"meanwhile\" \
+	-DG_LOG_DOMAIN=\"sametime\" \
 	$(st)
 
--- a/src/protocols/sametime/Makefile.mingw	Fri Dec 16 03:34:01 2005 +0000
+++ b/src/protocols/sametime/Makefile.mingw	Fri Dec 16 04:08:05 2005 +0000
@@ -47,14 +47,13 @@
 ##
 
 INCLUDE_PATHS +=	-I$(SAMETIME_ROOT) \
-			-I$(SAMETIME_ROOT)/meanwhile \
-			-I$(SAMETIME_ROOT)/meanwhile/mpi \
 			-I$(GTK_TOP)/include \
 			-I$(GTK_TOP)/include/glib-2.0 \
 			-I$(GTK_TOP)/lib/glib-2.0/include \
 			-I$(GAIM_TOP)/src \
 			-I$(GAIM_TOP)/src/win32 \
-			-I$(GAIM_TOP)
+			-I$(GAIM_TOP) \
+			$(MEANWHILE_CFLAGS)
 
 LIB_PATHS =		-L$(GTK_TOP)/lib \
 			-L$(GAIM_TOP)/src
@@ -64,25 +63,7 @@
 ##  SOURCES, OBJECTS
 ##
 
-C_SRC =		meanwhile/mpi/mpi.c \
-		meanwhile/channel.c \
-		meanwhile/cipher.c \
-		meanwhile/common.c \
-		meanwhile/error.c \
-		meanwhile/message.c \
-		meanwhile/mw_debug.c \
-		meanwhile/mw_util.c \
-		meanwhile/service.c \
-		meanwhile/session.c \
-		meanwhile/srvc_aware.c \
-		meanwhile/srvc_conf.c \
-		meanwhile/srvc_ft.c \
-		meanwhile/srvc_im.c \
-		meanwhile/srvc_place.c \
-		meanwhile/srvc_resolve.c \
-		meanwhile/srvc_store.c \
-		meanwhile/st_list.c \
-		sametime.c
+C_SRC =		sametime.c
 
 OBJECTS = $(C_SRC:%.c=%.o)
 
@@ -96,8 +77,8 @@
 		-lgobject-2.0 \
 		-lintl \
 		-lws2_32 \
-		-lgaim
-
+		-lgaim \
+		$(MEANWHILE_LIBS)
 
 ##
 ## RULES
--- a/src/protocols/sametime/meanwhile/.cvsignore	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-*.a
-.deps
-.libs
-*.la
-*.lo
-*.o
-*.dll
-*.lib
-Makefile
-Makefile.in
--- a/src/protocols/sametime/meanwhile/Makefile.am	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-SUBDIRS = mpi
-
-noinst_HEADERS = \
-	mw_channel.h \
-	mw_cipher.h \
-	mw_common.h \
-	mw_debug.h \
-	mw_error.h \
-	mw_message.h \
-	mw_service.h \
-	mw_session.h \
-	mw_srvc_aware.h \
-	mw_srvc_conf.h \
-	mw_srvc_ft.h \
-	mw_srvc_im.h \
-	mw_srvc_place.h \
-	mw_srvc_resolve.h \
-	mw_srvc_store.h \
-	mw_st_list.h \
-	mw_util.h 
-
-
-MEANWHILESOURCES = \
-	channel.c \
-	cipher.c \
-	common.c \
-	error.c \
-	message.c \
-	mw_debug.c \
-	mw_util.c \
-	service.c \
-	session.c \
-	srvc_aware.c \
-	srvc_conf.c \
-	srvc_ft.c \
-	srvc_im.c \
-	srvc_place.c \
-	srvc_store.c \
-	srvc_resolve.c \
-	st_list.c
-
-AM_CFLAGS = \
-	$(GLIB_CFLAGS) \
-	$(DEBUG_CFLAGS) \
-	-DG_LOG_DOMAIN=\"meanwhile\"
-	-I$(top_srcdir)/src 
-
-libmeanwhile_la_SOURCES = $(MEANWHILESOURCES)
-
-libmeanwhile_la_LIBADD = $(GLIB_LIBS) mpi/libmpi.la
-
-st =
-noinst_LTLIBRARIES = libmeanwhile.la
-
--- a/src/protocols/sametime/meanwhile/channel.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,961 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <glib.h>
-#include <glib/ghash.h>
-#include <glib/glist.h>
-#include <string.h>
-
-#include "mw_channel.h"
-#include "mw_cipher.h"
-#include "mw_debug.h"
-#include "mw_error.h"
-#include "mw_message.h"
-#include "mw_service.h"
-#include "mw_session.h"
-#include "mw_util.h"
-
-
-/** @todo reorganize this file, stuff is just strewn about */
-
-
-struct mwChannel {
-
-  /** session this channel belongs to */
-  struct mwSession *session;
-
-  enum mwChannelState state;
-
-  /** creator for incoming channel, target for outgoing channel */
-  struct mwLoginInfo user;
-
-  /* similar to data from the CreateCnl message in 8.4.1.7 */
-  guint32 reserved;    /**< special, unknown meaning */
-  guint32 id;          /**< channel ID */
-  guint32 service;     /**< service ID */
-  guint32 proto_type;  /**< service protocol type */
-  guint32 proto_ver;   /**< service protocol version */
-  guint32 options;     /**< channel options */
-
-  struct mwOpaque addtl_create;
-  struct mwOpaque addtl_accept;
-
-  /** all those supported ciphers */
-  GHashTable *supported;
-  guint16 offered_policy;  /**< @see enum mwEncryptPolicy */
-  guint16 policy;          /**< @see enum mwEncryptPolicy */
-
-  /** cipher information determined at channel acceptance */
-  struct mwCipherInstance *cipher;
-
-  /** statistics table */
-  GHashTable *stats;
-
-  GSList *outgoing_queue;     /**< queued outgoing messages */
-  GSList *incoming_queue;     /**< queued incoming messages */
-
-  struct mw_datum srvc_data;  /**< service-specific data */
-};
-
-
-struct mwChannelSet {
-  struct mwSession *session;  /**< owning session */
-  GHashTable *map;            /**< map of all channels, by ID */
-  guint32 counter;            /**< counter for outgoing ID */
-};
-
-
-static void flush_channel(struct mwChannel *);
-
-
-static const char *state_str(enum mwChannelState state) {
-  switch(state) {
-  case mwChannel_NEW:      return "new";
-  case mwChannel_INIT:     return "initializing";
-  case mwChannel_WAIT:     return "waiting";
-  case mwChannel_OPEN:     return "open";
-  case mwChannel_DESTROY:  return "closing";
-  case mwChannel_ERROR:    return "error";
-
-  case mwChannel_UNKNOWN:  /* fall through */
-  default:                 return "UNKNOWN";
-  }
-}
-
-
-static void state(struct mwChannel *chan, enum mwChannelState state,
-		  guint32 err_code) {
-
-  g_return_if_fail(chan != NULL);
-
-  if(chan->state == state) return;
-
-  chan->state = state;
-
-  if(err_code) {
-    g_message("channel 0x%08x state: %s (0x%08x)",
-	      chan->id, state_str(state), err_code);
-  } else {
-    g_message("channel 0x%08x state: %s", chan->id, state_str(state));
-  }
-}
-
-
-static gpointer get_stat(struct mwChannel *chan,
-			 enum mwChannelStatField field) {
-
-  return g_hash_table_lookup(chan->stats, (gpointer) field);
-}
-
-
-static void set_stat(struct mwChannel *chan, enum mwChannelStatField field,
-		     gpointer val) {
-
-  g_hash_table_insert(chan->stats, (gpointer) field, val);
-}
-
-
-#define incr_stat(chan, field, incr) \
-  set_stat(chan, field, get_stat(chan, field) + incr)
-
-
-#define timestamp_stat(chan, field) \
-  set_stat(chan, field, (gpointer) time(NULL))
-
-
-static void sup_free(gpointer a) {
-  mwCipherInstance_free(a);
-}
-
-
-struct mwCipherInstance *get_supported(struct mwChannel *chan, guint16 id) {
-  guint32 cid = (guint32) id;
-  return g_hash_table_lookup(chan->supported, GUINT_TO_POINTER(cid));
-}
-
-
-void put_supported(struct mwChannel *chan, struct mwCipherInstance *ci) {
-  struct mwCipher *cipher = mwCipherInstance_getCipher(ci);
-  guint32 cid = (guint32) mwCipher_getType(cipher);
-  g_hash_table_insert(chan->supported, GUINT_TO_POINTER(cid), ci);
-}
-
-
-struct mwChannel *mwChannel_newIncoming(struct mwChannelSet *cs, guint32 id) {
-  struct mwChannel *chan;
-
-  g_return_val_if_fail(cs != NULL, NULL);
-  g_return_val_if_fail(cs->session != NULL, NULL);
-
-  chan = g_new0(struct mwChannel, 1);
-  chan->state = mwChannel_NEW;
-  chan->session = cs->session;
-  chan->id = id;
-
-  chan->stats = g_hash_table_new(g_direct_hash, g_direct_equal);
-
-  chan->supported = g_hash_table_new_full(g_direct_hash, g_direct_equal,
-					  NULL, sup_free);
-
-  g_hash_table_insert(cs->map, GUINT_TO_POINTER(id), chan);
-
-  state(chan, mwChannel_WAIT, 0);
-
-  return chan;
-}
-
-
-struct mwChannel *mwChannel_newOutgoing(struct mwChannelSet *cs) {
-  guint32 id;
-  struct mwChannel *chan;
-
-  g_return_val_if_fail(cs != NULL, NULL);
-  g_return_val_if_fail(cs->map != NULL, NULL);
-
-  /* grab the next id, and try to make sure there isn't already a
-     channel using it */
-  do {
-    id = ++cs->counter;
-  } while(g_hash_table_lookup(cs->map, GUINT_TO_POINTER(id)));
-  
-  chan = mwChannel_newIncoming(cs, id);
-  state(chan, mwChannel_INIT, 0);
-
-  return chan;
-}
-
-
-guint32 mwChannel_getId(struct mwChannel *chan) {
-  g_return_val_if_fail(chan != NULL, 0);
-  return chan->id;
-}
-
-
-struct mwSession *mwChannel_getSession(struct mwChannel *chan) {
-  g_return_val_if_fail(chan != NULL, NULL);
-  return chan->session;
-}
-
-
-guint32 mwChannel_getServiceId(struct mwChannel *chan) {
-  g_return_val_if_fail(chan != NULL, 0);
-  return chan->service;
-}
-
-
-struct mwService *mwChannel_getService(struct mwChannel *chan) {
-  g_return_val_if_fail(chan != NULL, NULL);
-  return mwSession_getService(chan->session, chan->service);
-}
-
-
-void mwChannel_setService(struct mwChannel *chan, struct mwService *srvc) {
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(srvc != NULL);
-  g_return_if_fail(chan->state == mwChannel_INIT);
-  chan->service = mwService_getType(srvc);
-}
-
-
-gpointer mwChannel_getServiceData(struct mwChannel *chan) {
-  g_return_val_if_fail(chan != NULL, NULL);
-  return mw_datum_get(&chan->srvc_data);
-}
-
-
-void mwChannel_setServiceData(struct mwChannel *chan,
-			      gpointer data, GDestroyNotify clean) {
-
-  g_return_if_fail(chan != NULL);
-  mw_datum_set(&chan->srvc_data, data, clean);
-}
-
-
-void mwChannel_removeServiceData(struct mwChannel *chan) {
-  g_return_if_fail(chan != NULL);
-  mw_datum_clear(&chan->srvc_data);
-}
-
-
-guint32 mwChannel_getProtoType(struct mwChannel *chan) {
-  g_return_val_if_fail(chan != NULL, 0x00);
-  return chan->proto_type;
-}
-
-
-void mwChannel_setProtoType(struct mwChannel *chan, guint32 proto_type) {
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(chan->state == mwChannel_INIT);
-  chan->proto_type = proto_type;
-}
-
-
-guint32 mwChannel_getProtoVer(struct mwChannel *chan) {
-  g_return_val_if_fail(chan != NULL, 0x00);
-  return chan->proto_ver;
-}
-
-
-void mwChannel_setProtoVer(struct mwChannel *chan, guint32 proto_ver) {
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(chan->state == mwChannel_INIT);
-  chan->proto_ver = proto_ver;
-}
-
-
-guint16 mwChannel_getEncryptPolicy(struct mwChannel *chan) {
-  g_return_val_if_fail(chan != NULL, 0x00);
-  return chan->policy;
-}
-
-
-guint32 mwChannel_getOptions(struct mwChannel *chan) {
-  g_return_val_if_fail(chan != NULL, 0x00);
-  return chan->options;
-}
-
-
-void mwChannel_setOptions(struct mwChannel *chan, guint32 options) {
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(chan->state == mwChannel_INIT);
-  chan->options = options;
-}
-
-
-struct mwLoginInfo *mwChannel_getUser(struct mwChannel *chan) {
-  g_return_val_if_fail(chan != NULL, NULL);
-  return &chan->user;
-}
-
-
-struct mwOpaque *mwChannel_getAddtlCreate(struct mwChannel *chan) {
-  g_return_val_if_fail(chan != NULL, NULL);
-  return &chan->addtl_create;
-}
-
-
-struct mwOpaque *mwChannel_getAddtlAccept(struct mwChannel *chan) {
-  g_return_val_if_fail(chan != NULL, NULL);
-  return &chan->addtl_accept;
-}
-
-
-struct mwCipherInstance *mwChannel_getCipherInstance(struct mwChannel *chan) {
-  g_return_val_if_fail(chan != NULL, NULL);
-  return chan->cipher;
-}
-
-
-enum mwChannelState mwChannel_getState(struct mwChannel *chan) {
-  g_return_val_if_fail(chan != NULL, mwChannel_UNKNOWN);
-  return chan->state;
-}
-
-
-gpointer mwChannel_getStatistic(struct mwChannel *chan,
-				enum mwChannelStatField stat) {
-  
-  g_return_val_if_fail(chan != NULL, 0);
-  g_return_val_if_fail(chan->stats != NULL, 0);
-
-  return get_stat(chan, stat);
-}
-
-
-/* send a channel create message */
-int mwChannel_create(struct mwChannel *chan) {
-  struct mwMsgChannelCreate *msg;
-  GList *list, *l;
-  int ret;
-
-  g_return_val_if_fail(chan != NULL, -1);
-  g_return_val_if_fail(chan->state == mwChannel_INIT, -1);
-  g_return_val_if_fail(mwChannel_isOutgoing(chan), -1);
-
-  msg = (struct mwMsgChannelCreate *)
-    mwMessage_new(mwMessage_CHANNEL_CREATE);
-
-  msg->channel = chan->id;
-  msg->target.user = g_strdup(chan->user.user_id);
-  msg->target.community = g_strdup(chan->user.community);
-  msg->service = chan->service;
-  msg->proto_type = chan->proto_type;
-  msg->proto_ver = chan->proto_ver;
-  msg->options = chan->options;
-  mwOpaque_clone(&msg->addtl, &chan->addtl_create);
-
-  list = mwChannel_getSupportedCipherInstances(chan);
-  if(list) {
-    /* offer what we have */
-    for(l = list; l; l = l->next) {
-      struct mwEncryptItem *ei = mwCipherInstance_offer(l->data);
-      msg->encrypt.items = g_list_append(msg->encrypt.items, ei);
-    }
-
-    /* we're easy to get along with */
-    chan->offered_policy = mwEncrypt_WHATEVER;
-    g_list_free(list);
-
-  } else {
-    /* we apparently don't support anything */
-    chan->offered_policy = mwEncrypt_NONE;
-  }
-
-  msg->encrypt.mode = chan->offered_policy;
-  msg->encrypt.extra = chan->offered_policy;
-  
-  ret = mwSession_send(chan->session, MW_MESSAGE(msg));
-  mwMessage_free(MW_MESSAGE(msg));
-
-  state(chan, (ret)? mwChannel_ERROR: mwChannel_WAIT, ret);
-
-  return ret;
-}
-
-
-static void channel_open(struct mwChannel *chan) {
-  state(chan, mwChannel_OPEN, 0);
-  timestamp_stat(chan, mwChannelStat_OPENED_AT);
-  flush_channel(chan);
-}
-
-
-int mwChannel_accept(struct mwChannel *chan) {
-  struct mwSession *session;
-  struct mwMsgChannelAccept *msg;
-  struct mwCipherInstance *ci;
-
-  int ret;
-
-  g_return_val_if_fail(chan != NULL, -1);
-  g_return_val_if_fail(mwChannel_isIncoming(chan), -1);
-  g_return_val_if_fail(chan->state == mwChannel_WAIT, -1);
-
-  session = chan->session;
-  g_return_val_if_fail(session != NULL, -1);
-
-  msg = (struct mwMsgChannelAccept *)
-    mwMessage_new(mwMessage_CHANNEL_ACCEPT);
-
-  msg->head.channel = chan->id;
-  msg->service = chan->service;
-  msg->proto_type = chan->proto_type;
-  msg->proto_ver = chan->proto_ver;
-  mwOpaque_clone(&msg->addtl, &chan->addtl_accept);
-
-  ci = chan->cipher;
-
-  if(! ci) {
-    /* automatically select a cipher if one hasn't been already */
-
-    switch(chan->offered_policy) {
-    case mwEncrypt_NONE:
-      mwChannel_selectCipherInstance(chan, NULL);
-      break;
-      
-    case mwEncrypt_RC2_40:
-      ci = get_supported(chan, mwCipher_RC2_40);
-      mwChannel_selectCipherInstance(chan, ci);
-      break;
-
-    case mwEncrypt_RC2_128:
-      ci = get_supported(chan, mwCipher_RC2_128);
-      mwChannel_selectCipherInstance(chan, ci);
-      break;
-      
-    case mwEncrypt_WHATEVER:
-    case mwEncrypt_ALL:
-    default:
-      {
-	GList *l, *ll;
-
-	l = mwChannel_getSupportedCipherInstances(chan);
-	if(l) {
-	  /* nobody selected a cipher, so we'll just pick the last in
-	     the list of available ones */
-	  for(ll = l; ll->next; ll = ll->next);
-	  ci = ll->data;
-	  g_list_free(l);
-	  
-	  mwChannel_selectCipherInstance(chan, ci);
-	  
-	} else {
-	  /* this may cause breakage, but there's really nothing else
-	     we can do. They want something we can't provide. If they
-	     don't like it, then they'll error the channel out */
-	  mwChannel_selectCipherInstance(chan, NULL);
-	}
-      }
-    }
-  }
-
-  msg->encrypt.mode = chan->policy; /* set in selectCipherInstance */
-  msg->encrypt.extra = chan->offered_policy;
-
-  if(chan->cipher) {
-    msg->encrypt.item = mwCipherInstance_accept(chan->cipher);
-  }
-
-  ret = mwSession_send(session, MW_MESSAGE(msg));
-  mwMessage_free(MW_MESSAGE(msg));
-
-  if(ret) {
-    state(chan, mwChannel_ERROR, ret);
-  } else {
-    channel_open(chan);
-  }
-
-  return ret;
-}
-
-
-static void channel_free(struct mwChannel *chan) {
-  struct mwSession *s;
-  struct mwMessage *msg;
-  GSList *l;
-
-  /* maybe no warning in the future */
-  g_return_if_fail(chan != NULL);
-
-  s = chan->session;
-
-  mwLoginInfo_clear(&chan->user);
-  mwOpaque_clear(&chan->addtl_create);
-  mwOpaque_clear(&chan->addtl_accept);
-
-  if(chan->supported) {
-    g_hash_table_destroy(chan->supported);
-    chan->supported = NULL;
-  }
-
-  if(chan->stats) {
-    g_hash_table_destroy(chan->stats);
-    chan->stats = NULL;
-  }
-  
-  mwCipherInstance_free(chan->cipher);
-
-  /* clean up the outgoing queue */
-  for(l = chan->outgoing_queue; l; l = l->next) {
-    msg = (struct mwMessage *) l->data;
-    l->data = NULL;
-    mwMessage_free(msg);
-  }
-  g_slist_free(chan->outgoing_queue);
-
-  /* clean up the incoming queue */
-  for(l = chan->incoming_queue; l; l = l->next) {
-    msg = (struct mwMessage *) l->data;
-    l->data = NULL;
-    mwMessage_free(msg);
-  }
-  g_slist_free(chan->incoming_queue);
-
-  g_free(chan);
-}
-
-
-int mwChannel_destroy(struct mwChannel *chan,
-		      guint32 reason, struct mwOpaque *info) {
-
-  struct mwMsgChannelDestroy *msg;
-  struct mwSession *session;
-  struct mwChannelSet *cs;
-  int ret;
-
-  /* may make this not a warning in the future */
-  g_return_val_if_fail(chan != NULL, 0);
-
-  state(chan, reason? mwChannel_ERROR: mwChannel_DESTROY, reason);
-
-  session = chan->session;
-  g_return_val_if_fail(session != NULL, -1);
-
-  cs = mwSession_getChannels(session);
-  g_return_val_if_fail(cs != NULL, -1);
-
-  /* compose the message */
-  msg = (struct mwMsgChannelDestroy *)
-    mwMessage_new(mwMessage_CHANNEL_DESTROY);
-  msg->head.channel = chan->id;
-  msg->reason = reason;
-  if(info) mwOpaque_clone(&msg->data, info);
-
-  /* remove the channel from the channel set */
-  g_hash_table_remove(cs->map, GUINT_TO_POINTER(chan->id));
-  
-  /* send the message */
-  ret = mwSession_send(session, (struct mwMessage *) msg);
-  mwMessage_free(MW_MESSAGE(msg));
-
-  return ret;
-}
-
-
-static void queue_outgoing(struct mwChannel *chan,
-			   struct mwMsgChannelSend *msg) {
-
-  g_info("queue_outgoing, channel 0x%08x", chan->id);
-  chan->outgoing_queue = g_slist_append(chan->outgoing_queue, msg);
-}
-
-
-static int channel_send(struct mwChannel *chan,
-			struct mwMsgChannelSend *msg) {
-
-  int ret = 0;
-
-  /* if the channel is open, send and free the message. Otherwise,
-     queue the message to be sent once the channel is finally
-     opened */
-
-  if(chan->state == mwChannel_OPEN) {
-    ret = mwSession_send(chan->session, (struct mwMessage *) msg);
-    mwMessage_free(MW_MESSAGE(msg));
-
-  } else {
-    queue_outgoing(chan, msg);
-  }
-
-  return ret;
-}
-
-
-int mwChannel_sendEncrypted(struct mwChannel *chan,
-			    guint32 type, struct mwOpaque *data,
-			    gboolean encrypt) {
-
-  struct mwMsgChannelSend *msg;
-
-  g_return_val_if_fail(chan != NULL, -1);
-
-  msg = (struct mwMsgChannelSend *) mwMessage_new(mwMessage_CHANNEL_SEND);
-  msg->head.channel = chan->id;
-  msg->type = type;
-
-  mwOpaque_clone(&msg->data, data);
-
-  if(encrypt && chan->cipher) {
-    msg->head.options = mwMessageOption_ENCRYPT;
-    mwCipherInstance_encrypt(chan->cipher, &msg->data);
-  }
-
-  return channel_send(chan, msg);  
-}
-
-
-int mwChannel_send(struct mwChannel *chan, guint32 type,
-		   struct mwOpaque *data) {
-
-  return mwChannel_sendEncrypted(chan, type, data, TRUE);
-}
-
-
-static void queue_incoming(struct mwChannel *chan,
-			   struct mwMsgChannelSend *msg) {
-
-  /* we clone the message, because session_process will clear it once
-     we return */
-
-  struct mwMsgChannelSend *m = g_new0(struct mwMsgChannelSend, 1);
-  m->head.type = msg->head.type;
-  m->head.options = msg->head.options;
-  m->head.channel = msg->head.channel;
-  mwOpaque_clone(&m->head.attribs, &msg->head.attribs);
-
-  m->type = msg->type;
-  mwOpaque_clone(&m->data, &msg->data);
-
-  g_info("queue_incoming, channel 0x%08x", chan->id);
-  chan->incoming_queue = g_slist_append(chan->incoming_queue, m);
-}
-
-
-static void channel_recv(struct mwChannel *chan,
-			 struct mwMsgChannelSend *msg) {
-
-  struct mwService *srvc;
-  srvc = mwChannel_getService(chan);
-
-  incr_stat(chan, mwChannelStat_MSG_RECV, 1);
-
-  if(msg->head.options & mwMessageOption_ENCRYPT) {
-    struct mwOpaque data = { 0, 0 };
-    mwOpaque_clone(&data, &msg->data);
-
-    mwCipherInstance_decrypt(chan->cipher, &data);
-    mwService_recv(srvc, chan, msg->type, &data);
-    mwOpaque_clear(&data);
-    
-  } else {
-    mwService_recv(srvc, chan, msg->type, &msg->data);
-  }
-}
-
-
-static void flush_channel(struct mwChannel *chan) {
-  GSList *l;
-
-  for(l = chan->incoming_queue; l; l = l->next) {
-    struct mwMsgChannelSend *msg = (struct mwMsgChannelSend *) l->data;
-    l->data = NULL;
-
-    channel_recv(chan, msg);
-    mwMessage_free(MW_MESSAGE(msg));
-  }
-  g_slist_free(chan->incoming_queue);
-  chan->incoming_queue = NULL;
-
-  for(l = chan->outgoing_queue; l; l = l->next) {
-    struct mwMessage *msg = (struct mwMessage *) l->data;
-    l->data = NULL;
-
-    mwSession_send(chan->session, msg);
-    mwMessage_free(msg);
-  }
-  g_slist_free(chan->outgoing_queue);
-  chan->outgoing_queue = NULL;
-}
-
-
-void mwChannel_recv(struct mwChannel *chan, struct mwMsgChannelSend *msg) {
-  if(chan->state == mwChannel_OPEN) {
-    channel_recv(chan, msg);
-
-  } else {
-    queue_incoming(chan, msg);
-  }
-}
-
-
-struct mwChannel *mwChannel_find(struct mwChannelSet *cs, guint32 chan) {
-  g_return_val_if_fail(cs != NULL, NULL);
-  g_return_val_if_fail(cs->map != NULL, NULL);
-  return g_hash_table_lookup(cs->map, GUINT_TO_POINTER(chan));
-}
-
-
-void mwChannelSet_free(struct mwChannelSet *cs) {
-  if(! cs) return;
-  if(cs->map) g_hash_table_destroy(cs->map);
-  g_free(cs);
-}
-
-
-struct mwChannelSet *mwChannelSet_new(struct mwSession *s) {
-  struct mwChannelSet *cs = g_new0(struct mwChannelSet, 1);
-  cs->session = s;
-
-  /* for some reason, g_int_hash/g_int_equal cause a SIGSEGV */
-  cs->map = g_hash_table_new_full(g_direct_hash, g_direct_equal,
-				  NULL, (GDestroyNotify) channel_free);
-  return cs;
-}
-
-
-void mwChannel_recvCreate(struct mwChannel *chan,
-			  struct mwMsgChannelCreate *msg) {
-
-  struct mwSession *session;
-  GList *list;
-  struct mwService *srvc;
-  
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(msg != NULL);
-  g_return_if_fail(chan->id == msg->channel);
-
-  session = chan->session;
-  g_return_if_fail(session != NULL);
-
-  if(mwChannel_isOutgoing(chan)) {
-    g_warning("channel 0x%08x not an incoming channel", chan->id);
-    mwChannel_destroy(chan, ERR_REQUEST_INVALID, NULL);
-    return;
-  }
-
-  chan->offered_policy = msg->encrypt.mode;
-  g_message("channel offered with encrypt policy 0x%04x", chan->policy);
-
-  for(list = msg->encrypt.items; list; list = list->next) {
-    struct mwEncryptItem *ei = list->data;
-    struct mwCipher *cipher;
-    struct mwCipherInstance *ci;
-
-    g_message("channel offered cipher id 0x%04x", ei->id);
-    cipher = mwSession_getCipher(session, ei->id);
-    if(! cipher) {
-      g_message("no such cipher found in session");
-      continue;
-    }
-
-    ci = mwCipher_newInstance(cipher, chan);
-    mwCipherInstance_offered(ci, ei);
-    mwChannel_addSupportedCipherInstance(chan, ci);
-  }
-
-  mwLoginInfo_clone(&chan->user, &msg->creator);
-  chan->service = msg->service;
-  chan->proto_type = msg->proto_type;
-  chan->proto_ver = msg->proto_ver;
-  
-  srvc = mwSession_getService(session, msg->service);
-  if(srvc) {
-    mwService_recvCreate(srvc, chan, msg);
-
-  } else {
-    mwChannel_destroy(chan, ERR_SERVICE_NO_SUPPORT, NULL);
-  }  
-}
-
-
-void mwChannel_recvAccept(struct mwChannel *chan,
-			  struct mwMsgChannelAccept *msg) {
-
-  struct mwService *srvc;
-
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(msg != NULL);
-  g_return_if_fail(chan->id == msg->head.channel);
-
-  if(mwChannel_isIncoming(chan)) {
-    g_warning("channel 0x%08x not an outgoing channel", chan->id);
-    mwChannel_destroy(chan, ERR_REQUEST_INVALID, NULL);
-    return;
-  }
-
-  if(chan->state != mwChannel_WAIT) {
-    g_warning("channel 0x%08x state not WAIT: %s",
-	      chan->id, state_str(chan->state));
-    mwChannel_destroy(chan, ERR_REQUEST_INVALID, NULL);
-    return;
-  }
-
-  mwLoginInfo_clone(&chan->user, &msg->acceptor);
-
-  srvc = mwSession_getService(chan->session, chan->service);
-  if(! srvc) {
-    g_warning("no service: 0x%08x", chan->service);
-    mwChannel_destroy(chan, ERR_SERVICE_NO_SUPPORT, NULL);
-    return;
-  }
-
-  chan->policy = msg->encrypt.mode;
-  g_message("channel accepted with encrypt policy 0x%04x", chan->policy);
-
-  if(! msg->encrypt.mode || ! msg->encrypt.item) {
-    /* no mode or no item means no encryption */
-    mwChannel_selectCipherInstance(chan, NULL);
-
-  } else {
-    guint16 cid = msg->encrypt.item->id;
-    struct mwCipherInstance *ci = get_supported(chan, cid);
-
-    if(! ci) {
-      g_warning("not an offered cipher: 0x%04x", cid);
-      mwChannel_destroy(chan, ERR_REQUEST_INVALID, NULL);
-      return;
-    }
-
-    mwCipherInstance_accepted(ci, msg->encrypt.item);
-    mwChannel_selectCipherInstance(chan, ci);
-  }
-
-  /* mark it as open for the service */
-  state(chan, mwChannel_OPEN, 0);
-
-  /* let the service know */
-  mwService_recvAccept(srvc, chan, msg);
-
-  /* flush it if the service didn't just immediately close it */
-  if(mwChannel_isState(chan, mwChannel_OPEN)) {
-    channel_open(chan);
-  }
-}
-
-
-void mwChannel_recvDestroy(struct mwChannel *chan,
-			   struct mwMsgChannelDestroy *msg) {
-
-  struct mwChannelSet *cs;
-  struct mwService *srvc;
-
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(msg != NULL);
-  g_return_if_fail(chan->id == msg->head.channel);
-
-  state(chan, msg->reason? mwChannel_ERROR: mwChannel_DESTROY, msg->reason);
-
-  srvc = mwChannel_getService(chan);
-  if(srvc) mwService_recvDestroy(srvc, chan, msg);
-
-  cs = mwSession_getChannels(chan->session);
-  g_return_if_fail(cs != NULL);
-  g_return_if_fail(cs->map != NULL);
-
-  g_hash_table_remove(cs->map, GUINT_TO_POINTER(chan->id));
-}
-
-
-void mwChannel_populateSupportedCipherInstances(struct mwChannel *chan) {
-  struct mwSession *session;
-  GList *list;
-
-  g_return_if_fail(chan != NULL);
-
-  session = chan->session;
-  g_return_if_fail(session != NULL);
-
-  for(list = mwSession_getCiphers(session); list; list = list->next) {
-    struct mwCipherInstance *ci = mwCipher_newInstance(list->data, chan);
-    if(! ci) continue;
-    put_supported(chan, ci);
-  }
-}
-
-
-void mwChannel_addSupportedCipherInstance(struct mwChannel *chan,
-					  struct mwCipherInstance *ci) {
-  g_return_if_fail(chan != NULL);
-  g_message("channel 0x%08x added cipher %s", chan->id,
-	    NSTR(mwCipher_getName(mwCipherInstance_getCipher(ci))));
-  put_supported(chan, ci);
-}
-
-
-static void collect(gpointer a, gpointer b, gpointer c) {
-  GList **list = c;
-  *list = g_list_append(*list, b);
-}
-
-
-GList *mwChannel_getSupportedCipherInstances(struct mwChannel *chan) {
-  GList *list = NULL;
-
-  g_return_val_if_fail(chan != NULL, NULL);
-  g_hash_table_foreach(chan->supported, collect, &list);
-
-  return list;
-}
-
-
-void mwChannel_selectCipherInstance(struct mwChannel *chan,
-				    struct mwCipherInstance *ci) {
-  struct mwCipher *c;
-
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(chan->supported != NULL);
-
-  chan->cipher = ci;
-  if(ci) {
-    guint cid;
-
-    c = mwCipherInstance_getCipher(ci);
-    cid = mwCipher_getType(c);
-
-    g_hash_table_steal(chan->supported, GUINT_TO_POINTER(cid));
-
-    switch(mwCipher_getType(c)) {
-    case mwCipher_RC2_40:
-      chan->policy = mwEncrypt_RC2_40;
-      break;
-
-    case mwCipher_RC2_128:
-      chan->policy = mwEncrypt_RC2_128;
-      break;
-
-    default:
-      /* unsure if this is bad */
-      chan->policy = mwEncrypt_WHATEVER;
-    }
-
-    g_message("channel 0x%08x selected cipher %s",
-	      chan->id, NSTR(mwCipher_getName(c)));
-
-  } else {
-
-    chan->policy = mwEncrypt_NONE;
-    g_message("channel 0x%08x selected no cipher", chan->id);
-  }
-
-  g_hash_table_destroy(chan->supported);
-  chan->supported = NULL;
-}
-
-
--- a/src/protocols/sametime/meanwhile/cipher.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,968 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <stdlib.h>
-#include <time.h>
-
-#include "mpi/mpi.h"
-
-#include "mw_channel.h"
-#include "mw_cipher.h"
-#include "mw_debug.h"
-#include "mw_session.h"
-
-
-struct mwMpi {
-  mp_int i;
-};
-
-
-/** From RFC2268 */
-static guchar PT[] = {
-  0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
-  0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
-  0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
-  0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
-  0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
-  0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
-  0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
-  0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
-  0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
-  0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
-  0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
-  0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
-  0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
-  0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
-  0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
-  0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
-  0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
-  0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
-  0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
-  0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
-  0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
-  0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
-  0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
-  0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
-  0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
-  0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
-  0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
-  0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
-  0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
-  0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
-  0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
-  0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD
-};
-
-
-/** prime number used in DH exchange */
-static guchar dh_prime[] = {
-  0xCF, 0x84, 0xAF, 0xCE, 0x86, 0xDD, 0xFA, 0x52,
-  0x7F, 0x13, 0x6D, 0x10, 0x35, 0x75, 0x28, 0xEE,
-  0xFB, 0xA0, 0xAF, 0xEF, 0x80, 0x8F, 0x29, 0x17,
-  0x4E, 0x3B, 0x6A, 0x9E, 0x97, 0x00, 0x01, 0x71,
-  0x7C, 0x8F, 0x10, 0x6C, 0x41, 0xC1, 0x61, 0xA6,
-  0xCE, 0x91, 0x05, 0x7B, 0x34, 0xDA, 0x62, 0xCB,
-  0xB8, 0x7B, 0xFD, 0xC1, 0xB3, 0x5C, 0x1B, 0x91,
-  0x0F, 0xEA, 0x72, 0x24, 0x9D, 0x56, 0x6B, 0x9F
-};
-
-
-/** base used in DH exchange */
-#define DH_BASE  3
-
-
-struct mwMpi *mwMpi_new() {
-  struct mwMpi *i;
-  i = g_new0(struct mwMpi, 1);
-  mp_init(&i->i);
-  return i;
-}
-
-
-void mwMpi_free(struct mwMpi *i) {
-  if(! i) return;
-  mp_clear(&i->i);
-  g_free(i);
-}
-
-
-static void mwInitDHPrime(mp_int *i) {
-  mp_init(i);
-  mp_read_unsigned_bin(i, dh_prime, 64);
-}
-
-
-void mwMpi_setDHPrime(struct mwMpi *i) {
-  g_return_if_fail(i != NULL);
-  mp_read_unsigned_bin(&i->i, dh_prime, 64);
-}
-
-
-static void mwInitDHBase(mp_int *i) {
-  mp_init(i);
-  mp_set_int(i, DH_BASE);
-}
-
-
-void mwMpi_setDHBase(struct mwMpi *i) {
-  g_return_if_fail(i != NULL);
-  mp_set_int(&i->i, DH_BASE);
-}
-
-
-static void mp_set_rand(mp_int *i, guint bits) {
-  size_t len, l;
-  guchar *buf;
-
-  l = len = (bits / 8) + 1;
-  buf = g_malloc(len);
-
-  srand(clock());
-  while(l--) buf[l] = rand() & 0xff;
-
-  buf[0] &= (0xff >> (8 - (bits % 8)));
-
-  mp_read_unsigned_bin(i, buf, len);
-  g_free(buf);
-}
-
-
-void mwMpi_rand(struct mwMpi *i, guint bits) {
-  g_return_if_fail(i != NULL);
-  mp_set_rand(&i->i, bits);
-}
-
-
-static void mwDHRandKeypair(mp_int *private, mp_int *public) {
-  mp_int prime, base;
- 
-  mwInitDHPrime(&prime);
-  mwInitDHBase(&base);
-
-  mp_set_rand(private, 512);
-  mp_exptmod(&base, private, &prime, public);
-
-  mp_clear(&prime);
-  mp_clear(&base);
-}
-
-
-void mwMpi_randDHKeypair(struct mwMpi *private, struct mwMpi *public) {
-  g_return_if_fail(private != NULL);
-  g_return_if_fail(public != NULL);
-
-  mwDHRandKeypair(&private->i, &public->i);
-}
-
-
-static void mwDHCalculateShared(mp_int *shared, mp_int *remote,
-				mp_int *private) {
-  mp_int prime;
- 
-  mwInitDHPrime(&prime);
-  mp_exptmod(remote, private, &prime, shared);
-  mp_clear(&prime);
-}
-
-
-void mwMpi_calculateDHShared(struct mwMpi *shared, struct mwMpi *remote,
-			     struct mwMpi *private) {
-
-  g_return_if_fail(shared != NULL);
-  g_return_if_fail(remote != NULL);
-  g_return_if_fail(private != NULL);
-
-  mwDHCalculateShared(&shared->i, &remote->i, &private->i);
-}
-
-
-static void mwDHImportKey(mp_int *key, struct mwOpaque *o) {
-  mp_read_unsigned_bin(key, o->data, o->len);
-}
-
-
-void mwMpi_import(struct mwMpi *i, struct mwOpaque *o) {
-  g_return_if_fail(i != NULL);
-  g_return_if_fail(o != NULL);
-
-  mwDHImportKey(&i->i, o);
-}
-
-
-static void mwDHExportKey(mp_int *key, struct mwOpaque *o) {
-  o->len = mp_unsigned_bin_size(key);
-  o->data = g_malloc0(o->len);
-  mp_to_unsigned_bin(key, o->data);
-}
-
-
-void mwMpi_export(struct mwMpi *i, struct mwOpaque *o) {
-  g_return_if_fail(i != NULL);
-  g_return_if_fail(o != NULL);
-  
-  mwDHExportKey(&i->i, o);
-}
-
-
-void mwKeyRandom(guchar *key, gsize keylen) {
-  g_return_if_fail(key != NULL);
-
-  srand(clock());
-  while(keylen--) key[keylen] = rand() & 0xff;
-}
-
-
-void mwIV_init(guchar *iv) {
-  int i;
-  static guchar normal_iv[] = {
-    0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
-  };
-  for(i = 8; i--; iv[i] = normal_iv[i]);
-  /* memcpy(iv, normal_iv, 8); */
-}
-
-
-/* This does not seem to produce the same results as normal RC2 key
-   expansion would, but it works, so eh. It might be smart to farm
-   this out to mozilla or openssl */
-void mwKeyExpand(int *ekey, const guchar *key, gsize keylen) {
-  guchar tmp[128];
-  int i, j;
-
-  g_return_if_fail(keylen > 0);
-  g_return_if_fail(key != NULL);
-
-  if(keylen > 128) keylen = 128;
-
-  /* fill the first chunk with what key bytes we have */
-  for(i = keylen; i--; tmp[i] = key[i]);
-  /* memcpy(tmp, key, keylen); */
-
-  /* build the remaining key from the given data */
-  for(i = 0; keylen < 128; i++) {
-    tmp[keylen] = PT[ (tmp[keylen - 1] + tmp[i]) & 0xff ];
-    keylen++;
-  }
-
-  tmp[0] = PT[ tmp[0] & 0xff ];
-
-  for(i = 0, j = 0; i < 64; i++) {
-    ekey[i] = (tmp[j] & 0xff) | (tmp[j+1] << 8);
-    j += 2;
-  }
-}
-
-
-/* normal RC2 encryption given a full 128-byte (as 64 ints) key */
-static void mwEncryptBlock(const int *ekey, guchar *out) {
-
-  int a, b, c, d;
-  int i, j;
-
-  a = (out[7] << 8) | (out[6] & 0xff);
-  b = (out[5] << 8) | (out[4] & 0xff);
-  c = (out[3] << 8) | (out[2] & 0xff);
-  d = (out[1] << 8) | (out[0] & 0xff);
-
-  for(i = 0; i < 16; i++) {
-    j = i * 4;
-
-    d += ((c & (a ^ 0xffff)) + (b & a) + ekey[j++]);
-    d = (d << 1) | (d >> 15 & 0x0001);
-
-    c += ((b & (d ^ 0xffff)) + (a & d) + ekey[j++]);
-    c = (c << 2) | (c >> 14 & 0x0003);
-
-    b += ((a & (c ^ 0xffff)) + (d & c) + ekey[j++]);
-    b = (b << 3) | (b >> 13 & 0x0007);
-    
-    a += ((d & (b ^ 0xffff)) + (c & b) + ekey[j++]);
-    a = (a << 5) | (a >> 11 & 0x001f);
-
-    if(i == 4 || i == 10) {
-      d += ekey[a & 0x003f];
-      c += ekey[d & 0x003f];
-      b += ekey[c & 0x003f];
-      a += ekey[b & 0x003f];
-    }    
-  }
-
-  *out++ = d & 0xff;
-  *out++ = (d >> 8) & 0xff;
-  *out++ = c & 0xff;
-  *out++ = (c >> 8) & 0xff;
-  *out++ = b & 0xff;
-  *out++ = (b >> 8) & 0xff;
-  *out++ = a & 0xff;
-  *out++ = (a >> 8) & 0xff;
-}
-
-
-void mwEncryptExpanded(const int *ekey, guchar *iv,
-		       struct mwOpaque *in_data,
-		       struct mwOpaque *out_data) {
-
-  guchar *i = in_data->data;
-  gsize i_len = in_data->len;
-
-  guchar *o;
-  gsize o_len;
-
-  int x, y;
-
-  /* pad upwards to a multiple of 8 */
-  o_len = (i_len & -8) + 8;
-  o = g_malloc(o_len);
-
-  out_data->data = o;
-  out_data->len = o_len;
-
-  /* figure out the amount of padding */
-  y = o_len - i_len;
-
-  /* copy in to out, and write padding bytes */
-  for(x = i_len; x--; o[x] = i[x]);
-  for(x = i_len; x < o_len; o[x++] = y);
-  /* memcpy(o, i, i_len);
-     memset(o + i_len, y, y); */
-
-  /* encrypt in blocks */
-  for(x = o_len; x > 0; x -= 8) {
-    for(y = 8; y--; o[y] ^= iv[y]);
-    mwEncryptBlock(ekey, o);
-    for(y = 8; y--; iv[y] = o[y]);
-    /* memcpy(iv, o, 8); */
-    o += 8;
-  }
-}
-
-
-void mwEncrypt(const guchar *key, gsize keylen,
-	       guchar *iv,
-	       struct mwOpaque *in, struct mwOpaque *out) {
-
-  int ekey[64];
-  mwKeyExpand(ekey, key, keylen);
-  mwEncryptExpanded(ekey, iv, in, out);
-}
-
-
-static void mwDecryptBlock(const int *ekey, guchar *out) {
-
-  int a, b, c, d;
-  int i, j;
-
-  a = (out[7] << 8) | (out[6] & 0xff);
-  b = (out[5] << 8) | (out[4] & 0xff);
-  c = (out[3] << 8) | (out[2] & 0xff);
-  d = (out[1] << 8) | (out[0] & 0xff);
-
-  for(i = 16; i--; ) {
-    j = i * 4 + 3;
-
-    a = (a << 11) | (a >> 5 & 0x07ff);
-    a -= ((d & (b ^ 0xffff)) + (c & b) + ekey[j--]);
-
-    b = (b << 13) | (b >> 3 & 0x1fff);
-    b -= ((a & (c ^ 0xffff)) + (d & c) + ekey[j--]);
-
-    c = (c << 14) | (c >> 2 & 0x3fff);
-    c -= ((b & (d ^ 0xffff)) + (a & d) + ekey[j--]);
-
-    d = (d << 15) | (d >> 1 & 0x7fff);
-    d -= ((c & (a ^ 0xffff)) + (b & a) + ekey[j--]);
-
-    if(i == 5 || i == 11) {
-      a -= ekey[b & 0x003f];
-      b -= ekey[c & 0x003f];
-      c -= ekey[d & 0x003f];
-      d -= ekey[a & 0x003f];
-    }
-  }
-
-  *out++ = d & 0xff;
-  *out++ = (d >> 8) & 0xff;
-  *out++ = c & 0xff;
-  *out++ = (c >> 8) & 0xff;
-  *out++ = b & 0xff;
-  *out++ = (b >> 8) & 0xff;
-  *out++ = a & 0xff;
-  *out++ = (a >> 8) & 0xff;
-}
-
-
-void mwDecryptExpanded(const int *ekey, guchar *iv,
-		       struct mwOpaque *in_data,
-		       struct mwOpaque *out_data) {
-
-  guchar *i = in_data->data;
-  gsize i_len = in_data->len;
-
-  guchar *o;
-  gsize o_len;
-
-  int x, y;
-
-  /* this doesn't check to ensure that in_data->len is a multiple of
-     8, which is damn well ought to be. */
-
-  o = g_malloc(i_len);
-  o_len = i_len;
-  for(x = i_len; x--; o[x] = i[x]);
-  /* memcpy(o, i, i_len); */
-
-  out_data->data = o;
-  out_data->len = o_len;
-
-  for(x = o_len; x > 0; x -= 8) {
-    /* decrypt a block */
-    mwDecryptBlock(ekey, o);
-
-    /* modify the initialization vector */
-    for(y = 8; y--; o[y] ^= iv[y]);
-    for(y = 8; y--; iv[y] = i[y]);
-    /* memcpy(iv, i, 8); */
-    i += 8;
-    o += 8;
-  }
-
-  /* shorten the length by the value of the filler in the padding
-     bytes */
-  out_data->len -= *(o - 1);
-}
-
-
-void mwDecrypt(const guchar *key, gsize keylen, guchar *iv,
-	       struct mwOpaque *in, struct mwOpaque *out) {
-
-  int ekey[64];
-  mwKeyExpand(ekey, key, keylen);
-  mwDecryptExpanded(ekey, iv, in, out);
-}
-
-
-
-struct mwCipher_RC2_40 {
-  struct mwCipher cipher;
-  int session_key[64];
-  gboolean ready;
-};
-
-
-struct mwCipherInstance_RC2_40 {
-  struct mwCipherInstance instance;
-  int incoming_key[64];
-  guchar outgoing_iv[8];
-  guchar incoming_iv[8];
-};
-
-
-static const char *get_name_RC2_40() {
-  return "RC2/40 Cipher";
-}
-
-
-static const char *get_desc_RC2_40() {
-  return "RC2, 40-bit effective key";
-}
-
-
-static int encrypt_RC2_40(struct mwCipherInstance *ci,
-			  struct mwOpaque *data) {
-
-  struct mwCipherInstance_RC2_40 *cir;
-  struct mwCipher_RC2_40 *cr;
-  struct mwOpaque o = { 0, 0 };
-
-  cir = (struct mwCipherInstance_RC2_40 *) ci;
-  cr = (struct mwCipher_RC2_40 *) ci->cipher;
-
-  mwEncryptExpanded(cr->session_key, cir->outgoing_iv, data, &o);
-
-  mwOpaque_clear(data);
-  data->data = o.data;
-  data->len = o.len;
-
-  return 0;
-}
-
-
-static int decrypt_RC2_40(struct mwCipherInstance *ci,
-			  struct mwOpaque *data) {
-  
-  struct mwCipherInstance_RC2_40 *cir;
-  struct mwCipher_RC2_40 *cr;
-  struct mwOpaque o = { 0, 0 };
-
-  cir = (struct mwCipherInstance_RC2_40 *) ci;
-  cr = (struct mwCipher_RC2_40 *) ci->cipher;
-
-  mwDecryptExpanded(cir->incoming_key, cir->incoming_iv, data, &o);
-
-  mwOpaque_clear(data);
-  data->data = o.data;
-  data->len = o.len;
-
-  return 0;
-}
-
-
-static struct mwCipherInstance *
-new_instance_RC2_40(struct mwCipher *cipher,
-		    struct mwChannel *chan) {
-
-  struct mwCipher_RC2_40 *cr;
-  struct mwCipherInstance_RC2_40 *cir;
-  struct mwCipherInstance *ci;
-
-  cr = (struct mwCipher_RC2_40 *) cipher;
-
-  /* a bit of lazy initialization here */
-  if(! cr->ready) {
-    struct mwLoginInfo *info = mwSession_getLoginInfo(cipher->session);
-    mwKeyExpand(cr->session_key, (guchar *) info->login_id, 5);
-    cr->ready = TRUE;
-  }
-
-  cir = g_new0(struct mwCipherInstance_RC2_40, 1);
-  ci = &cir->instance;
-
-  ci->cipher = cipher;
-  ci->channel = chan;
-
-  mwIV_init(cir->incoming_iv);
-  mwIV_init(cir->outgoing_iv);
-
-  return ci;
-}
-
-
-static struct mwEncryptItem *new_item_RC2_40(struct mwCipherInstance *ci) {
-  struct mwEncryptItem *e;
-
-  e = g_new0(struct mwEncryptItem, 1);
-  e->id = mwCipher_RC2_40;
-  return e;
-}
-
-
-static struct mwEncryptItem *
-offer_RC2_40(struct mwCipherInstance *ci) {
-  return new_item_RC2_40(ci);
-}
-
-
-static void accepted_RC2_40(struct mwCipherInstance *ci,
-			    struct mwEncryptItem *item) {
-
-  struct mwCipherInstance_RC2_40 *cir;
-  struct mwLoginInfo *info;
-
-  cir = (struct mwCipherInstance_RC2_40 *) ci;
-  info = mwChannel_getUser(ci->channel);
-
-  if(info->login_id) {
-    mwKeyExpand(cir->incoming_key, (guchar *) info->login_id, 5);
-  }
-}
-
-
-static struct mwEncryptItem *
-accept_RC2_40(struct mwCipherInstance *ci) {
-
-  accepted_RC2_40(ci, NULL);
-  return new_item_RC2_40(ci);
-}
-
-
-struct mwCipher *mwCipher_new_RC2_40(struct mwSession *s) {
-  struct mwCipher_RC2_40 *cr = g_new0(struct mwCipher_RC2_40, 1);
-  struct mwCipher *c = &cr->cipher;
-
-  c->session = s;
-  c->type = mwCipher_RC2_40;
-  c->get_name = get_name_RC2_40;
-  c->get_desc = get_desc_RC2_40;
-  c->new_instance = new_instance_RC2_40;
-
-  c->offer = offer_RC2_40;
-
-  c->accepted = accepted_RC2_40;
-  c->accept = accept_RC2_40;
-
-  c->encrypt = encrypt_RC2_40;
-  c->decrypt = decrypt_RC2_40;
-
-  return c;
-}
-
-
-struct mwCipher_RC2_128 {
-  struct mwCipher cipher;
-  mp_int private_key;
-  struct mwOpaque public_key;
-};
-
-
-struct mwCipherInstance_RC2_128 {
-  struct mwCipherInstance instance;
-  int shared[64];      /* shared secret determined via DH exchange */
-  guchar outgoing_iv[8];
-  guchar incoming_iv[8];
-};
-
-
-static const char *get_name_RC2_128() {
-  return "RC2/128 Cipher";
-}
-
-
-static const char *get_desc_RC2_128() {
-  return "RC2, DH shared secret key";
-}
-
-
-static struct mwCipherInstance *
-new_instance_RC2_128(struct mwCipher *cipher,
-		     struct mwChannel *chan) {
-
-  struct mwCipher_RC2_128 *cr;
-  struct mwCipherInstance_RC2_128 *cir;
-  struct mwCipherInstance *ci;
-
-  cr = (struct mwCipher_RC2_128 *) cipher;
-
-  cir = g_new0(struct mwCipherInstance_RC2_128, 1);
-  ci = &cir->instance;
-  
-  ci->cipher = cipher;
-  ci->channel = chan;
-
-  mwIV_init(cir->incoming_iv);
-  mwIV_init(cir->outgoing_iv);
-
-  return ci;
-}
-
-
-static void offered_RC2_128(struct mwCipherInstance *ci,
-			    struct mwEncryptItem *item) {
-  
-  mp_int remote_key;
-  mp_int shared;
-  struct mwOpaque sho = { 0, 0 };
-
-  struct mwCipher *c;
-  struct mwCipher_RC2_128 *cr;
-  struct mwCipherInstance_RC2_128 *cir;
-
-  c = ci->cipher;
-  cr = (struct mwCipher_RC2_128 *) c;
-  cir = (struct mwCipherInstance_RC2_128 *) ci;
-
-  mp_init(&remote_key);
-  mp_init(&shared);
-
-  mwDHImportKey(&remote_key, &item->info);
-  mwDHCalculateShared(&shared, &remote_key, &cr->private_key);
-  mwDHExportKey(&shared, &sho);
-
-  /* key expanded from the last 16 bytes of the DH shared secret. This
-     took me forever to figure out. 16 bytes is 128 bit. */
-  /* the sh_len-16 is important, because the key len could
-     hypothetically start with 8bits or more unset, meaning the
-     exported key might be less than 64 bytes in length */
-  mwKeyExpand(cir->shared, sho.data+(sho.len-16), 16);
-  
-  mp_clear(&remote_key);
-  mp_clear(&shared);
-  mwOpaque_clear(&sho);
-}
-
-
-static struct mwEncryptItem *
-offer_RC2_128(struct mwCipherInstance *ci) {
-
-  struct mwCipher *c;
-  struct mwCipher_RC2_128 *cr;
-  struct mwEncryptItem *ei;
-
-  c = ci->cipher;
-  cr = (struct mwCipher_RC2_128 *) c;
-
-  ei = g_new0(struct mwEncryptItem, 1);
-  ei->id = mwCipher_RC2_128;
-  mwOpaque_clone(&ei->info, &cr->public_key);
-
-  return ei;
-}			  
-
-
-static void accepted_RC2_128(struct mwCipherInstance *ci,
-			     struct mwEncryptItem *item) {
-
-  return offered_RC2_128(ci, item);
-}
-
-
-static struct mwEncryptItem *
-accept_RC2_128(struct mwCipherInstance *ci) {
-
-  return offer_RC2_128(ci);
-}
-
-
-static int encrypt_RC2_128(struct mwCipherInstance *ci,
-			   struct mwOpaque *data) {
-
-  struct mwCipherInstance_RC2_128 *cir;
-  struct mwOpaque o = { 0, 0 };
-
-  cir = (struct mwCipherInstance_RC2_128 *) ci;
-
-  mwEncryptExpanded(cir->shared, cir->outgoing_iv, data, &o);
-
-  mwOpaque_clear(data);
-  data->data = o.data;
-  data->len = o.len;
-
-  return 0;
-}
-
-
-static int decrypt_RC2_128(struct mwCipherInstance *ci,
-			   struct mwOpaque *data) {
-
-  struct mwCipherInstance_RC2_128 *cir;
-  struct mwOpaque o = { 0, 0 };
-
-  cir = (struct mwCipherInstance_RC2_128 *) ci;
-
-  mwDecryptExpanded(cir->shared, cir->incoming_iv, data, &o);
-
-  mwOpaque_clear(data);
-  data->data = o.data;
-  data->len = o.len;
-
-  return 0;
-}
-
-
-static void clear_RC2_128(struct mwCipher *c) {
-  struct mwCipher_RC2_128 *cr;
-  cr = (struct mwCipher_RC2_128 *) c;
-
-  mp_clear(&cr->private_key);
-  mwOpaque_clear(&cr->public_key);
-}
-
-
-struct mwCipher *mwCipher_new_RC2_128(struct mwSession *s) {
-  struct mwCipher_RC2_128 *cr;
-  struct mwCipher *c;
-
-  mp_int pubkey;
-
-  cr = g_new0(struct mwCipher_RC2_128, 1);
-  c = &cr->cipher;
-
-  c->session = s;
-  c->type = mwCipher_RC2_128;
-  c->get_name = get_name_RC2_128;
-  c->get_desc = get_desc_RC2_128;
-  c->new_instance = new_instance_RC2_128;
-
-  c->offered = offered_RC2_128;
-  c->offer = offer_RC2_128;
-
-  c->accepted = accepted_RC2_128;
-  c->accept = accept_RC2_128;
-
-  c->encrypt = encrypt_RC2_128;
-  c->decrypt = decrypt_RC2_128;
-
-  c->clear = clear_RC2_128;
-  
-  mp_init(&cr->private_key);
-  mp_init(&pubkey);
-  mwDHRandKeypair(&cr->private_key, &pubkey);
-  mwDHExportKey(&pubkey, &cr->public_key);
-  mp_clear(&pubkey);
-
-  return c;
-}
-
-
-struct mwSession *mwCipher_getSession(struct mwCipher *cipher) {
-  g_return_val_if_fail(cipher != NULL, NULL);
-  return cipher->session;
-}
-
-
-guint16 mwCipher_getType(struct mwCipher *cipher) {
-  /* oh man, this is a bad failover... who the hell decided to make
-     zero a real cipher id? */
-  g_return_val_if_fail(cipher != NULL, 0xffff);
-  return cipher->type;
-}
-
-
-const char *mwCipher_getName(struct mwCipher *cipher) {
-  g_return_val_if_fail(cipher != NULL, NULL);
-  g_return_val_if_fail(cipher->get_name != NULL, NULL);
-  return cipher->get_name();
-}
-
-
-const char *mwCipher_getDesc(struct mwCipher *cipher) {
-  g_return_val_if_fail(cipher != NULL, NULL);
-  g_return_val_if_fail(cipher->get_desc != NULL, NULL);
-  return cipher->get_desc();
-}
-
-
-void mwCipher_free(struct mwCipher *cipher) {
-  if(! cipher) return;
-
-  if(cipher->clear)
-    cipher->clear(cipher);
-
-  g_free(cipher);
-}
-
-
-struct mwCipherInstance *mwCipher_newInstance(struct mwCipher *cipher,
-					      struct mwChannel *chan) {
-  g_return_val_if_fail(cipher != NULL, NULL);
-  g_return_val_if_fail(chan != NULL, NULL);
-  g_return_val_if_fail(cipher->new_instance != NULL, NULL);
-  return cipher->new_instance(cipher, chan);
-}
-
-
-struct mwCipher *mwCipherInstance_getCipher(struct mwCipherInstance *ci) {
-  g_return_val_if_fail(ci != NULL, NULL);
-  return ci->cipher;
-}
-
-
-struct mwChannel *mwCipherInstance_getChannel(struct mwCipherInstance *ci) {
-  g_return_val_if_fail(ci != NULL, NULL);
-  return ci->channel;
-}
-
-
-void mwCipherInstance_offered(struct mwCipherInstance *ci,
-			      struct mwEncryptItem *item) {
-  struct mwCipher *cipher;
-
-  g_return_if_fail(ci != NULL);
-
-  cipher = ci->cipher;
-  g_return_if_fail(cipher != NULL);
-
-  if(cipher->offered) cipher->offered(ci, item);
-}
-
-
-struct mwEncryptItem *
-mwCipherInstance_offer(struct mwCipherInstance *ci) {
-  struct mwCipher *cipher;
-
-  g_return_val_if_fail(ci != NULL, NULL);
-
-  cipher = ci->cipher;
-  g_return_val_if_fail(cipher != NULL, NULL);
-
-  return cipher->offer(ci);
-}
-
-
-void mwCipherInstance_accepted(struct mwCipherInstance *ci,
-			       struct mwEncryptItem *item) {
-  struct mwCipher *cipher;
-
-  g_return_if_fail(ci != NULL);
-
-  cipher = ci->cipher;
-  g_return_if_fail(cipher != NULL);
-
-  if(cipher->accepted) cipher->accepted(ci, item);
-}
-
-
-struct mwEncryptItem *
-mwCipherInstance_accept(struct mwCipherInstance *ci) {
-  struct mwCipher *cipher;
-
-  g_return_val_if_fail(ci != NULL, NULL);
-
-  cipher = ci->cipher;
-  g_return_val_if_fail(cipher != NULL, NULL);
-
-  return cipher->accept(ci);
-}
-
-
-int mwCipherInstance_encrypt(struct mwCipherInstance *ci,
-			     struct mwOpaque *data) {
-  struct mwCipher *cipher;
-
-  g_return_val_if_fail(data != NULL, 0);
-
-  if(! ci) return 0;
-  cipher = ci->cipher;
-
-  g_return_val_if_fail(cipher != NULL, -1);
-
-  return (cipher->encrypt)?
-    cipher->encrypt(ci, data): 0;
-}
-
-
-int mwCipherInstance_decrypt(struct mwCipherInstance *ci,
-			     struct mwOpaque *data) {
-  struct mwCipher *cipher;
-
-  g_return_val_if_fail(data != NULL, 0);
-
-  if(! ci) return 0;
-  cipher = ci->cipher;
-
-  g_return_val_if_fail(cipher != NULL, -1);
-
-  return (cipher->decrypt)?
-    cipher->decrypt(ci, data): 0;
-}
-
-
-void mwCipherInstance_free(struct mwCipherInstance *ci) {
-  struct mwCipher *cipher;
-
-  if(! ci) return;
-
-  cipher = ci->cipher;
-
-  if(cipher && cipher->clear_instance)
-    cipher->clear_instance(ci);
-
-  g_free(ci);
-}
-
--- a/src/protocols/sametime/meanwhile/common.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,927 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <glib.h>
-#include <string.h>
-
-#include "mw_common.h"
-
-
-/** @todo the *_get functions should make sure to clear their
-    structures in the event of failure, to prevent memory leaks */
-
-
-#define MW16_PUT(b, val) \
-  *(b)++ = ((val) >> 0x08) & 0xff; \
-  *(b)++ = (val) & 0xff;
-
-
-#define MW16_GET(b, val) \
-  val = (*(b)++ & 0xff) << 8; \
-  val = val | (*(b)++ & 0xff);
-
-
-#define MW32_PUT(b, val) \
-  *(b)++ = ((val) >> 0x18) & 0xff; \
-  *(b)++ = ((val) >> 0x10) & 0xff; \
-  *(b)++ = ((val) >> 0x08) & 0xff; \
-  *(b)++ = (val) & 0xff;
-
-
-#define MW32_GET(b, val) \
-  val = (*(b)++ & 0xff) << 0x18; \
-  val = val | (*(b)++ & 0xff) << 0x10; \
-  val = val | (*(b)++ & 0xff) << 0x08; \
-  val = val | (*(b)++ & 0xff);
-
-
-struct mwPutBuffer {
-  guchar *buf;  /**< head of buffer */
-  gsize len;    /**< length of buffer */
-
-  guchar *ptr;  /**< offset to first unused byte */
-  gsize rem;    /**< count of unused bytes remaining */
-};
-
-
-struct mwGetBuffer {
-  guchar *buf;  /**< head of buffer */
-  gsize len;    /**< length of buffer */
-
-  guchar *ptr;  /**< offset to first unused byte */
-  gsize rem;    /**< count of unused bytes remaining */
-
-  gboolean wrap;   /**< TRUE to indicate buf shouldn't be freed */
-  gboolean error;  /**< TRUE to indicate an error */
-};
-
-
-#define BUFFER_USED(buffer) \
-  ((buffer)->len - (buffer)->rem)
-
-
-/** ensure that there's at least enough space remaining in the put
-    buffer to fit needed. */
-static void ensure_buffer(struct mwPutBuffer *b, gsize needed) {
-  if(b->rem < needed) {
-    gsize len = b->len, use = BUFFER_USED(b);
-    guchar *buf;
-
-    /* newly created buffers are empty until written to, and then they
-       have 1024 available */
-    if(! len) len = 1024;
-
-    /* double len until it's large enough to fit needed */
-    while( (len - use) < needed ) len = len << 1;
-
-    /* create the new buffer. if there was anything in the old buffer,
-       copy it into the new buffer and free the old copy */
-    buf = g_malloc(len);
-    if(b->buf) {
-      memcpy(buf, b->buf, use);
-      g_free(b->buf);
-    }
-
-    /* put the new buffer into b */
-    b->buf = buf;
-    b->len = len;
-    b->ptr = buf + use;
-    b->rem = len - use;
-  }
-}
-
-
-/** determine if there are at least needed bytes available in the
-    buffer. sets the error flag if there's not at least needed bytes
-    left in the buffer
-
-    @returns true if there's enough data, false if not */
-static gboolean check_buffer(struct mwGetBuffer *b, gsize needed) {
-  if(! b->error)  b->error = (b->rem < needed);
-  return ! b->error;
-}
-
-
-struct mwPutBuffer *mwPutBuffer_new() {
-  return g_new0(struct mwPutBuffer, 1);
-}
-
-
-void mwPutBuffer_write(struct mwPutBuffer *b, gpointer data, gsize len) {
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(data != NULL);
-
-  if(! len) return;
-
-  ensure_buffer(b, len);
-  memcpy(b->ptr, data, len);
-  b->ptr += len;
-  b->rem -= len;
-}
-
-
-void mwPutBuffer_free(struct mwPutBuffer *b) {
-  if(! b) return;
-  g_free(b->buf);
-  g_free(b);
-}
-
-
-void mwPutBuffer_finalize(struct mwOpaque *to, struct mwPutBuffer *from) {
-  g_return_if_fail(to != NULL);
-  g_return_if_fail(from != NULL);
-
-  to->len = BUFFER_USED(from);
-  to->data = from->buf;
-
-  g_free(from);
-}
-
-
-struct mwGetBuffer *mwGetBuffer_new(struct mwOpaque *o) {
-  struct mwGetBuffer *b = g_new0(struct mwGetBuffer, 1);
-
-  if(o && o->len) {
-    b->buf = b->ptr = g_memdup(o->data, o->len);
-    b->len = b->rem = o->len;
-  }
-
-  return b;
-}
-
-
-struct mwGetBuffer *mwGetBuffer_wrap(const struct mwOpaque *o) {
-  struct mwGetBuffer *b = g_new0(struct mwGetBuffer, 1);
-
-  if(o && o->len) {
-    b->buf = b->ptr = o->data;
-    b->len = b->rem = o->len;
-  }
-  b->wrap = TRUE;
-
-  return b;
-}
-
-
-gsize mwGetBuffer_read(struct mwGetBuffer *b, gpointer data, gsize len) {
-  g_return_val_if_fail(b != NULL, 0);
-  g_return_val_if_fail(data != NULL, 0);
-
-  if(b->error) return 0;
-  if(! len) return 0;
-
-  if(b->rem < len)
-    len = b->rem;
-
-  memcpy(data, b->ptr, len);
-  b->ptr += len;
-  b->rem -= len;
-
-  return len;
-}
-
-
-gsize mwGetBuffer_advance(struct mwGetBuffer *b, gsize len) {
-  g_return_val_if_fail(b != NULL, 0);
-
-  if(b->error) return 0;
-  if(! len) return 0;
-
-  if(b->rem < len)
-    len = b->rem;
-
-  b->ptr += len;
-  b->rem -= len;
-
-  return len;
-}
-
-
-void mwGetBuffer_reset(struct mwGetBuffer *b) {
-  g_return_if_fail(b != NULL);
-
-  b->rem = b->len;
-  b->ptr = b->buf;
-  b->error = FALSE;
-}
-
-
-gsize mwGetBuffer_remaining(struct mwGetBuffer *b) {
-  g_return_val_if_fail(b != NULL, 0);
-  return b->rem;
-}
-
-
-gboolean mwGetBuffer_error(struct mwGetBuffer *b) {
-  g_return_val_if_fail(b != NULL, TRUE);
-  return b->error;
-}
-
-
-void mwGetBuffer_free(struct mwGetBuffer *b) {
-  if(! b) return;
-  if(! b->wrap) g_free(b->buf);
-  g_free(b);
-}
-
-
-#define guint16_buflen()  2
-
-
-void guint16_put(struct mwPutBuffer *b, guint16 val) {
-  g_return_if_fail(b != NULL);
-
-  ensure_buffer(b, guint16_buflen());
-  MW16_PUT(b->ptr, val);
-  b->rem -= guint16_buflen();
-}
-
-
-void guint16_get(struct mwGetBuffer *b, guint16 *val) {
-  g_return_if_fail(b != NULL);
-
-  if(b->error) return;
-  g_return_if_fail(check_buffer(b, guint16_buflen()));
-
-  MW16_GET(b->ptr, *val);
-  b->rem -= guint16_buflen();
-}
-
-
-guint16 guint16_peek(struct mwGetBuffer *b) {
-  guchar *buf = b->buf;
-  guint16 r = 0;
-  
-  if(b->rem >= guint16_buflen())
-    MW16_GET(buf, r);
-
-  return r;
-}
-
-
-#define guint32_buflen()  4
-
-
-void guint32_put(struct mwPutBuffer *b, guint32 val) {
-  g_return_if_fail(b != NULL);
-
-  ensure_buffer(b, guint32_buflen());
-  MW32_PUT(b->ptr, val);
-  b->rem -= guint32_buflen();
-}
-
-
-void guint32_get(struct mwGetBuffer *b, guint32 *val) {
-  g_return_if_fail(b != NULL);
-
-  if(b->error) return;
-  g_return_if_fail(check_buffer(b, guint32_buflen()));
-
-  MW32_GET(b->ptr, *val);
-  b->rem -= guint32_buflen();
-}
-
-
-guint32 guint32_peek(struct mwGetBuffer *b) {
-  guchar *buf = b->buf;
-  guint32 r = 0;
-
-  if(b->rem >= guint32_buflen())
-    MW32_GET(buf, r);
-
-  return r;
-}
-
-
-#define gboolean_buflen()  1
-
-
-void gboolean_put(struct mwPutBuffer *b, gboolean val) {
-  g_return_if_fail(b != NULL);
-
-  ensure_buffer(b, gboolean_buflen());
-  *(b->ptr) = !! val;
-  b->ptr++;
-  b->rem--;
-}
-
-
-void gboolean_get(struct mwGetBuffer *b, gboolean *val) {
-  g_return_if_fail(b != NULL);
-
-  if(b->error) return;
-  g_return_if_fail(check_buffer(b, gboolean_buflen()));
-
-  *val = !! *(b->ptr);
-  b->ptr++;
-  b->rem--;
-}
-
-
-gboolean gboolean_peek(struct mwGetBuffer *b) {
-  gboolean v = FALSE;
-
-  if(b->rem >= gboolean_buflen())
-    v = !! *(b->ptr);
-
-  return v;
-}
-
-
-gboolean mw_streq(const char *a, const char *b) {
-  return (a == b) || (a && b && !strcmp(a, b));
-}
-
-
-void mwString_put(struct mwPutBuffer *b, const char *val) {
-  gsize len = 0;
-
-  g_return_if_fail(b != NULL);
-
-  if(val) len = strlen(val);
-
-  guint16_put(b, (guint16) len);
-
-  if(len) {
-    ensure_buffer(b, len);
-    memcpy(b->ptr, val, len);
-    b->ptr += len;
-    b->rem -= len;
-  }
-}
-
-
-void mwString_get(struct mwGetBuffer *b, char **val) {
-  guint16 len = 0;
-
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(val != NULL);
-
-  *val = NULL;
-
-  if(b->error) return;
-  guint16_get(b, &len);
-
-  g_return_if_fail(check_buffer(b, (gsize) len));
-
-  if(len) {
-    *val = g_malloc0(len + 1);
-    memcpy(*val, b->ptr, len);
-    b->ptr += len;
-    b->rem -= len;
-  }
-}
-
-
-void mwOpaque_put(struct mwPutBuffer *b, const struct mwOpaque *o) {
-  gsize len;
-
-  g_return_if_fail(b != NULL);
-
-  if(! o) {
-    guint32_put(b, 0x00);
-    return;
-  }
-
-  len = o->len;
-  if(len)
-    g_return_if_fail(o->data != NULL);
-  
-  guint32_put(b, (guint32) len);
-
-  if(len) {
-    ensure_buffer(b, len);
-    memcpy(b->ptr, o->data, len);
-    b->ptr += len;
-    b->rem -= len;
-  }
-}
-
-
-void mwOpaque_get(struct mwGetBuffer *b, struct mwOpaque *o) {
-  guint32 tmp = 0;
-
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(o != NULL);
-
-  o->len = 0;
-  o->data = NULL;
-  
-  if(b->error) return;
-  guint32_get(b, &tmp);
-
-  g_return_if_fail(check_buffer(b, (gsize) tmp));
-
-  o->len = (gsize) tmp;
-  if(tmp > 0) {
-    o->data = g_memdup(b->ptr, tmp);
-    b->ptr += tmp;
-    b->rem -= tmp;
-  }
-}
-
-
-void mwOpaque_clear(struct mwOpaque *o) {
-  if(! o) return;
-  g_free(o->data);
-  o->data = NULL;
-  o->len = 0;
-}
-
-
-void mwOpaque_free(struct mwOpaque *o) {
-  if(! o) return;
-  g_free(o->data);
-  g_free(o);
-}
-
-
-void mwOpaque_clone(struct mwOpaque *to, const struct mwOpaque *from) {
-  g_return_if_fail(to != NULL);
-
-  to->len = 0;
-  to->data = NULL;
-
-  if(from) {
-    to->len = from->len;
-    if(to->len)
-      to->data = g_memdup(from->data, to->len);
-  }
-}
-
-
-/* 8.2 Common Structures */
-/* 8.2.1 Login Info block */
-
-
-void mwLoginInfo_put(struct mwPutBuffer *b, const struct mwLoginInfo *login) {
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(login != NULL);
-
-  mwString_put(b, login->login_id);
-  guint16_put(b, login->type);
-  mwString_put(b, login->user_id);
-  mwString_put(b, login->user_name);
-  mwString_put(b, login->community);
-  gboolean_put(b, login->full);
-
-  if(login->full) {
-    mwString_put(b, login->desc);
-    guint32_put(b, login->ip_addr);
-    mwString_put(b, login->server_id);
-  }
-}
-
-
-void mwLoginInfo_get(struct mwGetBuffer *b, struct mwLoginInfo *login) {
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(login != NULL);
-
-  if(b->error) return;
-
-  mwString_get(b, &login->login_id);
-  guint16_get(b, &login->type);
-  mwString_get(b, &login->user_id);
-  mwString_get(b, &login->user_name);
-  mwString_get(b, &login->community);
-  gboolean_get(b, &login->full);
-  
-  if(login->full) {
-    mwString_get(b, &login->desc);
-    guint32_get(b, &login->ip_addr);
-    mwString_get(b, &login->server_id);
-  }
-}
-
-
-void mwLoginInfo_clear(struct mwLoginInfo *login) {
-  if(! login) return;
-
-  g_free(login->login_id);
-  g_free(login->user_id);
-  g_free(login->user_name);
-  g_free(login->community);
-  g_free(login->desc);
-  g_free(login->server_id);
-
-  memset(login, 0x00, sizeof(struct mwLoginInfo));
-}
-
-
-void mwLoginInfo_clone(struct mwLoginInfo *to,
-		       const struct mwLoginInfo *from) {
-
-  g_return_if_fail(to != NULL);
-  g_return_if_fail(from != NULL);
-
-  to->login_id= g_strdup(from->login_id);
-  to->type = from->type;
-  to->user_id = g_strdup(from->user_id);
-  to->user_name = g_strdup(from->user_name);
-  to->community = g_strdup(from->community);
-
-  if( (to->full = from->full) ) {
-    to->desc = g_strdup(from->desc);
-    to->ip_addr = from->ip_addr;
-    to->server_id = g_strdup(from->server_id);
-  }
-}
-
-
-/* 8.2.2 Private Info Block */
-
-
-void mwUserItem_put(struct mwPutBuffer *b, const struct mwUserItem *user) {
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(user != NULL);
-
-  gboolean_put(b, user->full);
-  mwString_put(b, user->id);
-  mwString_put(b, user->community);
-  
-  if(user->full)
-    mwString_put(b, user->name);
-}
-
-
-void mwUserItem_get(struct mwGetBuffer *b, struct mwUserItem *user) {
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(user != NULL);
-
-  if(b->error) return;
-
-  gboolean_get(b, &user->full);
-  mwString_get(b, &user->id);
-  mwString_get(b, &user->community);
-
-  if(user->full)
-    mwString_get(b, &user->name);
-}
-
-
-void mwUserItem_clear(struct mwUserItem *user) {
-  if(! user) return;
-
-  g_free(user->id);
-  g_free(user->community);
-  g_free(user->name);
-
-  memset(user, 0x00, sizeof(struct mwUserItem));
-}
-
-
-void mwUserItem_clone(struct mwUserItem *to,
-		      const struct mwUserItem *from) {
-
-  g_return_if_fail(to != NULL);
-  g_return_if_fail(from != NULL);
-
-  to->full = from->full;
-  to->id = g_strdup(from->id);
-  to->community = g_strdup(from->community);
-  to->name = (to->full)? g_strdup(from->name): NULL;
-}
-
-
-void mwPrivacyInfo_put(struct mwPutBuffer *b,
-		       const struct mwPrivacyInfo *info) {
-  guint32 c;
-
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(info != NULL);
-
-  gboolean_put(b, info->deny);
-  guint32_put(b, info->count);
-
-  for(c = info->count; c--; ) mwUserItem_put(b, info->users + c);
-}
-
-
-void mwPrivacyInfo_get(struct mwGetBuffer *b, struct mwPrivacyInfo *info) {
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(info != NULL);
-
-  if(b->error) return;
-
-  gboolean_get(b, &info->deny);
-  guint32_get(b, &info->count);
-
-  if(info->count) {
-    guint32 c = info->count;
-    info->users = g_new0(struct mwUserItem, c);
-    while(c--) mwUserItem_get(b, info->users + c);
-  }
-}
-
-
-void mwPrivacyInfo_clone(struct mwPrivacyInfo *to,
-			 const struct mwPrivacyInfo *from) {
-
-  guint32 c;
-
-  g_return_if_fail(to != NULL);
-  g_return_if_fail(from != NULL);
-
-  to->deny = from->deny;
-  c = to->count = from->count;
-
-  to->users = g_new0(struct mwUserItem, c);
-  while(c--) mwUserItem_clone(to->users+c, from->users+c);
-}
-
-
-void mwPrivacyInfo_clear(struct mwPrivacyInfo *info) {
-  struct mwUserItem *u;
-  guint32 c;
-
-  g_return_if_fail(info != NULL);
-
-  u = info->users;
-  c = info->count;
-
-  while(c--) mwUserItem_clear(u + c);
-  g_free(u);
-
-  info->count = 0;
-  info->users = NULL;
-}
-
-
-/* 8.2.3 User Status Block */
-
-
-void mwUserStatus_put(struct mwPutBuffer *b,
-		      const struct mwUserStatus *stat) {
-
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(stat != NULL);
-
-  guint16_put(b, stat->status);
-  guint32_put(b, stat->time);
-  mwString_put(b, stat->desc);
-}
-
-
-void mwUserStatus_get(struct mwGetBuffer *b, struct mwUserStatus *stat) {
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(stat != NULL);
-
-  if(b->error) return;
-
-  guint16_get(b, &stat->status);
-  guint32_get(b, &stat->time);
-  mwString_get(b, &stat->desc);
-}
-
-
-void mwUserStatus_clear(struct mwUserStatus *stat) {
-  if(! stat) return;
-  g_free(stat->desc);
-  memset(stat, 0x00, sizeof(struct mwUserStatus));
-}
-
-
-void mwUserStatus_clone(struct mwUserStatus *to,
-			const struct mwUserStatus *from) {
-
-  g_return_if_fail(to != NULL);
-  g_return_if_fail(from != NULL);
-
-  to->status = from->status;
-  to->time = from->time;
-  to->desc = g_strdup(from->desc);
-}
-
-
-/* 8.2.4 ID Block */
-
-
-void mwIdBlock_put(struct mwPutBuffer *b, const struct mwIdBlock *id) {
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(id != NULL);
-
-  mwString_put(b, id->user);
-  mwString_put(b, id->community);
-}
-
-
-void mwIdBlock_get(struct mwGetBuffer *b, struct mwIdBlock *id) {
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(id != NULL);
-
-  if(b->error) return;
-
-  mwString_get(b, &id->user);
-  mwString_get(b, &id->community);
-}
-
-
-void mwIdBlock_clear(struct mwIdBlock *id) {
-  if(! id) return;
-
-  g_free(id->user);
-  id->user = NULL;
-
-  g_free(id->community);
-  id->community = NULL;
-}
-
-
-void mwIdBlock_clone(struct mwIdBlock *to, const struct mwIdBlock *from) {
-  g_return_if_fail(to != NULL);
-  g_return_if_fail(from != NULL);
-
-  to->user = g_strdup(from->user);
-  to->community = g_strdup(from->community);
-}
-
-
-guint mwIdBlock_hash(const struct mwIdBlock *idb) {
-  return (idb)? g_str_hash(idb->user): 0;
-}
-
-
-gboolean mwIdBlock_equal(const struct mwIdBlock *a,
-			 const struct mwIdBlock *b) {
-
-  g_return_val_if_fail(a != NULL, FALSE);
-  g_return_val_if_fail(b != NULL, FALSE);
-
-  return ( mw_streq(a->user, b->user) &&
-	   mw_streq(a->community, b->community) );
-}
-
-
-/* 8.2.5 Encryption Block */
-
-/** @todo I think this can be put into cipher */
-
-void mwEncryptItem_put(struct mwPutBuffer *b,
-		       const struct mwEncryptItem *ei) {
-
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(ei != NULL);
-  
-  guint16_put(b, ei->id);
-  mwOpaque_put(b, &ei->info);
-
-}
-
-
-void mwEncryptItem_get(struct mwGetBuffer *b, struct mwEncryptItem *ei) {
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(ei != NULL);
-
-  if(b->error) return;
-
-  guint16_get(b, &ei->id);
-  mwOpaque_get(b, &ei->info);
-}
-
-
-void mwEncryptItem_clear(struct mwEncryptItem *ei) {
-  if(! ei) return;
-  ei->id = 0x0000;
-  mwOpaque_clear(&ei->info);
-}
-
-
-void mwEncryptItem_free(struct mwEncryptItem *ei) {
-  mwEncryptItem_clear(ei);
-  g_free(ei);
-}
-
-
-/* 8.4.2.1 Awareness ID Block */
-
-
-/** @todo move this into srvc_aware */
-
-void mwAwareIdBlock_put(struct mwPutBuffer *b,
-			const struct mwAwareIdBlock *idb) {
-
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(idb != NULL);
-
-  guint16_put(b, idb->type);
-  mwString_put(b, idb->user);
-  mwString_put(b, idb->community);
-}
-
-
-void mwAwareIdBlock_get(struct mwGetBuffer *b, struct mwAwareIdBlock *idb) {
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(idb != NULL);
-
-  if(b->error) return;
-
-  guint16_get(b, &idb->type);
-  mwString_get(b, &idb->user);
-  mwString_get(b, &idb->community);
-}
-
-
-void mwAwareIdBlock_clone(struct mwAwareIdBlock *to,
-			  const struct mwAwareIdBlock *from) {
-
-  g_return_if_fail(to != NULL);
-  g_return_if_fail(from != NULL);
-
-  to->type = from->type;
-  to->user = g_strdup(from->user);
-  to->community = g_strdup(from->community);
-}
-
-
-void mwAwareIdBlock_clear(struct mwAwareIdBlock *idb) {
-  if(! idb) return;
-  g_free(idb->user);
-  g_free(idb->community);
-  memset(idb, 0x00, sizeof(struct mwAwareIdBlock));
-}
-
-
-guint mwAwareIdBlock_hash(const struct mwAwareIdBlock *a) {
-  return (a)? g_str_hash(a->user): 0;
-}
-
-
-gboolean mwAwareIdBlock_equal(const struct mwAwareIdBlock *a,
-			      const struct mwAwareIdBlock *b) {
-
-  g_return_val_if_fail(a != NULL, FALSE);
-  g_return_val_if_fail(b != NULL, FALSE);
-  
-  return ( (a->type == b->type) &&
-	   mw_streq(a->user, b->user) &&
-	   mw_streq(a->community, b->community) );
-}
-
-
-/* 8.4.2.4 Snapshot */
-
-void mwAwareSnapshot_get(struct mwGetBuffer *b, struct mwAwareSnapshot *idb) {
-  guint32 junk;
-  char *empty = NULL;
-
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(idb != NULL);
-
-  guint32_get(b, &junk);
-  mwAwareIdBlock_get(b, &idb->id);
-  mwString_get(b, &idb->group);
-  gboolean_get(b, &idb->online);
-
-  g_free(empty);
-
-  if(idb->online) {
-    mwString_get(b, &idb->alt_id);
-    mwUserStatus_get(b, &idb->status);
-    mwString_get(b, &idb->name);
-  }
-}
-
-
-void mwAwareSnapshot_clone(struct mwAwareSnapshot *to,
-			   const struct mwAwareSnapshot *from) {
-
-  g_return_if_fail(to != NULL);
-  g_return_if_fail(from != NULL);
-
-  mwAwareIdBlock_clone(&to->id, &from->id);
-  if( (to->online = from->online) ) {
-    to->alt_id = g_strdup(from->alt_id);
-    mwUserStatus_clone(&to->status, &from->status);
-    to->name = g_strdup(from->name);
-    to->group = g_strdup(from->group);
-  }
-}
-
-
-void mwAwareSnapshot_clear(struct mwAwareSnapshot *idb) {
-  if(! idb) return;
-  mwAwareIdBlock_clear(&idb->id);
-  mwUserStatus_clear(&idb->status);
-  g_free(idb->alt_id);
-  g_free(idb->name);
-  g_free(idb->group);
-  memset(idb, 0x00, sizeof(struct mwAwareSnapshot));
-}
-
--- a/src/protocols/sametime/meanwhile/error.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <stdio.h>
-#include <string.h>
-
-#include "mw_error.h"
-
-
-static char *err_to_str(guint32 code) {
-  static char b[11]; /* 0x12345678 + NULL terminator */
-  sprintf((char *) b, "0x%08x", code);
-  b[10] = '\0';
-  return b;
-}
-
-
-#define CASE(val, str) \
-case val: \
-  m = str; \
-  break;
-
-
-char* mwError(guint32 code) {
-  const char *m;
-
-  switch(code) {
-
-    /* 8.3.1.1 General error/success codes */
-    CASE(ERR_SUCCESS, "Success");
-    CASE(ERR_FAILURE, "General failure");
-    CASE(ERR_REQUEST_DELAY, "Request delayed");
-    CASE(ERR_REQUEST_INVALID, "Request is invalid");
-    CASE(ERR_NOT_AUTHORIZED, "Not authorized");
-    CASE(ERR_NO_USER, "User is not online");
-    CASE(ERR_CHANNEL_NO_SUPPORT, "Requested channel is not supported");
-    CASE(ERR_CHANNEL_EXISTS, "Requested channel already exists");
-    CASE(ERR_SERVICE_NO_SUPPORT, "Requested service is not supported");
-    CASE(ERR_PROTOCOL_NO_SUPPORT, "Requested protocol is not supported");
-    CASE(ERR_VERSION_NO_SUPPORT, "Version is not supported");
-    CASE(ERR_USER_SKETCHY, "User is invalid or not trusted");
-    CASE(ERR_ALREADY_INITIALIZED, "Already initialized");
-    CASE(ERR_ENCRYPT_NO_SUPPORT, "Encryption method not supported");
-    CASE(ERR_NO_COMMON_ENCRYPT, "No common encryption method");
-    
-    /* 8.3.1.2 Connection/disconnection errors */
-    CASE(VERSION_MISMATCH, "Version mismatch");
-    CASE(FAT_MESSAGE, "Message is too large");
-    CASE(CONNECTION_BROKEN, "Connection broken");
-    CASE(CONNECTION_ABORTED, "Connection aborted");
-    CASE(CONNECTION_REFUSED, "Connection refused");
-    CASE(CONNECTION_RESET, "Connection reset");
-    CASE(CONNECTION_TIMED, "Connection timed out");
-    CASE(CONNECTION_CLOSED, "Connection closed");
-    CASE(INCORRECT_LOGIN, "Incorrect Username/Password");
-    CASE(VERIFICATION_DOWN, "Login verification down or unavailable");
-    CASE(GUEST_IN_USE, "The guest name is currently being used");
-    CASE(MULTI_SERVER_LOGIN, "Login to two different servers concurrently");
-    CASE(MULTI_SERVER_LOGIN2, "Login to two different servers concurrently");
-    CASE(SERVER_BROKEN, "Server misconfiguration");
-
-    /* 8.3.1.3 Client error codes */
-    CASE(ERR_CLIENT_USER_GONE, "User is not online");
-    CASE(ERR_CLIENT_USER_DND, "User is in Do Not Disturb mode");
-    CASE(ERR_CLIENT_USER_ELSEWHERE, "Already logged in elsewhere");
-
-    /* 8.3.1.4 IM error codes */
-    CASE(ERR_IM_COULDNT_REGISTER, "Cannot register a reserved type");
-    CASE(ERR_IM_ALREADY_REGISTERED, "Requested type is already registered");
-    CASE(ERR_IM_NOT_REGISTERED, "Requested type is not registered");
-
-  default:
-    m = err_to_str(code);
-  }
-
-  return g_strdup(m);
-}
-
-
-#undef CASE
--- a/src/protocols/sametime/meanwhile/message.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,853 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <glib.h>
-
-#include "mw_debug.h"
-#include "mw_message.h"
-
-
-/* 7.1 Layering and message encapsulation */
-/* 7.1.1 The Sametime Message Header */
-
-
-static void mwMessageHead_put(struct mwPutBuffer *b, struct mwMessage *msg) {
-  guint16_put(b, msg->type);
-  guint16_put(b, msg->options);
-  guint32_put(b, msg->channel);
-  
-  if(msg->options & mwMessageOption_HAS_ATTRIBS)
-    mwOpaque_put(b, &msg->attribs);
-}
-
-
-static void mwMessageHead_get(struct mwGetBuffer *b, struct mwMessage *msg) {
-
-  if(mwGetBuffer_error(b)) return;
-
-  guint16_get(b, &msg->type);
-  guint16_get(b, &msg->options);
-  guint32_get(b, &msg->channel);
-
-  if(msg->options & mwMessageOption_HAS_ATTRIBS)
-    mwOpaque_get(b, &msg->attribs);
-}
-
-
-static void mwMessageHead_clone(struct mwMessage *to,
-				struct mwMessage *from) {
-
-  to->type = from->type;
-  to->options = from->options;
-  to->channel = from->channel;
-  mwOpaque_clone(&to->attribs, &from->attribs);
-}
-
-
-static void mwMessageHead_clear(struct mwMessage *msg) {
-  mwOpaque_clear(&msg->attribs);
-}
-
-
-/* 8.4 Messages */
-/* 8.4.1 Basic Community Messages */
-/* 8.4.1.1 Handshake */
-
-
-static void HANDSHAKE_put(struct mwPutBuffer *b, struct mwMsgHandshake *msg) {
-  guint16_put(b, msg->major);
-  guint16_put(b, msg->minor);
-  guint32_put(b, msg->head.channel);
-  guint32_put(b, msg->srvrcalc_addr);
-  guint16_put(b, msg->login_type);
-  guint32_put(b, msg->loclcalc_addr);
-  
-  if(msg->major >= 0x001e && msg->minor >= 0x001d) {
-    guint16_put(b, msg->unknown_a);
-    guint32_put(b, msg->unknown_b);
-    mwString_put(b, msg->local_host);
-  }
-}
-
-
-static void HANDSHAKE_get(struct mwGetBuffer *b, struct mwMsgHandshake *msg) {
-  if(mwGetBuffer_error(b)) return;
-
-  guint16_get(b, &msg->major);
-  guint16_get(b, &msg->minor);
-  guint32_get(b, &msg->head.channel);
-  guint32_get(b, &msg->srvrcalc_addr);
-  guint16_get(b, &msg->login_type);
-  guint32_get(b, &msg->loclcalc_addr);
-
-  if(msg->major >= 0x001e && msg->minor >= 0x001d) {
-    guint16_get(b, &msg->unknown_a);
-    guint32_get(b, &msg->unknown_b);
-    mwString_get(b, &msg->local_host);
-  }
-}
-
-
-static void HANDSHAKE_clear(struct mwMsgHandshake *msg) {
-  ; /* nothing to clean up */
-}
-
-
-/* 8.4.1.2 HandshakeAck */
-
-
-static void HANDSHAKE_ACK_get(struct mwGetBuffer *b,
-			      struct mwMsgHandshakeAck *msg) {
-
-  if(mwGetBuffer_error(b)) return;
-
-  guint16_get(b, &msg->major);
-  guint16_get(b, &msg->minor);
-  guint32_get(b, &msg->srvrcalc_addr);
-
-  /** @todo: get a better handle on what versions support what parts
-      of this message. eg: minor version 0x0018 doesn't send the
-      following */
-  if(msg->major >= 0x1e && msg->minor > 0x18) {
-    guint32_get(b, &msg->magic);
-    mwOpaque_get(b, &msg->data);
-  }
-}
-
-
-static void HANDSHAKE_ACK_put(struct mwPutBuffer *b,
-			      struct mwMsgHandshakeAck *msg) {
-
-  guint16_put(b, msg->major);
-  guint16_put(b, msg->minor);
-  guint32_put(b, msg->srvrcalc_addr);
-
-  if(msg->major >= 0x1e && msg->minor > 0x18) {
-    guint32_put(b, msg->magic);
-    mwOpaque_put(b, &msg->data);
-  }
-}
-
-
-static void HANDSHAKE_ACK_clear(struct mwMsgHandshakeAck *msg) {
-  mwOpaque_clear(&msg->data);
-}
-
-
-/* 8.4.1.3 Login */
-
-
-static void LOGIN_put(struct mwPutBuffer *b, struct mwMsgLogin *msg) {
-  guint16_put(b, msg->login_type);
-  mwString_put(b, msg->name);
-
-  /* ordering reversed from houri draft?? */
-  mwOpaque_put(b, &msg->auth_data);
-  guint16_put(b, msg->auth_type);
-
-  guint16_put(b, 0x0000); /* unknown */
-}
-
-
-static void LOGIN_get(struct mwGetBuffer *b, struct mwMsgLogin *msg) {
-  if(mwGetBuffer_error(b)) return;
-
-  guint16_get(b, &msg->login_type);
-  mwString_get(b, &msg->name);
-  mwOpaque_get(b, &msg->auth_data);
-  guint16_get(b, &msg->auth_type);
-}
-
-
-static void LOGIN_clear(struct mwMsgLogin *msg) {
-  g_free(msg->name);  msg->name = NULL;
-  mwOpaque_clear(&msg->auth_data);
-}
-
-
-/* 8.4.1.4 LoginAck */
-
-
-static void LOGIN_ACK_get(struct mwGetBuffer *b, struct mwMsgLoginAck *msg) {
-  guint16 junk;
-
-  if(mwGetBuffer_error(b)) return;
-
-  mwLoginInfo_get(b, &msg->login);
-  guint16_get(b, &junk);
-  mwPrivacyInfo_get(b, &msg->privacy);
-  mwUserStatus_get(b, &msg->status);
-}
-
-
-static void LOGIN_ACK_clear(struct mwMsgLoginAck *msg) {
-  mwLoginInfo_clear(&msg->login);
-  mwPrivacyInfo_clear(&msg->privacy);
-  mwUserStatus_clear(&msg->status);
-}
-
-
-/* 8.4.1.5 LoginCont */
-
-
-static void LOGIN_CONTINUE_put(struct mwPutBuffer *b,
-			       struct mwMsgLoginContinue *msg) {
-
-  ; /* nothing but a message header */
-}
-
-
-static void LOGIN_CONTINUE_get(struct mwGetBuffer *b,
-			       struct mwMsgLoginContinue *msg) {
-
-  ; /* nothing but a message header */
-}
-
-
-static void LOGIN_CONTINUE_clear(struct mwMsgLoginContinue *msg) {
-  ; /* this is a very simple message */
-}
-
-
-/* 8.4.1.6 AuthPassed */
-
-
-static void LOGIN_REDIRECT_get(struct mwGetBuffer *b,
-			       struct mwMsgLoginRedirect *msg) {
-
-  if(mwGetBuffer_error(b)) return;
-  mwString_get(b, &msg->host);
-  mwString_get(b, &msg->server_id);  
-}
-
-
-static void LOGIN_REDIRECT_put(struct mwPutBuffer *b,
-			       struct mwMsgLoginRedirect *msg) {
-  mwString_put(b, msg->host);
-  mwString_put(b, msg->server_id);
-}
-
-
-static void LOGIN_REDIRECT_clear(struct mwMsgLoginRedirect *msg) {
-  g_free(msg->host);
-  msg->host = NULL;
-
-  g_free(msg->server_id);
-  msg->server_id = NULL;
-}
-
-
-/* 8.4.1.7 CreateCnl */
-
-
-static void enc_offer_put(struct mwPutBuffer *b, struct mwEncryptOffer *enc) {
-  guint16_put(b, enc->mode);
-
-  if(enc->items) {
-    guint32 count;
-    struct mwPutBuffer *p;
-    struct mwOpaque o;
-    GList *list;
-
-    /* write the count, items, extra, and flag into a tmp buffer,
-       render that buffer into an opaque, and write it into b */
-
-    count = g_list_length(enc->items);
-    p = mwPutBuffer_new();
-
-    guint32_put(p, count);
-    for(list = enc->items; list; list = list->next) {
-      mwEncryptItem_put(p, list->data);
-    }
-
-    guint16_put(p, enc->extra);
-    gboolean_put(p, enc->flag);
-
-    mwPutBuffer_finalize(&o, p);
-    mwOpaque_put(b, &o);
-    mwOpaque_clear(&o);
-  }
-}
-
-
-static void CHANNEL_CREATE_put(struct mwPutBuffer *b,
-			       struct mwMsgChannelCreate *msg) {
-
-  guint32_put(b, msg->reserved);
-  guint32_put(b, msg->channel);
-  mwIdBlock_put(b, &msg->target);
-  guint32_put(b, msg->service);
-  guint32_put(b, msg->proto_type);
-  guint32_put(b, msg->proto_ver);
-  guint32_put(b, msg->options);
-  mwOpaque_put(b, &msg->addtl);
-  gboolean_put(b, msg->creator_flag);
-
-  if(msg->creator_flag)
-    mwLoginInfo_put(b, &msg->creator);
-
-  enc_offer_put(b, &msg->encrypt);
-
-  guint32_put(b, 0x00);
-  guint32_put(b, 0x00);
-  guint16_put(b, 0x07);
-}
-
-
-static void enc_offer_get(struct mwGetBuffer *b,
-			  struct mwEncryptOffer *enc) {
-  guint32 skip;
-
-  if(mwGetBuffer_error(b)) return;
-
-  guint16_get(b, &enc->mode);
-  guint32_get(b, &skip);
-
-  if(skip >= 7) {
-    guint32 count;
-
-    guint32_get(b, &count);
-
-    while(count-- && (! mwGetBuffer_error(b))) {
-      struct mwEncryptItem *ei = g_new0(struct mwEncryptItem, 1);
-      mwEncryptItem_get(b, ei);
-      enc->items = g_list_append(enc->items, ei);
-    }
-
-    guint16_get(b, &enc->extra);
-    gboolean_get(b, &enc->flag);
-  }
-}
-
-
-static void CHANNEL_CREATE_get(struct mwGetBuffer *b,
-			       struct mwMsgChannelCreate *msg) {
-
-  if(mwGetBuffer_error(b)) return;
-
-  guint32_get(b, &msg->reserved);
-  guint32_get(b, &msg->channel);
-  mwIdBlock_get(b, &msg->target);
-  guint32_get(b, &msg->service);
-  guint32_get(b, &msg->proto_type);
-  guint32_get(b, &msg->proto_ver);
-  guint32_get(b, &msg->options);
-  mwOpaque_get(b, &msg->addtl);
-  gboolean_get(b, &msg->creator_flag);
-  
-  if(msg->creator_flag)
-    mwLoginInfo_get(b, &msg->creator);
-  
-  enc_offer_get(b, &msg->encrypt);
-}
-
-
-static void CHANNEL_CREATE_clear(struct mwMsgChannelCreate *msg) {
-  GList *list;
-
-  mwIdBlock_clear(&msg->target);
-  mwOpaque_clear(&msg->addtl);
-  mwLoginInfo_clear(&msg->creator);
-  
-  for(list = msg->encrypt.items; list; list = list->next) {
-    mwEncryptItem_clear(list->data);
-    g_free(list->data);
-  }
-  g_list_free(msg->encrypt.items);
-}
-
-
-/* 8.4.1.8 AcceptCnl */
-
-
-static void enc_accept_put(struct mwPutBuffer *b,
-			   struct mwEncryptAccept *enc) {
-
-  guint16_put(b, enc->mode);
-
-  if(enc->item) {
-    struct mwPutBuffer *p;
-    struct mwOpaque o;
-
-    p = mwPutBuffer_new();
-
-    mwEncryptItem_put(p, enc->item);
-    guint16_put(p, enc->extra);
-    gboolean_put(p, enc->flag);
-
-    mwPutBuffer_finalize(&o, p);
-    mwOpaque_put(b, &o);
-    mwOpaque_clear(&o);
-  }
-}
-
-
-static void CHANNEL_ACCEPT_put(struct mwPutBuffer *b,
-			       struct mwMsgChannelAccept *msg) {
-  
-  guint32_put(b, msg->service);
-  guint32_put(b, msg->proto_type);
-  guint32_put(b, msg->proto_ver);
-  mwOpaque_put(b, &msg->addtl);
-  gboolean_put(b, msg->acceptor_flag);
-  
-  if(msg->acceptor_flag)
-    mwLoginInfo_put(b, &msg->acceptor);
-  
-  enc_accept_put(b, &msg->encrypt);
-
-  guint32_put(b, 0x00);
-  guint32_put(b, 0x00);
-  guint16_put(b, 0x07);
-}
-
-
-static void enc_accept_get(struct mwGetBuffer *b,
-			   struct mwEncryptAccept *enc) {
-  guint32 skip;
-
-  if(mwGetBuffer_error(b)) return;
-
-  guint16_get(b, &enc->mode);
-  guint32_get(b, &skip);
-
-  if(skip >= 6) {
-    enc->item = g_new0(struct mwEncryptItem, 1);
-    mwEncryptItem_get(b, enc->item);
-  }
-
-  if(skip >= 9) {
-    guint16_get(b, &enc->extra);
-    gboolean_get(b, &enc->flag);
-  }
-}
-
-
-static void CHANNEL_ACCEPT_get(struct mwGetBuffer *b,
-			       struct mwMsgChannelAccept *msg) {
-
-  if(mwGetBuffer_error(b)) return;
-
-  guint32_get(b, &msg->service);
-  guint32_get(b, &msg->proto_type);
-  guint32_get(b, &msg->proto_ver);
-  mwOpaque_get(b, &msg->addtl);
-  gboolean_get(b, &msg->acceptor_flag);
-
-  if(msg->acceptor_flag)
-    mwLoginInfo_get(b, &msg->acceptor);
-
-  enc_accept_get(b, &msg->encrypt);
-}
-
-
-static void CHANNEL_ACCEPT_clear(struct mwMsgChannelAccept *msg) {
-  mwOpaque_clear(&msg->addtl);
-  mwLoginInfo_clear(&msg->acceptor);
-
-  if(msg->encrypt.item) {
-    mwEncryptItem_clear(msg->encrypt.item);
-    g_free(msg->encrypt.item);
-  }
-}
-
-
-/* 8.4.1.9 SendOnCnl */
-
-
-static void CHANNEL_SEND_put(struct mwPutBuffer *b,
-			     struct mwMsgChannelSend *msg) {
-
-  guint16_put(b, msg->type);
-  mwOpaque_put(b, &msg->data);
-}
-
-
-static void CHANNEL_SEND_get(struct mwGetBuffer *b,
-			     struct mwMsgChannelSend *msg) {
-
-  if(mwGetBuffer_error(b)) return;
-
-  guint16_get(b, &msg->type);
-  mwOpaque_get(b, &msg->data);
-}
-
-
-static void CHANNEL_SEND_clear(struct mwMsgChannelSend *msg) {
-  mwOpaque_clear(&msg->data);
-}
-
-
-/* 8.4.1.10 DestroyCnl */
-
-
-static void CHANNEL_DESTROY_put(struct mwPutBuffer *b,
-				struct mwMsgChannelDestroy *msg) {
-  guint32_put(b, msg->reason);
-  mwOpaque_put(b, &msg->data);
-}
-
-
-static void CHANNEL_DESTROY_get(struct mwGetBuffer *b,
-				struct mwMsgChannelDestroy *msg) {
-
-  if(mwGetBuffer_error(b)) return;
-
-  guint32_get(b, &msg->reason);
-  mwOpaque_get(b, &msg->data);
-}
-
-
-static void CHANNEL_DESTROY_clear(struct mwMsgChannelDestroy *msg) {
-  mwOpaque_clear(&msg->data);
-}
-
-
-/* 8.4.1.11 SetUserStatus */
-
-
-static void SET_USER_STATUS_put(struct mwPutBuffer *b,
-				struct mwMsgSetUserStatus *msg) {
-  mwUserStatus_put(b, &msg->status);
-}
-
-
-static void SET_USER_STATUS_get(struct mwGetBuffer *b,
-				struct mwMsgSetUserStatus *msg) {
-
-  if(mwGetBuffer_error(b)) return;
-  mwUserStatus_get(b, &msg->status);
-}
-
-
-static void SET_USER_STATUS_clear(struct mwMsgSetUserStatus *msg) {
-  mwUserStatus_clear(&msg->status);
-}
-
-
-/* 8.4.1.12 SetPrivacyList */
-
-
-static void SET_PRIVACY_LIST_put(struct mwPutBuffer *b,
-				 struct mwMsgSetPrivacyList *msg) {
-  mwPrivacyInfo_put(b, &msg->privacy);
-}
-
-
-static void SET_PRIVACY_LIST_get(struct mwGetBuffer *b,
-				 struct mwMsgSetPrivacyList *msg) {
-
-  if(mwGetBuffer_error(b)) return;
-  mwPrivacyInfo_get(b, &msg->privacy);
-}
-
-
-static void SET_PRIVACY_LIST_clear(struct mwMsgSetPrivacyList *msg) {
-  mwPrivacyInfo_clear(&msg->privacy);
-}
-
-
-/* Sense Service messages */
-
-
-static void SENSE_SERVICE_put(struct mwPutBuffer *b,
-			      struct mwMsgSenseService *msg) {
-  guint32_put(b, msg->service);
-}
-
-
-static void SENSE_SERVICE_get(struct mwGetBuffer *b,
-			      struct mwMsgSenseService *msg) {
-
-  if(mwGetBuffer_error(b)) return;
-  guint32_get(b, &msg->service);
-}
-
-
-static void SENSE_SERVICE_clear(struct mwMsgSenseService *msg) {
-  ;
-}
-
-
-/* Admin messages */
-
-
-static void ADMIN_get(struct mwGetBuffer *b, struct mwMsgAdmin *msg) {
-  mwString_get(b, &msg->text);
-}
-
-
-static void ADMIN_clear(struct mwMsgAdmin *msg) {
-  g_free(msg->text);
-  msg->text = NULL;
-}
-
-
-/* Announcement messages */
-
-
-static void ANNOUNCE_get(struct mwGetBuffer *b, struct mwMsgAnnounce *msg) {
-  struct mwOpaque o = { 0, 0 };
-  struct mwGetBuffer *gb;
-  guint32 count;
-
-  gboolean_get(b, &msg->sender_present);
-  if(msg->sender_present)
-    mwLoginInfo_get(b, &msg->sender);
-  guint16_get(b, &msg->unknown_a);
-  
-  mwOpaque_get(b, &o);
-  gb = mwGetBuffer_wrap(&o);
-
-  gboolean_get(gb, &msg->may_reply);
-  mwString_get(gb, &msg->text);
-
-  mwGetBuffer_free(gb);
-  mwOpaque_clear(&o);
-
-  guint32_get(b, &count);
-  while(count--) {
-    char *r = NULL;
-    mwString_get(b, &r);
-    msg->recipients = g_list_prepend(msg->recipients, r);
-  }
-}
-
-
-static void ANNOUNCE_put(struct mwPutBuffer *b, struct mwMsgAnnounce *msg) {
-  struct mwOpaque o = { 0, 0 };
-  struct mwPutBuffer *pb;
-  GList *l;
-  
-  gboolean_put(b, msg->sender_present);
-  if(msg->sender_present)
-    mwLoginInfo_put(b, &msg->sender);
-  guint16_put(b, msg->unknown_a);
-
-  pb = mwPutBuffer_new();
-  
-  gboolean_put(pb, msg->may_reply);
-  mwString_put(pb, msg->text);
-
-  mwPutBuffer_finalize(&o, pb);
-  mwOpaque_put(b, &o);
-  mwOpaque_clear(&o);
-
-  guint32_put(b, g_list_length(msg->recipients));
-  for(l = msg->recipients; l; l = l->next) {
-    mwString_put(b, l->data);
-  }
-}
-
-
-static void ANNOUNCE_clear(struct mwMsgAnnounce *msg) {
-  mwLoginInfo_clear(&msg->sender);
-
-  g_free(msg->text);
-  msg->text = NULL;
-  
-  while(msg->recipients) {
-    g_free(msg->recipients->data);
-    msg->recipients = g_list_delete_link(msg->recipients, msg->recipients);
-  }
-}
-
-
-/* general functions */
-
-
-#define CASE(v, t) \
-case mwMessage_ ## v: \
-  msg = (struct mwMessage *) g_new0(struct t, 1); \
-  msg->type = type; \
-  break;
-
-
-struct mwMessage *mwMessage_new(enum mwMessageType type) {
-  struct mwMessage *msg = NULL;
-  
-  switch(type) {
-    CASE(HANDSHAKE, mwMsgHandshake);
-    CASE(HANDSHAKE_ACK, mwMsgHandshakeAck);
-    CASE(LOGIN, mwMsgLogin);
-    CASE(LOGIN_REDIRECT, mwMsgLoginRedirect);
-    CASE(LOGIN_CONTINUE, mwMsgLoginContinue);
-    CASE(LOGIN_ACK, mwMsgLoginAck);
-    CASE(CHANNEL_CREATE, mwMsgChannelCreate);
-    CASE(CHANNEL_DESTROY, mwMsgChannelDestroy);
-    CASE(CHANNEL_SEND, mwMsgChannelSend);
-    CASE(CHANNEL_ACCEPT, mwMsgChannelAccept);
-    CASE(SET_USER_STATUS, mwMsgSetUserStatus);
-    CASE(SET_PRIVACY_LIST, mwMsgSetPrivacyList);
-    CASE(SENSE_SERVICE, mwMsgSenseService);
-    CASE(ADMIN, mwMsgAdmin);
-    CASE(ANNOUNCE, mwMsgAnnounce);
-    
-  default:
-    g_warning("unknown message type 0x%02x\n", type);
-  }
-  
-  return msg;
-}
-
-
-#undef CASE
-
-
-/* each type needs to be passed to a specially named _get functions,
-   and cast to a specific subclass of mwMessage. */
-#define CASE(v, t) \
-case mwMessage_ ## v: \
-  msg = (struct mwMessage *) g_new0(struct t, 1); \
-  mwMessageHead_clone(msg, &head); \
-  v ## _get(b, (struct t *) msg); \
-  break;
-
-
-struct mwMessage *mwMessage_get(struct mwGetBuffer *b) {
-  struct mwMessage *msg = NULL;
-  struct mwMessage head;
-  
-  g_return_val_if_fail(b != NULL, NULL);
-
-  head.attribs.len = 0;
-  head.attribs.data = NULL;
-
-  /* attempt to read the header first */
-  mwMessageHead_get(b, &head);
-
-  if(mwGetBuffer_error(b)) {
-    mwMessageHead_clear(&head);
-    g_warning("problem parsing message head from buffer");
-    return NULL;
-  }
-
-  /* load the rest of the message depending on the header type */
-  switch(head.type) {
-    CASE(HANDSHAKE, mwMsgHandshake);
-    CASE(HANDSHAKE_ACK, mwMsgHandshakeAck);
-    CASE(LOGIN, mwMsgLogin);
-    CASE(LOGIN_REDIRECT, mwMsgLoginRedirect);
-    CASE(LOGIN_CONTINUE, mwMsgLoginContinue);
-    CASE(LOGIN_ACK, mwMsgLoginAck);
-    CASE(CHANNEL_CREATE, mwMsgChannelCreate);
-    CASE(CHANNEL_DESTROY, mwMsgChannelDestroy);
-    CASE(CHANNEL_SEND, mwMsgChannelSend);
-    CASE(CHANNEL_ACCEPT, mwMsgChannelAccept);
-    CASE(SET_USER_STATUS, mwMsgSetUserStatus);
-    CASE(SET_PRIVACY_LIST, mwMsgSetPrivacyList);
-    CASE(SENSE_SERVICE, mwMsgSenseService);
-    CASE(ADMIN, mwMsgAdmin);
-    CASE(ANNOUNCE, mwMsgAnnounce);
-
-  default:
-    g_warning("unknown message type 0x%02x, no parse handler", head.type);
-  }
-
-  if(mwGetBuffer_error(b)) {
-    g_warning("problem parsing message type 0x%02x, not enough data",
-	      head.type);
-  }
-
-  mwMessageHead_clear(&head);
-  
-  return msg;
-}
-
-
-#undef CASE
-
-
-#define CASE(v, t) \
-case mwMessage_ ## v: \
-  v ## _put(b, (struct t *) msg); \
-  break;
-
-
-void mwMessage_put(struct mwPutBuffer *b, struct mwMessage *msg) {
-
-  g_return_if_fail(b != NULL);
-  g_return_if_fail(msg != NULL);
-
-  mwMessageHead_put(b, msg);
-
-  switch(msg->type) {
-    CASE(HANDSHAKE, mwMsgHandshake);
-    CASE(HANDSHAKE_ACK, mwMsgHandshakeAck);
-    CASE(LOGIN, mwMsgLogin);
-    CASE(LOGIN_REDIRECT, mwMsgLoginRedirect);
-    CASE(LOGIN_CONTINUE, mwMsgLoginContinue);
-    CASE(CHANNEL_CREATE, mwMsgChannelCreate);
-    CASE(CHANNEL_DESTROY, mwMsgChannelDestroy);
-    CASE(CHANNEL_SEND, mwMsgChannelSend);
-    CASE(CHANNEL_ACCEPT, mwMsgChannelAccept);
-    CASE(SET_USER_STATUS, mwMsgSetUserStatus);
-    CASE(SET_PRIVACY_LIST, mwMsgSetPrivacyList);
-    CASE(SENSE_SERVICE, mwMsgSenseService);
-    CASE(ANNOUNCE, mwMsgAnnounce);
-    
-  default:
-    ; /* hrm. */
-  }
-}
-
-
-#undef CASE
-
-
-#define CASE(v, t) \
-case mwMessage_ ## v: \
-  v ## _clear((struct t *) msg); \
-  break;
-
-
-void mwMessage_free(struct mwMessage *msg) {
-  if(! msg) return;
-
-  mwMessageHead_clear(msg);
-
-  switch(msg->type) {
-    CASE(HANDSHAKE, mwMsgHandshake);
-    CASE(HANDSHAKE_ACK, mwMsgHandshakeAck);
-    CASE(LOGIN, mwMsgLogin);
-    CASE(LOGIN_REDIRECT, mwMsgLoginRedirect);
-    CASE(LOGIN_CONTINUE, mwMsgLoginContinue);
-    CASE(LOGIN_ACK, mwMsgLoginAck);
-    CASE(CHANNEL_CREATE, mwMsgChannelCreate);
-    CASE(CHANNEL_DESTROY, mwMsgChannelDestroy);
-    CASE(CHANNEL_SEND, mwMsgChannelSend);
-    CASE(CHANNEL_ACCEPT, mwMsgChannelAccept);
-    CASE(SET_USER_STATUS, mwMsgSetUserStatus);
-    CASE(SET_PRIVACY_LIST, mwMsgSetPrivacyList);
-    CASE(SENSE_SERVICE, mwMsgSenseService);
-    CASE(ADMIN, mwMsgAdmin);
-    CASE(ANNOUNCE, mwMsgAnnounce);
-    
-  default:
-    ; /* hrm. */
-  }
-
-  g_free(msg);
-}
-
-
-#undef CASE
-
-
--- a/src/protocols/sametime/meanwhile/mpi/.cvsignore	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-.deps
-.libs
-Makefile
-Makefile.in
-lib*
-*o
--- a/src/protocols/sametime/meanwhile/mpi/Makefile.am	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-
-noinst_LTLIBRARIES = libmpi.la
-
-libmpi_la_SOURCES = mpi.c
-
-noinst_HEADERS = logtab.h mpi-config.h mpi.h mpi-types.h
-
--- a/src/protocols/sametime/meanwhile/mpi/logtab.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-const double s_logv_2[] = {
-   0.000000000, 0.000000000, 1.000000000, 0.630929754, 	/*  0  1  2  3 */
-   0.500000000, 0.430676558, 0.386852807, 0.356207187, 	/*  4  5  6  7 */
-   0.333333333, 0.315464877, 0.301029996, 0.289064826, 	/*  8  9 10 11 */
-   0.278942946, 0.270238154, 0.262649535, 0.255958025, 	/* 12 13 14 15 */
-   0.250000000, 0.244650542, 0.239812467, 0.235408913, 	/* 16 17 18 19 */
-   0.231378213, 0.227670249, 0.224243824, 0.221064729, 	/* 20 21 22 23 */
-   0.218104292, 0.215338279, 0.212746054, 0.210309918, 	/* 24 25 26 27 */
-   0.208014598, 0.205846832, 0.203795047, 0.201849087, 	/* 28 29 30 31 */
-   0.200000000, 0.198239863, 0.196561632, 0.194959022, 	/* 32 33 34 35 */
-   0.193426404, 0.191958720, 0.190551412, 0.189200360, 	/* 36 37 38 39 */
-   0.187901825, 0.186652411, 0.185449023, 0.184288833, 	/* 40 41 42 43 */
-   0.183169251, 0.182087900, 0.181042597, 0.180031327, 	/* 44 45 46 47 */
-   0.179052232, 0.178103594, 0.177183820, 0.176291434, 	/* 48 49 50 51 */
-   0.175425064, 0.174583430, 0.173765343, 0.172969690, 	/* 52 53 54 55 */
-   0.172195434, 0.171441601, 0.170707280, 0.169991616, 	/* 56 57 58 59 */
-   0.169293808, 0.168613099, 0.167948779, 0.167300179, 	/* 60 61 62 63 */
-   0.166666667
-};
-
--- a/src/protocols/sametime/meanwhile/mpi/mpi-config.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/* Default configuration for MPI library */
-/* $Id: mpi-config.h 14563 2005-11-29 23:31:40Z taliesein $ */
-
-#ifndef MPI_CONFIG_H_
-#define MPI_CONFIG_H_
-
-/*
-  For boolean options, 
-  0 = no
-  1 = yes
-
-  Other options are documented individually.
-
- */
-
-#ifndef MP_IOFUNC
-#define MP_IOFUNC     0  /* include mp_print() ?                */
-#endif
-
-#ifndef MP_MODARITH
-#define MP_MODARITH   1  /* include modular arithmetic ?        */
-#endif
-
-#ifndef MP_NUMTH
-#define MP_NUMTH      1  /* include number theoretic functions? */
-#endif
-
-#ifndef MP_LOGTAB
-#define MP_LOGTAB     1  /* use table of logs instead of log()? */
-#endif
-
-#ifndef MP_MEMSET
-#define MP_MEMSET     1  /* use memset() to zero buffers?       */
-#endif
-
-#ifndef MP_MEMCPY
-#define MP_MEMCPY     1  /* use memcpy() to copy buffers?       */
-#endif
-
-#ifndef MP_CRYPTO
-#define MP_CRYPTO     0  /* erase memory on free?               */
-#endif
-
-#ifndef MP_ARGCHK
-/*
-  0 = no parameter checks
-  1 = runtime checks, continue execution and return an error to caller
-  2 = assertions; dump core on parameter errors
- */
-#define MP_ARGCHK     2  /* how to check input arguments        */
-#endif
-
-#ifndef MP_DEBUG
-#define MP_DEBUG      0  /* print diagnostic output?            */
-#endif
-
-#ifndef MP_DEFPREC
-#define MP_DEFPREC    16 /* default precision, in digits        */
-#endif
-
-#ifndef MP_MACRO
-#define MP_MACRO      1  /* use macros for frequent calls?      */
-#endif
-
-#ifndef MP_SQUARE
-#define MP_SQUARE     1  /* use separate squaring code?         */
-#endif
-
-#ifndef MP_PTAB_SIZE
-/*
-  When building mpprime.c, we build in a table of small prime
-  values to use for primality testing.  The more you include,
-  the more space they take up.  See primes.c for the possible
-  values (currently 16, 32, 64, 128, 256, and 6542)
- */
-#define MP_PTAB_SIZE  128  /* how many built-in primes?         */
-#endif
-
-#ifndef MP_COMPAT_MACROS
-#define MP_COMPAT_MACROS 0   /* define compatibility macros?    */
-#endif
-
-#endif /* ifndef MPI_CONFIG_H_ */
-
-
--- a/src/protocols/sametime/meanwhile/mpi/mpi-types.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-/* Type definitions generated by 'types.pl' */
-
-typedef char               mp_sign;
-typedef unsigned short     mp_digit;  /* 2 byte type */
-typedef unsigned int       mp_word;   /* 4 byte type */
-typedef unsigned int       mp_size;
-typedef int                mp_err;
-
-#define MP_DIGIT_BIT       (CHAR_BIT*sizeof(mp_digit))
-#define MP_DIGIT_MAX       USHRT_MAX
-#define MP_WORD_BIT        (CHAR_BIT*sizeof(mp_word))
-#define MP_WORD_MAX        UINT_MAX
-
-#define RADIX              (MP_DIGIT_MAX+1)
-
-#define MP_DIGIT_SIZE      2
-#define DIGIT_FMT          "%04X"
--- a/src/protocols/sametime/meanwhile/mpi/mpi.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4001 +0,0 @@
-/*
-    mpi.c
-
-    by Michael J. Fromberger <http://www.dartmouth.edu/~sting/>
-    Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved
-
-    Arbitrary precision integer arithmetic library
-
-    $Id: mpi.c 14563 2005-11-29 23:31:40Z taliesein $
- */
-
-#include "mpi.h"
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#if MP_DEBUG
-#include <stdio.h>
-
-#define DIAG(T,V) {fprintf(stderr,T);mp_print(V,stderr);fputc('\n',stderr);}
-#else
-#define DIAG(T,V)
-#endif
-
-/* 
-   If MP_LOGTAB is not defined, use the math library to compute the
-   logarithms on the fly.  Otherwise, use the static table below.
-   Pick which works best for your system.
- */
-#if MP_LOGTAB
-
-/* {{{ s_logv_2[] - log table for 2 in various bases */
-
-/*
-  A table of the logs of 2 for various bases (the 0 and 1 entries of
-  this table are meaningless and should not be referenced).  
-
-  This table is used to compute output lengths for the mp_toradix()
-  function.  Since a number n in radix r takes up about log_r(n)
-  digits, we estimate the output size by taking the least integer
-  greater than log_r(n), where:
-
-  log_r(n) = log_2(n) * log_r(2)
-
-  This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
-  which are the output bases supported.  
- */
-
-#include "logtab.h"
-
-/* }}} */
-#define LOG_V_2(R)  s_logv_2[(R)]
-
-#else
-
-#include <math.h>
-#define LOG_V_2(R)  (log(2.0)/log(R))
-
-#endif
-
-/* Default precision for newly created mp_int's      */
-static unsigned int s_mp_defprec = MP_DEFPREC;
-
-/* {{{ Digit arithmetic macros */
-
-/*
-  When adding and multiplying digits, the results can be larger than
-  can be contained in an mp_digit.  Thus, an mp_word is used.  These
-  macros mask off the upper and lower digits of the mp_word (the
-  mp_word may be more than 2 mp_digits wide, but we only concern
-  ourselves with the low-order 2 mp_digits)
-
-  If your mp_word DOES have more than 2 mp_digits, you need to
-  uncomment the first line, and comment out the second.
- */
-
-/* #define  CARRYOUT(W)  (((W)>>DIGIT_BIT)&MP_DIGIT_MAX) */
-#define  CARRYOUT(W)  ((W)>>DIGIT_BIT)
-#define  ACCUM(W)     ((W)&MP_DIGIT_MAX)
-
-/* }}} */
-
-/* {{{ Comparison constants */
-
-#define  MP_LT       -1
-#define  MP_EQ        0
-#define  MP_GT        1
-
-/* }}} */
-
-/* {{{ Constant strings */
-
-/* Constant strings returned by mp_strerror() */
-static const char *mp_err_string[] = {
-  "unknown result code",     /* say what?            */
-  "boolean true",            /* MP_OKAY, MP_YES      */
-  "boolean false",           /* MP_NO                */
-  "out of memory",           /* MP_MEM               */
-  "argument out of range",   /* MP_RANGE             */
-  "invalid input parameter", /* MP_BADARG            */
-  "result is undefined"      /* MP_UNDEF             */
-};
-
-/* Value to digit maps for radix conversion   */
-
-/* s_dmap_1 - standard digits and letters */
-static const char *s_dmap_1 = 
-  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
-
-#if 0
-/* s_dmap_2 - base64 ordering for digits  */
-static const char *s_dmap_2 =
-  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-#endif
-
-/* }}} */
-
-/* {{{ Static function declarations */
-
-/* 
-   If MP_MACRO is false, these will be defined as actual functions;
-   otherwise, suitable macro definitions will be used.  This works
-   around the fact that ANSI C89 doesn't support an 'inline' keyword
-   (although I hear C9x will ... about bloody time).  At present, the
-   macro definitions are identical to the function bodies, but they'll
-   expand in place, instead of generating a function call.
-
-   I chose these particular functions to be made into macros because
-   some profiling showed they are called a lot on a typical workload,
-   and yet they are primarily housekeeping.
- */
-#if MP_MACRO == 0
- void     s_mp_setz(mp_digit *dp, mp_size count); /* zero digits           */
- void     s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count); /* copy    */
- void    *s_mp_alloc(size_t nb, size_t ni);       /* general allocator     */
- void     s_mp_free(void *ptr);                   /* general free function */
-#else
-
- /* Even if these are defined as macros, we need to respect the settings
-    of the MP_MEMSET and MP_MEMCPY configuration options...
-  */
- #if MP_MEMSET == 0
-  #define  s_mp_setz(dp, count) \
-       {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=0;}
- #else
-  #define  s_mp_setz(dp, count) memset(dp, 0, (count) * sizeof(mp_digit))
- #endif /* MP_MEMSET */
-
- #if MP_MEMCPY == 0
-  #define  s_mp_copy(sp, dp, count) \
-       {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=(sp)[ix];}
- #else
-  #define  s_mp_copy(sp, dp, count) memcpy(dp, sp, (count) * sizeof(mp_digit))
- #endif /* MP_MEMCPY */
-
- #define  s_mp_alloc(nb, ni)  calloc(nb, ni)
- #define  s_mp_free(ptr) {if(ptr) free(ptr);}
-#endif /* MP_MACRO */
-
-mp_err   s_mp_grow(mp_int *mp, mp_size min);   /* increase allocated size */
-mp_err   s_mp_pad(mp_int *mp, mp_size min);    /* left pad with zeroes    */
-
-void     s_mp_clamp(mp_int *mp);               /* clip leading zeroes     */
-
-void     s_mp_exch(mp_int *a, mp_int *b);      /* swap a and b in place   */
-
-mp_err   s_mp_lshd(mp_int *mp, mp_size p);     /* left-shift by p digits  */
-void     s_mp_rshd(mp_int *mp, mp_size p);     /* right-shift by p digits */
-void     s_mp_div_2d(mp_int *mp, mp_digit d);  /* divide by 2^d in place  */
-void     s_mp_mod_2d(mp_int *mp, mp_digit d);  /* modulo 2^d in place     */
-mp_err   s_mp_mul_2d(mp_int *mp, mp_digit d);  /* multiply by 2^d in place*/
-void     s_mp_div_2(mp_int *mp);               /* divide by 2 in place    */
-mp_err   s_mp_mul_2(mp_int *mp);               /* multiply by 2 in place  */
-mp_digit s_mp_norm(mp_int *a, mp_int *b);      /* normalize for division  */
-mp_err   s_mp_add_d(mp_int *mp, mp_digit d);   /* unsigned digit addition */
-mp_err   s_mp_sub_d(mp_int *mp, mp_digit d);   /* unsigned digit subtract */
-mp_err   s_mp_mul_d(mp_int *mp, mp_digit d);   /* unsigned digit multiply */
-mp_err   s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r);
-		                               /* unsigned digit divide   */
-mp_err   s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu);
-                                               /* Barrett reduction       */
-mp_err   s_mp_add(mp_int *a, mp_int *b);       /* magnitude addition      */
-mp_err   s_mp_sub(mp_int *a, mp_int *b);       /* magnitude subtract      */
-mp_err   s_mp_mul(mp_int *a, mp_int *b);       /* magnitude multiply      */
-#if 0
-void     s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len);
-                                               /* multiply buffers in place */
-#endif
-#if MP_SQUARE
-mp_err   s_mp_sqr(mp_int *a);                  /* magnitude square        */
-#else
-#define  s_mp_sqr(a) s_mp_mul(a, a)
-#endif
-mp_err   s_mp_div(mp_int *a, mp_int *b);       /* magnitude divide        */
-mp_err   s_mp_2expt(mp_int *a, mp_digit k);    /* a = 2^k                 */
-int      s_mp_cmp(mp_int *a, mp_int *b);       /* magnitude comparison    */
-int      s_mp_cmp_d(mp_int *a, mp_digit d);    /* magnitude digit compare */
-int      s_mp_ispow2(mp_int *v);               /* is v a power of 2?      */
-int      s_mp_ispow2d(mp_digit d);             /* is d a power of 2?      */
-
-int      s_mp_tovalue(char ch, int r);          /* convert ch to value    */
-char     s_mp_todigit(int val, int r, int low); /* convert val to digit   */
-int      s_mp_outlen(int bits, int r);          /* output length in bytes */
-
-/* }}} */
-
-/* {{{ Default precision manipulation */
-
-unsigned int mp_get_prec(void)
-{
-  return s_mp_defprec;
-
-} /* end mp_get_prec() */
-
-void         mp_set_prec(unsigned int prec)
-{
-  if(prec == 0)
-    s_mp_defprec = MP_DEFPREC;
-  else
-    s_mp_defprec = prec;
-
-} /* end mp_set_prec() */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ mp_init(mp) */
-
-/*
-  mp_init(mp)
-
-  Initialize a new zero-valued mp_int.  Returns MP_OKAY if successful,
-  MP_MEM if memory could not be allocated for the structure.
- */
-
-mp_err mp_init(mp_int *mp)
-{
-  return mp_init_size(mp, s_mp_defprec);
-
-} /* end mp_init() */
-
-/* }}} */
-
-/* {{{ mp_init_array(mp[], count) */
-
-mp_err mp_init_array(mp_int mp[], int count)
-{
-  mp_err  res;
-  int     pos;
-
-  ARGCHK(mp !=NULL && count > 0, MP_BADARG);
-
-  for(pos = 0; pos < count; ++pos) {
-    if((res = mp_init(&mp[pos])) != MP_OKAY)
-      goto CLEANUP;
-  }
-
-  return MP_OKAY;
-
- CLEANUP:
-  while(--pos >= 0) 
-    mp_clear(&mp[pos]);
-
-  return res;
-
-} /* end mp_init_array() */
-
-/* }}} */
-
-/* {{{ mp_init_size(mp, prec) */
-
-/*
-  mp_init_size(mp, prec)
-
-  Initialize a new zero-valued mp_int with at least the given
-  precision; returns MP_OKAY if successful, or MP_MEM if memory could
-  not be allocated for the structure.
- */
-
-mp_err mp_init_size(mp_int *mp, mp_size prec)
-{
-  ARGCHK(mp != NULL && prec > 0, MP_BADARG);
-
-  if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit))) == NULL)
-    return MP_MEM;
-
-  SIGN(mp) = MP_ZPOS;
-  USED(mp) = 1;
-  ALLOC(mp) = prec;
-
-  return MP_OKAY;
-
-} /* end mp_init_size() */
-
-/* }}} */
-
-/* {{{ mp_init_copy(mp, from) */
-
-/*
-  mp_init_copy(mp, from)
-
-  Initialize mp as an exact copy of from.  Returns MP_OKAY if
-  successful, MP_MEM if memory could not be allocated for the new
-  structure.
- */
-
-mp_err mp_init_copy(mp_int *mp, mp_int *from)
-{
-  ARGCHK(mp != NULL && from != NULL, MP_BADARG);
-
-  if(mp == from)
-    return MP_OKAY;
-
-  if((DIGITS(mp) = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL)
-    return MP_MEM;
-
-  s_mp_copy(DIGITS(from), DIGITS(mp), USED(from));
-  USED(mp) = USED(from);
-  ALLOC(mp) = USED(from);
-  SIGN(mp) = SIGN(from);
-
-  return MP_OKAY;
-
-} /* end mp_init_copy() */
-
-/* }}} */
-
-/* {{{ mp_copy(from, to) */
-
-/*
-  mp_copy(from, to)
-
-  Copies the mp_int 'from' to the mp_int 'to'.  It is presumed that
-  'to' has already been initialized (if not, use mp_init_copy()
-  instead). If 'from' and 'to' are identical, nothing happens.
- */
-
-mp_err mp_copy(mp_int *from, mp_int *to)
-{
-  ARGCHK(from != NULL && to != NULL, MP_BADARG);
-
-  if(from == to)
-    return MP_OKAY;
-
-  { /* copy */
-    mp_digit   *tmp;
-
-    /*
-      If the allocated buffer in 'to' already has enough space to hold
-      all the used digits of 'from', we'll re-use it to avoid hitting
-      the memory allocater more than necessary; otherwise, we'd have
-      to grow anyway, so we just allocate a hunk and make the copy as
-      usual
-     */
-    if(ALLOC(to) >= USED(from)) {
-      s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from));
-      s_mp_copy(DIGITS(from), DIGITS(to), USED(from));
-      
-    } else {
-      if((tmp = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL)
-	return MP_MEM;
-
-      s_mp_copy(DIGITS(from), tmp, USED(from));
-
-      if(DIGITS(to) != NULL) {
-#if MP_CRYPTO
-	s_mp_setz(DIGITS(to), ALLOC(to));
-#endif
-	s_mp_free(DIGITS(to));
-      }
-
-      DIGITS(to) = tmp;
-      ALLOC(to) = USED(from);
-    }
-
-    /* Copy the precision and sign from the original */
-    USED(to) = USED(from);
-    SIGN(to) = SIGN(from);
-  } /* end copy */
-
-  return MP_OKAY;
-
-} /* end mp_copy() */
-
-/* }}} */
-
-/* {{{ mp_exch(mp1, mp2) */
-
-/*
-  mp_exch(mp1, mp2)
-
-  Exchange mp1 and mp2 without allocating any intermediate memory
-  (well, unless you count the stack space needed for this call and the
-  locals it creates...).  This cannot fail.
- */
-
-void mp_exch(mp_int *mp1, mp_int *mp2)
-{
-#if MP_ARGCHK == 2
-  assert(mp1 != NULL && mp2 != NULL);
-#else
-  if(mp1 == NULL || mp2 == NULL)
-    return;
-#endif
-
-  s_mp_exch(mp1, mp2);
-
-} /* end mp_exch() */
-
-/* }}} */
-
-/* {{{ mp_clear(mp) */
-
-/*
-  mp_clear(mp)
-
-  Release the storage used by an mp_int, and void its fields so that
-  if someone calls mp_clear() again for the same int later, we won't
-  get tollchocked.
- */
-
-void   mp_clear(mp_int *mp)
-{
-  if(mp == NULL)
-    return;
-
-  if(DIGITS(mp) != NULL) {
-#if MP_CRYPTO
-    s_mp_setz(DIGITS(mp), ALLOC(mp));
-#endif
-    s_mp_free(DIGITS(mp));
-    DIGITS(mp) = NULL;
-  }
-
-  USED(mp) = 0;
-  ALLOC(mp) = 0;
-
-} /* end mp_clear() */
-
-/* }}} */
-
-/* {{{ mp_clear_array(mp[], count) */
-
-void   mp_clear_array(mp_int mp[], int count)
-{
-  ARGCHK(mp != NULL && count > 0, MP_BADARG);
-
-  while(--count >= 0) 
-    mp_clear(&mp[count]);
-
-} /* end mp_clear_array() */
-
-/* }}} */
-
-/* {{{ mp_zero(mp) */
-
-/*
-  mp_zero(mp) 
-
-  Set mp to zero.  Does not change the allocated size of the structure,
-  and therefore cannot fail (except on a bad argument, which we ignore)
- */
-void   mp_zero(mp_int *mp)
-{
-  if(mp == NULL)
-    return;
-
-  s_mp_setz(DIGITS(mp), ALLOC(mp));
-  USED(mp) = 1;
-  SIGN(mp) = MP_ZPOS;
-
-} /* end mp_zero() */
-
-/* }}} */
-
-/* {{{ mp_set(mp, d) */
-
-void   mp_set(mp_int *mp, mp_digit d)
-{
-  if(mp == NULL)
-    return;
-
-  mp_zero(mp);
-  DIGIT(mp, 0) = d;
-
-} /* end mp_set() */
-
-/* }}} */
-
-/* {{{ mp_set_int(mp, z) */
-
-mp_err mp_set_int(mp_int *mp, long z)
-{
-  int            ix;
-  unsigned long  v = abs(z);
-  mp_err         res;
-
-  ARGCHK(mp != NULL, MP_BADARG);
-
-  mp_zero(mp);
-  if(z == 0)
-    return MP_OKAY;  /* shortcut for zero */
-
-  for(ix = sizeof(long) - 1; ix >= 0; ix--) {
-
-    if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY)
-      return res;
-
-    res = s_mp_add_d(mp, 
-		     (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX));
-    if(res != MP_OKAY)
-      return res;
-
-  }
-
-  if(z < 0)
-    SIGN(mp) = MP_NEG;
-
-  return MP_OKAY;
-
-} /* end mp_set_int() */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ Digit arithmetic */
-
-/* {{{ mp_add_d(a, d, b) */
-
-/*
-  mp_add_d(a, d, b)
-
-  Compute the sum b = a + d, for a single digit d.  Respects the sign of
-  its primary addend (single digits are unsigned anyway).
- */
-
-mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b)
-{
-  mp_err   res = MP_OKAY;
-
-  ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
-  if((res = mp_copy(a, b)) != MP_OKAY)
-    return res;
-
-  if(SIGN(b) == MP_ZPOS) {
-    res = s_mp_add_d(b, d);
-  } else if(s_mp_cmp_d(b, d) >= 0) {
-    res = s_mp_sub_d(b, d);
-  } else {
-    SIGN(b) = MP_ZPOS;
-
-    DIGIT(b, 0) = d - DIGIT(b, 0);
-  }
-
-  return res;
-
-} /* end mp_add_d() */
-
-/* }}} */
-
-/* {{{ mp_sub_d(a, d, b) */
-
-/*
-  mp_sub_d(a, d, b)
-
-  Compute the difference b = a - d, for a single digit d.  Respects the
-  sign of its subtrahend (single digits are unsigned anyway).
- */
-
-mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b)
-{
-  mp_err   res;
-
-  ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
-  if((res = mp_copy(a, b)) != MP_OKAY)
-    return res;
-
-  if(SIGN(b) == MP_NEG) {
-    if((res = s_mp_add_d(b, d)) != MP_OKAY)
-      return res;
-
-  } else if(s_mp_cmp_d(b, d) >= 0) {
-    if((res = s_mp_sub_d(b, d)) != MP_OKAY)
-      return res;
-
-  } else {
-    mp_neg(b, b);
-
-    DIGIT(b, 0) = d - DIGIT(b, 0);
-    SIGN(b) = MP_NEG;
-  }
-
-  if(s_mp_cmp_d(b, 0) == 0)
-    SIGN(b) = MP_ZPOS;
-
-  return MP_OKAY;
-
-} /* end mp_sub_d() */
-
-/* }}} */
-
-/* {{{ mp_mul_d(a, d, b) */
-
-/*
-  mp_mul_d(a, d, b)
-
-  Compute the product b = a * d, for a single digit d.  Respects the sign
-  of its multiplicand (single digits are unsigned anyway)
- */
-
-mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b)
-{
-  mp_err  res;
-
-  ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
-  if(d == 0) {
-    mp_zero(b);
-    return MP_OKAY;
-  }
-
-  if((res = mp_copy(a, b)) != MP_OKAY)
-    return res;
-
-  res = s_mp_mul_d(b, d);
-
-  return res;
-
-} /* end mp_mul_d() */
-
-/* }}} */
-
-/* {{{ mp_mul_2(a, c) */
-
-mp_err mp_mul_2(mp_int *a, mp_int *c)
-{
-  mp_err  res;
-
-  ARGCHK(a != NULL && c != NULL, MP_BADARG);
-
-  if((res = mp_copy(a, c)) != MP_OKAY)
-    return res;
-
-  return s_mp_mul_2(c);
-
-} /* end mp_mul_2() */
-
-/* }}} */
-
-/* {{{ mp_div_d(a, d, q, r) */
-
-/*
-  mp_div_d(a, d, q, r)
-
-  Compute the quotient q = a / d and remainder r = a mod d, for a
-  single digit d.  Respects the sign of its divisor (single digits are
-  unsigned anyway).
- */
-
-mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r)
-{
-  mp_err   res;
-  mp_digit rem;
-  int      pow;
-
-  ARGCHK(a != NULL, MP_BADARG);
-
-  if(d == 0)
-    return MP_RANGE;
-
-  /* Shortcut for powers of two ... */
-  if((pow = s_mp_ispow2d(d)) >= 0) {
-    mp_digit  mask;
-
-    mask = (1 << pow) - 1;
-    rem = DIGIT(a, 0) & mask;
-
-    if(q) {
-      mp_copy(a, q);
-      s_mp_div_2d(q, pow);
-    }
-
-    if(r)
-      *r = rem;
-
-    return MP_OKAY;
-  }
-
-  /*
-    If the quotient is actually going to be returned, we'll try to
-    avoid hitting the memory allocator by copying the dividend into it
-    and doing the division there.  This can't be any _worse_ than
-    always copying, and will sometimes be better (since it won't make
-    another copy)
-
-    If it's not going to be returned, we need to allocate a temporary
-    to hold the quotient, which will just be discarded.
-   */
-  if(q) {
-    if((res = mp_copy(a, q)) != MP_OKAY)
-      return res;
-
-    res = s_mp_div_d(q, d, &rem);
-    if(s_mp_cmp_d(q, 0) == MP_EQ)
-      SIGN(q) = MP_ZPOS;
-
-  } else {
-    mp_int  qp;
-
-    if((res = mp_init_copy(&qp, a)) != MP_OKAY)
-      return res;
-
-    res = s_mp_div_d(&qp, d, &rem);
-    if(s_mp_cmp_d(&qp, 0) == 0)
-      SIGN(&qp) = MP_ZPOS;
-
-    mp_clear(&qp);
-  }
-
-  if(r)
-    *r = rem;
-
-  return res;
-
-} /* end mp_div_d() */
-
-/* }}} */
-
-/* {{{ mp_div_2(a, c) */
-
-/*
-  mp_div_2(a, c)
-
-  Compute c = a / 2, disregarding the remainder.
- */
-
-mp_err mp_div_2(mp_int *a, mp_int *c)
-{
-  mp_err  res;
-
-  ARGCHK(a != NULL && c != NULL, MP_BADARG);
-
-  if((res = mp_copy(a, c)) != MP_OKAY)
-    return res;
-
-  s_mp_div_2(c);
-
-  return MP_OKAY;
-
-} /* end mp_div_2() */
-
-/* }}} */
-
-/* {{{ mp_expt_d(a, d, b) */
-
-mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c)
-{
-  mp_int   s, x;
-  mp_err   res;
-  mp_sign  cs = MP_ZPOS;
-
-  ARGCHK(a != NULL && c != NULL, MP_BADARG);
-
-  if((res = mp_init(&s)) != MP_OKAY)
-    return res;
-  if((res = mp_init_copy(&x, a)) != MP_OKAY)
-    goto X;
-
-  DIGIT(&s, 0) = 1;
-
-  if((d % 2) == 1)
-    cs = SIGN(a);
-
-  while(d != 0) {
-    if(d & 1) {
-      if((res = s_mp_mul(&s, &x)) != MP_OKAY)
-	goto CLEANUP;
-    }
-
-    d >>= 1;
-
-    if((res = s_mp_sqr(&x)) != MP_OKAY)
-      goto CLEANUP;
-  }
-
-  SIGN(&s) = cs;
-
-  s_mp_exch(&s, c);
-
-CLEANUP:
-  mp_clear(&x);
-X:
-  mp_clear(&s);
-
-  return res;
-
-} /* end mp_expt_d() */
-
-/* }}} */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ Full arithmetic */
-
-/* {{{ mp_abs(a, b) */
-
-/*
-  mp_abs(a, b)
-
-  Compute b = |a|.  'a' and 'b' may be identical.
- */
-
-mp_err mp_abs(mp_int *a, mp_int *b)
-{
-  mp_err   res;
-
-  ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
-  if((res = mp_copy(a, b)) != MP_OKAY)
-    return res;
-
-  SIGN(b) = MP_ZPOS;
-
-  return MP_OKAY;
-
-} /* end mp_abs() */
-
-/* }}} */
-
-/* {{{ mp_neg(a, b) */
-
-/*
-  mp_neg(a, b)
-
-  Compute b = -a.  'a' and 'b' may be identical.
- */
-
-mp_err mp_neg(mp_int *a, mp_int *b)
-{
-  mp_err   res;
-
-  ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
-  if((res = mp_copy(a, b)) != MP_OKAY)
-    return res;
-
-  if(s_mp_cmp_d(b, 0) == MP_EQ) 
-    SIGN(b) = MP_ZPOS;
-  else 
-    SIGN(b) = (SIGN(b) == MP_NEG) ? MP_ZPOS : MP_NEG;
-
-  return MP_OKAY;
-
-} /* end mp_neg() */
-
-/* }}} */
-
-/* {{{ mp_add(a, b, c) */
-
-/*
-  mp_add(a, b, c)
-
-  Compute c = a + b.  All parameters may be identical.
- */
-
-mp_err mp_add(mp_int *a, mp_int *b, mp_int *c)
-{
-  mp_err  res;
-  int     cmp;
-
-  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
-  if(SIGN(a) == SIGN(b)) { /* same sign:  add values, keep sign */
-
-    /* Commutativity of addition lets us do this in either order,
-       so we avoid having to use a temporary even if the result 
-       is supposed to replace the output
-     */
-    if(c == b) {
-      if((res = s_mp_add(c, a)) != MP_OKAY)
-	return res;
-    } else {
-      if(c != a && (res = mp_copy(a, c)) != MP_OKAY)
-	return res;
-
-      if((res = s_mp_add(c, b)) != MP_OKAY) 
-	return res;
-    }
-
-  } else if((cmp = s_mp_cmp(a, b)) > 0) {  /* different sign: a > b   */
-
-    /* If the output is going to be clobbered, we will use a temporary
-       variable; otherwise, we'll do it without touching the memory 
-       allocator at all, if possible
-     */
-    if(c == b) {
-      mp_int  tmp;
-
-      if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
-	return res;
-      if((res = s_mp_sub(&tmp, b)) != MP_OKAY) {
-	mp_clear(&tmp);
-	return res;
-      }
-
-      s_mp_exch(&tmp, c);
-      mp_clear(&tmp);
-
-    } else {
-
-      if(c != a && (res = mp_copy(a, c)) != MP_OKAY)
-	return res;
-      if((res = s_mp_sub(c, b)) != MP_OKAY)
-	return res;
-
-    }
-
-  } else if(cmp == 0) {             /* different sign, a == b   */
-
-    mp_zero(c);
-    return MP_OKAY;
-
-  } else {                          /* different sign: a < b    */
-
-    /* See above... */
-    if(c == a) {
-      mp_int  tmp;
-
-      if((res = mp_init_copy(&tmp, b)) != MP_OKAY)
-	return res;
-      if((res = s_mp_sub(&tmp, a)) != MP_OKAY) {
-	mp_clear(&tmp);
-	return res;
-      }
-
-      s_mp_exch(&tmp, c);
-      mp_clear(&tmp);
-
-    } else {
-
-      if(c != b && (res = mp_copy(b, c)) != MP_OKAY)
-	return res;
-      if((res = s_mp_sub(c, a)) != MP_OKAY)
-	return res;
-
-    }
-  }
-
-  if(USED(c) == 1 && DIGIT(c, 0) == 0)
-    SIGN(c) = MP_ZPOS;
-
-  return MP_OKAY;
-
-} /* end mp_add() */
-
-/* }}} */
-
-/* {{{ mp_sub(a, b, c) */
-
-/*
-  mp_sub(a, b, c)
-
-  Compute c = a - b.  All parameters may be identical.
- */
-
-mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c)
-{
-  mp_err  res;
-  int     cmp;
-
-  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
-  if(SIGN(a) != SIGN(b)) {
-    if(c == a) {
-      if((res = s_mp_add(c, b)) != MP_OKAY)
-	return res;
-    } else {
-      if(c != b && ((res = mp_copy(b, c)) != MP_OKAY))
-	return res;
-      if((res = s_mp_add(c, a)) != MP_OKAY)
-	return res;
-      SIGN(c) = SIGN(a);
-    }
-
-  } else if((cmp = s_mp_cmp(a, b)) > 0) { /* Same sign, a > b */
-    if(c == b) {
-      mp_int  tmp;
-
-      if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
-	return res;
-      if((res = s_mp_sub(&tmp, b)) != MP_OKAY) {
-	mp_clear(&tmp);
-	return res;
-      }
-      s_mp_exch(&tmp, c);
-      mp_clear(&tmp);
-
-    } else {
-      if(c != a && ((res = mp_copy(a, c)) != MP_OKAY))
-	return res;
-
-      if((res = s_mp_sub(c, b)) != MP_OKAY)
-	return res;
-    }
-
-  } else if(cmp == 0) {  /* Same sign, equal magnitude */
-    mp_zero(c);
-    return MP_OKAY;
-
-  } else {               /* Same sign, b > a */
-    if(c == a) {
-      mp_int  tmp;
-
-      if((res = mp_init_copy(&tmp, b)) != MP_OKAY)
-	return res;
-
-      if((res = s_mp_sub(&tmp, a)) != MP_OKAY) {
-	mp_clear(&tmp);
-	return res;
-      }
-      s_mp_exch(&tmp, c);
-      mp_clear(&tmp);
-
-    } else {
-      if(c != b && ((res = mp_copy(b, c)) != MP_OKAY)) 
-	return res;
-
-      if((res = s_mp_sub(c, a)) != MP_OKAY)
-	return res;
-    }
-
-    SIGN(c) = !SIGN(b);
-  }
-
-  if(USED(c) == 1 && DIGIT(c, 0) == 0)
-    SIGN(c) = MP_ZPOS;
-
-  return MP_OKAY;
-
-} /* end mp_sub() */
-
-/* }}} */
-
-/* {{{ mp_mul(a, b, c) */
-
-/*
-  mp_mul(a, b, c)
-
-  Compute c = a * b.  All parameters may be identical.
- */
-
-mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c)
-{
-  mp_err   res;
-  mp_sign  sgn;
-
-  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
-  sgn = (SIGN(a) == SIGN(b)) ? MP_ZPOS : MP_NEG;
-
-  if(c == b) {
-    if((res = s_mp_mul(c, a)) != MP_OKAY)
-      return res;
-
-  } else {
-    if((res = mp_copy(a, c)) != MP_OKAY)
-      return res;
-
-    if((res = s_mp_mul(c, b)) != MP_OKAY)
-      return res;
-  }
-  
-  if(sgn == MP_ZPOS || s_mp_cmp_d(c, 0) == MP_EQ)
-    SIGN(c) = MP_ZPOS;
-  else
-    SIGN(c) = sgn;
-  
-  return MP_OKAY;
-
-} /* end mp_mul() */
-
-/* }}} */
-
-/* {{{ mp_mul_2d(a, d, c) */
-
-/*
-  mp_mul_2d(a, d, c)
-
-  Compute c = a * 2^d.  a may be the same as c.
- */
-
-mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c)
-{
-  mp_err   res;
-
-  ARGCHK(a != NULL && c != NULL, MP_BADARG);
-
-  if((res = mp_copy(a, c)) != MP_OKAY)
-    return res;
-
-  if(d == 0)
-    return MP_OKAY;
-
-  return s_mp_mul_2d(c, d);
-
-} /* end mp_mul() */
-
-/* }}} */
-
-/* {{{ mp_sqr(a, b) */
-
-#if MP_SQUARE
-mp_err mp_sqr(mp_int *a, mp_int *b)
-{
-  mp_err   res;
-
-  ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
-  if((res = mp_copy(a, b)) != MP_OKAY)
-    return res;
-
-  if((res = s_mp_sqr(b)) != MP_OKAY)
-    return res;
-
-  SIGN(b) = MP_ZPOS;
-
-  return MP_OKAY;
-
-} /* end mp_sqr() */
-#endif
-
-/* }}} */
-
-/* {{{ mp_div(a, b, q, r) */
-
-/*
-  mp_div(a, b, q, r)
-
-  Compute q = a / b and r = a mod b.  Input parameters may be re-used
-  as output parameters.  If q or r is NULL, that portion of the
-  computation will be discarded (although it will still be computed)
-
-  Pay no attention to the hacker behind the curtain.
- */
-
-mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r)
-{
-  mp_err   res;
-  mp_int   qtmp, rtmp;
-  int      cmp;
-
-  ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
-  if(mp_cmp_z(b) == MP_EQ)
-    return MP_RANGE;
-
-  /* If a <= b, we can compute the solution without division, and
-     avoid any memory allocation
-   */
-  if((cmp = s_mp_cmp(a, b)) < 0) {
-    if(r) {
-      if((res = mp_copy(a, r)) != MP_OKAY)
-	return res;
-    }
-
-    if(q) 
-      mp_zero(q);
-
-    return MP_OKAY;
-
-  } else if(cmp == 0) {
-
-    /* Set quotient to 1, with appropriate sign */
-    if(q) {
-      int qneg = (SIGN(a) != SIGN(b));
-
-      mp_set(q, 1);
-      if(qneg)
-	SIGN(q) = MP_NEG;
-    }
-
-    if(r)
-      mp_zero(r);
-
-    return MP_OKAY;
-  }
-
-  /* If we get here, it means we actually have to do some division */
-
-  /* Set up some temporaries... */
-  if((res = mp_init_copy(&qtmp, a)) != MP_OKAY)
-    return res;
-  if((res = mp_init_copy(&rtmp, b)) != MP_OKAY)
-    goto CLEANUP;
-
-  if((res = s_mp_div(&qtmp, &rtmp)) != MP_OKAY)
-    goto CLEANUP;
-
-  /* Compute the signs for the output  */
-  SIGN(&rtmp) = SIGN(a); /* Sr = Sa              */
-  if(SIGN(a) == SIGN(b))
-    SIGN(&qtmp) = MP_ZPOS;  /* Sq = MP_ZPOS if Sa = Sb */
-  else
-    SIGN(&qtmp) = MP_NEG;   /* Sq = MP_NEG if Sa != Sb */
-
-  if(s_mp_cmp_d(&qtmp, 0) == MP_EQ)
-    SIGN(&qtmp) = MP_ZPOS;
-  if(s_mp_cmp_d(&rtmp, 0) == MP_EQ)
-    SIGN(&rtmp) = MP_ZPOS;
-
-  /* Copy output, if it is needed      */
-  if(q) 
-    s_mp_exch(&qtmp, q);
-
-  if(r) 
-    s_mp_exch(&rtmp, r);
-
-CLEANUP:
-  mp_clear(&rtmp);
-  mp_clear(&qtmp);
-
-  return res;
-
-} /* end mp_div() */
-
-/* }}} */
-
-/* {{{ mp_div_2d(a, d, q, r) */
-
-mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r)
-{
-  mp_err  res;
-
-  ARGCHK(a != NULL, MP_BADARG);
-
-  if(q) {
-    if((res = mp_copy(a, q)) != MP_OKAY)
-      return res;
-
-    s_mp_div_2d(q, d);
-  }
-
-  if(r) {
-    if((res = mp_copy(a, r)) != MP_OKAY)
-      return res;
-
-    s_mp_mod_2d(r, d);
-  }
-
-  return MP_OKAY;
-
-} /* end mp_div_2d() */
-
-/* }}} */
-
-/* {{{ mp_expt(a, b, c) */
-
-/*
-  mp_expt(a, b, c)
-
-  Compute c = a ** b, that is, raise a to the b power.  Uses a
-  standard iterative square-and-multiply technique.
- */
-
-mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c)
-{
-  mp_int   s, x;
-  mp_err   res;
-  mp_digit d;
-  int      dig, bit;
-
-  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
-  if(mp_cmp_z(b) < 0)
-    return MP_RANGE;
-
-  if((res = mp_init(&s)) != MP_OKAY)
-    return res;
-
-  mp_set(&s, 1);
-
-  if((res = mp_init_copy(&x, a)) != MP_OKAY)
-    goto X;
-
-  /* Loop over low-order digits in ascending order */
-  for(dig = 0; dig < (USED(b) - 1); dig++) {
-    d = DIGIT(b, dig);
-
-    /* Loop over bits of each non-maximal digit */
-    for(bit = 0; bit < DIGIT_BIT; bit++) {
-      if(d & 1) {
-	if((res = s_mp_mul(&s, &x)) != MP_OKAY) 
-	  goto CLEANUP;
-      }
-
-      d >>= 1;
-      
-      if((res = s_mp_sqr(&x)) != MP_OKAY)
-	goto CLEANUP;
-    }
-  }
-
-  /* Consider now the last digit... */
-  d = DIGIT(b, dig);
-
-  while(d) {
-    if(d & 1) {
-      if((res = s_mp_mul(&s, &x)) != MP_OKAY)
-	goto CLEANUP;
-    }
-
-    d >>= 1;
-
-    if((res = s_mp_sqr(&x)) != MP_OKAY)
-      goto CLEANUP;
-  }
-  
-  if(mp_iseven(b))
-    SIGN(&s) = SIGN(a);
-
-  res = mp_copy(&s, c);
-
-CLEANUP:
-  mp_clear(&x);
-X:
-  mp_clear(&s);
-
-  return res;
-
-} /* end mp_expt() */
-
-/* }}} */
-
-/* {{{ mp_2expt(a, k) */
-
-/* Compute a = 2^k */
-
-mp_err mp_2expt(mp_int *a, mp_digit k)
-{
-  ARGCHK(a != NULL, MP_BADARG);
-
-  return s_mp_2expt(a, k);
-
-} /* end mp_2expt() */
-
-/* }}} */
-
-/* {{{ mp_mod(a, m, c) */
-
-/*
-  mp_mod(a, m, c)
-
-  Compute c = a (mod m).  Result will always be 0 <= c < m.
- */
-
-mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c)
-{
-  mp_err  res;
-  int     mag;
-
-  ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
-
-  if(SIGN(m) == MP_NEG)
-    return MP_RANGE;
-
-  /*
-     If |a| > m, we need to divide to get the remainder and take the
-     absolute value.  
-
-     If |a| < m, we don't need to do any division, just copy and adjust
-     the sign (if a is negative).
-
-     If |a| == m, we can simply set the result to zero.
-
-     This order is intended to minimize the average path length of the
-     comparison chain on common workloads -- the most frequent cases are
-     that |a| != m, so we do those first.
-   */
-  if((mag = s_mp_cmp(a, m)) > 0) {
-    if((res = mp_div(a, m, NULL, c)) != MP_OKAY)
-      return res;
-    
-    if(SIGN(c) == MP_NEG) {
-      if((res = mp_add(c, m, c)) != MP_OKAY)
-	return res;
-    }
-
-  } else if(mag < 0) {
-    if((res = mp_copy(a, c)) != MP_OKAY)
-      return res;
-
-    if(mp_cmp_z(a) < 0) {
-      if((res = mp_add(c, m, c)) != MP_OKAY)
-	return res;
-
-    }
-    
-  } else {
-    mp_zero(c);
-
-  }
-
-  return MP_OKAY;
-
-} /* end mp_mod() */
-
-/* }}} */
-
-/* {{{ mp_mod_d(a, d, c) */
-
-/*
-  mp_mod_d(a, d, c)
-
-  Compute c = a (mod d).  Result will always be 0 <= c < d
- */
-mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c)
-{
-  mp_err   res;
-  mp_digit rem;
-
-  ARGCHK(a != NULL && c != NULL, MP_BADARG);
-
-  if(s_mp_cmp_d(a, d) > 0) {
-    if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY)
-      return res;
-
-  } else {
-    if(SIGN(a) == MP_NEG)
-      rem = d - DIGIT(a, 0);
-    else
-      rem = DIGIT(a, 0);
-  }
-
-  if(c)
-    *c = rem;
-
-  return MP_OKAY;
-
-} /* end mp_mod_d() */
-
-/* }}} */
-
-/* {{{ mp_sqrt(a, b) */
-
-/*
-  mp_sqrt(a, b)
-
-  Compute the integer square root of a, and store the result in b.
-  Uses an integer-arithmetic version of Newton's iterative linear
-  approximation technique to determine this value; the result has the
-  following two properties:
-
-     b^2 <= a
-     (b+1)^2 >= a
-
-  It is a range error to pass a negative value.
- */
-mp_err mp_sqrt(mp_int *a, mp_int *b)
-{
-  mp_int   x, t;
-  mp_err   res;
-
-  ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
-  /* Cannot take square root of a negative value */
-  if(SIGN(a) == MP_NEG)
-    return MP_RANGE;
-
-  /* Special cases for zero and one, trivial     */
-  if(mp_cmp_d(a, 0) == MP_EQ || mp_cmp_d(a, 1) == MP_EQ) 
-    return mp_copy(a, b);
-    
-  /* Initialize the temporaries we'll use below  */
-  if((res = mp_init_size(&t, USED(a))) != MP_OKAY)
-    return res;
-
-  /* Compute an initial guess for the iteration as a itself */
-  if((res = mp_init_copy(&x, a)) != MP_OKAY)
-    goto X;
-
-  for(;;) {
-    /* t = (x * x) - a */
-    mp_copy(&x, &t);      /* can't fail, t is big enough for original x */
-    if((res = mp_sqr(&t, &t)) != MP_OKAY ||
-       (res = mp_sub(&t, a, &t)) != MP_OKAY)
-      goto CLEANUP;
-
-    /* t = t / 2x       */
-    s_mp_mul_2(&x);
-    if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY)
-      goto CLEANUP;
-    s_mp_div_2(&x);
-
-    /* Terminate the loop, if the quotient is zero */
-    if(mp_cmp_z(&t) == MP_EQ)
-      break;
-
-    /* x = x - t       */
-    if((res = mp_sub(&x, &t, &x)) != MP_OKAY)
-      goto CLEANUP;
-
-  }
-
-  /* Copy result to output parameter */
-  mp_sub_d(&x, 1, &x);
-  s_mp_exch(&x, b);
-
- CLEANUP:
-  mp_clear(&x);
- X:
-  mp_clear(&t); 
-
-  return res;
-
-} /* end mp_sqrt() */
-
-/* }}} */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ Modular arithmetic */
-
-#if MP_MODARITH
-/* {{{ mp_addmod(a, b, m, c) */
-
-/*
-  mp_addmod(a, b, m, c)
-
-  Compute c = (a + b) mod m
- */
-
-mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
-{
-  mp_err  res;
-
-  ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
-
-  if((res = mp_add(a, b, c)) != MP_OKAY)
-    return res;
-  if((res = mp_mod(c, m, c)) != MP_OKAY)
-    return res;
-
-  return MP_OKAY;
-
-}
-
-/* }}} */
-
-/* {{{ mp_submod(a, b, m, c) */
-
-/*
-  mp_submod(a, b, m, c)
-
-  Compute c = (a - b) mod m
- */
-
-mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
-{
-  mp_err  res;
-
-  ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
-
-  if((res = mp_sub(a, b, c)) != MP_OKAY)
-    return res;
-  if((res = mp_mod(c, m, c)) != MP_OKAY)
-    return res;
-
-  return MP_OKAY;
-
-}
-
-/* }}} */
-
-/* {{{ mp_mulmod(a, b, m, c) */
-
-/*
-  mp_mulmod(a, b, m, c)
-
-  Compute c = (a * b) mod m
- */
-
-mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
-{
-  mp_err  res;
-
-  ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
-
-  if((res = mp_mul(a, b, c)) != MP_OKAY)
-    return res;
-  if((res = mp_mod(c, m, c)) != MP_OKAY)
-    return res;
-
-  return MP_OKAY;
-
-}
-
-/* }}} */
-
-/* {{{ mp_sqrmod(a, m, c) */
-
-#if MP_SQUARE
-mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c)
-{
-  mp_err  res;
-
-  ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
-
-  if((res = mp_sqr(a, c)) != MP_OKAY)
-    return res;
-  if((res = mp_mod(c, m, c)) != MP_OKAY)
-    return res;
-
-  return MP_OKAY;
-
-} /* end mp_sqrmod() */
-#endif
-
-/* }}} */
-
-/* {{{ mp_exptmod(a, b, m, c) */
-
-/*
-  mp_exptmod(a, b, m, c)
-
-  Compute c = (a ** b) mod m.  Uses a standard square-and-multiply
-  method with modular reductions at each step. (This is basically the
-  same code as mp_expt(), except for the addition of the reductions)
-  
-  The modular reductions are done using Barrett's algorithm (see
-  s_mp_reduce() below for details)
- */
-
-mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
-{
-  mp_int   s, x, mu;
-  mp_err   res;
-  mp_digit d, *db = DIGITS(b);
-  mp_size  ub = USED(b);
-  int      dig, bit;
-
-  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
-  if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0)
-    return MP_RANGE;
-
-  if((res = mp_init(&s)) != MP_OKAY)
-    return res;
-  if((res = mp_init_copy(&x, a)) != MP_OKAY)
-    goto X;
-  if((res = mp_mod(&x, m, &x)) != MP_OKAY ||
-     (res = mp_init(&mu)) != MP_OKAY)
-    goto MU;
-
-  mp_set(&s, 1);
-
-  /* mu = b^2k / m */
-  s_mp_add_d(&mu, 1); 
-  s_mp_lshd(&mu, 2 * USED(m));
-  if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY)
-    goto CLEANUP;
-
-  /* Loop over digits of b in ascending order, except highest order */
-  for(dig = 0; dig < (ub - 1); dig++) {
-    d = *db++;
-
-    /* Loop over the bits of the lower-order digits */
-    for(bit = 0; bit < DIGIT_BIT; bit++) {
-      if(d & 1) {
-	if((res = s_mp_mul(&s, &x)) != MP_OKAY)
-	  goto CLEANUP;
-	if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
-	  goto CLEANUP;
-      }
-
-      d >>= 1;
-
-      if((res = s_mp_sqr(&x)) != MP_OKAY)
-	goto CLEANUP;
-      if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
-	goto CLEANUP;
-    }
-  }
-
-  /* Now do the last digit... */
-  d = *db;
-
-  while(d) {
-    if(d & 1) {
-      if((res = s_mp_mul(&s, &x)) != MP_OKAY)
-	goto CLEANUP;
-      if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
-	goto CLEANUP;
-    }
-
-    d >>= 1;
-
-    if((res = s_mp_sqr(&x)) != MP_OKAY)
-      goto CLEANUP;
-    if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
-      goto CLEANUP;
-  }
-
-  s_mp_exch(&s, c);
-
- CLEANUP:
-  mp_clear(&mu);
- MU:
-  mp_clear(&x);
- X:
-  mp_clear(&s);
-
-  return res;
-
-} /* end mp_exptmod() */
-
-/* }}} */
-
-/* {{{ mp_exptmod_d(a, d, m, c) */
-
-mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c)
-{
-  mp_int   s, x;
-  mp_err   res;
-
-  ARGCHK(a != NULL && c != NULL, MP_BADARG);
-
-  if((res = mp_init(&s)) != MP_OKAY)
-    return res;
-  if((res = mp_init_copy(&x, a)) != MP_OKAY)
-    goto X;
-
-  mp_set(&s, 1);
-
-  while(d != 0) {
-    if(d & 1) {
-      if((res = s_mp_mul(&s, &x)) != MP_OKAY ||
-	 (res = mp_mod(&s, m, &s)) != MP_OKAY)
-	goto CLEANUP;
-    }
-
-    d /= 2;
-
-    if((res = s_mp_sqr(&x)) != MP_OKAY ||
-       (res = mp_mod(&x, m, &x)) != MP_OKAY)
-      goto CLEANUP;
-  }
-
-  s_mp_exch(&s, c);
-
-CLEANUP:
-  mp_clear(&x);
-X:
-  mp_clear(&s);
-
-  return res;
-
-} /* end mp_exptmod_d() */
-
-/* }}} */
-#endif /* if MP_MODARITH */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ Comparison functions */
-
-/* {{{ mp_cmp_z(a) */
-
-/*
-  mp_cmp_z(a)
-
-  Compare a <=> 0.  Returns <0 if a<0, 0 if a=0, >0 if a>0.
- */
-
-int    mp_cmp_z(mp_int *a)
-{
-  if(SIGN(a) == MP_NEG)
-    return MP_LT;
-  else if(USED(a) == 1 && DIGIT(a, 0) == 0)
-    return MP_EQ;
-  else
-    return MP_GT;
-
-} /* end mp_cmp_z() */
-
-/* }}} */
-
-/* {{{ mp_cmp_d(a, d) */
-
-/*
-  mp_cmp_d(a, d)
-
-  Compare a <=> d.  Returns <0 if a<d, 0 if a=d, >0 if a>d
- */
-
-int    mp_cmp_d(mp_int *a, mp_digit d)
-{
-  ARGCHK(a != NULL, MP_EQ);
-
-  if(SIGN(a) == MP_NEG)
-    return MP_LT;
-
-  return s_mp_cmp_d(a, d);
-
-} /* end mp_cmp_d() */
-
-/* }}} */
-
-/* {{{ mp_cmp(a, b) */
-
-int    mp_cmp(mp_int *a, mp_int *b)
-{
-  ARGCHK(a != NULL && b != NULL, MP_EQ);
-
-  if(SIGN(a) == SIGN(b)) {
-    int  mag;
-
-    if((mag = s_mp_cmp(a, b)) == MP_EQ)
-      return MP_EQ;
-
-    if(SIGN(a) == MP_ZPOS)
-      return mag;
-    else
-      return -mag;
-
-  } else if(SIGN(a) == MP_ZPOS) {
-    return MP_GT;
-  } else {
-    return MP_LT;
-  }
-
-} /* end mp_cmp() */
-
-/* }}} */
-
-/* {{{ mp_cmp_mag(a, b) */
-
-/*
-  mp_cmp_mag(a, b)
-
-  Compares |a| <=> |b|, and returns an appropriate comparison result
- */
-
-int    mp_cmp_mag(mp_int *a, mp_int *b)
-{
-  ARGCHK(a != NULL && b != NULL, MP_EQ);
-
-  return s_mp_cmp(a, b);
-
-} /* end mp_cmp_mag() */
-
-/* }}} */
-
-/* {{{ mp_cmp_int(a, z) */
-
-/*
-  This just converts z to an mp_int, and uses the existing comparison
-  routines.  This is sort of inefficient, but it's not clear to me how
-  frequently this wil get used anyway.  For small positive constants,
-  you can always use mp_cmp_d(), and for zero, there is mp_cmp_z().
- */
-int    mp_cmp_int(mp_int *a, long z)
-{
-  mp_int  tmp;
-  int     out;
-
-  ARGCHK(a != NULL, MP_EQ);
-  
-  mp_init(&tmp); mp_set_int(&tmp, z);
-  out = mp_cmp(a, &tmp);
-  mp_clear(&tmp);
-
-  return out;
-
-} /* end mp_cmp_int() */
-
-/* }}} */
-
-/* {{{ mp_isodd(a) */
-
-/*
-  mp_isodd(a)
-
-  Returns a true (non-zero) value if a is odd, false (zero) otherwise.
- */
-int    mp_isodd(mp_int *a)
-{
-  ARGCHK(a != NULL, 0);
-
-  return (DIGIT(a, 0) & 1);
-
-} /* end mp_isodd() */
-
-/* }}} */
-
-/* {{{ mp_iseven(a) */
-
-int    mp_iseven(mp_int *a)
-{
-  return !mp_isodd(a);
-
-} /* end mp_iseven() */
-
-/* }}} */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ Number theoretic functions */
-
-#if MP_NUMTH
-/* {{{ mp_gcd(a, b, c) */
-
-/*
-  Like the old mp_gcd() function, except computes the GCD using the
-  binary algorithm due to Josef Stein in 1961 (via Knuth).
- */
-mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c)
-{
-  mp_err   res;
-  mp_int   u, v, t;
-  mp_size  k = 0;
-
-  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
-  if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ)
-      return MP_RANGE;
-  if(mp_cmp_z(a) == MP_EQ) {
-    if((res = mp_copy(b, c)) != MP_OKAY)
-      return res;
-    SIGN(c) = MP_ZPOS; return MP_OKAY;
-  } else if(mp_cmp_z(b) == MP_EQ) {
-    if((res = mp_copy(a, c)) != MP_OKAY)
-      return res;
-    SIGN(c) = MP_ZPOS; return MP_OKAY;
-  }
-
-  if((res = mp_init(&t)) != MP_OKAY)
-    return res;
-  if((res = mp_init_copy(&u, a)) != MP_OKAY)
-    goto U;
-  if((res = mp_init_copy(&v, b)) != MP_OKAY)
-    goto V;
-
-  SIGN(&u) = MP_ZPOS;
-  SIGN(&v) = MP_ZPOS;
-
-  /* Divide out common factors of 2 until at least 1 of a, b is even */
-  while(mp_iseven(&u) && mp_iseven(&v)) {
-    s_mp_div_2(&u);
-    s_mp_div_2(&v);
-    ++k;
-  }
-
-  /* Initialize t */
-  if(mp_isodd(&u)) {
-    if((res = mp_copy(&v, &t)) != MP_OKAY)
-      goto CLEANUP;
-    
-    /* t = -v */
-    if(SIGN(&v) == MP_ZPOS)
-      SIGN(&t) = MP_NEG;
-    else
-      SIGN(&t) = MP_ZPOS;
-    
-  } else {
-    if((res = mp_copy(&u, &t)) != MP_OKAY)
-      goto CLEANUP;
-
-  }
-
-  for(;;) {
-    while(mp_iseven(&t)) {
-      s_mp_div_2(&t);
-    }
-
-    if(mp_cmp_z(&t) == MP_GT) {
-      if((res = mp_copy(&t, &u)) != MP_OKAY)
-	goto CLEANUP;
-
-    } else {
-      if((res = mp_copy(&t, &v)) != MP_OKAY)
-	goto CLEANUP;
-
-      /* v = -t */
-      if(SIGN(&t) == MP_ZPOS)
-	SIGN(&v) = MP_NEG;
-      else
-	SIGN(&v) = MP_ZPOS;
-    }
-
-    if((res = mp_sub(&u, &v, &t)) != MP_OKAY)
-      goto CLEANUP;
-
-    if(s_mp_cmp_d(&t, 0) == MP_EQ)
-      break;
-  }
-
-  s_mp_2expt(&v, k);       /* v = 2^k   */
-  res = mp_mul(&u, &v, c); /* c = u * v */
-
- CLEANUP:
-  mp_clear(&v);
- V:
-  mp_clear(&u);
- U:
-  mp_clear(&t);
-
-  return res;
-
-} /* end mp_bgcd() */
-
-/* }}} */
-
-/* {{{ mp_lcm(a, b, c) */
-
-/* We compute the least common multiple using the rule:
-
-   ab = [a, b](a, b)
-
-   ... by computing the product, and dividing out the gcd.
- */
-
-mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c)
-{
-  mp_int  gcd, prod;
-  mp_err  res;
-
-  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
-  /* Set up temporaries */
-  if((res = mp_init(&gcd)) != MP_OKAY)
-    return res;
-  if((res = mp_init(&prod)) != MP_OKAY)
-    goto GCD;
-
-  if((res = mp_mul(a, b, &prod)) != MP_OKAY)
-    goto CLEANUP;
-  if((res = mp_gcd(a, b, &gcd)) != MP_OKAY)
-    goto CLEANUP;
-
-  res = mp_div(&prod, &gcd, c, NULL);
-
- CLEANUP:
-  mp_clear(&prod);
- GCD:
-  mp_clear(&gcd);
-
-  return res;
-
-} /* end mp_lcm() */
-
-/* }}} */
-
-/* {{{ mp_xgcd(a, b, g, x, y) */
-
-/*
-  mp_xgcd(a, b, g, x, y)
-
-  Compute g = (a, b) and values x and y satisfying Bezout's identity
-  (that is, ax + by = g).  This uses the extended binary GCD algorithm
-  based on the Stein algorithm used for mp_gcd()
- */
-
-mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y)
-{
-  mp_int   gx, xc, yc, u, v, A, B, C, D;
-  mp_int  *clean[9];
-  mp_err   res;
-  int      last = -1;
-
-  if(mp_cmp_z(b) == 0)
-    return MP_RANGE;
-
-  /* Initialize all these variables we need */
-  if((res = mp_init(&u)) != MP_OKAY) goto CLEANUP;
-  clean[++last] = &u;
-  if((res = mp_init(&v)) != MP_OKAY) goto CLEANUP;
-  clean[++last] = &v;
-  if((res = mp_init(&gx)) != MP_OKAY) goto CLEANUP;
-  clean[++last] = &gx;
-  if((res = mp_init(&A)) != MP_OKAY) goto CLEANUP;
-  clean[++last] = &A;
-  if((res = mp_init(&B)) != MP_OKAY) goto CLEANUP;
-  clean[++last] = &B;
-  if((res = mp_init(&C)) != MP_OKAY) goto CLEANUP;
-  clean[++last] = &C;
-  if((res = mp_init(&D)) != MP_OKAY) goto CLEANUP;
-  clean[++last] = &D;
-  if((res = mp_init_copy(&xc, a)) != MP_OKAY) goto CLEANUP;
-  clean[++last] = &xc;
-  mp_abs(&xc, &xc);
-  if((res = mp_init_copy(&yc, b)) != MP_OKAY) goto CLEANUP;
-  clean[++last] = &yc;
-  mp_abs(&yc, &yc);
-
-  mp_set(&gx, 1);
-
-  /* Divide by two until at least one of them is even */
-  while(mp_iseven(&xc) && mp_iseven(&yc)) {
-    s_mp_div_2(&xc);
-    s_mp_div_2(&yc);
-    if((res = s_mp_mul_2(&gx)) != MP_OKAY)
-      goto CLEANUP;
-  }
-
-  mp_copy(&xc, &u);
-  mp_copy(&yc, &v);
-  mp_set(&A, 1); mp_set(&D, 1);
-
-  /* Loop through binary GCD algorithm */
-  for(;;) {
-    while(mp_iseven(&u)) {
-      s_mp_div_2(&u);
-
-      if(mp_iseven(&A) && mp_iseven(&B)) {
-	s_mp_div_2(&A); s_mp_div_2(&B);
-      } else {
-	if((res = mp_add(&A, &yc, &A)) != MP_OKAY) goto CLEANUP;
-	s_mp_div_2(&A);
-	if((res = mp_sub(&B, &xc, &B)) != MP_OKAY) goto CLEANUP;
-	s_mp_div_2(&B);
-      }
-    }
-
-    while(mp_iseven(&v)) {
-      s_mp_div_2(&v);
-
-      if(mp_iseven(&C) && mp_iseven(&D)) {
-	s_mp_div_2(&C); s_mp_div_2(&D);
-      } else {
-	if((res = mp_add(&C, &yc, &C)) != MP_OKAY) goto CLEANUP;
-	s_mp_div_2(&C);
-	if((res = mp_sub(&D, &xc, &D)) != MP_OKAY) goto CLEANUP;
-	s_mp_div_2(&D);
-      }
-    }
-
-    if(mp_cmp(&u, &v) >= 0) {
-      if((res = mp_sub(&u, &v, &u)) != MP_OKAY) goto CLEANUP;
-      if((res = mp_sub(&A, &C, &A)) != MP_OKAY) goto CLEANUP;
-      if((res = mp_sub(&B, &D, &B)) != MP_OKAY) goto CLEANUP;
-
-    } else {
-      if((res = mp_sub(&v, &u, &v)) != MP_OKAY) goto CLEANUP;
-      if((res = mp_sub(&C, &A, &C)) != MP_OKAY) goto CLEANUP;
-      if((res = mp_sub(&D, &B, &D)) != MP_OKAY) goto CLEANUP;
-
-    }
-
-    /* If we're done, copy results to output */
-    if(mp_cmp_z(&u) == 0) {
-      if(x)
-	if((res = mp_copy(&C, x)) != MP_OKAY) goto CLEANUP;
-
-      if(y)
-	if((res = mp_copy(&D, y)) != MP_OKAY) goto CLEANUP;
-      
-      if(g)
-	if((res = mp_mul(&gx, &v, g)) != MP_OKAY) goto CLEANUP;
-
-      break;
-    }
-  }
-
- CLEANUP:
-  while(last >= 0)
-    mp_clear(clean[last--]);
-
-  return res;
-
-} /* end mp_xgcd() */
-
-/* }}} */
-
-/* {{{ mp_invmod(a, m, c) */
-
-/*
-  mp_invmod(a, m, c)
-
-  Compute c = a^-1 (mod m), if there is an inverse for a (mod m).
-  This is equivalent to the question of whether (a, m) = 1.  If not,
-  MP_UNDEF is returned, and there is no inverse.
- */
-
-mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c)
-{
-  mp_int  g, x;
-  mp_sign sa;
-  mp_err  res;
-
-  ARGCHK(a && m && c, MP_BADARG);
-
-  if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
-    return MP_RANGE;
-
-  sa = SIGN(a);
-
-  if((res = mp_init(&g)) != MP_OKAY)
-    return res;
-  if((res = mp_init(&x)) != MP_OKAY)
-    goto X;
-
-  if((res = mp_xgcd(a, m, &g, &x, NULL)) != MP_OKAY)
-    goto CLEANUP;
-
-  if(mp_cmp_d(&g, 1) != MP_EQ) {
-    res = MP_UNDEF;
-    goto CLEANUP;
-  }
-
-  res = mp_mod(&x, m, c);
-  SIGN(c) = sa;
-
-CLEANUP:
-  mp_clear(&x);
-X:
-  mp_clear(&g);
-
-  return res;
-
-} /* end mp_invmod() */
-
-/* }}} */
-#endif /* if MP_NUMTH */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ mp_print(mp, ofp) */
-
-#if MP_IOFUNC
-/*
-  mp_print(mp, ofp)
-
-  Print a textual representation of the given mp_int on the output
-  stream 'ofp'.  Output is generated using the internal radix.
- */
-
-void   mp_print(mp_int *mp, FILE *ofp)
-{
-  int   ix;
-
-  if(mp == NULL || ofp == NULL)
-    return;
-
-  fputc((SIGN(mp) == MP_NEG) ? '-' : '+', ofp);
-
-  for(ix = USED(mp) - 1; ix >= 0; ix--) {
-    fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix));
-  }
-
-} /* end mp_print() */
-
-#endif /* if MP_IOFUNC */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ More I/O Functions */
-
-/* {{{ mp_read_signed_bin(mp, str, len) */
-
-/* 
-   mp_read_signed_bin(mp, str, len)
-
-   Read in a raw value (base 256) into the given mp_int
- */
-
-mp_err  mp_read_signed_bin(mp_int *mp, unsigned char *str, int len)
-{
-  mp_err         res;
-
-  ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
-
-  if((res = mp_read_unsigned_bin(mp, str + 1, len - 1)) == MP_OKAY) {
-    /* Get sign from first byte */
-    if(str[0])
-      SIGN(mp) = MP_NEG;
-    else
-      SIGN(mp) = MP_ZPOS;
-  }
-
-  return res;
-
-} /* end mp_read_signed_bin() */
-
-/* }}} */
-
-/* {{{ mp_signed_bin_size(mp) */
-
-int    mp_signed_bin_size(mp_int *mp)
-{
-  ARGCHK(mp != NULL, 0);
-
-  return mp_unsigned_bin_size(mp) + 1;
-
-} /* end mp_signed_bin_size() */
-
-/* }}} */
-
-/* {{{ mp_to_signed_bin(mp, str) */
-
-mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str)
-{
-  ARGCHK(mp != NULL && str != NULL, MP_BADARG);
-
-  /* Caller responsible for allocating enough memory (use mp_raw_size(mp)) */
-  str[0] = (char)SIGN(mp);
-
-  return mp_to_unsigned_bin(mp, str + 1);
-
-} /* end mp_to_signed_bin() */
-
-/* }}} */
-
-/* {{{ mp_read_unsigned_bin(mp, str, len) */
-
-/*
-  mp_read_unsigned_bin(mp, str, len)
-
-  Read in an unsigned value (base 256) into the given mp_int
- */
-
-mp_err  mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len)
-{
-  int     ix;
-  mp_err  res;
-
-  ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
-
-  mp_zero(mp);
-
-  for(ix = 0; ix < len; ix++) {
-    if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY)
-      return res;
-
-    if((res = mp_add_d(mp, str[ix], mp)) != MP_OKAY)
-      return res;
-  }
-  
-  return MP_OKAY;
-  
-} /* end mp_read_unsigned_bin() */
-
-/* }}} */
-
-/* {{{ mp_unsigned_bin_size(mp) */
-
-int     mp_unsigned_bin_size(mp_int *mp) 
-{
-  mp_digit   topdig;
-  int        count;
-
-  ARGCHK(mp != NULL, 0);
-
-  /* Special case for the value zero */
-  if(USED(mp) == 1 && DIGIT(mp, 0) == 0)
-    return 1;
-
-  count = (USED(mp) - 1) * sizeof(mp_digit);
-  topdig = DIGIT(mp, USED(mp) - 1);
-
-  while(topdig != 0) {
-    ++count;
-    topdig >>= CHAR_BIT;
-  }
-
-  return count;
-
-} /* end mp_unsigned_bin_size() */
-
-/* }}} */
-
-/* {{{ mp_to_unsigned_bin(mp, str) */
-
-mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str)
-{
-  mp_digit      *dp, *end, d;
-  unsigned char *spos;
-
-  ARGCHK(mp != NULL && str != NULL, MP_BADARG);
-
-  dp = DIGITS(mp);
-  end = dp + USED(mp) - 1;
-  spos = str;
-
-  /* Special case for zero, quick test */
-  if(dp == end && *dp == 0) {
-    *str = '\0';
-    return MP_OKAY;
-  }
-
-  /* Generate digits in reverse order */
-  while(dp < end) {
-    int      ix;
-
-    d = *dp;
-    for(ix = 0; ix < sizeof(mp_digit); ++ix) {
-      *spos = d & UCHAR_MAX;
-      d >>= CHAR_BIT;
-      ++spos;
-    }
-
-    ++dp;
-  }
-
-  /* Now handle last digit specially, high order zeroes are not written */
-  d = *end;
-  while(d != 0) {
-    *spos = d & UCHAR_MAX;
-    d >>= CHAR_BIT;
-    ++spos;
-  }
-
-  /* Reverse everything to get digits in the correct order */
-  while(--spos > str) {
-    unsigned char t = *str;
-    *str = *spos;
-    *spos = t;
-
-    ++str;
-  }
-
-  return MP_OKAY;
-
-} /* end mp_to_unsigned_bin() */
-
-/* }}} */
-
-/* {{{ mp_count_bits(mp) */
-
-int    mp_count_bits(mp_int *mp)
-{
-  int      len;
-  mp_digit d;
-
-  ARGCHK(mp != NULL, MP_BADARG);
-
-  len = DIGIT_BIT * (USED(mp) - 1);
-  d = DIGIT(mp, USED(mp) - 1);
-
-  while(d != 0) {
-    ++len;
-    d >>= 1;
-  }
-
-  return len;
-  
-} /* end mp_count_bits() */
-
-/* }}} */
-
-/* {{{ mp_read_radix(mp, str, radix) */
-
-/*
-  mp_read_radix(mp, str, radix)
-
-  Read an integer from the given string, and set mp to the resulting
-  value.  The input is presumed to be in base 10.  Leading non-digit
-  characters are ignored, and the function reads until a non-digit
-  character or the end of the string.
- */
-
-mp_err  mp_read_radix(mp_int *mp, unsigned char *str, int radix)
-{
-  int     ix = 0, val = 0;
-  mp_err  res;
-  mp_sign sig = MP_ZPOS;
-
-  ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX, 
-	 MP_BADARG);
-
-  mp_zero(mp);
-
-  /* Skip leading non-digit characters until a digit or '-' or '+' */
-  while(str[ix] && 
-	(s_mp_tovalue(str[ix], radix) < 0) && 
-	str[ix] != '-' &&
-	str[ix] != '+') {
-    ++ix;
-  }
-
-  if(str[ix] == '-') {
-    sig = MP_NEG;
-    ++ix;
-  } else if(str[ix] == '+') {
-    sig = MP_ZPOS; /* this is the default anyway... */
-    ++ix;
-  }
-
-  while((val = s_mp_tovalue(str[ix], radix)) >= 0) {
-    if((res = s_mp_mul_d(mp, radix)) != MP_OKAY)
-      return res;
-    if((res = s_mp_add_d(mp, val)) != MP_OKAY)
-      return res;
-    ++ix;
-  }
-
-  if(s_mp_cmp_d(mp, 0) == MP_EQ)
-    SIGN(mp) = MP_ZPOS;
-  else
-    SIGN(mp) = sig;
-
-  return MP_OKAY;
-
-} /* end mp_read_radix() */
-
-/* }}} */
-
-/* {{{ mp_radix_size(mp, radix) */
-
-int    mp_radix_size(mp_int *mp, int radix)
-{
-  int  len;
-  ARGCHK(mp != NULL, 0);
-
-  len = s_mp_outlen(mp_count_bits(mp), radix) + 1; /* for NUL terminator */
-
-  if(mp_cmp_z(mp) < 0)
-    ++len; /* for sign */
-
-  return len;
-
-} /* end mp_radix_size() */
-
-/* }}} */
-
-/* {{{ mp_value_radix_size(num, qty, radix) */
-
-/* num = number of digits
-   qty = number of bits per digit
-   radix = target base
-   
-   Return the number of digits in the specified radix that would be
-   needed to express 'num' digits of 'qty' bits each.
- */
-int    mp_value_radix_size(int num, int qty, int radix)
-{
-  ARGCHK(num >= 0 && qty > 0 && radix >= 2 && radix <= MAX_RADIX, 0);
-
-  return s_mp_outlen(num * qty, radix);
-
-} /* end mp_value_radix_size() */
-
-/* }}} */
-
-/* {{{ mp_toradix(mp, str, radix) */
-
-mp_err mp_toradix(mp_int *mp, unsigned char *str, int radix)
-{
-  int  ix, pos = 0;
-
-  ARGCHK(mp != NULL && str != NULL, MP_BADARG);
-  ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE);
-
-  if(mp_cmp_z(mp) == MP_EQ) {
-    str[0] = '0';
-    str[1] = '\0';
-  } else {
-    mp_err   res;
-    mp_int   tmp;
-    mp_sign  sgn;
-    mp_digit rem, rdx = (mp_digit)radix;
-    char     ch;
-
-    if((res = mp_init_copy(&tmp, mp)) != MP_OKAY)
-      return res;
-
-    /* Save sign for later, and take absolute value */
-    sgn = SIGN(&tmp); SIGN(&tmp) = MP_ZPOS;
-
-    /* Generate output digits in reverse order      */
-    while(mp_cmp_z(&tmp) != 0) {
-      if((res = s_mp_div_d(&tmp, rdx, &rem)) != MP_OKAY) {
-	mp_clear(&tmp);
-	return res;
-      }
-
-      /* Generate digits, use capital letters */
-      ch = s_mp_todigit(rem, radix, 0);
-
-      str[pos++] = ch;
-    }
-
-    /* Add - sign if original value was negative */
-    if(sgn == MP_NEG)
-      str[pos++] = '-';
-
-    /* Add trailing NUL to end the string        */
-    str[pos--] = '\0';
-
-    /* Reverse the digits and sign indicator     */
-    ix = 0;
-    while(ix < pos) {
-      char tmp = str[ix];
-
-      str[ix] = str[pos];
-      str[pos] = tmp;
-      ++ix;
-      --pos;
-    }
-    
-    mp_clear(&tmp);
-  }
-
-  return MP_OKAY;
-
-} /* end mp_toradix() */
-
-/* }}} */
-
-/* {{{ mp_char2value(ch, r) */
-
-int    mp_char2value(char ch, int r)
-{
-  return s_mp_tovalue(ch, r);
-
-} /* end mp_tovalue() */
-
-/* }}} */
-
-/* }}} */
-
-/* {{{ mp_strerror(ec) */
-
-/*
-  mp_strerror(ec)
-
-  Return a string describing the meaning of error code 'ec'.  The
-  string returned is allocated in static memory, so the caller should
-  not attempt to modify or free the memory associated with this
-  string.
- */
-const char  *mp_strerror(mp_err ec)
-{
-  int   aec = (ec < 0) ? -ec : ec;
-
-  /* Code values are negative, so the senses of these comparisons
-     are accurate */
-  if(ec < MP_LAST_CODE || ec > MP_OKAY) {
-    return mp_err_string[0];  /* unknown error code */
-  } else {
-    return mp_err_string[aec + 1];
-  }
-
-} /* end mp_strerror() */
-
-/* }}} */
-
-/*========================================================================*/
-/*------------------------------------------------------------------------*/
-/* Static function definitions (internal use only)                        */
-
-/* {{{ Memory management */
-
-/* {{{ s_mp_grow(mp, min) */
-
-/* Make sure there are at least 'min' digits allocated to mp              */
-mp_err   s_mp_grow(mp_int *mp, mp_size min)
-{
-  if(min > ALLOC(mp)) {
-    mp_digit   *tmp;
-
-    /* Set min to next nearest default precision block size */
-    min = ((min + (s_mp_defprec - 1)) / s_mp_defprec) * s_mp_defprec;
-
-    if((tmp = s_mp_alloc(min, sizeof(mp_digit))) == NULL)
-      return MP_MEM;
-
-    s_mp_copy(DIGITS(mp), tmp, USED(mp));
-
-#if MP_CRYPTO
-    s_mp_setz(DIGITS(mp), ALLOC(mp));
-#endif
-    s_mp_free(DIGITS(mp));
-    DIGITS(mp) = tmp;
-    ALLOC(mp) = min;
-  }
-
-  return MP_OKAY;
-
-} /* end s_mp_grow() */
-
-/* }}} */
-
-/* {{{ s_mp_pad(mp, min) */
-
-/* Make sure the used size of mp is at least 'min', growing if needed     */
-mp_err   s_mp_pad(mp_int *mp, mp_size min)
-{
-  if(min > USED(mp)) {
-    mp_err  res;
-
-    /* Make sure there is room to increase precision  */
-    if(min > ALLOC(mp) && (res = s_mp_grow(mp, min)) != MP_OKAY)
-      return res;
-
-    /* Increase precision; should already be 0-filled */
-    USED(mp) = min;
-  }
-
-  return MP_OKAY;
-
-} /* end s_mp_pad() */
-
-/* }}} */
-
-/* {{{ s_mp_setz(dp, count) */
-
-#if MP_MACRO == 0
-/* Set 'count' digits pointed to by dp to be zeroes                       */
-void s_mp_setz(mp_digit *dp, mp_size count)
-{
-#if MP_MEMSET == 0
-  int  ix;
-
-  for(ix = 0; ix < count; ix++)
-    dp[ix] = 0;
-#else
-  memset(dp, 0, count * sizeof(mp_digit));
-#endif
-
-} /* end s_mp_setz() */
-#endif
-
-/* }}} */
-
-/* {{{ s_mp_copy(sp, dp, count) */
-
-#if MP_MACRO == 0
-/* Copy 'count' digits from sp to dp                                      */
-void s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count)
-{
-#if MP_MEMCPY == 0
-  int  ix;
-
-  for(ix = 0; ix < count; ix++)
-    dp[ix] = sp[ix];
-#else
-  memcpy(dp, sp, count * sizeof(mp_digit));
-#endif
-
-} /* end s_mp_copy() */
-#endif
-
-/* }}} */
-
-/* {{{ s_mp_alloc(nb, ni) */
-
-#if MP_MACRO == 0
-/* Allocate ni records of nb bytes each, and return a pointer to that     */
-void    *s_mp_alloc(size_t nb, size_t ni)
-{
-  return calloc(nb, ni);
-
-} /* end s_mp_alloc() */
-#endif
-
-/* }}} */
-
-/* {{{ s_mp_free(ptr) */
-
-#if MP_MACRO == 0
-/* Free the memory pointed to by ptr                                      */
-void     s_mp_free(void *ptr)
-{
-  if(ptr)
-    free(ptr);
-
-} /* end s_mp_free() */
-#endif
-
-/* }}} */
-
-/* {{{ s_mp_clamp(mp) */
-
-/* Remove leading zeroes from the given value                             */
-void     s_mp_clamp(mp_int *mp)
-{
-  mp_size   du = USED(mp);
-  mp_digit *zp = DIGITS(mp) + du - 1;
-
-  while(du > 1 && !*zp--)
-    --du;
-
-  if(du == 1 && *zp == 0)
-    SIGN(mp) = MP_ZPOS;
-
-  USED(mp) = du;
-
-} /* end s_mp_clamp() */
-
-
-/* }}} */
-
-/* {{{ s_mp_exch(a, b) */
-
-/* Exchange the data for a and b; (b, a) = (a, b)                         */
-void     s_mp_exch(mp_int *a, mp_int *b)
-{
-  mp_int   tmp;
-
-  tmp = *a;
-  *a = *b;
-  *b = tmp;
-
-} /* end s_mp_exch() */
-
-/* }}} */
-
-/* }}} */
-
-/* {{{ Arithmetic helpers */
-
-/* {{{ s_mp_lshd(mp, p) */
-
-/* 
-   Shift mp leftward by p digits, growing if needed, and zero-filling
-   the in-shifted digits at the right end.  This is a convenient
-   alternative to multiplication by powers of the radix
- */   
-
-mp_err   s_mp_lshd(mp_int *mp, mp_size p)
-{
-  mp_err   res;
-  mp_size  pos;
-  mp_digit *dp;
-  int     ix;
-
-  if(p == 0)
-    return MP_OKAY;
-
-  if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY)
-    return res;
-
-  pos = USED(mp) - 1;
-  dp = DIGITS(mp);
-
-  /* Shift all the significant figures over as needed */
-  for(ix = pos - p; ix >= 0; ix--) 
-    dp[ix + p] = dp[ix];
-
-  /* Fill the bottom digits with zeroes */
-  for(ix = 0; ix < p; ix++)
-    dp[ix] = 0;
-
-  return MP_OKAY;
-
-} /* end s_mp_lshd() */
-
-/* }}} */
-
-/* {{{ s_mp_rshd(mp, p) */
-
-/* 
-   Shift mp rightward by p digits.  Maintains the invariant that
-   digits above the precision are all zero.  Digits shifted off the
-   end are lost.  Cannot fail.
- */
-
-void     s_mp_rshd(mp_int *mp, mp_size p)
-{
-  mp_size  ix;
-  mp_digit *dp;
-
-  if(p == 0)
-    return;
-
-  /* Shortcut when all digits are to be shifted off */
-  if(p >= USED(mp)) {
-    s_mp_setz(DIGITS(mp), ALLOC(mp));
-    USED(mp) = 1;
-    SIGN(mp) = MP_ZPOS;
-    return;
-  }
-
-  /* Shift all the significant figures over as needed */
-  dp = DIGITS(mp);
-  for(ix = p; ix < USED(mp); ix++)
-    dp[ix - p] = dp[ix];
-
-  /* Fill the top digits with zeroes */
-  ix -= p;
-  while(ix < USED(mp))
-    dp[ix++] = 0;
-
-  /* Strip off any leading zeroes    */
-  s_mp_clamp(mp);
-
-} /* end s_mp_rshd() */
-
-/* }}} */
-
-/* {{{ s_mp_div_2(mp) */
-
-/* Divide by two -- take advantage of radix properties to do it fast      */
-void     s_mp_div_2(mp_int *mp)
-{
-  s_mp_div_2d(mp, 1);
-
-} /* end s_mp_div_2() */
-
-/* }}} */
-
-/* {{{ s_mp_mul_2(mp) */
-
-mp_err s_mp_mul_2(mp_int *mp)
-{
-  int      ix;
-  mp_digit kin = 0, kout, *dp = DIGITS(mp);
-  mp_err   res;
-
-  /* Shift digits leftward by 1 bit */
-  for(ix = 0; ix < USED(mp); ix++) {
-    kout = (dp[ix] >> (DIGIT_BIT - 1)) & 1;
-    dp[ix] = (dp[ix] << 1) | kin;
-
-    kin = kout;
-  }
-
-  /* Deal with rollover from last digit */
-  if(kin) {
-    if(ix >= ALLOC(mp)) {
-      if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY)
-	return res;
-      dp = DIGITS(mp);
-    }
-
-    dp[ix] = kin;
-    USED(mp) += 1;
-  }
-
-  return MP_OKAY;
-
-} /* end s_mp_mul_2() */
-
-/* }}} */
-
-/* {{{ s_mp_mod_2d(mp, d) */
-
-/*
-  Remainder the integer by 2^d, where d is a number of bits.  This
-  amounts to a bitwise AND of the value, and does not require the full
-  division code
- */
-void     s_mp_mod_2d(mp_int *mp, mp_digit d)
-{
-  unsigned int  ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT);
-  unsigned int  ix;
-  mp_digit      dmask, *dp = DIGITS(mp);
-
-  if(ndig >= USED(mp))
-    return;
-
-  /* Flush all the bits above 2^d in its digit */
-  dmask = (1 << nbit) - 1;
-  dp[ndig] &= dmask;
-
-  /* Flush all digits above the one with 2^d in it */
-  for(ix = ndig + 1; ix < USED(mp); ix++)
-    dp[ix] = 0;
-
-  s_mp_clamp(mp);
-
-} /* end s_mp_mod_2d() */
-
-/* }}} */
-
-/* {{{ s_mp_mul_2d(mp, d) */
-
-/*
-  Multiply by the integer 2^d, where d is a number of bits.  This
-  amounts to a bitwise shift of the value, and does not require the
-  full multiplication code.
- */
-mp_err    s_mp_mul_2d(mp_int *mp, mp_digit d)
-{
-  mp_err   res;
-  mp_digit save, next, mask, *dp;
-  mp_size  used;
-  int      ix;
-
-  if((res = s_mp_lshd(mp, d / DIGIT_BIT)) != MP_OKAY)
-    return res;
-
-  dp = DIGITS(mp); used = USED(mp);
-  d %= DIGIT_BIT;
-
-  mask = (1 << d) - 1;
-
-  /* If the shift requires another digit, make sure we've got one to
-     work with */
-  if((dp[used - 1] >> (DIGIT_BIT - d)) & mask) {
-    if((res = s_mp_grow(mp, used + 1)) != MP_OKAY)
-      return res;
-    dp = DIGITS(mp);
-  }
-
-  /* Do the shifting... */
-  save = 0;
-  for(ix = 0; ix < used; ix++) {
-    next = (dp[ix] >> (DIGIT_BIT - d)) & mask;
-    dp[ix] = (dp[ix] << d) | save;
-    save = next;
-  }
-
-  /* If, at this point, we have a nonzero carryout into the next
-     digit, we'll increase the size by one digit, and store it...
-   */
-  if(save) {
-    dp[used] = save;
-    USED(mp) += 1;
-  }
-
-  s_mp_clamp(mp);
-  return MP_OKAY;
-
-} /* end s_mp_mul_2d() */
-
-/* }}} */
-
-/* {{{ s_mp_div_2d(mp, d) */
-
-/*
-  Divide the integer by 2^d, where d is a number of bits.  This
-  amounts to a bitwise shift of the value, and does not require the
-  full division code (used in Barrett reduction, see below)
- */
-void     s_mp_div_2d(mp_int *mp, mp_digit d)
-{
-  int       ix;
-  mp_digit  save, next, mask, *dp = DIGITS(mp);
-
-  s_mp_rshd(mp, d / DIGIT_BIT);
-  d %= DIGIT_BIT;
-
-  mask = (1 << d) - 1;
-
-  save = 0;
-  for(ix = USED(mp) - 1; ix >= 0; ix--) {
-    next = dp[ix] & mask;
-    dp[ix] = (dp[ix] >> d) | (save << (DIGIT_BIT - d));
-    save = next;
-  }
-
-  s_mp_clamp(mp);
-
-} /* end s_mp_div_2d() */
-
-/* }}} */
-
-/* {{{ s_mp_norm(a, b) */
-
-/*
-  s_mp_norm(a, b)
-
-  Normalize a and b for division, where b is the divisor.  In order
-  that we might make good guesses for quotient digits, we want the
-  leading digit of b to be at least half the radix, which we
-  accomplish by multiplying a and b by a constant.  This constant is
-  returned (so that it can be divided back out of the remainder at the
-  end of the division process).
-
-  We multiply by the smallest power of 2 that gives us a leading digit
-  at least half the radix.  By choosing a power of 2, we simplify the 
-  multiplication and division steps to simple shifts.
- */
-mp_digit s_mp_norm(mp_int *a, mp_int *b)
-{
-  mp_digit  t, d = 0;
-
-  t = DIGIT(b, USED(b) - 1);
-  while(t < (RADIX / 2)) {
-    t <<= 1;
-    ++d;
-  }
-    
-  if(d != 0) {
-    s_mp_mul_2d(a, d);
-    s_mp_mul_2d(b, d);
-  }
-
-  return d;
-
-} /* end s_mp_norm() */
-
-/* }}} */
-
-/* }}} */
-
-/* {{{ Primitive digit arithmetic */
-
-/* {{{ s_mp_add_d(mp, d) */
-
-/* Add d to |mp| in place                                                 */
-mp_err   s_mp_add_d(mp_int *mp, mp_digit d)    /* unsigned digit addition */
-{
-  mp_word   w, k = 0;
-  mp_size   ix = 1, used = USED(mp);
-  mp_digit *dp = DIGITS(mp);
-
-  w = dp[0] + d;
-  dp[0] = ACCUM(w);
-  k = CARRYOUT(w);
-
-  while(ix < used && k) {
-    w = dp[ix] + k;
-    dp[ix] = ACCUM(w);
-    k = CARRYOUT(w);
-    ++ix;
-  }
-
-  if(k != 0) {
-    mp_err  res;
-
-    if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY)
-      return res;
-
-    DIGIT(mp, ix) = k;
-  }
-
-  return MP_OKAY;
-
-} /* end s_mp_add_d() */
-
-/* }}} */
-
-/* {{{ s_mp_sub_d(mp, d) */
-
-/* Subtract d from |mp| in place, assumes |mp| > d                        */
-mp_err   s_mp_sub_d(mp_int *mp, mp_digit d)    /* unsigned digit subtract */
-{
-  mp_word   w, b = 0;
-  mp_size   ix = 1, used = USED(mp);
-  mp_digit *dp = DIGITS(mp);
-
-  /* Compute initial subtraction    */
-  w = (RADIX + dp[0]) - d;
-  b = CARRYOUT(w) ? 0 : 1;
-  dp[0] = ACCUM(w);
-
-  /* Propagate borrows leftward     */
-  while(b && ix < used) {
-    w = (RADIX + dp[ix]) - b;
-    b = CARRYOUT(w) ? 0 : 1;
-    dp[ix] = ACCUM(w);
-    ++ix;
-  }
-
-  /* Remove leading zeroes          */
-  s_mp_clamp(mp);
-
-  /* If we have a borrow out, it's a violation of the input invariant */
-  if(b)
-    return MP_RANGE;
-  else
-    return MP_OKAY;
-
-} /* end s_mp_sub_d() */
-
-/* }}} */
-
-/* {{{ s_mp_mul_d(a, d) */
-
-/* Compute a = a * d, single digit multiplication                         */
-mp_err   s_mp_mul_d(mp_int *a, mp_digit d)
-{
-  mp_word w, k = 0;
-  mp_size ix, max;
-  mp_err  res;
-  mp_digit *dp = DIGITS(a);
-
-  /*
-    Single-digit multiplication will increase the precision of the
-    output by at most one digit.  However, we can detect when this
-    will happen -- if the high-order digit of a, times d, gives a
-    two-digit result, then the precision of the result will increase;
-    otherwise it won't.  We use this fact to avoid calling s_mp_pad()
-    unless absolutely necessary.
-   */
-  max = USED(a);
-  w = dp[max - 1] * d;
-  if(CARRYOUT(w) != 0) {
-    if((res = s_mp_pad(a, max + 1)) != MP_OKAY)
-      return res;
-    dp = DIGITS(a);
-  }
-
-  for(ix = 0; ix < max; ix++) {
-    w = (dp[ix] * d) + k;
-    dp[ix] = ACCUM(w);
-    k = CARRYOUT(w);
-  }
-
-  /* If there is a precision increase, take care of it here; the above
-     test guarantees we have enough storage to do this safely.
-   */
-  if(k) {
-    dp[max] = k; 
-    USED(a) = max + 1;
-  }
-
-  s_mp_clamp(a);
-
-  return MP_OKAY;
-  
-} /* end s_mp_mul_d() */
-
-/* }}} */
-
-/* {{{ s_mp_div_d(mp, d, r) */
-
-/*
-  s_mp_div_d(mp, d, r)
-
-  Compute the quotient mp = mp / d and remainder r = mp mod d, for a
-  single digit d.  If r is null, the remainder will be discarded.
- */
-
-mp_err   s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r)
-{
-  mp_word   w = 0, t;
-  mp_int    quot;
-  mp_err    res;
-  mp_digit *dp = DIGITS(mp), *qp;
-  int       ix;
-
-  if(d == 0)
-    return MP_RANGE;
-
-  /* Make room for the quotient */
-  if((res = mp_init_size(&quot, USED(mp))) != MP_OKAY)
-    return res;
-
-  USED(&quot) = USED(mp); /* so clamping will work below */
-  qp = DIGITS(&quot);
-
-  /* Divide without subtraction */
-  for(ix = USED(mp) - 1; ix >= 0; ix--) {
-    w = (w << DIGIT_BIT) | dp[ix];
-
-    if(w >= d) {
-      t = w / d;
-      w = w % d;
-    } else {
-      t = 0;
-    }
-
-    qp[ix] = t;
-  }
-
-  /* Deliver the remainder, if desired */
-  if(r)
-    *r = w;
-
-  s_mp_clamp(&quot);
-  mp_exch(&quot, mp);
-  mp_clear(&quot);
-
-  return MP_OKAY;
-
-} /* end s_mp_div_d() */
-
-/* }}} */
-
-/* }}} */
-
-/* {{{ Primitive full arithmetic */
-
-/* {{{ s_mp_add(a, b) */
-
-/* Compute a = |a| + |b|                                                  */
-mp_err   s_mp_add(mp_int *a, mp_int *b)        /* magnitude addition      */
-{
-  mp_word   w = 0;
-  mp_digit *pa, *pb;
-  mp_size   ix, used = USED(b);
-  mp_err    res;
-
-  /* Make sure a has enough precision for the output value */
-  if((used > USED(a)) && (res = s_mp_pad(a, used)) != MP_OKAY)
-    return res;
-
-  /*
-    Add up all digits up to the precision of b.  If b had initially
-    the same precision as a, or greater, we took care of it by the
-    padding step above, so there is no problem.  If b had initially
-    less precision, we'll have to make sure the carry out is duly
-    propagated upward among the higher-order digits of the sum.
-   */
-  pa = DIGITS(a);
-  pb = DIGITS(b);
-  for(ix = 0; ix < used; ++ix) {
-    w += *pa + *pb++;
-    *pa++ = ACCUM(w);
-    w = CARRYOUT(w);
-  }
-
-  /* If we run out of 'b' digits before we're actually done, make
-     sure the carries get propagated upward...  
-   */
-  used = USED(a);
-  while(w && ix < used) {
-    w += *pa;
-    *pa++ = ACCUM(w);
-    w = CARRYOUT(w);
-    ++ix;
-  }
-
-  /* If there's an overall carry out, increase precision and include
-     it.  We could have done this initially, but why touch the memory
-     allocator unless we're sure we have to?
-   */
-  if(w) {
-    if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
-      return res;
-
-    DIGIT(a, ix) = w;  /* pa may not be valid after s_mp_pad() call */
-  }
-
-  return MP_OKAY;
-
-} /* end s_mp_add() */
-
-/* }}} */
-
-/* {{{ s_mp_sub(a, b) */
-
-/* Compute a = |a| - |b|, assumes |a| >= |b|                              */
-mp_err   s_mp_sub(mp_int *a, mp_int *b)        /* magnitude subtract      */
-{
-  mp_word   w = 0;
-  mp_digit *pa, *pb;
-  mp_size   ix, used = USED(b);
-
-  /*
-    Subtract and propagate borrow.  Up to the precision of b, this
-    accounts for the digits of b; after that, we just make sure the
-    carries get to the right place.  This saves having to pad b out to
-    the precision of a just to make the loops work right...
-   */
-  pa = DIGITS(a);
-  pb = DIGITS(b);
-
-  for(ix = 0; ix < used; ++ix) {
-    w = (RADIX + *pa) - w - *pb++;
-    *pa++ = ACCUM(w);
-    w = CARRYOUT(w) ? 0 : 1;
-  }
-
-  used = USED(a);
-  while(ix < used) {
-    w = RADIX + *pa - w;
-    *pa++ = ACCUM(w);
-    w = CARRYOUT(w) ? 0 : 1;
-    ++ix;
-  }
-
-  /* Clobber any leading zeroes we created    */
-  s_mp_clamp(a);
-
-  /* 
-     If there was a borrow out, then |b| > |a| in violation
-     of our input invariant.  We've already done the work,
-     but we'll at least complain about it...
-   */
-  if(w)
-    return MP_RANGE;
-  else
-    return MP_OKAY;
-
-} /* end s_mp_sub() */
-
-/* }}} */
-
-/* {{{ s_mp_mul(a, b) */
-
-/* Compute a = |a| * |b|                                                  */
-mp_err   s_mp_mul(mp_int *a, mp_int *b)
-{
-  mp_word   w, k = 0;
-  mp_int    tmp;
-  mp_err    res;
-  mp_size   ix, jx, ua = USED(a), ub = USED(b);
-  mp_digit *pa, *pb, *pt, *pbt;
-
-  if((res = mp_init_size(&tmp, ua + ub)) != MP_OKAY)
-    return res;
-
-  /* This has the effect of left-padding with zeroes... */
-  USED(&tmp) = ua + ub;
-
-  /* We're going to need the base value each iteration */
-  pbt = DIGITS(&tmp);
-
-  /* Outer loop:  Digits of b */
-
-  pb = DIGITS(b);
-  for(ix = 0; ix < ub; ++ix, ++pb) {
-    if(*pb == 0) 
-      continue;
-
-    /* Inner product:  Digits of a */
-    pa = DIGITS(a);
-    for(jx = 0; jx < ua; ++jx, ++pa) {
-      pt = pbt + ix + jx;
-      w = *pb * *pa + k + *pt;
-      *pt = ACCUM(w);
-      k = CARRYOUT(w);
-    }
-
-    pbt[ix + jx] = k;
-    k = 0;
-  }
-
-  s_mp_clamp(&tmp);
-  s_mp_exch(&tmp, a);
-
-  mp_clear(&tmp);
-
-  return MP_OKAY;
-
-} /* end s_mp_mul() */
-
-/* }}} */
-
-/* {{{ s_mp_kmul(a, b, out, len) */
-
-#if 0
-void   s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len)
-{
-  mp_word   w, k = 0;
-  mp_size   ix, jx;
-  mp_digit *pa, *pt;
-
-  for(ix = 0; ix < len; ++ix, ++b) {
-    if(*b == 0)
-      continue;
-    
-    pa = a;
-    for(jx = 0; jx < len; ++jx, ++pa) {
-      pt = out + ix + jx;
-      w = *b * *pa + k + *pt;
-      *pt = ACCUM(w);
-      k = CARRYOUT(w);
-    }
-
-    out[ix + jx] = k;
-    k = 0;
-  }
-
-} /* end s_mp_kmul() */
-#endif
-
-/* }}} */
-
-/* {{{ s_mp_sqr(a) */
-
-/*
-  Computes the square of a, in place.  This can be done more
-  efficiently than a general multiplication, because many of the
-  computation steps are redundant when squaring.  The inner product
-  step is a bit more complicated, but we save a fair number of
-  iterations of the multiplication loop.
- */
-#if MP_SQUARE
-mp_err   s_mp_sqr(mp_int *a)
-{
-  mp_word  w, k = 0;
-  mp_int   tmp;
-  mp_err   res;
-  mp_size  ix, jx, kx, used = USED(a);
-  mp_digit *pa1, *pa2, *pt, *pbt;
-
-  if((res = mp_init_size(&tmp, 2 * used)) != MP_OKAY)
-    return res;
-
-  /* Left-pad with zeroes */
-  USED(&tmp) = 2 * used;
-
-  /* We need the base value each time through the loop */
-  pbt = DIGITS(&tmp);
-
-  pa1 = DIGITS(a);
-  for(ix = 0; ix < used; ++ix, ++pa1) {
-    if(*pa1 == 0)
-      continue;
-
-    w = DIGIT(&tmp, ix + ix) + (*pa1 * *pa1);
-
-    pbt[ix + ix] = ACCUM(w);
-    k = CARRYOUT(w);
-
-    /*
-      The inner product is computed as:
-
-         (C, S) = t[i,j] + 2 a[i] a[j] + C
-
-      This can overflow what can be represented in an mp_word, and
-      since C arithmetic does not provide any way to check for
-      overflow, we have to check explicitly for overflow conditions
-      before they happen.
-     */
-    for(jx = ix + 1, pa2 = DIGITS(a) + jx; jx < used; ++jx, ++pa2) {
-      mp_word  u = 0, v;
-      
-      /* Store this in a temporary to avoid indirections later */
-      pt = pbt + ix + jx;
-
-      /* Compute the multiplicative step */
-      w = *pa1 * *pa2;
-
-      /* If w is more than half MP_WORD_MAX, the doubling will
-	 overflow, and we need to record a carry out into the next
-	 word */
-      u = (w >> (MP_WORD_BIT - 1)) & 1;
-
-      /* Double what we've got, overflow will be ignored as defined
-	 for C arithmetic (we've already noted if it is to occur)
-       */
-      w *= 2;
-
-      /* Compute the additive step */
-      v = *pt + k;
-
-      /* If we do not already have an overflow carry, check to see
-	 if the addition will cause one, and set the carry out if so 
-       */
-      u |= ((MP_WORD_MAX - v) < w);
-
-      /* Add in the rest, again ignoring overflow */
-      w += v;
-
-      /* Set the i,j digit of the output */
-      *pt = ACCUM(w);
-
-      /* Save carry information for the next iteration of the loop.
-	 This is why k must be an mp_word, instead of an mp_digit */
-      k = CARRYOUT(w) | (u << DIGIT_BIT);
-
-    } /* for(jx ...) */
-
-    /* Set the last digit in the cycle and reset the carry */
-    k = DIGIT(&tmp, ix + jx) + k;
-    pbt[ix + jx] = ACCUM(k);
-    k = CARRYOUT(k);
-
-    /* If we are carrying out, propagate the carry to the next digit
-       in the output.  This may cascade, so we have to be somewhat
-       circumspect -- but we will have enough precision in the output
-       that we won't overflow 
-     */
-    kx = 1;
-    while(k) {
-      k = pbt[ix + jx + kx] + 1;
-      pbt[ix + jx + kx] = ACCUM(k);
-      k = CARRYOUT(k);
-      ++kx;
-    }
-  } /* for(ix ...) */
-
-  s_mp_clamp(&tmp);
-  s_mp_exch(&tmp, a);
-
-  mp_clear(&tmp);
-
-  return MP_OKAY;
-
-} /* end s_mp_sqr() */
-#endif
-
-/* }}} */
-
-/* {{{ s_mp_div(a, b) */
-
-/*
-  s_mp_div(a, b)
-
-  Compute a = a / b and b = a mod b.  Assumes b > a.
- */
-
-mp_err   s_mp_div(mp_int *a, mp_int *b)
-{
-  mp_int   quot, rem, t;
-  mp_word  q;
-  mp_err   res;
-  mp_digit d;
-  int      ix;
-
-  if(mp_cmp_z(b) == 0)
-    return MP_RANGE;
-
-  /* Shortcut if b is power of two */
-  if((ix = s_mp_ispow2(b)) >= 0) {
-    mp_copy(a, b);  /* need this for remainder */
-    s_mp_div_2d(a, (mp_digit)ix);
-    s_mp_mod_2d(b, (mp_digit)ix);
-
-    return MP_OKAY;
-  }
-
-  /* Allocate space to store the quotient */
-  if((res = mp_init_size(&quot, USED(a))) != MP_OKAY)
-    return res;
-
-  /* A working temporary for division     */
-  if((res = mp_init_size(&t, USED(a))) != MP_OKAY)
-    goto T;
-
-  /* Allocate space for the remainder     */
-  if((res = mp_init_size(&rem, USED(a))) != MP_OKAY)
-    goto REM;
-
-  /* Normalize to optimize guessing       */
-  d = s_mp_norm(a, b);
-
-  /* Perform the division itself...woo!   */
-  ix = USED(a) - 1;
-
-  while(ix >= 0) {
-    /* Find a partial substring of a which is at least b */
-    while(s_mp_cmp(&rem, b) < 0 && ix >= 0) {
-      if((res = s_mp_lshd(&rem, 1)) != MP_OKAY) 
-	goto CLEANUP;
-
-      if((res = s_mp_lshd(&quot, 1)) != MP_OKAY)
-	goto CLEANUP;
-
-      DIGIT(&rem, 0) = DIGIT(a, ix);
-      s_mp_clamp(&rem);
-      --ix;
-    }
-
-    /* If we didn't find one, we're finished dividing    */
-    if(s_mp_cmp(&rem, b) < 0) 
-      break;    
-
-    /* Compute a guess for the next quotient digit       */
-    q = DIGIT(&rem, USED(&rem) - 1);
-    if(q <= DIGIT(b, USED(b) - 1) && USED(&rem) > 1)
-      q = (q << DIGIT_BIT) | DIGIT(&rem, USED(&rem) - 2);
-
-    q /= DIGIT(b, USED(b) - 1);
-
-    /* The guess can be as much as RADIX + 1 */
-    if(q >= RADIX)
-      q = RADIX - 1;
-
-    /* See what that multiplies out to                   */
-    mp_copy(b, &t);
-    if((res = s_mp_mul_d(&t, q)) != MP_OKAY)
-      goto CLEANUP;
-
-    /* 
-       If it's too big, back it off.  We should not have to do this
-       more than once, or, in rare cases, twice.  Knuth describes a
-       method by which this could be reduced to a maximum of once, but
-       I didn't implement that here.
-     */
-    while(s_mp_cmp(&t, &rem) > 0) {
-      --q;
-      s_mp_sub(&t, b);
-    }
-
-    /* At this point, q should be the right next digit   */
-    if((res = s_mp_sub(&rem, &t)) != MP_OKAY)
-      goto CLEANUP;
-
-    /*
-      Include the digit in the quotient.  We allocated enough memory
-      for any quotient we could ever possibly get, so we should not
-      have to check for failures here
-     */
-    DIGIT(&quot, 0) = q;
-  }
-
-  /* Denormalize remainder                */
-  if(d != 0) 
-    s_mp_div_2d(&rem, d);
-
-  s_mp_clamp(&quot);
-  s_mp_clamp(&rem);
-
-  /* Copy quotient back to output         */
-  s_mp_exch(&quot, a);
-  
-  /* Copy remainder back to output        */
-  s_mp_exch(&rem, b);
-
-CLEANUP:
-  mp_clear(&rem);
-REM:
-  mp_clear(&t);
-T:
-  mp_clear(&quot);
-
-  return res;
-
-} /* end s_mp_div() */
-
-/* }}} */
-
-/* {{{ s_mp_2expt(a, k) */
-
-mp_err   s_mp_2expt(mp_int *a, mp_digit k)
-{
-  mp_err    res;
-  mp_size   dig, bit;
-
-  dig = k / DIGIT_BIT;
-  bit = k % DIGIT_BIT;
-
-  mp_zero(a);
-  if((res = s_mp_pad(a, dig + 1)) != MP_OKAY)
-    return res;
-  
-  DIGIT(a, dig) |= (1 << bit);
-
-  return MP_OKAY;
-
-} /* end s_mp_2expt() */
-
-/* }}} */
-
-/* {{{ s_mp_reduce(x, m, mu) */
-
-/*
-  Compute Barrett reduction, x (mod m), given a precomputed value for
-  mu = b^2k / m, where b = RADIX and k = #digits(m).  This should be
-  faster than straight division, when many reductions by the same
-  value of m are required (such as in modular exponentiation).  This
-  can nearly halve the time required to do modular exponentiation,
-  as compared to using the full integer divide to reduce.
-
-  This algorithm was derived from the _Handbook of Applied
-  Cryptography_ by Menezes, Oorschot and VanStone, Ch. 14,
-  pp. 603-604.  
- */
-
-mp_err   s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu)
-{
-  mp_int   q;
-  mp_err   res;
-  mp_size  um = USED(m);
-
-  if((res = mp_init_copy(&q, x)) != MP_OKAY)
-    return res;
-
-  s_mp_rshd(&q, um - 1);       /* q1 = x / b^(k-1)  */
-  s_mp_mul(&q, mu);            /* q2 = q1 * mu      */
-  s_mp_rshd(&q, um + 1);       /* q3 = q2 / b^(k+1) */
-
-  /* x = x mod b^(k+1), quick (no division) */
-  s_mp_mod_2d(x, DIGIT_BIT * (um + 1));
-
-  /* q = q * m mod b^(k+1), quick (no division) */
-  s_mp_mul(&q, m);
-  s_mp_mod_2d(&q, DIGIT_BIT * (um + 1));
-
-  /* x = x - q */
-  if((res = mp_sub(x, &q, x)) != MP_OKAY)
-    goto CLEANUP;
-
-  /* If x < 0, add b^(k+1) to it */
-  if(mp_cmp_z(x) < 0) {
-    mp_set(&q, 1);
-    if((res = s_mp_lshd(&q, um + 1)) != MP_OKAY)
-      goto CLEANUP;
-    if((res = mp_add(x, &q, x)) != MP_OKAY)
-      goto CLEANUP;
-  }
-
-  /* Back off if it's too big */
-  while(mp_cmp(x, m) >= 0) {
-    if((res = s_mp_sub(x, m)) != MP_OKAY)
-      break;
-  }
-
- CLEANUP:
-  mp_clear(&q);
-
-  return res;
-
-} /* end s_mp_reduce() */
-
-/* }}} */
-
-/* }}} */
-
-/* {{{ Primitive comparisons */
-
-/* {{{ s_mp_cmp(a, b) */
-
-/* Compare |a| <=> |b|, return 0 if equal, <0 if a<b, >0 if a>b           */
-int      s_mp_cmp(mp_int *a, mp_int *b)
-{
-  mp_size   ua = USED(a), ub = USED(b);
-
-  if(ua > ub)
-    return MP_GT;
-  else if(ua < ub)
-    return MP_LT;
-  else {
-    int      ix = ua - 1;
-    mp_digit *ap = DIGITS(a) + ix, *bp = DIGITS(b) + ix;
-
-    while(ix >= 0) {
-      if(*ap > *bp)
-	return MP_GT;
-      else if(*ap < *bp)
-	return MP_LT;
-
-      --ap; --bp; --ix;
-    }
-
-    return MP_EQ;
-  }
-
-} /* end s_mp_cmp() */
-
-/* }}} */
-
-/* {{{ s_mp_cmp_d(a, d) */
-
-/* Compare |a| <=> d, return 0 if equal, <0 if a<d, >0 if a>d             */
-int      s_mp_cmp_d(mp_int *a, mp_digit d)
-{
-  mp_size  ua = USED(a);
-  mp_digit *ap = DIGITS(a);
-
-  if(ua > 1)
-    return MP_GT;
-
-  if(*ap < d) 
-    return MP_LT;
-  else if(*ap > d)
-    return MP_GT;
-  else
-    return MP_EQ;
-
-} /* end s_mp_cmp_d() */
-
-/* }}} */
-
-/* {{{ s_mp_ispow2(v) */
-
-/*
-  Returns -1 if the value is not a power of two; otherwise, it returns
-  k such that v = 2^k, i.e. lg(v).
- */
-int      s_mp_ispow2(mp_int *v)
-{
-  mp_digit d, *dp;
-  mp_size  uv = USED(v);
-  int      extra = 0, ix;
-
-  d = DIGIT(v, uv - 1); /* most significant digit of v */
-
-  while(d && ((d & 1) == 0)) {
-    d >>= 1;
-    ++extra;
-  }
-
-  if(d == 1) {
-    ix = uv - 2;
-    dp = DIGITS(v) + ix;
-
-    while(ix >= 0) {
-      if(*dp)
-	return -1; /* not a power of two */
-
-      --dp; --ix;
-    }
-
-    return ((uv - 1) * DIGIT_BIT) + extra;
-  } 
-
-  return -1;
-
-} /* end s_mp_ispow2() */
-
-/* }}} */
-
-/* {{{ s_mp_ispow2d(d) */
-
-int      s_mp_ispow2d(mp_digit d)
-{
-  int   pow = 0;
-
-  while((d & 1) == 0) {
-    ++pow; d >>= 1;
-  }
-
-  if(d == 1)
-    return pow;
-
-  return -1;
-
-} /* end s_mp_ispow2d() */
-
-/* }}} */
-
-/* }}} */
-
-/* {{{ Primitive I/O helpers */
-
-/* {{{ s_mp_tovalue(ch, r) */
-
-/*
-  Convert the given character to its digit value, in the given radix.
-  If the given character is not understood in the given radix, -1 is
-  returned.  Otherwise the digit's numeric value is returned.
-
-  The results will be odd if you use a radix < 2 or > 62, you are
-  expected to know what you're up to.
- */
-int      s_mp_tovalue(char ch, int r)
-{
-  int    val, xch;
-  
-  if(r > 36)
-    xch = ch;
-  else
-    xch = toupper(ch);
-
-  if(isdigit(xch))
-    val = xch - '0';
-  else if(isupper(xch))
-    val = xch - 'A' + 10;
-  else if(islower(xch))
-    val = xch - 'a' + 36;
-  else if(xch == '+')
-    val = 62;
-  else if(xch == '/')
-    val = 63;
-  else 
-    return -1;
-
-  if(val < 0 || val >= r)
-    return -1;
-
-  return val;
-
-} /* end s_mp_tovalue() */
-
-/* }}} */
-
-/* {{{ s_mp_todigit(val, r, low) */
-
-/*
-  Convert val to a radix-r digit, if possible.  If val is out of range
-  for r, returns zero.  Otherwise, returns an ASCII character denoting
-  the value in the given radix.
-
-  The results may be odd if you use a radix < 2 or > 64, you are
-  expected to know what you're doing.
- */
-  
-char     s_mp_todigit(int val, int r, int low)
-{
-  char   ch;
-
-  if(val < 0 || val >= r)
-    return 0;
-
-  ch = s_dmap_1[val];
-
-  if(r <= 36 && low)
-    ch = tolower(ch);
-
-  return ch;
-
-} /* end s_mp_todigit() */
-
-/* }}} */
-
-/* {{{ s_mp_outlen(bits, radix) */
-
-/* 
-   Return an estimate for how long a string is needed to hold a radix
-   r representation of a number with 'bits' significant bits.
-
-   Does not include space for a sign or a NUL terminator.
- */
-int      s_mp_outlen(int bits, int r)
-{
-  return (int)((double)bits * LOG_V_2(r) + 0.5);
-
-} /* end s_mp_outlen() */
-
-/* }}} */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* HERE THERE BE DRAGONS                                                  */
--- a/src/protocols/sametime/meanwhile/mpi/mpi.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,221 +0,0 @@
-/*
-    mpi.h
-
-    by Michael J. Fromberger <http://www.dartmouth.edu/~sting/>
-    Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved
-
-    Arbitrary precision integer arithmetic library
-
-    $Id: mpi.h 14563 2005-11-29 23:31:40Z taliesein $
- */
-
-#ifndef _H_MPI_
-#define _H_MPI_
-
-#include "mpi-config.h"
-
-#if MP_DEBUG
-#undef MP_IOFUNC
-#define MP_IOFUNC 1
-#endif
-
-#if MP_IOFUNC
-#include <stdio.h>
-#include <ctype.h>
-#endif
-
-#include <limits.h>
-
-#define  MP_NEG  1
-#define  MP_ZPOS 0
-
-/* Included for compatibility... */
-#define  NEG     MP_NEG
-#define  ZPOS    MP_ZPOS
-
-#define  MP_OKAY          0 /* no error, all is well */
-#define  MP_YES           0 /* yes (boolean result)  */
-#define  MP_NO           -1 /* no (boolean result)   */
-#define  MP_MEM          -2 /* out of memory         */
-#define  MP_RANGE        -3 /* argument out of range */
-#define  MP_BADARG       -4 /* invalid parameter     */
-#define  MP_UNDEF        -5 /* answer is undefined   */
-#define  MP_LAST_CODE    MP_UNDEF
-
-#include "mpi-types.h"
-
-/* Included for compatibility... */
-#define DIGIT_BIT         MP_DIGIT_BIT
-#define DIGIT_MAX         MP_DIGIT_MAX
-
-/* Macros for accessing the mp_int internals           */
-#define  SIGN(MP)     ((MP)->sign)
-#define  USED(MP)     ((MP)->used)
-#define  ALLOC(MP)    ((MP)->alloc)
-#define  DIGITS(MP)   ((MP)->dp)
-#define  DIGIT(MP,N)  (MP)->dp[(N)]
-
-#if MP_ARGCHK == 1
-#define  ARGCHK(X,Y)  {if(!(X)){return (Y);}}
-#elif MP_ARGCHK == 2
-#include <assert.h>
-#define  ARGCHK(X,Y)  assert(X)
-#else
-#define  ARGCHK(X,Y)  /*  */
-#endif
-
-/* This defines the maximum I/O base (minimum is 2)   */
-#define MAX_RADIX         64
-
-typedef struct {
-  mp_sign       sign;    /* sign of this quantity      */
-  mp_size       alloc;   /* how many digits allocated  */
-  mp_size       used;    /* how many digits used       */
-  mp_digit     *dp;      /* the digits themselves      */
-} mp_int;
-
-/*------------------------------------------------------------------------*/
-/* Default precision                                                      */
-
-unsigned int mp_get_prec(void);
-void         mp_set_prec(unsigned int prec);
-
-/*------------------------------------------------------------------------*/
-/* Memory management                                                      */
-
-mp_err mp_init(mp_int *mp);
-mp_err mp_init_array(mp_int mp[], int count);
-mp_err mp_init_size(mp_int *mp, mp_size prec);
-mp_err mp_init_copy(mp_int *mp, mp_int *from);
-mp_err mp_copy(mp_int *from, mp_int *to);
-void   mp_exch(mp_int *mp1, mp_int *mp2);
-void   mp_clear(mp_int *mp);
-void   mp_clear_array(mp_int mp[], int count);
-void   mp_zero(mp_int *mp);
-void   mp_set(mp_int *mp, mp_digit d);
-mp_err mp_set_int(mp_int *mp, long z);
-
-/*------------------------------------------------------------------------*/
-/* Single digit arithmetic                                                */
-
-mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b);
-mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b);
-mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b);
-mp_err mp_mul_2(mp_int *a, mp_int *c);
-mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r);
-mp_err mp_div_2(mp_int *a, mp_int *c);
-mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c);
-
-/*------------------------------------------------------------------------*/
-/* Sign manipulations                                                     */
-
-mp_err mp_abs(mp_int *a, mp_int *b);
-mp_err mp_neg(mp_int *a, mp_int *b);
-
-/*------------------------------------------------------------------------*/
-/* Full arithmetic                                                        */
-
-mp_err mp_add(mp_int *a, mp_int *b, mp_int *c);
-mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c);
-mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c);
-mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c);
-#if MP_SQUARE
-mp_err mp_sqr(mp_int *a, mp_int *b);
-#else
-#define mp_sqr(a, b) mp_mul(a, a, b)
-#endif
-mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r);
-mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r);
-mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c);
-mp_err mp_2expt(mp_int *a, mp_digit k);
-mp_err mp_sqrt(mp_int *a, mp_int *b);
-
-/*------------------------------------------------------------------------*/
-/* Modular arithmetic                                                     */
-
-#if MP_MODARITH
-mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c);
-mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c);
-mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
-mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
-mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
-#if MP_SQUARE
-mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c);
-#else
-#define mp_sqrmod(a, m, c) mp_mulmod(a, a, m, c)
-#endif
-mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
-mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c);
-#endif /* MP_MODARITH */
-
-/*------------------------------------------------------------------------*/
-/* Comparisons                                                            */
-
-int    mp_cmp_z(mp_int *a);
-int    mp_cmp_d(mp_int *a, mp_digit d);
-int    mp_cmp(mp_int *a, mp_int *b);
-int    mp_cmp_mag(mp_int *a, mp_int *b);
-int    mp_cmp_int(mp_int *a, long z);
-int    mp_isodd(mp_int *a);
-int    mp_iseven(mp_int *a);
-
-/*------------------------------------------------------------------------*/
-/* Number theoretic                                                       */
-
-#if MP_NUMTH
-mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c);
-mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c);
-mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y);
-mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c);
-#endif /* end MP_NUMTH */
-
-/*------------------------------------------------------------------------*/
-/* Input and output                                                       */
-
-#if MP_IOFUNC
-void   mp_print(mp_int *mp, FILE *ofp);
-#endif /* end MP_IOFUNC */
-
-/*------------------------------------------------------------------------*/
-/* Base conversion                                                        */
-
-#define BITS     1
-#define BYTES    CHAR_BIT
-
-mp_err mp_read_signed_bin(mp_int *mp, unsigned char *str, int len);
-int    mp_signed_bin_size(mp_int *mp);
-mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str);
-
-mp_err mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len);
-int    mp_unsigned_bin_size(mp_int *mp);
-mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str);
-
-int    mp_count_bits(mp_int *mp);
-
-#if MP_COMPAT_MACROS
-#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
-#define mp_raw_size(mp)           mp_signed_bin_size(mp)
-#define mp_toraw(mp, str)         mp_to_signed_bin((mp), (str))
-#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
-#define mp_mag_size(mp)           mp_unsigned_bin_size(mp)
-#define mp_tomag(mp, str)         mp_to_unsigned_bin((mp), (str))
-#endif
-
-mp_err mp_read_radix(mp_int *mp, unsigned char *str, int radix);
-int    mp_radix_size(mp_int *mp, int radix);
-int    mp_value_radix_size(int num, int qty, int radix);
-mp_err mp_toradix(mp_int *mp, unsigned char *str, int radix);
-
-int    mp_char2value(char ch, int r);
-
-#define mp_tobinary(M, S)  mp_toradix((M), (S), 2)
-#define mp_tooctal(M, S)   mp_toradix((M), (S), 8)
-#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
-#define mp_tohex(M, S)     mp_toradix((M), (S), 16)
-
-/*------------------------------------------------------------------------*/
-/* Error strings                                                          */
-
-const  char  *mp_strerror(mp_err ec);
-
-#endif /* end _H_MPI_ */
--- a/src/protocols/sametime/meanwhile/mw_channel.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,366 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_CHANNEL_H
-#define _MW_CHANNEL_H
-
-
-#include <time.h>
-#include "mw_common.h"
-
-
-/** @file mw_channel.h
-    
-Life-cycle of an outgoing channel:
-
-1: mwChannel_new is called. If there is a channel in the outgoing
-collection in state NEW, then it is returned. Otherwise, a channel
-is allocated, assigned a unique outgoing id, marked as NEW, and
-returned.
-
-2: channel is set to INIT status (effectively earmarking it as in-
-use).  fields on the channel can then be set as necessary to
-prepare it for creation.
-
-3: mwChannel_create is called. The channel is marked to WAIT status
-and a message is sent to the server. The channel is also marked as
-inactive as of that moment.
-
-4: the channel is accepted (step 5) or rejected (step 7)
-
-5: an accept message is received from the server, and the channel
-is marked as OPEN, and the inactive mark is removed. And messages
-in the in or out queues for that channel are processed. The channel
-is now ready to be used.
-
-6: data is sent and received over the channel
-
-7: the channel is closed either by receipt of a close message or by
-local action. If by local action, then a close message is sent to
-the server.  The channel is cleaned up, its queues dumped, and it
-is set to NEW status to await re-use.
-
-Life-cycle of an incoming channel:
-
-1: a channel create message is received. A channel is allocated and
-given an id matching the message. It is placed in status WAIT, and
-marked as inactive as of that moment. The service matching that
-channel is alerted of the incoming creation request.
-
-2: the service can either accept (step 3) or reject (step 5) the
-channel
-
-3: mwChannel_accept is called. The channel is marked as OPEN, and
-an accept message is sent to the server. And messages in the in or
-out queues for that channel are processed. The channel is now ready
-to be used.
-
-4: data is sent and received over the channel
-
-5: The channel is closed either by receipt of a close message or by
-local action. If by local action, then a close message is sent to
-the server.  The channel is cleaned up, its queues dumped, and it
-is deallocated. */
-
-
-/* place-holders */
-struct mwCipherInstance;
-struct mwMsgChannelAccept;
-struct mwMsgChannelCreate;
-struct mwMsgChannelDestroy;
-struct mwMsgChannelSend;
-struct mwService;
-struct mwSession;
-
-
-
-/** @struct mwChannel
-    Represents a channel to a service */
-struct mwChannel;
-
-
-/** @struct mwChannelSet
-    Collection of channels */
-struct mwChannelSet;
-
-
-/** special ID indicating the master channel */
-#define MW_MASTER_CHANNEL_ID  0x00000000
-
-
-/** non-zero if a channel id appears to be that of an outgoing channel */
-#define mwChannel_idIsOutgoing(id) \
-  (! (0x80000000 & (id)))
-
-/** non-zero if a channel id appears to be that of an incoming channel */
-#define mwChannel_idIsIncoming(id) \
-  (! mwChannel_idIsOutgoing(id))
-
-/** non-zero if a channel appears to be an outgoing channel */
-#define mwChannel_isOutgoing(chan) \
-  mwChannel_idIsOutgoing(mwChannel_getId(chan))
-
-/** non-zero if a channel appears to be an incoming channel */
-#define mwChannel_isIncoming(chan) \
-  mwChannel_idIsIncoming(mwChannel_getId(chan))
-
-
-/** channel status */
-enum mwChannelState {
-  mwChannel_NEW,      /**< channel is newly allocated, in the pool */
-  mwChannel_INIT,     /**< channel is being prepared, out of the pool */
-  mwChannel_WAIT,     /**< channel is waiting for accept */
-  mwChannel_OPEN,     /**< channel is accepted and open */
-  mwChannel_DESTROY,  /**< channel is being destroyed */
-  mwChannel_ERROR,    /**< channel is being destroyed due to error */
-  mwChannel_UNKNOWN,  /**< unknown state, or error determining state */
-};
-
-
-#define mwChannel_isState(chan, state) \
-  (mwChannel_getState(chan) == (state))
-
-
-/** channel statistic fields.
-    @see mwChannel_getStatistic */
-enum mwChannelStatField {
-  mwChannelStat_MSG_SENT,      /**< total send-on-chan messages sent */
-  mwChannelStat_MSG_RECV,      /**< total send-on-chan messages received */
-  mwChannelStat_U_BYTES_SENT,  /**< total bytes sent, pre-encryption */
-  mwChannelStat_U_BYTES_RECV,  /**< total bytes received, post-decryption */
-  mwChannelStat_OPENED_AT,     /**< time when channel was opened */
-  mwChannelStat_CLOSED_AT,     /**< time when channel was closed */
-};
-
-
-/** @enum mwEncryptPolicy
-
-    Policy for a channel, dictating what sort of encryption should be
-    used, if any, and when.
-*/
-enum mwEncryptPolicy {
-  mwEncrypt_NONE      = 0x0000, /**< encrypt none */
-  mwEncrypt_WHATEVER  = 0x0001, /**< encrypt whatever you want */
-  mwEncrypt_ALL       = 0x0002, /**< encrypt all, any cipher */
-  mwEncrypt_RC2_40    = 0x1000, /**< encrypt all, RC2/40 cipher */
-  mwEncrypt_RC2_128   = 0x2000, /**< encrypt all, RC2/128 cipher */
-};
-
-
-/** Allocate and initialize a channel set for a session */
-struct mwChannelSet *mwChannelSet_new(struct mwSession *);
-
-
-/** Clear and deallocate a channel set. Closes, clears, and frees all
-    contained channels. */
-void mwChannelSet_free(struct mwChannelSet *);
-
-
-/** Create an incoming channel with the given channel id. Channel's state
-    will be set to WAIT. Primarily for use in mw_session */
-struct mwChannel *mwChannel_newIncoming(struct mwChannelSet *, guint32 id);
-
-
-/** Create an outgoing channel. Its channel ID will be generated by
-    the owning channel set. Channel's state will be set to INIT */
-struct mwChannel *mwChannel_newOutgoing(struct mwChannelSet *);
-
-
-/** Obtain a reference to a channel by its id.
-    @returns the channel matching chan, or NULL */
-struct mwChannel *mwChannel_find(struct mwChannelSet *cs, guint32 chan);
-
-
-/** get the ID for a channel. 0x00 indicates an error, as that is not
-    a permissible value */
-guint32 mwChannel_getId(struct mwChannel *);
-
-
-/** get the session for a channel. */
-struct mwSession *mwChannel_getSession(struct mwChannel *);
-
-
-/** get the ID of the service for a channel. This may be 0x00 for NEW
-    channels */
-guint32 mwChannel_getServiceId(struct mwChannel *);
-
-
-/** get the service for a channel. This may be NULL for NEW
-    channels */
-struct mwService *mwChannel_getService(struct mwChannel *);
-
-
-/** associate a channel with an owning service */
-void mwChannel_setService(struct mwChannel *chan, struct mwService *srvc);
-
-
-/** get service-specific data. This is for use by service
-    implementations to easily associate information with the
-    channel */
-gpointer mwChannel_getServiceData(struct mwChannel *chan);
-
-
-/** set service-specific data. This is for use by service
-    implementations to easily associate information with the
-    channel */
-void mwChannel_setServiceData(struct mwChannel *chan,
-			      gpointer data, GDestroyNotify clean);
-
-
-void mwChannel_removeServiceData(struct mwChannel *chan);
-
-
-guint32 mwChannel_getProtoType(struct mwChannel *chan);
-
-
-void mwChannel_setProtoType(struct mwChannel *chan, guint32 proto_type);
-
-
-guint32 mwChannel_getProtoVer(struct mwChannel *chan);
-
-
-void mwChannel_setProtoVer(struct mwChannel *chan, guint32 proto_ver);
-
-
-/** Channel encryption policy.
-
-    Cannot currently be set, used internally to automatically
-    negotiate ciphers. Future revisions may allow this to be specified
-    in a new channel to dictate channel encryption.
-
-    @see enum mwEncryptPolicy
-*/
-guint16 mwChannel_getEncryptPolicy(struct mwChannel *chan);
-
-
-guint32 mwChannel_getOptions(struct mwChannel *chan);
-
-
-void mwChannel_setOptions(struct mwChannel *chan, guint32 options);
-
-
-/** User at the other end of the channel. The target user for outgoing
-    channels, the creator for incoming channels */
-struct mwLoginInfo *mwChannel_getUser(struct mwChannel *chan);
-
-
-/** direct reference to the create addtl information for a channel */
-struct mwOpaque *mwChannel_getAddtlCreate(struct mwChannel *);
-
-
-/** direct reference to the accept addtl information for a channel */
-struct mwOpaque *mwChannel_getAddtlAccept(struct mwChannel *);
-
-
-/** automatically adds instances of all ciphers in the session to the
-    list of supported ciphers for a channel */
-void mwChannel_populateSupportedCipherInstances(struct mwChannel *chan);
-
-
-/** add a cipher instance to a channel's list of supported
-    ciphers. Channel must be NEW. */
-void mwChannel_addSupportedCipherInstance(struct mwChannel *chan,
-					  struct mwCipherInstance *ci);
-
-
-/** the list of supported ciphers for a channel. This list will be
-    empty once a cipher has been selected for the channel */
-GList *mwChannel_getSupportedCipherInstances(struct mwChannel *chan);
-
-
-/** select a cipher instance for a channel. A NULL instance indicates
-    that no encryption should be used. */
-void mwChannel_selectCipherInstance(struct mwChannel *chan,
-				    struct mwCipherInstance *ci);
-
-
-/** get the state of a channel  */
-enum mwChannelState mwChannel_getState(struct mwChannel *);
-
-
-/** obtain the value for a statistic field as a gpointer */
-gpointer mwChannel_getStatistic(struct mwChannel *chan,
-				enum mwChannelStatField stat);
-
-
-/** Formally open a channel.
-
-    For outgoing channels: instruct the session to send a channel
-    create message to the server, and to mark the channel (which must
-    be in INIT status) as being in WAIT status.
-   
-    For incoming channels: configures the channel according to options
-    in the channel create message. Marks the channel as being in WAIT
-    status
-*/
-int mwChannel_create(struct mwChannel *chan);
-
-
-/** Formally accept an incoming channel. Instructs the session to send
-    a channel accept message to the server, and to mark the channel as
-    being OPEN. */
-int mwChannel_accept(struct mwChannel *chan);
-
-
-/** Destroy a channel. Sends a channel-destroy message to the server,
-    and perform cleanup to remove the channel.
-
-    @param chan    the channel to destroy
-    @param reason  the reason code for closing the channel
-    @param data    optional additional information 
-*/
-int mwChannel_destroy(struct mwChannel *chan, guint32 reason,
-		      struct mwOpaque *data);
-
-
-/** Compose a send-on-channel message, encrypt it as per the channel's
-    specification, and send it */
-int mwChannel_send(struct mwChannel *chan, guint32 msg_type,
-		   struct mwOpaque *msg);
-
-
-/** Compose a send-on-channel message, and if encrypt is TRUE, encrypt
-    it as per the channel's specification, and send it */
-int mwChannel_sendEncrypted(struct mwChannel *chan,
-			    guint32 msg_type, struct mwOpaque *msg,
-			    gboolean encrypt);
-
-
-/** pass a create message to a channel for handling */
-void mwChannel_recvCreate(struct mwChannel *chan,
-			  struct mwMsgChannelCreate *msg);
-
-
-/** pass an accept message to a channel for handling */
-void mwChannel_recvAccept(struct mwChannel *chan,
-			  struct mwMsgChannelAccept *msg);
-
-
-/** pass a destroy message to a channel for handling */
-void mwChannel_recvDestroy(struct mwChannel *chan,
-			   struct mwMsgChannelDestroy *msg);
-
-
-/** Feed data into a channel. */
-void mwChannel_recv(struct mwChannel *chan, struct mwMsgChannelSend *msg);
-
-
-#endif
-
--- a/src/protocols/sametime/meanwhile/mw_cipher.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,294 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_CIPHER_H
-#define _MW_CIPHER_H
-
-
-#include <glib.h>
-#include "mw_common.h"
-
-
-/* place-holders */
-struct mwChannel;
-struct mwSession;
-
-
-/** @enum mwCipherType
-    Common cipher types */
-enum mwCipherType {
-  mwCipher_RC2_40   = 0x0000,
-  mwCipher_RC2_128  = 0x0001,
-};
-
-
-struct mwCipher;
-struct mwCipherInstance;
-
-
-/** Obtain an instance of a given cipher, which can be used for the
-    processing of a single channel. */
-typedef struct mwCipherInstance *(*mwCipherInstantiator)
-     (struct mwCipher *cipher, struct mwChannel *chan);
-
-
-/** Generate a descriptor for use in a channel create message to
-    indicate the availability of this cipher
-
-    @todo remove for 1.0
-*/
-typedef struct mwEncryptItem *(*mwCipherDescriptor)
-     (struct mwCipherInstance *instance);
-
-
-/** Process (encrypt or decrypt, depending) the given data. The passed
-    buffer may be freed in processing and be replaced with a freshly
-    allocated buffer. The post-processed buffer must in turn be freed
-    after use */
-typedef int (*mwCipherProcessor)
-     (struct mwCipherInstance *ci, struct mwOpaque *data);
-
-
-/** A cipher. Ciphers are primarily used to provide cipher instances
-    for bi-directional encryption on channels, but some may be used
-    for other activities. Expand upon this structure to create a
-    custom encryption provider.
-    @see mwCipherInstance */
-struct mwCipher {
-
-  /** service this cipher is providing for
-      @see mwCipher_getSession */
-  struct mwSession *session;
-
-  guint16 type;               /**< @see mwCipher_getType */
-  const char *(*get_name)(void);  /**< @see mwCipher_getName */
-  const char *(*get_desc)(void);  /**< @see mwCipher_getDesc */
-
-  /** Generate a new Cipher Instance for use on a channel
-      @see mwCipher_newInstance */
-  mwCipherInstantiator new_instance;
-
-  void (*offered)(struct mwCipherInstance *ci, struct mwEncryptItem *item);
-  struct mwEncryptItem *(*offer)(struct mwCipherInstance *ci);
-  void (*accepted)(struct mwCipherInstance *ci, struct mwEncryptItem *item);
-  struct mwEncryptItem *(*accept)(struct mwCipherInstance *ci);
-
-  mwCipherProcessor encrypt; /**< @see mwCipherInstance_encrypt */
-  mwCipherProcessor decrypt; /**< @see mwCipherInstance_decrypt */
-
-  /** prepare this cipher for being free'd
-      @see mwCipher_free */
-  void (*clear)(struct mwCipher *c);
-
-  /** clean up a cipher instance before being free'd
-      @see mwCipherInstance_free */
-  void (*clear_instance)(struct mwCipherInstance *ci);
-};
-
-
-/** An instance of a cipher. Expand upon this structure to contain
-    necessary state data
-    @see mwCipher */
-struct mwCipherInstance {
-
-  /** the parent cipher.
-      @see mwCipherInstance_getCipher */
-  struct mwCipher *cipher;
-
-  /** the channel this instances processes
-      @see mwCipherInstance_getChannel */
-  struct mwChannel *channel;
-};
-
-
-struct mwCipher *mwCipher_new_RC2_40(struct mwSession *s);
-
-
-struct mwCipher *mwCipher_new_RC2_128(struct mwSession *s);
-
-
-struct mwSession *mwCipher_getSession(struct mwCipher *cipher);
-
-
-guint16 mwCipher_getType(struct mwCipher *cipher);
-
-
-const char *mwCipher_getName(struct mwCipher *cipher);
-
-
-const char *mwCipher_getDesc(struct mwCipher *cipher);
-
-
-struct mwCipherInstance *mwCipher_newInstance(struct mwCipher *cipher,
-					      struct mwChannel *channel);
-
-
-/** destroy a cipher */
-void mwCipher_free(struct mwCipher* cipher);
-
-
-/** reference the parent cipher of an instance */
-struct mwCipher *mwCipherInstance_getCipher(struct mwCipherInstance *ci);
-
-
-/** Indicates a cipher has been offered to our channel */
-void mwCipherInstance_offered(struct mwCipherInstance *ci,
-			      struct mwEncryptItem *item);
-
-
-/** Offer a cipher */
-struct mwEncryptItem *
-mwCipherInstance_offer(struct mwCipherInstance *ci);
-
-
-/** Indicates an offered cipher has been accepted */
-void mwCipherInstance_accepted(struct mwCipherInstance *ci,
-			       struct mwEncryptItem *item);
-
-
-/** Accept a cipher offered to our channel */
-struct mwEncryptItem *
-mwCipherInstance_accept(struct mwCipherInstance *ci);
-
-
-/** encrypt data */
-int mwCipherInstance_encrypt(struct mwCipherInstance *ci,
-			     struct mwOpaque *data);
-
-
-/** decrypt data */
-int mwCipherInstance_decrypt(struct mwCipherInstance *ci,
-			     struct mwOpaque *data);
-
-
-/** destroy a cipher instance */
-void mwCipherInstance_free(struct mwCipherInstance *ci);
-
-
-/**
-  @section General Cipher Functions
-
-  These functions are reused where encryption is necessary outside of
-  a channel (eg. session authentication)
-*/
-/* @{ */
-
-
-/** generate some pseudo-random bytes
-    @param keylen  count of bytes to write into key
-    @param key     buffer to write keys into
-*/
-void mwKeyRandom(guchar *key, gsize keylen);
-
-
-/** Setup an Initialization Vector. IV must be at least 8 bytes */
-void mwIV_init(guchar *iv);
-
-
-/** Expand a variable-length key into a 128-byte key (represented as
-    an an array of 64 ints) */
-void mwKeyExpand(int *ekey, const guchar *key, gsize keylen);
-
-
-/** Encrypt data using an already-expanded key */
-void mwEncryptExpanded(const int *ekey, guchar *iv,
-		       struct mwOpaque *in,
-		       struct mwOpaque *out);
-
-
-/** Encrypt data using an expanded form of the given key */
-void mwEncrypt(const guchar *key, gsize keylen, guchar *iv,
-	       struct mwOpaque *in, struct mwOpaque *out);
-
-
-/** Decrypt data using an already expanded key */
-void mwDecryptExpanded(const int *ekey, guchar *iv,
-		       struct mwOpaque *in,
-		       struct mwOpaque *out);
-
-
-/** Decrypt data using an expanded form of the given key */
-void mwDecrypt(const guchar *key, gsize keylen, guchar *iv,
-	       struct mwOpaque *in, struct mwOpaque *out);
-
-
-/* @} */
-
-
-/**
-  @section Diffie-Hellman Functions
-
-  These functions are reused where DH Key negotiation is necessary
-  outside of a channel (eg. session authentication). These are
-  wrapping a full multiple-precision integer math library, but most of
-  the functionality there-of is not exposed. Currently, the math is
-  provided by a copy of the public domain libmpi.
-
-  for more information on the used MPI Library, visit
-  http://www.cs.dartmouth.edu/~sting/mpi/
-*/
-/* @{ */
-
-
-/** @struct mwMpi */
-struct mwMpi;
-
-
-/** prepare a new mpi value */
-struct mwMpi *mwMpi_new(void);
-
-
-/** destroy an mpi value */
-void mwMpi_free(struct mwMpi *i);
-
-
-/** Import a value from an opaque */
-void mwMpi_import(struct mwMpi *i, struct mwOpaque *o);
-
-
-/** Export a value into an opaque */
-void mwMpi_export(struct mwMpi *i, struct mwOpaque *o);
-
-
-/** initialize and set a big integer to the Sametime Prime value */
-void mwMpi_setDHPrime(struct mwMpi *i);
-
-
-/** initialize and set a big integer to the Sametime Base value */
-void mwMpi_setDHBase(struct mwMpi *i);
-
-
-/** sets private to a randomly generated value, and calculates public
-    using the Sametime Prime and Base */
-void mwMpi_randDHKeypair(struct mwMpi *private, struct mwMpi *public);
-
-
-/** sets the shared key value based on the remote and private keys,
-    using the Sametime Prime and Base */
-void mwMpi_calculateDHShared(struct mwMpi *shared, struct mwMpi *remote,
-			     struct mwMpi *private);
-
-
-/* @} */
-
-
-#endif
-
-
--- a/src/protocols/sametime/meanwhile/mw_client.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +0,0 @@
-
-#ifndef _MW_CLIENT_H
-#define _MW_CLIENT_H
-
-
-#include <glib.h>
-#include <glib/glist.h>
-
-
-/* place-holders */
-struct mwChannel;
-struct mwClient;
-struct mwClientHandler;
-struct mwConnection;
-struct mwConnectionHandler;
-struct mwMessage;
-struct mwService;
-struct mwSession;
-
-
-
-/* @file mw_client.h
-   
-*/
-
-
-
-/* @section Client
-
-*/
-/*@{*/
-
-
-struct mwClient;
-
-
-typedef (struct mwConnectionHandler *)(*mwClientConnect)
-     (struct mwClient *c, const char *host);
-
-
-struct mwClientHandler {
-  mwClientConnect connect;
-}
-
-
-struct mwClient *
-mwClient_new(struct mwClientHandler *h);
-
-
-struct mwChannel *
-mwClient_newChannel(struct mwClient *client,
-		    struct mwService *srvc);
-
-
-struct mwChannel *
-mwClient_newMasterChannel(struct mwClient *client,
-			  struct mwSession *session);
-
-
-int mwClient_sendKeepAlive(struct mwClient *client);
-
-
-void mwClient_setUsesCountByte(struct mwClient *client,
-			      gboolean use);
-
-
-gboolean mwClient_getUsesCountByte(struct mwClient *client);
-
-
-void mwClient_destroy(struct mwClient *client);
-
-
-/*@}*/
-
-
-
-/* @section Connection
-
-*/
-/*{*/
-
-
-struct mwConnection;
-
-
-typedef (int)(*mwConnectionWrite)
-     (struct mwConnection *c, const char *buf, gsize len);
-
-
-typedef (void)(*mwConnectionClose)
-     (struct mwConnection *c);
-
-
-struct mwConnectionHandler {
-  mwConnectionWrite write;
-  mwConnectionClose close;
-}
-
-
-struct mwConnection *
-mwConnection_new(struct mwConnectionHandler *h);
-
-
-void mwConnection_recv(struct mwConnection *connection,
-		       const char *buf,
-		       gsize len);
-
-
-void mwConnection_destroy(struct mwConnection *connection);
-
-
-/*@}*/
-
-
-
-/* @section Channel
-
-*/
-/*@{*/
-
-
-struct mwChannel;
-
-
-int mwChannel_sendMessage(struct mwChannel *channel,
-			  struct mwMessage *msg);
-
-
-int mwChannel_send(struct mwChannel *channel,
-		   guint32 type,
-		   guint32 options,
-		   struct mwOpaque *data);
-
-
-int mwChannel_destroy(struct mwChannel *channel,
-		      guint32 reason,
-		      struct mwOpaque *info);
-
-
-gboolean mwChannel_isMasterChannel(struct mwChannel *channel);
-
-
-guint32 mwChannel_getId(struct mwChannel *channel);
-
-
-enum mwChannelState mwChannel_getState(struct mwChannel *channel);
-
-
-
-/*@}*/
-
-
-
-#endif
--- a/src/protocols/sametime/meanwhile/mw_common.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,427 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_COMMON_H
-#define _MW_COMMON_H
-
-
-#include <glib.h>
-
-
-/** @file mw_common.h
-
-    Common data types and functions for handling those types.
-
-    Functions in this file all fit into similar naming conventions of
-    <code>TYPE_ACTION</code> as per the activity they perform. The
-    following actions are available:
-
-    <code>void TYPE_put(struct mwPutBuffer *b, TYPE *val)</code>
-    - marshalls val onto the buffer b. The buffer will grow as necessary
-    to fit all the data put into it. For guint16, guint32, and
-    gboolean, <code>TYPE val</code> is used instead of <code>TYPE
-    \*val</code>.
-
-    <code>void TYPE_get(struct mwGetBuffer *b, TYPE *val)</code>
-    - unmarshals val from the buffer b. Failure (due to lack of
-    insufficient remaining buffer) is indicated in the buffer's error
-    field. A call to a _get function with a buffer in an error state
-    has to effect.
-
-    <code>void TYPE_clear(TYPE *val)</code>
-    - zeros and frees internal members of val, but does not free val
-    itself. Needs to be called before free-ing any complex types which
-    have been unmarshalled from a TYPE_get or populated from a
-    TYPE_clone call to prevent memory leaks.
-
-    <code>void TYPE_clone(TYPE *to, TYPE *from)</code>
-    - copies/clones members of from into to. May result in memory
-    allocation for some types. Note that to is not cleared
-    before-hand, it must already be in a pristine condition.
-
-    <code>gboolean TYPE_equal(TYPE *y, TYPE *z)</code>
-    - simple equality test.
-*/
-
-
-/** @struct mwPutBuffer
-    buffer to be written to */
-struct mwPutBuffer;
-
-/** @struct mwGetBuffer
-    buffer to be read from */
-struct mwGetBuffer;
-
-
-/** A length of binary data, not null-terminated. */
-struct mwOpaque {
-  gsize len;     /**< length of data. */
-  guchar *data;  /**< data, normally with no NULL termination */
-};
-
-
-/* 8.3.6 Login Types */
-
-/** The type of login. Normally meaning the type of client code being
-    used to login with.
-
-    If you know of any additional client identifiers, please add them
-    below or submit an RFE to the meanwhile tracker.
-*/
-enum mwLoginType {
-  mwLogin_LIB           = 0x1000,  /**< official Lotus binary library */
-  mwLogin_JAVA_WEB      = 0x1001,  /**< official Lotus Java applet */
-  mwLogin_BINARY        = 0x1002,  /**< official Lotus binary application */
-  mwLogin_JAVA_APP      = 0x1003,  /**< official Lotus Java application */
-  mwLogin_LINKS         = 0x100a,  /**< official Sametime Links toolkit */
-
-  /* now we're getting crazy */
-  mwLogin_NOTES_6_5        = 0x1200,
-  mwLogin_NOTES_6_5_3      = 0x1203,
-  mwLogin_NOTES_7_0_beta   = 0x1210,
-  mwLogin_NOTES_7_0        = 0x1214,
-  mwLogin_ICT              = 0x1300,
-  mwLogin_ICT_1_7_8_2      = 0x1302,
-  mwLogin_ICT_SIP          = 0x1303,
-  mwLogin_NOTESBUDDY_4_14  = 0x1400,  /**< 0xff00 mask? */
-  mwLogin_NOTESBUDDY_4_15  = 0x1405,
-  mwLogin_NOTESBUDDY_4_16  = 0x1406,
-  mwLogin_SANITY           = 0x1600,
-  mwLogin_ST_PERL          = 0x1625,
-  mwLogin_PMR_ALERT        = 0x1650,
-  mwLogin_TRILLIAN         = 0x16aa,  /**< http://sf.net/st-plugin/ */
-  mwLogin_TRILLIAN_IBM     = 0x16bb,
-  mwLogin_MEANWHILE        = 0x1700,  /**< Meanwhile library */
-};
-
-
-/* 8.2 Common Structures */
-/* 8.2.1 Login Info block */
-
-struct mwLoginInfo {
-  char *login_id;   /**< community-unique ID of the login */
-  guint16 type;     /**< @see mwLoginType */
-  char *user_id;    /**< community-unique ID of the user */
-  char *user_name;  /**< name of user (nick name, full name, etc) */
-  char *community;  /**< community name (usually domain name) */
-  gboolean full;    /**< if FALSE, following fields non-existant */
-  char *desc;       /**< implementation defined description */
-  guint32 ip_addr;  /**< ip addr of the login */
-  char *server_id;  /**< unique ID of login's server */
-};
-
-
-/* 8.2.2 Private Info Block */
-
-struct mwUserItem {
-  gboolean full;    /**< if FALSE, don't include name */
-  char *id;         /**< user id */
-  char *community;  /**< community */
-  char *name;       /**< user name */
-};
-
-
-struct mwPrivacyInfo {
-  gboolean deny;             /**< deny (true) or allow (false) users */
-  guint32 count;             /**< count of users */
-  struct mwUserItem *users;  /**< the users list */
-};
-
-
-/* 8.3.5 User Status Types */
-
-enum mwStatusType {
-  mwStatus_ACTIVE  = 0x0020,
-  mwStatus_IDLE    = 0x0040,
-  mwStatus_AWAY    = 0x0060,
-  mwStatus_BUSY    = 0x0080,
-};
-
-
-/* 8.2.3 User Status Block */
-
-struct mwUserStatus {
-  guint16 status;  /**< @see mwStatusType */
-  guint32 time;    /**< last status change time in seconds */
-  char *desc;      /**< status description */
-};
-
-
-/* 8.2.4 ID Block */
-
-struct mwIdBlock {
-  char *user;       /**< user id (login id or empty for some services) */
-  char *community;  /**< community id (NULL for same community) */
-};
-
-
-/* 8.3.8.2 Awareness Presence Types */
-
-/* @todo move mwAwareType, mwAwareIdBlock and mwAwareSnapshot into the
-   aware service and out of common */
-
-/** type codes for mwAwareIdBlock */
-enum mwAwareType {
-  mwAware_USER    = 0x0002,  /**< a single user */
-  mwAware_GROUP   = 0x0003,  /**< a group */
-  mwAware_SERVER  = 0x0008,  /**< a server */
-};
-
-
-/* 8.4.2 Awareness Messages */
-/* 8.4.2.1 Awareness ID Block */
-
-struct mwAwareIdBlock {
-  guint16 type;     /**< @see mwAwareType */
-  char *user;       /**< user id */
-  char *community;  /**< community id (NULL for same community) */
-};
-
-
-/* 8.4.2.4 Snapshot */
-
-struct mwAwareSnapshot {
-  struct mwAwareIdBlock id;
-  char *group;                 /**< group this id belongs to */
-  gboolean online;             /**< is this user online? */
-  char *alt_id;                /**< alternate ID, often same as id.user */
-  struct mwUserStatus status;  /**< status of this user */
-  char *name;                  /**< Formatted version of ID */
-};
-
-
-/** encryption blocks */
-struct mwEncryptItem {
-  guint16 id;            /**< cipher identifier */
-  struct mwOpaque info;  /**< cipher information */
-};
-
-
-/** @name buffer utility functions */
-/*@{*/
-
-
-/** allocate a new empty buffer */
-struct mwPutBuffer *mwPutBuffer_new(void);
-
-
-/** write raw data to the put buffer */
-void mwPutBuffer_write(struct mwPutBuffer *b, gpointer data, gsize len);
-
-
-/** destroy the buffer */
-void mwPutBuffer_free(struct mwPutBuffer *b);
-
-
-/** move the buffer's data into an opaque, destroy the buffer */
-void mwPutBuffer_finalize(struct mwOpaque *to, struct mwPutBuffer *from);
-
-
-/** allocate a new buffer with a copy of the given data */
-struct mwGetBuffer *mwGetBuffer_new(struct mwOpaque *data);
-
-
-/** read len bytes of raw data from the get buffer into mem. If len is
-    greater than the count of bytes remaining in the buffer, the
-    buffer's error flag will NOT be set.
-
-    @returns count of bytes successfully copied to mem */
-gsize mwGetBuffer_read(struct mwGetBuffer *b, gpointer mem, gsize len);
-
-
-/** skip len bytes in the get buffer. If len is greater than the count
-    of bytes remaining in the buffer, the buffer's error flag will NOT
-    be set.
-
-    @returns count of bytes successfully skipped */
-gsize mwGetBuffer_advance(struct mwGetBuffer *b, gsize len);
-
-
-/** allocate a new buffer backed by the given data. Calling
-    mwGetBuffer_free will not result in the underlying data being
-    freed */
-struct mwGetBuffer *mwGetBuffer_wrap(const struct mwOpaque *data);
-
-
-/** destroy the buffer */
-void mwGetBuffer_free(struct mwGetBuffer *b);
-
-
-/** reset the buffer to the very beginning. Also clears the buffer's
-    error flag. */
-void mwGetBuffer_reset(struct mwGetBuffer *b);
-
-
-/** count of remaining available bytes */
-gsize mwGetBuffer_remaining(struct mwGetBuffer *b);
-
-
-/** TRUE if an error occurred while reading a basic type from this
-    buffer */
-gboolean mwGetBuffer_error(struct mwGetBuffer *b);
-
-
-/*@}*/
-
-
-/** @name Basic Data Type Marshalling
-    The basic types are combined to construct the complex types.
- */
-/*@{*/
-
-
-void guint16_put(struct mwPutBuffer *b, guint16 val);
-
-void guint16_get(struct mwGetBuffer *b, guint16 *val);
-
-guint16 guint16_peek(struct mwGetBuffer *b);
-
-
-void guint32_put(struct mwPutBuffer *b, guint32 val);
-
-void guint32_get(struct mwGetBuffer *b, guint32 *val);
-
-guint32 guint32_peek(struct mwGetBuffer *b);
-
-
-void gboolean_put(struct mwPutBuffer *b, gboolean val);
-
-void gboolean_get(struct mwGetBuffer *b, gboolean *val);
-
-gboolean gboolean_peek(struct mwGetBuffer *b);
-
-
-void mwString_put(struct mwPutBuffer *b, const char *str);
-
-void mwString_get(struct mwGetBuffer *b, char **str);
-
-
-void mwOpaque_put(struct mwPutBuffer *b, const struct mwOpaque *o);
-
-void mwOpaque_get(struct mwGetBuffer *b, struct mwOpaque *o);
-
-void mwOpaque_clear(struct mwOpaque *o);
-
-void mwOpaque_free(struct mwOpaque *o);
-
-void mwOpaque_clone(struct mwOpaque *to, const struct mwOpaque *from);
-
-
-/*@}*/
-
-
-/** @name Complex Data Type Marshalling */
-/*@{*/
-
-
-void mwLoginInfo_put(struct mwPutBuffer *b, const struct mwLoginInfo *info);
-
-void mwLoginInfo_get(struct mwGetBuffer *b, struct mwLoginInfo *info);
-
-void mwLoginInfo_clear(struct mwLoginInfo *info);
-
-void mwLoginInfo_clone(struct mwLoginInfo *to, const struct mwLoginInfo *from);
-
-
-void mwUserItem_put(struct mwPutBuffer *b, const struct mwUserItem *user);
-
-void mwUserItem_get(struct mwGetBuffer *b, struct mwUserItem *user);
-
-void mwUserItem_clear(struct mwUserItem *user);
-
-void mwUserItem_clone(struct mwUserItem *to, const struct mwUserItem *from);
-
-
-void mwPrivacyInfo_put(struct mwPutBuffer *b,
-		       const struct mwPrivacyInfo *info);
-
-void mwPrivacyInfo_get(struct mwGetBuffer *b, struct mwPrivacyInfo *info);
-
-void mwPrivacyInfo_clear(struct mwPrivacyInfo *info);
-
-void mwPrivacyInfo_clone(struct mwPrivacyInfo *to,
-			 const struct mwPrivacyInfo *from);
-
-
-void mwUserStatus_put(struct mwPutBuffer *b,
-		      const struct mwUserStatus *stat);
-
-void mwUserStatus_get(struct mwGetBuffer *b, struct mwUserStatus *stat);
-
-void mwUserStatus_clear(struct mwUserStatus *stat);
-
-void mwUserStatus_clone(struct mwUserStatus *to,
-			const struct mwUserStatus *from);
-
-
-void mwIdBlock_put(struct mwPutBuffer *b, const struct mwIdBlock *id);
-
-void mwIdBlock_get(struct mwGetBuffer *b, struct mwIdBlock *id);
-
-void mwIdBlock_clear(struct mwIdBlock *id);
-
-void mwIdBlock_clone(struct mwIdBlock *to,
-		     const struct mwIdBlock *from);
-
-guint mwIdBlock_hash(const struct mwIdBlock *idb);
-
-gboolean mwIdBlock_equal(const struct mwIdBlock *a,
-			 const struct mwIdBlock *b);
-
-
-void mwAwareIdBlock_put(struct mwPutBuffer *b,
-			const struct mwAwareIdBlock *idb);
-
-void mwAwareIdBlock_get(struct mwGetBuffer *b, struct mwAwareIdBlock *idb);
-
-void mwAwareIdBlock_clear(struct mwAwareIdBlock *idb);
-
-void mwAwareIdBlock_clone(struct mwAwareIdBlock *to,
-			  const struct mwAwareIdBlock *from);
-
-guint mwAwareIdBlock_hash(const struct mwAwareIdBlock *a);
-
-gboolean mwAwareIdBlock_equal(const struct mwAwareIdBlock *a,
-			      const struct mwAwareIdBlock *b);
-
-
-void mwAwareSnapshot_get(struct mwGetBuffer *b,
-			 struct mwAwareSnapshot *idb);
-
-void mwAwareSnapshot_clear(struct mwAwareSnapshot *idb);
-
-void mwAwareSnapshot_clone(struct mwAwareSnapshot *to,
-			   const struct mwAwareSnapshot *from);
-
-
-void mwEncryptItem_put(struct mwPutBuffer *b,
-		       const struct mwEncryptItem *item);
-
-void mwEncryptItem_get(struct mwGetBuffer *b, struct mwEncryptItem *item);
-
-void mwEncryptItem_clear(struct mwEncryptItem *item);
-
-void mwEncryptItem_free(struct mwEncryptItem *item);
-
-
-/*@}*/
-
-
-#endif
--- a/src/protocols/sametime/meanwhile/mw_debug.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-
-#include <glib/gstring.h>
-
-#include "mw_debug.h"
-
-
-
-#define FRMT1            "%02x"
-#define FRMT2            FRMT1 FRMT1 " "
-#define FRMT4            FRMT2 FRMT2
-#define FRMT8            FRMT4 FRMT4
-#define FRMT16           FRMT8 FRMT8
-
-#define ADVANCE(b, n, c)  {b += c; n -= c;}
-
-
-
-/** writes hex pairs of buf to str */
-static void pretty_print(GString *str, const guchar *buf, gsize len) {
-  while(len >= 16) {
-    /* write a complete line */
-    g_string_append_printf(str, FRMT16,
-			   buf[0],  buf[1],  buf[2],  buf[3],
-			   buf[4],  buf[5],  buf[6],  buf[7],
-			   buf[8],  buf[9],  buf[10], buf[11],
-			   buf[12], buf[13], buf[14], buf[15]);
-    ADVANCE(buf, len, 16);
-    
-    /* append \n to each line but the last */
-    if(len) g_string_append(str, "\n");
-  }
-
-  /* write an incomplete line */
-  if(len >= 8) {
-    g_string_append_printf(str, FRMT8,
-			   buf[0], buf[1], buf[2], buf[3],
-			   buf[4], buf[5], buf[6], buf[7]);
-    ADVANCE(buf, len, 8);
-  }
-  
-  if(len >= 4) {
-    g_string_append_printf(str, FRMT4,
-			   buf[0], buf[1], buf[2], buf[3]);
-    ADVANCE(buf, len, 4);
-  }
-
-  if(len >= 2) {
-    g_string_append_printf(str, FRMT2, buf[0], buf[1]);
-    ADVANCE(buf, len, 2);
-  }
-
-  if(len >= 1) {
-    g_string_append_printf(str, FRMT1, buf[0]);
-    ADVANCE(buf, len, 1);
-  }
-}
-
-
-
-void mw_debug_datav(const guchar *buf, gsize len,
-		    const char *msg, va_list args) {
-  GString *str;
-
-  g_return_if_fail(buf != NULL || len == 0);
-
-  str = g_string_new(NULL);
-
-  if(msg) {
-    char *txt = g_strdup_vprintf(msg, args);
-    g_string_append_printf(str, "%s\n", txt);
-    g_free(txt);
-  }
-  pretty_print(str, buf, len);
-
-  g_debug("%s", str->str);
-  g_string_free(str, TRUE);
-}
-
-
-
-void mw_debug_data(const guchar *buf, gsize len,
-		   const char *msg, ...) {
-  va_list args;
-  
-  g_return_if_fail(buf != NULL || len == 0);
-
-  va_start(args, msg);
-  mw_debug_datav(buf, len, msg, args);
-  va_end(args);
-}
-
-
-
-void mw_debug_opaquev(struct mwOpaque *o, const char *txt, va_list args) {
-  g_return_if_fail(o != NULL);
-  mw_debug_datav(o->data, o->len, txt, args);
-}
-
-
-
-void mw_debug_opaque(struct mwOpaque *o, const char *txt, ...) {
-  va_list args;
-
-  g_return_if_fail(o != NULL);
-
-  va_start(args, txt);
-  mw_debug_opaquev(o, txt, args);
-  va_end(args);
-}
-
-
-void mw_mailme_datav(const guchar *buf, gsize len,
-		     const char *info, va_list args) {
-
-#if defined(MW_MAILME) && MW_MAILME
-  GString *str;
-  char *txt;
-
-  str = g_string_new(MW_MAILME_MESSAGE "\n"
-		     "  Please send mail to: " MW_MAILME_ADDRESS "\n"
-		     MW_MAILME_CUT_START "\n");
-  str = g_string_new(NULL);
-
-  txt = g_strdup_vprintf(info, args);
-  g_string_append_printf(str, "%s\n", txt);
-  g_free(txt);
-
-  if(buf && len) pretty_print(str, buf, len);
-
-  g_string_append(str, MW_MAILME_CUT_STOP);
-
-  g_debug(str->str);
-  g_string_free(str, TRUE);
-
-#else
-  mw_debug_datav(buf, len, info, args);
-
-#endif
-}
-
-
-
-void mw_mailme_data(const guchar *buf, gsize len,
-		    const char *info, ...) {
-  va_list args;
-  va_start(args, info);
-  mw_mailme_datav(buf, len, info, args);
-  va_end(args);
-}
-
-
-
-void mw_mailme_opaquev(struct mwOpaque *o, const char *info, va_list args) {
-  mw_mailme_datav(o->data, o->len, info, args);
-}
-
-
-
-void mw_mailme_opaque(struct mwOpaque *o, const char *info, ...) {
-  va_list args;
-  va_start(args, info);
-  mw_mailme_opaquev(o, info, args);
-  va_end(args);
-}
--- a/src/protocols/sametime/meanwhile/mw_debug.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_DEBUG_H
-#define _MW_DEBUG_H
-
-
-#include <stdarg.h>
-#include <glib.h>
-
-#include "mw_common.h"
-
-
-/** replaces NULL strings with "(null)". useful for printf where
-    you're unsure that the %s will be non-NULL. Note that while the
-    linux printf will do this automatically, not all will. The others
-    will instead segfault */
-#define NSTR(str) ((str)? (str): "(null)")
-
-
-#ifndef g_debug
-#define g_debug(format...) g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
-#endif
-
-
-#ifndef g_info
-#define g_info(format...) g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
-#endif
-
-
-#ifndef MW_MAILME_ADDRESS
-/** email address used in mw_debug_mailme. */
-#define MW_MAILME_ADDRESS  "meanwhile-devel@lists.sourceforge.net"
-#endif
-
-
-#ifndef MW_MAILME_CUT_START
-#define MW_MAILME_CUT_START  "-------- begin copy --------"
-#endif
-
-
-#ifndef MW_MAILME_CUT_STOP
-#define MW_MAILME_CUT_STOP   "--------- end copy ---------"
-#endif
-
-
-#ifndef MW_MAILME_MESSAGE
-/** message used in mw_debug_mailme instructing user on what to do
-    with the debugging output produced from that function */
-#define MW_MAILME_MESSAGE "\n" \
- "  Greetings! It seems that you've run across protocol data that the\n" \
- "Meanwhile library does not yet know about. As such, there may be\n"    \
- "some unexpected behaviour in this session. If you'd like to help\n"    \
- "resolve this issue, please copy and paste the following block into\n"  \
- "an email to the address listed below with a brief explanation of\n"    \
- "what you were doing at the time of this message. Thanks a lot!"
-#endif
-
-
-void mw_debug_datav(const guchar *buf, gsize len,
-		    const char *info, va_list args);
-
-
-void mw_debug_data(const guchar *buf, gsize len,
-		   const char *info, ...);
-
-
-void mw_debug_opaquev(struct mwOpaque *o, const char *info, va_list args);
-
-
-void mw_debug_opaque(struct mwOpaque *o, const char *info, ...);
-
-
-void mw_mailme_datav(const guchar *buf, gsize len,
-		     const char *info, va_list args);
-
-void mw_mailme_data(const guchar *buf, gsize len,
-		    const char *info, ...);
-
-
-/** Outputs a hex dump of a mwOpaque with debugging info and a
-    pre-defined message. Identical to mw_mailme_opaque, but taking a
-    va_list argument */
-void mw_mailme_opaquev(struct mwOpaque *o, const char *info, va_list args);
-
-
-
-/** Outputs a hex dump of a mwOpaque with debugging info and a
-    pre-defined message.
-
-    if MW_MAILME is undefined or false, this function acts the same as
-    mw_mailme_opaque.
-
-    @arg block  data to be printed in a hex block
-    @arg info   a printf-style format string
-
-    The resulting message is in the following format:
-    @code
-    MW_MAILME_MESSAGE
-    " Please send mail to: " MW_MAILME_ADDRESS
-    MW_MAILME_CUT_START
-    info
-    block
-    MW_MAILME_CUT_STOP
-    @endcode
- */
-void mw_mailme_opaque(struct mwOpaque *o, const char *info, ...);
-
-
-#endif
-
--- a/src/protocols/sametime/meanwhile/mw_error.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_ERROR_H
-#define _MW_ERROR_H
-
-#include <glib.h>
-
-
-/** @file mw_error.h
-
-    Common error code constants used by Meanwhile.
-
-    Not all of these error codes (or even many, really) will ever
-    actually appear from Meanwhile. These are taken directly from the
-    houri draft, along with the minimal explanation for each.
-*/
-
-
-/** reference to a new string appropriate for the given error code.*/
-char* mwError(guint32 code);
-
-
-/* 8.3 Constants */
-/* 8.3.1 Error Codes */
-/* 8.3.1.1 General error/success codes */
-
-/** @enum ERR_GENERAL
-    general error codes */
-enum ERR_GENERAL {
-  ERR_SUCCESS                = 0x00000000,
-  ERR_FAILURE                = 0x80000000,
-  ERR_REQUEST_DELAY          = 0x00000001,
-  ERR_REQUEST_INVALID        = 0x80000001,
-  ERR_NOT_LOGGED_IN          = 0x80000002,
-  ERR_NOT_AUTHORIZED         = 0x80000003,
-  ERR_ABORT                  = 0x80000004,
-  ERR_NO_ELEMENT             = 0x80000005,
-  ERR_NO_USER                = 0x80000006,
-  ERR_BAD_DATA               = 0x80000007,
-  ERR_NOT_IMPLEMENTED        = 0x80000008,
-  ERR_UNKNOWN_ERROR          = 0x80000009, /* what is this? */
-  ERR_STARVING               = 0x8000000a,
-  ERR_CHANNEL_NO_SUPPORT     = 0x8000000b,
-  ERR_CHANNEL_EXISTS         = 0x8000000c,
-  ERR_SERVICE_NO_SUPPORT     = 0x8000000d,
-  ERR_PROTOCOL_NO_SUPPORT    = 0x8000000e,
-  ERR_PROTOCOL_NO_SUPPORT2   = 0x8000000f, /* duplicate? */
-  ERR_VERSION_NO_SUPPORT     = 0x80000010,
-  ERR_USER_SKETCHY           = 0x80000011,
-  ERR_ALREADY_INITIALIZED    = 0x80000013,
-  ERR_NOT_OWNER              = 0x80000014,
-  ERR_TOKEN_INVALID          = 0x80000015,
-  ERR_TOKEN_EXPIRED          = 0x80000016,
-  ERR_TOKEN_IP_MISMATCH      = 0x80000017,
-  ERR_PORT_IN_USE            = 0x80000018,
-  ERR_NETWORK_DEAD           = 0x80000019,
-  ERR_NO_MASTER_CHANNEL      = 0x8000001a,
-  ERR_ALREADY_SUBSCRIBED     = 0x8000001b,
-  ERR_NOT_SUBSCRIBED         = 0x8000001c,
-  ERR_ENCRYPT_NO_SUPPORT     = 0x8000001d,
-  ERR_ENCRYPT_UNINITIALIZED  = 0x8000001e,
-  ERR_ENCRYPT_UNACCEPTABLE   = 0x8000001f,
-  ERR_ENCRYPT_INVALID        = 0x80000020,
-  ERR_NO_COMMON_ENCRYPT      = 0x80000021,
-  ERR_CHANNEL_DESTROYED      = 0x80000022,
-  ERR_CHANNEL_REDIRECTED     = 0x80000023
-};
-
-
-/* 8.3.1.2 Connection/disconnection errors */
-
-#define VERSION_MISMATCH     0x80000200
-#define INSUF_BUFFER         0x80000201
-#define NOT_IN_USE           0x80000202
-#define INSUF_SOCKET         0x80000203
-#define HARDWARE_ERROR       0x80000204
-#define NETWORK_DOWN         0x80000205
-#define HOST_DOWN            0x80000206
-#define HOST_UNREACHABLE     0x80000207
-#define TCPIP_ERROR          0x80000208
-#define FAT_MESSAGE          0x80000209
-#define PROXY_ERROR          0x8000020A
-#define SERVER_FULL          0x8000020B
-#define SERVER_NORESPOND     0x8000020C
-#define CANT_CONNECT         0x8000020D
-#define USER_REMOVED         0x8000020E
-#define PROTOCOL_ERROR       0x8000020F
-#define USER_RESTRICTED      0x80000210
-#define INCORRECT_LOGIN      0x80000211
-#define ENCRYPT_MISMATCH     0x80000212
-#define USER_UNREGISTERED    0x80000213
-#define VERIFICATION_DOWN    0x80000214
-#define USER_TOO_IDLE        0x80000216
-#define GUEST_IN_USE         0x80000217
-#define USER_EXISTS          0x80000218
-#define USER_RE_LOGIN        0x80000219
-#define BAD_NAME             0x8000021A
-#define REG_MODE_NS          0x8000021B
-#define WRONG_USER_PRIV      0x8000021C
-#define NEED_EMAIL           0x8000021D
-#define DNS_ERROR            0x8000021E
-#define DNS_FATAL_ERROR      0x8000021F
-#define DNS_NOT_FOUND        0x80000220
-#define CONNECTION_BROKEN    0x80000221
-#define CONNECTION_ABORTED   0x80000222
-#define CONNECTION_REFUSED   0x80000223
-#define CONNECTION_RESET     0x80000224
-#define CONNECTION_TIMED     0x80000225
-#define CONNECTION_CLOSED    0x80000226
-#define MULTI_SERVER_LOGIN   0x80000227
-#define MULTI_SERVER_LOGIN2  0x80000228
-#define MULTI_LOGIN_COMP     0x80000229
-#define MUTLI_LOGIN_ALREADY  0x8000022A
-#define SERVER_BROKEN        0x8000022B
-#define SERVER_PATH_OLD      0x8000022C
-#define APPLET_LOGOUT        0x8000022D
-
-
-/* 8.3.1.3 Client error codes */
-
-/** @enum ERR_CLIENT
-    Client error codes */
-enum ERR_CLIENT {
-  ERR_CLIENT_USER_GONE       = 0x80002000, /* user isn't here */
-  ERR_CLIENT_USER_DND        = 0x80002001, /* user is DND */
-  ERR_CLIENT_USER_ELSEWHERE  = 0x80002002, /* already logged in elsewhere */
-};
-
-
-/* 8.3.1.4 IM error codes */
-
-/** @enum ERR_IM
-    IM error codes */
-enum ERR_IM {
-  ERR_IM_COULDNT_REGISTER    = 0x80002003,
-  ERR_IM_ALREADY_REGISTERED  = 0x80002004,
-
-  /** apparently, this is used to mean that the requested feature (per
-      the channel create addtl data) is not supported by the client on
-      the other end of the IM channel */
-  ERR_IM_NOT_REGISTERED      = 0x80002005,
-};
-
-
-#endif
--- a/src/protocols/sametime/meanwhile/mw_message.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,295 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_MESSAGE_H
-#define _MW_MESSAGE_H
-
-
-#include <glib/glist.h>
-#include "mw_common.h"
-
-
-/** Cast a pointer to a message subtype (eg, mwMsgHandshake,
-    mwMsgAdmin) into a pointer to a mwMessage */
-#define MW_MESSAGE(msg) (&msg->head)
-
-
-/** Indicates the type of a message. */
-enum mwMessageType {
-  mwMessage_HANDSHAKE         = 0x0000,  /**< mwMsgHandshake */
-  mwMessage_HANDSHAKE_ACK     = 0x8000,  /**< mwMsgHandshakeAck */
-  mwMessage_LOGIN             = 0x0001,  /**< mwMsgLogin */
-  mwMessage_LOGIN_ACK         = 0x8001,  /**< mwMsgLoginAck */
-  mwMessage_LOGIN_REDIRECT    = 0x0018,  /**< mwMsgLoginRedirect */
-  mwMessage_LOGIN_CONTINUE    = 0x0016,  /**< mwMsgLoginContinue */
-
-  mwMessage_CHANNEL_CREATE    = 0x0002,  /**< mwMsgChannelCreate */
-  mwMessage_CHANNEL_DESTROY   = 0x0003,  /**< mwMsgChannelDestroy */
-  mwMessage_CHANNEL_SEND      = 0x0004,  /**< mwMsgChannelSend */
-  mwMessage_CHANNEL_ACCEPT    = 0x0006,  /**< mwMsgChannelAccept */
-
-  mwMessage_SET_USER_STATUS   = 0x0009,  /**< mwMsgSetUserStatus */
-  mwMessage_SET_PRIVACY_LIST  = 0x000b,  /**< mwMsgSetPrivacyList */
-  mwMessage_SENSE_SERVICE     = 0x0011,  /**< mwMsgSenseService */
-  mwMessage_ADMIN             = 0x0019,  /**< mwMsgAdmin */
-  mwMessage_ANNOUNCE          = 0x0022,  /**< mwMsgAnnounce */
-};
-
-
-enum mwMessageOption {
-  mwMessageOption_ENCRYPT      = 0x4000,  /**< message data is encrypted */
-  mwMessageOption_HAS_ATTRIBS  = 0x8000,  /**< message has attributes */
-};
-
-
-/** @see mwMessageOption */
-#define MW_MESSAGE_HAS_OPTION(msg, opt) \
-  ((msg)->options & (opt))
-
-
-struct mwMessage {
-  guint16 type;     /**< @see mwMessageType */
-  guint16 options;  /**< @see mwMessageOption */
-  guint32 channel;  /**< ID of channel message is intended for */
-  struct mwOpaque attribs;  /**< optional message attributes */
-};
-
-
-
-/** Allocate and initialize a new message of the specified type */
-struct mwMessage *mwMessage_new(enum mwMessageType type);
-
-
-/** build a message from its representation */
-struct mwMessage *mwMessage_get(struct mwGetBuffer *b);
-
-
-void mwMessage_put(struct mwPutBuffer *b, struct mwMessage *msg);
-
-
-void mwMessage_free(struct mwMessage *msg);
-
-
-/* 8.4 Messages */
-/* 8.4.1 Basic Community Messages */
-/* 8.4.1.1 Handshake */
-
-struct mwMsgHandshake {
-  struct mwMessage head;
-  guint16 major;          /**< client's major version number */
-  guint16 minor;          /**< client's minor version number */
-  guint32 srvrcalc_addr;  /**< 0.0.0.0 */
-  guint16 login_type;     /**< @see mwLoginType */
-  guint32 loclcalc_addr;  /**< local public IP */
-  guint16 unknown_a;      /**< normally 0x0100 */
-  guint32 unknown_b;      /**< normally 0x00000000 */
-  char *local_host;       /**< name of client host */
-};
-
-
-/* 8.4.1.2 HandshakeAck */
-
-struct mwMsgHandshakeAck {
-  struct mwMessage head;
-  guint16 major;          /**< server's major version number */
-  guint16 minor;          /**< server's minor version number */
-  guint32 srvrcalc_addr;  /**< server-calculated address */
-  guint32 magic;          /**< four bytes of something */
-  struct mwOpaque data;   /**< server's DH public key for auth */
-};
-
-
-/* 8.3.7 Authentication Types */
-
-enum mwAuthType {
-  mwAuthType_PLAIN    = 0x0000,
-  mwAuthType_TOKEN    = 0x0001,
-  mwAuthType_ENCRYPT  = 0x0002, /**< @todo remove for 1.0 */
-  mwAuthType_RC2_40   = 0x0002,
-  mwAuthType_RC2_128  = 0x0004,
-};
-
-
-/* 8.4.1.3 Login */
-
-struct mwMsgLogin {
-  struct mwMessage head;
-  guint16 login_type;         /**< @see mwLoginType */
-  char *name;                 /**< user identification */
-  guint16 auth_type;          /**< @see mwAuthType */
-  struct mwOpaque auth_data;  /**< authentication data */
-};
-
-
-/* 8.4.1.4 LoginAck */
-
-struct mwMsgLoginAck {
-  struct mwMessage head;
-  struct mwLoginInfo login;
-  struct mwPrivacyInfo privacy;
-  struct mwUserStatus status;
-};
-
-
-/* 8.4.1.5 LoginCont */
-
-struct mwMsgLoginContinue {
-  struct mwMessage head;
-};
-
-
-/* 8.4.1.6 AuthPassed */
-
-struct mwMsgLoginRedirect {
-  struct mwMessage head;
-  char *host;
-  char *server_id;
-};
-
-
-/* 8.4.1.7 CreateCnl */
-
-/** an offer of encryption items */
-struct mwEncryptOffer {
-  guint16 mode;   /**< encryption mode */
-  GList *items;   /**< list of mwEncryptItem offered */
-  guint16 extra;  /**< encryption mode again? */
-  gboolean flag;  /**< unknown flag */
-};
-
-
-struct mwMsgChannelCreate {
-  struct mwMessage head;
-  guint32 reserved;         /**< unknown reserved data */
-  guint32 channel;          /**< intended ID for new channel */
-  struct mwIdBlock target;  /**< User ID. for service use */
-  guint32 service;          /**< ID for the target service */
-  guint32 proto_type;       /**< protocol type for the service */
-  guint32 proto_ver;        /**< protocol version for the service */
-  guint32 options;          /**< options */
-  struct mwOpaque addtl;    /**< service-specific additional data */
-  gboolean creator_flag;    /**< indicate presence of creator information */
-  struct mwLoginInfo creator;
-  struct mwEncryptOffer encrypt;
-};
-
-
-/* 8.4.1.8 AcceptCnl */
-
-/** a selected encryption item from those offered */
-struct mwEncryptAccept {
-  guint16 mode;                /**< encryption mode */
-  struct mwEncryptItem *item;  /**< chosen mwEncryptItem (optional) */
-  guint16 extra;               /**< encryption mode again? */
-  gboolean flag;               /**< unknown flag */
-};
-
-
-struct mwMsgChannelAccept {
-  struct mwMessage head;
-  guint32 service;         /**< ID for the channel's service */
-  guint32 proto_type;      /**< protocol type for the service */
-  guint32 proto_ver;       /**< protocol version for the service */
-  struct mwOpaque addtl;   /**< service-specific additional data */
-  gboolean acceptor_flag;  /**< indicate presence of acceptor information */
-  struct mwLoginInfo acceptor;
-  struct mwEncryptAccept encrypt;
-};
-
-
-/* 8.4.1.9 SendOnCnl */
-
-struct mwMsgChannelSend {
-  struct mwMessage head;
-
-  /** message type. each service defines its own send types. Type IDs
-      are only necessarily unique within a given service. */
-  guint16 type;
-
-  /** protocol data to be interpreted by the handling service */
-  struct mwOpaque data;
-};
-
-
-/* 8.4.1.10 DestroyCnl */
-
-struct mwMsgChannelDestroy {
-  struct mwMessage head;
-  guint32 reason;        /**< reason for closing the channel. */
-  struct mwOpaque data;  /**< additional information */
-};
-
-
-/* 8.4.1.11 SetUserStatus */
-
-struct mwMsgSetUserStatus {
-  struct mwMessage head;
-  struct mwUserStatus status;
-};
-
-
-/* 8.4.1.12 SetPrivacyList */
-
-struct mwMsgSetPrivacyList {
-  struct mwMessage head;
-  struct mwPrivacyInfo privacy;
-};
-
-
-/* Sense Service */
-
-/** Sent to the server to request the presense of a service by its
-    ID. Sent to the client to indicate the presense of such a
-    service */
-struct mwMsgSenseService {
-  struct mwMessage head;
-  guint32 service;
-};
-
-
-/* Admin */
-
-/** An administrative broadcast message */
-struct mwMsgAdmin {
-  struct mwMessage head;
-  char *text;
-};
-
-
-/* Announce */
-
-/** An announcement between users */
-struct mwMsgAnnounce {
-  struct mwMessage head;
-  gboolean sender_present;    /**< indicates presence of sender data */
-  struct mwLoginInfo sender;  /**< who sent the announcement */
-  guint16 unknown_a;          /**< unknown A. Usually 0x00 */
-  gboolean may_reply;         /**< replies allowed */
-  char *text;                 /**< text of message */
-
-  /** list of (char *) indicating recipients. Recipient users are in
-      the format "@U username" and recipient NAB groups are in the
-      format "@G groupname" */
-  GList *recipients;
-};
-
-
-#endif
-
--- a/src/protocols/sametime/meanwhile/mw_service.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,360 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_SERVICE_H
-#define _MW_SERVICE_H
-
-
-#include "mw_common.h"
-
-
-/* place-holders */
-struct mwChannel;
-struct mwService;
-struct mwSession;
-struct mwMsgChannelCreate;
-struct mwMsgChannelAccept;
-struct mwMsgChannelDestroy;
-
-
-/** State-tracking for a service */
-enum mwServiceState {
-  mwServiceState_STOPPED,   /**< the service is not active */
-  mwServiceState_STOPPING,  /**< the service is shutting down */
-  mwServiceState_STARTED,   /**< the service is active */
-  mwServiceState_STARTING,  /**< the service is starting up */
-  mwServiceState_ERROR,     /**< error in service, shutting down */
-  mwServiceState_UNKNOWN,   /**< error determining state */
-};
-
-
-/** Casts a concrete service (such as mwServiceAware) into a mwService */
-#define MW_SERVICE(srv) ((struct mwService *) srv)
-
-
-#define MW_SERVICE_IS_STATE(srvc, state) \
-  (mwService_getState(MW_SERVICE(srvc)) == (state))
-
-#define MW_SERVICE_IS_STOPPED(srvc)  \
-  MW_SERVICE_IS_STATE(srvc, mwServiceState_STOPPED)
-
-#define MW_SERVICE_IS_STOPPING(srvc) \
-  MW_SERVICE_IS_STATE(srvc, mwServiceState_STOPPING)
-
-#define MW_SERVICE_IS_STARTED(srvc)  \
-  MW_SERVICE_IS_STATE(srvc, mwServiceState_STARTED)
-
-#define MW_SERVICE_IS_STARTING(srvc) \
-  MW_SERVICE_IS_STATE(srvc, mwServiceState_STARTING)
-
-
-/** If a service is STARTING or STARTED, it's considered LIVE */
-#define MW_SERVICE_IS_LIVE(srvc) \
-  (MW_SERVICE_IS_STARTING(srvc) || MW_SERVICE_IS_STARTED(srvc))
-
-/** If a service is STOPPING or STOPPED, it's considered DEAD */
-#define MW_SERVICE_IS_DEAD(srvc) \
-  (MW_SERVICE_IS_STOPPING(srvc) || MW_SERVICE_IS_STOPPED(srvc))
-
-
-typedef void (*mwService_funcStart)(struct mwService *service);
-
-typedef void (*mwService_funcStop)(struct mwService *service);
-
-typedef void (*mwService_funcClear)(struct mwService *service);
-
-typedef const char *(*mwService_funcGetName)(struct mwService *service);
-
-typedef const char *(*mwService_funcGetDesc)(struct mwService *service);
-
-/** @todo remove msg and replace with appropriate additional parameters */
-typedef void (*mwService_funcRecvCreate)
-     (struct mwService *service,
-      struct mwChannel *channel,
-      struct mwMsgChannelCreate *msg);
-
-/** @todo remove msg and replace with appropriate additional parameters */
-typedef void (*mwService_funcRecvAccept)
-     (struct mwService *service,
-      struct mwChannel *channel,
-      struct mwMsgChannelAccept *msg);
-
-/** @todo remove msg and replace with appropriate additional parameters */
-typedef void (*mwService_funcRecvDestroy)
-     (struct mwService *service,
-      struct mwChannel *channel,
-      struct mwMsgChannelDestroy *msg);
-
-typedef void (*mwService_funcRecv)
-     (struct mwService *service,
-      struct mwChannel *channel,
-      guint16 msg_type,
-      struct mwOpaque *data);
-
-
-/** A service is the recipient of sendOnCnl messages sent over
-    channels marked with the corresponding service id. Services
-    provide functionality such as IM relaying, Awareness tracking and
-    notification, and Conference handling.  It is a service's
-    responsibility to accept or destroy channels, and to process data
-    sent over those channels */
-struct mwService {
-
-  /** the unique identifier by which this service is registered. The
-      type value also relates to those channels which will be directed
-      to this service */
-  guint32 type;
-
-  /** the state of this service. Determines whether or not the session
-      should call the start function upon receipt of a service
-      available message. Should not be set or checked by hand.
-
-      @relates mwService_getState */
-  enum mwServiceState state;
-
-  /** session this service is attached to.
-      @relates mwService_getSession */
-  struct mwSession *session;
-
-  /** @return string short name of the service
-      @relates mwService_getName */
-  mwService_funcGetName get_name;
-
-  /** @return string short description of the service
-      @relates mwService_getDesc */
-  mwService_funcGetDesc get_desc;
-
-  /** The service's channel create handler. Called when the session
-      receives a channel create message with a service matching this
-      service's type.
-
-      @relates mwService_recvCreate */
-  mwService_funcRecvCreate recv_create;
-
-  /** The service's channel accept handler. Called when the session
-      receives a channel accept message for a channel with a service
-      matching this service's type.
-
-      @relates mwService_recvAccept */
-  mwService_funcRecvAccept recv_accept;
-
-  /** The service's channel destroy handler. Called when the session
-      receives a channel destroy message for a channel with a service
-      matching this service's type.
-
-      @relates mwService_recvDestroy */
-  mwService_funcRecvDestroy recv_destroy;
-
-  /** The service's input handler. Called when the session receives
-      data on a channel belonging to this service
-
-      @relates mwService_recv */
-  mwService_funcRecv recv;
-
-  /** The service's start handler. Called upon the receipt of a
-      service available message.
-
-      @relates mwService_start */
-  mwService_funcStart start;
-
-  /** The service's stop handler. Called when the session is shutting
-      down, or when the service is free'd.
-
-      @relates mwService_stop */
-  mwService_funcStop stop;
-  
-  /** The service's cleanup handler. Service implementations should
-      presume that mwService::stop will be called first. The clear
-      handler is not for shutting down channels or generating
-      non-cleanup side-effects, it is only for handling tear-down of
-      the service, and will only be called once for any instance.
-
-      @relates mwService_free */
-  mwService_funcClear clear;
-
-  /** Optional client data, not for use by service implementations
-
-      @relates mwService_getClientData
-      @relates mwService_setClientData */
-  gpointer client_data;
-
-  /** Optional client data cleanup function. Called with client_data
-      from mwService_free
-
-      @relates mwService_getClientData
-      @relates mwService_setClientData */
-  GDestroyNotify client_cleanup;
-};
-
-
-/** @name Service Extension API
-
-    These functions are for use by service implementations */
-/*@{*/
-
-
-/** Prepares a newly allocated service for use.
-    
-    Intended for use by service implementations, rather than by code
-    utilizing a service.
-    
-    The service state will be initialized to STOPPED.
-    
-    @param service       the service to initialize
-    @param session       the service's owning session
-    @param service_type  the service ID number */
-void mwService_init(struct mwService *service,
-		    struct mwSession *session,
-		    guint32 service_type);
-
-
-/** Indicate that a service is started. To be used by service
-    implementations when the service is fully started. */
-void mwService_started(struct mwService *service);
-
-
-/** Indicate that a service is stopped. To be used by service
-    implementations when the service is fully stopped. */
-void mwService_stopped(struct mwService *service);
-
-
-/*@}*/
-
-
-/** @name General Services API
-
-    These functions provide unified access to the general functions of
-    a client service, with some simple sanity-checking. */
-/*@{*/
-
-
-/** Triggers the recv_create handler on the service.
-
-    @param service  the service to handle the message
-    @param channel  the channel being created
-    @param msg      the channel create message */
-void mwService_recvCreate(struct mwService *service,
-			  struct mwChannel *channel,
-			  struct mwMsgChannelCreate *msg);
-
-
-/** Triggers the recv_accept handler on the service.
-
-    @param service  the service to handle the message
-    @param channel  the channel being accepted
-    @param msg      the channel accept message */
-void mwService_recvAccept(struct mwService *service,
-			  struct mwChannel *channel,
-			  struct mwMsgChannelAccept *msg);
-
-
-/** Triggers the recv_destroy handler on the service.
-
-    @param service  the service to handle the message
-    @param channel  the channel being destroyed
-    @param msg      the channel destroy message */
-void mwService_recvDestroy(struct mwService *service,
-			   struct mwChannel *channel,
-			   struct mwMsgChannelDestroy *msg);
-
-
-/** Triggers the input handler on the service
-
-    @param service   the service to receive the input
-    @param channel   the channel the input was received from
-    @param msg_type  the service-dependant message type
-    @param data      the message data */
-void mwService_recv(struct mwService *service,
-		    struct mwChannel *channel,
-		    guint16 msg_type,
-		    struct mwOpaque *data);
-
-
-/** @return the appropriate type id for the service */
-guint32 mwService_getType(struct mwService *);
-
-
-/** @return string short name of the service */
-const char *mwService_getName(struct mwService *);
-
-
-/** @return string short description of the service */
-const char *mwService_getDesc(struct mwService *);
-
-
-/** @return the service's session */
-struct mwSession *mwService_getSession(struct mwService *service);
-
-
-/** @returns the service's state
-*/
-enum mwServiceState mwService_getState(struct mwService *service);
-
-
-/** Triggers the start handler for the service. Normally called from
-    the session upon receipt of a service available message. Service
-    implementations should use this handler to open any necessary
-    channels, etc. Checks that the service is STOPPED, or returns.
-    
-    @param service The service to start
-*/
-void mwService_start(struct mwService *service);
-
-
-/** Triggers the stop handler for the service. Normally called from
-    the session before closing down the connection. Checks that the
-    service is STARTED or STARTING, or returns
-
-    @param service The service to stop
-*/
-void mwService_stop(struct mwService *service);
-
-
-/** Frees memory used by a service. Will trigger the stop handler if
-    the service is STARTED or STARTING. Triggers clear handler to allow
-    cleanup.
-
-    @param service The service to clear and free
-*/
-void mwService_free(struct mwService *service);
-
-
-/** Associates client data with service. If there is existing data, it
-    will not have its cleanup function called. Client data is not for
-    use by service implementations. Rather, it is for use by client
-    code which may later make use of those service implementations. */
-void mwService_setClientData(struct mwService *service,
-			     gpointer data, GDestroyNotify cleanup);
-
-
-/** Reference associated client data */
-gpointer mwService_getClientData(struct mwService *service);
-
-
-/** Removes client data from service. If there is a cleanup function,
-    it will be called. */
-void mwService_removeClientData(struct mwService *service);
-
-
-/*@}*/
-
-
-#endif
-
--- a/src/protocols/sametime/meanwhile/mw_session.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,387 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_SESSION_H
-#define _MW_SESSION_H
-
-
-/** @file mw_session.h
-
-    A client session with a Sametime server is encapsulated in the
-    mwSession structure. The session controls channels, provides
-    encryption ciphers, and manages services using messages over the
-    Master channel.
-
-    A session does not directly communicate with a socket or stream,
-    instead the session is initialized from client code with an
-    instance of a mwSessionHandler structure. This session handler
-    provides functions as call-backs for common session events, and
-    provides functions for writing-to and closing the connection to
-    the server.
-
-    A session does not perform reads on a socket directly. Instead, it
-    must be fed from an outside source via the mwSession_recv
-    function. The session will buffer and merge data passed to this
-    function to build complete protocol messages, and will act upon
-    each complete message accordingly.
-*/
-
-
-#include "mw_common.h"
-
-
-struct mwChannelSet;
-struct mwCipher;
-struct mwMessage;
-struct mwService;
-
-
-/** default protocol major version */
-#define MW_PROTOCOL_VERSION_MAJOR  0x001e
-
-
-/** default protocol minor version */
-#define MW_PROTOCOL_VERSION_MINOR  0x001d
-
-
-/** @section Session Properties
-    for use with mwSession_setProperty, et al.
-*/
-/*@{*/
-
-/** char *, session user ID */
-#define mwSession_AUTH_USER_ID      "session.auth.user"
-
-/** char *, plaintext password */
-#define mwSession_AUTH_PASSWORD     "session.auth.password"
-
-/** struct mwOpaque *, authentication token */
-#define mwSession_AUTH_TOKEN        "session.auth.token"
-
-/** char *, hostname of client */
-#define mwSession_CLIENT_HOST       "client.host"
-
-/** guint32, local IP of client */
-#define mwSession_CLIENT_IP         "client.ip"
-
-/** guint16, major version of client protocol */
-#define mwSession_CLIENT_VER_MAJOR  "client.version.major"
-
-/** guint16, minor version of client protocol */
-#define mwSession_CLIENT_VER_MINOR  "client.version.minor"
-
-/** guint16, client type identifier */
-#define mwSession_CLIENT_TYPE_ID    "client.id"
-
-/** guint16, major version of server protocol */
-#define mwSession_SERVER_VER_MAJOR  "server.version.major"
-
-/** guint16, minor version of server protocol */
-#define mwSession_SERVER_VER_MINOR  "server.version.minor"
-
-/*@}*/
-
-
-enum mwSessionState {
-  mwSession_STARTING,      /**< session is starting */
-  mwSession_HANDSHAKE,     /**< session has sent handshake */
-  mwSession_HANDSHAKE_ACK, /**< session has received handshake ack */
-  mwSession_LOGIN,         /**< session has sent login */
-  mwSession_LOGIN_REDIR,   /**< session has been redirected */
-  mwSession_LOGIN_ACK,     /**< session has received login ack */
-  mwSession_STARTED,       /**< session is active */
-  mwSession_STOPPING,      /**< session is shutting down */
-  mwSession_STOPPED,       /**< session is stopped */
-  mwSession_UNKNOWN,       /**< indicates an error determining state */
-  mwSession_LOGIN_CONT,    /**< session has sent a login continue */
-};
-
-
-#define mwSession_isState(session, state) \
-  (mwSession_getState((session)) == (state))
-
-#define mwSession_isStarting(s) \
-  (mwSession_isState((s), mwSession_STARTING)  || \
-   mwSession_isState((s), mwSession_HANDSHAKE) || \
-   mwSession_isState((s), mwSession_HANDSHAKE_ACK) || \
-   mwSession_isState((s), mwSession_LOGIN) || \
-   mwSession_isState((s), mwSession_LOGIN_ACK) || \
-   mwSession_isState((s), mwSession_LOGIN_REDIR) || \
-   mwSession_isState((s), mwSession_LOGIN_CONT))
-
-#define mwSession_isStarted(s) \
-  (mwSession_isState((s), mwSession_STARTED))
-
-#define mwSession_isStopping(s) \
-  (mwSession_isState((s), mwSession_STOPPING))
-
-#define mwSession_isStopped(s) \
-  (mwSession_isState((s), mwSession_STOPPED))
-
-
-/** @struct mwSession
-
-    Represents a Sametime client session */
-struct mwSession;
-
-
-/** @struct mwSessionHandler
-
-    session handler. Structure which interfaces a session with client
-    code to provide I/O and event handling */
-struct mwSessionHandler {
-  
-  /** write data to the server connection. Required. Should return
-      zero for success, non-zero for error */
-  int (*io_write)(struct mwSession *, const guchar *buf, gsize len);
-  
-  /** close the server connection. Required */
-  void (*io_close)(struct mwSession *);
-
-  /** triggered by mwSession_free. Optional. Put cleanup code here */
-  void (*clear)(struct mwSession *);
-
-  /** Called when the session has changed status.
-
-      @see mwSession_getStateInfo for uses of info field
-
-      @param s      the session
-      @param state  the session's state
-      @param info   additional state information */
-  void (*on_stateChange)(struct mwSession *s,
-			 enum mwSessionState state, gpointer info);
-
-  /** called when privacy information has been sent or received
-
-      @see mwSession_getPrivacyInfo
-  */
-  void (*on_setPrivacyInfo)(struct mwSession *);
-
-  /** called when user status has changed
-
-      @see mwSession_getUserStatus */
-  void (*on_setUserStatus)(struct mwSession *);
-
-  /** called when an admin messages has been received */
-  void (*on_admin)(struct mwSession *, const char *text);
-
-  /** called when an announcement arrives */
-  void (*on_announce)(struct mwSession *, struct mwLoginInfo *from,
-		      gboolean may_reply, const char *text);
-
-};
-
-
-/** allocate a new session */
-struct mwSession *mwSession_new(struct mwSessionHandler *);
-
-
-/** stop, clear, free a session. Does not free contained ciphers or
-    services, these must be taken care of explicitly. */
-void mwSession_free(struct mwSession *);
-
-
-/** obtain a reference to the session's handler */
-struct mwSessionHandler *mwSession_getHandler(struct mwSession *);
-
-
-/** instruct the session to begin. This will result in the initial
-    handshake message being sent. */
-void mwSession_start(struct mwSession *);
-
-
-/** instruct the session to shut down with the following reason
-    code. */
-void mwSession_stop(struct mwSession *, guint32 reason);
-
-
-/** Data is buffered, unpacked, and parsed into a message, then
-    processed accordingly. */
-void mwSession_recv(struct mwSession *, const guchar *, gsize);
-
-
-/** primarily used by services to have messages serialized and sent
-    @param s    session to send message over
-    @param msg  message to serialize and send
-    @returns    0 for success */
-int mwSession_send(struct mwSession *s, struct mwMessage *msg);
-
-
-/** sends the keepalive byte */
-int mwSession_sendKeepalive(struct mwSession *s);
-
-
-/** respond to a login redirect message by forcing the login sequence
-    to continue through the immediate server. */
-int mwSession_forceLogin(struct mwSession *s);
-
-
-/** send an announcement to a list of users/groups. Targets of
-    announcement must be in the same community as the session.
-
-    @param s          session to send announcement from
-    @param may_reply  permit clients to reply. Not all clients honor this.
-    @param text       text of announcement
-    @param recipients list of recipients. Each recipient is specified
-                      by a single string, prefix with "@U " for users
-                      and "@G " for Notes Address Book groups.
-*/
-int mwSession_sendAnnounce(struct mwSession *s, gboolean may_reply,
-			   const char *text, const GList *recipients);
-
-
-/** set the internal privacy information, and inform the server as
-    necessary. Triggers the on_setPrivacyInfo call-back. */
-int mwSession_setPrivacyInfo(struct mwSession *, struct mwPrivacyInfo *);
-
-
-/** direct reference to the session's internal privacy structure */
-struct mwPrivacyInfo *mwSession_getPrivacyInfo(struct mwSession *);
-
-
-/** reference the login information for the session */
-struct mwLoginInfo *mwSession_getLoginInfo(struct mwSession *);
-
-
-/** set the internal user status state, and inform the server as
-    necessary. Triggers the on_setUserStatus call-back */
-int mwSession_setUserStatus(struct mwSession *, struct mwUserStatus *);
-
-
-struct mwUserStatus *mwSession_getUserStatus(struct mwSession *);
-
-
-/** current status of the session */
-enum mwSessionState mwSession_getState(struct mwSession *);
-
-
-/** additional status-specific information. Depending on the state of
-    the session, this value has different meaning.
-
-    @li @c mwSession_STOPPING guint32 error code causing
-    the session to shut down
-
-    @li @c mwSession_STOPPED guint32 error code causing
-    the session to shut down
-
-    @li @c mwSession_LOGIN_REDIR (char *) host to redirect
-    to
-*/
-gpointer mwSession_getStateInfo(struct mwSession *);
-
-
-struct mwChannelSet *mwSession_getChannels(struct mwSession *);
-
-
-/** adds a service to the session. If the session is started (or when
-    the session is successfully started) and the service has a start
-    function, the session will request service availability from the
-    server. On receipt of the service availability notification, the
-    session will call the service's start function.
-
-    @return TRUE if the session was added correctly */
-gboolean mwSession_addService(struct mwSession *, struct mwService *);
-
-
-/** find a service by its type identifier */
-struct mwService *mwSession_getService(struct mwSession *, guint32 type);
-
-
-/** removes a service from the session. If the session is started and
-    the service has a stop function, it will be called. Returns the
-    removed service */
-struct mwService *mwSession_removeService(struct mwSession *, guint32 type);
-
-
-/** a GList of services in this session. The GList needs to be freed
-    after use */
-GList *mwSession_getServices(struct mwSession *);
-
-
-/** instruct a STARTED session to check the server for the presense of
-    a given service. The service will be automatically started upon
-    receipt of an affirmative reply from the server. This function is
-    automatically called upon all services in a session when the
-    session is fully STARTED.
-
-    Services which terminate due to an error may call this on
-    themselves to re-initialize when their server-side counterpart is
-    made available again.
-
-    @param s     owning session
-    @param type  service type ID */
-void mwSession_senseService(struct mwSession *s, guint32 type);
-
-
-/** adds a cipher to the session. */
-gboolean mwSession_addCipher(struct mwSession *, struct mwCipher *);
-
-
-/** find a cipher by its type identifier */
-struct mwCipher *mwSession_getCipher(struct mwSession *, guint16 type);
-
-
-/** remove a cipher from the session */
-struct mwCipher *mwSession_removeCipher(struct mwSession *, guint16 type);
-
-
-/** a GList of ciphers in this session. The GList needs to be freed
-    after use */
-GList *mwSession_getCiphers(struct mwSession *);
-
-
-/** associate a key:value pair with the session. If an existing value is
-    associated with the same key, it will have its clear function called
-    and will be replaced with the new value */
-void mwSession_setProperty(struct mwSession *, const char *key,
-			   gpointer val, GDestroyNotify clear);
-
-
-/** obtain the value of a previously set property, or NULL */
-gpointer mwSession_getProperty(struct mwSession *, const char *key);
-
-
-/** remove a property, calling the optional GDestroyNotify function
-    indicated in mwSession_setProperty if applicable */
-void mwSession_removeProperty(struct mwSession *, const char *key);
-
-
-/** associate arbitrary data with the session for use by the client
-    code. Only client applications should use this, never services.
-
-    @param session  the session to associate the data with
-    @param data     arbitrary client data
-    @param clear    optional cleanup function called on data from
-                    mwSession_removeClientData and mwSession_free
-*/
-void mwSession_setClientData(struct mwSession *session,
-			     gpointer data, GDestroyNotify clear);
-
-
-gpointer mwSession_getClientData(struct mwSession *session);
-
-
-/** remove client data, calling the optional GDestroyNotify function
-    indicated in mwSession_setClientData if applicable */
-void mwSession_removeClientData(struct mwSession *session);
-
-
-#endif
-
--- a/src/protocols/sametime/meanwhile/mw_srvc_aware.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,270 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_SRVC_AWARE_H
-#define _MW_SRVC_AWARE_H
-
-
-#include "mw_common.h"
-
-
-/** @file mw_srvc_aware.h
-
-    The aware service...
-
-    @todo remove the whole idea of an instantiated mwAwareList and
-    instead use arbitrary pointers (including NULL) as keys to
-    internally stored lists. This removes the problem of the service
-    free'ing its lists and invalidating mwAwareList references from
-    client code.
-*/
-
-
-/** Type identifier for the aware service */
-#define mwService_AWARE  0x00000011
-
-
-/** @struct mwServiceAware
-
-    Instance of an Aware Service. The members of this structure are
-    not made available. Accessing the parts of an aware service should
-    be performed through the appropriate functions. Note that
-    instances of this structure can be safely cast to a mwService.
-*/
-struct mwServiceAware;
-
-
-/** @struct mwAwareList
-
-    Instance of an Aware List. The members of this structure are not
-    made available. Access to the parts of an aware list should be
-    handled through the appropriate functions.
-
-    Any references to an aware list are rendered invalid when the
-    parent service is free'd
-*/
-struct mwAwareList;
-
-
-/** @struct mwAwareAttribute
-
-    Key/Opaque pair indicating an identity's attribute.
- */
-struct mwAwareAttribute;
-
-
-/** Predefined keys appropriate for a mwAwareAttribute
- */
-enum mwAwareAttributeKeys {
-  mwAttribute_AV_PREFS_SET   = 0x01, /**< A/V prefs specified, gboolean */
-  mwAttribute_MICROPHONE     = 0x02, /**< has a microphone, gboolean */
-  mwAttribute_SPEAKERS       = 0x03, /**< has speakers, gboolean */
-  mwAttribute_VIDEO_CAMERA   = 0x04, /**< has a video camera, gboolean */
-  mwAttribute_FILE_TRANSFER  = 0x06, /**< supports file transfers, gboolean */
-};
-
-
-typedef void (*mwAwareAttributeHandler)
-     (struct mwServiceAware *srvc,
-      struct mwAwareAttribute *attrib);
-
-
-struct mwAwareHandler {
-  mwAwareAttributeHandler on_attrib;
-  void (*clear)(struct mwServiceAware *srvc);
-};
-
-
-/** Appropriate function type for the on-aware signal
-
-    @param list  mwAwareList emiting the signal
-    @param id    awareness status information
-    @param data  user-specified data
-*/
-typedef void (*mwAwareSnapshotHandler)
-     (struct mwAwareList *list,
-      struct mwAwareSnapshot *id);
-
-
-/** Appropriate function type for the on-option signal. The option's
-    value may need to be explicitly loaded in some instances,
-    resulting in this handler being triggered again.
-
-    @param list    mwAwareList emiting the signal
-    @param id      awareness the attribute belongs to
-    @param attrib  attribute
-*/
-typedef void (*mwAwareIdAttributeHandler)
-     (struct mwAwareList *list,
-      struct mwAwareIdBlock *id,
-      struct mwAwareAttribute *attrib);
-
-
-struct mwAwareListHandler {
-  /** handle aware updates */
-  mwAwareSnapshotHandler on_aware;
-
-  /** handle attribute updates */
-  mwAwareIdAttributeHandler on_attrib;
-
-  /** optional. Called from mwAwareList_free */
-  void (*clear)(struct mwAwareList *list);
-};
-
-
-struct mwServiceAware *
-mwServiceAware_new(struct mwSession *session,
-		   struct mwAwareHandler *handler);
-
-
-/** Set an attribute value for this session */
-int mwServiceAware_setAttribute(struct mwServiceAware *srvc,
-				guint32 key, struct mwOpaque *opaque);
-
-
-int mwServiceAware_setAttributeBoolean(struct mwServiceAware *srvc,
-				       guint32 key, gboolean val);
-
-
-int mwServiceAware_setAttributeInteger(struct mwServiceAware *srvc,
-				       guint32 key, guint32 val);
-
-
-int mwServiceAware_setAttributeString(struct mwServiceAware *srvc,
-				      guint32 key, const char *str);
-
-
-/** Unset an attribute for this session */
-int mwServiceAware_unsetAttribute(struct mwServiceAware *srvc,
-				  guint32 key);
-
-
-guint32 mwAwareAttribute_getKey(const struct mwAwareAttribute *attrib);
-
-
-gboolean mwAwareAttribute_asBoolean(const struct mwAwareAttribute *attrib);
-
-
-guint32 mwAwareAttribute_asInteger(const struct mwAwareAttribute *attrib);
-
-
-/** Copy of attribute string, must be g_free'd. If the attribute's
-    content cannot be loaded as a string, returns NULL */
-char *mwAwareAttribute_asString(const struct mwAwareAttribute *attrib);
-
-
-/** Direct access to an attribute's underlying opaque */
-const struct mwOpaque *
-mwAwareAttribute_asOpaque(const struct mwAwareAttribute *attrib);
-
-
-/** Allocate and initialize an aware list */
-struct mwAwareList *
-mwAwareList_new(struct mwServiceAware *srvc,
-		struct mwAwareListHandler *handler);
-
-
-/** Clean and free an aware list */
-void mwAwareList_free(struct mwAwareList *list);
-
-
-struct mwAwareListHandler *mwAwareList_getHandler(struct mwAwareList *list);
-
-
-/** Add a collection of user IDs to an aware list.
-    @param list     mwAwareList to add user ID to
-    @param id_list  mwAwareIdBlock list of user IDs to add
-    @return         0 for success, non-zero to indicate an error.
-*/
-int mwAwareList_addAware(struct mwAwareList *list, GList *id_list);
-
-
-/** Remove a collection of user IDs from an aware list.
-    @param list     mwAwareList to remove user ID from
-    @param id_list  mwAwareIdBlock list of user IDs to remove
-    @return  0      for success, non-zero to indicate an error.
-*/
-int mwAwareList_removeAware(struct mwAwareList *list, GList *id_list);
-
-
-int mwAwareList_removeAllAware(struct mwAwareList *list);
-
-
-/** watch an NULL terminated array of keys */
-int mwAwareList_watchAttributeArray(struct mwAwareList *list,
-				    guint32 *keys);
-
-
-/** watch a NULL terminated list of keys */
-int mwAwareList_watchAttributes(struct mwAwareList *list,
-				guint32 key, ...);
-
-
-/** stop watching a NULL terminated array of keys */
-int mwAwareList_unwatchAttributeArray(struct mwAwareList *list,
-				      guint32 *keys);
-
-
-/** stop watching a NULL terminated list of keys */
-int mwAwareList_unwatchAttributes(struct mwAwareList *list,
-				  guint32 key, ...);
-
-
-/** remove all watched attributes */
-int mwAwareList_unwatchAllAttributes(struct mwAwareList *list);
-
-
-guint32 *mwAwareList_getWatchedAttributes(struct mwAwareList *list);
-
-
-void mwAwareList_setClientData(struct mwAwareList *list,
-			       gpointer data, GDestroyNotify cleanup);
-
-
-void mwAwareList_removeClientData(struct mwAwareList *list);
-
-
-gpointer mwAwareList_getClientData(struct mwAwareList *list);
-
-
-/** trigger a got_aware event constructed from the passed user and
-    status information. Useful for adding false users and having the
-    getText function work for them */
-void mwServiceAware_setStatus(struct mwServiceAware *srvc,
-			      struct mwAwareIdBlock *user,
-			      struct mwUserStatus *stat);
-
-
-/** look up the status description for a user */
-const char *mwServiceAware_getText(struct mwServiceAware *srvc,
-				   struct mwAwareIdBlock *user);
-
-
-/** look up the last known copy of an attribute for a user by the
-    attribute's key */
-const struct mwAwareAttribute *
-mwServiceAware_getAttribute(struct mwServiceAware *srvc,
-			    struct mwAwareIdBlock *user,
-			    guint32 key);
-
-
-#endif
-
-
--- a/src/protocols/sametime/meanwhile/mw_srvc_conf.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,199 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_SRVC_CONF_H
-#define _MW_SRVC_CONF_H
-
-
-#include <glib/glist.h>
-#include "mw_common.h"
-
-
-/** Type identifier for the conference service */
-#define mwService_CONFERENCE  0x80000010
-
-
-enum mwConferenceState {
-  mwConference_NEW,      /**< new outgoing conference */
-  mwConference_PENDING,  /**< outgoing conference pending creation */
-  mwConference_INVITED,  /**< invited to incoming conference */
-  mwConference_OPEN,     /**< conference open and active */
-  mwConference_CLOSING,  /**< conference is closing */
-  mwConference_ERROR,    /**< conference is closing due to error */
-  mwConference_UNKNOWN,  /**< unable to determine conference state */
-};
-
-
-/** @struct mwServiceConference
-    Instance of the multi-user conference service */
-struct mwServiceConference;
-
-
-/** @struct mwConference
-    A multi-user chat */
-struct mwConference;
-
-
-/** Handler structure used to provide callbacks for an instance of the
-    conferencing service */
-struct mwConferenceHandler {
-
-  /** triggered when we receive a conference invitation. Call
-      mwConference_accept to accept the invitation and join the
-      conference, or mwConference_close to reject the invitation.
-
-      @param conf     the newly created conference
-      @param inviter  the indentity of the user who sent the invitation
-      @param invite   the invitation text
-   */
-  void (*on_invited)(struct mwConference *conf,
-		     struct mwLoginInfo *inviter, const char *invite);
-
-  /** triggered when we enter the conference. Provides the initial
-      conference membership list as a GList of mwLoginInfo structures
-
-      @param conf     the conference just joined
-      @param members  mwLoginInfo list of existing conference members
-  */
-  void (*conf_opened)(struct mwConference *conf, GList *members);
-
-  /** triggered when a conference is closed. This is typically when
-      we've left it */
-  void (*conf_closed)(struct mwConference *, guint32 reason);
-
-  /** triggered when someone joins the conference */
-  void (*on_peer_joined)(struct mwConference *, struct mwLoginInfo *);
-
-  /** triggered when someone leaves the conference */
-  void (*on_peer_parted)(struct mwConference *, struct mwLoginInfo *);
-
-  /** triggered when someone says something */
-  void (*on_text)(struct mwConference *conf,
-		  struct mwLoginInfo *who, const char *what);
-
-  /** typing notification */
-  void (*on_typing)(struct mwConference *conf,
-		    struct mwLoginInfo *who, gboolean typing);
-
-  /** optional. called from mwService_free */
-  void (*clear)(struct mwServiceConference *srvc);
-};
-
-
-/** Allocate a new conferencing service, attaching the given handler
-    @param sess     owning session
-    @param handler  handler providing call-back functions for the service
- */
-struct mwServiceConference *
-mwServiceConference_new(struct mwSession *sess,
-			struct mwConferenceHandler *handler);
-
-
-/** @returns the conference handler for the service */
-struct mwConferenceHandler *
-mwServiceConference_getHandler(struct mwServiceConference *srvc);
-
-
-/** a mwConference list of the conferences in this service. The GList
-    will need to be destroyed with g_list_free after use */
-GList *mwServiceConference_getConferences(struct mwServiceConference *srvc);
-
-
-/** Allocate a new conference, in state NEW with the given title.
-    @see mwConference_create */
-struct mwConference *mwConference_new(struct mwServiceConference *srvc,
-				      const char *title);
-
-
-/** @returns the owning service of a conference */
-struct mwServiceConference *mwConference_getService(struct mwConference *conf);
-
-
-/** @returns unique conference name */
-const char *mwConference_getName(struct mwConference *conf);
-
-
-/** @returns conference title */
-const char *mwConference_getTitle(struct mwConference *conf);
-
-
-/** a mwIdBlock list of the members of the conference. The GList will
-    need to be free'd after use */
-GList *mwConference_getMembers(struct mwConference *conf);
-
-
-/** Initiate a conference. Conference must be in state NEW. If no name
-    or title for the conference has been set, they will be
-    generated. Conference will be placed into state PENDING. */
-int mwConference_open(struct mwConference *conf);
-
-
-/** Leave and close an existing conference, or reject an invitation.
-    Triggers mwServiceConfHandler::conf_closed and free's the
-    conference.
- */
-int mwConference_destroy(struct mwConference *conf,
-			 guint32 reason, const char *text);
-
-
-#define mwConference_reject(c,r,t) \
-  mwConference_destroy((c),(r),(t))
-
-
-/** accept a conference invitation. Conference must be in the state
-    INVITED. */
-int mwConference_accept(struct mwConference *conf);
-
-
-/** invite another user to an ACTIVE conference
-    @param conf  conference
-    @param who   user to invite
-    @param text  invitation message
- */
-int mwConference_invite(struct mwConference *conf,
-			struct mwIdBlock *who, const char *text);
-
-
-/** send a text message over an open conference */
-int mwConference_sendText(struct mwConference *conf, const char *text);
-
-
-/** send typing notification over an open conference */
-int mwConference_sendTyping(struct mwConference *conf, gboolean typing);
-
-
-/** associate arbitrary client data and an optional cleanup function
-    with a conference. If there is already client data with a clear
-    function, it will not be called. */
-void mwConference_setClientData(struct mwConference *conf,
-				gpointer data, GDestroyNotify clear);
-
-
-/** reference associated client data */
-gpointer mwConference_getClientData(struct mwConference *conf);
-
-
-/** remove associated client data if any, and call the cleanup
-    function on the data as necessary */
-void mwConference_removeClientData(struct mwConference *conf);
-				    
-
-#endif
-
--- a/src/protocols/sametime/meanwhile/mw_srvc_ft.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,239 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-
-#ifndef _MW_SRVC_FT_H
-#define _MW_SRVC_FT_H
-
-
-#include "mw_common.h"
-
-
-/** @file mw_srvc_ft.h
-
-    A file transfer is a simple way to get large chunks of binary data
-    from one client to another.
-*/
-
-
-/** @struct mwServiceFileTransfer
-    File transfer service
-*/
-struct mwServiceFileTransfer;
-
-
-/** @struct mwFileTransfer
-    A single file trasfer session
- */
-struct mwFileTransfer;
-
-
-#define mwService_FILE_TRANSFER  0x00000038
-
-
-enum mwFileTransferState {
-  mwFileTransfer_NEW,   /**< file transfer is not open */
-  mwFileTransfer_PENDING,  /**< file transfer is opening */
-  mwFileTransfer_OPEN,     /**< file transfer is open */
-  mwFileTransfer_CANCEL_LOCAL,
-  mwFileTransfer_CANCEL_REMOTE,
-  mwFileTransfer_DONE,
-  mwFileTransfer_ERROR,    /**< error in file transfer */
-  mwFileTransfer_UNKNOWN,  /**< unknown state */
-};
-
-
-#define mwFileTransfer_isState(ft, state) \
-  (mwFileTransfer_getState(ft) == (state))
-
-#define mwFileTransfer_isNew(ft) \
-  mwFileTransfer_isState((ft), mwFileTransfer_NEW)
-
-#define mwFileTransfer_isPending(ft) \
-  mwFileTransfer_isState((ft), mwFileTransfer_PENDING)
-
-#define mwFileTransfer_isOpen(ft) \
-  mwFileTransfer_isState((ft), mwFileTransfer_OPEN)
-
-#define mwFileTransfer_isDone(ft) \
-  mwFileTransfer_isState((ft), mwFileTransfer_DONE)
-
-#define mwFileTransfer_isCancelLocal(ft) \
-  mwFileTransfer_isState((ft), mwFileTransfer_CANCEL_LOCAL)
-
-#define mwFileTransfer_isCancelRemote(ft) \
-  mwFileTransfer_isState((ft), mwFileTransfer_CANCEL_REMOTE)
-
-
-enum mwFileTranferCode {
-  mwFileTransfer_SUCCESS   = 0x00000000,
-  mwFileTransfer_REJECTED  = 0x08000606,
-};
-
-
-struct mwFileTransferHandler {
-
-  /** an incoming file transfer has been offered */
-  void (*ft_offered)(struct mwFileTransfer *ft);
-
-  /** a file transfer has been fully initiated */
-  void (*ft_opened)(struct mwFileTransfer *ft);
-
-  /** a file transfer has been closed. Check the status of the file
-      transfer to determine if the transfer was complete or if it had
-      been interrupted */
-  void (*ft_closed)(struct mwFileTransfer *ft, guint32 code);
-
-  /** receive a chunk of a file from an inbound file transfer. */
-  void (*ft_recv)(struct mwFileTransfer *ft, struct mwOpaque *data);
-
-  /** received an ack for a sent chunk on an outbound file transfer.
-      this indicates that a previous call to mwFileTransfer_send has
-      reached the target and that the target has responded. */
-  void (*ft_ack)(struct mwFileTransfer *ft);
-
-  /** optional. called from mwService_free */
-  void (*clear)(struct mwServiceFileTransfer *srvc);
-};
-
-
-struct mwServiceFileTransfer *
-mwServiceFileTransfer_new(struct mwSession *session,
-			  struct mwFileTransferHandler *handler);
-
-
-struct mwFileTransferHandler *
-mwServiceFileTransfer_getHandler(struct mwServiceFileTransfer *srvc);
-
-
-const GList *
-mwServiceFileTransfer_getTransfers(struct mwServiceFileTransfer *srvc);
-
-
-struct mwFileTransfer *
-mwFileTransfer_new(struct mwServiceFileTransfer *srvc,
-		   const struct mwIdBlock *who, const char *msg,
-		   const char *filename, guint32 filesize);
-
-
-/** deallocate a file transfer. will call mwFileTransfer_close if
-    necessary */
-void
-mwFileTransfer_free(struct mwFileTransfer *ft);
-
-
-/** the status of this file transfer */
-enum mwFileTransferState
-mwFileTransfer_getState(struct mwFileTransfer *ft);
-
-
-struct mwServiceFileTransfer *
-mwFileTransfer_getService(struct mwFileTransfer *ft);
-
-
-/** the user on the other end of the file transfer */
-const struct mwIdBlock *
-mwFileTransfer_getUser(struct mwFileTransfer *ft);
-
-
-/** the message sent along with an offered file transfer */
-const char *
-mwFileTransfer_getMessage(struct mwFileTransfer *ft);
-
-
-/** the publicized file name. Not necessarily related to any actual
-    file on either system */
-const char *
-mwFileTransfer_getFileName(struct mwFileTransfer *ft);
-
-
-/** total bytes intended to be sent/received */
-guint32 mwFileTransfer_getFileSize(struct mwFileTransfer *ft);
-
-
-/** bytes remaining to be received/send */
-guint32 mwFileTransfer_getRemaining(struct mwFileTransfer *ft);
-
-
-/** count of bytes sent/received over this file transfer so far */
-#define mwFileTransfer_getSent(ft) \
-  (mwFileTransfer_getFileSize(ft) - mwFileTransfer_getRemaining(ft))
-
-
-/** initiate an outgoing file transfer */
-int mwFileTransfer_offer(struct mwFileTransfer *ft);
-
-
-/** accept an incoming file transfer */
-int mwFileTransfer_accept(struct mwFileTransfer *ft);
-
-
-/** reject an incoming file transfer */
-#define mwFileTransfer_reject(ft) \
-  mwFileTransfer_close((ft), mwFileTransfer_REJECTED)
-
-
-/** cancel an open file transfer */
-#define mwFileTransfer_cancel(ft) \
-  mwFileTransfer_close((ft), mwFileTransfer_SUCCESS);
-
-
-/** Close a file transfer. This will trigger the ft_close function of the
-    session's handler.
-
-    @see mwFileTransfer_reject
-    @see mwFileTransfer_cancel
-*/
-int mwFileTransfer_close(struct mwFileTransfer *ft, guint32 code);
-
-
-/** send a chunk of data over an outbound file transfer. The client at
-    the other end of the transfer should respond with an acknowledgement
-    message, which can be caught in the service's handler.
-
-    @see mwFileTransferHandler::ft_ack
-*/
-int mwFileTransfer_send(struct mwFileTransfer *ft,
-			struct mwOpaque *data);
-
-
-/** acknowledge the receipt of a chunk of data from an inbound file
-    transfer.  This should be done after every received chunk, or the
-    transfer will stall. However, not all clients will wait for an ack
-    after sending a chunk before sending the next chunk, so it is
-    possible to have the handler's ft_recv function triggered again
-    even if no ack was sent.
-
-    @see mwFileTransferHandler::ft_recv
-*/
-int mwFileTransfer_ack(struct mwFileTransfer *ft);
-
-
-void mwFileTransfer_setClientData(struct mwFileTransfer *ft,
-				  gpointer data, GDestroyNotify clean);
-
-
-gpointer mwFileTransfer_getClientData(struct mwFileTransfer *ft);
-
-
-void mwFileTransfer_removeClientData(struct mwFileTransfer *ft);
-
-
-#endif
--- a/src/protocols/sametime/meanwhile/mw_srvc_im.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,267 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_SRVC_IM_H
-#define _MW_SRVC_IM_H
-
-
-#include <glib.h>
-#include "mw_common.h"
-
-
-/** @file mw_srvc_im.h
-
-    The IM service provides one-on-one communication between
-    users. Messages sent over conversations may relay different types
-    of information, in a variety of formats. The basic feature-set
-    provides plain-text chat with typing notification. More complex
-    features may be negotiated transparently by setting the IM Client
-    Type for a conversation, or for the service as a whole.
- */
-
-
-/** Type identifier for the IM service */
-#define mwService_IM  0x00001000
-
-
-/** @struct mwServiceIm
-
-    An instance of the IM service. This service provides simple
-    instant messaging functionality */
-struct mwServiceIm;
-
-
-/** @struct mwConversation
-
-    A conversation between the local service and a single other user */
-struct mwConversation;
-
-
-enum mwImClientType {
-  mwImClient_PLAIN       = 0x00000001,  /**< text, typing */
-  mwImClient_NOTESBUDDY  = 0x00033453,  /**< adds html, subject, mime */
-  mwImClient_PRECONF     = 0x00000019,  /**< pre-conference, legacy */
-  mwImClient_UNKNOWN     = 0xffffffff,  /**< trouble determining type */
-};
-
-
-/**
-   Types of supported messages. When a conversation is created, the
-   least common denominator of features between either side of the
-   conversation (based on what features are available in the IM
-   service itself) becomes the set of supported features for that
-   conversation. At any point, the feature set for the service may
-   change, without affecting any existing conversations.
-
-   @see mwServiceIm_supports
-   @see mwServiceIm_setSupported
-   @see mwConversation_supports
-   @see mwConversation_send
-   @see mwServiceImHandler::conversation_recv
- */
-enum mwImSendType {
-  mwImSend_PLAIN,   /**< char *, plain-text message */
-  mwImSend_TYPING,  /**< gboolean, typing status */
-  mwImSend_HTML,    /**< char *, HTML formatted message (NOTESBUDDY) */
-  mwImSend_SUBJECT, /**< char *, conversation subject (NOTESBUDDY) */
-  mwImSend_MIME,    /**< char *, MIME-encoded message (NOTESBUDDY) */
-  mwImSend_TIMESTAMP, /**< char *, YYYY:MM:DD:HH:mm:SS format (NOTESBUDDY) */
-};
-
-
-
-/** @see mwConversation_getState */
-enum mwConversationState {
-  mwConversation_CLOSED,   /**< conversation is not open */
-  mwConversation_PENDING,  /**< conversation is opening */
-  mwConversation_OPEN,     /**< conversation is open */
-  mwConversation_UNKNOWN,  /**< unknown state */
-};
-
-
-#define mwConversation_isState(conv, state) \
-  (mwConversation_getState(conv) == (state))
-
-#define mwConversation_isClosed(conv) \
-  mwConversation_isState((conv), mwConversation_CLOSED)
-
-#define mwConversation_isPending(conv) \
-  mwConversation_isState((conv), mwConversation_PENDING)
-
-#define mwConversation_isOpen(conv) \
-  mwConversation_isState((conv), mwConversation_OPEN)
-
-
-
-/** IM Service Handler. Provides functions for events triggered from an
-    IM service instance. */
-struct mwImHandler {
-
-  /** A conversation has been successfully opened */
-  void (*conversation_opened)(struct mwConversation *conv);
-
-  /** A conversation has been closed */
-  void (*conversation_closed)(struct mwConversation *conv, guint32 err);
-  
-  /** A message has been received on a conversation */
-  void (*conversation_recv)(struct mwConversation *conv,
-			    enum mwImSendType type, gconstpointer msg);
-
-  /** Handle a Place invitation. Set this to NULL and we should end up
-      receiving a conference invitation instead. */
-  void (*place_invite)(struct mwConversation *conv,
-		       const char *message,
-		       const char *title, const char *name);
-
-  /** optional. called from mwService_free */
-  void (*clear)(struct mwServiceIm *srvc);
-};
-
-
-struct mwServiceIm *mwServiceIm_new(struct mwSession *session,
-				    struct mwImHandler *handler);
-
-
-struct mwImHandler *mwServiceIm_getHandler(struct mwServiceIm *srvc);
-
-
-/** reference an existing conversation to target, or create a new
-    conversation to target if one does not already exist */
-struct mwConversation *mwServiceIm_getConversation(struct mwServiceIm *srvc,
-						   struct mwIdBlock *target);
-
-
-/** reference an existing conversation to target */
-struct mwConversation *mwServiceIm_findConversation(struct mwServiceIm *srvc,
-						    struct mwIdBlock *target);
-
-
-/** determine if the conversations created from this service will
-    support a given send type */
-gboolean mwServiceIm_supports(struct mwServiceIm *srvc,
-			      enum mwImSendType type);
-
-
-/** Set the default client type for the service. Newly created
-    conversations will attempt to meet this level of functionality
-    first.
-
-    @param srvc       the IM service
-    @param type       the send type to enable/disable
-*/
-void mwServiceIm_setClientType(struct mwServiceIm *srvc,
-			       enum mwImClientType type);
-
-
-enum mwImClientType mwServiceIm_getClientType(struct mwServiceIm *srvc);
-
-
-/** attempt to open a conversation. If the conversation was not
-    already open and it is accepted,
-    mwServiceImHandler::conversation_opened will be triggered. Upon
-    failure, mwServiceImHandler::conversation_closed will be
-    triggered */
-void mwConversation_open(struct mwConversation *conv);
-
-
-/** close a conversation. If the conversation was not already closed,
-    mwServiceImHandler::conversation_closed will be triggered */
-void mwConversation_close(struct mwConversation *conv, guint32 err);
-
-
-/** determine whether a conversation supports the given message type */
-gboolean mwConversation_supports(struct mwConversation *conv,
-				 enum mwImSendType type);
-
-
-enum mwImClientType mwConversation_getClientType(struct mwConversation *conv);
-
-
-/** get the state of a conversation
-
-    @see mwConversation_isOpen
-    @see mwConversation_isClosed
-    @see mwConversation_isPending
-*/
-enum mwConversationState mwConversation_getState(struct mwConversation *conv);
-
-
-/** send a message over an open conversation */
-int mwConversation_send(struct mwConversation *conv,
-			enum mwImSendType type, gconstpointer send);
-
-
-/** @returns owning service for a conversation */
-struct mwServiceIm *mwConversation_getService(struct mwConversation *conv);
-
-
-/** login information for conversation partner. returns NULL if conversation 
-    is not OPEN */
-struct mwLoginInfo *mwConversation_getTargetInfo(struct mwConversation *conv);
-
-
-/** ID for conversation partner */
-struct mwIdBlock *mwConversation_getTarget(struct mwConversation *conv);
-
-
-/** set whether outgoing messages should be encrypted using the
-    negotiated cipher, if any */
-void mwConversation_setEncrypted(struct mwConversation *conv,
-				 gboolean useCipher);
-
-
-/** determine whether outgoing messages are being encrypted */
-gboolean mwConversation_isEncrypted(struct mwConversation *conv);
-
-
-/** Associates client data with a conversation. If there is existing data,
-    it will not have its cleanup function called.
-
-    @see mwConversation_getClientData
-    @see mwConversation_removeClientData
-*/
-void mwConversation_setClientData(struct mwConversation *conv,
-				  gpointer data, GDestroyNotify clean);
-
-
-/** Reference associated client data
-
-    @see mwConversation_setClientData
-    @see mwConversation_removeClientData
- */
-gpointer mwConversation_getClientData(struct mwConversation *conv);
-
-
-/** Remove any associated client data, calling the optional cleanup
-    function if one was provided
-
-    @see mwConversation_setClientData
-    @see mwConversation_getClientData
-*/
-void mwConversation_removeClientData(struct mwConversation *conv);
-
-
-/** close and destroy the conversation and its backing channel, and
-    call the optional client data cleanup function */
-void mwConversation_free(struct mwConversation *conv);
-
-
-#endif
-
--- a/src/protocols/sametime/meanwhile/mw_srvc_place.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_SRVC_PLACE_H
-#define _MW_SRVC_PLACE_H
-
-
-#include <glib/glist.h>
-#include "mw_common.h"
-
-
-/** Type identifier for the place service */
-#define mwService_PLACE  0x80000022
-
-
-/** @struct mwServicePlace */
-struct mwServicePlace;
-
-
-/** @struct mwPlace */
-struct mwPlace;
-
-
-struct mwPlaceHandler {
-  void (*opened)(struct mwPlace *place);
-  void (*closed)(struct mwPlace *place, guint32 code);
-
-  void (*peerJoined)(struct mwPlace *place,
-		     const struct mwIdBlock *peer);
-
-  void (*peerParted)(struct mwPlace *place,
-		     const struct mwIdBlock *peer);
-
-  void (*peerSetAttribute)(struct mwPlace *place,
-			   const struct mwIdBlock *peer,
-			   guint32 attr, struct mwOpaque *o);
-
-  void (*peerUnsetAttribute)(struct mwPlace *place,
-			     const struct mwIdBlock *peer,
-			     guint32 attr);
-
-  void (*message)(struct mwPlace *place,
-		  const struct mwIdBlock *who,
-		  const char *msg);
-
-  void (*clear)(struct mwServicePlace *srvc);
-};
-
-
-enum mwPlacePeerAttribute {
-  mwPlacePeer_TYPING = 0x00000008,
-};
-
-
-struct mwServicePlace *
-mwServicePlace_new(struct mwSession *session,
-		   struct mwPlaceHandler *handler);
-
-
-struct mwPlaceHandler *
-mwServicePlace_getHandler(struct mwServicePlace *srvc);
-
-
-const GList *mwServicePlace_getPlaces(struct mwServicePlace *srvc);
-
-
-struct mwPlace *mwPlace_new(struct mwServicePlace *srvc,
-			    const char *name, const char *title);
-
-
-struct mwServicePlace *mwPlace_getService(struct mwPlace *place);
-
-
-const char *mwPlace_getName(struct mwPlace *place);
-
-
-const char *mwPlace_getTitle(struct mwPlace *place);
-
-
-int mwPlace_open(struct mwPlace *place);
-
-
-int mwPlace_destroy(struct mwPlace *place, guint32 code);
-
-
-/** returns a GList* of struct mwIdBlock*. The GList will need to be
-    freed after use, the mwIdBlock structures should not be modified
-    or freed */
-GList *mwPlace_getMembers(struct mwPlace *place);
-
-
-int mwPlace_sendText(struct mwPlace *place, const char *msg);
-
-
-/** send a legacy invitation for this place to a user. The user will
-    receive an apparent invitation from a Conference (rather than a
-    Place) */
-int mwPlace_legacyInvite(struct mwPlace *place,
-			 struct mwIdBlock *idb,
-			 const char *message);
-
-
-int mwPlace_setAttribute(struct mwPlace *place, guint32 attrib,
-			 struct mwOpaque *data);
-
-
-int mwPlace_unsetAttribute(struct mwPlace *place, guint32 attrib);
-
-
-void mwPlace_setClientData(struct mwPlace *place,
-			   gpointer data, GDestroyNotify clean);
-
-
-gpointer mwPlace_getClientData(struct mwPlace *place);
-
-
-void mwPlace_removeClientData(struct mwPlace *place);
-
-
-#endif
--- a/src/protocols/sametime/meanwhile/mw_srvc_resolve.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_SRVC_RESOLVE_H
-#define _MW_SRVC_RESOLVE_H
-
-
-#include <glib.h>
-#include <glib/glist.h>
-
-
-/** Type identifier for the conference service */
-#define mwService_RESOLVE  0x00000015
-
-
-/** Return value of mwServiceResolve_search indicating an error */
-#define SEARCH_ERROR  0x00
-
-
-/** @struct mwServiceResolve
-    User lookup service */
-struct mwServiceResolve;
-
-
-enum mwResolveFlag {
-  /** return unique results or none at all */
-  mwResolveFlag_UNIQUE    = 0x00000001,
-
-  /** return only the first result */
-  mwResolveFlag_FIRST     = 0x00000002,
-
-  /** search all directories, not just the first with a match */
-  mwResolveFlag_ALL_DIRS  = 0x00000004,
-
-  /** search for users */
-  mwResolveFlag_USERS     = 0x00000008,
-
-  /** search for groups */
-  mwResolveFlag_GROUPS    = 0x00000010,
-};
-
-
-/** @see mwResolveResult */
-enum mwResolveCode {
-  /** successful search */
-  mwResolveCode_SUCCESS     = 0x00000000,
-
-  /** only some of the nested searches were successful */
-  mwResolveCode_PARTIAL     = 0x00010000,
-
-  /** more than one result (occurs when mwResolveFlag_UNIQUE is used
-      and more than one result would have been otherwise returned) */
-  mwResolveCode_MULTIPLE    = 0x80020000,
-
-  /** the name is not resolvable due to its format */
-  mwResolveCode_BAD_FORMAT  = 0x80030000,
-};
-
-
-enum mwResolveMatchType {
-  mwResolveMatch_USER   = 0x00000001,
-  mwResolveMatch_GROUP  = 0x00000002,
-};
-
-
-struct mwResolveMatch {
-  char *id;      /**< user id */
-  char *name;    /**< user name */
-  char *desc;    /**< description */
-  guint32 type;  /**< @see mwResolveMatchType */
-};
-
-
-struct mwResolveResult {
-  guint32 code;    /**< @see mwResolveCode */
-  char *name;      /**< name of the result */
-  GList *matches;  /**< list of mwResolveMatch */
-};
-
-
-/** Handle the results of a resolve request. If there was a cleanup
-    function specified to mwServiceResolve_search, it will be called
-    upon the user data after this callback returns.
-
-    @param srvc     the resolve service
-    @param id       the resolve request ID
-    @param code     return code
-    @param results  list of mwResolveResult
-    @param data     optional user data attached to the request
-*/
-typedef void (*mwResolveHandler)
-     (struct mwServiceResolve *srvc,
-      guint32 id, guint32 code, GList *results,
-      gpointer data);
-
-
-/** Allocate a new resolve service */
-struct mwServiceResolve *mwServiceResolve_new(struct mwSession *);
-
-
-/** Inisitate a resolve request.
-
-    @param srvc     the resolve service
-    @param queries  list query strings
-    @param flags    search flags
-    @param handler  result handling function
-    @param data     optional user data attached to the request
-    @param cleanup  optional function to clean up user data
-    @return         generated ID for the search request, or SEARCH_ERROR
-*/
-guint32 mwServiceResolve_resolve(struct mwServiceResolve *srvc,
-				 GList *queries, enum mwResolveFlag flags,
-				 mwResolveHandler handler,
-				 gpointer data, GDestroyNotify cleanup);
-
-
-/** Cancel a resolve request by its generated ID. The handler function
-    will not be called, and the optional cleanup function will be
-    called upon the optional user data for the request */
-void mwServiceResolve_cancelResolve(struct mwServiceResolve *, guint32);
-
-
-#endif
--- a/src/protocols/sametime/meanwhile/mw_srvc_store.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,186 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_SRVC_STORE_H
-#define _MW_SRVC_STORE_H
-
-
-#include <glib.h>
-#include "mw_common.h"
-
-
-/** Type identifier for the storage service */
-#define mwService_STORAGE  0x00000018
-
-
-/** @struct mwServiceStorage
-    @see mwServiceStorage_new
-
-    Instance of the storage service */
-struct mwServiceStorage;
-
-
-/** @struct mwStorage
-
-    Unit Represents information intended for loading from or saving to
-    the storage service */
-struct mwStorageUnit;
-
-
-/** The upper limit of reserved Lotus keys */
-#define LOTUS_RESERVED_LIMIT  0x186a0
-
-
-/** Check if a key is in the range of Lotus reserved keys */
-#define KEY_IS_LOTUS_RESERVED(key) \
-  (((guint32) key) <= (LOTUS_RESERVED_LIMIT))
-
-
-/** Some common keys storage keys. Anything in the range 0x00 to
-    0x186a0 (100000) is reserved for use by the Lotus
-    clients. */
-enum mwStorageKey {
-
-  /** The buddy list, in the Sametime .dat file format. String */
-  mwStore_AWARE_LIST      = 0x00000000,
-
-  /** Default text for chat invitations. String */
-  mwStore_INVITE_CHAT     = 0x00000006,
-
-  /** Default text for meeting invitations. String */
-  mwStore_INVITE_MEETING  = 0x0000000e,
-
-  /** Last five Away messages, separated by semicolon. String */
-  mwStore_AWAY_MESSAGES   = 0x00000050,
-
-  /** Last five Busy (DND) messages, separated by semicolon. String */
-  mwStore_BUSY_MESSAGES   = 0x0000005a,
-
-  /** Last five Active messages, separated by semicolon. String */
-  mwStore_ACTIVE_MESSAGES = 0x00000064,
-};
-
-
-/** Appropriate function type for load and store callbacks.
-    @param srvc       the storage service
-    @param result     the result value of the load or store call
-    @param item       the storage unit loaded or saved
-    @param data       optional user data
-*/
-typedef void (*mwStorageCallback)
-     (struct mwServiceStorage *srvc,
-      guint32 result, struct mwStorageUnit *item,
-      gpointer data);
-
-
-/** Allocates and initializes a storage service instance for use on
-    the passed session. */
-struct mwServiceStorage *mwServiceStorage_new(struct mwSession *);
-
-
-/** create an empty storage unit */
-struct mwStorageUnit *mwStorageUnit_new(guint32 key);
-
-
-/** creates a storage unit with the passed key, and a copy of data. */
-struct mwStorageUnit *mwStorageUnit_newOpaque(guint32 key,
-					      struct mwOpaque *data);
-
-
-/** creates a storage unit with the passed key, and an encapsulated
-    boolean value */
-struct mwStorageUnit *mwStorageUnit_newBoolean(guint32 key,
-					       gboolean val);
-
-
-struct mwStorageUnit *mwStorageUnit_newInteger(guint32 key,
-					       guint32 val);
-
-
-/** creates a storage unit with the passed key, and an encapsulated
-    string value. */
-struct mwStorageUnit *mwStorageUnit_newString(guint32 key,
-					      const char *str);
-
-
-/** get the key for the given storage unit */
-guint32 mwStorageUnit_getKey(struct mwStorageUnit *);
-
-
-/** attempts to obtain a boolean value from a storage unit. If the
-    unit is empty, or does not contain the type in a recongnizable
-    format, val is returned instead */
-gboolean mwStorageUnit_asBoolean(struct mwStorageUnit *, gboolean val);
-
-
-/** attempts to obtain a guint32 value from a storage unit. If the
-    unit is empty, or does not contain the type in a recognizable
-    format, val is returned instead */
-guint32 mwStorageUnit_asInteger(struct mwStorageUnit *, guint32 val);
-
-
-/** attempts to obtain a string value from a storage unit. If the unit
-    is empty, or does not contain the type in a recognizable format,
-    NULL is returned instead. Note that the string returned is a copy,
-    and will need to be deallocated at some point. */
-char *mwStorageUnit_asString(struct mwStorageUnit *);
-
-
-/** direct access to the opaque data backing the storage unit */
-struct mwOpaque *mwStorageUnit_asOpaque(struct mwStorageUnit *);
-
-
-/** clears and frees a storage unit */
-void mwStorageUnit_free(struct mwStorageUnit *);
-
-      
-/** Initiates a load call to the storage service. If the service is
-    not currently available, the call will be cached and processed
-    when the service is started.
-
-    @param srvc       the storage service
-    @param item       storage unit to load
-    @param cb         callback function when the load call completes
-    @param data       user data for callback
-    @param data_free  optional cleanup function for user data
-*/
-void mwServiceStorage_load(struct mwServiceStorage *srvc,
-			   struct mwStorageUnit *item,
-			   mwStorageCallback cb,
-			   gpointer data, GDestroyNotify data_free);
-
-
-/** Initiates a store call to the storage service. If the service is
-    not currently available, the call will be cached and processed
-    when the service is started.
-
-    @param srvc       the storage service
-    @param item       storage unit to save
-    @param cb         callback function when the load call completes
-    @param data       optional user data for callback
-    @param data_free  optional cleanup function for user data
- */
-void mwServiceStorage_save(struct mwServiceStorage *srvc,
-			   struct mwStorageUnit *item,
-			   mwStorageCallback cb,
-			   gpointer data, GDestroyNotify data_free);
-
-
-#endif
--- a/src/protocols/sametime/meanwhile/mw_st_list.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_ST_LIST_H
-#define _MW_ST_LIST_H
-
-
-#include <glib.h>
-#include <glib/glist.h>
-#include "mw_common.h"
-
-
-#define ST_LIST_MAJOR  3
-#define ST_LIST_MINOR  1
-#define ST_LIST_MICRO  3
-
-
-enum mwSametimeGroupType {
-  mwSametimeGroup_NORMAL  = 1,  /**< a normal group of users */
-  mwSametimeGroup_DYNAMIC = 2,  /**< a server-side group */
-  mwSametimeGroup_UNKNOWN = 0,  /**< error determining group type */
-};
-
-
-enum mwSametimeUserType {
-  mwSametimeUser_NORMAL   = 1,  /**< user on same community */
-  mwSametimeUser_EXTERNAL = 2,  /**< external user */
-  mwSametimeUser_UNKNOWN  = 0,  /**< error determining user type */
-};
-
-
-/** @struct mwSametimeList
-
-    Represents a group-based buddy list. */
-struct mwSametimeList;
-
-
-/** @struct mwSametimeGroup
-
-    Represents a group in a buddy list */
-struct mwSametimeGroup;
-
-
-/** @struct mwSametimeUser
-
-    Represents a user in a group in a buddy list */
-struct mwSametimeUser;
-
-
-/** Create a new list */
-struct mwSametimeList *mwSametimeList_new(void);
-
-
-/** Free the list, all of its groups, and all of the groups' members */
-void mwSametimeList_free(struct mwSametimeList *l);
-
-
-/** Load a sametime list from a buffer. The list must be encapsulated
-    as a string (eg, the first two bytes in the buffer should be the
-    length of the string) */
-void mwSametimeList_get(struct mwGetBuffer *b, struct mwSametimeList *l);
-
-
-/** Write a sametime list onto a buffer. The list will be encapsulated
-    in a string (the first two bytes written will be the length of the
-    rest of the written list data) */
-void mwSametimeList_put(struct mwPutBuffer *b, struct mwSametimeList *l);
-
-
-/** convert a plain string into a sametime list */
-struct mwSametimeList *mwSametimeList_load(const char *str);
-
-
-/** convert a sametime list into a string */
-char *mwSametimeList_store(struct mwSametimeList *l);
-
-
-void mwSametimeList_setMajor(struct mwSametimeList *l, guint v);
-
-
-guint mwSametimeList_getMajor(struct mwSametimeList *l);
-
-
-void mwSametimeList_setMinor(struct mwSametimeList *l, guint v);
-
-
-guint mwSametimeList_getMinor(struct mwSametimeList *l);
-
-
-void mwSametimeList_setMicro(struct mwSametimeList *l, guint v);
-
-
-guint mwSametimeList_getMicro(struct mwSametimeList *l);
-
-
-/** Get a GList snapshot of the groups in a list */
-GList *mwSametimeList_getGroups(struct mwSametimeList *l);
-
-
-struct mwSametimeGroup *
-mwSametimeList_findGroup(struct mwSametimeList *l,
-			 const char *name);
-
-
-/** Create a new group in a list */
-struct mwSametimeGroup *
-mwSametimeGroup_new(struct mwSametimeList *l,
-		    enum mwSametimeGroupType type,
-		    const char *name);
-
-
-/** Remove a group from its list, and free it. Also frees all users
-    contained in the group */
-void mwSametimeGroup_free(struct mwSametimeGroup *g);
-
-
-enum mwSametimeGroupType mwSametimeGroup_getType(struct mwSametimeGroup *g);
-
-
-const char *mwSametimeGroup_getName(struct mwSametimeGroup *g);
-
-
-void mwSametimeGroup_setAlias(struct mwSametimeGroup *g,
-			      const char *alias);
-
-
-const char *mwSametimeGroup_getAlias(struct mwSametimeGroup *g);
-
-
-void mwSametimeGroup_setOpen(struct mwSametimeGroup *g, gboolean open);
-
-
-gboolean mwSametimeGroup_isOpen(struct mwSametimeGroup *g);
-
-
-struct mwSametimeList *mwSametimeGroup_getList(struct mwSametimeGroup *g);
-
-
-/** Get a GList snapshot of the users in a list */
-GList *mwSametimeGroup_getUsers(struct mwSametimeGroup *g);
-
-
-struct mwSametimeUser *
-mwSametimeGroup_findUser(struct mwSametimeGroup *g,
-			 struct mwIdBlock *user);
-
-
-/** Create a user in a group */
-struct mwSametimeUser *
-mwSametimeUser_new(struct mwSametimeGroup *g,
-		   enum mwSametimeUserType type,
-		   struct mwIdBlock *user);
-
-
-/** Remove user from its group, and free it */
-void mwSametimeUser_free(struct mwSametimeUser *u);
-
-
-struct mwSametimeGroup *mwSametimeUser_getGroup(struct mwSametimeUser *u);
-
-
-enum mwSametimeUserType mwSametimeUser_getType(struct mwSametimeUser *u);
-
-
-const char *mwSametimeUser_getUser(struct mwSametimeUser *u);
-
-
-const char *mwSametimeUser_getCommunity(struct mwSametimeUser *u);
-
-
-void mwSametimeUser_setShortName(struct mwSametimeUser *u, const char *name);
-
-
-const char *mwSametimeUser_getShortName(struct mwSametimeUser *u);
-
-
-void mwSametimeUser_setAlias(struct mwSametimeUser *u, const char *alias);
-
-
-const char *mwSametimeUser_getAlias(struct mwSametimeUser *u);
-
-
-#endif
--- a/src/protocols/sametime/meanwhile/mw_util.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include "mw_util.h"
-
-
-static void collect_keys(gpointer key, gpointer val, gpointer data) {
-  GList **list = data;
-  *list = g_list_append(*list, key);
-}
-
-
-GList *map_collect_keys(GHashTable *ht) {
-  GList *ret = NULL;
-  g_hash_table_foreach(ht, collect_keys, &ret);
-  return ret;
-}
-
-
-static void collect_values(gpointer key, gpointer val, gpointer data) {
-  GList **list = data;
-  *list = g_list_append(*list, val);
-}
-
-
-GList *map_collect_values(GHashTable *ht) {
-  GList *ret = NULL;
-  g_hash_table_foreach(ht, collect_values, &ret);
-  return ret;
-}
-
-
-struct mw_datum *mw_datum_new(gpointer data, GDestroyNotify clear) {
-  struct mw_datum *d = g_new(struct mw_datum, 1);
-  mw_datum_set(d, data, clear);
-  return d;
-}
-
-
-void mw_datum_set(struct mw_datum *d, gpointer data, GDestroyNotify clear) {
-  d->data = data;
-  d->clear = clear;
-}
-
-
-gpointer mw_datum_get(struct mw_datum *d) {
-  return d->data;
-}
-
-
-void mw_datum_clear(struct mw_datum *d) {
-  if(d->clear) {
-    d->clear(d->data);
-    d->clear = NULL;
-  }
-  d->data = NULL;
-}
-
-
-void mw_datum_free(struct mw_datum *d) {
-  mw_datum_clear(d);
-  g_free(d);
-}
--- a/src/protocols/sametime/meanwhile/mw_util.h	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MW_UTIL_H
-#define _MW_UTIL_H
-
-
-#include <glib.h>
-#include <glib/ghash.h>
-#include <glib/glist.h>
-
-
-#define map_guint_new() \
-  g_hash_table_new(g_direct_hash, g_direct_equal)
-
-
-#define map_guint_new_full(valfree) \
-  g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (valfree))
-
-
-#define map_guint_insert(ht, key, val) \
-  g_hash_table_insert((ht), GUINT_TO_POINTER((guint)(key)), (val))
-
-
-#define map_guint_replace(ht, key, val) \
-  g_hash_table_replace((ht), GUINT_TO_POINTER((guint)(key)), (val))
-
-
-#define map_guint_lookup(ht, key) \
-  g_hash_table_lookup((ht), GUINT_TO_POINTER((guint)(key)))
-
-
-#define map_guint_remove(ht, key) \
-  g_hash_table_remove((ht), GUINT_TO_POINTER((guint)(key)))
-
-
-#define map_guint_steal(ht, key) \
-  g_hash_table_steal((ht), GUINT_TO_POINTER((guint)(key)))
-
-
-GList *map_collect_keys(GHashTable *ht);
-
-
-GList *map_collect_values(GHashTable *ht);
-
-
-struct mw_datum {
-  gpointer data;
-  GDestroyNotify clear;
-};
-
-
-struct mw_datum *mw_datum_new(gpointer data, GDestroyNotify clear);
-
-
-void mw_datum_set(struct mw_datum *d, gpointer data, GDestroyNotify clear);
-
-
-gpointer mw_datum_get(struct mw_datum *d);
-
-
-void mw_datum_clear(struct mw_datum *d);
-
-
-void mw_datum_free(struct mw_datum *d);
-
-
-#endif
--- a/src/protocols/sametime/meanwhile/service.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,267 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include "mw_channel.h"
-#include "mw_debug.h"
-#include "mw_error.h"
-#include "mw_message.h"
-#include "mw_service.h"
-
-
-/* I tried to be explicit with the g_return_* calls, to make the debug
-   logging a bit more sensible. Hence all the explicit "foo != NULL"
-   checks. */
-
-
-void mwService_recvCreate(struct mwService *s, struct mwChannel *chan,
-			  struct mwMsgChannelCreate *msg) {
-
-  /* ensure none are null, ensure that the service and channel belong
-     to the same session, and ensure that the message belongs on the
-     channel */
-  g_return_if_fail(s != NULL);
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(msg != NULL);
-  g_return_if_fail(s->session == mwChannel_getSession(chan));
-  g_return_if_fail(mwChannel_getId(chan) == msg->channel);
-
-  if(s->recv_create) {
-    s->recv_create(s, chan, msg);
-  } else {
-    mwChannel_destroy(chan, ERR_FAILURE, NULL);
-  }
-}
-
-
-void mwService_recvAccept(struct mwService *s, struct mwChannel *chan,
-			  struct mwMsgChannelAccept *msg) {
-
-  /* ensure none are null, ensure that the service and channel belong
-     to the same session, and ensure that the message belongs on the
-     channel */
-  g_return_if_fail(s != NULL);
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(msg != NULL);
-  g_return_if_fail(s->session == mwChannel_getSession(chan));
-  g_return_if_fail(mwChannel_getId(chan) == msg->head.channel);
-
-  if(s->recv_accept)
-    s->recv_accept(s, chan, msg);
-}
-
-
-void mwService_recvDestroy(struct mwService *s, struct mwChannel *chan,
-			   struct mwMsgChannelDestroy *msg) {
-
-  /* ensure none are null, ensure that the service and channel belong
-     to the same session, and ensure that the message belongs on the
-     channel */
-  g_return_if_fail(s != NULL);
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(msg != NULL);
-  g_return_if_fail(s->session == mwChannel_getSession(chan));
-  g_return_if_fail(mwChannel_getId(chan) == msg->head.channel);
-
-  if(s->recv_destroy)
-    s->recv_destroy(s, chan, msg);
-}
-
-
-void mwService_recv(struct mwService *s, struct mwChannel *chan,
-		    guint16 msg_type, struct mwOpaque *data) {
-
-  /* ensure that none are null. zero-length messages are acceptable */
-  g_return_if_fail(s != NULL);
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(data != NULL);
-  g_return_if_fail(s->session == mwChannel_getSession(chan));
-
-  /*
-  g_message("mwService_recv: session = %p, service = %p, b = %p, n = %u",
-	    mwService_getSession(s), s, data->data, data->len);
-  */
-
-  if(s->recv)
-    s->recv(s, chan, msg_type, data);
-}
-
-
-guint32 mwService_getType(struct mwService *s) {
-  g_return_val_if_fail(s != NULL, 0x00);
-  return s->type;
-}
-
-
-const char *mwService_getName(struct mwService *s) {
-  g_return_val_if_fail(s != NULL, NULL);
-  g_return_val_if_fail(s->get_name != NULL, NULL);
-
-  return s->get_name(s);
-}
-
-
-const char *mwService_getDesc(struct mwService *s) {
-  g_return_val_if_fail(s != NULL, NULL);
-  g_return_val_if_fail(s->get_desc != NULL, NULL);
-
-  return s->get_desc(s);
-}
-
-
-struct mwSession *mwService_getSession(struct mwService *s) {
-  g_return_val_if_fail(s != NULL, NULL);
-  return s->session;
-}
-
-
-void mwService_init(struct mwService *srvc, struct mwSession *sess,
-		    guint32 type) {
-
-  /* ensure nothing is null, and there's no such thing as a zero
-     service type */
-  g_return_if_fail(srvc != NULL);
-  g_return_if_fail(sess != NULL);
-  g_return_if_fail(type != 0x00);
-
-  srvc->session = sess;
-  srvc->type = type;
-  srvc->state = mwServiceState_STOPPED;
-}
-
-
-enum mwServiceState mwService_getState(struct mwService *srvc) {
-  g_return_val_if_fail(srvc != NULL, mwServiceState_STOPPED);
-  return srvc->state;
-}
-
-
-void mwService_start(struct mwService *srvc) {
-  g_return_if_fail(srvc != NULL);
-
-  if(! MW_SERVICE_IS_STOPPED(srvc))
-    return;
-
-  srvc->state = mwServiceState_STARTING;
-  g_message("starting service %s", NSTR(mwService_getName(srvc)));
-
-  if(srvc->start) {
-    srvc->start(srvc);
-  } else {
-    mwService_started(srvc);
-  }
-}
-
-
-void mwService_started(struct mwService *srvc) {
-  g_return_if_fail(srvc != NULL);
-
-  srvc->state = mwServiceState_STARTED;
-  g_message("started service %s", NSTR(mwService_getName(srvc)));
-}
-
-
-void mwService_error(struct mwService *srvc) {
-  g_return_if_fail(srvc != NULL);
-
-  if(MW_SERVICE_IS_DEAD(srvc))
-    return;
-
-  srvc->state = mwServiceState_ERROR;
-  g_message("error in service %s", NSTR(mwService_getName(srvc)));
-
-  if(srvc->stop) {
-    srvc->stop(srvc);
-  } else {
-    mwService_stopped(srvc);
-  }
-}
-
-
-void mwService_stop(struct mwService *srvc) {
-  g_return_if_fail(srvc != NULL);
-
-  if(MW_SERVICE_IS_DEAD(srvc))
-    return;
-
-  srvc->state = mwServiceState_STOPPING;
-  g_message("stopping service %s", NSTR(mwService_getName(srvc)));
-
-  if(srvc->stop) {
-    srvc->stop(srvc);
-  } else {
-    mwService_stopped(srvc);
-  }
-}
-
-
-void mwService_stopped(struct mwService *srvc) {
-  g_return_if_fail(srvc != NULL);
-
-  if(srvc->state != mwServiceState_STOPPED) {
-    srvc->state = mwServiceState_STOPPED;
-    g_message("stopped service %s", NSTR(mwService_getName(srvc)));
-  }
-}
-
-
-void mwService_free(struct mwService *srvc) {
-  g_return_if_fail(srvc != NULL);
-
-  mwService_stop(srvc);
-
-  if(srvc->clear)
-    srvc->clear(srvc);
-
-  if(srvc->client_cleanup)
-    srvc->client_cleanup(srvc->client_data);
-
-  g_free(srvc);
-}
-
-
-/** @todo switch the following to using mw_datum */
-
-void mwService_setClientData(struct mwService *srvc,
-			     gpointer data, GDestroyNotify cleanup) {
-
-  g_return_if_fail(srvc != NULL);
-
-  srvc->client_data = data;
-  srvc->client_cleanup = cleanup;
-}
-
-
-gpointer mwService_getClientData(struct mwService *srvc) {
-  g_return_val_if_fail(srvc != NULL, NULL);
-  return srvc->client_data;
-}
-
-
-void mwService_removeClientData(struct mwService *srvc) {
-  g_return_if_fail(srvc != NULL);
-
-  if(srvc->client_cleanup) {
-    srvc->client_cleanup(srvc->client_data);
-    srvc->client_cleanup = NULL;
-  }
-
-  srvc->client_data = NULL;
-}
-
--- a/src/protocols/sametime/meanwhile/session.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1206 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <glib.h>
-#include <string.h>
-
-#include "mw_channel.h"
-#include "mw_cipher.h"
-#include "mw_debug.h"
-#include "mw_error.h"
-#include "mw_message.h"
-#include "mw_service.h"
-#include "mw_session.h"
-#include "mw_util.h"
-
-
-/** the hash table key for a service, for mwSession::services */
-#define SERVICE_KEY(srvc) mwService_getType(srvc)
-
-/** the hash table key for a cipher, for mwSession::ciphers */
-#define CIPHER_KEY(ciph)  mwCipher_getType(ciph)
-
-
-#define GPOINTER(val)  (GUINT_TO_POINTER((guint) (val)))
-#define GUINT(val)     (GPOINTER_TO_UINT((val)))
-
-
-struct mwSession {
-
-  /** provides I/O and callback functions */
-  struct mwSessionHandler *handler;
-
-  enum mwSessionState state;  /**< session state */
-  gpointer state_info;        /**< additional state info */
-
-  /* input buffering for an incoming message */
-  guchar *buf;  /**< buffer for incoming message data */
-  gsize buf_len;       /**< length of buf */
-  gsize buf_used;      /**< offset to last-used byte of buf */
-  
-  struct mwLoginInfo login;      /**< login information */
-  struct mwUserStatus status;    /**< user status */
-  struct mwPrivacyInfo privacy;  /**< privacy list */
-
-  /** the collection of channels */
-  struct mwChannelSet *channels;
-
-  /** the collection of services, keyed to guint32 service id */
-  GHashTable *services;
-
-  /** the collection of ciphers, keyed to guint16 cipher type */
-  GHashTable *ciphers;
-
-  /** arbitrary key:value pairs */
-  GHashTable *attributes;
-
-  /** optional user data */
-  struct mw_datum client_data;
-};
-
-
-static void property_set(struct mwSession *s, const char *key,
-			 gpointer val, GDestroyNotify clean) {
-
-  g_hash_table_insert(s->attributes, g_strdup(key),
-		      mw_datum_new(val, clean));
-}
-
-
-static gpointer property_get(struct mwSession *s, const char *key) {
-  struct mw_datum *p = g_hash_table_lookup(s->attributes, key);
-  return p? p->data: NULL;
-}
-
-
-static void property_del(struct mwSession *s, const char *key) {
-  g_hash_table_remove(s->attributes, key);
-}
-
-
-/**
-   set up the default properties for a newly created session
-*/
-static void session_defaults(struct mwSession *s) {
-  property_set(s, mwSession_CLIENT_VER_MAJOR,
-	       GPOINTER(MW_PROTOCOL_VERSION_MAJOR), NULL);
-
-  property_set(s, mwSession_CLIENT_VER_MINOR, 
-	       GPOINTER(MW_PROTOCOL_VERSION_MINOR), NULL);
-
-  property_set(s, mwSession_CLIENT_TYPE_ID,
-	       GPOINTER(mwLogin_MEANWHILE), NULL);
-}
-
-
-struct mwSession *mwSession_new(struct mwSessionHandler *handler) {
-  struct mwSession *s;
-
-  g_return_val_if_fail(handler != NULL, NULL);
-
-  /* consider io_write and io_close to be absolute necessities */
-  g_return_val_if_fail(handler->io_write != NULL, NULL);
-  g_return_val_if_fail(handler->io_close != NULL, NULL);
-
-  s = g_new0(struct mwSession, 1);
-
-  s->state = mwSession_STOPPED;
-
-  s->handler = handler;
-
-  s->channels = mwChannelSet_new(s);
-  s->services = map_guint_new();
-  s->ciphers = map_guint_new();
-
-  s->attributes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
-					(GDestroyNotify) mw_datum_free);
-
-  session_defaults(s);
-
-  return s;
-}
-
-
-/** free and reset the session buffer */
-static void session_buf_free(struct mwSession *s) {
-  g_return_if_fail(s != NULL);
-
-  g_free(s->buf);
-  s->buf = NULL;
-  s->buf_len = 0;
-  s->buf_used = 0;
-}
-
-
-/** a polite string version of the session state enum */
-static const char *state_str(enum mwSessionState state) {
-  switch(state) {
-  case mwSession_STARTING:      return "starting";
-  case mwSession_HANDSHAKE:     return "handshake sent";
-  case mwSession_HANDSHAKE_ACK: return "handshake acknowledged";
-  case mwSession_LOGIN:         return "login sent";
-  case mwSession_LOGIN_REDIR:   return "login redirected";
-  case mwSession_LOGIN_CONT:    return "forcing login";
-  case mwSession_LOGIN_ACK:     return "login acknowledged";
-  case mwSession_STARTED:       return "started";
-  case mwSession_STOPPING:      return "stopping";
-  case mwSession_STOPPED:       return "stopped";
-
-  case mwSession_UNKNOWN:       /* fall-through */
-  default:                      return "UNKNOWN";
-  }
-}
-
-
-void mwSession_free(struct mwSession *s) {
-  struct mwSessionHandler *h;
-
-  g_return_if_fail(s != NULL);
-
-  if(! mwSession_isStopped(s)) {
-    g_debug("session is not stopped (state: %s), proceeding with free",
-	    state_str(s->state));
-  }
-
-  h = s->handler;
-  if(h && h->clear) h->clear(s);
-  s->handler = NULL;
-
-  session_buf_free(s);
-
-  mwChannelSet_free(s->channels);
-  g_hash_table_destroy(s->services);
-  g_hash_table_destroy(s->ciphers);
-  g_hash_table_destroy(s->attributes);
-
-  mwLoginInfo_clear(&s->login);
-  mwUserStatus_clear(&s->status);
-  mwPrivacyInfo_clear(&s->privacy);
-
-  g_free(s);
-}
-
-
-/** write data to the session handler */
-static int io_write(struct mwSession *s, const guchar *buf, gsize len) {
-  g_return_val_if_fail(s != NULL, -1);
-  g_return_val_if_fail(s->handler != NULL, -1);
-  g_return_val_if_fail(s->handler->io_write != NULL, -1);
-
-  return s->handler->io_write(s, buf, len);
-}
-
-
-/** close the session handler */
-static void io_close(struct mwSession *s) {
-  g_return_if_fail(s != NULL);
-  g_return_if_fail(s->handler != NULL);
-  g_return_if_fail(s->handler->io_close != NULL);
-
-  s->handler->io_close(s);
-}
-
-
-static void state(struct mwSession *s, enum mwSessionState state,
-		  gpointer info) {
-
-  struct mwSessionHandler *sh;
-
-  g_return_if_fail(s != NULL);
-  g_return_if_fail(s->handler != NULL);
-
-  if(mwSession_isState(s, state)) return;
-
-  s->state = state;
-  s->state_info = info;
-
-  switch(state) {
-  case mwSession_STOPPING:
-  case mwSession_STOPPED:
-    g_message("session state: %s (0x%08x)", state_str(state),
-	      GPOINTER_TO_UINT(info));
-    break;
-
-  case mwSession_LOGIN_REDIR:
-    g_message("session state: %s (%s)", state_str(state),
-	      (char *)info);
-    break;
-
-  default:
-    g_message("session state: %s", state_str(state));
-  }
-
-  sh = s->handler;
-  if(sh && sh->on_stateChange)
-    sh->on_stateChange(s, state, info);
-}
-
-
-void mwSession_start(struct mwSession *s) {
-  struct mwMsgHandshake *msg;
-  int ret;
-
-  g_return_if_fail(s != NULL);
-  g_return_if_fail(mwSession_isStopped(s));
-
-  if(mwSession_isStarted(s) || mwSession_isStarting(s)) {
-    g_debug("attempted to start session that is already started/starting");
-    return;
-  }
-  
-  state(s, mwSession_STARTING, 0);
-
-  msg = (struct mwMsgHandshake *) mwMessage_new(mwMessage_HANDSHAKE);
-  msg->major = GUINT(property_get(s, mwSession_CLIENT_VER_MAJOR));
-  msg->minor = GUINT(property_get(s, mwSession_CLIENT_VER_MINOR));
-  msg->login_type = GUINT(property_get(s, mwSession_CLIENT_TYPE_ID));
-
-  msg->loclcalc_addr = GUINT(property_get(s, mwSession_CLIENT_IP));
-
-  if(msg->major >= 0x001e && msg->minor >= 0x001d) {
-    msg->unknown_a = 0x0100;
-    msg->local_host = (char *) property_get(s, mwSession_CLIENT_HOST);
-  }
-
-  ret = mwSession_send(s, MW_MESSAGE(msg));
-  mwMessage_free(MW_MESSAGE(msg));
-
-  if(ret) {
-    mwSession_stop(s, CONNECTION_BROKEN);
-  } else {
-    state(s, mwSession_HANDSHAKE, 0);
-  }
-}
-
-
-void mwSession_stop(struct mwSession *s, guint32 reason) {
-  GList *list, *l = NULL;
-  struct mwMsgChannelDestroy *msg;
-
-  g_return_if_fail(s != NULL);
-  
-  if(mwSession_isStopped(s) || mwSession_isStopping(s)) {
-    g_debug("attempted to stop session that is already stopped/stopping");
-    return;
-  }
-
-  state(s, mwSession_STOPPING, GUINT_TO_POINTER(reason));
-
-  for(list = l = mwSession_getServices(s); l; l = l->next)
-    mwService_stop(MW_SERVICE(l->data));
-  g_list_free(list);
-
-  msg = (struct mwMsgChannelDestroy *)
-    mwMessage_new(mwMessage_CHANNEL_DESTROY);
-
-  msg->head.channel = MW_MASTER_CHANNEL_ID;
-  msg->reason = reason;
-
-  /* don't care if this fails, we're closing the connection anyway */
-  mwSession_send(s, MW_MESSAGE(msg));
-  mwMessage_free(MW_MESSAGE(msg));
-
-  session_buf_free(s);
-
-  /* close the connection */
-  io_close(s);
-
-  state(s, mwSession_STOPPED, GUINT_TO_POINTER(reason));
-}
-
-
-/** compose authentication information into an opaque based on the
-    password, encrypted via RC2/40 */
-static void compose_auth_rc2_40(struct mwOpaque *auth, const char *pass) {
-  guchar iv[8], key[5];
-  struct mwOpaque a, b, z;
-  struct mwPutBuffer *p;
-
-  /* get an IV and a random five-byte key */
-  mwIV_init(iv);
-  mwKeyRandom(key, 5);
-
-  /* the opaque with the key */
-  a.len = 5;
-  a.data = key;
-
-  /* the opaque to receive the encrypted pass */
-  b.len = 0;
-  b.data = NULL;
-
-  /* the plain-text pass dressed up as an opaque */
-  z.len = strlen(pass);
-  z.data = (guchar *) pass;
-
-  /* the opaque with the encrypted pass */
-  mwEncrypt(a.data, a.len, iv, &z, &b);
-
-  /* an opaque containing the other two opaques */
-  p = mwPutBuffer_new();
-  mwOpaque_put(p, &a);
-  mwOpaque_put(p, &b);
-  mwPutBuffer_finalize(auth, p);
-
-  /* this is the only one to clear, as the other uses a static buffer */
-  mwOpaque_clear(&b);
-}
-
-
-static void compose_auth_rc2_128(struct mwOpaque *auth, const char *pass,
-				 guint32 magic, struct mwOpaque *rkey) {
-
-  guchar iv[8];
-  struct mwOpaque a, b, c;
-  struct mwPutBuffer *p;
-
-  struct mwMpi *private, *public;
-  struct mwMpi *remote;
-  struct mwMpi *shared;
-
-  private = mwMpi_new();
-  public = mwMpi_new();
-  remote = mwMpi_new();
-  shared = mwMpi_new();
-
-  mwIV_init(iv);
-
-  mwMpi_randDHKeypair(private, public);
-  mwMpi_import(remote, rkey);
-  mwMpi_calculateDHShared(shared, remote, private);
-
-  /* put the password in opaque a */
-  p = mwPutBuffer_new();
-  guint32_put(p, magic);
-  mwString_put(p, pass);
-  mwPutBuffer_finalize(&a, p);
-
-  /* put the shared key in opaque b */
-  mwMpi_export(shared, &b);
-
-  /* encrypt the password (a) using the shared key (b), put the result
-     in opaque c */
-  mwEncrypt(b.data+(b.len-16), 16, iv, &a, &c);
-
-  /* don't need the shared key anymore, re-use opaque (b) as the
-     export of the public key */
-  mwOpaque_clear(&b);
-  mwMpi_export(public, &b);
-
-  p = mwPutBuffer_new();
-  guint16_put(p, 0x0001);  /* XXX: unknown */
-  mwOpaque_put(p, &b);
-  mwOpaque_put(p, &c);
-  mwPutBuffer_finalize(auth, p);
-
-  mwOpaque_clear(&a);
-  mwOpaque_clear(&b);
-  mwOpaque_clear(&c);
-
-  mwMpi_free(private);
-  mwMpi_free(public);
-  mwMpi_free(remote);
-  mwMpi_free(shared);
-}
-
-
-/** handle the receipt of a handshake_ack message by sending the login
-    message */
-static void HANDSHAKE_ACK_recv(struct mwSession *s,
-			       struct mwMsgHandshakeAck *msg) {
-  struct mwMsgLogin *log;
-  int ret;
-			       
-  g_return_if_fail(s != NULL);
-  g_return_if_fail(msg != NULL);
-  g_return_if_fail(mwSession_isState(s, mwSession_HANDSHAKE) ||
-		   mwSession_isState(s, mwSession_LOGIN_CONT));
-
-  if(mwSession_isState(s, mwSession_LOGIN_CONT)) {
-    /* this is a login continuation, don't re-send the login. We
-       should receive a login ack in a moment */
-
-    state(s, mwSession_HANDSHAKE_ACK, 0);
-    state(s, mwSession_LOGIN, 0);
-    return;
-
-  } else {
-    state(s, mwSession_HANDSHAKE_ACK, 0);
-  }
-
-  /* record the major/minor versions from the server */
-  property_set(s, mwSession_SERVER_VER_MAJOR, GPOINTER(msg->major), NULL);
-  property_set(s, mwSession_SERVER_VER_MINOR, GPOINTER(msg->minor), NULL);
-
-  /* compose the login message */
-  log = (struct mwMsgLogin *) mwMessage_new(mwMessage_LOGIN);
-  log->login_type = GUINT(property_get(s, mwSession_CLIENT_TYPE_ID));
-  log->name = g_strdup(property_get(s, mwSession_AUTH_USER_ID));
-
-  /** @todo default to password for now. later use token optionally */
-  {
-    const char *pw;
-    pw = (const char *) property_get(s, mwSession_AUTH_PASSWORD);
-   
-    if(msg->data.len >= 64) {
-      /* good login encryption */
-      log->auth_type = mwAuthType_RC2_128;
-      compose_auth_rc2_128(&log->auth_data, pw, msg->magic, &msg->data);
-
-    } else {
-      /* BAD login encryption */
-      log->auth_type = mwAuthType_RC2_40;
-      compose_auth_rc2_40(&log->auth_data, pw);
-    }
-  }
-  
-  /* send the login message */
-  ret = mwSession_send(s, MW_MESSAGE(log));
-  mwMessage_free(MW_MESSAGE(log));
-
-  if(! ret) {
-    /* sent login OK, set state appropriately */
-    state(s, mwSession_LOGIN, 0);
-  }
-}
-
-
-/** handle the receipt of a login_ack message. This completes the
-    startup sequence for the session */
-static void LOGIN_ACK_recv(struct mwSession *s,
-			   struct mwMsgLoginAck *msg) {
-  GList *ll, *l;
-
-  g_return_if_fail(s != NULL);
-  g_return_if_fail(msg != NULL);
-  g_return_if_fail(mwSession_isState(s, mwSession_LOGIN));
-
-  /* store the login information in the session */
-  mwLoginInfo_clear(&s->login);
-  mwLoginInfo_clone(&s->login, &msg->login);
-
-  state(s, mwSession_LOGIN_ACK, 0);
-
-  /* start up our services */
-  for(ll = l = mwSession_getServices(s); l; l = l->next) {
-    mwService_start(l->data);
-  }
-  g_list_free(ll);
-
-  /* @todo any further startup stuff? */
-
-  state(s, mwSession_STARTED, 0);
-}
-
-
-static void CHANNEL_CREATE_recv(struct mwSession *s,
-				struct mwMsgChannelCreate *msg) {
-  struct mwChannel *chan;
-  chan = mwChannel_newIncoming(s->channels, msg->channel);
-
-  /* hand off to channel */
-  mwChannel_recvCreate(chan, msg);
-}
-
-
-static void CHANNEL_ACCEPT_recv(struct mwSession *s,
-				struct mwMsgChannelAccept *msg) {
-  struct mwChannel *chan;
-  chan = mwChannel_find(s->channels, msg->head.channel);
-
-  g_return_if_fail(chan != NULL);
-
-  /* hand off to channel */
-  mwChannel_recvAccept(chan, msg);
-}
-
-
-static void CHANNEL_DESTROY_recv(struct mwSession *s,
-				 struct mwMsgChannelDestroy *msg) {
-
-  /* the server can indicate that we should close the session by
-     destroying the zero channel */
-  if(msg->head.channel == MW_MASTER_CHANNEL_ID) {
-    mwSession_stop(s, msg->reason);
-
-  } else {
-    struct mwChannel *chan;
-    chan = mwChannel_find(s->channels, msg->head.channel);
-
-    /* we don't have any such channel... so I guess we destroyed it.
-       This is to remove a warning from timing errors when two clients
-       both try to close a channel at about the same time. */
-    if(! chan) return;
-    
-    /* hand off to channel */
-    mwChannel_recvDestroy(chan, msg);
-  }
-}
-
-
-static void CHANNEL_SEND_recv(struct mwSession *s,
-			      struct mwMsgChannelSend *msg) {
-  struct mwChannel *chan;
-  chan = mwChannel_find(s->channels, msg->head.channel);
-
-  /* if we don't have any such channel, we're certainly not going to
-     accept data from it */
-  if(! chan) return;
-
-  /* hand off to channel */
-  mwChannel_recv(chan, msg);
-}
-
-
-static void SET_PRIVACY_LIST_recv(struct mwSession *s,
-				  struct mwMsgSetPrivacyList *msg) {
-  struct mwSessionHandler *sh = s->handler;
-
-  g_info("SET_PRIVACY_LIST");
-
-  mwPrivacyInfo_clear(&s->privacy);
-  mwPrivacyInfo_clone(&s->privacy, &msg->privacy);
-
-  if(sh && sh->on_setPrivacyInfo)
-    sh->on_setPrivacyInfo(s);
-}
-
-
-static void SET_USER_STATUS_recv(struct mwSession *s,
-				 struct mwMsgSetUserStatus *msg) {
-  struct mwSessionHandler *sh = s->handler;
-
-  mwUserStatus_clear(&s->status);
-  mwUserStatus_clone(&s->status, &msg->status);
-
-  if(sh && sh->on_setUserStatus)
-    sh->on_setUserStatus(s);
-}
-
-
-static void SENSE_SERVICE_recv(struct mwSession *s,
-			       struct mwMsgSenseService *msg) {
-  struct mwService *srvc;
-
-  srvc = mwSession_getService(s, msg->service);
-  if(srvc) mwService_start(srvc);
-}
-
-
-static void ADMIN_recv(struct mwSession *s, struct mwMsgAdmin *msg) {
-  struct mwSessionHandler *sh = s->handler;
-
-  if(sh && sh->on_admin)
-    sh->on_admin(s, msg->text);
-}
-
-
-static void ANNOUNCE_recv(struct mwSession *s, struct mwMsgAnnounce *msg) {
-  struct mwSessionHandler *sh = s->handler;
-
-  if(sh && sh->on_announce)
-    sh->on_announce(s, &msg->sender, msg->may_reply, msg->text);
-}
-
-
-static void LOGIN_REDIRECT_recv(struct mwSession *s,
-				struct mwMsgLoginRedirect *msg) {
-
-  state(s, mwSession_LOGIN_REDIR, msg->host);
-}
-
-
-#define CASE(var, type) \
-case mwMessage_ ## var: \
-  var ## _recv(s, (struct type *) msg); \
-  break;
-
-
-static void session_process(struct mwSession *s,
-			    const guchar *buf, gsize len) {
-
-  struct mwOpaque o = { .len = len, .data = (guchar *) buf };
-  struct mwGetBuffer *b;
-  struct mwMessage *msg;
-
-  g_return_if_fail(s != NULL);
-  g_return_if_fail(buf != NULL);
-
-  /* ignore zero-length messages */
-  if(len == 0) return;
-
-  /* wrap up buf */
-  b = mwGetBuffer_wrap(&o);
-
-  /* attempt to parse the message. */
-  msg = mwMessage_get(b);
-
-  if(mwGetBuffer_error(b)) {
-    mw_mailme_opaque(&o, "parsing of message failed");
-  }
-
-  mwGetBuffer_free(b);
-
-  g_return_if_fail(msg != NULL);
-
-  /* handle each of the appropriate incoming types of mwMessage */
-  switch(msg->type) {
-    CASE(HANDSHAKE_ACK, mwMsgHandshakeAck);
-    CASE(LOGIN_REDIRECT, mwMsgLoginRedirect);
-    CASE(LOGIN_ACK, mwMsgLoginAck);
-    CASE(CHANNEL_CREATE, mwMsgChannelCreate);
-    CASE(CHANNEL_DESTROY, mwMsgChannelDestroy);
-    CASE(CHANNEL_SEND, mwMsgChannelSend);
-    CASE(CHANNEL_ACCEPT, mwMsgChannelAccept);
-    CASE(SET_PRIVACY_LIST, mwMsgSetPrivacyList);
-    CASE(SET_USER_STATUS, mwMsgSetUserStatus);
-    CASE(SENSE_SERVICE, mwMsgSenseService);
-    CASE(ADMIN, mwMsgAdmin);
-    CASE(ANNOUNCE, mwMsgAnnounce);
-    
-  default:
-    g_warning("unknown message type 0x%04x, no handler", msg->type);
-  }
-
-  mwMessage_free(msg);
-}
-
-
-#undef CASE
-
-
-#define ADVANCE(b, n, count) { b += count; n -= count; }
-
-
-/* handle input to complete an existing buffer */
-static gsize session_recv_cont(struct mwSession *s,
-			       const guchar *b, gsize n) {
-
-  /* determine how many bytes still required */
-  gsize x = s->buf_len - s->buf_used;
-
-  /* g_message(" session_recv_cont: session = %p, b = %p, n = %u",
-	    s, b, n); */
-  
-  if(n < x) {
-    /* not quite enough; still need some more */
-    memcpy(s->buf+s->buf_used, b, n);
-    s->buf_used += n;
-    return 0;
-    
-  } else {
-    /* enough to finish the buffer, at least */
-    memcpy(s->buf+s->buf_used, b, x);
-    ADVANCE(b, n, x);
-    
-    if(s->buf_len == 4) {
-      /* if only the length bytes were being buffered, we'll now try
-       to complete an actual message */
-
-      struct mwOpaque o = { 4, s->buf };
-      struct mwGetBuffer *gb = mwGetBuffer_wrap(&o);
-      x = guint32_peek(gb);
-      mwGetBuffer_free(gb);
-
-      if(n < x) {
-	/* there isn't enough to meet the demands of the length, so
-	   we'll buffer it for next time */
-
-	guchar *t;
-	x += 4;
-	t = (guchar *) g_malloc(x);
-	memcpy(t, s->buf, 4);
-	memcpy(t+4, b, n);
-	
-	session_buf_free(s);
-	
-	s->buf = t;
-	s->buf_len = x;
-	s->buf_used = n + 4;
-	return 0;
-	
-      } else {
-	/* there's enough (maybe more) for a full message. don't need
-	   the old session buffer (which recall, was only the length
-	   bytes) any more */
-	
-	session_buf_free(s);
-	session_process(s, b, x);
-	ADVANCE(b, n, x);
-      }
-      
-    } else {
-      /* process the now-complete buffer. remember to skip the first
-	 four bytes, since they're just the size count */
-      session_process(s, s->buf+4, s->buf_len-4);
-      session_buf_free(s);
-    }
-  }
-
-  return n;
-}
-
-
-/* handle input when there's nothing previously buffered */
-static gsize session_recv_empty(struct mwSession *s,
-				const guchar *b, gsize n) {
-
-  struct mwOpaque o = { n, (guchar *) b };
-  struct mwGetBuffer *gb;
-  gsize x;
-
-  if(n < 4) {
-    /* uh oh. less than four bytes means we've got an incomplete
-       length indicator. Have to buffer to get the rest of it. */
-    s->buf = (guchar *) g_malloc0(4);
-    memcpy(s->buf, b, n);
-    s->buf_len = 4;
-    s->buf_used = n;
-    return 0;
-  }
-  
-  /* peek at the length indicator. if it's a zero length message,
-     don't process, just skip it */
-  gb = mwGetBuffer_wrap(&o);
-  x = guint32_peek(gb);
-  mwGetBuffer_free(gb);
-  if(! x) return n - 4;
-
-  if(n < (x + 4)) {
-    /* if the total amount of data isn't enough to cover the length
-       bytes and the length indicated by those bytes, then we'll need
-       to buffer. This is where the DOS mentioned below in
-       session_recv takes place */
-
-    x += 4;
-    s->buf = (guchar *) g_malloc(x);
-    memcpy(s->buf, b, n);
-    s->buf_len = x;
-    s->buf_used = n;
-    return 0;
-    
-  } else {
-    /* advance past length bytes */
-    ADVANCE(b, n, 4);
-    
-    /* process and advance */
-    session_process(s, b, x);
-    ADVANCE(b, n, x);
-
-    /* return left-over count */
-    return n;
-  }
-}
-
-
-static gsize session_recv(struct mwSession *s,
-			  const guchar *b, gsize n) {
-
-  /* This is messy and kind of confusing. I'd like to simplify it at
-     some point, but the constraints are as follows:
-
-      - buffer up to a single full message on the session buffer
-      - buffer must contain the four length bytes
-      - the four length bytes indicate how much we'll need to buffer
-      - the four length bytes might not arrive all at once, so it's
-        possible that we'll need to buffer to get them.
-      - since our buffering includes the length bytes, we know we
-        still have an incomplete length if the buffer length is only
-        four. */
-  
-  /** @todo we should allow a compiled-in upper limit to message
-     sizes, and just drop messages over that size. However, to do that
-     we'd need to keep track of the size of a message and keep
-     dropping bytes until we'd fulfilled the entire length. eg: if we
-     receive a message size of 10MB, we need to pass up exactly 10MB
-     before it's safe to start processing the rest as a new
-     message. As it stands, a malicious packet from the server can run
-     us out of memory by indicating it's going to send us some
-     obscenely long message (even if it never actually sends it) */
-  
-  /* g_message(" session_recv: session = %p, b = %p, n = %u",
-	    s, b, n); */
-  
-  if(s->buf_len == 0) {
-    while(n && (*b & 0x80)) {
-      /* keep-alive and series bytes are ignored */
-      ADVANCE(b, n, 1);
-    }
-  }
-
-  if(n == 0) {
-    return 0;
-
-  } else if(s->buf_len > 0) {
-    return session_recv_cont(s, b, n);
-
-  } else {
-    return session_recv_empty(s, b, n);
-  }
-}
-
-
-#undef ADVANCE
-
-
-void mwSession_recv(struct mwSession *s, const guchar *buf, gsize n) {
-  guchar *b = (guchar *) buf;
-  gsize remain = 0;
-
-  g_return_if_fail(s != NULL);
-
-  while(n > 0) {
-    remain = session_recv(s, b, n);
-    b += (n - remain);
-    n = remain;
-  }
-}
-
-
-int mwSession_send(struct mwSession *s, struct mwMessage *msg) {
-  struct mwPutBuffer *b;
-  struct mwOpaque o;
-  int ret = 0;
-
-  g_return_val_if_fail(s != NULL, -1);
-
-  /* writing nothing is easy */
-  if(! msg) return 0;
-
-  /* first we render the message into an opaque */
-  b = mwPutBuffer_new();
-  mwMessage_put(b, msg);
-  mwPutBuffer_finalize(&o, b);
-
-  /* then we render the opaque into... another opaque! */
-  b = mwPutBuffer_new();
-  mwOpaque_put(b, &o);
-  mwOpaque_clear(&o);
-  mwPutBuffer_finalize(&o, b);
-
-  /* then we use that opaque's data and length to write to the socket */
-  ret = io_write(s, o.data, o.len);
-  mwOpaque_clear(&o);
-
-  /* ensure we could actually write the message */
-  if(! ret) {
-
-    /* special case, as the server doesn't always respond to user
-       status messages. Thus, we trigger the event when we send the
-       messages as well as when we receive them */
-    if(msg->type == mwMessage_SET_USER_STATUS) {
-      SET_USER_STATUS_recv(s, (struct mwMsgSetUserStatus *) msg);
-    }
-  }
-
-  return ret;
-}
-
-
-int mwSession_sendKeepalive(struct mwSession *s) {
-  const guchar b = 0x80;
-
-  g_return_val_if_fail(s != NULL, -1);
-  return io_write(s, &b, 1);
-}
-
-
-int mwSession_forceLogin(struct mwSession *s) {
-  struct mwMsgLoginContinue *msg;
-  int ret;
-
-  g_return_val_if_fail(s != NULL, -1);
-  g_return_val_if_fail(mwSession_isState(s, mwSession_LOGIN_REDIR), -1);
-  
-  state(s, mwSession_LOGIN_CONT, 0x00);
-
-  msg = (struct mwMsgLoginContinue *)
-    mwMessage_new(mwMessage_LOGIN_CONTINUE);
-
-  ret = mwSession_send(s, MW_MESSAGE(msg));
-  mwMessage_free(MW_MESSAGE(msg));
-  
-  return ret;
-}
-
-
-int mwSession_sendAnnounce(struct mwSession *s, gboolean may_reply,
-			   const char *text, const GList *recipients) {
-
-  struct mwMsgAnnounce *msg;
-  int ret;
-
-  g_return_val_if_fail(s != NULL, -1);
-  g_return_val_if_fail(mwSession_isStarted(s), -1);
-  
-  msg = (struct mwMsgAnnounce *) mwMessage_new(mwMessage_ANNOUNCE);
-
-  msg->recipients = (GList *) recipients;
-  msg->may_reply = may_reply;
-  msg->text = g_strdup(text);
-
-  ret = mwSession_send(s, MW_MESSAGE(msg));
-
-  msg->recipients = NULL;  /* don't kill our recipients param */
-  mwMessage_free(MW_MESSAGE(msg));
-
-  return ret;
-}
-
-
-struct mwSessionHandler *mwSession_getHandler(struct mwSession *s) {
-  g_return_val_if_fail(s != NULL, NULL);
-  return s->handler;
-}
-
-
-struct mwLoginInfo *mwSession_getLoginInfo(struct mwSession *s) {
-  g_return_val_if_fail(s != NULL, NULL);
-  return &s->login;
-}
-
-
-int mwSession_setPrivacyInfo(struct mwSession *s,
-			     struct mwPrivacyInfo *privacy) {
-
-  struct mwMsgSetPrivacyList *msg;
-  int ret;
-
-  g_return_val_if_fail(s != NULL, -1);
-  g_return_val_if_fail(privacy != NULL, -1);
-
-  msg = (struct mwMsgSetPrivacyList *)
-    mwMessage_new(mwMessage_SET_PRIVACY_LIST);
-
-  mwPrivacyInfo_clone(&msg->privacy, privacy);
-
-  ret = mwSession_send(s, MW_MESSAGE(msg));
-  mwMessage_free(MW_MESSAGE(msg));
-
-  return ret;
-}
-
-
-struct mwPrivacyInfo *mwSession_getPrivacyInfo(struct mwSession *s) {
-  g_return_val_if_fail(s != NULL, NULL);
-  return &s->privacy;
-}
-
-
-int mwSession_setUserStatus(struct mwSession *s,
-			    struct mwUserStatus *stat) {
-
-  struct mwMsgSetUserStatus *msg;
-  int ret;
-
-  g_return_val_if_fail(s != NULL, -1);
-  g_return_val_if_fail(stat != NULL, -1);
-
-  msg = (struct mwMsgSetUserStatus *)
-    mwMessage_new(mwMessage_SET_USER_STATUS);
-
-  mwUserStatus_clone(&msg->status, stat);
-
-  ret = mwSession_send(s, MW_MESSAGE(msg));
-  mwMessage_free(MW_MESSAGE(msg));
-
-  return ret;
-}
-
-
-struct mwUserStatus *mwSession_getUserStatus(struct mwSession *s) {
-  g_return_val_if_fail(s != NULL, NULL);
-  return &s->status;
-}
-
-
-enum mwSessionState mwSession_getState(struct mwSession *s) {
-  g_return_val_if_fail(s != NULL, mwSession_UNKNOWN);
-  return s->state;
-}
-
-
-gpointer mwSession_getStateInfo(struct mwSession *s) {
-  g_return_val_if_fail(s != NULL, 0);
-  return s->state_info;
-}
-
-
-struct mwChannelSet *mwSession_getChannels(struct mwSession *session) {
-  g_return_val_if_fail(session != NULL, NULL);
-  return session->channels;
-}
-
-
-gboolean mwSession_addService(struct mwSession *s, struct mwService *srv) {
-  g_return_val_if_fail(s != NULL, FALSE);
-  g_return_val_if_fail(srv != NULL, FALSE);
-  g_return_val_if_fail(s->services != NULL, FALSE);
-
-  if(map_guint_lookup(s->services, SERVICE_KEY(srv))) {
-    return FALSE;
-
-  } else {
-    map_guint_insert(s->services, SERVICE_KEY(srv), srv);
-    if(mwSession_isState(s, mwSession_STARTED))
-      mwSession_senseService(s, mwService_getType(srv));
-    return TRUE;
-  }
-}
-
-
-struct mwService *mwSession_getService(struct mwSession *s, guint32 srv) {
-  g_return_val_if_fail(s != NULL, NULL);
-  g_return_val_if_fail(s->services != NULL, NULL);
-
-  return map_guint_lookup(s->services, srv);
-}
-
-
-struct mwService *mwSession_removeService(struct mwSession *s, guint32 srv) {
-  struct mwService *svc;
-
-  g_return_val_if_fail(s != NULL, NULL);
-  g_return_val_if_fail(s->services != NULL, NULL);
-
-  svc = map_guint_lookup(s->services, srv);
-  if(svc) map_guint_remove(s->services, srv);
-  return svc;
-}
-
-
-GList *mwSession_getServices(struct mwSession *s) {
-  g_return_val_if_fail(s != NULL, NULL);
-  g_return_val_if_fail(s->services != NULL, NULL);
-
-  return map_collect_values(s->services);
-}
-
-
-void mwSession_senseService(struct mwSession *s, guint32 srvc) {
-  struct mwMsgSenseService *msg;
-
-  g_return_if_fail(s != NULL);
-  g_return_if_fail(srvc != 0x00);
-  g_return_if_fail(mwSession_isStarted(s));
-
-  msg = (struct mwMsgSenseService *)
-    mwMessage_new(mwMessage_SENSE_SERVICE);
-  msg->service = srvc;
-
-  mwSession_send(s, MW_MESSAGE(msg));
-  mwMessage_free(MW_MESSAGE(msg));
-}
-
-
-gboolean mwSession_addCipher(struct mwSession *s, struct mwCipher *c) {
-  g_return_val_if_fail(s != NULL, FALSE);
-  g_return_val_if_fail(c != NULL, FALSE);
-  g_return_val_if_fail(s->ciphers != NULL, FALSE);
-
-  if(map_guint_lookup(s->ciphers, mwCipher_getType(c))) {
-    g_message("cipher %s is already added, apparently",
-	      NSTR(mwCipher_getName(c)));
-    return FALSE;
-
-  } else {
-    g_message("adding cipher %s", NSTR(mwCipher_getName(c)));
-    map_guint_insert(s->ciphers, mwCipher_getType(c), c);
-    return TRUE;
-  }
-}
-
-
-struct mwCipher *mwSession_getCipher(struct mwSession *s, guint16 c) {
-  g_return_val_if_fail(s != NULL, NULL);
-  g_return_val_if_fail(s->ciphers != NULL, NULL);
-
-  return map_guint_lookup(s->ciphers, c);
-}
-
-
-struct mwCipher *mwSession_removeCipher(struct mwSession *s, guint16 c) {
-  struct mwCipher *ciph;
-
-  g_return_val_if_fail(s != NULL, NULL);
-  g_return_val_if_fail(s->ciphers != NULL, NULL);
-
-  ciph = map_guint_lookup(s->ciphers, c);
-  if(ciph) map_guint_remove(s->ciphers, c);
-  return ciph;
-}
-
-
-GList *mwSession_getCiphers(struct mwSession *s) {
-  g_return_val_if_fail(s != NULL, NULL);
-  g_return_val_if_fail(s->ciphers != NULL, NULL);
-
-  return map_collect_values(s->ciphers);
-}
-
-
-void mwSession_setProperty(struct mwSession *s, const char *key,
-			   gpointer val, GDestroyNotify clean) {
-
-  g_return_if_fail(s != NULL);
-  g_return_if_fail(s->attributes != NULL);
-  g_return_if_fail(key != NULL);
-
-  property_set(s, key, val, clean);
-}
-
-
-gpointer mwSession_getProperty(struct mwSession *s, const char *key) {
- 
-  g_return_val_if_fail(s != NULL, NULL);
-  g_return_val_if_fail(s->attributes != NULL, NULL);
-  g_return_val_if_fail(key != NULL, NULL);
-
-  return property_get(s, key);
-}
-
-
-void mwSession_removeProperty(struct mwSession *s, const char *key) {
-  g_return_if_fail(s != NULL);
-  g_return_if_fail(s->attributes != NULL);
-  g_return_if_fail(key != NULL);
-
-  property_del(s, key);
-}
-
-
-void mwSession_setClientData(struct mwSession *session,
-			     gpointer data, GDestroyNotify clear) {
-
-  g_return_if_fail(session != NULL);
-  mw_datum_set(&session->client_data, data, clear);
-}
-
-
-gpointer mwSession_getClientData(struct mwSession *session) {
-  g_return_val_if_fail(session != NULL, NULL);
-  return mw_datum_get(&session->client_data);
-}
-
-
-void mwSession_removeClientData(struct mwSession *session) {
-  g_return_if_fail(session != NULL);
-  mw_datum_clear(&session->client_data);
-}
-
--- a/src/protocols/sametime/meanwhile/srvc_aware.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1318 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <glib.h>
-#include <glib/ghash.h>
-#include <glib/glist.h>
-#include <string.h>
-
-#include "mw_channel.h"
-#include "mw_debug.h"
-#include "mw_error.h"
-#include "mw_message.h"
-#include "mw_service.h"
-#include "mw_session.h"
-#include "mw_srvc_aware.h"
-#include "mw_util.h"
-
-
-struct mwServiceAware {
-  struct mwService service;
-
-  struct mwAwareHandler *handler;
-
-  /** map of ENTRY_KEY(aware_entry):aware_entry */
-  GHashTable *entries;
-
-  /** set of guint32:attrib_watch_entry attribute keys */
-  GHashTable *attribs;
-
-  /** collection of lists of awareness for this service. Each item is
-      a mwAwareList */
-  GList *lists;
-
-  /** the buddy list channel */
-  struct mwChannel *channel;
-};
-
-
-struct mwAwareList {
-
-  /** the owning service */
-  struct mwServiceAware *service;
-
-  /** map of ENTRY_KEY(aware_entry):aware_entry */
-  GHashTable *entries;
-
-  /** set of guint32:attrib_watch_entry attribute keys */
-  GHashTable *attribs;
-
-  struct mwAwareListHandler *handler;
-  struct mw_datum client_data;
-};
-
-
-struct mwAwareAttribute {
-  guint32 key;
-  struct mwOpaque data;
-};
-
-
-struct attrib_entry {
-  guint32 key;
-  GList *membership;
-};
-
-
-/** an actual awareness entry, belonging to any number of aware lists */
-struct aware_entry {
-  struct mwAwareSnapshot aware;
-
-  /** list of mwAwareList containing this entry */
-  GList *membership;
-
-  /** collection of attribute values for this entry.
-      map of ATTRIB_KEY(mwAwareAttribute):mwAwareAttribute */
-  GHashTable *attribs;
-};
-
-
-#define ENTRY_KEY(entry) &entry->aware.id
-
-
-/** the channel send types used by this service */
-enum msg_types {
-  msg_AWARE_ADD       = 0x0068,  /**< remove an aware */
-  msg_AWARE_REMOVE    = 0x0069,  /**< add an aware */
-
-  msg_OPT_DO_SET      = 0x00c9,  /**< set an attribute */
-  msg_OPT_DO_UNSET    = 0x00ca,  /**< unset an attribute */
-  msg_OPT_WATCH       = 0x00cb,  /**< set the attribute watch list */
-
-  msg_AWARE_SNAPSHOT  = 0x01f4,  /**< recv aware snapshot */
-  msg_AWARE_UPDATE    = 0x01f5,  /**< recv aware update */
-  msg_AWARE_GROUP     = 0x01f6,  /**< recv group aware */
-
-  msg_OPT_GOT_SET     = 0x0259,  /**< recv attribute set update */
-  msg_OPT_GOT_UNSET   = 0x025a,  /**< recv attribute unset update */
-
-  msg_OPT_GOT_UNKNOWN = 0x025b,  /**< UNKNOWN */
-  
-  msg_OPT_DID_SET     = 0x025d,  /**< attribute set response */
-  msg_OPT_DID_UNSET   = 0x025e,  /**< attribute unset response */
-  msg_OPT_DID_ERROR   = 0x025f,  /**< attribute set/unset error */
-};
-
-
-static void aware_entry_free(struct aware_entry *ae) {
-  mwAwareSnapshot_clear(&ae->aware);
-  g_list_free(ae->membership);
-  g_hash_table_destroy(ae->attribs);
-  g_free(ae);
-}
-
-
-static void attrib_entry_free(struct attrib_entry *ae) {
-  g_list_free(ae->membership);
-  g_free(ae);
-}
-
-
-static void attrib_free(struct mwAwareAttribute *attrib) {
-  mwOpaque_clear(&attrib->data);
-  g_free(attrib);
-}
-
-
-static struct aware_entry *aware_find(struct mwServiceAware *srvc,
-				      struct mwAwareIdBlock *srch) {
-  g_return_val_if_fail(srvc != NULL, NULL);
-  g_return_val_if_fail(srvc->entries != NULL, NULL);
-  g_return_val_if_fail(srch != NULL, NULL);
-  
-  return g_hash_table_lookup(srvc->entries, srch);
-}
-
-
-static struct aware_entry *list_aware_find(struct mwAwareList *list,
-					   struct mwAwareIdBlock *srch) {
-  g_return_val_if_fail(list != NULL, NULL);
-  g_return_val_if_fail(list->entries != NULL, NULL);
-  g_return_val_if_fail(srch != NULL, NULL);
-
-  return g_hash_table_lookup(list->entries, srch);
-}
-
-
-static void compose_list(struct mwPutBuffer *b, GList *id_list) {
-  guint32_put(b, g_list_length(id_list));
-  for(; id_list; id_list = id_list->next)
-    mwAwareIdBlock_put(b, id_list->data);
-}
-
-
-static int send_add(struct mwChannel *chan, GList *id_list) {
-  struct mwPutBuffer *b = mwPutBuffer_new();
-  struct mwOpaque o;
-  int ret;
-
-  g_return_val_if_fail(chan != NULL, 0);
-
-  compose_list(b, id_list);
-
-  mwPutBuffer_finalize(&o, b);
-
-  ret = mwChannel_send(chan, msg_AWARE_ADD, &o);
-  mwOpaque_clear(&o);
-
-  return ret;  
-}
-
-
-static int send_rem(struct mwChannel *chan, GList *id_list) {
-  struct mwPutBuffer *b = mwPutBuffer_new();
-  struct mwOpaque o;
-  int ret;
-
-  g_return_val_if_fail(chan != NULL, 0);
-
-  compose_list(b, id_list);
-  mwPutBuffer_finalize(&o, b);
-
-  ret = mwChannel_send(chan, msg_AWARE_REMOVE, &o);
-  mwOpaque_clear(&o);
-
-  return ret;
-}
-
-
-static gboolean collect_dead(gpointer key, gpointer val, gpointer data) {
-  struct aware_entry *aware = val;
-  GList **dead = data;
-
-  if(aware->membership == NULL) {
-    g_info(" removing %s, %s",
-	   NSTR(aware->aware.id.user), NSTR(aware->aware.id.community));
-    *dead = g_list_append(*dead, aware);
-    return TRUE;
-
-  } else {
-    return FALSE;
-  }
-}
-
-
-static int remove_unused(struct mwServiceAware *srvc) {
-  /* - create a GList of all the unused aware entries
-     - remove each unused aware from the service
-     - if the service is alive, send a removal message for the collected
-     unused.
-  */
-
-  int ret = 0;
-  GList *dead = NULL, *l;
-
-  if(srvc->entries) {
-    g_info("bring out your dead *clang*");
-    g_hash_table_foreach_steal(srvc->entries, collect_dead, &dead);
-  }
- 
-  if(dead) {
-    if(MW_SERVICE_IS_LIVE(srvc))
-      ret = send_rem(srvc->channel, dead) || ret;
-    
-    for(l = dead; l; l = l->next)
-      aware_entry_free(l->data);
-
-    g_list_free(dead);
-  }
-
-  return ret;
-}
-
-
-static int send_attrib_list(struct mwServiceAware *srvc) {
-  struct mwPutBuffer *b;
-  struct mwOpaque o;
-
-  int tmp;
-  GList *l;
-
-  g_return_val_if_fail(srvc != NULL, -1);
-  g_return_val_if_fail(srvc->channel != NULL, 0);
-
-  l = map_collect_keys(srvc->attribs);
-  tmp = g_list_length(l);
-
-  b = mwPutBuffer_new();
-  guint32_put(b, 0x00);
-  guint32_put(b, tmp);
-  
-  for(; l; l = g_list_delete_link(l, l)) {
-    guint32_put(b, GPOINTER_TO_UINT(l->data));
-  }
-
-  mwPutBuffer_finalize(&o, b);
-  tmp = mwChannel_send(srvc->channel, msg_OPT_WATCH, &o);
-  mwOpaque_clear(&o);
-
-  return tmp;
-}
-
-
-static gboolean collect_attrib_dead(gpointer key, gpointer val,
-				    gpointer data) {
-
-  struct attrib_entry *attrib = val;
-  GList **dead = data;
-
-  if(attrib->membership == NULL) {
-    g_info(" removing 0x%08x", GPOINTER_TO_UINT(key));
-    *dead = g_list_append(*dead, attrib);
-    return TRUE;
-
-  } else {
-    return FALSE;
-  }
-}
-
-
-static int remove_unused_attrib(struct mwServiceAware *srvc) {
-  GList *dead = NULL;
-
-  if(srvc->attribs) {
-    g_info("collecting dead attributes");
-    g_hash_table_foreach_steal(srvc->attribs, collect_attrib_dead, &dead);
-  }
- 
-  /* since we stole them, we'll have to clean 'em up manually */
-  for(; dead; dead = g_list_delete_link(dead, dead)) {
-    attrib_entry_free(dead->data);
-  }
-
-  return MW_SERVICE_IS_LIVE(srvc)? send_attrib_list(srvc): 0;
-}
-
-
-static void recv_accept(struct mwServiceAware *srvc,
-			struct mwChannel *chan,
-			struct mwMsgChannelAccept *msg) {
-
-  g_return_if_fail(srvc->channel != NULL);
-  g_return_if_fail(srvc->channel == chan);
-
-  if(MW_SERVICE_IS_STARTING(MW_SERVICE(srvc))) {
-    GList *list = NULL;
-
-    list = map_collect_values(srvc->entries);
-    send_add(chan, list);
-    g_list_free(list);
-
-    send_attrib_list(srvc);
-
-    mwService_started(MW_SERVICE(srvc));
-
-  } else {
-    mwChannel_destroy(chan, ERR_FAILURE, NULL);
-  }
-}
-
-
-static void recv_destroy(struct mwServiceAware *srvc,
-			 struct mwChannel *chan,
-			 struct mwMsgChannelDestroy *msg) {
-
-  srvc->channel = NULL;
-  mwService_stop(MW_SERVICE(srvc));
-
-  /** @todo session sense service and mwService_start */
-}
-
-
-/** called from SNAPSHOT_recv, UPDATE_recv, and
-    mwServiceAware_setStatus */
-static void status_recv(struct mwServiceAware *srvc,
-			struct mwAwareSnapshot *idb) {
-
-  struct aware_entry *aware;
-  GList *l;
-
-  aware = aware_find(srvc, &idb->id);
-
-  if(! aware) {
-    /* we don't deal with receiving status for something we're not
-       monitoring, but it will happen sometimes, eg from manually set
-       status */
-    return;
-  }
-  
-  /* clear the existing status, then clone in the new status */
-  mwAwareSnapshot_clear(&aware->aware);
-  mwAwareSnapshot_clone(&aware->aware, idb);
-  
-  /* trigger each of the entry's lists */
-  for(l = aware->membership; l; l = l->next) {
-    struct mwAwareList *alist = l->data;
-    struct mwAwareListHandler *handler = alist->handler;
-
-    if(handler && handler->on_aware)
-      handler->on_aware(alist, idb);
-  }
-}
-
-
-static void attrib_recv(struct mwServiceAware *srvc,
-			struct mwAwareIdBlock *idb,
-			struct mwAwareAttribute *attrib) {
-
-  struct aware_entry *aware;
-  struct mwAwareAttribute *old_attrib = NULL;
-  GList *l;
-  guint32 key;
-  gpointer k;
-
-  aware = aware_find(srvc, idb);
-  g_return_if_fail(aware != NULL);
-
-  key = attrib->key;
-  k = GUINT_TO_POINTER(key);
-
-  if(aware->attribs)
-    old_attrib = g_hash_table_lookup(aware->attribs, k);
-
-  if(! old_attrib) {
-    old_attrib = g_new0(struct mwAwareAttribute, 1);
-    old_attrib->key = key;
-    g_hash_table_insert(aware->attribs, k, old_attrib);
-  }
-  
-  mwOpaque_clear(&old_attrib->data);
-  mwOpaque_clone(&old_attrib->data, &attrib->data);
-  
-  for(l = aware->membership; l; l = l->next) {
-    struct mwAwareList *list = l->data;
-    struct mwAwareListHandler *h = list->handler;
-
-    if(h && h->on_attrib &&
-       list->attribs && g_hash_table_lookup(list->attribs, k))
-
-      h->on_attrib(list, idb, old_attrib);
-  }
-}
-
-
-gboolean list_add(struct mwAwareList *list, struct mwAwareIdBlock *id) {
-
-  struct mwServiceAware *srvc = list->service;
-  struct aware_entry *aware;
-
-  g_return_val_if_fail(id->user != NULL, FALSE);
-  g_return_val_if_fail(strlen(id->user) > 0, FALSE);
-
-  if(! list->entries)
-    list->entries = g_hash_table_new((GHashFunc) mwAwareIdBlock_hash,
-				     (GEqualFunc) mwAwareIdBlock_equal);
-
-  aware = list_aware_find(list, id);
-  if(aware) return FALSE;
-
-  aware = aware_find(srvc, id);
-  if(! aware) {
-    aware = g_new0(struct aware_entry, 1);
-    aware->attribs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
-					   (GDestroyNotify) attrib_free);
-    mwAwareIdBlock_clone(ENTRY_KEY(aware), id);
-
-    g_hash_table_insert(srvc->entries, ENTRY_KEY(aware), aware);
-  }
-
-  aware->membership = g_list_append(aware->membership, list);
-
-  g_hash_table_insert(list->entries, ENTRY_KEY(aware), aware);
-
-  return TRUE;
-}
-
-
-static void group_member_recv(struct mwServiceAware *srvc,
-			      struct mwAwareSnapshot *idb) {
-  /* @todo
-     - look up group by id
-     - find each list group belongs to
-     - add user to lists
-  */
-
-  struct mwAwareIdBlock gsrch = { mwAware_GROUP, idb->group, NULL };
-  struct aware_entry *grp;
-  GList *l, *m;
-
-  grp = aware_find(srvc, &gsrch);
-  g_return_if_fail(grp != NULL); /* this could happen, with timing. */
-
-  l = g_list_prepend(NULL, &idb->id);
-
-  for(m = grp->membership; m; m = m->next) {
-
-    /* if we just list_add, we won't receive updates for attributes,
-       so annoyingly we have to turn around and send out an add aware
-       message for each incoming group member */
-
-    /* list_add(m->data, &idb->id); */
-    mwAwareList_addAware(m->data, l);
-  }
-
-  g_list_free(l);
-}
-
-
-static void recv_SNAPSHOT(struct mwServiceAware *srvc,
-			  struct mwGetBuffer *b) {
-
-  guint32 count;
-
-  struct mwAwareSnapshot *snap;
-  snap = g_new0(struct mwAwareSnapshot, 1);
-
-  guint32_get(b, &count);
-
-  while(count--) {
-    mwAwareSnapshot_get(b, snap);
-
-    if(mwGetBuffer_error(b)) {
-      mwAwareSnapshot_clear(snap);
-      break;
-    }
-
-    if(snap->group)
-      group_member_recv(srvc, snap);
-
-    status_recv(srvc, snap);
-    mwAwareSnapshot_clear(snap);
-  }
-
-  g_free(snap);
-}
-
-
-static void recv_UPDATE(struct mwServiceAware *srvc,
-			struct mwGetBuffer *b) {
-
-  struct mwAwareSnapshot *snap;
-
-  snap = g_new0(struct mwAwareSnapshot, 1);
-  mwAwareSnapshot_get(b, snap);
-
-  if(snap->group)
-    group_member_recv(srvc, snap);
-
-  if(! mwGetBuffer_error(b))
-    status_recv(srvc, snap);
-
-  mwAwareSnapshot_clear(snap);
-  g_free(snap);
-}
-
-
-static void recv_GROUP(struct mwServiceAware *srvc,
-		       struct mwGetBuffer *b) {
-
-  struct mwAwareIdBlock idb = { 0, 0, 0 };
-
-  /* really nothing to be done with this. The group should have
-     already been added to the list and service, and is now simply
-     awaiting a snapshot/update with users listed as belonging in said
-     group. */
-
-  mwAwareIdBlock_get(b, &idb);
-  mwAwareIdBlock_clear(&idb);
-}
-
-
-static void recv_OPT_GOT_SET(struct mwServiceAware *srvc,
-			     struct mwGetBuffer *b) {
-
-  struct mwAwareAttribute attrib;
-  struct mwAwareIdBlock idb;
-  guint32 junk, check;
-
-  guint32_get(b, &junk);
-  mwAwareIdBlock_get(b, &idb);
-  guint32_get(b, &junk);
-  guint32_get(b, &check);
-  guint32_get(b, &junk);
-  guint32_get(b, &attrib.key);
-
-  if(check) {
-    mwOpaque_get(b, &attrib.data);
-  } else {
-    attrib.data.len = 0;
-    attrib.data.data = NULL;
-  }
-
-  attrib_recv(srvc, &idb, &attrib);
-
-  mwAwareIdBlock_clear(&idb);
-  mwOpaque_clear(&attrib.data);
-}
-
-
-static void recv_OPT_GOT_UNSET(struct mwServiceAware *srvc,
-			       struct mwGetBuffer *b) {
-
-  struct mwAwareAttribute attrib;
-  struct mwAwareIdBlock idb;
-  guint32 junk;
-
-  attrib.key = 0;
-  attrib.data.len = 0;
-  attrib.data.data = NULL;
-
-  guint32_get(b, &junk);
-  mwAwareIdBlock_get(b, &idb);
-  guint32_get(b, &attrib.key);
-
-  attrib_recv(srvc, &idb, &attrib);
-
-  mwAwareIdBlock_clear(&idb);
-}
-
-
-static void recv(struct mwService *srvc, struct mwChannel *chan,
-		 guint16 type, struct mwOpaque *data) {
-
-  struct mwServiceAware *srvc_aware = (struct mwServiceAware *) srvc;
-  struct mwGetBuffer *b;
-
-  g_return_if_fail(srvc_aware->channel == chan);
-  g_return_if_fail(srvc->session == mwChannel_getSession(chan));
-  g_return_if_fail(data != NULL);
-
-  b = mwGetBuffer_wrap(data);
-
-  switch(type) {
-  case msg_AWARE_SNAPSHOT:
-    recv_SNAPSHOT(srvc_aware, b);
-    break;
-
-  case msg_AWARE_UPDATE:
-    recv_UPDATE(srvc_aware, b);
-    break;
-
-  case msg_AWARE_GROUP:
-    recv_GROUP(srvc_aware, b);
-    break;
-
-  case msg_OPT_GOT_SET:
-    recv_OPT_GOT_SET(srvc_aware, b);
-    break;
-
-  case msg_OPT_GOT_UNSET:
-    recv_OPT_GOT_UNSET(srvc_aware, b);
-    break;
-
-  case msg_OPT_GOT_UNKNOWN:
-  case msg_OPT_DID_SET:
-  case msg_OPT_DID_UNSET:
-  case msg_OPT_DID_ERROR:
-    break;
-
-  default:
-    mw_mailme_opaque(data, "unknown message in aware service: 0x%04x", type);
-  }
-
-  mwGetBuffer_free(b);  
-}
-
-
-static void clear(struct mwService *srvc) {
-  struct mwServiceAware *srvc_aware = (struct mwServiceAware *) srvc;
-
-  g_return_if_fail(srvc != NULL);
-
-  while(srvc_aware->lists)
-    mwAwareList_free( (struct mwAwareList *) srvc_aware->lists->data );
-
-  g_hash_table_destroy(srvc_aware->entries);
-  srvc_aware->entries = NULL;
-
-  g_hash_table_destroy(srvc_aware->attribs);
-  srvc_aware->attribs = NULL;
-}
-
-
-static const char *name(struct mwService *srvc) {
-  return "Presence Awareness";
-}
-
-
-static const char *desc(struct mwService *srvc) {
-  return "Buddy list service with support for server-side groups";
-}
-
-
-static struct mwChannel *make_blist(struct mwServiceAware *srvc,
-				    struct mwChannelSet *cs) {
-
-  struct mwChannel *chan = mwChannel_newOutgoing(cs);
-
-  mwChannel_setService(chan, MW_SERVICE(srvc));
-  mwChannel_setProtoType(chan, 0x00000011);
-  mwChannel_setProtoVer(chan, 0x00030005);
-
-  return mwChannel_create(chan)? NULL: chan;
-}
-
-
-static void start(struct mwService *srvc) {
-  struct mwServiceAware *srvc_aware;
-  struct mwChannel *chan = NULL;
-
-  srvc_aware = (struct mwServiceAware *) srvc;
-  chan = make_blist(srvc_aware, mwSession_getChannels(srvc->session));
-
-  if(chan != NULL) {
-    srvc_aware->channel = chan;
-  } else {
-    mwService_stopped(srvc);
-  }
-}
-
-
-static void stop(struct mwService *srvc) {
-  struct mwServiceAware *srvc_aware;
-
-  srvc_aware = (struct mwServiceAware *) srvc;
-
-  if(srvc_aware->channel) {
-    mwChannel_destroy(srvc_aware->channel, ERR_SUCCESS, NULL);
-    srvc_aware->channel = NULL;
-  }
-
-  mwService_stopped(srvc);
-}
-
-
-struct mwServiceAware *
-mwServiceAware_new(struct mwSession *session,
-		   struct mwAwareHandler *handler) {
-
-  struct mwService *service;
-  struct mwServiceAware *srvc;
-
-  g_return_val_if_fail(session != NULL, NULL);
-  g_return_val_if_fail(handler != NULL, NULL);
-
-  srvc = g_new0(struct mwServiceAware, 1);
-  srvc->handler = handler;
-  srvc->entries = g_hash_table_new_full((GHashFunc) mwAwareIdBlock_hash,
-					(GEqualFunc) mwAwareIdBlock_equal,
-					NULL,
-					(GDestroyNotify) aware_entry_free);
-
-  srvc->attribs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
-					(GDestroyNotify) attrib_entry_free);
-
-  service = MW_SERVICE(srvc);
-  mwService_init(service, session, mwService_AWARE);
-
-  service->recv_accept = (mwService_funcRecvAccept) recv_accept;
-  service->recv_destroy = (mwService_funcRecvDestroy) recv_destroy;
-  service->recv = recv;
-  service->start = start;
-  service->stop = stop;
-  service->clear = clear;
-  service->get_name = name;
-  service->get_desc = desc;
-
-  return srvc;
-}
-
-
-int mwServiceAware_setAttribute(struct mwServiceAware *srvc,
-				guint32 key, struct mwOpaque *data) {
-  struct mwPutBuffer *b;
-  struct mwOpaque o;
-  int ret;
-
-  b = mwPutBuffer_new();
-
-  guint32_put(b, 0x00);
-  guint32_put(b, data->len);
-  guint32_put(b, 0x00);
-  guint32_put(b, key);
-  mwOpaque_put(b, data);
-
-  mwPutBuffer_finalize(&o, b);
-  ret = mwChannel_send(srvc->channel, msg_OPT_DO_SET, &o);
-  mwOpaque_clear(&o);
-
-  return ret;
-}
-
-
-int mwServiceAware_setAttributeBoolean(struct mwServiceAware *srvc,
-				       guint32 key, gboolean val) {
-  int ret;
-  struct mwPutBuffer *b;
-  struct mwOpaque o;
- 
-  b = mwPutBuffer_new();
-
-  gboolean_put(b, FALSE);
-  gboolean_put(b, val);
-
-  mwPutBuffer_finalize(&o, b);
-
-  ret = mwServiceAware_setAttribute(srvc, key, &o);
-  mwOpaque_clear(&o);
-
-  return ret;
-}
-
-
-int mwServiceAware_setAttributeInteger(struct mwServiceAware *srvc,
-				       guint32 key, guint32 val) {
-  int ret;
-  struct mwPutBuffer *b;
-  struct mwOpaque o;
-  
-  b = mwPutBuffer_new();
-  guint32_put(b, val);
-
-  mwPutBuffer_finalize(&o, b);
-
-  ret = mwServiceAware_setAttribute(srvc, key, &o);
-  mwOpaque_clear(&o);
-
-  return ret;
-}
-
-
-int mwServiceAware_setAttributeString(struct mwServiceAware *srvc,
-				      guint32 key, const char *str) {
-  int ret;
-  struct mwPutBuffer *b;
-  struct mwOpaque o;
-
-  b = mwPutBuffer_new();
-  mwString_put(b, str);
-
-  mwPutBuffer_finalize(&o, b);
-
-  ret = mwServiceAware_setAttribute(srvc, key, &o);
-  mwOpaque_clear(&o);
-
-  return ret;
-}
-
-
-int mwServiceAware_unsetAttribute(struct mwServiceAware *srvc,
-				  guint32 key) {
-  struct mwPutBuffer *b;
-  struct mwOpaque o;
-  int ret;
-
-  b = mwPutBuffer_new();
-
-  guint32_put(b, 0x00);
-  guint32_put(b, key);
-  
-  mwPutBuffer_finalize(&o, b);
-  ret = mwChannel_send(srvc->channel, msg_OPT_DO_UNSET, &o);
-  mwOpaque_clear(&o);
-
-  return ret;
-}
-
-
-guint32 mwAwareAttribute_getKey(const struct mwAwareAttribute *attrib) {
-  g_return_val_if_fail(attrib != NULL, 0x00);
-  return attrib->key;
-}
-
-
-gboolean mwAwareAttribute_asBoolean(const struct mwAwareAttribute *attrib) {
-  struct mwGetBuffer *b;
-  gboolean ret;
-  
-  if(! attrib) return FALSE;
-
-  b = mwGetBuffer_wrap(&attrib->data);
-  if(attrib->data.len >= 4) {
-    guint32 r32 = 0x00;
-    guint32_get(b, &r32);
-    ret = !! r32;
-
-  } else if(attrib->data.len >= 2) {
-    guint16 r16 = 0x00;
-    guint16_get(b, &r16);
-    ret = !! r16;
-
-  } else if(attrib->data.len) {
-    gboolean_get(b, &ret);
-  }
-
-  mwGetBuffer_free(b);
-
-  return ret;
-}
-
-
-guint32 mwAwareAttribute_asInteger(const struct mwAwareAttribute *attrib) {
-  struct mwGetBuffer *b;
-  guint32 r32 = 0x00;
-  
-  if(! attrib) return 0x00;
-
-  b = mwGetBuffer_wrap(&attrib->data);
-  if(attrib->data.len >= 4) {
-    guint32_get(b, &r32);
-
-  } else if(attrib->data.len == 3) {
-    gboolean rb = FALSE;
-    guint16 r16 = 0x00;
-    gboolean_get(b, &rb);
-    guint16_get(b, &r16);
-    r32 = (guint32) r16;
-
-  } else if(attrib->data.len == 2) {
-    guint16 r16 = 0x00;
-    guint16_get(b, &r16);
-    r32 = (guint32) r16;
-
-  } else if(attrib->data.len) {
-    gboolean rb = FALSE;
-    gboolean_get(b, &rb);
-    r32 = (guint32) rb;
-  }
-
-  mwGetBuffer_free(b);
-
-  return r32;
-}
-
-
-char *mwAwareAttribute_asString(const struct mwAwareAttribute *attrib) {
-  struct mwGetBuffer *b;
-  char *ret = NULL;
-
-  if(! attrib) return NULL;
-
-  b = mwGetBuffer_wrap(&attrib->data);
-  mwString_get(b, &ret);
-  mwGetBuffer_free(b);
-
-  return ret;
-}
-
-
-const struct mwOpaque *
-mwAwareAttribute_asOpaque(const struct mwAwareAttribute *attrib) {
-  g_return_val_if_fail(attrib != NULL, NULL);
-  return &attrib->data;
-}
-			  
-
-struct mwAwareList *
-mwAwareList_new(struct mwServiceAware *srvc,
-		struct mwAwareListHandler *handler) {
-
-  struct mwAwareList *al;
-
-  g_return_val_if_fail(srvc != NULL, NULL);
-  g_return_val_if_fail(handler != NULL, NULL);
-
-  al = g_new0(struct mwAwareList, 1);
-  al->service = srvc;
-  al->handler = handler;
-
-  srvc->lists = g_list_prepend(srvc->lists, al);
-
-  return al;
-}
-
-
-void mwAwareList_free(struct mwAwareList *list) {
-  struct mwServiceAware *srvc;
-  struct mwAwareListHandler *handler;
-
-  g_return_if_fail(list != NULL);
-  g_return_if_fail(list->service != NULL);
-
-  srvc = list->service;
-  srvc->lists = g_list_remove_all(srvc->lists, list);
-
-  handler = list->handler;
-  if(handler && handler->clear) {
-    handler->clear(list);
-    list->handler = NULL;
-  }
-
-  mw_datum_clear(&list->client_data);
-
-  mwAwareList_unwatchAllAttributes(list);
-  mwAwareList_removeAllAware(list);
-
-  list->service = NULL;
-
-  g_free(list);
-}
-
-
-struct mwAwareListHandler *mwAwareList_getHandler(struct mwAwareList *list) {
-  g_return_val_if_fail(list != NULL, NULL);
-  return list->handler;
-}
-
-
-static void watch_add(struct mwAwareList *list, guint32 key) {
-  struct mwServiceAware *srvc;
-  struct attrib_entry *watch;
-  gpointer k = GUINT_TO_POINTER(key);
-
-  if(! list->attribs)
-    list->attribs = g_hash_table_new(g_direct_hash, g_direct_equal);
-
-  if(g_hash_table_lookup(list->attribs, k))
-    return;
-
-  srvc = list->service;
-
-  watch = g_hash_table_lookup(srvc->attribs, k);
-  if(! watch) {
-    watch = g_new0(struct attrib_entry, 1);
-    watch->key = key;
-    g_hash_table_insert(srvc->attribs, k, watch);
-  }
-
-  g_hash_table_insert(list->attribs, k, watch);
-
-  watch->membership = g_list_prepend(watch->membership, list);
-}
-
-
-static void watch_remove(struct mwAwareList *list, guint32 key) {
-  struct attrib_entry *watch = NULL;
-  gpointer k = GUINT_TO_POINTER(key);
-
-  if(list->attribs)
-    watch = g_hash_table_lookup(list->attribs, k);
-
-  g_return_if_fail(watch != NULL);
-
-  g_hash_table_remove(list->attribs, k);
-  watch->membership = g_list_remove(watch->membership, list);
-}
-
-
-int mwAwareList_watchAttributeArray(struct mwAwareList *list,
-				    guint32 *keys) {
-  guint32 k;
-
-  g_return_val_if_fail(list != NULL, -1);
-  g_return_val_if_fail(list->service != NULL, -1);
-
-  if(! keys) return 0;
-
-  for(k = *keys; k; keys++)
-    watch_add(list, k);
-
-  return send_attrib_list(list->service);
-}
-
-
-int mwAwareList_watchAttributes(struct mwAwareList *list,
-				guint32 key, ...) {
-  guint32 k;
-  va_list args;
-
-  g_return_val_if_fail(list != NULL, -1);
-  g_return_val_if_fail(list->service != NULL, -1);
-
-  va_start(args, key);
-  for(k = key; k; k = va_arg(args, guint32))
-    watch_add(list, k);
-  va_end(args);
-
-  return send_attrib_list(list->service);
-}
-
-
-int mwAwareList_unwatchAttributeArray(struct mwAwareList *list,
-				      guint32 *keys) {
-  guint32 k;
-
-  g_return_val_if_fail(list != NULL, -1);
-  g_return_val_if_fail(list->service != NULL, -1);
-
-  if(! keys) return 0;
-
-  for(k = *keys; k; keys++)
-    watch_add(list, k);
-
-  return remove_unused_attrib(list->service);
-}
-
-
-int mwAwareList_unwatchAttributes(struct mwAwareList *list,
-				  guint32 key, ...) {
-  guint32 k;
-  va_list args;
-
-  g_return_val_if_fail(list != NULL, -1);
-  g_return_val_if_fail(list->service != NULL, -1);
-
-  va_start(args, key);
-  for(k = key; k; k = va_arg(args, guint32))
-    watch_remove(list, k);
-  va_end(args);
-
-  return remove_unused_attrib(list->service);
-}
-
-
-static void dismember_attrib(gpointer k, struct attrib_entry *watch,
-			    struct mwAwareList *list) {
-
-  watch->membership = g_list_remove(watch->membership, list);
-}
-
-
-int mwAwareList_unwatchAllAttributes(struct mwAwareList *list) {
-  
-  struct mwServiceAware *srvc;
-
-  g_return_val_if_fail(list != NULL, -1);
-  srvc = list->service;
-
-  if(list->attribs) {
-    g_hash_table_foreach(list->attribs, (GHFunc) dismember_attrib, list);
-    g_hash_table_destroy(list->attribs);
-  }
-
-  return remove_unused_attrib(srvc);
-}
-
-
-static void collect_attrib_keys(gpointer key, struct attrib_entry *attrib,
-				guint32 **ck) {
-  guint32 *keys = (*ck)++;
-  *keys = GPOINTER_TO_UINT(key);
-}
-
-
-guint32 *mwAwareList_getWatchedAttributes(struct mwAwareList *list) {
-  guint32 *keys, **ck;
-  guint count;
-
-  g_return_val_if_fail(list != NULL, NULL);
-  g_return_val_if_fail(list->attribs != NULL, NULL);
-  
-  count = g_hash_table_size(list->attribs);
-  keys = g_new0(guint32, count + 1);
-
-  ck = &keys;
-  g_hash_table_foreach(list->attribs, (GHFunc) collect_attrib_keys, ck);
-
-  return keys;
-}
-
-
-int mwAwareList_addAware(struct mwAwareList *list, GList *id_list) {
-
-  /* for each awareness id:
-     - if it's already in the list, continue
-     - if it's not in the service list:
-       - create an awareness
-       - add it to the service list
-     - add this list to the membership
-     - add to the list
-  */
-
-  struct mwServiceAware *srvc;
-  GList *additions = NULL;
-  int ret = 0;
-
-  g_return_val_if_fail(list != NULL, -1);
-
-  srvc = list->service;
-  g_return_val_if_fail(srvc != NULL, -1);
-
-  for(; id_list; id_list = id_list->next) {
-    if(list_add(list, id_list->data))
-      additions = g_list_prepend(additions, id_list->data);
-  }
-
-  /* if the service is alive-- or getting there-- we'll need to send
-     these additions upstream */
-  if(MW_SERVICE_IS_LIVE(srvc) && additions)
-    ret = send_add(srvc->channel, additions);
-
-  g_list_free(additions);
-  return ret;
-}
-
-
-int mwAwareList_removeAware(struct mwAwareList *list, GList *id_list) {
-
-  /* for each awareness id:
-     - if it's not in the list, forget it
-     - remove from the list
-     - remove list from the membership
-
-     - call remove round
-  */
-
-  struct mwServiceAware *srvc;
-  struct mwAwareIdBlock *id;
-  struct aware_entry *aware;
-
-  g_return_val_if_fail(list != NULL, -1);
-
-  srvc = list->service;
-  g_return_val_if_fail(srvc != NULL, -1);
-
-  for(; id_list; id_list = id_list->next) {
-    id = id_list->data;
-    aware = list_aware_find(list, id);
-
-    if(! aware) {
-      g_warning("buddy %s, %s not in list",
-		NSTR(id->user),
-		NSTR(id->community));
-      continue;
-    }
-
-    aware->membership = g_list_remove(aware->membership, list);
-    g_hash_table_remove(list->entries, id);
-  }
-
-  return remove_unused(srvc);
-}
-
-
-static void dismember_aware(gpointer k, struct aware_entry *aware,
-			    struct mwAwareList *list) {
-
-  aware->membership = g_list_remove(aware->membership, list);
-}
-
-
-int mwAwareList_removeAllAware(struct mwAwareList *list) {
-  struct mwServiceAware *srvc;
-
-  g_return_val_if_fail(list != NULL, -1);
-  srvc = list->service;
-
-  g_return_val_if_fail(srvc != NULL, -1);
-
-  /* for each entry, remove the aware list from the service entry's
-     membership collection */
-  if(list->entries) {
-    g_hash_table_foreach(list->entries, (GHFunc) dismember_aware, list);
-    g_hash_table_destroy(list->entries);
-  }
-
-  return remove_unused(srvc);
-}
-
-
-void mwAwareList_setClientData(struct mwAwareList *list,
-			       gpointer data, GDestroyNotify clear) {
-
-  g_return_if_fail(list != NULL);
-  mw_datum_set(&list->client_data, data, clear);
-}
-
-
-gpointer mwAwareList_getClientData(struct mwAwareList *list) {
-  g_return_val_if_fail(list != NULL, NULL);
-  return mw_datum_get(&list->client_data);
-}
-
-
-void mwAwareList_removeClientData(struct mwAwareList *list) {
-  g_return_if_fail(list != NULL);
-  mw_datum_clear(&list->client_data);
-}
-
-
-void mwServiceAware_setStatus(struct mwServiceAware *srvc,
-			      struct mwAwareIdBlock *user,
-			      struct mwUserStatus *stat) {
-
-  struct mwAwareSnapshot idb;
-
-  g_return_if_fail(srvc != NULL);
-  g_return_if_fail(user != NULL);
-  g_return_if_fail(stat != NULL);
-
-  /* just reference the strings. then we don't need to free them */
-  idb.id.type = user->type;
-  idb.id.user = user->user;
-  idb.id.community = user->community;
-
-  idb.group = NULL;
-  idb.online = TRUE;
-  idb.alt_id = NULL;
-
-  idb.status.status = stat->status;
-  idb.status.time = stat->time;
-  idb.status.desc = stat->desc;
-
-  idb.name = NULL;
-
-  status_recv(srvc, &idb);
-}
-
-
-const struct mwAwareAttribute *
-mwServiceAware_getAttribute(struct mwServiceAware *srvc,
-			    struct mwAwareIdBlock *user,
-			    guint32 key) {
-
-  struct aware_entry *aware;
-
-  g_return_val_if_fail(srvc != NULL, NULL);
-  g_return_val_if_fail(user != NULL, NULL);
-  g_return_val_if_fail(key != 0x00, NULL);
-
-  aware = aware_find(srvc, user);
-  g_return_val_if_fail(aware != NULL, NULL);
-
-  return g_hash_table_lookup(aware->attribs, GUINT_TO_POINTER(key));
-}
-
-
-const char *mwServiceAware_getText(struct mwServiceAware *srvc,
-				   struct mwAwareIdBlock *user) {
-
-  struct aware_entry *aware;
-
-  g_return_val_if_fail(srvc != NULL, NULL);
-  g_return_val_if_fail(user != NULL, NULL);
-
-  aware = aware_find(srvc, user);
-  if(! aware) return NULL;
-
-  return aware->aware.status.desc;
-}
-
-
--- a/src/protocols/sametime/meanwhile/srvc_conf.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,865 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <glib.h>
-#include <glib/ghash.h>
-#include <glib/glist.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include "mw_channel.h"
-#include "mw_debug.h"
-#include "mw_error.h"
-#include "mw_message.h"
-#include "mw_service.h"
-#include "mw_session.h"
-#include "mw_srvc_conf.h"
-#include "mw_util.h"
-
-
-/* This thing needs a re-write. More than anything else, I need to
-   re-examine the conferencing service protocol from more modern
-   clients */
-
-
-#define PROTOCOL_TYPE   0x00000010
-#define PROTOCOL_VER    0x00000002
-
-
-/** @see mwMsgChannelSend::type
-    @see recv */
-enum msg_type {
-  msg_WELCOME  = 0x0000,  /**< welcome message */
-  msg_INVITE   = 0x0001,  /**< outgoing invitation */
-  msg_JOIN     = 0x0002,  /**< someone joined */
-  msg_PART     = 0x0003,  /**< someone left */
-  msg_MESSAGE  = 0x0004,  /**< conference message */
-};
-
-
-/** the conferencing service */
-struct mwServiceConference {
-  struct mwService service;
-
-  /** call-back handler for this service */
-  struct mwConferenceHandler *handler;
-
-  /** collection of conferences in this service */
-  GList *confs;
-};
-
-
-/** a conference and its members */
-struct mwConference {
-  enum mwConferenceState state;   /**< state of the conference */
-  struct mwServiceConference *service;  /**< owning service */
-  struct mwChannel *channel;      /**< conference's channel */
-
-  char *name;   /**< server identifier for the conference */
-  char *title;  /**< topic for the conference */
-
-  struct mwLoginInfo owner;  /**< person who created this conference */
-  GHashTable *members;       /**< mapping guint16:mwLoginInfo */
-  struct mw_datum client_data;
-};
-
-
-#define MEMBER_FIND(conf, id) \
-  g_hash_table_lookup(conf->members, GUINT_TO_POINTER((guint) id))
-
-
-#define MEMBER_ADD(conf, id, member) \
-  g_hash_table_insert(conf->members, GUINT_TO_POINTER((guint) id), member)
-
-
-#define MEMBER_REM(conf, id) \
-  g_hash_table_remove(conf->members, GUINT_TO_POINTER((guint) id));
-
-
-/** clear and free a login info block */
-static void login_free(struct mwLoginInfo *li) {
-  mwLoginInfo_clear(li);
-  g_free(li);
-}
-
-
-/** generates a random conference name built around a user name */
-static char *conf_generate_name(const char *user) {
-  guint a, b;
-  char *ret;
-  
-  user = user? user: "";
-
-  srand(clock() + rand());
-  a = ((rand() & 0xff) << 8) | (rand() & 0xff);
-  b = time(NULL);
-
-  ret = g_strdup_printf("%s(%08x,%04x)", user, b, a);
-  g_debug("generated random conference name: '%s'", ret);
-  return ret;
-}
-
-
-
-
-
-static struct mwConference *conf_new(struct mwServiceConference *srvc) {
-
-  struct mwConference *conf;
-  struct mwSession *session;
-  const char *user;
-
-  conf = g_new0(struct mwConference, 1);
-  conf->state = mwConference_NEW;
-  conf->service = srvc;
-  conf->members = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
-					(GDestroyNotify) login_free);
-
-  session = mwService_getSession(MW_SERVICE(srvc));
-  user = mwSession_getProperty(session, mwSession_AUTH_USER_ID);
-
-  srvc->confs = g_list_prepend(srvc->confs, conf);
-
-  return conf;
-}
-
-
-/** clean and free a conference structure */
-static void conf_free(struct mwConference *conf) {
-  struct mwServiceConference *srvc;
-
-  /* this shouldn't ever happen, but just to be sure */
-  g_return_if_fail(conf != NULL);
-  
-  srvc = conf->service;
-
-  if(conf->members)
-    g_hash_table_destroy(conf->members);
-
-  g_list_remove_all(srvc->confs, conf);
-
-  mw_datum_clear(&conf->client_data);
-  
-  g_free(conf->name);
-  g_free(conf->title);
-  g_free(conf);
-}
-
-
-static struct mwConference *conf_find(struct mwServiceConference *srvc,
-				      struct mwChannel *chan) {
-  GList *l;
-
-  g_return_val_if_fail(srvc != NULL, NULL);
-  g_return_val_if_fail(chan != NULL, NULL);
-  
-  for(l = srvc->confs; l; l = l->next) {
-    struct mwConference *conf = l->data;
-    if(conf->channel == chan) return conf;
-  }
-
-  return NULL;
-}
-
-
-static const char *conf_state_str(enum mwConferenceState state) {
-  switch(state) {
-  case mwConference_NEW:      return "new";
-  case mwConference_PENDING:  return "pending";
-  case mwConference_INVITED:  return "invited";
-  case mwConference_OPEN:     return "open";
-  case mwConference_CLOSING:  return "closing";
-  case mwConference_ERROR:    return "error";
-
-  case mwConference_UNKNOWN:  /* fall through */
-  default:                    return "UNKNOWN";
-  }
-}
-
-
-static void conf_state(struct mwConference *conf,
-		       enum mwConferenceState state) {
-  g_return_if_fail(conf != NULL);
-
-  if(conf->state == state) return;
-
-  conf->state = state;
-  g_message("conference %s state: %s",
-	    NSTR(conf->name), conf_state_str(state));
-}
-
-
-static void recv_channelCreate(struct mwService *srvc,
-			       struct mwChannel *chan,
-			       struct mwMsgChannelCreate *msg) {
-
-  /* - this is how we really receive invitations
-     - create a conference and associate it with the channel
-     - obtain the invite data from the msg addtl info
-     - mark the conference as INVITED
-     - trigger the got_invite event
-  */
-
-  struct mwServiceConference *srvc_conf = (struct mwServiceConference *) srvc;
-  struct mwConference *conf;
-
-  struct mwGetBuffer *b;
-
-  char *invite = NULL;
-  guint tmp;
-
-  conf = conf_new(srvc_conf);
-  conf->channel = chan;
-
-  b = mwGetBuffer_wrap(&msg->addtl);
-
-  guint32_get(b, &tmp);
-  mwString_get(b, &conf->name);
-  mwString_get(b, &conf->title);
-  guint32_get(b, &tmp);
-  mwLoginInfo_get(b, &conf->owner);
-  guint32_get(b, &tmp);
-  mwString_get(b, &invite);
-
-  if(mwGetBuffer_error(b)) {
-    g_warning("failure parsing addtl for conference invite");
-    mwConference_destroy(conf, ERR_FAILURE, NULL);
-
-  } else {
-    struct mwConferenceHandler *h = srvc_conf->handler;
-    conf_state(conf, mwConference_INVITED);
-    if(h->on_invited)
-      h->on_invited(conf, &conf->owner, invite);
-  }
-
-  mwGetBuffer_free(b);
-  g_free(invite);
-}
-
-
-static void recv_channelAccept(struct mwService *srvc,
-			       struct mwChannel *chan,
-			       struct mwMsgChannelAccept *msg) {
-
-  ;
-}
-
-
-static void recv_channelDestroy(struct mwService *srvc,
-				struct mwChannel *chan,
-				struct mwMsgChannelDestroy *msg) {
-
-  /* - find conference from channel
-     - trigger got_closed
-     - remove conference, dealloc
-  */
-
-  struct mwServiceConference *srvc_conf = (struct mwServiceConference *) srvc;
-  struct mwConference *conf = conf_find(srvc_conf, chan);
-  struct mwConferenceHandler *h = srvc_conf->handler;
-
-  /* if there's no such conference, then I guess there's nothing to worry
-     about. Except of course for the fact that we should never receive a
-     channel destroy for a conference that doesn't exist. */
-  if(! conf) return;
-
-  conf->channel = NULL;
-
-  conf_state(conf, msg->reason? mwConference_ERROR: mwConference_CLOSING);
-
-  if(h->conf_closed)
-    h->conf_closed(conf, msg->reason);
-
-  mwConference_destroy(conf, ERR_SUCCESS, NULL);
-}
-
-
-static void WELCOME_recv(struct mwServiceConference *srvc,
-			 struct mwConference *conf,
-			 struct mwGetBuffer *b) {
-
-  struct mwConferenceHandler *h;
-  guint16 tmp16;
-  guint32 tmp32;
-  guint32 count;
-  GList *l = NULL;
-
-  /* re-read name and title */
-  g_free(conf->name);
-  g_free(conf->title);
-  conf->name = NULL;
-  conf->title = NULL;
-  mwString_get(b, &conf->name);
-  mwString_get(b, &conf->title);
-
-  /* some numbers we don't care about, then a count of members */
-  guint16_get(b, &tmp16);
-  guint32_get(b, &tmp32);
-  guint32_get(b, &count);
-
-  if(mwGetBuffer_error(b)) {
-    g_warning("error parsing welcome message for conference");
-    mwConference_destroy(conf, ERR_FAILURE, NULL);
-    return;
-  }
-  
-  while(count--) {
-    guint16 member_id;
-    struct mwLoginInfo *member = g_new0(struct mwLoginInfo, 1);
-
-    guint16_get(b, &member_id);
-    mwLoginInfo_get(b, member);
-
-    if(mwGetBuffer_error(b)) {
-      login_free(member);
-      break;
-    }
-
-    MEMBER_ADD(conf, member_id, member);
-    l = g_list_append(l, member);
-  }
-
-  conf_state(conf, mwConference_OPEN);
-
-  h = srvc->handler;
-  if(h->conf_opened)
-    h->conf_opened(conf, l);
-
-  /* get rid of the GList, but not its contents */
-  g_list_free(l);
-}
-
-
-static void JOIN_recv(struct mwServiceConference *srvc,
-		      struct mwConference *conf,
-		      struct mwGetBuffer *b) {
-
-  struct mwConferenceHandler *h;
-  guint16 m_id;
-  struct mwLoginInfo *m;
-  
-  /* for some inane reason, conferences we create will send a join
-     message for ourselves before the welcome message. Since the
-     welcome message will list our ID among those in the channel,
-     we're going to just pretend that these join messages don't
-     exist */
-  if(conf->state == mwConference_PENDING)
-    return;
-
-  m = g_new0(struct mwLoginInfo, 1);
-
-  guint16_get(b, &m_id);
-  mwLoginInfo_get(b, m);
-
-  if(mwGetBuffer_error(b)) {
-    g_warning("failed parsing JOIN message in conference");
-    login_free(m);
-    return;
-  }
-
-  MEMBER_ADD(conf, m_id, m);
-
-  h = srvc->handler;
-  if(h->on_peer_joined)
-    h->on_peer_joined(conf, m);
-}
-
-
-static void PART_recv(struct mwServiceConference *srvc,
-		      struct mwConference *conf,
-		      struct mwGetBuffer *b) {
-
-  /* - parse who left
-     - look up their membership
-     - remove them from the members list
-     - trigger the event
-  */
-
-  struct mwConferenceHandler *h;
-  guint16 id = 0;
-  struct mwLoginInfo *m;
-
-  guint16_get(b, &id);
-
-  if(mwGetBuffer_error(b)) return;
-
-  m = MEMBER_FIND(conf, id);
-  if(! m) return;
-
-  h = srvc->handler;
-  if(h->on_peer_parted)
-    h->on_peer_parted(conf, m);
-
-  MEMBER_REM(conf, id);
-}
-
-
-static void text_recv(struct mwServiceConference *srvc,
-		      struct mwConference *conf,
-		      struct mwLoginInfo *m,
-		      struct mwGetBuffer *b) {
-
-  /* this function acts a lot like receiving an IM Text message. The text
-     message contains only a string */
-
-  char *text = NULL;
-  struct mwConferenceHandler *h;
-  
-  mwString_get(b, &text);
-
-  if(mwGetBuffer_error(b)) {
-    g_warning("failed to parse text message in conference");
-    g_free(text);
-    return;
-  }
-
-  h = srvc->handler;
-  if(text && h->on_text) {
-    h->on_text(conf, m, text);
-  }
-
-  g_free(text);
-}
-
-
-static void data_recv(struct mwServiceConference *srvc,
-		      struct mwConference *conf,
-		      struct mwLoginInfo *m,
-		      struct mwGetBuffer *b) {
-
-  /* this function acts a lot like receiving an IM Data message. The
-     data message has a type, a subtype, and an opaque. We only
-     support typing notification though. */
-
-  /** @todo it's possible that some clients send text in a data
-      message, as we've seen rarely in the IM service. Have to add
-      support for that here */
-
-  guint32 type, subtype;
-  struct mwConferenceHandler *h;
-
-  guint32_get(b, &type);
-  guint32_get(b, &subtype);
-
-  if(mwGetBuffer_error(b)) return;
-
-  /* don't know how to deal with any others yet */
-  if(type != 0x01) {
-    g_message("unknown data message type (0x%08x, 0x%08x)", type, subtype);
-    return;
-  }
-
-  h = srvc->handler;
-  if(h->on_typing) {
-    h->on_typing(conf, m, !subtype);
-  }
-}
-
-
-static void MESSAGE_recv(struct mwServiceConference *srvc,
-			 struct mwConference *conf,
-			 struct mwGetBuffer *b) {
-
-  /* - look up who send the message by their id
-     - trigger the event
-  */
-
-  guint16 id;
-  guint32 type;
-  struct mwLoginInfo *m;
-
-  /* an empty buffer isn't an error, just ignored */
-  if(! mwGetBuffer_remaining(b)) return;
-
-  guint16_get(b, &id);
-  guint32_get(b, &type); /* reuse type variable */
-  guint32_get(b, &type);
-
-  if(mwGetBuffer_error(b)) return;
-
-  m = MEMBER_FIND(conf, id);
-  if(! m) {
-    g_warning("received message type 0x%04x from"
-	      " unknown conference member %u", type, id);
-    return;
-  }
-  
-  switch(type) {
-  case 0x01:  /* type is text */
-    text_recv(srvc, conf, m, b);
-    break;
-
-  case 0x02:  /* type is data */
-    data_recv(srvc, conf, m, b);
-    break;
-
-  default:
-    g_warning("unknown message type 0x%4x received in conference", type);
-  }
-}
-
-
-static void recv(struct mwService *srvc, struct mwChannel *chan,
-		 guint16 type, struct mwOpaque *data) {
-
-  struct mwServiceConference *srvc_conf = (struct mwServiceConference *) srvc;
-  struct mwConference *conf = conf_find(srvc_conf, chan);
-  struct mwGetBuffer *b;
-
-  g_return_if_fail(conf != NULL);
-
-  b = mwGetBuffer_wrap(data);
-
-  switch(type) {
-  case msg_WELCOME:
-    WELCOME_recv(srvc_conf, conf, b);
-    break;
-
-  case msg_JOIN:
-    JOIN_recv(srvc_conf, conf, b);
-    break;
-
-  case msg_PART:
-    PART_recv(srvc_conf, conf, b);
-    break;
-
-  case msg_MESSAGE:
-    MESSAGE_recv(srvc_conf, conf, b);
-    break;
-
-  default:
-    ; /* hrm. should log this. TODO */
-  }
-}
-
-
-static void clear(struct mwServiceConference *srvc) {
-  struct mwConferenceHandler *h;
-
-  while(srvc->confs)
-    conf_free(srvc->confs->data);
-
-  h = srvc->handler;
-  if(h && h->clear)
-    h->clear(srvc);
-  srvc->handler = NULL;
-}
-
-
-static const char *name(struct mwService *srvc) {
-  return "Basic Conferencing";
-}
-
-
-static const char *desc(struct mwService *srvc) {
-  return "Multi-user plain-text conferencing";
-}
-
-
-static void start(struct mwService *srvc) {
-  mwService_started(srvc);
-}
-
-
-static void stop(struct mwServiceConference *srvc) {
-  while(srvc->confs)
-    mwConference_destroy(srvc->confs->data, ERR_SUCCESS, NULL);
-
-  mwService_stopped(MW_SERVICE(srvc));
-}
-
-
-struct mwServiceConference *
-mwServiceConference_new(struct mwSession *session,
-			struct mwConferenceHandler *handler) {
-
-  struct mwServiceConference *srvc_conf;
-  struct mwService *srvc;
-
-  g_return_val_if_fail(session != NULL, NULL);
-  g_return_val_if_fail(handler != NULL, NULL);
-
-  srvc_conf = g_new0(struct mwServiceConference, 1);
-  srvc = &srvc_conf->service;
-
-  mwService_init(srvc, session, mwService_CONFERENCE);
-  srvc->start = start;
-  srvc->stop = (mwService_funcStop) stop;
-  srvc->recv_create = recv_channelCreate;
-  srvc->recv_accept = recv_channelAccept;
-  srvc->recv_destroy = recv_channelDestroy;
-  srvc->recv = recv;
-  srvc->clear = (mwService_funcClear) clear;
-  srvc->get_name = name;
-  srvc->get_desc = desc;
-
-  srvc_conf->handler = handler;
-
-  return srvc_conf;
-}
-
-
-struct mwConference *mwConference_new(struct mwServiceConference *srvc,
-				      const char *title) {
-  struct mwConference *conf;
-
-  g_return_val_if_fail(srvc != NULL, NULL);
-
-  conf = conf_new(srvc);
-  conf->title = g_strdup(title);
-
-  return conf;
-}
-
-
-struct mwServiceConference *
-mwConference_getService(struct mwConference *conf) {
-  g_return_val_if_fail(conf != NULL, NULL);
-  return conf->service;
-}
-
-
-const char *mwConference_getName(struct mwConference *conf) {
-  g_return_val_if_fail(conf != NULL, NULL);
-  return conf->name;
-}
-
-
-const char *mwConference_getTitle(struct mwConference *conf) {
-  g_return_val_if_fail(conf != NULL, NULL);
-  return conf->title;
-}
-
-
-GList *mwConference_memebers(struct mwConference *conf) {
-  g_return_val_if_fail(conf != NULL, NULL);
-  g_return_val_if_fail(conf->members != NULL, NULL);
-
-  return map_collect_values(conf->members);
-}
-
-
-int mwConference_open(struct mwConference *conf) {
-  struct mwSession *session;
-  struct mwChannel *chan;
-  struct mwPutBuffer *b;
-  int ret;
-  
-  g_return_val_if_fail(conf != NULL, -1);
-  g_return_val_if_fail(conf->service != NULL, -1);
-  g_return_val_if_fail(conf->state == mwConference_NEW, -1);
-  g_return_val_if_fail(conf->channel == NULL, -1);
-
-  session = mwService_getSession(MW_SERVICE(conf->service));
-  g_return_val_if_fail(session != NULL, -1);
-
-  if(! conf->name) {
-    char *user = mwSession_getProperty(session, mwSession_AUTH_USER_ID);
-    conf->name = conf_generate_name(user? user: "meanwhile");
-  }
-
-  chan = mwChannel_newOutgoing(mwSession_getChannels(session));
-  mwChannel_setService(chan, MW_SERVICE(conf->service));
-  mwChannel_setProtoType(chan, PROTOCOL_TYPE);
-  mwChannel_setProtoVer(chan, PROTOCOL_VER);
-  
-  /* offer all known ciphers */
-  mwChannel_populateSupportedCipherInstances(chan);
-
-  b = mwPutBuffer_new();
-  mwString_put(b, conf->name);
-  mwString_put(b, conf->title);
-  guint32_put(b, 0x00);
-  mwPutBuffer_finalize(mwChannel_getAddtlCreate(chan), b);
-
-  ret = mwChannel_create(chan);
-  if(ret) {
-    conf_state(conf, mwConference_ERROR);
-  } else {
-    conf_state(conf, mwConference_PENDING);
-    conf->channel = chan;
-  }
-
-  return ret;
-}
-
-
-int mwConference_destroy(struct mwConference *conf,
-			 guint32 reason, const char *text) {
-
-  struct mwServiceConference *srvc;
-  struct mwOpaque info = { 0, 0 };
-  int ret = 0;
-
-  g_return_val_if_fail(conf != NULL, -1);
-
-  srvc = conf->service;
-  g_return_val_if_fail(srvc != NULL, -1);
-
-  /* remove conference from the service */
-  srvc->confs = g_list_remove_all(srvc->confs, conf);
-
-  /* close the channel if applicable */
-  if(conf->channel) {
-    if(text && *text) {
-      info.len = strlen(text);
-      info.data = (guchar *) text;
-    }
-
-    ret = mwChannel_destroy(conf->channel, reason, &info);
-  }
-  
-  /* free the conference */
-  conf_free(conf);
-
-  return ret;
-}
-
-
-int mwConference_accept(struct mwConference *conf) {
-  /* - if conference is not INVITED, return -1
-     - accept the conference channel
-     - send an empty JOIN message
-  */
-
-  struct mwChannel *chan;
-  int ret;
-
-  g_return_val_if_fail(conf != NULL, -1);
-  g_return_val_if_fail(conf->state == mwConference_INVITED, -1);
-
-  chan = conf->channel;
-  ret = mwChannel_accept(chan);
-
-  if(! ret)
-    ret = mwChannel_sendEncrypted(chan, msg_JOIN, NULL, FALSE);
-
-  return ret;
-}
-
-
-int mwConference_invite(struct mwConference *conf,
-			struct mwIdBlock *who,
-			const char *text) {
-
-  struct mwPutBuffer *b;
-  struct mwOpaque o;
-  int ret;
-
-  g_return_val_if_fail(conf != NULL, -1);
-  g_return_val_if_fail(conf->channel != NULL, -1);
-  g_return_val_if_fail(who != NULL, -1);
-
-  b = mwPutBuffer_new();
-
-  mwIdBlock_put(b, who);
-  guint16_put(b, 0x00);
-  guint32_put(b, 0x00);
-  mwString_put(b, text);
-  mwString_put(b, who->user);
-
-  mwPutBuffer_finalize(&o, b);
-  ret = mwChannel_sendEncrypted(conf->channel, msg_INVITE, &o, FALSE);
-  mwOpaque_clear(&o);
-
-  return ret;
-}
-
-
-int mwConference_sendText(struct mwConference *conf, const char *text) {
-  struct mwPutBuffer *b;
-  struct mwOpaque o;
-  int ret;
-
-  g_return_val_if_fail(conf != NULL, -1);
-  g_return_val_if_fail(conf->channel != NULL, -1);
-
-  b = mwPutBuffer_new();
-
-  guint32_put(b, 0x01);
-  mwString_put(b, text);
-
-  mwPutBuffer_finalize(&o, b);
-  ret = mwChannel_sendEncrypted(conf->channel, msg_MESSAGE, &o, FALSE);
-  mwOpaque_clear(&o);
-
-  return ret;
-}
-
-
-int mwConference_sendTyping(struct mwConference *conf, gboolean typing) {
-  struct mwPutBuffer *b;
-  struct mwOpaque o;
-  int ret;
-
-  g_return_val_if_fail(conf != NULL, -1);
-  g_return_val_if_fail(conf->channel != NULL, -1);
-  g_return_val_if_fail(conf->state == mwConference_OPEN, -1);
-
-  b = mwPutBuffer_new();
-
-  guint32_put(b, 0x02);
-  guint32_put(b, 0x01);
-  guint32_put(b, !typing);
-  mwOpaque_put(b, NULL);
-
-  mwPutBuffer_finalize(&o, b);
-  ret = mwChannel_sendEncrypted(conf->channel, msg_MESSAGE, &o, FALSE);
-  mwOpaque_clear(&o);
-
-  return ret;
-}
-
-
-void mwConference_setClientData(struct mwConference *conference,
-			     gpointer data, GDestroyNotify clear) {
-
-  g_return_if_fail(conference != NULL);
-  mw_datum_set(&conference->client_data, data, clear);
-}
-
-
-gpointer mwConference_getClientData(struct mwConference *conference) {
-  g_return_val_if_fail(conference != NULL, NULL);
-  return mw_datum_get(&conference->client_data);
-}
-
-
-void mwConference_removeClientData(struct mwConference *conference) {
-  g_return_if_fail(conference != NULL);
-  mw_datum_clear(&conference->client_data);
-}
-
-
-struct mwConferenceHandler *
-mwServiceConference_getHandler(struct mwServiceConference *srvc) {
-  g_return_val_if_fail(srvc != NULL, NULL);
-  return srvc->handler;
-}
-
-
-GList *mwServiceConference_getConferences(struct mwServiceConference *srvc) {
-  g_return_val_if_fail(srvc != NULL, NULL);
-  return g_list_copy(srvc->confs);
-}
-
--- a/src/protocols/sametime/meanwhile/srvc_ft.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,654 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-
-#include <glib/glist.h>
-
-#include "mw_channel.h"
-#include "mw_common.h"
-#include "mw_debug.h"
-#include "mw_error.h"
-#include "mw_message.h"
-#include "mw_service.h"
-#include "mw_session.h"
-#include "mw_srvc_ft.h"
-#include "mw_util.h"
-
-
-#define PROTOCOL_TYPE  0x00000000
-#define PROTOCOL_VER   0x00000001
-
-
-/** send-on-channel type: FT transfer data */
-#define msg_TRANSFER  0x0001
-
-
-/** ack received transfer data */
-#define msg_RECEIVED  0x0002
-
-
-struct mwServiceFileTransfer {
-  struct mwService service;
-
-  struct mwFileTransferHandler *handler;
-  GList *transfers;
-};
-
-
-struct mwFileTransfer {
-  struct mwServiceFileTransfer *service;
-  
-  struct mwChannel *channel;
-  struct mwIdBlock who;
-
-  enum mwFileTransferState state;
-
-  char *filename;
-  char *message;
-
-  guint32 size;
-  guint32 remaining;
-
-  struct mw_datum client_data;
-};
-
-
-/** momentarily places a mwLoginInfo into a mwIdBlock */
-static void login_into_id(struct mwIdBlock *to, struct mwLoginInfo *from) {
-  to->user = from->user_id;
-  to->community = from->community;
-}
-
-
-static const char *ft_state_str(enum mwFileTransferState state) {
-  switch(state) {
-  case mwFileTransfer_NEW:
-    return "new";
-
-  case mwFileTransfer_PENDING:
-    return "pending";
-
-  case mwFileTransfer_OPEN:
-    return "open";
-
-  case mwFileTransfer_CANCEL_LOCAL:
-    return "cancelled locally";
-
-  case mwFileTransfer_CANCEL_REMOTE:
-    return "cancelled remotely";
-
-  case mwFileTransfer_DONE:
-    return "done";
-
-  case mwFileTransfer_ERROR:
-    return "error";
-
-  case mwFileTransfer_UNKNOWN:
-  default:
-    return "UNKNOWN";
-  }
-}
-
-
-static void ft_state(struct mwFileTransfer *ft,
-		     enum mwFileTransferState state) {
-
-  g_return_if_fail(ft != NULL);
-
-  if(ft->state == state) return;
-
-  g_info("setting ft (%s, %s) state: %s",
-	 NSTR(ft->who.user), NSTR(ft->who.community),
-	 ft_state_str(state));
-
-  ft->state = state;
-}
-
-
-static void recv_channelCreate(struct mwServiceFileTransfer *srvc,
-			       struct mwChannel *chan,
-			       struct mwMsgChannelCreate *msg) {
-
-  struct mwFileTransferHandler *handler;
-  struct mwGetBuffer *b;
-
-  char *fnm, *txt;
-  guint32 size, junk;
-  gboolean b_err;
-
-  g_return_if_fail(srvc->handler != NULL);
-  handler = srvc->handler;
-  
-  b = mwGetBuffer_wrap(&msg->addtl);
-
-  guint32_get(b, &junk); /* unknown */
-  mwString_get(b, &fnm); /* offered filename */
-  mwString_get(b, &txt); /* offering message */
-  guint32_get(b, &size); /* size of offered file */
-  guint32_get(b, &junk); /* unknown */
-  /* and we just skip an unknown guint16 at the end */
-
-  b_err = mwGetBuffer_error(b);
-  mwGetBuffer_free(b);
-
-  if(b_err) {
-    g_warning("bad/malformed addtl in File Transfer service");
-    mwChannel_destroy(chan, ERR_FAILURE, NULL);
-
-  } else {
-    struct mwIdBlock idb;
-    struct mwFileTransfer *ft;
-
-    login_into_id(&idb, mwChannel_getUser(chan));
-    ft = mwFileTransfer_new(srvc, &idb, txt, fnm, size);
-    ft->channel = chan;
-    ft_state(ft, mwFileTransfer_PENDING);
-
-    mwChannel_setServiceData(chan, ft, NULL);
-
-    if(handler->ft_offered)
-      handler->ft_offered(ft);
-  }
-
-  g_free(fnm);
-  g_free(txt);
-}
-
-
-static void recv_channelAccept(struct mwServiceFileTransfer *srvc,
-			       struct mwChannel *chan,
-			       struct mwMsgChannelAccept *msg) {
-
-  struct mwFileTransferHandler *handler;
-  struct mwFileTransfer *ft;
-
-  g_return_if_fail(srvc->handler != NULL);
-  handler = srvc->handler;
-
-  ft = mwChannel_getServiceData(chan);
-  g_return_if_fail(ft != NULL);
-
-  ft_state(ft, mwFileTransfer_OPEN);
-
-  if(handler->ft_opened)
-    handler->ft_opened(ft);
-}
-
-
-static void recv_channelDestroy(struct mwServiceFileTransfer *srvc,
-				struct mwChannel *chan,
-				struct mwMsgChannelDestroy *msg) {
-
-  struct mwFileTransferHandler *handler;
-  struct mwFileTransfer *ft;
-  guint32 code;
-
-  code = msg->reason;
-
-  g_return_if_fail(srvc->handler != NULL);
-  handler = srvc->handler;
-
-  ft = mwChannel_getServiceData(chan);
-  g_return_if_fail(ft != NULL);
-
-  ft->channel = NULL;
-
-  if(! mwFileTransfer_isDone(ft))
-    ft_state(ft, mwFileTransfer_CANCEL_REMOTE);
-
-  mwFileTransfer_close(ft, code);
-}
-
-
-static void recv_TRANSFER(struct mwFileTransfer *ft,
-			  struct mwOpaque *data) {
-
-  struct mwServiceFileTransfer *srvc;
-  struct mwFileTransferHandler *handler;
-  
-  srvc = ft->service;
-  handler = srvc->handler;
-
-  g_return_if_fail(mwFileTransfer_isOpen(ft));
-
-  if(data->len > ft->remaining) {
-    /* @todo handle error */
-
-  } else {
-    ft->remaining -= data->len;
-
-    if(! ft->remaining)
-      ft_state(ft, mwFileTransfer_DONE);
-    
-    if(handler->ft_recv)
-      handler->ft_recv(ft, data);
-  }
-}
-
-
-static void recv_RECEIVED(struct mwFileTransfer *ft,
-			  struct mwOpaque *data) {
-
-  struct mwServiceFileTransfer *srvc;
-  struct mwFileTransferHandler *handler;
-  
-  srvc = ft->service;
-  handler = srvc->handler;
-
-  if(! ft->remaining)
-    ft_state(ft, mwFileTransfer_DONE);
-
-  if(handler->ft_ack)
-    handler->ft_ack(ft);
-
-  if(! ft->remaining)
-    mwFileTransfer_close(ft, mwFileTransfer_SUCCESS);
-}
-
-
-static void recv(struct mwService *srvc, struct mwChannel *chan,
-		 guint16 type, struct mwOpaque *data) {
-
-  struct mwFileTransfer *ft;
-  
-  ft = mwChannel_getServiceData(chan);
-  g_return_if_fail(ft != NULL);
-
-  switch(type) {
-  case msg_TRANSFER:
-    recv_TRANSFER(ft, data);
-    break;
-
-  case msg_RECEIVED:
-    recv_RECEIVED(ft, data);
-    break;
-
-  default:
-    mw_mailme_opaque(data, "unknown message in ft service: 0x%04x", type);
-  }
-}
-
-
-static void clear(struct mwServiceFileTransfer *srvc) {
-  struct mwFileTransferHandler *h;
-  
-  h = srvc->handler;
-  if(h && h->clear)
-    h->clear(srvc);
-  srvc->handler = NULL;
-}
-
-
-static const char *name(struct mwService *srvc) {
-  return "File Transfer";
-}
-
-
-static const char *desc(struct mwService *srvc) {
-  return "Provides file transfer capabilities through the community server";
-}
-
-
-static void start(struct mwService *srvc) {
-  mwService_started(srvc);
-}
-
-
-static void stop(struct mwServiceFileTransfer *srvc) {
-  while(srvc->transfers) {
-    mwFileTransfer_free(srvc->transfers->data);
-  }
-
-  mwService_stopped(MW_SERVICE(srvc));
-}
-
-
-struct mwServiceFileTransfer *
-mwServiceFileTransfer_new(struct mwSession *session,
-			  struct mwFileTransferHandler *handler) {
-
-  struct mwServiceFileTransfer *srvc_ft;
-  struct mwService *srvc;
-
-  g_return_val_if_fail(session != NULL, NULL);
-  g_return_val_if_fail(handler != NULL, NULL);
-
-  srvc_ft = g_new0(struct mwServiceFileTransfer, 1);
-  srvc = MW_SERVICE(srvc_ft);
-
-  mwService_init(srvc, session, mwService_FILE_TRANSFER);
-  srvc->recv_create = (mwService_funcRecvCreate) recv_channelCreate;
-  srvc->recv_accept = (mwService_funcRecvAccept) recv_channelAccept;
-  srvc->recv_destroy = (mwService_funcRecvDestroy) recv_channelDestroy;
-  srvc->recv = recv;
-  srvc->clear = (mwService_funcClear) clear;
-  srvc->get_name = name;
-  srvc->get_desc = desc;
-  srvc->start = start;
-  srvc->stop = (mwService_funcStop) stop;
-
-  srvc_ft->handler = handler;
-
-  return srvc_ft;
-}
-
-
-struct mwFileTransferHandler *
-mwServiceFileTransfer_getHandler(struct mwServiceFileTransfer *srvc) {
-  g_return_val_if_fail(srvc != NULL, NULL);
-  return srvc->handler;
-}
-
-
-const GList *
-mwServiceFileTransfer_getTransfers(struct mwServiceFileTransfer *srvc) {
-  g_return_val_if_fail(srvc != NULL, NULL);
-  return srvc->transfers;
-}
-
-
-struct mwFileTransfer *
-mwFileTransfer_new(struct mwServiceFileTransfer *srvc,
-		   const struct mwIdBlock *who, const char *msg,
-		   const char *filename, guint32 filesize) {
-  
-  struct mwFileTransfer *ft;
-
-  g_return_val_if_fail(srvc != NULL, NULL);
-  g_return_val_if_fail(who != NULL, NULL);
-  
-  ft = g_new0(struct mwFileTransfer, 1);
-  ft->service = srvc;
-  mwIdBlock_clone(&ft->who, who);
-  ft->filename = g_strdup(filename);
-  ft->message = g_strdup(msg);
-  ft->size = ft->remaining = filesize;
-
-  ft_state(ft, mwFileTransfer_NEW);
-
-  /* stick a reference in the service */
-  srvc->transfers = g_list_prepend(srvc->transfers, ft);
-
-  return ft;
-}
-
-
-struct mwServiceFileTransfer *
-mwFileTransfer_getService(struct mwFileTransfer *ft) {
-  g_return_val_if_fail(ft != NULL, NULL);
-  return ft->service;
-}
-
-
-enum mwFileTransferState
-mwFileTransfer_getState(struct mwFileTransfer *ft) {
-  g_return_val_if_fail(ft != NULL, mwFileTransfer_UNKNOWN);
-  return ft->state;
-}
-
-
-const struct mwIdBlock *
-mwFileTransfer_getUser(struct mwFileTransfer *ft) {
-  g_return_val_if_fail(ft != NULL, NULL);
-  return &ft->who;
-}
-
-
-const char *
-mwFileTransfer_getMessage(struct mwFileTransfer *ft) {
-  g_return_val_if_fail(ft != NULL, NULL);
-  return ft->message;
-}
-
-
-const char *
-mwFileTransfer_getFileName(struct mwFileTransfer *ft) {
-  g_return_val_if_fail(ft != NULL, NULL);
-  return ft->filename;
-}
-
-
-guint32 mwFileTransfer_getFileSize(struct mwFileTransfer *ft) {
-  g_return_val_if_fail(ft != NULL, 0);
-  return ft->size;
-}
-
-
-guint32 mwFileTransfer_getRemaining(struct mwFileTransfer *ft) {
-  g_return_val_if_fail(ft != NULL, 0);
-  return ft->remaining;
-}
-
-
-int mwFileTransfer_accept(struct mwFileTransfer *ft) {
-  struct mwServiceFileTransfer *srvc;
-  struct mwFileTransferHandler *handler;
-  int ret;
-
-  g_return_val_if_fail(ft != NULL, -1);
-  g_return_val_if_fail(ft->channel != NULL, -1);
-  g_return_val_if_fail(mwFileTransfer_isPending(ft), -1);
-  g_return_val_if_fail(mwChannel_isIncoming(ft->channel), -1);
-  g_return_val_if_fail(mwChannel_isState(ft->channel, mwChannel_WAIT), -1);
-
-  g_return_val_if_fail(ft->service != NULL, -1);
-  srvc = ft->service;
-
-  g_return_val_if_fail(srvc->handler != NULL, -1);
-  handler = srvc->handler;
-
-  ret = mwChannel_accept(ft->channel);
-
-  if(ret) {
-    mwFileTransfer_close(ft, ERR_FAILURE);
-
-  } else {
-    ft_state(ft, mwFileTransfer_OPEN);
-    if(handler->ft_opened)
-      handler->ft_opened(ft);
-  }
-
-  return ret;
-}
-
-
-static void ft_create_chan(struct mwFileTransfer *ft) {
-  struct mwSession *s;
-  struct mwChannelSet *cs;
-  struct mwChannel *chan;
-  struct mwLoginInfo *login;
-  struct mwPutBuffer *b;
-  
-  /* we only should be calling this if there isn't a channel already
-     associated with the conversation */
-  g_return_if_fail(ft != NULL);
-  g_return_if_fail(mwFileTransfer_isNew(ft));
-  g_return_if_fail(ft->channel == NULL);
-		   
-  s = mwService_getSession(MW_SERVICE(ft->service));
-  cs = mwSession_getChannels(s);
-
-  chan = mwChannel_newOutgoing(cs);
-  mwChannel_setService(chan, MW_SERVICE(ft->service));
-  mwChannel_setProtoType(chan, PROTOCOL_TYPE);
-  mwChannel_setProtoVer(chan, PROTOCOL_VER);
-
-  /* offer all known ciphers */
-  mwChannel_populateSupportedCipherInstances(chan);
-
-  /* set the target */
-  login = mwChannel_getUser(chan);
-  login->user_id = g_strdup(ft->who.user);
-  login->community = g_strdup(ft->who.community);
-
-  /* compose the addtl create */
-  b = mwPutBuffer_new();
-  guint32_put(b, 0x00);
-  mwString_put(b, ft->filename);
-  mwString_put(b, ft->message);
-  guint32_put(b, ft->size);
-  guint32_put(b, 0x00);
-  guint16_put(b, 0x00);
-
-  mwPutBuffer_finalize(mwChannel_getAddtlCreate(chan), b);
-
-  ft->channel = mwChannel_create(chan)? NULL: chan;
-  if(ft->channel) {
-    mwChannel_setServiceData(ft->channel, ft, NULL);
-  }
-}
-
-
-int mwFileTransfer_offer(struct mwFileTransfer *ft) {
-  struct mwServiceFileTransfer *srvc;
-  struct mwFileTransferHandler *handler;
-
-  g_return_val_if_fail(ft != NULL, -1);
-  g_return_val_if_fail(ft->channel == NULL, -1);
-  g_return_val_if_fail(mwFileTransfer_isNew(ft), -1);
-
-  g_return_val_if_fail(ft->service != NULL, -1);
-  srvc = ft->service;
-
-  g_return_val_if_fail(srvc->handler != NULL, -1);
-  handler = srvc->handler;
-
-  ft_create_chan(ft);
-  if(ft->channel) {
-    ft_state(ft, mwFileTransfer_PENDING);
-  } else {
-    ft_state(ft, mwFileTransfer_ERROR);
-    mwFileTransfer_close(ft, ERR_FAILURE);
-  }
-
-  return 0;
-}
-
-
-int mwFileTransfer_close(struct mwFileTransfer *ft, guint32 code) {
-  struct mwServiceFileTransfer *srvc;
-  struct mwFileTransferHandler *handler;
-  int ret = 0;
-
-  g_return_val_if_fail(ft != NULL, -1);
-
-  if(mwFileTransfer_isOpen(ft))
-    ft_state(ft, mwFileTransfer_CANCEL_LOCAL);
-
-  if(ft->channel) {
-    ret = mwChannel_destroy(ft->channel, code, NULL);
-    ft->channel = NULL;
-  }
-
-  srvc = ft->service;
-  g_return_val_if_fail(srvc != NULL, ret);
-
-  handler = srvc->handler;
-  g_return_val_if_fail(handler != NULL, ret);
-
-  if(handler->ft_closed)
-    handler->ft_closed(ft, code);
-
-  return ret;
-}
-
-
-void mwFileTransfer_free(struct mwFileTransfer *ft) {
-  struct mwServiceFileTransfer *srvc;
-
-  if(! ft) return;
-
-  srvc = ft->service;
-  if(srvc)
-    srvc->transfers = g_list_remove(srvc->transfers, ft);
-
-  if(ft->channel) {
-    mwChannel_destroy(ft->channel, mwFileTransfer_SUCCESS, NULL);
-    ft->channel = NULL;
-  }
-
-  mwFileTransfer_removeClientData(ft);
-
-  mwIdBlock_clear(&ft->who);
-  g_free(ft->filename);
-  g_free(ft->message);
-  g_free(ft);
-}
-
-
-int mwFileTransfer_send(struct mwFileTransfer *ft,
-			struct mwOpaque *data) {
-
-  struct mwChannel *chan;
-  int ret;
-
-  g_return_val_if_fail(ft != NULL, -1);
-  g_return_val_if_fail(mwFileTransfer_isOpen(ft), -1);
-  g_return_val_if_fail(ft->channel != NULL, -1);
-  chan = ft->channel;
-
-  g_return_val_if_fail(mwChannel_isOutgoing(chan), -1);
-
-  if(data->len > ft->remaining) {
-    /* @todo handle error */
-    return -1;
-  }
-
-  ret = mwChannel_send(chan, msg_TRANSFER, data);
-  if(! ret) ft->remaining -= data->len;
-  
-  /* we're not done until we receive an ACK for the last piece of
-     outgoing data */
-
-  return ret;
-}
-
-
-int mwFileTransfer_ack(struct mwFileTransfer *ft) {
-  struct mwChannel *chan;
-
-  g_return_val_if_fail(ft != NULL, -1);
-
-  chan = ft->channel;
-  g_return_val_if_fail(chan != NULL, -1);
-  g_return_val_if_fail(mwChannel_isIncoming(chan), -1);
-
-  return mwChannel_sendEncrypted(chan, msg_RECEIVED, NULL, FALSE);
-}
-
-
-void mwFileTransfer_setClientData(struct mwFileTransfer *ft,
-				  gpointer data, GDestroyNotify clean) {
-  g_return_if_fail(ft != NULL);
-  mw_datum_set(&ft->client_data, data, clean);
-}
-
-
-gpointer mwFileTransfer_getClientData(struct mwFileTransfer *ft) {
-  g_return_val_if_fail(ft != NULL, NULL);
-  return mw_datum_get(&ft->client_data);
-}
-
-
-void mwFileTransfer_removeClientData(struct mwFileTransfer *ft) {
-  g_return_if_fail(ft != NULL);
-  mw_datum_clear(&ft->client_data);
-}
-
--- a/src/protocols/sametime/meanwhile/srvc_im.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1055 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <glib.h>
-#include <glib/glist.h>
-#include <string.h>
-
-#include "mw_channel.h"
-#include "mw_debug.h"
-#include "mw_error.h"
-#include "mw_message.h"
-#include "mw_service.h"
-#include "mw_session.h"
-#include "mw_srvc_im.h"
-#include "mw_util.h"
-
-
-#define PROTOCOL_TYPE  0x00001000
-#define PROTOCOL_VER   0x00000003
-
-
-/* data for the addtl blocks of channel creation */
-#define mwImAddtlA_NORMAL  0x00000001
-
-#define mwImAddtlB_NORMAL      0x00000001  /**< standard */
-#define mwImAddtlB_PRECONF     0x00000019  /**< pre-conference chat */
-#define mwImAddtlB_NOTESBUDDY  0x00033453  /**< notesbuddy */
-
-#define mwImAddtlC_NORMAL  0x00000002
-
-
-/* send-on-channel message type */
-#define msg_MESSAGE  0x0064  /**< IM message */
-
-
-#define BREAKUP  2048
-
-
-/* which type of im? */
-enum mwImType {
-  mwIm_TEXT  = 0x00000001,  /**< text message */
-  mwIm_DATA  = 0x00000002,  /**< status message (usually) */
-};
-
-
-/* which type of data im? */
-enum mwImDataType {
-  mwImData_TYPING   = 0x00000001,  /**< common use typing indicator */
-  mwImData_SUBJECT  = 0x00000003,  /**< notesbuddy IM topic */
-  mwImData_HTML     = 0x00000004,  /**< notesbuddy HTML message */
-  mwImData_MIME     = 0x00000005,  /**< notesbuddy MIME message, w/image */
-  mwImData_TIMESTAMP = 0x00000006, /**< notesbuddy timestamp */
-
-  mwImData_INVITE   = 0x0000000a,  /**< Places invitation */
-
-  mwImData_MULTI_START  = 0x00001388,
-  mwImData_MULTI_STOP   = 0x00001389,
-};
-
-
-/** @todo might be appropriate to make a couple of hashtables to
-    reference conversations by channel and target */
-struct mwServiceIm {
-  struct mwService service;
-
-  enum mwImClientType features;
-
-  struct mwImHandler *handler;
-  GList *convs;  /**< list of struct im_convo */
-};
-
-
-struct mwConversation {
-  struct mwServiceIm *service;  /**< owning service */
-  struct mwChannel *channel;    /**< channel */
-  struct mwIdBlock target;      /**< conversation target */
-
-  gboolean ext_id;              /**< special treatment, external ID */
-
-  /** state of the conversation, based loosely on the state of its
-      underlying channel */
-  enum mwConversationState state;
-
-  enum mwImClientType features;
-
-  GString *multi;               /**< buffer for multi-chunk message */
-  enum mwImSendType multi_type; /**< type of incoming multi-chunk message */
-
-  struct mw_datum client_data;
-};
-
-
-/** momentarily places a mwLoginInfo into a mwIdBlock */
-static void login_into_id(struct mwIdBlock *to, struct mwLoginInfo *from) {
-  to->user = from->user_id;
-  to->community = from->community;
-}
-
-
-static struct mwConversation *convo_find_by_user(struct mwServiceIm *srvc,
-						 struct mwIdBlock *to) {
-  GList *l;
-
-  for(l = srvc->convs; l; l = l->next) {
-    struct mwConversation *c = l->data;
-    if(mwIdBlock_equal(&c->target, to))
-       return c;
-  }
-
-  return NULL;
-}
-
-
-static const char *conv_state_str(enum mwConversationState state) {
-  switch(state) {
-  case mwConversation_CLOSED:
-    return "closed";
-
-  case mwConversation_OPEN:
-    return "open";
-
-  case mwConversation_PENDING:
-    return "pending";
-
-  case mwConversation_UNKNOWN:
-  default:
-    return "UNKNOWN";
-  }
-}
-
-
-static void convo_set_state(struct mwConversation *conv,
-			    enum mwConversationState state) {
-
-  g_return_if_fail(conv != NULL);
-
-  if(conv->state != state) {
-    g_info("setting conversation (%s, %s) state: %s",
-	   NSTR(conv->target.user), NSTR(conv->target.community),
-	   conv_state_str(state));
-    conv->state = state;
-  }
-}
-
-
-struct mwConversation *mwServiceIm_findConversation(struct mwServiceIm *srvc,
-						    struct mwIdBlock *to) {
-  g_return_val_if_fail(srvc != NULL, NULL);
-  g_return_val_if_fail(to != NULL, NULL);
-
-  return convo_find_by_user(srvc, to);
-}
-
-
-struct mwConversation *mwServiceIm_getConversation(struct mwServiceIm *srvc,
-						   struct mwIdBlock *to) {
-  struct mwConversation *c;
-
-  g_return_val_if_fail(srvc != NULL, NULL);
-  g_return_val_if_fail(to != NULL, NULL);
-
-  c = convo_find_by_user(srvc, to);
-  if(! c) {
-    c = g_new0(struct mwConversation, 1);
-    c->service = srvc;
-    mwIdBlock_clone(&c->target, to);
-    c->state = mwConversation_CLOSED;
-    c->features = srvc->features;
-
-    /* mark external users */
-    /* c->ext_id = g_str_has_prefix(to->user, "@E "); */
-
-    srvc->convs = g_list_prepend(srvc->convs, c);
-  }
-
-  return c;
-}
-
-
-static void convo_create_chan(struct mwConversation *c) {
-  struct mwSession *s;
-  struct mwChannelSet *cs;
-  struct mwChannel *chan;
-  struct mwLoginInfo *login;
-  struct mwPutBuffer *b;
-
-  /* we only should be calling this if there isn't a channel already
-     associated with the conversation */
-  g_return_if_fail(c != NULL);
-  g_return_if_fail(mwConversation_isPending(c));
-  g_return_if_fail(c->channel == NULL);
-
-  s = mwService_getSession(MW_SERVICE(c->service));
-  cs = mwSession_getChannels(s);
-
-  chan = mwChannel_newOutgoing(cs);
-  mwChannel_setService(chan, MW_SERVICE(c->service));
-  mwChannel_setProtoType(chan, PROTOCOL_TYPE);
-  mwChannel_setProtoVer(chan, PROTOCOL_VER);
-
-  /* offer all known ciphers */
-  mwChannel_populateSupportedCipherInstances(chan);
-
-  /* set the target */
-  login = mwChannel_getUser(chan);
-  login->user_id = g_strdup(c->target.user);
-  login->community = g_strdup(c->target.community);
-
-  /* compose the addtl create, with optional FANCY HTML! */
-  b = mwPutBuffer_new();
-  guint32_put(b, mwImAddtlA_NORMAL);
-  guint32_put(b, c->features);
-  mwPutBuffer_finalize(mwChannel_getAddtlCreate(chan), b);
-
-  c->channel = mwChannel_create(chan)? NULL: chan;
-  if(c->channel) {
-    mwChannel_setServiceData(c->channel, c, NULL);
-  }
-}
-
-
-void mwConversation_open(struct mwConversation *conv) {
-  g_return_if_fail(conv != NULL);
-  g_return_if_fail(mwConversation_isClosed(conv));
-
-  convo_set_state(conv, mwConversation_PENDING);
-  convo_create_chan(conv);
-}
-
-
-static void convo_opened(struct mwConversation *conv) {
-  struct mwImHandler *h = NULL;
-
-  g_return_if_fail(conv != NULL);
-  g_return_if_fail(conv->service != NULL);
-
-  convo_set_state(conv, mwConversation_OPEN);
-  h = conv->service->handler;
-
-  g_return_if_fail(h != NULL);
-
-  if(h->conversation_opened)
-    h->conversation_opened(conv);
-}
-
-
-static void convo_free(struct mwConversation *conv) {
-  struct mwServiceIm *srvc;
-
-  mwConversation_removeClientData(conv);
-
-  srvc = conv->service;
-  srvc->convs = g_list_remove_all(srvc->convs, conv);
-
-  mwIdBlock_clear(&conv->target);
-  g_free(conv);
-}
-
-
-static int send_accept(struct mwConversation *c) {
-
-  struct mwChannel *chan = c->channel;
-  struct mwSession *s = mwChannel_getSession(chan);
-  struct mwUserStatus *stat = mwSession_getUserStatus(s);
-
-  struct mwPutBuffer *b;
-  struct mwOpaque *o;
-
-  b = mwPutBuffer_new();
-  guint32_put(b, mwImAddtlA_NORMAL);
-  guint32_put(b, c->features);
-  guint32_put(b, mwImAddtlC_NORMAL);
-  mwUserStatus_put(b, stat);
-
-  o = mwChannel_getAddtlAccept(chan);
-  mwOpaque_clear(o);
-  mwPutBuffer_finalize(o, b);
-
-  return mwChannel_accept(chan);
-}
-
-
-static void recv_channelCreate(struct mwService *srvc,
-			       struct mwChannel *chan,
-			       struct mwMsgChannelCreate *msg) {
-
-  /* - ensure it's the right service,proto,and proto ver
-     - check the opaque for the right opaque junk
-     - if not, close channel
-     - compose & send a channel accept
-  */
-
-  struct mwServiceIm *srvc_im = (struct mwServiceIm *) srvc;
-  struct mwImHandler *handler;
-  struct mwSession *s;
-  struct mwUserStatus *stat;
-  guint32 x, y, z;
-  struct mwGetBuffer *b;
-  struct mwConversation *c = NULL;
-  struct mwIdBlock idb;
-
-  handler = srvc_im->handler;
-  s = mwChannel_getSession(chan);
-  stat = mwSession_getUserStatus(s);
-
-  /* ensure the appropriate service/proto/ver */
-  x = mwChannel_getServiceId(chan);
-  y = mwChannel_getProtoType(chan);
-  z = mwChannel_getProtoVer(chan);
-
-  if( (x != mwService_IM) || (y != PROTOCOL_TYPE) || (z != PROTOCOL_VER) ) {
-    g_warning("unacceptable service, proto, ver:"
-	      " 0x%08x, 0x%08x, 0x%08x", x, y, z);
-    mwChannel_destroy(chan, ERR_SERVICE_NO_SUPPORT, NULL);
-    return;
-  }
-
-  /* act upon the values in the addtl block */
-  b = mwGetBuffer_wrap(&msg->addtl);
-  guint32_get(b, &x);
-  guint32_get(b, &y);
-  z = (guint) mwGetBuffer_error(b);
-  mwGetBuffer_free(b);
-
-  if(z /* buffer error, BOOM! */ ) {
-    g_warning("bad/malformed addtl in IM service");
-    mwChannel_destroy(chan, ERR_FAILURE, NULL);
-    return;
-
-  } else if(x != mwImAddtlA_NORMAL) {
-    g_message("unknown params: 0x%08x, 0x%08x", x, y);
-    mwChannel_destroy(chan, ERR_IM_NOT_REGISTERED, NULL);
-    return;
-    
-  } else if(y == mwImAddtlB_PRECONF) {
-    if(! handler->place_invite) {
-      g_info("rejecting place-invite channel");
-      mwChannel_destroy(chan, ERR_IM_NOT_REGISTERED, NULL);
-      return;
-
-    } else {
-      g_info("accepting place-invite channel");
-    }
-
-  } else if(y != mwImClient_PLAIN && y != srvc_im->features) {
-    /** reject what we do not understand */
-    mwChannel_destroy(chan, ERR_IM_NOT_REGISTERED, NULL);
-    return;
-
-  } else if(stat->status == mwStatus_BUSY) {
-    g_info("rejecting IM channel due to DND status");
-    mwChannel_destroy(chan, ERR_CLIENT_USER_DND, NULL);
-    return;
-  }
-
-  login_into_id(&idb, mwChannel_getUser(chan));
-
-#if 0
-  c = convo_find_by_user(srvc_im, &idb);
-#endif
-
-  if(! c) {
-    c = g_new0(struct mwConversation, 1);
-    c->service = srvc_im;
-    srvc_im->convs = g_list_prepend(srvc_im->convs, c);
-  }
-
-#if 0
-  /* we're going to re-associate any existing conversations with this
-     new channel. That means closing any existing ones */
-  if(c->channel) {
-    g_info("closing existing IM channel 0x%08x", mwChannel_getId(c->channel));
-    mwConversation_close(c, ERR_SUCCESS);
-  }
-#endif
-
-  /* set up the conversation with this channel, target, and be fancy
-     if the other side requested it */
-  c->channel = chan;
-  mwIdBlock_clone(&c->target, &idb);
-  c->features = y;
-  convo_set_state(c, mwConversation_PENDING);
-  mwChannel_setServiceData(c->channel, c, NULL);
-
-  if(send_accept(c)) {
-    g_warning("sending IM channel accept failed");
-    mwConversation_free(c);
-
-  } else {
-    convo_opened(c);
-  }
-}
-
-
-static void recv_channelAccept(struct mwService *srvc, struct mwChannel *chan,
-			       struct mwMsgChannelAccept *msg) {
-
-  struct mwConversation *conv;
-
-  conv = mwChannel_getServiceData(chan);
-  if(! conv) {
-    g_warning("received channel accept for non-existant conversation");
-    mwChannel_destroy(chan, ERR_FAILURE, NULL);
-    return;
-  }
-
-  convo_opened(conv);
-}
-
-
-static void recv_channelDestroy(struct mwService *srvc, struct mwChannel *chan,
-				struct mwMsgChannelDestroy *msg) {
-
-  struct mwConversation *c;
-
-  c = mwChannel_getServiceData(chan);
-  g_return_if_fail(c != NULL);
-
-  c->channel = NULL;
-
-  if(mwChannel_isState(chan, mwChannel_ERROR)) {
-
-    /* checking for failure on the receiving end to accept html
-       messages. Fail-over to a non-html format on a new channel for
-       the convo */
-    if(c->features != mwImClient_PLAIN
-       && (msg->reason == ERR_IM_NOT_REGISTERED ||
-	   msg->reason == ERR_SERVICE_NO_SUPPORT)) {
-
-      g_debug("falling back on a plaintext conversation");
-      c->features = mwImClient_PLAIN;
-      convo_create_chan(c);
-      return;
-    }
-  }
-
-  mwConversation_close(c, msg->reason);
-}
-
-
-static void convo_recv(struct mwConversation *conv, enum mwImSendType type,
-		       gconstpointer msg) {
-
-  struct mwServiceIm *srvc;
-  struct mwImHandler *handler;
-
-  g_return_if_fail(conv != NULL);
-
-  srvc = conv->service;
-  g_return_if_fail(srvc != NULL);
-
-  handler = srvc->handler;
-  if(handler && handler->conversation_recv)
-    handler->conversation_recv(conv, type, msg);
-}
-
-
-static void convo_multi_start(struct mwConversation *conv) {
-  g_return_if_fail(conv->multi == NULL);
-  conv->multi = g_string_new(NULL);
-}
-
-
-static void convo_multi_stop(struct mwConversation *conv) {
-
-  g_return_if_fail(conv->multi != NULL);
-
-  /* actually send it */
-  convo_recv(conv, conv->multi_type, conv->multi->str);
-
-  /* clear up the multi buffer */
-  g_string_free(conv->multi, TRUE);
-  conv->multi = NULL;
-}
-
-
-static void recv_text(struct mwServiceIm *srvc, struct mwChannel *chan,
-		      struct mwGetBuffer *b) {
-
-  struct mwConversation *c;
-  char *text = NULL;
-
-  mwString_get(b, &text);
-
-  if(! text) return;
-
-  c = mwChannel_getServiceData(chan);
-  if(c) {
-    if(c->multi) {
-      g_string_append(c->multi, text);
-
-    } else {
-      convo_recv(c, mwImSend_PLAIN, text); 
-    }
-  }
-
-  g_free(text);
-}
-
-
-static void convo_invite(struct mwConversation *conv,
-			 struct mwOpaque *o) {
-
-  struct mwServiceIm *srvc;
-  struct mwImHandler *handler;
-
-  struct mwGetBuffer *b;
-  char *title, *name, *msg;
-
-  g_info("convo_invite");
-
-  srvc = conv->service;
-  handler = srvc->handler;
-
-  g_return_if_fail(handler != NULL);
-  g_return_if_fail(handler->place_invite != NULL);
-
-  b = mwGetBuffer_wrap(o);
-  mwGetBuffer_advance(b, 4);
-  mwString_get(b, &title);
-  mwString_get(b, &msg);
-  mwGetBuffer_advance(b, 19);
-  mwString_get(b, &name);
-
-  if(! mwGetBuffer_error(b)) {
-    handler->place_invite(conv, msg, title, name);
-  }
-
-  mwGetBuffer_free(b);
-  g_free(msg);
-  g_free(title);
-  g_free(name);
-}
-
-
-static void recv_data(struct mwServiceIm *srvc, struct mwChannel *chan,
-		      struct mwGetBuffer *b) {
-
-  struct mwConversation *conv;
-  guint32 type, subtype;
-  struct mwOpaque o = { 0, 0 };
-  char *x;
-
-  guint32_get(b, &type);
-  guint32_get(b, &subtype);
-  mwOpaque_get(b, &o);
-
-  if(mwGetBuffer_error(b)) {
-    mwOpaque_clear(&o);
-    return;
-  }
-
-  conv = mwChannel_getServiceData(chan);
-  if(! conv) return;
-
-  switch(type) {
-  case mwImData_TYPING:
-    convo_recv(conv, mwImSend_TYPING, GINT_TO_POINTER(! subtype));
-    break;
-
-  case mwImData_HTML:
-    if(o.len) {
-      if(conv->multi) {
-	g_string_append_len(conv->multi, (char *) o.data, o.len);
-	conv->multi_type = mwImSend_HTML;
-
-      } else {
-	x = g_strndup((char *) o.data, o.len);
-	convo_recv(conv, mwImSend_HTML, x);
-	g_free(x);
-      }
-    }
-    break;
-
-  case mwImData_SUBJECT:
-    x = g_strndup((char *) o.data, o.len);
-    convo_recv(conv, mwImSend_SUBJECT, x);
-    g_free(x);
-    break;
-
-  case mwImData_MIME:
-    if(conv->multi) {
-      g_string_append_len(conv->multi, (char *) o.data, o.len);
-      conv->multi_type = mwImSend_MIME;
-
-    } else {
-      x = g_strndup((char *) o.data, o.len);
-      convo_recv(conv, mwImSend_MIME, x);
-      g_free(x);
-    }
-    break;
-
-  case mwImData_TIMESTAMP:
-    /* todo */
-    break;
-
-  case mwImData_INVITE:
-    convo_invite(conv, &o);
-    break;
-
-  case mwImData_MULTI_START:
-    convo_multi_start(conv);
-    break;
-
-  case mwImData_MULTI_STOP:
-    convo_multi_stop(conv);
-    break;
-
-  default:
-    
-    mw_mailme_opaque(&o, "unknown data message type in IM service:"
-		     " (0x%08x, 0x%08x)", type, subtype);
-  }
-
-  mwOpaque_clear(&o);
-}
-
-
-static void recv(struct mwService *srvc, struct mwChannel *chan,
-		 guint16 type, struct mwOpaque *data) {
-
-  /* - ensure message type is something we want
-     - parse message type into either mwIMText or mwIMData
-     - handle
-  */
-
-  struct mwGetBuffer *b;
-  guint32 mt;
-
-  g_return_if_fail(type == msg_MESSAGE);
-
-  b = mwGetBuffer_wrap(data);
-  guint32_get(b, &mt);
-
-  if(mwGetBuffer_error(b)) {
-    g_warning("failed to parse message for IM service");
-    mwGetBuffer_free(b);
-    return;
-  }
-
-  switch(mt) {
-  case mwIm_TEXT:
-    recv_text((struct mwServiceIm *) srvc, chan, b);
-    break;
-
-  case mwIm_DATA:
-    recv_data((struct mwServiceIm *) srvc, chan, b);
-    break;
-
-  default:
-    g_warning("unknown message type 0x%08x for IM service", mt);
-  }
-
-  if(mwGetBuffer_error(b))
-    g_warning("failed to parse message type 0x%08x for IM service", mt);
-
-  mwGetBuffer_free(b);
-}
-
-
-static void clear(struct mwServiceIm *srvc) {
-  struct mwImHandler *h;
-
-  while(srvc->convs)
-    convo_free(srvc->convs->data);
-
-  h = srvc->handler;
-  if(h && h->clear)
-    h->clear(srvc);
-  srvc->handler = NULL;
-}
-
-
-static const char *name(struct mwService *srvc) {
-  return "Instant Messaging";
-}
-
-
-static const char *desc(struct mwService *srvc) {
-  return "IM service with Standard and NotesBuddy features";
-}
-
-
-static void start(struct mwService *srvc) {
-  mwService_started(srvc);
-}
-
-
-static void stop(struct mwServiceIm *srvc) {
-
-  while(srvc->convs)
-    mwConversation_free(srvc->convs->data);
-
-  mwService_stopped(MW_SERVICE(srvc));
-}
-
-
-struct mwServiceIm *mwServiceIm_new(struct mwSession *session,
-				    struct mwImHandler *hndl) {
-
-  struct mwServiceIm *srvc_im;
-  struct mwService *srvc;
-
-  g_return_val_if_fail(session != NULL, NULL);
-  g_return_val_if_fail(hndl != NULL, NULL);
-
-  srvc_im = g_new0(struct mwServiceIm, 1);
-  srvc = MW_SERVICE(srvc_im);
-
-  mwService_init(srvc, session, mwService_IM);
-  srvc->recv_create = recv_channelCreate;
-  srvc->recv_accept = recv_channelAccept;
-  srvc->recv_destroy = recv_channelDestroy;
-  srvc->recv = recv;
-  srvc->clear = (mwService_funcClear) clear;
-  srvc->get_name = name;
-  srvc->get_desc = desc;
-  srvc->start = start;
-  srvc->stop = (mwService_funcStop) stop;
-
-  srvc_im->features = mwImClient_PLAIN;
-  srvc_im->handler = hndl;
-
-  return srvc_im;
-}
-
-
-struct mwImHandler *mwServiceIm_getHandler(struct mwServiceIm *srvc) {
-  g_return_val_if_fail(srvc != NULL, NULL);
-  return srvc->handler;
-}
-
-
-gboolean mwServiceIm_supports(struct mwServiceIm *srvc,
-			      enum mwImSendType type) {
-
-  g_return_val_if_fail(srvc != NULL, FALSE);
-
-  switch(type) {
-  case mwImSend_PLAIN:
-  case mwImSend_TYPING:
-    return TRUE;
-
-  case mwImSend_SUBJECT:
-  case mwImSend_HTML:
-  case mwImSend_MIME:
-  case mwImSend_TIMESTAMP:
-    return srvc->features == mwImClient_NOTESBUDDY;
-
-  default:
-    return FALSE;
-  }
-}
-
-
-void mwServiceIm_setClientType(struct mwServiceIm *srvc,
-			       enum mwImClientType type) {
-
-  g_return_if_fail(srvc != NULL);
-  srvc->features = type;
-}
-
-
-enum mwImClientType mwServiceIm_getClientType(struct mwServiceIm *srvc) {
-  g_return_val_if_fail(srvc != NULL, mwImClient_UNKNOWN);
-  return srvc->features;
-}
-
-
-static int convo_send_data(struct mwConversation *conv,
-			   guint32 type, guint32 subtype,
-			   struct mwOpaque *data) {
-  struct mwPutBuffer *b;
-  struct mwOpaque o;
-  struct mwChannel *chan;
-  int ret;
-
-  chan = conv->channel;
-  g_return_val_if_fail(chan != NULL, -1);
-
-  b = mwPutBuffer_new();
-
-  guint32_put(b, mwIm_DATA);
-  guint32_put(b, type);
-  guint32_put(b, subtype);
-  mwOpaque_put(b, data);
-
-  mwPutBuffer_finalize(&o, b);
-
-  ret = mwChannel_sendEncrypted(chan, msg_MESSAGE, &o, !conv->ext_id);
-  mwOpaque_clear(&o);
-
-  return ret;
-}
-
-
-static int convo_send_multi_start(struct mwConversation *conv) {
-  return convo_send_data(conv, mwImData_MULTI_START, 0x00, NULL);
-}
-
-
-static int convo_send_multi_stop(struct mwConversation *conv) {
-  return convo_send_data(conv, mwImData_MULTI_STOP, 0x00, NULL);
-}
-
-
-/* breaks up a large message into segments, sends a start_segment
-   message, then sends each segment in turn, then sends a stop_segment
-   message */
-static int
-convo_sendSegmented(struct mwConversation *conv, const char *message,
-		    int (*send)(struct mwConversation *conv,
-				const char *msg)) {
-  char *buf = (char *) message;
-  gsize len;
-  int ret = 0;
-
-  len = strlen(buf);
-  ret = convo_send_multi_start(conv);
-
-  while(len && !ret) {
-    char tail;
-    gsize seg;
-
-    seg = BREAKUP;
-    if(len < BREAKUP)
-      seg = len;
-
-    /* temporarily NUL-terminate this segment */
-    tail = buf[seg];
-    buf[seg] = 0x00;
-
-    ret = send(conv, buf);
-
-    /* restore this segment */
-    buf[seg] = tail;
-    
-    buf += seg;
-    len -= seg;
-  }
-
-  if(! ret)
-    ret = convo_send_multi_stop(conv);
-
-  return ret;
-}
-
-
-static int convo_sendText(struct mwConversation *conv, const char *text) {
-  struct mwPutBuffer *b;
-  struct mwOpaque o;
-  int ret;
-  
-  b = mwPutBuffer_new();
-
-  guint32_put(b, mwIm_TEXT);
-  mwString_put(b, text);
-
-  mwPutBuffer_finalize(&o, b);
-  ret = mwChannel_sendEncrypted(conv->channel, msg_MESSAGE, &o, !conv->ext_id);
-  mwOpaque_clear(&o);
-
-  return ret;
-}
-
-
-static int convo_sendTyping(struct mwConversation *conv, gboolean typing) {
-  return convo_send_data(conv, mwImData_TYPING, !typing, NULL);
-}
-
-
-static int convo_sendSubject(struct mwConversation *conv,
-			     const char *subject) {
-  struct mwOpaque o;
-
-  o.len = strlen(subject);
-  o.data = (guchar *) subject;
-
-  return convo_send_data(conv, mwImData_SUBJECT, 0x00, &o);
-}
-
-
-static int convo_sendHtml(struct mwConversation *conv, const char *html) {
-  struct mwOpaque o;
-
-  o.len = strlen(html);
-  o.data = (guchar *) html;
-
-  if(o.len > BREAKUP) {
-    return convo_sendSegmented(conv, html, convo_sendHtml);
-  } else {
-    return convo_send_data(conv, mwImData_HTML, 0x00, &o);
-  }
-}
-
-
-static int convo_sendMime(struct mwConversation *conv, const char *mime) {
-  struct mwOpaque o;
-
-  o.len = strlen(mime);
-  o.data = (guchar *) mime;
-
-  if(o.len > BREAKUP) {
-    return convo_sendSegmented(conv, mime, convo_sendMime);
-  } else {
-    return convo_send_data(conv, mwImData_MIME, 0x00, &o);
-  }
-}
-
-
-int mwConversation_send(struct mwConversation *conv, enum mwImSendType type,
-			gconstpointer msg) {
-
-  g_return_val_if_fail(conv != NULL, -1);
-  g_return_val_if_fail(mwConversation_isOpen(conv), -1);
-  g_return_val_if_fail(conv->channel != NULL, -1);
-
-  switch(type) {
-  case mwImSend_PLAIN:
-    return convo_sendText(conv, msg);
-  case mwImSend_TYPING:
-    return convo_sendTyping(conv, GPOINTER_TO_INT(msg));
-  case mwImSend_SUBJECT:
-    return convo_sendSubject(conv, msg);
-  case mwImSend_HTML:
-    return convo_sendHtml(conv, msg);
-  case mwImSend_MIME:
-    return convo_sendMime(conv, msg);
-
-  default:
-    g_warning("unsupported IM Send Type, 0x%x", type);
-    return -1;
-  }
-}
-
-
-enum mwConversationState mwConversation_getState(struct mwConversation *conv) {
-  g_return_val_if_fail(conv != NULL, mwConversation_UNKNOWN);
-  return conv->state;
-}
-
-
-struct mwServiceIm *mwConversation_getService(struct mwConversation *conv) {
-  g_return_val_if_fail(conv != NULL, NULL);
-  return conv->service;
-}
-
-
-gboolean mwConversation_supports(struct mwConversation *conv,
-				 enum mwImSendType type) {
-  g_return_val_if_fail(conv != NULL, FALSE);
-
-  switch(type) {
-  case mwImSend_PLAIN:
-  case mwImSend_TYPING:
-    return TRUE;
-
-  case mwImSend_SUBJECT:
-  case mwImSend_HTML:
-  case mwImSend_MIME:
-    return conv->features == mwImClient_NOTESBUDDY;
-
-  default:
-    return FALSE;
-  }
-}
-
-
-enum mwImClientType
-mwConversation_getClientType(struct mwConversation *conv) {
-  g_return_val_if_fail(conv != NULL, mwImClient_UNKNOWN);
-  return conv->features;
-}
-
-
-struct mwIdBlock *mwConversation_getTarget(struct mwConversation *conv) {
-  g_return_val_if_fail(conv != NULL, NULL);
-  return &conv->target;
-}
-
-
-struct mwLoginInfo *mwConversation_getTargetInfo(struct mwConversation *conv) {
-  g_return_val_if_fail(conv != NULL, NULL);
-  g_return_val_if_fail(conv->channel != NULL, NULL);
-  return mwChannel_getUser(conv->channel);
-}
-
-
-void mwConversation_setClientData(struct mwConversation *conv,
-				  gpointer data, GDestroyNotify clean) {
-  g_return_if_fail(conv != NULL);
-  mw_datum_set(&conv->client_data, data, clean);
-}
-
-
-gpointer mwConversation_getClientData(struct mwConversation *conv) {
-  g_return_val_if_fail(conv != NULL, NULL);
-  return mw_datum_get(&conv->client_data);
-}
-
-
-void mwConversation_removeClientData(struct mwConversation *conv) {
-  g_return_if_fail(conv != NULL);
-  mw_datum_clear(&conv->client_data);
-}
-
-
-void mwConversation_close(struct mwConversation *conv, guint32 reason) {
-  struct mwServiceIm *srvc;
-  struct mwImHandler *h;
-
-  g_return_if_fail(conv != NULL);
-
-  convo_set_state(conv, mwConversation_CLOSED);
-
-  srvc = conv->service;
-  g_return_if_fail(srvc != NULL);
-
-  h = srvc->handler;
-  if(h && h->conversation_closed)
-    h->conversation_closed(conv, reason);
-
-  if(conv->channel) {
-    mwChannel_destroy(conv->channel, reason, NULL);
-    conv->channel = NULL;
-  }
-}
-
-
-void mwConversation_free(struct mwConversation *conv) {
-  g_return_if_fail(conv != NULL);
-
-  if(! mwConversation_isClosed(conv))
-    mwConversation_close(conv, ERR_SUCCESS);
-
-  convo_free(conv);
-}
-
--- a/src/protocols/sametime/meanwhile/srvc_place.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1075 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <glib.h>
-#include <glib/ghash.h>
-#include <glib/glist.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "mw_channel.h"
-#include "mw_common.h"
-#include "mw_debug.h"
-#include "mw_error.h"
-#include "mw_message.h"
-#include "mw_service.h"
-#include "mw_session.h"
-#include "mw_srvc_place.h"
-#include "mw_util.h"
-
-
-#define PROTOCOL_TYPE  0x00
-#define PROTOCOL_VER   0x05
-
-
-enum incoming_msg {
-  msg_in_JOIN_RESPONSE  = 0x0000,  /* ? */
-  msg_in_INFO           = 0x0002,
-  msg_in_MESSAGE        = 0x0004,
-  msg_in_SECTION        = 0x0014,  /* see in_section_subtype */
-  msg_in_UNKNOWNa       = 0x0015,
-};
-
-
-enum in_section_subtype {
-  msg_in_SECTION_LIST  = 0x0000,  /* list of section members */
-  msg_in_SECTION_PEER  = 0x0001,  /* see in_section_peer_subtye */
-  msg_in_SECTION_PART  = 0x0003,
-};
-
-
-enum in_section_peer_subtype {
-  msg_in_SECTION_PEER_JOIN        = 0x0000,
-  msg_in_SECTION_PEER_PART        = 0x0001,  /* after msg_in_SECTION_PART */
-  msg_in_SECTION_PEER_CLEAR_ATTR  = 0x0003,
-  msg_in_SECTION_PEER_SET_ATTR    = 0x0004,
-};
-
-
-enum outgoing_msg {
-  msg_out_JOIN_PLACE  = 0x0000,  /* ? */
-  msg_out_PEER_INFO   = 0x0002,  /* ? */
-  msg_out_MESSAGE     = 0x0003,
-  msg_out_OLD_INVITE  = 0x0005,  /* old-style conf. invitation */
-  msg_out_SET_ATTR    = 0x000a,
-  msg_out_CLEAR_ATTR  = 0x000b,
-  msg_out_SECTION     = 0x0014,  /* see out_section_subtype */
-  msg_out_UNKNOWNb    = 0x001e,  /* ? maybe enter stage ? */
-};
-
-
-enum out_section_subtype {
-  msg_out_SECTION_LIST  = 0x0002,  /* req list of members */
-  msg_out_SECTION_PART  = 0x0003,
-};
-
-
-/*
-  : allocate section
-  : state = NEW
-
-  : create channel
-  : state = PENDING
-
-  : channel accepted
-  : msg_out_JOIN_PLACE  (maybe create?)
-  : state = JOINING
-
-  : msg_in_JOIN_RESPONSE (contains our place member ID and section ID)
-  : msg_in_INFO (for place, not peer)
-  : state = JOINED
-
-  : msg_out_SECTION_LIST (asking for all sections) (optional)
-  : msg_in_SECTION_LIST (listing all sections, as requested above)
-
-  : msg_out_PEER_INFO (with our place member ID) (optional)
-  : msg_in_INFO (peer info as requested above)
-
-  : msg_out_SECTION_LIST (with our section ID) (sorta optional)
-  : msg_in_SECTION_LIST (section listing as requested above)
-
-  : msg_out_UNKNOWNb
-  : msg_in_SECTION_PEER_JOINED (empty, with our place member ID)
-  : state = OPEN
-
-  : stuff... (invites, joins, parts, messages, attr)
-
-  : state = CLOSING
-  : msg_out_SECTION_PART
-  : destroy channel
-  : deallocate section
-*/
-
-
-struct mwServicePlace {
-  struct mwService service;
-  struct mwPlaceHandler *handler;
-  GList *places;
-};
-
-
-enum mwPlaceState {
-  mwPlace_NEW,
-  mwPlace_PENDING,
-  mwPlace_JOINING,
-  mwPlace_JOINED,
-  mwPlace_OPEN,
-  mwPlace_CLOSING,
-  mwPlace_ERROR,
-  mwPlace_UNKNOWN,
-};
-
-
-struct mwPlace {
-  struct mwServicePlace *service;
-
-  enum mwPlaceState state;
-  struct mwChannel *channel;
-
-  char *name;
-  char *title;
-  GHashTable *members;  /* mapping of member ID: place_member */
-  guint32 our_id;       /* our member ID */
-  guint32 section;      /* the section we're using */
-
-  guint32 requests;     /* counter for requests */
-
-  struct mw_datum client_data;
-};
-
-
-struct place_member {
-  guint32 place_id;
-  guint16 member_type;
-  struct mwIdBlock idb;
-  char *login_id;
-  char *name;
-  guint16 login_type;
-  guint32 unknown_a;
-  guint32 unknown_b;
-};
-
-
-#define GET_MEMBER(place, id) \
-  (g_hash_table_lookup(place->members, GUINT_TO_POINTER(id)))
-
-
-#define PUT_MEMBER(place, member) \
-  (g_hash_table_insert(place->members, \
-                       GUINT_TO_POINTER(member->place_id), member))
-
-
-#define REMOVE_MEMBER_ID(place, id) \
-  (g_hash_table_remove(place->members, GUINT_TO_POINTER(id)))
-
-
-#define REMOVE_MEMBER(place, member) \
-  REMOVE_MEMBER_ID(place, member->place_id)
-
-
-static void member_free(struct place_member *p) {
-  mwIdBlock_clear(&p->idb);
-  g_free(p->login_id);
-  g_free(p->name);
-  g_free(p);
-}
-
-
-__attribute__((used))
-static const struct mwLoginInfo *
-member_as_login_info(struct place_member *p) {
-  static struct mwLoginInfo li;
-  
-  li.login_id = p->login_id;
-  li.type = p->login_type;
-  li.user_id = p->idb.user;
-  li.user_name = p->name;
-  li.community = p->idb.community;
-  li.full = FALSE;
-
-  return &li;
-}
-
-
-static const char *place_state_str(enum mwPlaceState s) {
-  switch(s) {
-  case mwPlace_NEW:      return "new";
-  case mwPlace_PENDING:  return "pending";
-  case mwPlace_JOINING:  return "joining";
-  case mwPlace_JOINED:   return "joined";
-  case mwPlace_OPEN:     return "open";
-  case mwPlace_CLOSING:  return "closing";
-  case mwPlace_ERROR:    return "error";
-
-  case mwPlace_UNKNOWN:  /* fall-through */
-  default:               return "UNKNOWN";
-  }
-}
-
-
-static void place_state(struct mwPlace *place, enum mwPlaceState s) {
-  g_return_if_fail(place != NULL);
-  
-  if(place->state == s) return;
-
-  place->state = s;
-  g_message("place %s state: %s", NSTR(place->name), place_state_str(s));
-}
-
-
-static void place_free(struct mwPlace *place) {
-  struct mwServicePlace *srvc;
-
-  if(! place) return;
-  
-  srvc = place->service;
-  g_return_if_fail(srvc != NULL);
-
-  srvc->places = g_list_remove_all(srvc->places, place);
-
-  mw_datum_clear(&place->client_data);
-
-  g_hash_table_destroy(place->members);
-
-  g_free(place->name);
-  g_free(place->title);
-  g_free(place);
-}
-
-
-static int recv_JOIN_RESPONSE(struct mwPlace *place,
-			      struct mwGetBuffer *b) {
-  
-  int ret = 0;
-  guint32 our_id, section;
-
-  guint32_get(b, &our_id);
-  guint32_get(b, &section);
-
-  place->our_id = our_id;
-  place->section = section;
-
-  return ret;
-}
-
-
-static int send_SECTION_LIST(struct mwPlace *place, guint32 section) {
-  int ret = 0;
-  struct mwOpaque o = {0, 0};
-  struct mwPutBuffer *b;
-
-  b = mwPutBuffer_new();
-  guint16_put(b, msg_out_SECTION_LIST);
-  guint32_put(b, section);
-  gboolean_put(b, FALSE);
-  guint32_put(b, ++place->requests);
-  mwPutBuffer_finalize(&o, b);
-
-  ret = mwChannel_send(place->channel, msg_out_SECTION, &o);
-  mwOpaque_clear(&o);
-
-  return ret;
-}
-
-
-static int recv_INFO(struct mwPlace *place,
-		     struct mwGetBuffer *b) {
-
-  int ret = 0;
-  guint32 skip = 0;
-  guint32 section = 0;
-
-  guint32_get(b, &skip);
-  guint32_get(b, &section);
-  mwGetBuffer_advance(b, skip);
-
-  if(! section) {
-    /* this is a place info rather than member info */
-    if(place->title) g_free(place->title);
-    mwGetBuffer_advance(b, 2);
-    mwString_get(b, &place->title);
-
-    place_state(place, mwPlace_JOINED);
-    ret = send_SECTION_LIST(place, place->section);
-  }
-
-  return ret;
-}
-
-
-static int recv_MESSAGE(struct mwPlace *place,
-			struct mwGetBuffer *b) {
-
-  struct mwServicePlace *srvc;
-  guint32 pm_id;
-  guint32 unkn_a, unkn_b, ign;
-  struct place_member *pm;
-  char *msg = NULL;
-  int ret = 0;
-
-  srvc = place->service;
-
-  /* no messages before becoming fully open, please */
-  g_return_val_if_fail(place->state == mwPlace_OPEN, -1);
-
-  /* regarding unkn_a and unkn_b:
-
-     they're probably a section indicator and a message count, I'm
-     just not sure which is which. Until this implementation supports
-     place sections in the API, it really doesn't matter. */
-  
-  guint32_get(b, &pm_id);
-  pm = GET_MEMBER(place, pm_id);
-  g_return_val_if_fail(pm != NULL, -1);
-
-  guint32_get(b, &unkn_a);
-  guint32_get(b, &ign);     /* actually an opaque length */
-  
-  if(! ign) return ret;
-
-  guint32_get(b, &unkn_b);
-  mwString_get(b, &msg);
-
-  if(srvc->handler && srvc->handler->message)
-    srvc->handler->message(place, &pm->idb, msg);
-
-  g_free(msg);
-
-  return ret;
-}
-
-
-static void place_opened(struct mwPlace *place) {
-    struct mwServicePlace *srvc;
-
-    place_state(place, mwPlace_OPEN);
-
-    srvc = place->service;
-    if(srvc->handler && srvc->handler->opened)
-      srvc->handler->opened(place);
-}
-
-
-static int recv_SECTION_PEER_JOIN(struct mwPlace *place,
-				  struct mwGetBuffer *b) {
-  struct mwServicePlace *srvc;
-  struct place_member *pm;
-  guint32 section;
-  int ret = 0;
-
-  srvc = place->service;
-
-  guint32_get(b, &section);
-  if(! section) {
-    g_info("SECTION_PEER_JOIN with section 0x00");
-    return 0;
-  }
-
-  mwGetBuffer_advance(b, 4);
-
-  pm = g_new0(struct place_member, 1);
-  guint32_get(b, &pm->place_id);
-  guint16_get(b, &pm->member_type);
-  mwIdBlock_get(b, &pm->idb);
-  mwString_get(b, &pm->login_id);
-  mwString_get(b, &pm->name);
-  guint16_get(b, &pm->login_type);
-  guint32_get(b, &pm->unknown_a);
-  guint32_get(b, &pm->unknown_b);
-
-  PUT_MEMBER(place, pm);
-  if(srvc->handler && srvc->handler->peerJoined)
-    srvc->handler->peerJoined(place, &pm->idb);
-
-  if(pm->place_id == place->our_id)
-    place_opened(place);
-
-  return ret;
-}
-
-
-static int recv_SECTION_PEER_PART(struct mwPlace *place,
-				  struct mwGetBuffer *b) {
-  struct mwServicePlace *srvc;
-  int ret = 0;
-  guint32 section, id;
-  struct place_member *pm;
-
-  srvc = place->service;
-
-  guint32_get(b, &section);
-  g_return_val_if_fail(section == place->section, 0);
-
-  guint32_get(b, &id);
-  pm = GET_MEMBER(place, id);
-
-  /* SECTION_PART may have been called already */
-  if(! pm) return 0;
-
-  if(srvc->handler && srvc->handler->peerParted)
-    srvc->handler->peerParted(place, &pm->idb);
-
-  REMOVE_MEMBER(place, pm);
-
-  return ret;
-}
-
-
-static int recv_SECTION_PEER_CLEAR_ATTR(struct mwPlace *place,
-					struct mwGetBuffer *b) {
-  struct mwServicePlace *srvc;
-  int ret = 0;
-  guint32 id, attr;
-  struct place_member *pm;
-  
-  srvc = place->service;
-
-  guint32_get(b, &id);
-  guint32_get(b, &attr);
-
-  pm = GET_MEMBER(place, id);
-  g_return_val_if_fail(pm != NULL, -1);
-
-  if(srvc->handler && srvc->handler->peerUnsetAttribute)
-    srvc->handler->peerUnsetAttribute(place, &pm->idb, attr);
-
-  return ret;
-}
-
-
-static int recv_SECTION_PEER_SET_ATTR(struct mwPlace *place,
-				      struct mwGetBuffer *b) {
-  struct mwServicePlace *srvc;
-  int ret = 0;
-  guint32 id, attr;
-  struct mwOpaque o = {0,0};
-  struct place_member *pm;
-  
-  srvc = place->service;
-
-  guint32_get(b, &id);
-  mwGetBuffer_advance(b, 4);
-  mwOpaque_get(b, &o);
-  mwGetBuffer_advance(b, 4);
-  guint32_get(b, &attr);
-
-  pm = GET_MEMBER(place, id);
-  g_return_val_if_fail(pm != NULL, -1);
-
-  if(srvc->handler && srvc->handler->peerSetAttribute)
-    srvc->handler->peerSetAttribute(place, &pm->idb, attr, &o);
-
-  mwOpaque_clear(&o);
-
-  return ret;
-}
-
-
-static int recv_SECTION_PEER(struct mwPlace *place,
-			      struct mwGetBuffer *b) {
-  guint16 subtype;
-  int res;
-
-  guint16_get(b, &subtype);
-
-  g_return_val_if_fail(! mwGetBuffer_error(b), -1);
-
-  switch(subtype) {
-  case msg_in_SECTION_PEER_JOIN:
-    res = recv_SECTION_PEER_JOIN(place, b);
-    break;
-
-  case msg_in_SECTION_PEER_PART:
-    res = recv_SECTION_PEER_PART(place, b);
-    break;
-
-  case msg_in_SECTION_PEER_CLEAR_ATTR:
-    res = recv_SECTION_PEER_CLEAR_ATTR(place, b);
-    break;
-
-  case msg_in_SECTION_PEER_SET_ATTR:
-    res = recv_SECTION_PEER_SET_ATTR(place, b);
-    break;
-
-  default:
-    res = -1;
-  }
-
-  return res;
-}
-
-
-static int recv_SECTION_LIST(struct mwPlace *place,
-			     struct mwGetBuffer *b) {
-  int ret = 0;
-  guint32 sec, count;
-
-  mwGetBuffer_advance(b, 4);
-  guint32_get(b, &sec);
-
-  g_return_val_if_fail(sec == place->section, -1);
-
-  mwGetBuffer_advance(b, 8);
-  guint32_get(b, &count);
-  mwGetBuffer_advance(b, 8);
-
-  while(count--) {
-    struct place_member *m;
-
-    m = g_new0(struct place_member, 1);
-    mwGetBuffer_advance(b, 4);
-    guint32_get(b, &m->place_id);
-    guint16_get(b, &m->member_type);
-    mwIdBlock_get(b, &m->idb);
-    mwString_get(b, &m->login_id);
-    mwString_get(b, &m->name);
-    guint16_get(b, &m->login_type);
-    guint32_get(b, &m->unknown_a);
-    guint32_get(b, &m->unknown_b);
-
-    PUT_MEMBER(place, m);
-  }
-
-  if(place->state != mwPlace_OPEN)
-    place_opened(place);
-
-  return ret;
-}
-
-
-static int recv_SECTION_PART(struct mwPlace *place,
-			     struct mwGetBuffer *b) {
-  /* look up user in place
-     remove user from place
-     trigger event */
-
-  struct mwServicePlace *srvc;
-  guint32 pm_id;
-  struct place_member *pm;
-
-  srvc = place->service;
-
-  guint32_get(b, &pm_id);
-  pm = GET_MEMBER(place, pm_id);
-
-  /* SECTION_PEER_PART may have been called already */
-  if(! pm) return 0;
-
-  if(srvc->handler && srvc->handler->peerParted)
-    srvc->handler->peerParted(place, &pm->idb);
-
-  REMOVE_MEMBER(place, pm);
-
-  return 0;
-}
-
-
-static int recv_SECTION(struct mwPlace *place, struct mwGetBuffer *b) {
-  guint16 subtype;
-  int res;
-
-  guint16_get(b, &subtype);
-
-  g_return_val_if_fail(! mwGetBuffer_error(b), -1);
-
-  switch(subtype) {
-  case msg_in_SECTION_LIST:
-    res = recv_SECTION_LIST(place, b);
-    break;
-
-  case msg_in_SECTION_PEER:
-    res = recv_SECTION_PEER(place, b);
-    break;
-
-  case msg_in_SECTION_PART:
-    res = recv_SECTION_PART(place, b);
-    break;
-
-  default:
-    res = -1;
-  }
-
-  return res;
-}
-
-
-static int recv_UNKNOWNa(struct mwPlace *place, struct mwGetBuffer *b) {
-  int res = 0;
-
-  if(place->state == mwPlace_JOINING) {
-    ;
-    /* place_state(place, mwPlace_JOINED);
-       res = send_SECTION_LIST(place, place->section); */
-  
-  } else if(place->state == mwPlace_JOINED) {
-    ;
-    /* if(GET_MEMBER(place, place->our_id))
-       place_opened(place); */
-  }
-
-  return res;
-}
-
-
-static void recv(struct mwService *service, struct mwChannel *chan,
-		 guint16 type, struct mwOpaque *data) {
-
-  struct mwPlace *place;
-  struct mwGetBuffer *b;
-  int res = 0;
-
-  place = mwChannel_getServiceData(chan);
-  g_return_if_fail(place != NULL);
-
-  b = mwGetBuffer_wrap(data);
-  switch(type) {
-  case msg_in_JOIN_RESPONSE:
-    res = recv_JOIN_RESPONSE(place, b);
-    break;
-
-  case msg_in_INFO:
-    res = recv_INFO(place, b);
-    break;
-
-  case msg_in_MESSAGE:
-    res = recv_MESSAGE(place, b);
-    break;
-
-  case msg_in_SECTION:
-    res = recv_SECTION(place, b);
-    break;
-
-  case msg_in_UNKNOWNa:
-    res = recv_UNKNOWNa(place, b);
-    break;
-
-  default:
-    mw_mailme_opaque(data, "Received unknown message type 0x%x on place %s",
-		     type, NSTR(place->name));
-  }
-
-  if(res) {
-    mw_mailme_opaque(data, "Troubling parsing message type 0x0%x on place %s",
-		     type, NSTR(place->name));
-  }
-
-  mwGetBuffer_free(b);
-}
-
-
-static void stop(struct mwServicePlace *srvc) {
-  while(srvc->places)
-    mwPlace_destroy(srvc->places->data, ERR_SUCCESS);
-
-  mwService_stopped(MW_SERVICE(srvc));
-}
-
-
-static int send_JOIN_PLACE(struct mwPlace *place) {
-  struct mwOpaque o = {0, 0};
-  struct mwPutBuffer *b;
-  int ret;
-
-  b = mwPutBuffer_new();
-  gboolean_put(b, FALSE);
-  guint16_put(b, 0x01);
-  guint16_put(b, 0x02); /* 0x01 */
-  guint16_put(b, 0x01); /* 0x00 */
-
-  mwPutBuffer_finalize(&o, b);
-
-  ret = mwChannel_send(place->channel, msg_out_JOIN_PLACE, &o);
-
-  mwOpaque_clear(&o);
-
-  if(ret) {
-    place_state(place, mwPlace_ERROR);
-  } else {
-    place_state(place, mwPlace_JOINING);
-  }
-
-  return ret;
-}
-
-
-static void recv_channelAccept(struct mwService *service,
-			       struct mwChannel *chan,
-			       struct mwMsgChannelAccept *msg) {
-  struct mwServicePlace *srvc;
-  struct mwPlace *place;
-  int res;
-
-  srvc = (struct mwServicePlace *) service;
-  g_return_if_fail(srvc != NULL);
-
-  place = mwChannel_getServiceData(chan);
-  g_return_if_fail(place != NULL);
-
-  res = send_JOIN_PLACE(place);
-}
-
-
-static void recv_channelDestroy(struct mwService *service,
-				struct mwChannel *chan,
-				struct mwMsgChannelDestroy *msg) {
-  struct mwServicePlace *srvc;
-  struct mwPlace *place;
-
-  srvc = (struct mwServicePlace *) service;
-  g_return_if_fail(srvc != NULL);
-
-  place = mwChannel_getServiceData(chan);
-  g_return_if_fail(place != NULL);
-
-  place_state(place, mwPlace_ERROR);
-
-  place->channel = NULL;
-
-  if(srvc->handler && srvc->handler->closed)
-    srvc->handler->closed(place, msg->reason);  
-
-  mwPlace_destroy(place, msg->reason);
-}
-
-
-static void clear(struct mwServicePlace *srvc) {
-
-  if(srvc->handler && srvc->handler->clear)
-    srvc->handler->clear(srvc);
-
-  while(srvc->places)
-    place_free(srvc->places->data);
-}
-
-
-static const char *get_name(struct mwService *srvc) {
-  return "Places Conferencing";
-}
-
-
-static const char *get_desc(struct mwService *srvc) {
-  return "Barebones conferencing via Places";
-}
-
-
-struct mwServicePlace *
-mwServicePlace_new(struct mwSession *session,
-		   struct mwPlaceHandler *handler) {
-
-  struct mwServicePlace *srvc_place;
-  struct mwService *srvc;
-
-  g_return_val_if_fail(session != NULL, NULL);
-  g_return_val_if_fail(handler != NULL, NULL);
-
-  srvc_place = g_new0(struct mwServicePlace, 1);
-  srvc_place->handler = handler;
-
-  srvc = MW_SERVICE(srvc_place);
-  mwService_init(srvc, session, mwService_PLACE);
-  srvc->start = NULL;
-  srvc->stop = (mwService_funcStop) stop;
-  srvc->recv_create = NULL;
-  srvc->recv_accept = recv_channelAccept;
-  srvc->recv_destroy = recv_channelDestroy;
-  srvc->recv = recv;
-  srvc->clear = (mwService_funcClear) clear;
-  srvc->get_name = get_name;
-  srvc->get_desc = get_desc;
-
-  return srvc_place;
-}
-
-
-struct mwPlaceHandler *
-mwServicePlace_getHandler(struct mwServicePlace *srvc) {
-  g_return_val_if_fail(srvc != NULL, NULL);
-  return srvc->handler;
-}
-
-
-const GList *mwServicePlace_getPlaces(struct mwServicePlace *srvc) {
-  g_return_val_if_fail(srvc != NULL, NULL);
-  return srvc->places;
-}
-
-
-struct mwPlace *mwPlace_new(struct mwServicePlace *srvc,
-			    const char *name, const char *title) {
-  struct mwPlace *place;
-
-  g_return_val_if_fail(srvc != NULL, NULL);
-  
-  place = g_new0(struct mwPlace, 1);
-  place->service = srvc;
-  place->name = g_strdup(name);
-  place->title = g_strdup(title);
-  place->state = mwPlace_NEW;
-
-  place->members = g_hash_table_new_full(g_direct_hash, g_direct_equal,
-					 NULL, (GDestroyNotify) member_free);
-
-  srvc->places = g_list_prepend(srvc->places, place);
-  
-  return place;
-}
-
-
-struct mwServicePlace *mwPlace_getService(struct mwPlace *place) {
-  g_return_val_if_fail(place != NULL, NULL);
-  return place->service;
-}
-
-
-static char *place_generate_name(const char *user) {
-  guint a, b;
-  char *ret;
-  
-  user = user? user: "meanwhile";
-
-  srand(clock() + rand());
-  a = ((rand() & 0xff) << 8) | (rand() & 0xff);
-  b = time(NULL);
-
-  ret = g_strdup_printf("%s(%08x,%04x)", user, b, a);
-  g_debug("generated random conference name: '%s'", ret);
-  return ret;
-}
-
-
-const char *mwPlace_getName(struct mwPlace *place) {
-  g_return_val_if_fail(place != NULL, NULL);
-
-  if(! place->name) {
-    struct mwSession *session;
-    struct mwLoginInfo *li;
-
-    session = mwService_getSession(MW_SERVICE(place->service));
-    li = mwSession_getLoginInfo(session);
-
-    place->name = place_generate_name(li? li->user_id: NULL);
-  }
-
-  return place->name;
-}
-
-
-static char *place_generate_title(const char *user) {
-  char *ret;
-  
-  user = user? user: "Meanwhile";
-  ret = g_strdup_printf("%s's Conference", user);
-  g_debug("generated conference title: %s", ret);
-
-  return ret;
-}
-
-
-const char *mwPlace_getTitle(struct mwPlace *place) {
-  g_return_val_if_fail(place != NULL, NULL);
-
-  if(! place->title) {
-    struct mwSession *session;
-    struct mwLoginInfo *li;
-
-    session = mwService_getSession(MW_SERVICE(place->service));
-    li = mwSession_getLoginInfo(session);
-
-    place->title = place_generate_title(li? li->user_name: NULL);
-  }
-
-  return place->title;
-}
-
-
-int mwPlace_open(struct mwPlace *p) {
-  struct mwSession *session;
-  struct mwChannelSet *cs;
-  struct mwChannel *chan;
-  struct mwPutBuffer *b;
-  int ret;
-
-  g_return_val_if_fail(p != NULL, -1);
-  g_return_val_if_fail(p->service != NULL, -1);
-
-  session = mwService_getSession(MW_SERVICE(p->service));
-  g_return_val_if_fail(session != NULL, -1);
-
-  cs = mwSession_getChannels(session);
-  g_return_val_if_fail(cs != NULL, -1);
-
-  chan = mwChannel_newOutgoing(cs);
-  mwChannel_setService(chan, MW_SERVICE(p->service));
-  mwChannel_setProtoType(chan, PROTOCOL_TYPE);
-  mwChannel_setProtoVer(chan, PROTOCOL_VER);
-
-  mwChannel_populateSupportedCipherInstances(chan);
-
-  b = mwPutBuffer_new();
-  mwString_put(b, mwPlace_getName(p));
-  mwString_put(b, mwPlace_getTitle(p));
-  guint32_put(b, 0x00); /* ? */
-
-  mwPutBuffer_finalize(mwChannel_getAddtlCreate(chan), b);
-
-  ret = mwChannel_create(chan);
-  if(ret) {
-    place_state(p, mwPlace_ERROR);
-  } else {
-    place_state(p, mwPlace_PENDING);
-    p->channel = chan;
-    mwChannel_setServiceData(chan, p, NULL);
-  }
-
-  return ret;
-}
-
-
-int mwPlace_destroy(struct mwPlace *p, guint32 code) {
-  int ret = 0;
-
-  place_state(p, mwPlace_CLOSING);
-
-  if(p->channel) {
-    ret = mwChannel_destroy(p->channel, code, NULL);
-    p->channel = NULL;
-  }
-
-  place_free(p);
-
-  return ret;
-}
-
-
-GList *mwPlace_getMembers(struct mwPlace *place) {
-  GList *l, *ll;
-
-  g_return_val_if_fail(place != NULL, NULL);
-  g_return_val_if_fail(place->members != NULL, NULL);
-
-  ll = map_collect_values(place->members);
-  for(l = ll; l; l = l->next) {
-    struct place_member *pm = l->data;
-    l->data = &pm->idb;
-    g_info("collected member %u: %s, %s", pm->place_id,
-	   NSTR(pm->idb.user), NSTR(pm->idb.community));
-  }
-
-  return ll;
-}
-
-
-int mwPlace_sendText(struct mwPlace *place, const char *msg) {
-  struct mwOpaque o = {0,0};
-  struct mwPutBuffer *b;
-  int ret;
-
-  b = mwPutBuffer_new();
-  guint32_put(b, 0x01);  /* probably a message type */
-  mwString_put(b, msg);
-  mwPutBuffer_finalize(&o, b);
-
-  b = mwPutBuffer_new();
-  guint32_put(b, place->section);
-  mwOpaque_put(b, &o);
-  mwOpaque_clear(&o);
-  mwPutBuffer_finalize(&o, b);
-
-  ret = mwChannel_send(place->channel, msg_out_MESSAGE, &o);
-  mwOpaque_clear(&o);
-  return ret;
-}
-
-
-int mwPlace_legacyInvite(struct mwPlace *place,
-			 struct mwIdBlock *idb,
-			 const char *message) {
-
-  struct mwOpaque o = {0,0};
-  struct mwPutBuffer *b;
-  int ret;
-
-  b = mwPutBuffer_new();
-  mwIdBlock_put(b, idb);
-  mwString_put(b, idb->user);
-  mwString_put(b, idb->user);
-  mwString_put(b, message);
-  gboolean_put(b, FALSE);
-  mwPutBuffer_finalize(&o, b);
-
-  ret = mwChannel_send(place->channel, msg_out_OLD_INVITE, &o);
-  mwOpaque_clear(&o);
-  return ret;
-}
-
-
-int mwPlace_setAttribute(struct mwPlace *place, guint32 attrib,
-			 struct mwOpaque *data) {
-
-  struct mwOpaque o = {0,0};
-  struct mwPutBuffer *b;
-  int ret;
-
-  b = mwPutBuffer_new();
-  guint32_put(b, place->our_id);
-  guint32_put(b, 0x00);
-  guint32_put(b, attrib);
-  mwOpaque_put(b, data);
-  
-  ret = mwChannel_send(place->channel, msg_out_SET_ATTR, &o);
-  mwOpaque_clear(&o);
-  return ret;
-}
-
-
-int mwPlace_unsetAttribute(struct mwPlace *place, guint32 attrib) {
-  struct mwOpaque o = {0,0};
-  struct mwPutBuffer *b;
-  int ret;
-
-  b = mwPutBuffer_new();
-  guint32_put(b, place->our_id);
-  guint32_put(b, attrib);
-  
-  ret = mwChannel_send(place->channel, msg_out_SET_ATTR, &o);
-  mwOpaque_clear(&o);
-  return ret;
-}
-
-
-void mwPlace_setClientData(struct mwPlace *place,
-			   gpointer data, GDestroyNotify clear) {
-
-  g_return_if_fail(place != NULL);
-  mw_datum_set(&place->client_data, data, clear);
-}
-
-
-gpointer mwPlace_getClientData(struct mwPlace *place) {
-  g_return_val_if_fail(place != NULL, NULL);
-  return mw_datum_get(&place->client_data);
-}
-
-
-void mwPlace_removeClientData(struct mwPlace *place) {
-  g_return_if_fail(place != NULL);
-  mw_datum_clear(&place->client_data);
-}
--- a/src/protocols/sametime/meanwhile/srvc_resolve.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,389 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <glib/ghash.h>
-
-#include "mw_channel.h"
-#include "mw_common.h"
-#include "mw_debug.h"
-#include "mw_error.h"
-#include "mw_service.h"
-#include "mw_session.h"
-#include "mw_srvc_resolve.h"
-
-
-#define PROTOCOL_TYPE  0x00000015
-#define PROTOCOL_VER   0x00000000
-
-
-/** oddly, there is only one message type in this service */
-#define RESOLVE_ACTION  0x02
-
-
-struct mwServiceResolve {
-  struct mwService service;
-
-  struct mwChannel *channel;  /**< channel for this service */
-  GHashTable *searches;       /**< guint32:struct mw_search */
-  guint32 counter;            /**< incremented to provide searche IDs */
-};
-
-
-/** structure representing an active search. keeps track of the ID,
-    the handler, and the optional user data and cleanup */
-struct mw_search {
-  struct mwServiceResolve *service;
-  guint32 id;
-  mwResolveHandler handler;
-  gpointer data;
-  GDestroyNotify cleanup;
-};
-
-
-static struct mw_search *search_new(struct mwServiceResolve *srvc,
-				    mwResolveHandler handler,
-				    gpointer data, GDestroyNotify cleanup) {
-
-  struct mw_search *search = g_new0(struct mw_search, 1);
-
-  search->service = srvc;
-  search->handler = handler;
-
-  /* we want search IDs that aren't SEARCH_ERROR */
-  do {
-    search->id = srvc->counter++;
-  } while(search->id == SEARCH_ERROR);
-
-  search->data = data;
-  search->cleanup = cleanup;
-
-  return search;
-}
-
-
-/** called whenever a mw_search is removed from the searches table of
-    the service */
-static void search_free(struct mw_search *search) {
-  g_return_if_fail(search != NULL);
-
-  if(search->cleanup)
-    search->cleanup(search->data);
-  
-  g_free(search);
-}
-
-
-static const char *get_name(struct mwService *srvc) {
-  return "Identity Resolution";
-}
-
-
-static const char *get_desc(struct mwService *srvc) {
-  return "Resolves short IDs to full IDs";
-}
-
-
-static struct mwChannel *make_channel(struct mwServiceResolve *srvc) {
-  struct mwSession *session;
-  struct mwChannelSet *cs;
-  struct mwChannel *chan;
-
-  session = mwService_getSession(MW_SERVICE(srvc));
-  cs = mwSession_getChannels(session);
-  chan = mwChannel_newOutgoing(cs);
- 
-  mwChannel_setService(chan, MW_SERVICE(srvc));
-  mwChannel_setProtoType(chan, PROTOCOL_TYPE);
-  mwChannel_setProtoVer(chan, PROTOCOL_VER);
-
-  return mwChannel_create(chan)? NULL: chan;
-}
-
-
-static void start(struct mwServiceResolve *srvc) {
-  struct mwChannel *chan;
-
-  g_return_if_fail(srvc != NULL);
-
-  chan = make_channel(srvc);
-  if(chan) {
-    srvc->channel = chan;
-  } else {
-    mwService_stopped(MW_SERVICE(srvc));
-    return;
-  }
-
-  /* semi-lazily create the searches table */
-  srvc->searches = g_hash_table_new_full(g_direct_hash, g_direct_equal,
-					 NULL, (GDestroyNotify) search_free);
-}
-
-
-static void stop(struct mwServiceResolve *srvc) {
-  g_return_if_fail(srvc != NULL);
-
-  if(srvc->channel) {
-    mwChannel_destroy(srvc->channel, ERR_SUCCESS, NULL);
-    srvc->channel = NULL;
-  }
-
-  /* destroy all the pending requests. */
-  g_hash_table_destroy(srvc->searches);
-  srvc->searches = NULL;
-  
-  mwService_stopped(MW_SERVICE(srvc));
-}
-
-
-static void clear(struct mwServiceResolve *srvc) {
-  if(srvc->searches) {
-    g_hash_table_destroy(srvc->searches);
-    srvc->searches = NULL;
-  }
-}
-
-
-static void recv_create(struct mwServiceResolve *srvc,
-			struct mwChannel *chan,
-			struct mwMsgChannelCreate *msg) {
-
-  /* you serve me, not the other way around */
-  mwChannel_destroy(chan, ERR_FAILURE, NULL);
-}
-
-
-static void recv_accept(struct mwServiceResolve *srvc,
-			struct mwChannel *chan,
-			struct mwMsgChannelAccept *msg) {
-  
-  g_return_if_fail(srvc != NULL);
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(chan == srvc->channel);
-
-  mwService_started(MW_SERVICE(srvc));
-}
-
-
-static void recv_destroy(struct mwServiceResolve *srvc,
-			 struct mwChannel *chan,
-			 struct mwMsgChannelDestroy *msg) {
-
-  struct mwSession *session;
-
-  g_return_if_fail(srvc != NULL);
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(chan == srvc->channel);
-
-  srvc->channel = NULL;
-  mwService_stop(MW_SERVICE(srvc));
-
-  session = mwService_getSession(MW_SERVICE(srvc));
-  g_return_if_fail(session != NULL);
-
-  mwSession_senseService(session, mwService_getType(MW_SERVICE(srvc)));
-}
-
-
-static GList *load_matches(struct mwGetBuffer *b, guint32 count) {
-  GList *matches = NULL;
-
-  while(count--) {
-    struct mwResolveMatch *m = g_new0(struct mwResolveMatch, 1);
-
-    mwString_get(b, &m->id);
-    mwString_get(b, &m->name);
-    mwString_get(b, &m->desc);
-    guint32_get(b, &m->type);
- 
-    matches = g_list_append(matches, m);
-  }
-
-  return matches;
-}
-
-
-static GList *load_results(struct mwGetBuffer *b, guint32 count) {
-  GList *results = NULL;
-
-  while(count--) {
-    struct mwResolveResult *r = g_new0(struct mwResolveResult, 1);
-    guint32 junk, matches;
-
-    guint32_get(b, &junk);
-    guint32_get(b, &r->code);
-    mwString_get(b, &r->name);
-
-    guint32_get(b, &matches);
-    r->matches = load_matches(b, matches);
-
-    results = g_list_append(results, r);
-  }
-
-  return results;
-}
-
-
-static void free_matches(GList *matches) {
-  for(; matches; matches = g_list_delete_link(matches, matches)) {
-    struct mwResolveMatch *m = matches->data;
-    g_free(m->id);
-    g_free(m->name);
-    g_free(m->desc);
-    g_free(m);
-  }
-}
-
-
-static void free_results(GList *results) {
-  for(; results; results = g_list_delete_link(results, results)) {
-    struct mwResolveResult *r = results->data;
-    g_free(r->name);
-    free_matches(r->matches);
-    g_free(r);
-  }
-}
-
-
-static void recv(struct mwServiceResolve *srvc,
-		 struct mwChannel *chan,
-		 guint16 type, struct mwOpaque *data) {
-
-  struct mwGetBuffer *b;
-  guint32 junk, id, code, count;
-  struct mw_search *search;
-
-  g_return_if_fail(srvc != NULL);
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(chan == srvc->channel);
-  g_return_if_fail(data != NULL);
-
-  if(type != RESOLVE_ACTION) {
-    mw_mailme_opaque(data, "unknown message in resolve service: 0x%04x", type);
-    return;
-  }
-
-  b = mwGetBuffer_wrap(data);
-  guint32_get(b, &junk);
-  guint32_get(b, &id);
-  guint32_get(b, &code);
-  guint32_get(b, &count);
-
-  if(mwGetBuffer_error(b)) {
-    g_warning("error parsing search result");
-    mwGetBuffer_free(b);
-    return;
-  }
-  
-  search = g_hash_table_lookup(srvc->searches, GUINT_TO_POINTER(id));
-
-  if(search) {
-    GList *results = load_results(b, count);
-    if(mwGetBuffer_error(b)) {
-      g_warning("error parsing search results");
-    } else {
-      g_debug("triggering handler");
-      search->handler(srvc, id, code, results, search->data);
-    }
-    free_results(results);
-    g_hash_table_remove(srvc->searches, GUINT_TO_POINTER(id));
-
-  } else {
-    g_debug("no search found: 0x%x", id);
-  }
-
-  mwGetBuffer_free(b);
-}
-
-
-struct mwServiceResolve *mwServiceResolve_new(struct mwSession *session) {
-  struct mwServiceResolve *srvc_resolve;
-  struct mwService *srvc;
-
-  g_return_val_if_fail(session != NULL, NULL);
-
-  srvc_resolve = g_new0(struct mwServiceResolve, 1);
-
-  srvc = MW_SERVICE(srvc_resolve);
-
-  mwService_init(srvc, session, mwService_RESOLVE);
-  srvc->get_name = get_name;
-  srvc->get_desc = get_desc;
-  srvc->recv_create = (mwService_funcRecvCreate) recv_create;
-  srvc->recv_accept = (mwService_funcRecvAccept) recv_accept;
-  srvc->recv_destroy = (mwService_funcRecvDestroy) recv_destroy;
-  srvc->recv = (mwService_funcRecv) recv;
-  srvc->start = (mwService_funcStart) start;
-  srvc->stop = (mwService_funcStop) stop;
-  srvc->clear = (mwService_funcClear) clear;
-
-  return srvc_resolve;
-}
-
-
-guint32 mwServiceResolve_resolve(struct mwServiceResolve *srvc,
-				 GList *queries, enum mwResolveFlag flags,
-				 mwResolveHandler handler,
-				 gpointer data, GDestroyNotify cleanup) {
-
-  struct mw_search *search;
-  struct mwPutBuffer *b;
-  struct mwOpaque o = { 0, 0 };
-  int ret, count = 0;
-
-  g_return_val_if_fail(srvc != NULL, SEARCH_ERROR);
-  g_return_val_if_fail(handler != NULL, SEARCH_ERROR);
-
-  count = g_list_length(queries);
-  g_return_val_if_fail(count > 0, SEARCH_ERROR);
-
-  search = search_new(srvc, handler, data, cleanup);
-
-  b = mwPutBuffer_new();
-  guint32_put(b, 0x00); /* to be overwritten */
-  guint32_put(b, search->id);
-  guint32_put(b, count);
-  for(; queries; queries = queries->next)
-    mwString_put(b, queries->data);
-  guint32_put(b, flags);
-
-  mwPutBuffer_finalize(&o, b);
-  
-  ret = mwChannel_send(srvc->channel, RESOLVE_ACTION, &o);
-  if(ret) {
-    search_free(search);
-    return SEARCH_ERROR;
-
-  } else {
-    g_hash_table_insert(srvc->searches,
-			GUINT_TO_POINTER(search->id), search);
-    return search->id;
-  }
-}
-
-
-void mwServiceResolve_cancelResolve(struct mwServiceResolve *srvc,
-				    guint32 id) {
-
-  g_return_if_fail(srvc != NULL);
-  g_return_if_fail(srvc->searches != NULL);
-
-  g_hash_table_remove(srvc->searches, GUINT_TO_POINTER(id));
-}
-
--- a/src/protocols/sametime/meanwhile/srvc_store.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,608 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <glib/glist.h>
-
-#include "mw_channel.h"
-#include "mw_debug.h"
-#include "mw_error.h"
-#include "mw_message.h"
-#include "mw_service.h"
-#include "mw_session.h"
-#include "mw_srvc_store.h"
-
-
-#define PROTOCOL_TYPE  0x00000025
-#define PROTOCOL_VER   0x00000001
-
-
-enum storage_action {
-  action_load    = 0x0004,
-  action_loaded  = 0x0005,
-  action_save    = 0x0006,
-  action_saved   = 0x0007,
-};
-
-
-struct mwStorageUnit {
-  /** key by which data is referenced in service
-      @see mwStorageKey */
-  guint32 key;
-
-  /** Data associated with key in service */
-  struct mwOpaque data;
-};
-
-
-struct mwStorageReq {
-  guint32 id;                  /**< unique id for this request */
-  guint32 result_code;         /**< result code for completed request */
-  enum storage_action action;  /**< load or save */
-  struct mwStorageUnit *item;  /**< the key/data pair */ 
-  mwStorageCallback cb;        /**< callback to notify upon completion */
-  gpointer data;               /**< user data to pass with callback */
-  GDestroyNotify data_free;    /**< optionally frees user data */
-};
-
-
-struct mwServiceStorage {
-  struct mwService service;
-
-  /** collection of mwStorageReq */
-  GList *pending;
-
-  /** current service channel */
-  struct mwChannel *channel;
-
-  /** keep track of the counter */
-  guint32 id_counter;
-};
-
-
-static void request_get(struct mwGetBuffer *b, struct mwStorageReq *req) {
-  guint32 id, count, junk;
-
-  if(mwGetBuffer_error(b)) return;
-
-  guint32_get(b, &id);
-  guint32_get(b, &req->result_code);
-
-  if(req->action == action_loaded) {
-    guint32_get(b, &count);
-
-    if(count > 0) {
-      guint32_get(b, &junk);
-      guint32_get(b, &req->item->key);
-
-      mwOpaque_clear(&req->item->data);
-      mwOpaque_get(b, &req->item->data);
-    }
-  }
-}
-
-
-static void request_put(struct mwPutBuffer *b, struct mwStorageReq *req) {
-
-  guint32_put(b, req->id);
-  guint32_put(b, 1);
-
-  if(req->action == action_save) {
-    guint32_put(b, 20 + req->item->data.len); /* ugh, offset garbage */
-    guint32_put(b, req->item->key);
-    mwOpaque_put(b, &req->item->data);
-
-  } else {
-    guint32_put(b, req->item->key);
-  }
-}
-
-
-static int request_send(struct mwChannel *chan, struct mwStorageReq *req) {
-  struct mwPutBuffer *b;
-  struct mwOpaque o = { 0, 0 };
-  int ret;
-
-  b = mwPutBuffer_new();
-  request_put(b, req);
-
-  mwPutBuffer_finalize(&o, b);
-  ret = mwChannel_send(chan, req->action, &o);
-  mwOpaque_clear(&o);
-
-  if(! ret) {
-    if(req->action == action_save) {
-      req->action = action_saved;
-    } else if(req->action == action_load) {
-      req->action = action_loaded;
-    }
-  }
-
-  return ret;
-}
-
-
-static struct mwStorageReq *request_find(struct mwServiceStorage *srvc,
-					 guint32 id) {
-  GList *l;
-
-  for(l = srvc->pending; l; l = l->next) {
-    struct mwStorageReq *r = l->data;
-    if(r->id == id) return r;
-  }
-
-  return NULL;
-}
-
-
-static const char *action_str(enum storage_action act) {
-  switch(act) {
-  case action_load:    return "load";
-  case action_loaded:  return "loaded";
-  case action_save:    return "save";
-  case action_saved:   return "saved";
-  default:             return "UNKNOWN";
-  }
-}
-
-
-static void request_trigger(struct mwServiceStorage *srvc,
-			    struct mwStorageReq *req) {
-
-  struct mwStorageUnit *item = req->item;
-
-  g_message("storage request %s: key = 0x%x, result = 0x%x, length = %u",
-	    action_str(req->action),
-	    item->key, req->result_code, (guint) item->data.len);
-  
-  if(req->cb)
-    req->cb(srvc, req->result_code, item, req->data);
-}
-
-
-static void request_free(struct mwStorageReq *req) {
-  if(req->data_free) {
-    req->data_free(req->data);
-    req->data = NULL;
-    req->data_free = NULL;
-  }
-
-  mwStorageUnit_free(req->item);
-  g_free(req);
-}
-
-
-static void request_remove(struct mwServiceStorage *srvc,
-			   struct mwStorageReq *req) {
-
-  srvc->pending = g_list_remove_all(srvc->pending, req);
-  request_free(req);
-}
-
-
-static const char *get_name(struct mwService *srvc) {
-  return "User Storage";
-}
-
-
-static const char *get_desc(struct mwService *srvc) {
-  return "Stores user data and settings on the server";
-}
-
-
-static struct mwChannel *make_channel(struct mwServiceStorage *srvc) {
-  struct mwSession *session;
-  struct mwChannelSet *cs;
-  struct mwChannel *chan;
-
-  session = mwService_getSession(MW_SERVICE(srvc));
-  cs = mwSession_getChannels(session);
-  chan = mwChannel_newOutgoing(cs);
- 
-  mwChannel_setService(chan, MW_SERVICE(srvc));
-  mwChannel_setProtoType(chan, PROTOCOL_TYPE);
-  mwChannel_setProtoVer(chan, PROTOCOL_VER);
-
-  return mwChannel_create(chan)? NULL: chan;
-}
-
-
-static void start(struct mwService *srvc) {
-  struct mwServiceStorage *srvc_store;
-  struct mwChannel *chan;
-
-  g_return_if_fail(srvc != NULL);
-  srvc_store = (struct mwServiceStorage *) srvc;
-
-  chan = make_channel(srvc_store);
-  if(chan) {
-    srvc_store->channel = chan;
-  } else {
-    mwService_stopped(srvc);
-  }
-}
-
-
-static void stop(struct mwService *srvc) {
-
-  struct mwServiceStorage *srvc_store;
-  GList *l;
-
-  g_return_if_fail(srvc != NULL);
-  srvc_store = (struct mwServiceStorage *) srvc;
-
-  if(srvc_store->channel) {
-    mwChannel_destroy(srvc_store->channel, ERR_SUCCESS, NULL);
-    srvc_store->channel = NULL;
-  }
-
-#if 1
-  /* the new way */
-  /* remove pending requests. Sometimes we can crash the storage
-     service, and when that happens, we end up resending the killer
-     request over and over again, and the service never stays up */
-  for(l = srvc_store->pending; l; l = l->next)
-    request_free(l->data);
-
-  g_list_free(srvc_store->pending);
-  srvc_store->pending = NULL;
-
-  srvc_store->id_counter = 0;
-
-#else
-  /* the old way */
-  /* reset all of the started requests to their unstarted states */
-  for(l = srvc_store->pending; l; l = l->next) {
-    struct mwStorageReq *req = l->data;
-
-    if(req->action == action_loaded) {
-      req->action = action_load;
-    } else if(req->action == action_saved) {
-      req->action = action_save;
-    }
-  }
-#endif
-
-  mwService_stopped(srvc);
-}
-
-
-static void recv_channelAccept(struct mwService *srvc,
-			       struct mwChannel *chan,
-			       struct mwMsgChannelAccept *msg) {
- 
-  struct mwServiceStorage *srvc_stor;
-  GList *l;
-
-  g_return_if_fail(srvc != NULL);
-  srvc_stor = (struct mwServiceStorage *) srvc;
-
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(chan == srvc_stor->channel);
-
-  /* send all pending requests */
-  for(l = srvc_stor->pending; l; l = l->next) {
-    struct mwStorageReq *req = l->data;
-
-    if(req->action == action_save || req->action == action_load) {
-      request_send(chan, req);
-    }
-  }
-
-  mwService_started(srvc);
-}
-
-
-static void recv_channelDestroy(struct mwService *srvc,
-				struct mwChannel *chan,
-				struct mwMsgChannelDestroy *msg) {
-
-  struct mwSession *session;
-  struct mwServiceStorage *srvc_stor;
-
-  g_return_if_fail(srvc != NULL);
-  g_return_if_fail(chan != NULL);
-
-  session = mwService_getSession(srvc);
-  g_return_if_fail(session != NULL);
-
-  srvc_stor = (struct mwServiceStorage *) srvc;
-  srvc_stor->channel = NULL;
-
-  mwService_stop(srvc);
-  mwSession_senseService(session, mwService_getType(srvc));
-}
-
-
-static void recv(struct mwService *srvc, struct mwChannel *chan,
-		 guint16 type, struct mwOpaque *data) {
-
-  /* process into results, trigger callbacks */
-
-  struct mwGetBuffer *b;
-  struct mwServiceStorage *srvc_stor;
-  struct mwStorageReq *req;
-  guint32 id;
-
-  g_return_if_fail(srvc != NULL);
-  srvc_stor = (struct mwServiceStorage *) srvc;
-
-  g_return_if_fail(chan != NULL);
-  g_return_if_fail(chan == srvc_stor->channel);
-  g_return_if_fail(data != NULL);
-
-  b = mwGetBuffer_wrap(data);
-
-  id = guint32_peek(b);
-  req = request_find(srvc_stor, id);
-
-  if(! req) {
-    g_warning("couldn't find request 0x%x in storage service", id);
-    mwGetBuffer_free(b);
-    return;
-  }
-
-  g_return_if_fail(req->action == type);
-  request_get(b, req);
-
-  if(mwGetBuffer_error(b)) {
-    mw_mailme_opaque(data, "storage request 0x%x, type: 0x%x", id, type);
-
-  } else {
-    request_trigger(srvc_stor, req);
-  }
-
-  mwGetBuffer_free(b);
-  request_remove(srvc_stor, req);
-}
-
-
-static void clear(struct mwService *srvc) {
-  struct mwServiceStorage *srvc_stor;
-  GList *l;
-
-  srvc_stor = (struct mwServiceStorage *) srvc;
-
-  for(l = srvc_stor->pending; l; l = l->next)
-    request_free(l->data);
-
-  g_list_free(srvc_stor->pending);
-  srvc_stor->pending = NULL;
-
-  srvc_stor->id_counter = 0;
-}
-
-
-struct mwServiceStorage *mwServiceStorage_new(struct mwSession *session) {
-  struct mwServiceStorage *srvc_store;
-  struct mwService *srvc;
-
-  srvc_store = g_new0(struct mwServiceStorage, 1);
-  srvc = MW_SERVICE(srvc_store);
-
-  mwService_init(srvc, session, mwService_STORAGE);
-  srvc->get_name = get_name;
-  srvc->get_desc = get_desc;
-  srvc->recv_accept = recv_channelAccept;
-  srvc->recv_destroy = recv_channelDestroy;
-  srvc->recv = recv;
-  srvc->start = start;
-  srvc->stop = stop;
-  srvc->clear = clear;
-
-  return srvc_store;
-}
-
-
-struct mwStorageUnit *mwStorageUnit_new(guint32 key) {
-  struct mwStorageUnit *u;
-
-  u = g_new0(struct mwStorageUnit, 1);
-  u->key = key;
-
-  return u;
-}
-
-
-struct mwStorageUnit *mwStorageUnit_newOpaque(guint32 key,
-					      struct mwOpaque *data) {
-  struct mwStorageUnit *u;
-
-  u = g_new0(struct mwStorageUnit, 1);
-  u->key = key;
-
-  if(data)
-    mwOpaque_clone(&u->data, data);
-
-  return u;
-}
-
-
-struct mwStorageUnit *mwStorageUnit_newBoolean(guint32 key,
-					       gboolean val) {
-
-  return mwStorageUnit_newInteger(key, (guint32) val);
-}
-
-
-struct mwStorageUnit *mwStorageUnit_newInteger(guint32 key,
-					       guint32 val) {
-  struct mwStorageUnit *u;
-  struct mwPutBuffer *b;
-
-  u = g_new0(struct mwStorageUnit, 1);
-  u->key = key;
-  
-  b = mwPutBuffer_new();
-  guint32_put(b, val);
-  mwPutBuffer_finalize(&u->data, b);
-
-  return u;
-}
-
-
-struct mwStorageUnit *mwStorageUnit_newString(guint32 key,
-					      const char *str) {
-  struct mwStorageUnit *u;
-  struct mwPutBuffer *b;
-
-  u = g_new0(struct mwStorageUnit, 1);
-  u->key = key;
-
-  b = mwPutBuffer_new();
-  mwString_put(b, str);
-  mwPutBuffer_finalize(&u->data, b);
-
-  return u;
-}
-
-
-guint32 mwStorageUnit_getKey(struct mwStorageUnit *item) {
-  g_return_val_if_fail(item != NULL, 0x00); /* feh, unsafe */
-  return item->key;
-}
-
-
-gboolean mwStorageUnit_asBoolean(struct mwStorageUnit *item,
-				 gboolean val) {
-
-  return !! mwStorageUnit_asInteger(item, (guint32) val);
-}
-
-
-guint32 mwStorageUnit_asInteger(struct mwStorageUnit *item,
-				guint32 val) {
-  struct mwGetBuffer *b;
-  guint32 v;
-
-  g_return_val_if_fail(item != NULL, val);
-
-  b = mwGetBuffer_wrap(&item->data);
-
-  guint32_get(b, &v);
-  if(! mwGetBuffer_error(b)) val = v;
-  mwGetBuffer_free(b);
-
-  return val;
-}
-
-
-char *mwStorageUnit_asString(struct mwStorageUnit *item) {
-  struct mwGetBuffer *b;
-  char *c = NULL;
-
-  g_return_val_if_fail(item != NULL, NULL);
-
-  b = mwGetBuffer_wrap(&item->data);
-
-  mwString_get(b, &c);
-
-  if(mwGetBuffer_error(b))
-    g_debug("error obtaining string value from opaque");
-
-  mwGetBuffer_free(b);
-
-  return c;
-}
-
-
-struct mwOpaque *mwStorageUnit_asOpaque(struct mwStorageUnit *item) {
-  g_return_val_if_fail(item != NULL, NULL);
-  return &item->data;
-}
-
-
-void mwStorageUnit_free(struct mwStorageUnit *item) {
-  if(! item) return;
-
-  mwOpaque_clear(&item->data);
-  g_free(item);
-}
-
-
-static struct mwStorageReq *request_new(struct mwServiceStorage *srvc,
-					struct mwStorageUnit *item,
-					mwStorageCallback cb,
-					gpointer data, GDestroyNotify df) {
-
-  struct mwStorageReq *req = g_new0(struct mwStorageReq, 1);
-
-  req->id = ++srvc->id_counter;
-  req->item = item;
-  req->cb = cb;
-  req->data = data;
-  req->data_free = df;
-
-  return req;
-}
-
-
-void mwServiceStorage_load(struct mwServiceStorage *srvc,
-			   struct mwStorageUnit *item,
-			   mwStorageCallback cb,
-			   gpointer data, GDestroyNotify d_free) {
-
-  /* - construct a request
-     - put request at end of pending
-     - if channel is open and connected
-       - compose the load message
-       - send message
-       - set request to sent
-     - else
-       - start service
-  */ 
-
-  struct mwStorageReq *req;
-
-  req = request_new(srvc, item, cb, data, d_free);
-  req->action = action_load;
-
-  srvc->pending = g_list_append(srvc->pending, req);
-
-  if(MW_SERVICE_IS_STARTED(MW_SERVICE(srvc)))
-    request_send(srvc->channel, req);
-}
-
-
-void mwServiceStorage_save(struct mwServiceStorage *srvc,
-			   struct mwStorageUnit *item,
-			   mwStorageCallback cb,
-			   gpointer data, GDestroyNotify d_free) {
-
-  /* - construct a request
-     - put request at end of pending
-     - if channel is open and connected
-       - compose the save message
-       - send message
-       - set request to sent
-     - else
-       - start service
-  */
-
-  struct mwStorageReq *req;
-
-  req = request_new(srvc, item, cb, data, d_free);
-  req->action = action_save;
-
-  srvc->pending = g_list_append(srvc->pending, req);
-
-  if(MW_SERVICE_IS_STARTED(MW_SERVICE(srvc)))
-    request_send(srvc->channel, req);
-}
-
--- a/src/protocols/sametime/meanwhile/st_list.c	Fri Dec 16 03:34:01 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,668 +0,0 @@
-
-/*
-  Meanwhile - Unofficial Lotus Sametime Community Client Library
-  Copyright (C) 2004  Christopher (siege) O'Brien
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library General Public
-  License as published by the Free Software Foundation; either
-  version 2 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
-  Library General Public License for more details.
-  
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <stdio.h>
-#include <string.h>
-#include <glib/gstring.h>
-
-#include "mw_debug.h"
-#include "mw_util.h"
-#include "mw_st_list.h"
-
-
-struct mwSametimeList {
-  guint ver_major;
-  guint ver_minor;
-  guint ver_micro;
-
-  GList *groups;
-};
-
-
-struct mwSametimeGroup {
-  struct mwSametimeList *list;
-
-  enum mwSametimeGroupType type;
-  char *name;
-  char *alias;
-  gboolean open;
-
-  GList *users;
-};
-
-
-struct mwSametimeUser {
-  struct mwSametimeGroup *group;
-
-  enum mwSametimeUserType type;
-  struct mwIdBlock id;
-  char *name;
-  char *alias;
-};
-
-
-static void user_free(struct mwSametimeUser *u) {
-  struct mwSametimeGroup *g;
-
-  g = u->group;
-  g->users = g_list_remove(g->users, u);
-
-  mwIdBlock_clear(&u->id);
-  g_free(u->name);
-  g_free(u->alias);
-  g_free(u);
-}
-
-
-static void group_free(struct mwSametimeGroup *g) {
-  struct mwSametimeList *l;
-
-  l = g->list;
-  l->groups = g_list_remove(l->groups, g);
-
-  while(g->users)
-    mwSametimeUser_free(g->users->data);
-
-  g_free(g->name);
-  g_free(g->alias);
-  g_free(g);
-}
-
-
-static void list_free(struct mwSametimeList *l) {
-  while(l->groups)
-    mwSametimeGroup_free(l->groups->data);
-
-  g_free(l);
-}
-
-
-struct mwSametimeList *
-mwSametimeList_new() {
-
-  struct mwSametimeList *stl;
-
-  stl = g_new0(struct mwSametimeList, 1);
-  stl->ver_major = ST_LIST_MAJOR;
-  stl->ver_minor = ST_LIST_MINOR;
-  stl->ver_micro = ST_LIST_MICRO;
-
-  return stl;
-}
-
-
-void mwSametimeList_setMajor(struct mwSametimeList *l, guint v) {
-  g_return_if_fail(l != NULL);
-  l->ver_major = v;
-}
-
-
-guint mwSametimeList_getMajor(struct mwSametimeList *l) {
-  g_return_val_if_fail(l != NULL, 0);
-  return l->ver_major;
-}
-
-
-void mwSametimeList_setMinor(struct mwSametimeList *l, guint v) {
-  g_return_if_fail(l != NULL);
-  l->ver_minor = v;
-}
-
-
-guint mwSametimeList_getMinor(struct mwSametimeList *l) {
-  g_return_val_if_fail(l != NULL, 0);
-  return l->ver_minor;
-}
-
-
-void mwSametimeList_setMicro(struct mwSametimeList *l, guint v) {
-  g_return_if_fail(l != NULL);
-  l->ver_micro = v;
-}
-
-
-guint mwSametimeList_getMicro(struct mwSametimeList *l) {
-  g_return_val_if_fail(l != NULL, 0);
-  return l->ver_micro;
-}
-
-
-GList *mwSametimeList_getGroups(struct mwSametimeList *l) {
-  g_return_val_if_fail(l != NULL, NULL);
-  return g_list_copy(l->groups);
-}
-
-
-struct mwSametimeGroup *
-mwSametimeList_findGroup(struct mwSametimeList *l,
-			 const char *name) {
-  GList *s;
-
-  g_return_val_if_fail(l != NULL, NULL);
-  g_return_val_if_fail(name != NULL, NULL);
-  g_return_val_if_fail(*name != '\0', NULL);
-
-  for(s = l->groups; s; s = s->next) {
-    struct mwSametimeGroup *g = s->data;
-    if(! strcmp(g->name, name)) return g;
-  }
-
-  return NULL;
-}
-
-
-void mwSametimeList_free(struct mwSametimeList *l) {
-  g_return_if_fail(l != NULL);
-  list_free(l);
-}
-
-
-struct mwSametimeGroup *
-mwSametimeGroup_new(struct mwSametimeList *list,
-		    enum mwSametimeGroupType type,
-		    const char *name) {
-  
-  struct mwSametimeGroup *stg;
-
-  g_return_val_if_fail(list != NULL, NULL);
-  g_return_val_if_fail(name != NULL, NULL);
-  g_return_val_if_fail(*name != '\0', NULL);
-
-  stg = g_new0(struct mwSametimeGroup, 1);
-  stg->list = list;
-  stg->type = type;
-  stg->name = g_strdup(name);
-
-  list->groups = g_list_append(list->groups, stg);
-
-  return stg;
-}
-
-
-enum mwSametimeGroupType mwSametimeGroup_getType(struct mwSametimeGroup *g) {
-  g_return_val_if_fail(g != NULL, mwSametimeGroup_UNKNOWN);
-  return g->type;
-}
-
-
-const char *mwSametimeGroup_getName(struct mwSametimeGroup *g) {
-  g_return_val_if_fail(g != NULL, NULL);
-  return g->name;
-}
-
-
-void mwSametimeGroup_setAlias(struct mwSametimeGroup *g,
-			      const char *alias) {
-  g_return_if_fail(g != NULL);
-
-  g_free(g->alias);
-  g->alias = g_strdup(alias);
-}
-
-
-const char *mwSametimeGroup_getAlias(struct mwSametimeGroup *g) {
-  g_return_val_if_fail(g != NULL, NULL);
-  return g->alias;
-}
-
-
-void mwSametimeGroup_setOpen(struct mwSametimeGroup *g, gboolean open) {
-  g_return_if_fail(g != NULL);
-  g->open = open;
-}
-
-
-gboolean mwSametimeGroup_isOpen(struct mwSametimeGroup *g) {
-  g_return_val_if_fail(g != NULL, FALSE);
-  return g->open;
-}
-
-
-struct mwSametimeList *mwSametimeGroup_getList(struct mwSametimeGroup *g) {
-  g_return_val_if_fail(g != NULL, NULL);
-  return g->list;
-}
-
-
-GList *mwSametimeGroup_getUsers(struct mwSametimeGroup *g) {
-  g_return_val_if_fail(g != NULL, NULL);
-  return g_list_copy(g->users);
-}
-
-
-struct mwSametimeUser *
-mwSametimeGroup_findUser(struct mwSametimeGroup *g,
-			 struct mwIdBlock *user) {
-  GList *s;
-
-  g_return_val_if_fail(g != NULL, NULL);
-  g_return_val_if_fail(user != NULL, NULL);
-
-  for(s = g->users; s; s = s->next) {
-    struct mwSametimeUser *u = s->data;
-    if(mwIdBlock_equal(user, &u->id)) return u;
-  }
-
-  return NULL;
-}
-
-
-void mwSametimeGroup_free(struct mwSametimeGroup *g) {
-  g_return_if_fail(g != NULL);
-  g_return_if_fail(g->list != NULL);
-  group_free(g);
-}
-
-
-struct mwSametimeUser *
-mwSametimeUser_new(struct mwSametimeGroup *group,
-		   enum mwSametimeUserType type,
-		   struct mwIdBlock *id) {
-
-  struct mwSametimeUser *stu;
-
-  g_return_val_if_fail(group != NULL, NULL);
-  g_return_val_if_fail(id != NULL, NULL);
-  
-  stu = g_new0(struct mwSametimeUser, 1);
-  stu->group = group;
-  stu->type = type;
-  mwIdBlock_clone(&stu->id, id);
-
-  group->users = g_list_append(group->users, stu);
-  
-  return stu;
-}
-
-
-struct mwSametimeGroup *mwSametimeUser_getGroup(struct mwSametimeUser *u) {
-  g_return_val_if_fail(u != NULL, NULL);
-  return u->group;
-}
-
-
-enum mwSametimeUserType mwSametimeUser_getType(struct mwSametimeUser *u) {
-  g_return_val_if_fail(u != NULL, mwSametimeUser_UNKNOWN);
-  return u->type;
-}
-
-
-const char *mwSametimeUser_getUser(struct mwSametimeUser *u) {
-  g_return_val_if_fail(u != NULL, NULL);
-  return u->id.user;
-}
-
-
-const char *mwSametimeUser_getCommunity(struct mwSametimeUser *u) {
-  g_return_val_if_fail(u != NULL, NULL);
-  return u->id.community;
-}
-
-
-void mwSametimeUser_setShortName(struct mwSametimeUser *u, const char *name) {
-  g_return_if_fail(u != NULL);
-  g_free(u->name);
-  u->name = g_strdup(name);
-}
-
-
-const char *mwSametimeUser_getShortName(struct mwSametimeUser *u) {
-  g_return_val_if_fail(u != NULL, NULL);
-  return u->name;
-}
-
-
-void mwSametimeUser_setAlias(struct mwSametimeUser *u, const char *alias) {
-  g_return_if_fail(u != NULL);
-  g_free(u->alias);
-  u->alias = g_strdup(alias);
-}
-
-
-const char *mwSametimeUser_getAlias(struct mwSametimeUser *u) {
-  g_return_val_if_fail(u != NULL, NULL);
-  return u->alias;
-}
-
-
-void mwSametimeUser_free(struct mwSametimeUser *u) {
-  g_return_if_fail(u != NULL);
-  g_return_if_fail(u->group != NULL);
-  user_free(u);
-}
-
-
-static void str_replace(char *str, char from, char to) {
-  if(! str) return;
-  for(; *str; str++) if(*str == from) *str = to;
-}
-
-
-static char user_type_to_char(enum mwSametimeUserType type) {
-  switch(type) {
-  case mwSametimeUser_NORMAL:    return '1';
-  case mwSametimeUser_EXTERNAL:  return '2';
-  case mwSametimeUser_UNKNOWN:
-  default:                       return '9';
-  }
-}
-
-
-static enum mwSametimeUserType user_char_to_type(char type) {
-  switch(type) {
-  case '1':  return mwSametimeUser_NORMAL;
-  case '2':  return mwSametimeUser_EXTERNAL;
-  default:   return mwSametimeUser_UNKNOWN;
-  }
-}
-
-
-static void user_put(GString *str, struct mwSametimeUser *u) {
-  char *id, *name, *alias;
-  char type;
-  
-  id = g_strdup(u->id.user);
-  name = g_strdup(u->name);
-  alias = g_strdup(u->alias);
-  type = user_type_to_char(u->type);
-
-  if(id) str_replace(id, ' ', ';');
-  if(name) str_replace(name, ' ', ';');
-  if(alias) str_replace(alias, ' ', ';');
-
-  if(!name && alias) {
-    name = alias;
-    alias = NULL;
-  }
-
-  g_string_append_printf(str, "U %s%c:: %s,%s\r\n",
-			 id, type, (name? name: ""), (alias? alias: ""));
-
-  g_free(id);
-  g_free(name);
-  g_free(alias);  
-}
-
-
-static char group_type_to_char(enum mwSametimeGroupType type) {
-  switch(type) {
-  case mwSametimeGroup_NORMAL:   return '2';
-  case mwSametimeGroup_DYNAMIC:  return '3';
-  case mwSametimeGroup_UNKNOWN:
-  default:                       return '9';
-  }
-}
-
-
-static enum mwSametimeGroupType group_char_to_type(char type) {
-  switch(type) {
-  case '2':  return mwSametimeGroup_NORMAL;
-  case '3':  return mwSametimeGroup_DYNAMIC;
-  default:   return mwSametimeGroup_UNKNOWN;
-  }
-}
-
-
-static void group_put(GString *str, struct mwSametimeGroup *g) {
-  char *name, *alias;
-  char type;
-  GList *gl;
-
-  name = g_strdup(g->name);
-  alias = g_strdup((g->alias)? g->alias: name);
-  type = group_type_to_char(g->type);
-
-  str_replace(name, ' ', ';');
-  str_replace(alias, ' ', ';');
-
-  g_string_append_printf(str, "G %s%c %s %c\r\n",
-			 name, type, alias, (g->open? 'O':'C'));
-
-  for(gl = g->users; gl; gl = gl->next) {
-    user_put(str, gl->data);
-  }
-
-  g_free(name);
-  g_free(alias);
-}
-
-
-/** composes a GString with the written contents of a sametime list */
-static GString *list_store(struct mwSametimeList *l) {
-  GString *str;
-  GList *gl;
-
-  g_return_val_if_fail(l != NULL, NULL);
-
-  str = g_string_new(NULL);
-  g_string_append_printf(str, "Version=%u.%u.%u\r\n",
-			 l->ver_major, l->ver_minor, l->ver_micro);
-
-  for(gl = l->groups; gl; gl = gl->next) {
-    group_put(str, gl->data);
-  }
-
-  return str;
-}
-
-
-char *mwSametimeList_store(struct mwSametimeList *l) {
-  GString *str;
-  char *s;
-
-  g_return_val_if_fail(l != NULL, NULL);
-
-  str = list_store(l);
-  s = str->str;
-  g_string_free(str, FALSE);
-  return s;
-}
-
-
-void mwSametimeList_put(struct mwPutBuffer *b, struct mwSametimeList *l) {
-  GString *str;
-  guint16 len;
-
-  g_return_if_fail(l != NULL);
-  g_return_if_fail(b != NULL);
-
-  str = list_store(l);
-  len = (guint16) str->len;
-  guint16_put(b, len);
-  mwPutBuffer_write(b, str->str, len);
-
-  g_string_free(str, TRUE);
-}
-
-
-static void get_version(const char *line, struct mwSametimeList *l) {
-  guint major = 0, minor = 0, micro = 0;
-  int ret;
-
-  ret = sscanf(line, "Version=%u.%u.%u\n", &major, &minor, &micro);
-  if(ret != 3) {
-    g_warning("strange sametime list version line:\n%s", line);
-  }
-
-  l->ver_major = major;
-  l->ver_minor = minor;
-  l->ver_micro = micro;
-}
-
-
-static struct mwSametimeGroup *get_group(const char *line,
-					 struct mwSametimeList *l) {
-  struct mwSametimeGroup *group;
-  char *name, *alias;
-  char type = '2', open = 'O';
-  int ret;
-
-  ret = strlen(line);
-  name = g_malloc0(ret);
-  alias = g_malloc0(ret);
-
-  ret = sscanf(line, "G %s %s %c\n",
-	       name, alias, &open);
-
-  if(ret < 3) {
-    g_warning("strange sametime list group line:\n%s", line);
-  }
-  
-  str_replace(name, ';', ' ');
-  str_replace(alias, ';', ' ');
-
-  if(name && *name) {
-    int l = strlen(name)-1;
-    type = name[l];
-    name[l] = '\0';
-  }
-
-  group = g_new0(struct mwSametimeGroup, 1);
-  group->list = l;
-  group->name = name;
-  group->type = group_char_to_type(type);
-  group->alias = alias;
-  group->open = (open == 'O');
-
-  l->groups = g_list_append(l->groups, group);
-
-  return group;
-}
-
-
-static void get_user(const char *line, struct mwSametimeGroup *g) {
-  struct mwSametimeUser *user;
-  struct mwIdBlock idb = { 0, 0 };
-  char *name, *alias = NULL;
-  char type = '1';
-  int ret;
-  
-  ret = strlen(line);
-  idb.user = g_malloc0(ret);
-  name = g_malloc0(ret);
-
-  ret = sscanf(line, "U %s %s",
-	       idb.user, name);
-
-  if(ret < 2) {
-    g_warning("strange sametime list user line:\n%s", line);
-  }
-
-  str_replace(idb.user, ';', ' ');
-  str_replace(name, ';', ' ');
-
-  if(idb.user && *idb.user) {
-    char *tmp = strstr(idb.user, "::");
-    if(tmp--) {
-      type = *(tmp);
-      *tmp = '\0';
-    }
-  }
-
-  if(name && *name) {
-    char *tmp = strrchr(name, ',');
-    if(tmp) {
-      *tmp++ = '\0';
-      if(*tmp) alias = tmp;
-    }
-  }
-
-  user = g_new0(struct mwSametimeUser, 1);
-  user->group = g;
-  user->id.user = idb.user;
-  user->type = user_char_to_type(type);
-  user->name = name;
-  user->alias = g_strdup(alias);
-  
-  g->users = g_list_append(g->users, user);
-}
-
-
-/** returns a line from str, and advances str */
-static char *fetch_line(char **str) {
-  char *start = *str;
-  char *end;
-
-  /* move to first non-whitespace character */
-  while(*start && g_ascii_isspace(*start)) start++;
-  if(! *start) return NULL;
-
-  for(end = start + 1; *end; end++) {
-    if(*end == '\n' || *end == '\r') {
-      *(end++) = '\0';
-      break;
-    }
-  }
-
-  *str = end;
-  return start;
-}
-
-
-void list_get(const char *lines, struct mwSametimeList *l) {
-  char *s = (char *) lines;
-  char *line;
-
-  struct mwSametimeGroup *g = NULL;
-  
-  while( (line = fetch_line(&s)) ) {
-    switch(*line) {
-    case 'V':
-      get_version(line, l);
-      break;
-
-    case 'G':
-      g = get_group(line, l);
-      break;
-
-    case 'U':
-      get_user(line, g);
-      break;
-
-    default:
-      g_warning("unknown sametime list data line:\n%s", line);
-    }
-  }  
-}
-
-
-struct mwSametimeList *mwSametimeList_load(const char *data) {
-  struct mwSametimeList *l;
-
-  g_return_val_if_fail(data != NULL, NULL);
-  
-  l = mwSametimeList_new();
-  list_get(data, l);
-
-  return l;
-}
-
-
-void mwSametimeList_get(struct mwGetBuffer *b, struct mwSametimeList *l) {
-  char *str = NULL;
-
-  g_return_if_fail(l != NULL);
-  g_return_if_fail(b != NULL);
-
-  mwString_get(b, &str);
-  list_get(str, l);
-  g_free(str);
-}
-
--- a/src/protocols/sametime/sametime.c	Fri Dec 16 03:34:01 2005 +0000
+++ b/src/protocols/sametime/sametime.c	Fri Dec 16 04:08:05 2005 +0000
@@ -3229,7 +3229,7 @@
   pd = gc->proto_data;
 
   ret = mwServiceAware_getText(pd->srvc_aware, &t);
-  return g_strdup(ret);
+  return ret? g_markup_escape_text(ret, -1): NULL;
 }
 
 
@@ -4187,7 +4187,11 @@
     g_string_append(str, "<hr>");
     
     tmp = mwServiceAware_getText(pd->srvc_aware, &idb);
-    if(tmp) g_string_append(str, tmp);
+    if(tmp) {
+      tmp = g_markup_escape_text(tmp, -1);
+      g_string_append(str, tmp);
+      g_free((char *) tmp);
+    }
   }
 
   /* @todo emit a signal to allow a plugin to override the display of