changeset 1598:a087125d8fc8

Replace libjabber with loudmouth
author franky
date Sun, 11 Oct 2009 15:38:32 +0200
parents 4f59a414217e
children dcd5d4c75199
files mcabber/Makefile.am mcabber/configure.ac mcabber/connwrap/Makefile.am mcabber/connwrap/aclocal.m4 mcabber/connwrap/configure mcabber/connwrap/configure.in mcabber/connwrap/connwrap.c mcabber/connwrap/connwrap.h mcabber/connwrap/connwrap.spec mcabber/connwrap/md5.c mcabber/connwrap/md5.h mcabber/libjabber/Makefile.am mcabber/libjabber/aclocal.m4 mcabber/libjabber/asciitab.h mcabber/libjabber/config.h.in mcabber/libjabber/configure mcabber/libjabber/configure.in mcabber/libjabber/expat.c mcabber/libjabber/genhash.c mcabber/libjabber/hashtable.c mcabber/libjabber/hashtable.h mcabber/libjabber/iasciitab.h mcabber/libjabber/jabber.h mcabber/libjabber/jconn.c mcabber/libjabber/jid.c mcabber/libjabber/jpacket.c mcabber/libjabber/jutil.c mcabber/libjabber/latin1tab.h mcabber/libjabber/libxode.h mcabber/libjabber/log.c mcabber/libjabber/log.h mcabber/libjabber/nametab.h mcabber/libjabber/pool.c mcabber/libjabber/pproxy.c mcabber/libjabber/rate.c mcabber/libjabber/sha.c mcabber/libjabber/snprintf.c mcabber/libjabber/socket.c mcabber/libjabber/str.c mcabber/libjabber/utf8tab.h mcabber/libjabber/xmldef.h mcabber/libjabber/xmlnode.c mcabber/libjabber/xmlparse.c mcabber/libjabber/xmlparse.h mcabber/libjabber/xmlrole.c mcabber/libjabber/xmlrole.h mcabber/libjabber/xmltok.c mcabber/libjabber/xmltok.h mcabber/libjabber/xmltok_impl.h mcabber/libjabber/xmltok_impl_c.h mcabber/libjabber/xmltok_ns_c.h mcabber/libjabber/xstream.c mcabber/mcabberrc.example mcabber/src/Makefile.am mcabber/src/commands.c mcabber/src/commands.h mcabber/src/events.c mcabber/src/events.h mcabber/src/fifo.c mcabber/src/histolog.c mcabber/src/histolog.h mcabber/src/hooks.c mcabber/src/hooks.h mcabber/src/jab_iq.c mcabber/src/jab_priv.h mcabber/src/jabglue.c mcabber/src/jabglue.h mcabber/src/main.c mcabber/src/otr.c mcabber/src/pgp.c mcabber/src/screen.c mcabber/src/screen.h mcabber/src/settings.c mcabber/src/settings.h mcabber/src/utils.c mcabber/src/utils.h mcabber/src/xmpp.c mcabber/src/xmpp.h mcabber/src/xmpp_defines.h mcabber/src/xmpp_helper.c mcabber/src/xmpp_helper.h mcabber/src/xmpp_iq.c mcabber/src/xmpp_iqrequest.c mcabber/src/xmpp_muc.c mcabber/src/xmpp_s10n.c
diffstat 85 files changed, 5141 insertions(+), 27389 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/Makefile.am	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/Makefile.am	Sun Oct 11 15:38:32 2009 +0200
@@ -1,2 +1,2 @@
-SUBDIRS = connwrap libjabber src doc
+SUBDIRS = src doc
 ACLOCAL_AMFLAGS = -I macros
--- a/mcabber/configure.ac	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/configure.ac	Sun Oct 11 15:38:32 2009 +0200
@@ -138,6 +138,12 @@
                                   [g_list_append])],
                  [g_regex_new])
 
+dnl AC_CHECK_LIB([loudmouth1],[lm_session_is_open],,AC_MSG_ERROR([ERROR! loudmouth1 not found...]))
+LOUDMOUTH_CFLAGS=`pkg-config --cflags loudmouth-1.0`
+LOUDMOUTH_LIBS=`pkg-config --libs loudmouth-1.0`
+AC_SUBST(LOUDMOUTH_CFLAGS)
+AC_SUBST(LOUDMOUTH_LIBS)
+
 # Check for gpgme
 AC_ARG_ENABLE(gpgme, AC_HELP_STRING([--disable-gpgme], [disable GPGME support]),
     [ if test x"$enableval" = x"no"; then
@@ -162,48 +168,6 @@
   )
 fi
 
-AC_ARG_WITH(ssl, [  --with-ssl              enable SSL secured connections using either OpenSSL
-                          or GnuTLS],
-        [with_ssl=$withval])
-
-if test "$with_ssl" != "no"; then
-    AC_ARG_WITH(openssl,
-        [  --with-openssl=[DIR]      enable SSL secured connections using the OpenSSL
-                          library in DIR (optional)],
-        [with_openssl=$withval])
-
-    if test -z "$with_openssl"; then
-        for ac_dir in /usr/local /usr; do
-            if test -f "$ac_dir/include/openssl/ssl.h"; then
-                with_openssl=$ac_dir
-                break;
-            fi
-        done
-    fi
-
-    AC_MSG_CHECKING(for OpenSSL)
-
-    if test -n "$with_openssl" -a "$with_openssl" != "no"; then
-        if test "$with_openssl" = "yes"; then with_openssl="/usr"; fi
-        CFLAGS="$CFLAGS -I${with_openssl}"
-        AC_DEFINE([HAVE_OPENSSL], [], [OpenSSL])
-        AC_MSG_RESULT([found in $with_openssl])
-        AC_CHECK_LIB(crypto, main)
-        AC_CHECK_LIB(ssl, main)
-    else
-        AC_MSG_RESULT([not found or disabled])
-
-        PKG_PROG_PKG_CONFIG
-        PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 1.0.0],
-                          have_gnutls=yes, have_gnutls=no)
-        if test "$have_gnutls" = "yes"; then
-            AC_DEFINE([HAVE_GNUTLS], 1, [GNU TLS])
-            CXXFLAGS="$CXXFLAGS $LIBGNUTLS_CFLAGS"
-            LIBS="$LIBS $LIBGNUTLS_LIBS"
-        fi
-    fi
-fi
-
 # Check for Enchant stuff
 AC_ARG_ENABLE(enchant, [  --enable-enchant       enable enchant support],
               enable_enchant=$enableval, enchant="")
@@ -270,9 +234,7 @@
 # We need _GNU_SOURCE for strptime() and strcasestr()
 CFLAGS="$CFLAGS -D_GNU_SOURCE"
 
-AC_CONFIG_FILES([connwrap/Makefile
-                 libjabber/Makefile
-                 src/Makefile
+AC_CONFIG_FILES([src/Makefile
                  doc/Makefile
                  doc/guide/Makefile
                  doc/help/Makefile
--- a/mcabber/connwrap/Makefile.am	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-EXTRA_DIST = connwrap.c md5.c connwrap.h md5.h connwrap.spec
-SUBDIRS = 
-INCLUDES = 
-CPPFLAGS = 
-noinst_LIBRARIES = libconnwrap.a
-libconnwrap_a_SOURCES =  connwrap.c md5.c
-AUTOMAKE_OPTIONS = foreign
--- a/mcabber/connwrap/aclocal.m4	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,297 +0,0 @@
-dnl aclocal.m4 generated automatically by aclocal 1.4-p6
-
-dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl This program is distributed in the hope that it will be useful,
-dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-dnl PARTICULAR PURPOSE.
-
-# Do all the work for Automake.  This macro actually does too much --
-# some checks are only needed if your package does certain things.
-# But this isn't really a big deal.
-
-# serial 1
-
-dnl Usage:
-dnl AM_INIT_AUTOMAKE(package,version, [no-define])
-
-AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
-AC_REQUIRE([AC_PROG_INSTALL])
-PACKAGE=[$1]
-AC_SUBST(PACKAGE)
-VERSION=[$2]
-AC_SUBST(VERSION)
-dnl test to see if srcdir already configured
-if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
-  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
-fi
-ifelse([$3],,
-AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
-AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
-AC_REQUIRE([AM_SANITY_CHECK])
-AC_REQUIRE([AC_ARG_PROGRAM])
-dnl FIXME This is truly gross.
-missing_dir=`cd $ac_aux_dir && pwd`
-AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}, $missing_dir)
-AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
-AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}, $missing_dir)
-AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
-AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
-AC_REQUIRE([AC_PROG_MAKE_SET])])
-
-# Copyright 2002  Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-
-# AM_AUTOMAKE_VERSION(VERSION)
-# ----------------------------
-# Automake X.Y traces this macro to ensure aclocal.m4 has been
-# generated from the m4 files accompanying Automake X.Y.
-AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.4"])
-
-# AM_SET_CURRENT_AUTOMAKE_VERSION
-# -------------------------------
-# Call AM_AUTOMAKE_VERSION so it can be traced.
-# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
-AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-	 [AM_AUTOMAKE_VERSION([1.4-p6])])
-
-#
-# Check to make sure that the build environment is sane.
-#
-
-AC_DEFUN([AM_SANITY_CHECK],
-[AC_MSG_CHECKING([whether build environment is sane])
-# Just in case
-sleep 1
-echo timestamp > conftestfile
-# Do `set' in a subshell so we don't clobber the current shell's
-# arguments.  Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
-   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
-   if test "[$]*" = "X"; then
-      # -L didn't work.
-      set X `ls -t $srcdir/configure conftestfile`
-   fi
-   if test "[$]*" != "X $srcdir/configure conftestfile" \
-      && test "[$]*" != "X conftestfile $srcdir/configure"; then
-
-      # If neither matched, then we have a broken ls.  This can happen
-      # if, for instance, CONFIG_SHELL is bash and it inherits a
-      # broken ls alias from the environment.  This has actually
-      # happened.  Such a system could not be considered "sane".
-      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
-alias in your environment])
-   fi
-
-   test "[$]2" = conftestfile
-   )
-then
-   # Ok.
-   :
-else
-   AC_MSG_ERROR([newly created file is older than distributed files!
-Check your system clock])
-fi
-rm -f conftest*
-AC_MSG_RESULT(yes)])
-
-dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
-dnl The program must properly implement --version.
-AC_DEFUN([AM_MISSING_PROG],
-[AC_MSG_CHECKING(for working $2)
-# Run test in a subshell; some versions of sh will print an error if
-# an executable is not found, even if stderr is redirected.
-# Redirect stdin to placate older versions of autoconf.  Sigh.
-if ($2 --version) < /dev/null > /dev/null 2>&1; then
-   $1=$2
-   AC_MSG_RESULT(found)
-else
-   $1="$3/missing $2"
-   AC_MSG_RESULT(missing)
-fi
-AC_SUBST($1)])
-
-dnl Autoconf macros for libgnutls-extra
-dnl $id$
-
-# Modified for LIBGNUTLS_EXTRA -- nmav
-# Configure paths for LIBGCRYPT
-# Shamelessly stolen from the one of XDELTA by Owen Taylor
-# Werner Koch   99-12-09
-
-dnl AM_PATH_LIBGNUTLS_EXTRA([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
-dnl Test for libgnutls-extra, and define LIBGNUTLS_EXTRA_CFLAGS and LIBGNUTLS_EXTRA_LIBS
-dnl
-AC_DEFUN(AM_PATH_LIBGNUTLS_EXTRA,
-[dnl
-dnl Get the cflags and libraries from the libgnutls-extra-config script
-dnl
-AC_ARG_WITH(libgnutls-extra-prefix,
-          [  --with-libgnutls-extra-prefix=PFX   Prefix where libgnutls-extra is installed (optional)],
-          libgnutls_extra_config_prefix="$withval", libgnutls_extra_config_prefix="")
-
-  if test x$libgnutls_extra_config_prefix != x ; then
-     libgnutls_extra_config_args="$libgnutls_extra_config_args --prefix=$libgnutls_extra_config_prefix"
-     if test x${LIBGNUTLS_EXTRA_CONFIG+set} != xset ; then
-        LIBGNUTLS_EXTRA_CONFIG=$libgnutls_extra_config_prefix/bin/libgnutls-extra-config
-     fi
-  fi
-
-  AC_PATH_PROG(LIBGNUTLS_EXTRA_CONFIG, libgnutls-extra-config, no)
-  min_libgnutls_version=ifelse([$1], ,0.1.0,$1)
-  AC_MSG_CHECKING(for libgnutls - version >= $min_libgnutls_version)
-  no_libgnutls=""
-  if test "$LIBGNUTLS_EXTRA_CONFIG" = "no" ; then
-    no_libgnutls=yes
-  else
-    LIBGNUTLS_EXTRA_CFLAGS=`$LIBGNUTLS_EXTRA_CONFIG $libgnutls_extra_config_args --cflags`
-    LIBGNUTLS_EXTRA_LIBS=`$LIBGNUTLS_EXTRA_CONFIG $libgnutls_extra_config_args --libs`
-    libgnutls_extra_config_version=`$LIBGNUTLS_EXTRA_CONFIG $libgnutls_extra_config_args --version`
-
-
-      ac_save_CFLAGS="$CFLAGS"
-      ac_save_LIBS="$LIBS"
-      CFLAGS="$CFLAGS $LIBGNUTLS_EXTRA_CFLAGS"
-      LIBS="$LIBS $LIBGNUTLS_EXTRA_LIBS"
-dnl
-dnl Now check if the installed libgnutls is sufficiently new. Also sanity
-dnl checks the results of libgnutls-extra-config to some extent
-dnl
-      rm -f conf.libgnutlstest
-      AC_TRY_RUN([
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <gnutls/extra.h>
-
-int
-main ()
-{
-    system ("touch conf.libgnutlstest");
-
-    if( strcmp( gnutls_extra_check_version(NULL), "$libgnutls_extra_config_version" ) )
-    {
-      printf("\n*** 'libgnutls-extra-config --version' returned %s, but LIBGNUTLS_EXTRA (%s)\n",
-             "$libgnutls_extra_config_version", gnutls_extra_check_version(NULL) );
-      printf("*** was found! If libgnutls-extra-config was correct, then it is best\n");
-      printf("*** to remove the old version of LIBGNUTLS_EXTRA. You may also be able to fix the error\n");
-      printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
-      printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
-      printf("*** required on your system.\n");
-      printf("*** If libgnutls-extra-config was wrong, set the environment variable LIBGNUTLS_EXTRA_CONFIG\n");
-      printf("*** to point to the correct copy of libgnutls-extra-config, and remove the file config.cache\n");
-      printf("*** before re-running configure\n");
-    }
-    else if ( strcmp(gnutls_extra_check_version(NULL), LIBGNUTLS_EXTRA_VERSION ) )
-    {
-      printf("\n*** LIBGNUTLS_EXTRA header file (version %s) does not match\n", LIBGNUTLS_EXTRA_VERSION);
-      printf("*** library (version %s). This is may be due to a different version of gnutls\n", gnutls_extra_check_version(NULL) );
-      printf("*** and gnutls-extra.\n");
-    }
-    else
-    {
-      if ( gnutls_extra_check_version( "$min_libgnutls_version" ) )
-      {
-        return 0;
-      }
-     else
-      {
-        printf("no\n*** An old version of LIBGNUTLS_EXTRA (%s) was found.\n",
-                gnutls_extra_check_version(NULL) );
-        printf("*** You need a version of LIBGNUTLS_EXTRA newer than %s. The latest version of\n",
-               "$min_libgnutls_version" );
-        printf("*** LIBGNUTLS_EXTRA is always available from ftp://gnutls.hellug.gr/pub/gnutls.\n");
-        printf("*** \n");
-        printf("*** If you have already installed a sufficiently new version, this error\n");
-        printf("*** probably means that the wrong copy of the libgnutls-extra-config shell script is\n");
-        printf("*** being found. The easiest way to fix this is to remove the old version\n");
-        printf("*** of LIBGNUTLS_EXTRA, but you can also set the LIBGNUTLS_EXTRA_CONFIG environment to point to the\n");
-        printf("*** correct copy of libgnutls-extra-config. (In this case, you will have to\n");
-        printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
-        printf("*** so that the correct libraries are found at run-time))\n");
-      }
-    }
-  return 1;
-}
-],, no_libgnutls=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
-       CFLAGS="$ac_save_CFLAGS"
-       LIBS="$ac_save_LIBS"
-  fi
-
-  if test "x$no_libgnutls" = x ; then
-     AC_MSG_RESULT(yes)
-     ifelse([$2], , :, [$2])
-  else
-     if test -f conf.libgnutlstest ; then
-        :
-     else
-        AC_MSG_RESULT(no)
-     fi
-     if test "$LIBGNUTLS_EXTRA_CONFIG" = "no" ; then
-       echo "*** The libgnutls-extra-config script installed by LIBGNUTLS_EXTRA could not be found"
-       echo "*** If LIBGNUTLS_EXTRA was installed in PREFIX, make sure PREFIX/bin is in"
-       echo "*** your path, or set the LIBGNUTLS_EXTRA_CONFIG environment variable to the"
-       echo "*** full path to libgnutls-extra-config."
-     else
-       if test -f conf.libgnutlstest ; then
-        :
-       else
-          echo "*** Could not run libgnutls test program, checking why..."
-          CFLAGS="$CFLAGS $LIBGNUTLS_EXTRA_CFLAGS"
-          LIBS="$LIBS $LIBGNUTLS_EXTRA_LIBS"
-          AC_TRY_LINK([
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <gnutls/extra.h>
-],      [ return !!gnutls_extra_check_version(NULL); ],
-        [ echo "*** The test program compiled, but did not run. This usually means"
-          echo "*** that the run-time linker is not finding LIBGNUTLS_EXTRA or finding the wrong"
-          echo "*** version of LIBGNUTLS_EXTRA. If it is not finding LIBGNUTLS_EXTRA, you'll need to set your"
-          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
-          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
-          echo "*** is required on your system"
-          echo "***"
-          echo "*** If you have an old version installed, it is best to remove it, although"
-          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
-          echo "***" ],
-        [ echo "*** The test program failed to compile or link. See the file config.log for the"
-          echo "*** exact error that occured. This usually means LIBGNUTLS_EXTRA was incorrectly installed"
-          echo "*** or that you have moved LIBGNUTLS_EXTRA since it was installed. In the latter case, you"
-          echo "*** may want to edit the libgnutls-extra-config script: $LIBGNUTLS_EXTRA_CONFIG" ])
-          CFLAGS="$ac_save_CFLAGS"
-          LIBS="$ac_save_LIBS"
-       fi
-     fi
-     LIBGNUTLS_EXTRA_CFLAGS=""
-     LIBGNUTLS_EXTRA_LIBS=""
-     ifelse([$3], , :, [$3])
-  fi
-  rm -f conf.libgnutlstest
-  AC_SUBST(LIBGNUTLS_EXTRA_CFLAGS)
-  AC_SUBST(LIBGNUTLS_EXTRA_LIBS)
-])
-
-dnl *-*wedit:notab*-*  Please keep this as the last line.
-
--- a/mcabber/connwrap/configure	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1893 +0,0 @@
-#! /bin/sh
-
-# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.13 
-# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-
-# Defaults:
-ac_help=
-ac_default_prefix=/usr/local
-# Any additions from configure.in:
-ac_help="$ac_help
-  --with-ssl              enable SSL secured connections using either OpenSSL
-			  or GnuTLS"
-ac_help="$ac_help
-  --with-openssl=[DIR]    enable SSL secured connections using the OpenSSL
-			  library in DIR (optional)"
-ac_help="$ac_help
-  --with-libgnutls-extra-prefix=PFX   Prefix where libgnutls-extra is installed (optional)"
-
-# Initialize some variables set by options.
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-build=NONE
-cache_file=./config.cache
-exec_prefix=NONE
-host=NONE
-no_create=
-nonopt=NONE
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-target=NONE
-verbose=
-x_includes=NONE
-x_libraries=NONE
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
-
-# Initialize some other variables.
-subdirs=
-MFLAGS= MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-# Maximum number of lines to put in a shell here document.
-ac_max_here_lines=12
-
-ac_prev=
-for ac_option
-do
-
-  # If the previous option needs an argument, assign it.
-  if test -n "$ac_prev"; then
-    eval "$ac_prev=\$ac_option"
-    ac_prev=
-    continue
-  fi
-
-  case "$ac_option" in
-  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
-  *) ac_optarg= ;;
-  esac
-
-  # Accept the important Cygnus configure options, so we can diagnose typos.
-
-  case "$ac_option" in
-
-  -bindir | --bindir | --bindi | --bind | --bin | --bi)
-    ac_prev=bindir ;;
-  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
-    bindir="$ac_optarg" ;;
-
-  -build | --build | --buil | --bui | --bu)
-    ac_prev=build ;;
-  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
-    build="$ac_optarg" ;;
-
-  -cache-file | --cache-file | --cache-fil | --cache-fi \
-  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
-    ac_prev=cache_file ;;
-  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
-  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
-    cache_file="$ac_optarg" ;;
-
-  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
-    ac_prev=datadir ;;
-  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
-  | --da=*)
-    datadir="$ac_optarg" ;;
-
-  -disable-* | --disable-*)
-    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
-    # Reject names that are not valid shell variable names.
-    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
-      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
-    fi
-    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
-    eval "enable_${ac_feature}=no" ;;
-
-  -enable-* | --enable-*)
-    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
-    # Reject names that are not valid shell variable names.
-    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
-      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
-    fi
-    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
-    case "$ac_option" in
-      *=*) ;;
-      *) ac_optarg=yes ;;
-    esac
-    eval "enable_${ac_feature}='$ac_optarg'" ;;
-
-  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
-  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
-  | --exec | --exe | --ex)
-    ac_prev=exec_prefix ;;
-  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
-  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
-  | --exec=* | --exe=* | --ex=*)
-    exec_prefix="$ac_optarg" ;;
-
-  -gas | --gas | --ga | --g)
-    # Obsolete; use --with-gas.
-    with_gas=yes ;;
-
-  -help | --help | --hel | --he)
-    # Omit some internal or obsolete options to make the list less imposing.
-    # This message is too long to be a string in the A/UX 3.1 sh.
-    cat << EOF
-Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
-Configuration:
-  --cache-file=FILE       cache test results in FILE
-  --help                  print this message
-  --no-create             do not create output files
-  --quiet, --silent       do not print \`checking...' messages
-  --version               print the version of autoconf that created configure
-Directory and file names:
-  --prefix=PREFIX         install architecture-independent files in PREFIX
-                          [$ac_default_prefix]
-  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
-                          [same as prefix]
-  --bindir=DIR            user executables in DIR [EPREFIX/bin]
-  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
-  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
-  --datadir=DIR           read-only architecture-independent data in DIR
-                          [PREFIX/share]
-  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
-  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
-                          [PREFIX/com]
-  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
-  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
-  --includedir=DIR        C header files in DIR [PREFIX/include]
-  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
-  --infodir=DIR           info documentation in DIR [PREFIX/info]
-  --mandir=DIR            man documentation in DIR [PREFIX/man]
-  --srcdir=DIR            find the sources in DIR [configure dir or ..]
-  --program-prefix=PREFIX prepend PREFIX to installed program names
-  --program-suffix=SUFFIX append SUFFIX to installed program names
-  --program-transform-name=PROGRAM
-                          run sed PROGRAM on installed program names
-EOF
-    cat << EOF
-Host type:
-  --build=BUILD           configure for building on BUILD [BUILD=HOST]
-  --host=HOST             configure for HOST [guessed]
-  --target=TARGET         configure for TARGET [TARGET=HOST]
-Features and packages:
-  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
-  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
-  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
-  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
-  --x-includes=DIR        X include files are in DIR
-  --x-libraries=DIR       X library files are in DIR
-EOF
-    if test -n "$ac_help"; then
-      echo "--enable and --with options recognized:$ac_help"
-    fi
-    exit 0 ;;
-
-  -host | --host | --hos | --ho)
-    ac_prev=host ;;
-  -host=* | --host=* | --hos=* | --ho=*)
-    host="$ac_optarg" ;;
-
-  -includedir | --includedir | --includedi | --included | --include \
-  | --includ | --inclu | --incl | --inc)
-    ac_prev=includedir ;;
-  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
-  | --includ=* | --inclu=* | --incl=* | --inc=*)
-    includedir="$ac_optarg" ;;
-
-  -infodir | --infodir | --infodi | --infod | --info | --inf)
-    ac_prev=infodir ;;
-  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
-    infodir="$ac_optarg" ;;
-
-  -libdir | --libdir | --libdi | --libd)
-    ac_prev=libdir ;;
-  -libdir=* | --libdir=* | --libdi=* | --libd=*)
-    libdir="$ac_optarg" ;;
-
-  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
-  | --libexe | --libex | --libe)
-    ac_prev=libexecdir ;;
-  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
-  | --libexe=* | --libex=* | --libe=*)
-    libexecdir="$ac_optarg" ;;
-
-  -localstatedir | --localstatedir | --localstatedi | --localstated \
-  | --localstate | --localstat | --localsta | --localst \
-  | --locals | --local | --loca | --loc | --lo)
-    ac_prev=localstatedir ;;
-  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
-  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
-  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
-    localstatedir="$ac_optarg" ;;
-
-  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
-    ac_prev=mandir ;;
-  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
-    mandir="$ac_optarg" ;;
-
-  -nfp | --nfp | --nf)
-    # Obsolete; use --without-fp.
-    with_fp=no ;;
-
-  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
-  | --no-cr | --no-c)
-    no_create=yes ;;
-
-  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
-  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
-    no_recursion=yes ;;
-
-  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
-  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
-  | --oldin | --oldi | --old | --ol | --o)
-    ac_prev=oldincludedir ;;
-  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
-  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
-  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
-    oldincludedir="$ac_optarg" ;;
-
-  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
-    ac_prev=prefix ;;
-  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
-    prefix="$ac_optarg" ;;
-
-  -program-prefix | --program-prefix | --program-prefi | --program-pref \
-  | --program-pre | --program-pr | --program-p)
-    ac_prev=program_prefix ;;
-  -program-prefix=* | --program-prefix=* | --program-prefi=* \
-  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
-    program_prefix="$ac_optarg" ;;
-
-  -program-suffix | --program-suffix | --program-suffi | --program-suff \
-  | --program-suf | --program-su | --program-s)
-    ac_prev=program_suffix ;;
-  -program-suffix=* | --program-suffix=* | --program-suffi=* \
-  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
-    program_suffix="$ac_optarg" ;;
-
-  -program-transform-name | --program-transform-name \
-  | --program-transform-nam | --program-transform-na \
-  | --program-transform-n | --program-transform- \
-  | --program-transform | --program-transfor \
-  | --program-transfo | --program-transf \
-  | --program-trans | --program-tran \
-  | --progr-tra | --program-tr | --program-t)
-    ac_prev=program_transform_name ;;
-  -program-transform-name=* | --program-transform-name=* \
-  | --program-transform-nam=* | --program-transform-na=* \
-  | --program-transform-n=* | --program-transform-=* \
-  | --program-transform=* | --program-transfor=* \
-  | --program-transfo=* | --program-transf=* \
-  | --program-trans=* | --program-tran=* \
-  | --progr-tra=* | --program-tr=* | --program-t=*)
-    program_transform_name="$ac_optarg" ;;
-
-  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-  | -silent | --silent | --silen | --sile | --sil)
-    silent=yes ;;
-
-  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
-    ac_prev=sbindir ;;
-  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
-  | --sbi=* | --sb=*)
-    sbindir="$ac_optarg" ;;
-
-  -sharedstatedir | --sharedstatedir | --sharedstatedi \
-  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
-  | --sharedst | --shareds | --shared | --share | --shar \
-  | --sha | --sh)
-    ac_prev=sharedstatedir ;;
-  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
-  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
-  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
-  | --sha=* | --sh=*)
-    sharedstatedir="$ac_optarg" ;;
-
-  -site | --site | --sit)
-    ac_prev=site ;;
-  -site=* | --site=* | --sit=*)
-    site="$ac_optarg" ;;
-
-  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
-    ac_prev=srcdir ;;
-  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
-    srcdir="$ac_optarg" ;;
-
-  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
-  | --syscon | --sysco | --sysc | --sys | --sy)
-    ac_prev=sysconfdir ;;
-  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
-  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
-    sysconfdir="$ac_optarg" ;;
-
-  -target | --target | --targe | --targ | --tar | --ta | --t)
-    ac_prev=target ;;
-  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
-    target="$ac_optarg" ;;
-
-  -v | -verbose | --verbose | --verbos | --verbo | --verb)
-    verbose=yes ;;
-
-  -version | --version | --versio | --versi | --vers)
-    echo "configure generated by autoconf version 2.13"
-    exit 0 ;;
-
-  -with-* | --with-*)
-    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
-    # Reject names that are not valid shell variable names.
-    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
-      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
-    fi
-    ac_package=`echo $ac_package| sed 's/-/_/g'`
-    case "$ac_option" in
-      *=*) ;;
-      *) ac_optarg=yes ;;
-    esac
-    eval "with_${ac_package}='$ac_optarg'" ;;
-
-  -without-* | --without-*)
-    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
-    # Reject names that are not valid shell variable names.
-    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
-      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
-    fi
-    ac_package=`echo $ac_package| sed 's/-/_/g'`
-    eval "with_${ac_package}=no" ;;
-
-  --x)
-    # Obsolete; use --with-x.
-    with_x=yes ;;
-
-  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
-  | --x-incl | --x-inc | --x-in | --x-i)
-    ac_prev=x_includes ;;
-  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
-  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
-    x_includes="$ac_optarg" ;;
-
-  -x-libraries | --x-libraries | --x-librarie | --x-librari \
-  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
-    ac_prev=x_libraries ;;
-  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
-  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
-    x_libraries="$ac_optarg" ;;
-
-  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
-    ;;
-
-  *)
-    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
-      echo "configure: warning: $ac_option: invalid host type" 1>&2
-    fi
-    if test "x$nonopt" != xNONE; then
-      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
-    fi
-    nonopt="$ac_option"
-    ;;
-
-  esac
-done
-
-if test -n "$ac_prev"; then
-  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
-fi
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-# File descriptor usage:
-# 0 standard input
-# 1 file creation
-# 2 errors and warnings
-# 3 some systems may open it to /dev/tty
-# 4 used on the Kubota Titan
-# 6 checking for... messages and results
-# 5 compiler messages saved in config.log
-if test "$silent" = yes; then
-  exec 6>/dev/null
-else
-  exec 6>&1
-fi
-exec 5>./config.log
-
-echo "\
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-" 1>&5
-
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Also quote any args containing shell metacharacters.
-ac_configure_args=
-for ac_arg
-do
-  case "$ac_arg" in
-  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
-  | --no-cr | --no-c) ;;
-  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
-  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
-  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
-  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
-  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
-  esac
-done
-
-# NLS nuisances.
-# Only set these to C if already set.  These must not be set unconditionally
-# because not all systems understand e.g. LANG=C (notably SCO).
-# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
-# Non-C LC_CTYPE values break the ctype check.
-if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
-if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
-if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo > confdefs.h
-
-# A filename unique to this package, relative to the directory that
-# configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=aclocal.m4
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
-  ac_srcdir_defaulted=yes
-  # Try the directory containing this script, then its parent.
-  ac_prog=$0
-  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
-  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
-  srcdir=$ac_confdir
-  if test ! -r $srcdir/$ac_unique_file; then
-    srcdir=..
-  fi
-else
-  ac_srcdir_defaulted=no
-fi
-if test ! -r $srcdir/$ac_unique_file; then
-  if test "$ac_srcdir_defaulted" = yes; then
-    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
-  else
-    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
-  fi
-fi
-srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
-
-# Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
-  if test "x$prefix" != xNONE; then
-    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
-  else
-    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
-  fi
-fi
-for ac_site_file in $CONFIG_SITE; do
-  if test -r "$ac_site_file"; then
-    echo "loading site script $ac_site_file"
-    . "$ac_site_file"
-  fi
-done
-
-if test -r "$cache_file"; then
-  echo "loading cache $cache_file"
-  . $cache_file
-else
-  echo "creating cache $cache_file"
-  > $cache_file
-fi
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-ac_exeext=
-ac_objext=o
-if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
-  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
-  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
-    ac_n= ac_c='
-' ac_t='	'
-  else
-    ac_n=-n ac_c= ac_t=
-  fi
-else
-  ac_n= ac_c='\c' ac_t=
-fi
-
-
-ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
-  if test -f $ac_dir/install-sh; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f $ac_dir/install.sh; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  fi
-done
-if test -z "$ac_aux_dir"; then
-  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
-fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
-
-am__api_version="1.4"
-# Find a good install program.  We prefer a C program (faster),
-# so one script is as good as another.  But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# ./install, which can be erroneously created by make from ./install.sh.
-echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:565: checking for a BSD compatible install" >&5
-if test -z "$INSTALL"; then
-if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-    IFS="${IFS= 	}"; ac_save_IFS="$IFS"; IFS=":"
-  for ac_dir in $PATH; do
-    # Account for people who put trailing slashes in PATH elements.
-    case "$ac_dir/" in
-    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
-    *)
-      # OSF1 and SCO ODT 3.0 have their own names for install.
-      # Don't use installbsd from OSF since it installs stuff as root
-      # by default.
-      for ac_prog in ginstall scoinst install; do
-        if test -f $ac_dir/$ac_prog; then
-	  if test $ac_prog = install &&
-            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
-	    # AIX install.  It has an incompatible calling convention.
-	    :
-	  else
-	    ac_cv_path_install="$ac_dir/$ac_prog -c"
-	    break 2
-	  fi
-	fi
-      done
-      ;;
-    esac
-  done
-  IFS="$ac_save_IFS"
-
-fi
-  if test "${ac_cv_path_install+set}" = set; then
-    INSTALL="$ac_cv_path_install"
-  else
-    # As a last resort, use the slow shell script.  We don't cache a
-    # path for INSTALL within a source directory, because that will
-    # break other packages using the cache if that directory is
-    # removed, or if the path is relative.
-    INSTALL="$ac_install_sh"
-  fi
-fi
-echo "$ac_t""$INSTALL" 1>&6
-
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-
-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
-
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
-echo "configure:618: checking whether build environment is sane" >&5
-# Just in case
-sleep 1
-echo timestamp > conftestfile
-# Do `set' in a subshell so we don't clobber the current shell's
-# arguments.  Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
-   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
-   if test "$*" = "X"; then
-      # -L didn't work.
-      set X `ls -t $srcdir/configure conftestfile`
-   fi
-   if test "$*" != "X $srcdir/configure conftestfile" \
-      && test "$*" != "X conftestfile $srcdir/configure"; then
-
-      # If neither matched, then we have a broken ls.  This can happen
-      # if, for instance, CONFIG_SHELL is bash and it inherits a
-      # broken ls alias from the environment.  This has actually
-      # happened.  Such a system could not be considered "sane".
-      { echo "configure: error: ls -t appears to fail.  Make sure there is not a broken
-alias in your environment" 1>&2; exit 1; }
-   fi
-
-   test "$2" = conftestfile
-   )
-then
-   # Ok.
-   :
-else
-   { echo "configure: error: newly created file is older than distributed files!
-Check your system clock" 1>&2; exit 1; }
-fi
-rm -f conftest*
-echo "$ac_t""yes" 1>&6
-if test "$program_transform_name" = s,x,x,; then
-  program_transform_name=
-else
-  # Double any \ or $.  echo might interpret backslashes.
-  cat <<\EOF_SED > conftestsed
-s,\\,\\\\,g; s,\$,$$,g
-EOF_SED
-  program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
-  rm -f conftestsed
-fi
-test "$program_prefix" != NONE &&
-  program_transform_name="s,^,${program_prefix},; $program_transform_name"
-# Use a double $ so make ignores it.
-test "$program_suffix" != NONE &&
-  program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
-
-# sed with no file args requires a program.
-test "$program_transform_name" = "" && program_transform_name="s,x,x,"
-
-echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:675: checking whether ${MAKE-make} sets \${MAKE}" >&5
-set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftestmake <<\EOF
-all:
-	@echo 'ac_maketemp="${MAKE}"'
-EOF
-# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
-eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
-if test -n "$ac_maketemp"; then
-  eval ac_cv_prog_make_${ac_make}_set=yes
-else
-  eval ac_cv_prog_make_${ac_make}_set=no
-fi
-rm -f conftestmake
-fi
-if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  SET_MAKE=
-else
-  echo "$ac_t""no" 1>&6
-  SET_MAKE="MAKE=${MAKE-make}"
-fi
-
-
-PACKAGE=connwrap
-
-VERSION=0.1
-
-if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
-  { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
-fi
-cat >> confdefs.h <<EOF
-#define PACKAGE "$PACKAGE"
-EOF
-
-cat >> confdefs.h <<EOF
-#define VERSION "$VERSION"
-EOF
-
-
-
-missing_dir=`cd $ac_aux_dir && pwd`
-echo $ac_n "checking for working aclocal-${am__api_version}""... $ac_c" 1>&6
-echo "configure:721: checking for working aclocal-${am__api_version}" >&5
-# Run test in a subshell; some versions of sh will print an error if
-# an executable is not found, even if stderr is redirected.
-# Redirect stdin to placate older versions of autoconf.  Sigh.
-if (aclocal-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then
-   ACLOCAL=aclocal-${am__api_version}
-   echo "$ac_t""found" 1>&6
-else
-   ACLOCAL="$missing_dir/missing aclocal-${am__api_version}"
-   echo "$ac_t""missing" 1>&6
-fi
-
-echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
-echo "configure:734: checking for working autoconf" >&5
-# Run test in a subshell; some versions of sh will print an error if
-# an executable is not found, even if stderr is redirected.
-# Redirect stdin to placate older versions of autoconf.  Sigh.
-if (autoconf --version) < /dev/null > /dev/null 2>&1; then
-   AUTOCONF=autoconf
-   echo "$ac_t""found" 1>&6
-else
-   AUTOCONF="$missing_dir/missing autoconf"
-   echo "$ac_t""missing" 1>&6
-fi
-
-echo $ac_n "checking for working automake-${am__api_version}""... $ac_c" 1>&6
-echo "configure:747: checking for working automake-${am__api_version}" >&5
-# Run test in a subshell; some versions of sh will print an error if
-# an executable is not found, even if stderr is redirected.
-# Redirect stdin to placate older versions of autoconf.  Sigh.
-if (automake-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then
-   AUTOMAKE=automake-${am__api_version}
-   echo "$ac_t""found" 1>&6
-else
-   AUTOMAKE="$missing_dir/missing automake-${am__api_version}"
-   echo "$ac_t""missing" 1>&6
-fi
-
-echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
-echo "configure:760: checking for working autoheader" >&5
-# Run test in a subshell; some versions of sh will print an error if
-# an executable is not found, even if stderr is redirected.
-# Redirect stdin to placate older versions of autoconf.  Sigh.
-if (autoheader --version) < /dev/null > /dev/null 2>&1; then
-   AUTOHEADER=autoheader
-   echo "$ac_t""found" 1>&6
-else
-   AUTOHEADER="$missing_dir/missing autoheader"
-   echo "$ac_t""missing" 1>&6
-fi
-
-echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
-echo "configure:773: checking for working makeinfo" >&5
-# Run test in a subshell; some versions of sh will print an error if
-# an executable is not found, even if stderr is redirected.
-# Redirect stdin to placate older versions of autoconf.  Sigh.
-if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
-   MAKEINFO=makeinfo
-   echo "$ac_t""found" 1>&6
-else
-   MAKEINFO="$missing_dir/missing makeinfo"
-   echo "$ac_t""missing" 1>&6
-fi
-
-
-
-# Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:790: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test -n "$RANLIB"; then
-  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_prog_RANLIB="ranlib"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
-fi
-fi
-RANLIB="$ac_cv_prog_RANLIB"
-if test -n "$RANLIB"; then
-  echo "$ac_t""$RANLIB" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-
-# Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:821: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_prog_CC="gcc"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
-  echo "$ac_t""$CC" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:851: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
-  ac_prog_rejected=no
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
-        ac_prog_rejected=yes
-	continue
-      fi
-      ac_cv_prog_CC="cc"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# -gt 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    set dummy "$ac_dir/$ac_word" "$@"
-    shift
-    ac_cv_prog_CC="$@"
-  fi
-fi
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
-  echo "$ac_t""$CC" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-  if test -z "$CC"; then
-    case "`uname -s`" in
-    *win32* | *WIN32*)
-      # Extract the first word of "cl", so it can be a program name with args.
-set dummy cl; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:902: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_prog_CC="cl"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
-  echo "$ac_t""$CC" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
- ;;
-    esac
-  fi
-  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:934: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-cat > conftest.$ac_ext << EOF
-
-#line 945 "configure"
-#include "confdefs.h"
-
-main(){return(0);}
-EOF
-if { (eval echo configure:950: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  ac_cv_prog_cc_works=yes
-  # If we can't run a trivial program, we are probably using a cross compiler.
-  if (./conftest; exit) 2>/dev/null; then
-    ac_cv_prog_cc_cross=no
-  else
-    ac_cv_prog_cc_cross=yes
-  fi
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  ac_cv_prog_cc_works=no
-fi
-rm -fr conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
-if test $ac_cv_prog_cc_works = no; then
-  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
-fi
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:976: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
-echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:981: checking whether we are using GNU C" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.c <<EOF
-#ifdef __GNUC__
-  yes;
-#endif
-EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:990: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
-  ac_cv_prog_gcc=yes
-else
-  ac_cv_prog_gcc=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc" 1>&6
-
-if test $ac_cv_prog_gcc = yes; then
-  GCC=yes
-else
-  GCC=
-fi
-
-ac_test_CFLAGS="${CFLAGS+set}"
-ac_save_CFLAGS="$CFLAGS"
-CFLAGS=
-echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:1009: checking whether ${CC-cc} accepts -g" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  echo 'void f(){}' > conftest.c
-if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
-  ac_cv_prog_cc_g=yes
-else
-  ac_cv_prog_cc_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS="$ac_save_CFLAGS"
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-
-for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
-do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1045: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test -n "$CXX"; then
-  ac_cv_prog_CXX="$CXX" # Let the user override the test.
-else
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_prog_CXX="$ac_prog"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-fi
-fi
-CXX="$ac_cv_prog_CXX"
-if test -n "$CXX"; then
-  echo "$ac_t""$CXX" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-test -n "$CXX" && break
-done
-test -n "$CXX" || CXX="gcc"
-
-
-echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1077: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
-
-ac_ext=C
-# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cxx_cross
-
-cat > conftest.$ac_ext << EOF
-
-#line 1088 "configure"
-#include "confdefs.h"
-
-int main(){return(0);}
-EOF
-if { (eval echo configure:1093: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  ac_cv_prog_cxx_works=yes
-  # If we can't run a trivial program, we are probably using a cross compiler.
-  if (./conftest; exit) 2>/dev/null; then
-    ac_cv_prog_cxx_cross=no
-  else
-    ac_cv_prog_cxx_cross=yes
-  fi
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  ac_cv_prog_cxx_works=no
-fi
-rm -fr conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
-if test $ac_cv_prog_cxx_works = no; then
-  { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
-fi
-echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1119: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
-echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
-cross_compiling=$ac_cv_prog_cxx_cross
-
-echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
-echo "configure:1124: checking whether we are using GNU C++" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.C <<EOF
-#ifdef __GNUC__
-  yes;
-#endif
-EOF
-if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1133: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
-  ac_cv_prog_gxx=yes
-else
-  ac_cv_prog_gxx=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gxx" 1>&6
-
-if test $ac_cv_prog_gxx = yes; then
-  GXX=yes
-else
-  GXX=
-fi
-
-ac_test_CXXFLAGS="${CXXFLAGS+set}"
-ac_save_CXXFLAGS="$CXXFLAGS"
-CXXFLAGS=
-echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
-echo "configure:1152: checking whether ${CXX-g++} accepts -g" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  echo 'void f(){}' > conftest.cc
-if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
-  ac_cv_prog_cxx_g=yes
-else
-  ac_cv_prog_cxx_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
-if test "$ac_test_CXXFLAGS" = set; then
-  CXXFLAGS="$ac_save_CXXFLAGS"
-elif test $ac_cv_prog_cxx_g = yes; then
-  if test "$GXX" = yes; then
-    CXXFLAGS="-g -O2"
-  else
-    CXXFLAGS="-g"
-  fi
-else
-  if test "$GXX" = yes; then
-    CXXFLAGS="-O2"
-  else
-    CXXFLAGS=
-  fi
-fi
-
-
-###
-###     SSL libs
-###
-
-# Check whether --with-ssl or --without-ssl was given.
-if test "${with_ssl+set}" = set; then
-  withval="$with_ssl"
-  with_ssl=$withval
-fi
-
-
-if test "$with_ssl" != "no"; then
-    # Check whether --with-openssl or --without-openssl was given.
-if test "${with_openssl+set}" = set; then
-  withval="$with_openssl"
-  with_openssl=$withval
-fi
-
-
-    if test -z "$with_openssl"; then
-	for ac_dir in /usr/local /usr; do
-	    if test -f "$ac_dir/include/openssl/ssl.h"; then
-		with_openssl=$ac_dir
-		break;
-	    fi
-	done
-    fi
-
-    echo $ac_n "checking for OpenSSL""... $ac_c" 1>&6
-echo "configure:1213: checking for OpenSSL" >&5
-
-    if test -n "$with_openssl" -a "$with_openssl" != "no"; then
-	if test "$with_openssl" = "yes"; then with_openssl="/usr"; fi
-	CFLAGS="$CFLAGS -I${with_openssl}"
-	cat >> confdefs.h <<\EOF
-#define HAVE_OPENSSL 1
-EOF
-
-	echo "$ac_t""found in $with_openssl" 1>&6
-	echo $ac_n "checking for main in -lcrypto""... $ac_c" 1>&6
-echo "configure:1224: checking for main in -lcrypto" >&5
-ac_lib_var=`echo crypto'_'main | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-lcrypto  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1232 "configure"
-#include "confdefs.h"
-
-int main() {
-main()
-; return 0; }
-EOF
-if { (eval echo configure:1239: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  
-		echo $ac_n "checking for SSLeay_add_all_algorithms in -lcrypto""... $ac_c" 1>&6
-echo "configure:1256: checking for SSLeay_add_all_algorithms in -lcrypto" >&5
-ac_lib_var=`echo crypto'_'SSLeay_add_all_algorithms | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-lcrypto  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1264 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
-char SSLeay_add_all_algorithms();
-
-int main() {
-SSLeay_add_all_algorithms()
-; return 0; }
-EOF
-if { (eval echo configure:1275: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  
-		    cat >> confdefs.h <<\EOF
-#define HAVE_SSLEAY 1
-EOF
-
-		
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-	    
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-	echo $ac_n "checking for main in -lssl""... $ac_c" 1>&6
-echo "configure:1306: checking for main in -lssl" >&5
-ac_lib_var=`echo ssl'_'main | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-lssl  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1314 "configure"
-#include "confdefs.h"
-
-int main() {
-main()
-; return 0; }
-EOF
-if { (eval echo configure:1321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo ssl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
-    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
-  LIBS="-lssl $LIBS"
-
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-    else
-	echo "$ac_t""not found or disabled" 1>&6
-
-	# Check whether --with-libgnutls-extra-prefix or --without-libgnutls-extra-prefix was given.
-if test "${with_libgnutls_extra_prefix+set}" = set; then
-  withval="$with_libgnutls_extra_prefix"
-  libgnutls_extra_config_prefix="$withval"
-else
-  libgnutls_extra_config_prefix=""
-fi
-
-
-  if test x$libgnutls_extra_config_prefix != x ; then
-     libgnutls_extra_config_args="$libgnutls_extra_config_args --prefix=$libgnutls_extra_config_prefix"
-     if test x${LIBGNUTLS_EXTRA_CONFIG+set} != xset ; then
-        LIBGNUTLS_EXTRA_CONFIG=$libgnutls_extra_config_prefix/bin/libgnutls-extra-config
-     fi
-  fi
-
-  # Extract the first word of "libgnutls-extra-config", so it can be a program name with args.
-set dummy libgnutls-extra-config; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1370: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_LIBGNUTLS_EXTRA_CONFIG'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  case "$LIBGNUTLS_EXTRA_CONFIG" in
-  /*)
-  ac_cv_path_LIBGNUTLS_EXTRA_CONFIG="$LIBGNUTLS_EXTRA_CONFIG" # Let the user override the test with a path.
-  ;;
-  ?:/*)			 
-  ac_cv_path_LIBGNUTLS_EXTRA_CONFIG="$LIBGNUTLS_EXTRA_CONFIG" # Let the user override the test with a dos path.
-  ;;
-  *)
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do 
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_path_LIBGNUTLS_EXTRA_CONFIG="$ac_dir/$ac_word"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-  test -z "$ac_cv_path_LIBGNUTLS_EXTRA_CONFIG" && ac_cv_path_LIBGNUTLS_EXTRA_CONFIG="no"
-  ;;
-esac
-fi
-LIBGNUTLS_EXTRA_CONFIG="$ac_cv_path_LIBGNUTLS_EXTRA_CONFIG"
-if test -n "$LIBGNUTLS_EXTRA_CONFIG"; then
-  echo "$ac_t""$LIBGNUTLS_EXTRA_CONFIG" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-  min_libgnutls_version=0.0.1
-  echo $ac_n "checking for libgnutls - version >= $min_libgnutls_version""... $ac_c" 1>&6
-echo "configure:1405: checking for libgnutls - version >= $min_libgnutls_version" >&5
-  no_libgnutls=""
-  if test "$LIBGNUTLS_EXTRA_CONFIG" = "no" ; then
-    no_libgnutls=yes
-  else
-    LIBGNUTLS_EXTRA_CFLAGS=`$LIBGNUTLS_EXTRA_CONFIG $libgnutls_extra_config_args --cflags`
-    LIBGNUTLS_EXTRA_LIBS=`$LIBGNUTLS_EXTRA_CONFIG $libgnutls_extra_config_args --libs`
-    libgnutls_extra_config_version=`$LIBGNUTLS_EXTRA_CONFIG $libgnutls_extra_config_args --version`
-
-
-      ac_save_CFLAGS="$CFLAGS"
-      ac_save_LIBS="$LIBS"
-      CFLAGS="$CFLAGS $LIBGNUTLS_EXTRA_CFLAGS"
-      LIBS="$LIBS $LIBGNUTLS_EXTRA_LIBS"
-      rm -f conf.libgnutlstest
-      if test "$cross_compiling" = yes; then
-  echo $ac_n "cross compiling; assumed OK... $ac_c"
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1424 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <gnutls/extra.h>
-
-int
-main ()
-{
-    system ("touch conf.libgnutlstest");
-
-    if( strcmp( gnutls_extra_check_version(NULL), "$libgnutls_extra_config_version" ) )
-    {
-      printf("\n*** 'libgnutls-extra-config --version' returned %s, but LIBGNUTLS_EXTRA (%s)\n",
-             "$libgnutls_extra_config_version", gnutls_extra_check_version(NULL) );
-      printf("*** was found! If libgnutls-extra-config was correct, then it is best\n");
-      printf("*** to remove the old version of LIBGNUTLS_EXTRA. You may also be able to fix the error\n");
-      printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
-      printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
-      printf("*** required on your system.\n");
-      printf("*** If libgnutls-extra-config was wrong, set the environment variable LIBGNUTLS_EXTRA_CONFIG\n");
-      printf("*** to point to the correct copy of libgnutls-extra-config, and remove the file config.cache\n");
-      printf("*** before re-running configure\n");
-    }
-    else if ( strcmp(gnutls_extra_check_version(NULL), LIBGNUTLS_EXTRA_VERSION ) )
-    {
-      printf("\n*** LIBGNUTLS_EXTRA header file (version %s) does not match\n", LIBGNUTLS_EXTRA_VERSION);
-      printf("*** library (version %s). This is may be due to a different version of gnutls\n", gnutls_extra_check_version(NULL) );
-      printf("*** and gnutls-extra.\n");
-    }
-    else
-    {
-      if ( gnutls_extra_check_version( "$min_libgnutls_version" ) )
-      {
-        return 0;
-      }
-     else
-      {
-        printf("no\n*** An old version of LIBGNUTLS_EXTRA (%s) was found.\n",
-                gnutls_extra_check_version(NULL) );
-        printf("*** You need a version of LIBGNUTLS_EXTRA newer than %s. The latest version of\n",
-               "$min_libgnutls_version" );
-        printf("*** LIBGNUTLS_EXTRA is always available from ftp://gnutls.hellug.gr/pub/gnutls.\n");
-        printf("*** \n");
-        printf("*** If you have already installed a sufficiently new version, this error\n");
-        printf("*** probably means that the wrong copy of the libgnutls-extra-config shell script is\n");
-        printf("*** being found. The easiest way to fix this is to remove the old version\n");
-        printf("*** of LIBGNUTLS_EXTRA, but you can also set the LIBGNUTLS_EXTRA_CONFIG environment to point to the\n");
-        printf("*** correct copy of libgnutls-extra-config. (In this case, you will have to\n");
-        printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
-        printf("*** so that the correct libraries are found at run-time))\n");
-      }
-    }
-  return 1;
-}
-
-EOF
-if { (eval echo configure:1483: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
-  :
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -fr conftest*
-  no_libgnutls=yes
-fi
-rm -fr conftest*
-fi
-
-       CFLAGS="$ac_save_CFLAGS"
-       LIBS="$ac_save_LIBS"
-  fi
-
-  if test "x$no_libgnutls" = x ; then
-     echo "$ac_t""yes" 1>&6
-     
-	    CXXFLAGS="$CXXFLAGS $LIBGNUTLS_CFLAGS"
-	    LIBS="$LIBS $LIBGNUTLS_LIBS -lgnutls-extra"
-	    cat >> confdefs.h <<\EOF
-#define HAVE_GNUTLS 1
-EOF
-
-	
-  else
-     if test -f conf.libgnutlstest ; then
-        :
-     else
-        echo "$ac_t""no" 1>&6
-     fi
-     if test "$LIBGNUTLS_EXTRA_CONFIG" = "no" ; then
-       echo "*** The libgnutls-extra-config script installed by LIBGNUTLS_EXTRA could not be found"
-       echo "*** If LIBGNUTLS_EXTRA was installed in PREFIX, make sure PREFIX/bin is in"
-       echo "*** your path, or set the LIBGNUTLS_EXTRA_CONFIG environment variable to the"
-       echo "*** full path to libgnutls-extra-config."
-     else
-       if test -f conf.libgnutlstest ; then
-        :
-       else
-          echo "*** Could not run libgnutls test program, checking why..."
-          CFLAGS="$CFLAGS $LIBGNUTLS_EXTRA_CFLAGS"
-          LIBS="$LIBS $LIBGNUTLS_EXTRA_LIBS"
-          cat > conftest.$ac_ext <<EOF
-#line 1528 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <gnutls/extra.h>
-
-int main() {
- return !!gnutls_extra_check_version(NULL); 
-; return 0; }
-EOF
-if { (eval echo configure:1540: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  rm -rf conftest*
-   echo "*** The test program compiled, but did not run. This usually means"
-          echo "*** that the run-time linker is not finding LIBGNUTLS_EXTRA or finding the wrong"
-          echo "*** version of LIBGNUTLS_EXTRA. If it is not finding LIBGNUTLS_EXTRA, you'll need to set your"
-          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
-          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
-          echo "*** is required on your system"
-          echo "***"
-          echo "*** If you have an old version installed, it is best to remove it, although"
-          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
-          echo "***" 
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-   echo "*** The test program failed to compile or link. See the file config.log for the"
-          echo "*** exact error that occured. This usually means LIBGNUTLS_EXTRA was incorrectly installed"
-          echo "*** or that you have moved LIBGNUTLS_EXTRA since it was installed. In the latter case, you"
-          echo "*** may want to edit the libgnutls-extra-config script: $LIBGNUTLS_EXTRA_CONFIG" 
-fi
-rm -f conftest*
-          CFLAGS="$ac_save_CFLAGS"
-          LIBS="$ac_save_LIBS"
-       fi
-     fi
-     LIBGNUTLS_EXTRA_CFLAGS=""
-     LIBGNUTLS_EXTRA_LIBS=""
-     :
-  fi
-  rm -f conf.libgnutlstest
-  
-  
-
-    fi
-fi
-
-echo $ac_n "checking for inet_aton() presence""... $ac_c" 1>&6
-echo "configure:1578: checking for inet_aton() presence" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 1581 "configure"
-#include "confdefs.h"
-
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-
-int main() {
-
-
-struct in_addr inp;
-inet_aton("address", &inp);
-
-
-; return 0; }
-EOF
-if { (eval echo configure:1600: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  rm -rf conftest*
-  have_aton=yes
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  have_aton=no
-fi
-rm -f conftest*
-
-if test "$have_aton" = "yes"; then
-    cat >> confdefs.h <<\EOF
-#define HAVE_INET_ATON 1
-EOF
-
-    echo "$ac_t""yes" 1>&6
-else
-    echo "$ac_t""no" 1>&6
-fi
-
-trap '' 1 2 15
-cat > confcache <<\EOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs.  It is not useful on other systems.
-# If it contains results you don't want to keep, you may remove or edit it.
-#
-# By default, configure uses ./config.cache as the cache file,
-# creating it if it does not exist already.  You can give configure
-# the --cache-file=FILE option to use a different cache file; that is
-# what configure does when it calls configure scripts in
-# subdirectories, so they share the cache.
-# Giving --cache-file=/dev/null disables caching, for debugging configure.
-# config.status only pays attention to the cache file if you give it the
-# --recheck option to rerun configure.
-#
-EOF
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, don't put newlines in cache variables' values.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(set) 2>&1 |
-  case `(ac_space=' '; set | grep ac_space) 2>&1` in
-  *ac_space=\ *)
-    # `set' does not quote correctly, so add quotes (double-quote substitution
-    # turns \\\\ into \\, and sed turns \\ into \).
-    sed -n \
-      -e "s/'/'\\\\''/g" \
-      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
-    ;;
-  *)
-    # `set' quotes correctly as required by POSIX, so do not add quotes.
-    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
-    ;;
-  esac >> confcache
-if cmp -s $cache_file confcache; then
-  :
-else
-  if test -w $cache_file; then
-    echo "updating cache $cache_file"
-    cat confcache > $cache_file
-  else
-    echo "not updating unwritable cache $cache_file"
-  fi
-fi
-rm -f confcache
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-# Any assignment to VPATH causes Sun make to only execute
-# the first set of double-colon rules, so remove it if not needed.
-# If there is a colon in the path, we need to keep it.
-if test "x$srcdir" = x.; then
-  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
-fi
-
-trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
-
-# Transform confdefs.h into DEFS.
-# Protect against shell expansion while executing Makefile rules.
-# Protect against Makefile macro expansion.
-cat > conftest.defs <<\EOF
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
-s%[ 	`~#$^&*(){}\\|;'"<>?]%\\&%g
-s%\[%\\&%g
-s%\]%\\&%g
-s%\$%$$%g
-EOF
-DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
-rm -f conftest.defs
-
-
-# Without the "./", some shells look in PATH for config.status.
-: ${CONFIG_STATUS=./config.status}
-
-echo creating $CONFIG_STATUS
-rm -f $CONFIG_STATUS
-cat > $CONFIG_STATUS <<EOF
-#! /bin/sh
-# Generated automatically by configure.
-# Run this file to recreate the current configuration.
-# This directory was configured as follows,
-# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-#
-# $0 $ac_configure_args
-#
-# Compiler output produced by configure, useful for debugging
-# configure, is in ./config.log if it exists.
-
-ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
-for ac_option
-do
-  case "\$ac_option" in
-  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
-    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
-    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
-    echo "$CONFIG_STATUS generated by autoconf version 2.13"
-    exit 0 ;;
-  -help | --help | --hel | --he | --h)
-    echo "\$ac_cs_usage"; exit 0 ;;
-  *) echo "\$ac_cs_usage"; exit 1 ;;
-  esac
-done
-
-ac_given_srcdir=$srcdir
-ac_given_INSTALL="$INSTALL"
-
-trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-# Protect against being on the right side of a sed subst in config.status.
-sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
- s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
-$ac_vpsub
-$extrasub
-s%@SHELL@%$SHELL%g
-s%@CFLAGS@%$CFLAGS%g
-s%@CPPFLAGS@%$CPPFLAGS%g
-s%@CXXFLAGS@%$CXXFLAGS%g
-s%@FFLAGS@%$FFLAGS%g
-s%@DEFS@%$DEFS%g
-s%@LDFLAGS@%$LDFLAGS%g
-s%@LIBS@%$LIBS%g
-s%@exec_prefix@%$exec_prefix%g
-s%@prefix@%$prefix%g
-s%@program_transform_name@%$program_transform_name%g
-s%@bindir@%$bindir%g
-s%@sbindir@%$sbindir%g
-s%@libexecdir@%$libexecdir%g
-s%@datadir@%$datadir%g
-s%@sysconfdir@%$sysconfdir%g
-s%@sharedstatedir@%$sharedstatedir%g
-s%@localstatedir@%$localstatedir%g
-s%@libdir@%$libdir%g
-s%@includedir@%$includedir%g
-s%@oldincludedir@%$oldincludedir%g
-s%@infodir@%$infodir%g
-s%@mandir@%$mandir%g
-s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
-s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
-s%@INSTALL_DATA@%$INSTALL_DATA%g
-s%@PACKAGE@%$PACKAGE%g
-s%@VERSION@%$VERSION%g
-s%@ACLOCAL@%$ACLOCAL%g
-s%@AUTOCONF@%$AUTOCONF%g
-s%@AUTOMAKE@%$AUTOMAKE%g
-s%@AUTOHEADER@%$AUTOHEADER%g
-s%@MAKEINFO@%$MAKEINFO%g
-s%@SET_MAKE@%$SET_MAKE%g
-s%@RANLIB@%$RANLIB%g
-s%@CC@%$CC%g
-s%@CXX@%$CXX%g
-s%@LIBGNUTLS_EXTRA_CONFIG@%$LIBGNUTLS_EXTRA_CONFIG%g
-s%@LIBGNUTLS_EXTRA_CFLAGS@%$LIBGNUTLS_EXTRA_CFLAGS%g
-s%@LIBGNUTLS_EXTRA_LIBS@%$LIBGNUTLS_EXTRA_LIBS%g
-
-CEOF
-EOF
-
-cat >> $CONFIG_STATUS <<\EOF
-
-# Split the substitutions into bite-sized pieces for seds with
-# small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
-ac_file=1 # Number of current file.
-ac_beg=1 # First line for current file.
-ac_end=$ac_max_sed_cmds # Line after last line for current file.
-ac_more_lines=:
-ac_sed_cmds=""
-while $ac_more_lines; do
-  if test $ac_beg -gt 1; then
-    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
-  else
-    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
-  fi
-  if test ! -s conftest.s$ac_file; then
-    ac_more_lines=false
-    rm -f conftest.s$ac_file
-  else
-    if test -z "$ac_sed_cmds"; then
-      ac_sed_cmds="sed -f conftest.s$ac_file"
-    else
-      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
-    fi
-    ac_file=`expr $ac_file + 1`
-    ac_beg=$ac_end
-    ac_end=`expr $ac_end + $ac_max_sed_cmds`
-  fi
-done
-if test -z "$ac_sed_cmds"; then
-  ac_sed_cmds=cat
-fi
-EOF
-
-cat >> $CONFIG_STATUS <<EOF
-
-CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
-  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
-  case "$ac_file" in
-  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
-       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
-  *) ac_file_in="${ac_file}.in" ;;
-  esac
-
-  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
-
-  # Remove last slash and all that follows it.  Not all systems have dirname.
-  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
-  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
-    # The file is in a subdirectory.
-    test ! -d "$ac_dir" && mkdir "$ac_dir"
-    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
-    # A "../" for each directory in $ac_dir_suffix.
-    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
-  else
-    ac_dir_suffix= ac_dots=
-  fi
-
-  case "$ac_given_srcdir" in
-  .)  srcdir=.
-      if test -z "$ac_dots"; then top_srcdir=.
-      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
-  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
-  *) # Relative path.
-    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
-    top_srcdir="$ac_dots$ac_given_srcdir" ;;
-  esac
-
-  case "$ac_given_INSTALL" in
-  [/$]*) INSTALL="$ac_given_INSTALL" ;;
-  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
-  esac
-
-  echo creating "$ac_file"
-  rm -f "$ac_file"
-  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
-  case "$ac_file" in
-  *Makefile*) ac_comsub="1i\\
-# $configure_input" ;;
-  *) ac_comsub= ;;
-  esac
-
-  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
-  sed -e "$ac_comsub
-s%@configure_input@%$configure_input%g
-s%@srcdir@%$srcdir%g
-s%@top_srcdir@%$top_srcdir%g
-s%@INSTALL@%$INSTALL%g
-" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
-fi; done
-rm -f conftest.s*
-
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-
-exit 0
-EOF
-chmod +x $CONFIG_STATUS
-rm -fr confdefs* $ac_clean_files
-test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
-
--- a/mcabber/connwrap/configure.in	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-AC_INIT(aclocal.m4)
-AM_INIT_AUTOMAKE(connwrap, 0.1)
-
-AC_PROG_RANLIB
-
-AC_PROG_CC
-AC_PROG_CXX
-
-###
-###     SSL libs
-###
-
-AC_ARG_WITH(ssl, [  --with-ssl              enable SSL secured connections using either OpenSSL
-			  or GnuTLS],
-	[with_ssl=$withval])
-
-if test "$with_ssl" != "no"; then
-    AC_ARG_WITH(openssl,
-	[  --with-openssl=[DIR]    enable SSL secured connections using the OpenSSL
-			  library in DIR (optional)],
-	[with_openssl=$withval])
-
-    if test -z "$with_openssl"; then
-	for ac_dir in /usr/local /usr; do
-	    if test -f "$ac_dir/include/openssl/ssl.h"; then
-		with_openssl=$ac_dir
-		break;
-	    fi
-	done
-    fi
-
-    AC_MSG_CHECKING(for OpenSSL)
-
-    if test -n "$with_openssl" -a "$with_openssl" != "no"; then
-	if test "$with_openssl" = "yes"; then with_openssl="/usr"; fi
-	CFLAGS="$CFLAGS -I${with_openssl}"
-	AC_DEFINE(HAVE_OPENSSL)
-	AC_MSG_RESULT([found in $with_openssl])
-	AC_CHECK_LIB(crypto, main, [
-		AC_CHECK_LIB(crypto, SSLeay_add_all_algorithms, [
-		    AC_DEFINE(HAVE_SSLEAY)
-		])
-	    ])
-	AC_CHECK_LIB(ssl, main)
-    else
-	AC_MSG_RESULT([not found or disabled])
-
-	AM_PATH_LIBGNUTLS_EXTRA(0.0.1, [
-	    CXXFLAGS="$CXXFLAGS $LIBGNUTLS_CFLAGS"
-	    LIBS="$LIBS $LIBGNUTLS_LIBS -lgnutls-extra"
-	    AC_DEFINE(HAVE_GNUTLS)
-	])
-    fi
-fi
-
-AC_MSG_CHECKING(for inet_aton() presence)
-
-AC_TRY_LINK([
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-], [
-
-struct in_addr inp;
-inet_aton("address", &inp);
-
-], have_aton=yes, have_aton=no)
-
-if test "$have_aton" = "yes"; then
-    AC_DEFINE(HAVE_INET_ATON)
-    AC_MSG_RESULT(yes)
-else
-    AC_MSG_RESULT(no)
-fi
-
-AC_OUTPUT(Makefile)
--- a/mcabber/connwrap/connwrap.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,641 +0,0 @@
-#include "connwrap.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <netdb.h>
-#include <string.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <unistd.h>
-
-#define PROXY_TIMEOUT   10
-    // HTTP proxy timeout in seconds (for the CONNECT method)
-
-#ifdef HAVE_OPENSSL
-# define OPENSSL_NO_KRB5 1
-# include <openssl/ssl.h>
-# include <openssl/err.h>
-# define HAVE_SSL
-# undef HAVE_GNUTLS // Can't use both...
-#elif defined HAVE_GNUTLS
-# include <gnutls/gnutls.h>
-# define HAVE_SSL
-#endif
-
-static int in_http_connect = 0;
-
-#ifdef HAVE_OPENSSL
-static SSL_CTX *ctx = NULL;
-typedef struct { int fd; SSL *ssl; } sslsock;
-#elif defined HAVE_GNUTLS
-typedef struct { int fd; gnutls_session_t session; } sslsock;
-#endif
-
-
-#ifdef HAVE_SSL
-
-/* verify > 0 indicates verify depth as well */
-static int verify = -1;
-static const char *cafile = NULL;
-static const char *capath = NULL;
-static const char *cipherlist = NULL;
-static const char *peer = NULL;
-static const char *sslerror = NULL;
-
-#ifdef HAVE_OPENSSL
-static int verify_cb(int preverify_ok, X509_STORE_CTX *cx)
-{
-    X509 *cert;
-    X509_NAME *nm;
-    int lastpos;
-
-    if(!preverify_ok) {
-	long err = X509_STORE_CTX_get_error(cx);
-
-	sslerror = X509_verify_cert_error_string(err);
-	return 0;
-    }
-
-    if (peer == NULL)
-	return 1;
-
-    if ((cert = X509_STORE_CTX_get_current_cert(cx)) == NULL) {
-	sslerror = "internal SSL error";
-	return 0;
-    }
-
-    /* We only want to look at the peername if we're working on the peer
-     * certificate. */
-    if (cert != cx->cert)
-	return 1;
-
-    if ((nm = X509_get_subject_name (cert)) == NULL) {
-	sslerror = "internal SSL error";
-	return 0;
-    }
-
-    for(lastpos = -1; ; ) {
-	X509_NAME_ENTRY *e;
-	ASN1_STRING *a;
-	ASN1_STRING *p;
-	int match;
-
-        lastpos = X509_NAME_get_index_by_NID(nm, NID_commonName, lastpos);
-	if (lastpos == -1)
-	    break;
-	if ((e = X509_NAME_get_entry(nm, lastpos)) == NULL) {
-	    sslerror = "internal SSL error";
-	    return 0;
-	}
-	if ((a = X509_NAME_ENTRY_get_data(e)) == NULL) {
-	    sslerror = "internal SSL error";
-	    return 0;
-	}
-	if ((p = ASN1_STRING_type_new(ASN1_STRING_type(a))) == NULL) {
-	    sslerror = "internal SSL error";
-	    return 0;
-	}
-	(void) ASN1_STRING_set(p, peer, -1);
-	match = !ASN1_STRING_cmp(a, p);
-	ASN1_STRING_free(p);
-	if(match)
-	    return 1;
-    }
-
-    sslerror = "server certificate cn mismatch";
-    return 0;
-}
-#endif
-
-static void init(int fd, sslsock *p) {
-#ifdef HAVE_GNUTLS
-    gnutls_certificate_credentials_t xcred;
-#endif
-
-#ifdef HAVE_OPENSSL
-    if(ctx)
-	return;
-    SSL_library_init();
-    SSL_load_error_strings();
-
-#ifdef HAVE_SSLEAY
-    SSLeay_add_all_algorithms();
-#else
-    OpenSSL_add_all_algorithms();
-#endif
-
-    /* May need to use distinct SSLEAY bindings below... */
-
-    ctx = SSL_CTX_new(SSLv23_client_method());
-    if(cipherlist)
-	(void)SSL_CTX_set_cipher_list(ctx, cipherlist);
-    if(cafile || capath)
-	(void)SSL_CTX_load_verify_locations(ctx, cafile, capath);
-    if(verify) {
-	SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_cb);
-	if(verify > 0)
-	    SSL_CTX_set_verify_depth(ctx, verify);
-    } else
-	SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
-
-    p->ssl = SSL_new(ctx);
-    SSL_set_fd(p->ssl, p->fd = fd);
-
-#elif defined HAVE_GNUTLS
-    gnutls_global_init();
-    gnutls_certificate_allocate_credentials(&xcred);
-    gnutls_init(&(p->session), GNUTLS_CLIENT);
-    gnutls_set_default_priority(p->session);
-    gnutls_credentials_set(p->session, GNUTLS_CRD_CERTIFICATE, xcred);
-    p->fd = fd;
-    gnutls_transport_set_ptr(p->session,(gnutls_transport_ptr_t)fd);
-#endif
-}
-
-static sslsock *socks = NULL;
-static int sockcount = 0;
-
-static sslsock *getsock(int fd) {
-    int i;
-
-    for(i = 0; i < sockcount; i++)
-	if(socks[i].fd == fd)
-	    return &socks[i];
-
-    return NULL;
-}
-
-static sslsock *addsock(int fd) {
-    sslsock *p;
-
-    sockcount++;
-
-    if (socks)
-	socks = (sslsock *) realloc(socks, sizeof(sslsock)*sockcount);
-    else
-	socks = (sslsock *) malloc(sizeof(sslsock)*sockcount);
-
-    p = &socks[sockcount-1];
-
-    init(fd, p);
-
-    sslerror = NULL;
-
-    return p;
-}
-
-static void delsock(int fd) {
-    int i, nsockcount;
-    sslsock *nsocks;
-
-    nsockcount = 0;
-
-    if (sockcount > 1) {
-	nsocks = (sslsock *) malloc(sizeof(sslsock)*(sockcount-1));
-
-	for(i = 0; i < sockcount; i++) {
-	    if(socks[i].fd != fd) {
-		nsocks[nsockcount++] = socks[i];
-	    } else {
-#ifdef HAVE_OPENSSL
-		SSL_free(socks[i].ssl);
-#elif defined HAVE_GNUTLS
-		gnutls_bye(socks[i].session, GNUTLS_SHUT_WR);
-		gnutls_deinit(socks[i].session);
-#endif
-	    }
-	}
-
-    } else {
-#ifdef HAVE_OPENSSL
-	if (ctx)
-	    SSL_CTX_free(ctx);
-	ctx = 0;
-#endif
-	nsocks = NULL;
-    }
-
-    if (socks)
-	free(socks);
-    socks = nsocks;
-    sockcount = nsockcount;
-}
-
-void cw_set_ssl_options(int sslverify,
-                        const char *sslcafile, const char *sslcapath,
-                        const char *sslciphers, const char *sslpeer) {
-    verify = sslverify;
-    cafile = sslcafile;
-    capath = sslcapath;
-    cipherlist = sslciphers;
-    peer = sslpeer;
-}
-
-const char *cw_get_ssl_error(void) {
-    return sslerror;
-}
-
-#else // HAVE_SSL
-
-void cw_set_ssl_options(int sslverify,
-                        const char *sslcafile, const char *sslcapath,
-                        const char *sslciphers, const char *sslpeer) { }
-
-const char *cw_get_ssl_error(void) {
-    return NULL;
-}
-
-#endif // HAVE_SSL
-
-static char *bindaddr = 0, *proxyhost = 0, *proxyuser = 0, *proxypass = 0;
-static int proxyport = 3128;
-static int proxy_ssl = 0;
-
-#define SOCKOUT(s) write(sockfd, s, strlen(s))
-
-int cw_http_connect(int sockfd, const struct sockaddr *serv_addr, int addrlen) {
-    int err, pos, fl;
-    struct hostent *server;
-    struct sockaddr_in paddr;
-    char buf[512];
-    fd_set rfds;
-
-    fl = 0;
-    err = 0;
-    in_http_connect = 1;
-
-    if(!(server = gethostbyname(proxyhost))) {
-	errno = h_errno;
-	err = -1;
-    }
-
-    if(!err) {
-	memset(&paddr, 0, sizeof(paddr));
-	paddr.sin_family = AF_INET;
-	memcpy(&paddr.sin_addr.s_addr, *server->h_addr_list, server->h_length);
-	paddr.sin_port = htons(proxyport);
-
-	fl = fcntl(sockfd, F_GETFL);
-	fcntl(sockfd, F_SETFL, fl & ~O_NONBLOCK);
-
-	buf[0] = 0;
-
-	err = cw_connect(sockfd, (struct sockaddr *) &paddr, sizeof(paddr),
-	                 proxy_ssl);
-    }
-
-    errno = ECONNREFUSED;
-
-    if(!err) {
-	struct sockaddr_in *sin = (struct sockaddr_in *) serv_addr;
-	char *ip = inet_ntoa(sin->sin_addr), c;
-	struct timeval tv;
-
-	snprintf(buf, sizeof(buf), "%d", ntohs(sin->sin_port));
-	SOCKOUT("CONNECT ");
-	SOCKOUT(ip);
-	SOCKOUT(":");
-	SOCKOUT(buf);
-	SOCKOUT(" HTTP/1.0\r\n");
-
-	if(proxyuser) {
-	    char *b;
-	    SOCKOUT("Proxy-Authorization: Basic ");
-
-	    snprintf(buf, sizeof(buf), "%s:%s", proxyuser, proxypass);
-	    b = cw_base64_encode(buf);
-	    SOCKOUT(b);
-	    free(b);
-
-	    SOCKOUT("\r\n");
-	}
-
-	SOCKOUT("\r\n");
-
-	buf[0] = 0;
-
-	while(err != -1) {
-	    FD_ZERO(&rfds);
-	    FD_SET(sockfd, &rfds);
-
-	    tv.tv_sec = PROXY_TIMEOUT;
-	    tv.tv_usec = 0;
-
-	    err = select(sockfd+1, &rfds, 0, 0, &tv);
-
-	    if(err < 1) err = -1;
-
-	    if(err != -1 && FD_ISSET(sockfd, &rfds)) {
-		err = read(sockfd, &c, 1);
-		if(!err) err = -1;
-
-		if(err != -1) {
-		    pos = strlen(buf);
-		    buf[pos] = c;
-		    buf[pos+1] = 0;
-
-		    if(strlen(buf) > 4)
-		    if(!strcmp(buf+strlen(buf)-4, "\r\n\r\n"))
-			break;
-		}
-	    }
-	}
-    }
-
-    if(err != -1 && strlen(buf)) {
-	char *p = strstr(buf, " ");
-
-	err = -1;
-
-	if(p)
-	if(atoi(++p) == 200)
-	    err = 0;
-
-	fcntl(sockfd, F_SETFL, fl);
-	if(fl & O_NONBLOCK) {
-	    errno = EINPROGRESS;
-	    err = -1;
-	}
-    }
-
-    in_http_connect = 0;
-
-    return err;
-}
-
-int cw_connect(int sockfd, const struct sockaddr *serv_addr, int addrlen,
-               int ssl) {
-    int rc;
-    struct sockaddr_in ba;
-
-    if(bindaddr)
-    if(strlen(bindaddr)) {
-#ifdef HAVE_INET_ATON
-	struct in_addr addr;
-	rc = inet_aton(bindaddr, &addr);
-	ba.sin_addr.s_addr = addr.s_addr;
-#else
-	rc = inet_pton(AF_INET, bindaddr, &ba);
-#endif
-
-	if(rc) {
-	    ba.sin_port = 0;
-	    rc = bind(sockfd, (struct sockaddr *) &ba, sizeof(ba));
-	} else {
-	    rc = -1;
-	}
-
-	if(rc) return rc;
-    }
-
-    if(proxyhost && !in_http_connect)
-        rc = cw_http_connect(sockfd, serv_addr, addrlen);
-    else
-        rc = connect(sockfd, serv_addr, addrlen);
-
-#ifdef HAVE_OPENSSL
-    if(ssl && !rc) {
-	sslsock *p = addsock(sockfd);
-	if(SSL_connect(p->ssl) != 1)
-	    return -1; // XXX "Can't connect to SSL"
-    }
-#endif
-
-    return rc;
-}
-
-int cw_nb_connect(int sockfd, const struct sockaddr *serv_addr, int addrlen,
-                  int ssl, int *state) {
-    int rc = 0;
-    struct sockaddr_in ba;
-
-    if(bindaddr)
-    if(strlen(bindaddr)) {
-#ifdef HAVE_INET_ATON
-	struct in_addr addr;
-	rc = inet_aton(bindaddr, &addr);
-	ba.sin_addr.s_addr = addr.s_addr;
-#else
-	rc = inet_pton(AF_INET, bindaddr, &ba);
-#endif
-
-	if(rc) {
-	    ba.sin_port = 0;
-	    rc = bind(sockfd, (struct sockaddr *) &ba, sizeof(ba));
-	} else {
-	    rc = -1;
-	}
-
-	if(rc) return rc;
-    }
-
-#ifdef HAVE_SSL
-    if(ssl) {
-	if ( !(*state & CW_CONNECT_WANT_SOMETHING)) {
-	    rc = cw_connect(sockfd, serv_addr, addrlen, 0);
-        } else { /* check if the socket is connected correctly */
-	    int optlen = sizeof(int), optval;
-	    if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval,
-	                   (socklen_t*)&optlen) || optval)
-                return -1;
-	}
-
-	if(!rc) {
-#ifdef HAVE_GNUTLS
-            int ret;
-#endif
-	    sslsock *p;
-	    if (*state & CW_CONNECT_SSL)
-		p = getsock(sockfd);
-	    else
-		p = addsock(sockfd);
-
-#ifdef HAVE_GNUTLS
-	    do {
-	       ret = gnutls_handshake(p->session);
-	    } while ((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED));
-	    if (ret < 0) {
-	      gnutls_deinit(p->session);
-	      gnutls_perror(ret);
-	      return -1;
-	    }
-	    else{
-	      *state = 1;
-	      return 0;
-	    }
-#elif defined HAVE_OPENSSL
-	    rc = SSL_connect(p->ssl);
-	    switch(rc){
-	    case 1:
-		*state = 0;
-		return 0;
-	    case 0:
-		return -1;
-	    default:
-		switch (SSL_get_error(p->ssl, rc)){
-		case SSL_ERROR_WANT_READ:
-		    *state = CW_CONNECT_SSL | CW_CONNECT_WANT_READ;
-		    return 0;
-		case SSL_ERROR_WANT_WRITE:
-		    *state = CW_CONNECT_SSL | CW_CONNECT_WANT_WRITE;
-		    return 0;
-		default:
-		    return -1;
-		}
-	    }
-#endif
-	} else { /* catch EINPROGRESS error from the connect call */
-	    if (errno == EINPROGRESS){
-		*state = CW_CONNECT_STARTED | CW_CONNECT_WANT_WRITE;
-		return 0;
-	    }
-	}
-
-	return rc;
-    }
-#endif
-    if ( !(*state & CW_CONNECT_WANT_SOMETHING)) {
-	rc = cw_connect(sockfd, serv_addr, addrlen, 0);
-    } else { /* check if the socket is connected correctly */
-	int optlen = sizeof(int), optval;
-	if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval,
-	               (socklen_t*)&optlen) || optval)
-	    return -1;
-	*state = 0;
-	return 0;
-    }
-    if (rc)
-	if (errno == EINPROGRESS){
-	    *state = CW_CONNECT_STARTED | CW_CONNECT_WANT_WRITE;
-	    return 0;
-	}
-    return rc;
-}
-
-int cw_accept(int s, struct sockaddr *addr, int *addrlen, int ssl) {
-#ifdef HAVE_OPENSSL
-    int rc;
-
-    if(ssl) {
-	rc = accept(s, addr, (socklen_t*)addrlen);
-
-	if(!rc) {
-	    sslsock *p = addsock(s);
-	    if(SSL_accept(p->ssl) != 1)
-		return -1;
-	}
-	return rc;
-    }
-#endif
-    return accept(s, addr, (socklen_t*)addrlen);
-}
-
-int cw_write(int fd, const void *buf, int count, int ssl) {
-#ifdef HAVE_SSL
-    sslsock *p;
-
-    if(ssl) {
-#ifdef HAVE_GNUTLS
-      p = getsock(fd);
-      if(p) {
-          int ret;
-          if((ret = gnutls_record_send( p->session, buf, count) < 0))
-              fprintf(stderr, "Can't write to server");
-          return ret;
-      }
-#elif defined HAVE_OPENSSL
-      if((p = getsock(fd)) != NULL)
-          return SSL_write(p->ssl, buf, count);
-#endif
-    }
-#endif // HAVE_SSL
-    return write(fd, buf, count);
-}
-
-int cw_read(int fd, void *buf, int count, int ssl) {
-#ifdef HAVE_SSL
-    sslsock *p;
-
-    if(ssl) {
-#ifdef HAVE_GNUTLS
-      p = getsock(fd);
-      if(p) {
-          int ret;
-          do {
-              ret = gnutls_record_recv(p->session, buf, count);
-          } while (ret < 0 &&
-                   (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN));
-          return ret;
-       }
-#elif defined HAVE_OPENSSL
-      if((p = getsock(fd)) != NULL)
-          return SSL_read(p->ssl, buf, count);
-#endif
-    }
-#endif // HAVE_SSL
-    return read(fd, buf, count);
-}
-
-void cw_close(int fd) {
-#ifdef HAVE_SSL
-    delsock(fd);
-#endif
-    close(fd);
-}
-
-#define FREEVAR(v) if(v) free(v), v = 0;
-
-void cw_setbind(const char *abindaddr) {
-    FREEVAR(bindaddr);
-    bindaddr = strdup(abindaddr);
-}
-
-void cw_setproxy(const char *aproxyhost, int aproxyport,
-                 const char *aproxyuser, const char *aproxypass) {
-    FREEVAR(proxyhost);
-    FREEVAR(proxyuser);
-    FREEVAR(proxypass);
-
-    if(aproxyhost && strlen(aproxyhost)) proxyhost = strdup(aproxyhost);
-    if(aproxyuser && strlen(aproxyuser)) proxyuser = strdup(aproxyuser);
-    if(aproxypass && strlen(aproxypass)) proxypass = strdup(aproxypass);
-    proxyport = aproxyport;
-}
-
-char *cw_base64_encode(const char *in) {
-    static char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._";
-
-    int j = 0;
-    int inlen = strlen(in);
-    char *out = (char *) malloc(inlen*4+1), c;
-
-    for(out[0] = 0; inlen >= 3; inlen -= 3) {
-	strncat(out, &base64digits[ in[j] >> 2 ], 1);
-	strncat(out, &base64digits[ ((in[j] << 4) & 0x30) | (in[j+1] >> 4) ], 1);
-	strncat(out, &base64digits[ ((in[j+1] << 2) & 0x3c) | (in[j+2] >> 6) ], 1);
-	strncat(out, &base64digits[ in[j+2] & 0x3f ], 1);
-	j += 3;
-    }
-
-    if(inlen > 0) {
-	unsigned char fragment;
-
-	strncat(out, &base64digits[in[j] >> 2], 1);
-	fragment = (in[j] << 4) & 0x30;
-
-	if(inlen > 1)
-	    fragment |= in[j+1] >> 4;
-
-	strncat(out, &base64digits[fragment], 1);
-
-	c = (inlen < 2) ? '-' : base64digits[ (in[j+1] << 2) & 0x3c ];
-	strncat(out, &c, 1);
-	c = '-';
-	strncat(out, &c, 1);
-    }
-
-    return out;
-}
--- a/mcabber/connwrap/connwrap.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-#ifndef __CONNWRAP_H__
-#define __CONNWRAP_H__
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-int cw_connect(int sockfd, const struct sockaddr *serv_addr, int addrlen, int ssl);
-
-#define CW_CONNECT_STARTED 0x1
-#define CW_CONNECT_SSL 0x2
-#define CW_CONNECT_WANT_READ 0x4
-#define CW_CONNECT_WANT_WRITE 0x8
-#define CW_CONNECT_WANT_SOMETHING 0xC
-#define CW_CONNECT_BLOCKING 0x10
-
-/* non-blocking socket
-   state should be initialized with 0, subsequent calls should keep the
-   modified state (state is a bitwise OR between CW_CONNECT_XXX)
-   returns 0 for OK, or if it wants subsequent calls
-	   -1 for a fatal error
- */
-int cw_nb_connect(int sockfd, const struct sockaddr *serv_addr, int addrlen, int ssl, int *state);
-int cw_accept(int s, struct sockaddr *addr, int *addrlen, int ssl);
-
-int cw_write(int fd, const void *buf, int count, int ssl);
-int cw_read(int fd, void *buf, int count, int ssl);
-
-void cw_close(int fd);
-
-void cw_set_ssl_options(int sslverify, const char *sslcafile, const char *sslcapath, const char *sslciphers, const char *sslpeer);
-const char *cw_get_ssl_error(void);
-void cw_setproxy(const char *aproxyhost, int aproxyport, const char *aproxyuser, const char *aproxypass);
-void cw_setbind(const char *abindaddr);
-
-char *cw_base64_encode(const char *in);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--- a/mcabber/connwrap/connwrap.spec	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-Summary: A static library made in motor IDE
-Name: connwrap
-Version: 0.1
-Release: 1
-Copyright: GPL
-Group: Development/Libraries
-URL: http://konst.org.ua/motor/
-Packager: Konstantin Klyagin
-Source: %{name}-%{version}.tar.gz
-BuildRoot: /var/tmp/%{name}-buildroot/
-
-%description
-Motor is a text mode based programming environment for Linux. It
-consists of a powerful editor with syntax highlight feature, project
-manager, makefile generator, gdb front-end, etc. Deep CVS integration is
-also provided.
-
-%prep
-%setup
-
-%build
-./configure --prefix=/usr
-make
-
-%install
-rm -rf $RPM_BUILD_ROOT
-make prefix=$RPM_BUILD_ROOT/usr sysconfdir=$RPM_BUILD_ROOT/etc install
-
-find $RPM_BUILD_ROOT/usr/ -type f -print | \
-    grep -v '\/(README|COPYING|INSTALL|TODO|ChangeLog)$' | \
-    sed "s@^$RPM_BUILD_ROOT@@g" | \
-    sed 's/^\(.\+\/man.\+\)$/\1*/g' \
-    > %{name}-%{version}-filelist
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files -f %{name}-%{version}-filelist
-%defattr(-, root, root)
-
-%doc README COPYING INSTALL TODO ChangeLog
-
-%changelog
--- a/mcabber/connwrap/md5.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,408 +0,0 @@
-/*
-  Copyright (C) 1999 Aladdin Enterprises.  All rights reserved.
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  L. Peter Deutsch
-  ghost@aladdin.com
-
- */
-/*
-  Independent implementation of MD5 (RFC 1321).
-
-  This code implements the MD5 Algorithm defined in RFC 1321.
-  It is derived directly from the text of the RFC and not from the
-  reference implementation.
-
-  The original and principal author of md5.c is L. Peter Deutsch
-  <ghost@aladdin.com>.  Other authors are noted in the change history
-  that follows (in reverse chronological order):
-
-  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
-  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
-  1999-05-03 lpd Original version.
- */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "md5.h"
-
-#if STDC_HEADERS
-# include <string.h>
-#else
-# if !HAVE_STRCHR
-#  define strchr index
-#  define strrchr rindex
-# endif
-char *strchr (), *strrchr ();
-# if !HAVE_MEMCPY
-#  define memcpy(d, s, n) bcopy ((s), (d), (n))
-#  define memmove(d, s, n) bcopy ((s), (d), (n))
-# endif
-#endif
-
-#ifdef TEST
-/*
- * Compile with -DTEST to create a self-contained executable test program.
- * The test program should print out the same values as given in section
- * A.5 of RFC 1321, reproduced below.
- */
-main()
-{
-    static const char *const test[7] = {
-	"", /*d41d8cd98f00b204e9800998ecf8427e*/
-	"945399884.61923487334tuvga", /*0cc175b9c0f1b6a831c399e269772661*/
-	"abc", /*900150983cd24fb0d6963f7d28e17f72*/
-	"message digest", /*f96b697d7cb7938d525a2f31aaf161d0*/
-	"abcdefghijklmnopqrstuvwxyz", /*c3fcd3d76192e4007dfb496cca67e13b*/
-	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
-				/*d174ab98d277d9f5a5611c2c9f419d9f*/
-	"12345678901234567890123456789012345678901234567890123456789012345678901234567890" /*57edf4a22be3c955ac49da2e2107b67a*/
-    };
-    int i;
-
-    for (i = 0; i < 7; ++i) {
-	md5_state_t state;
-	md5_byte_t digest[16];
-	int di;
-
-	md5_init(&state);
-	md5_append(&state, (const md5_byte_t *)test[i], strlen(test[i]));
-	md5_finish(&state, digest);
-	printf("MD5 (\"%s\") = ", test[i]);
-	for (di = 0; di < 16; ++di)
-	    printf("%02x", digest[di]);
-	printf("\n");
-    }
-    return 0;
-}
-#endif /* TEST */
-
-
-/*
- * For reference, here is the program that computed the T values.
- */
-#if 0
-#include <math.h>
-main()
-{
-    int i;
-    for (i = 1; i <= 64; ++i) {
-	unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i)));
-	printf("#define T%d 0x%08lx\n", i, v);
-    }
-    return 0;
-}
-#endif
-/*
- * End of T computation program.
- */
-#define T1 0xd76aa478
-#define T2 0xe8c7b756
-#define T3 0x242070db
-#define T4 0xc1bdceee
-#define T5 0xf57c0faf
-#define T6 0x4787c62a
-#define T7 0xa8304613
-#define T8 0xfd469501
-#define T9 0x698098d8
-#define T10 0x8b44f7af
-#define T11 0xffff5bb1
-#define T12 0x895cd7be
-#define T13 0x6b901122
-#define T14 0xfd987193
-#define T15 0xa679438e
-#define T16 0x49b40821
-#define T17 0xf61e2562
-#define T18 0xc040b340
-#define T19 0x265e5a51
-#define T20 0xe9b6c7aa
-#define T21 0xd62f105d
-#define T22 0x02441453
-#define T23 0xd8a1e681
-#define T24 0xe7d3fbc8
-#define T25 0x21e1cde6
-#define T26 0xc33707d6
-#define T27 0xf4d50d87
-#define T28 0x455a14ed
-#define T29 0xa9e3e905
-#define T30 0xfcefa3f8
-#define T31 0x676f02d9
-#define T32 0x8d2a4c8a
-#define T33 0xfffa3942
-#define T34 0x8771f681
-#define T35 0x6d9d6122
-#define T36 0xfde5380c
-#define T37 0xa4beea44
-#define T38 0x4bdecfa9
-#define T39 0xf6bb4b60
-#define T40 0xbebfbc70
-#define T41 0x289b7ec6
-#define T42 0xeaa127fa
-#define T43 0xd4ef3085
-#define T44 0x04881d05
-#define T45 0xd9d4d039
-#define T46 0xe6db99e5
-#define T47 0x1fa27cf8
-#define T48 0xc4ac5665
-#define T49 0xf4292244
-#define T50 0x432aff97
-#define T51 0xab9423a7
-#define T52 0xfc93a039
-#define T53 0x655b59c3
-#define T54 0x8f0ccc92
-#define T55 0xffeff47d
-#define T56 0x85845dd1
-#define T57 0x6fa87e4f
-#define T58 0xfe2ce6e0
-#define T59 0xa3014314
-#define T60 0x4e0811a1
-#define T61 0xf7537e82
-#define T62 0xbd3af235
-#define T63 0x2ad7d2bb
-#define T64 0xeb86d391
-
-static void
-md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
-{
-    md5_word_t
-	a = pms->abcd[0], b = pms->abcd[1],
-	c = pms->abcd[2], d = pms->abcd[3];
-    md5_word_t t;
-
-#ifndef ARCH_IS_BIG_ENDIAN
-# define ARCH_IS_BIG_ENDIAN 1	/* slower, default implementation */
-#endif
-#if ARCH_IS_BIG_ENDIAN
-
-    /*
-     * On big-endian machines, we must arrange the bytes in the right
-     * order.  (This also works on machines of unknown byte order.)
-     */
-    md5_word_t X[16];
-    const md5_byte_t *xp = data;
-    int i;
-
-    for (i = 0; i < 16; ++i, xp += 4)
-	X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
-
-#else  /* !ARCH_IS_BIG_ENDIAN */
-
-    /*
-     * On little-endian machines, we can process properly aligned data
-     * without copying it.
-     */
-    md5_word_t xbuf[16];
-    const md5_word_t *X;
-
-    if (!((data - (const md5_byte_t *)0) & 3)) {
-	/* data are properly aligned */
-	X = (const md5_word_t *)data;
-    } else {
-	/* not aligned */
-	memcpy(xbuf, data, 64);
-	X = xbuf;
-    }
-#endif
-
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
-
-    /* Round 1. */
-    /* Let [abcd k s i] denote the operation
-       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
-#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + F(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-    /* Do the following 16 operations. */
-    SET(a, b, c, d,  0,  7,  T1);
-    SET(d, a, b, c,  1, 12,  T2);
-    SET(c, d, a, b,  2, 17,  T3);
-    SET(b, c, d, a,  3, 22,  T4);
-    SET(a, b, c, d,  4,  7,  T5);
-    SET(d, a, b, c,  5, 12,  T6);
-    SET(c, d, a, b,  6, 17,  T7);
-    SET(b, c, d, a,  7, 22,  T8);
-    SET(a, b, c, d,  8,  7,  T9);
-    SET(d, a, b, c,  9, 12, T10);
-    SET(c, d, a, b, 10, 17, T11);
-    SET(b, c, d, a, 11, 22, T12);
-    SET(a, b, c, d, 12,  7, T13);
-    SET(d, a, b, c, 13, 12, T14);
-    SET(c, d, a, b, 14, 17, T15);
-    SET(b, c, d, a, 15, 22, T16);
-#undef SET
-
-     /* Round 2. */
-     /* Let [abcd k s i] denote the operation
-          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
-#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + G(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-     /* Do the following 16 operations. */
-    SET(a, b, c, d,  1,  5, T17);
-    SET(d, a, b, c,  6,  9, T18);
-    SET(c, d, a, b, 11, 14, T19);
-    SET(b, c, d, a,  0, 20, T20);
-    SET(a, b, c, d,  5,  5, T21);
-    SET(d, a, b, c, 10,  9, T22);
-    SET(c, d, a, b, 15, 14, T23);
-    SET(b, c, d, a,  4, 20, T24);
-    SET(a, b, c, d,  9,  5, T25);
-    SET(d, a, b, c, 14,  9, T26);
-    SET(c, d, a, b,  3, 14, T27);
-    SET(b, c, d, a,  8, 20, T28);
-    SET(a, b, c, d, 13,  5, T29);
-    SET(d, a, b, c,  2,  9, T30);
-    SET(c, d, a, b,  7, 14, T31);
-    SET(b, c, d, a, 12, 20, T32);
-#undef SET
-
-     /* Round 3. */
-     /* Let [abcd k s t] denote the operation
-          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + H(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-     /* Do the following 16 operations. */
-    SET(a, b, c, d,  5,  4, T33);
-    SET(d, a, b, c,  8, 11, T34);
-    SET(c, d, a, b, 11, 16, T35);
-    SET(b, c, d, a, 14, 23, T36);
-    SET(a, b, c, d,  1,  4, T37);
-    SET(d, a, b, c,  4, 11, T38);
-    SET(c, d, a, b,  7, 16, T39);
-    SET(b, c, d, a, 10, 23, T40);
-    SET(a, b, c, d, 13,  4, T41);
-    SET(d, a, b, c,  0, 11, T42);
-    SET(c, d, a, b,  3, 16, T43);
-    SET(b, c, d, a,  6, 23, T44);
-    SET(a, b, c, d,  9,  4, T45);
-    SET(d, a, b, c, 12, 11, T46);
-    SET(c, d, a, b, 15, 16, T47);
-    SET(b, c, d, a,  2, 23, T48);
-#undef SET
-
-     /* Round 4. */
-     /* Let [abcd k s t] denote the operation
-          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
-#define I(x, y, z) ((y) ^ ((x) | ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + I(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-     /* Do the following 16 operations. */
-    SET(a, b, c, d,  0,  6, T49);
-    SET(d, a, b, c,  7, 10, T50);
-    SET(c, d, a, b, 14, 15, T51);
-    SET(b, c, d, a,  5, 21, T52);
-    SET(a, b, c, d, 12,  6, T53);
-    SET(d, a, b, c,  3, 10, T54);
-    SET(c, d, a, b, 10, 15, T55);
-    SET(b, c, d, a,  1, 21, T56);
-    SET(a, b, c, d,  8,  6, T57);
-    SET(d, a, b, c, 15, 10, T58);
-    SET(c, d, a, b,  6, 15, T59);
-    SET(b, c, d, a, 13, 21, T60);
-    SET(a, b, c, d,  4,  6, T61);
-    SET(d, a, b, c, 11, 10, T62);
-    SET(c, d, a, b,  2, 15, T63);
-    SET(b, c, d, a,  9, 21, T64);
-#undef SET
-
-     /* Then perform the following additions. (That is increment each
-        of the four registers by the value it had before this block
-        was started.) */
-    pms->abcd[0] += a;
-    pms->abcd[1] += b;
-    pms->abcd[2] += c;
-    pms->abcd[3] += d;
-}
-
-void
-md5_init(md5_state_t *pms)
-{
-    pms->count[0] = pms->count[1] = 0;
-    pms->abcd[0] = 0x67452301;
-    pms->abcd[1] = 0xefcdab89;
-    pms->abcd[2] = 0x98badcfe;
-    pms->abcd[3] = 0x10325476;
-}
-
-void
-md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
-{
-    const md5_byte_t *p = data;
-    int left = nbytes;
-    int offset = (pms->count[0] >> 3) & 63;
-    md5_word_t nbits = (md5_word_t)(nbytes << 3);
-
-    if (nbytes <= 0)
-	return;
-
-    /* Update the message length. */
-    pms->count[1] += nbytes >> 29;
-    pms->count[0] += nbits;
-    if (pms->count[0] < nbits)
-	pms->count[1]++;
-
-    /* Process an initial partial block. */
-    if (offset) {
-	int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
-
-	memcpy(pms->buf + offset, p, copy);
-	if (offset + copy < 64)
-	    return;
-	p += copy;
-	left -= copy;
-	md5_process(pms, pms->buf);
-    }
-
-    /* Process full blocks. */
-    for (; left >= 64; p += 64, left -= 64)
-	md5_process(pms, p);
-
-    /* Process a final partial block. */
-    if (left)
-	memcpy(pms->buf, p, left);
-}
-
-void
-md5_finish(md5_state_t *pms, md5_byte_t digest[16])
-{
-    static const md5_byte_t pad[64] = {
-	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    };
-    md5_byte_t data[8];
-    int i;
-
-    /* Save the length before padding. */
-    for (i = 0; i < 8; ++i)
-	data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
-    /* Pad to 56 bytes mod 64. */
-    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
-    /* Append the length. */
-    md5_append(pms, data, 8);
-    for (i = 0; i < 16; ++i)
-	digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
-}
--- a/mcabber/connwrap/md5.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
-  Copyright (C) 1999 Aladdin Enterprises.  All rights reserved.
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  L. Peter Deutsch
-  ghost@aladdin.com
-
- */
-/*
-  Independent implementation of MD5 (RFC 1321).
-
-  This code implements the MD5 Algorithm defined in RFC 1321.
-  It is derived directly from the text of the RFC and not from the
-  reference implementation.
-
-  The original and principal author of md5.h is L. Peter Deutsch
-  <ghost@aladdin.com>.  Other authors are noted in the change history
-  that follows (in reverse chronological order):
-
-  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
-  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
-	added conditionalization for C++ compilation from Martin
-	Purschke <purschke@bnl.gov>.
-  1999-05-03 lpd Original version.
- */
-
-#ifndef md5_INCLUDED
-#  define md5_INCLUDED
-
-/*
- * This code has some adaptations for the Ghostscript environment, but it
- * will compile and run correctly in any environment with 8-bit chars and
- * 32-bit ints.  Specifically, it assumes that if the following are
- * defined, they have the same meaning as in Ghostscript: P1, P2, P3,
- * ARCH_IS_BIG_ENDIAN.
- */
-
-typedef unsigned char md5_byte_t; /* 8-bit byte */
-typedef unsigned int md5_word_t; /* 32-bit word */
-
-/* Define the state of the MD5 Algorithm. */
-typedef struct md5_state_s {
-    md5_word_t count[2];	/* message length in bits, lsw first */
-    md5_word_t abcd[4];		/* digest buffer */
-    md5_byte_t buf[64];		/* accumulate block */
-} md5_state_t;
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/* Initialize the algorithm. */
-#ifdef P1
-void md5_init(P1(md5_state_t *pms));
-#else
-void md5_init(md5_state_t *pms);
-#endif
-
-/* Append a string to the message. */
-#ifdef P3
-void md5_append(P3(md5_state_t *pms, const md5_byte_t *data, int nbytes));
-#else
-void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
-#endif
-
-/* Finish the message and return the digest. */
-#ifdef P2
-void md5_finish(P2(md5_state_t *pms, md5_byte_t digest[16]));
-#else
-void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
-#endif
-
-#ifdef __cplusplus
-}  /* end extern "C" */
-#endif
-
-#endif /* md5_INCLUDED */
--- a/mcabber/libjabber/Makefile.am	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-noinst_LIBRARIES = liblibjabber.a
-EXTRA_DIST = jid.c log.c jutil.c str.c expat.c hashtable.c genhash.c pproxy.c pool.c rate.c xmlparse.c xstream.c xmltok.c xmlnode.c jconn.c xmlrole.c jpacket.c snprintf.c socket.c sha.c xmltok_impl_c.h latin1tab.h log.h asciitab.h libxode.h jabber.h hashtable.h xmlparse.h iasciitab.h xmldef.h xmltok.h utf8tab.h xmltok_impl.h xmlrole.h nametab.h xmltok_ns_c.h
-AUTOMAKE_OPTIONS = foreign
-
-liblibjabber_a_SOURCES =  jid.c log.c jutil.c str.c expat.c hashtable.c genhash.c pproxy.c pool.c rate.c xmlparse.c xstream.c xmltok.c xmlnode.c jconn.c xmlrole.c jpacket.c snprintf.c socket.c sha.c
-
-SUBDIRS = 
-INCLUDES = -I$(top_srcdir)/connwrap
-CPPFLAGS = 
--- a/mcabber/libjabber/aclocal.m4	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +0,0 @@
-dnl aclocal.m4 generated automatically by aclocal 1.4-p6
-
-dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl This program is distributed in the hope that it will be useful,
-dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-dnl PARTICULAR PURPOSE.
-
-# Do all the work for Automake.  This macro actually does too much --
-# some checks are only needed if your package does certain things.
-# But this isn't really a big deal.
-
-# serial 1
-
-dnl Usage:
-dnl AM_INIT_AUTOMAKE(package,version, [no-define])
-
-AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
-AC_REQUIRE([AC_PROG_INSTALL])
-PACKAGE=[$1]
-AC_SUBST(PACKAGE)
-VERSION=[$2]
-AC_SUBST(VERSION)
-dnl test to see if srcdir already configured
-if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
-  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
-fi
-ifelse([$3],,
-AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
-AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
-AC_REQUIRE([AM_SANITY_CHECK])
-AC_REQUIRE([AC_ARG_PROGRAM])
-dnl FIXME This is truly gross.
-missing_dir=`cd $ac_aux_dir && pwd`
-AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}, $missing_dir)
-AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
-AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}, $missing_dir)
-AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
-AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
-AC_REQUIRE([AC_PROG_MAKE_SET])])
-
-# Copyright 2002  Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-
-# AM_AUTOMAKE_VERSION(VERSION)
-# ----------------------------
-# Automake X.Y traces this macro to ensure aclocal.m4 has been
-# generated from the m4 files accompanying Automake X.Y.
-AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.4"])
-
-# AM_SET_CURRENT_AUTOMAKE_VERSION
-# -------------------------------
-# Call AM_AUTOMAKE_VERSION so it can be traced.
-# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
-AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-	 [AM_AUTOMAKE_VERSION([1.4-p6])])
-
-#
-# Check to make sure that the build environment is sane.
-#
-
-AC_DEFUN([AM_SANITY_CHECK],
-[AC_MSG_CHECKING([whether build environment is sane])
-# Just in case
-sleep 1
-echo timestamp > conftestfile
-# Do `set' in a subshell so we don't clobber the current shell's
-# arguments.  Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
-   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
-   if test "[$]*" = "X"; then
-      # -L didn't work.
-      set X `ls -t $srcdir/configure conftestfile`
-   fi
-   if test "[$]*" != "X $srcdir/configure conftestfile" \
-      && test "[$]*" != "X conftestfile $srcdir/configure"; then
-
-      # If neither matched, then we have a broken ls.  This can happen
-      # if, for instance, CONFIG_SHELL is bash and it inherits a
-      # broken ls alias from the environment.  This has actually
-      # happened.  Such a system could not be considered "sane".
-      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
-alias in your environment])
-   fi
-
-   test "[$]2" = conftestfile
-   )
-then
-   # Ok.
-   :
-else
-   AC_MSG_ERROR([newly created file is older than distributed files!
-Check your system clock])
-fi
-rm -f conftest*
-AC_MSG_RESULT(yes)])
-
-dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
-dnl The program must properly implement --version.
-AC_DEFUN([AM_MISSING_PROG],
-[AC_MSG_CHECKING(for working $2)
-# Run test in a subshell; some versions of sh will print an error if
-# an executable is not found, even if stderr is redirected.
-# Redirect stdin to placate older versions of autoconf.  Sigh.
-if ($2 --version) < /dev/null > /dev/null 2>&1; then
-   $1=$2
-   AC_MSG_RESULT(found)
-else
-   $1="$3/missing $2"
-   AC_MSG_RESULT(missing)
-fi
-AC_SUBST($1)])
-
-# Define a conditional.
-
-AC_DEFUN([AM_CONDITIONAL],
-[AC_SUBST($1_TRUE)
-AC_SUBST($1_FALSE)
-if $2; then
-  $1_TRUE=
-  $1_FALSE='#'
-else
-  $1_TRUE='#'
-  $1_FALSE=
-fi])
-
--- a/mcabber/libjabber/asciitab.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
-/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
-/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
-/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
-/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
-/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
-/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
-/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
-/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
-/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
-/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
--- a/mcabber/libjabber/config.h.in	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/* include/config.h.in.  Generated automatically from configure.in by autoheader.  */
-
-/* Define if you have the ANSI C header files.  */
-#undef STDC_HEADERS
-
-/* Define if your processor stores words with the most significant
-   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
-#undef WORDS_BIGENDIAN
-
-#undef POOL_NO_HEAP
-#undef HAVE_LIBSOCKET
-#undef HAVE_SNPRINTF
-
-/* The number of bytes in a int.  */
-#undef SIZEOF_INT
-
-/* The number of bytes in a short.  */
-#undef SIZEOF_SHORT
-
-/* Define if you have the nsl library (-lnsl).  */
-#undef HAVE_LIBNSL
-
-/* Name of package */
-#undef PACKAGE
-
-/* Version number of package */
-#undef VERSION
-
--- a/mcabber/libjabber/configure	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1469 +0,0 @@
-#! /bin/sh
-
-# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.13 
-# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-
-# Defaults:
-ac_help=
-ac_default_prefix=/usr/local
-# Any additions from configure.in:
-ac_help="$ac_help
-  --disable-jabber   Build without Jabber"
-
-# Initialize some variables set by options.
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-build=NONE
-cache_file=./config.cache
-exec_prefix=NONE
-host=NONE
-no_create=
-nonopt=NONE
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-target=NONE
-verbose=
-x_includes=NONE
-x_libraries=NONE
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
-
-# Initialize some other variables.
-subdirs=
-MFLAGS= MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-# Maximum number of lines to put in a shell here document.
-ac_max_here_lines=12
-
-ac_prev=
-for ac_option
-do
-
-  # If the previous option needs an argument, assign it.
-  if test -n "$ac_prev"; then
-    eval "$ac_prev=\$ac_option"
-    ac_prev=
-    continue
-  fi
-
-  case "$ac_option" in
-  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
-  *) ac_optarg= ;;
-  esac
-
-  # Accept the important Cygnus configure options, so we can diagnose typos.
-
-  case "$ac_option" in
-
-  -bindir | --bindir | --bindi | --bind | --bin | --bi)
-    ac_prev=bindir ;;
-  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
-    bindir="$ac_optarg" ;;
-
-  -build | --build | --buil | --bui | --bu)
-    ac_prev=build ;;
-  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
-    build="$ac_optarg" ;;
-
-  -cache-file | --cache-file | --cache-fil | --cache-fi \
-  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
-    ac_prev=cache_file ;;
-  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
-  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
-    cache_file="$ac_optarg" ;;
-
-  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
-    ac_prev=datadir ;;
-  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
-  | --da=*)
-    datadir="$ac_optarg" ;;
-
-  -disable-* | --disable-*)
-    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
-    # Reject names that are not valid shell variable names.
-    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
-      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
-    fi
-    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
-    eval "enable_${ac_feature}=no" ;;
-
-  -enable-* | --enable-*)
-    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
-    # Reject names that are not valid shell variable names.
-    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
-      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
-    fi
-    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
-    case "$ac_option" in
-      *=*) ;;
-      *) ac_optarg=yes ;;
-    esac
-    eval "enable_${ac_feature}='$ac_optarg'" ;;
-
-  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
-  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
-  | --exec | --exe | --ex)
-    ac_prev=exec_prefix ;;
-  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
-  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
-  | --exec=* | --exe=* | --ex=*)
-    exec_prefix="$ac_optarg" ;;
-
-  -gas | --gas | --ga | --g)
-    # Obsolete; use --with-gas.
-    with_gas=yes ;;
-
-  -help | --help | --hel | --he)
-    # Omit some internal or obsolete options to make the list less imposing.
-    # This message is too long to be a string in the A/UX 3.1 sh.
-    cat << EOF
-Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
-Configuration:
-  --cache-file=FILE       cache test results in FILE
-  --help                  print this message
-  --no-create             do not create output files
-  --quiet, --silent       do not print \`checking...' messages
-  --version               print the version of autoconf that created configure
-Directory and file names:
-  --prefix=PREFIX         install architecture-independent files in PREFIX
-                          [$ac_default_prefix]
-  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
-                          [same as prefix]
-  --bindir=DIR            user executables in DIR [EPREFIX/bin]
-  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
-  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
-  --datadir=DIR           read-only architecture-independent data in DIR
-                          [PREFIX/share]
-  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
-  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
-                          [PREFIX/com]
-  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
-  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
-  --includedir=DIR        C header files in DIR [PREFIX/include]
-  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
-  --infodir=DIR           info documentation in DIR [PREFIX/info]
-  --mandir=DIR            man documentation in DIR [PREFIX/man]
-  --srcdir=DIR            find the sources in DIR [configure dir or ..]
-  --program-prefix=PREFIX prepend PREFIX to installed program names
-  --program-suffix=SUFFIX append SUFFIX to installed program names
-  --program-transform-name=PROGRAM
-                          run sed PROGRAM on installed program names
-EOF
-    cat << EOF
-Host type:
-  --build=BUILD           configure for building on BUILD [BUILD=HOST]
-  --host=HOST             configure for HOST [guessed]
-  --target=TARGET         configure for TARGET [TARGET=HOST]
-Features and packages:
-  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
-  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
-  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
-  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
-  --x-includes=DIR        X include files are in DIR
-  --x-libraries=DIR       X library files are in DIR
-EOF
-    if test -n "$ac_help"; then
-      echo "--enable and --with options recognized:$ac_help"
-    fi
-    exit 0 ;;
-
-  -host | --host | --hos | --ho)
-    ac_prev=host ;;
-  -host=* | --host=* | --hos=* | --ho=*)
-    host="$ac_optarg" ;;
-
-  -includedir | --includedir | --includedi | --included | --include \
-  | --includ | --inclu | --incl | --inc)
-    ac_prev=includedir ;;
-  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
-  | --includ=* | --inclu=* | --incl=* | --inc=*)
-    includedir="$ac_optarg" ;;
-
-  -infodir | --infodir | --infodi | --infod | --info | --inf)
-    ac_prev=infodir ;;
-  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
-    infodir="$ac_optarg" ;;
-
-  -libdir | --libdir | --libdi | --libd)
-    ac_prev=libdir ;;
-  -libdir=* | --libdir=* | --libdi=* | --libd=*)
-    libdir="$ac_optarg" ;;
-
-  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
-  | --libexe | --libex | --libe)
-    ac_prev=libexecdir ;;
-  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
-  | --libexe=* | --libex=* | --libe=*)
-    libexecdir="$ac_optarg" ;;
-
-  -localstatedir | --localstatedir | --localstatedi | --localstated \
-  | --localstate | --localstat | --localsta | --localst \
-  | --locals | --local | --loca | --loc | --lo)
-    ac_prev=localstatedir ;;
-  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
-  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
-  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
-    localstatedir="$ac_optarg" ;;
-
-  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
-    ac_prev=mandir ;;
-  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
-    mandir="$ac_optarg" ;;
-
-  -nfp | --nfp | --nf)
-    # Obsolete; use --without-fp.
-    with_fp=no ;;
-
-  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
-  | --no-cr | --no-c)
-    no_create=yes ;;
-
-  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
-  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
-    no_recursion=yes ;;
-
-  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
-  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
-  | --oldin | --oldi | --old | --ol | --o)
-    ac_prev=oldincludedir ;;
-  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
-  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
-  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
-    oldincludedir="$ac_optarg" ;;
-
-  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
-    ac_prev=prefix ;;
-  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
-    prefix="$ac_optarg" ;;
-
-  -program-prefix | --program-prefix | --program-prefi | --program-pref \
-  | --program-pre | --program-pr | --program-p)
-    ac_prev=program_prefix ;;
-  -program-prefix=* | --program-prefix=* | --program-prefi=* \
-  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
-    program_prefix="$ac_optarg" ;;
-
-  -program-suffix | --program-suffix | --program-suffi | --program-suff \
-  | --program-suf | --program-su | --program-s)
-    ac_prev=program_suffix ;;
-  -program-suffix=* | --program-suffix=* | --program-suffi=* \
-  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
-    program_suffix="$ac_optarg" ;;
-
-  -program-transform-name | --program-transform-name \
-  | --program-transform-nam | --program-transform-na \
-  | --program-transform-n | --program-transform- \
-  | --program-transform | --program-transfor \
-  | --program-transfo | --program-transf \
-  | --program-trans | --program-tran \
-  | --progr-tra | --program-tr | --program-t)
-    ac_prev=program_transform_name ;;
-  -program-transform-name=* | --program-transform-name=* \
-  | --program-transform-nam=* | --program-transform-na=* \
-  | --program-transform-n=* | --program-transform-=* \
-  | --program-transform=* | --program-transfor=* \
-  | --program-transfo=* | --program-transf=* \
-  | --program-trans=* | --program-tran=* \
-  | --progr-tra=* | --program-tr=* | --program-t=*)
-    program_transform_name="$ac_optarg" ;;
-
-  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-  | -silent | --silent | --silen | --sile | --sil)
-    silent=yes ;;
-
-  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
-    ac_prev=sbindir ;;
-  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
-  | --sbi=* | --sb=*)
-    sbindir="$ac_optarg" ;;
-
-  -sharedstatedir | --sharedstatedir | --sharedstatedi \
-  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
-  | --sharedst | --shareds | --shared | --share | --shar \
-  | --sha | --sh)
-    ac_prev=sharedstatedir ;;
-  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
-  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
-  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
-  | --sha=* | --sh=*)
-    sharedstatedir="$ac_optarg" ;;
-
-  -site | --site | --sit)
-    ac_prev=site ;;
-  -site=* | --site=* | --sit=*)
-    site="$ac_optarg" ;;
-
-  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
-    ac_prev=srcdir ;;
-  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
-    srcdir="$ac_optarg" ;;
-
-  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
-  | --syscon | --sysco | --sysc | --sys | --sy)
-    ac_prev=sysconfdir ;;
-  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
-  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
-    sysconfdir="$ac_optarg" ;;
-
-  -target | --target | --targe | --targ | --tar | --ta | --t)
-    ac_prev=target ;;
-  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
-    target="$ac_optarg" ;;
-
-  -v | -verbose | --verbose | --verbos | --verbo | --verb)
-    verbose=yes ;;
-
-  -version | --version | --versio | --versi | --vers)
-    echo "configure generated by autoconf version 2.13"
-    exit 0 ;;
-
-  -with-* | --with-*)
-    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
-    # Reject names that are not valid shell variable names.
-    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
-      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
-    fi
-    ac_package=`echo $ac_package| sed 's/-/_/g'`
-    case "$ac_option" in
-      *=*) ;;
-      *) ac_optarg=yes ;;
-    esac
-    eval "with_${ac_package}='$ac_optarg'" ;;
-
-  -without-* | --without-*)
-    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
-    # Reject names that are not valid shell variable names.
-    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
-      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
-    fi
-    ac_package=`echo $ac_package| sed 's/-/_/g'`
-    eval "with_${ac_package}=no" ;;
-
-  --x)
-    # Obsolete; use --with-x.
-    with_x=yes ;;
-
-  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
-  | --x-incl | --x-inc | --x-in | --x-i)
-    ac_prev=x_includes ;;
-  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
-  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
-    x_includes="$ac_optarg" ;;
-
-  -x-libraries | --x-libraries | --x-librarie | --x-librari \
-  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
-    ac_prev=x_libraries ;;
-  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
-  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
-    x_libraries="$ac_optarg" ;;
-
-  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
-    ;;
-
-  *)
-    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
-      echo "configure: warning: $ac_option: invalid host type" 1>&2
-    fi
-    if test "x$nonopt" != xNONE; then
-      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
-    fi
-    nonopt="$ac_option"
-    ;;
-
-  esac
-done
-
-if test -n "$ac_prev"; then
-  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
-fi
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-# File descriptor usage:
-# 0 standard input
-# 1 file creation
-# 2 errors and warnings
-# 3 some systems may open it to /dev/tty
-# 4 used on the Kubota Titan
-# 6 checking for... messages and results
-# 5 compiler messages saved in config.log
-if test "$silent" = yes; then
-  exec 6>/dev/null
-else
-  exec 6>&1
-fi
-exec 5>./config.log
-
-echo "\
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-" 1>&5
-
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Also quote any args containing shell metacharacters.
-ac_configure_args=
-for ac_arg
-do
-  case "$ac_arg" in
-  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
-  | --no-cr | --no-c) ;;
-  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
-  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
-  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
-  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
-  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
-  esac
-done
-
-# NLS nuisances.
-# Only set these to C if already set.  These must not be set unconditionally
-# because not all systems understand e.g. LANG=C (notably SCO).
-# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
-# Non-C LC_CTYPE values break the ctype check.
-if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
-if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
-if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo > confdefs.h
-
-# A filename unique to this package, relative to the directory that
-# configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=aclocal.m4
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
-  ac_srcdir_defaulted=yes
-  # Try the directory containing this script, then its parent.
-  ac_prog=$0
-  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
-  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
-  srcdir=$ac_confdir
-  if test ! -r $srcdir/$ac_unique_file; then
-    srcdir=..
-  fi
-else
-  ac_srcdir_defaulted=no
-fi
-if test ! -r $srcdir/$ac_unique_file; then
-  if test "$ac_srcdir_defaulted" = yes; then
-    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
-  else
-    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
-  fi
-fi
-srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
-
-# Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
-  if test "x$prefix" != xNONE; then
-    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
-  else
-    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
-  fi
-fi
-for ac_site_file in $CONFIG_SITE; do
-  if test -r "$ac_site_file"; then
-    echo "loading site script $ac_site_file"
-    . "$ac_site_file"
-  fi
-done
-
-if test -r "$cache_file"; then
-  echo "loading cache $cache_file"
-  . $cache_file
-else
-  echo "creating cache $cache_file"
-  > $cache_file
-fi
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-ac_exeext=
-ac_objext=o
-if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
-  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
-  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
-    ac_n= ac_c='
-' ac_t='	'
-  else
-    ac_n=-n ac_c= ac_t=
-  fi
-else
-  ac_n= ac_c='\c' ac_t=
-fi
-
-
-ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
-  if test -f $ac_dir/install-sh; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f $ac_dir/install.sh; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  fi
-done
-if test -z "$ac_aux_dir"; then
-  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
-fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
-
-am__api_version="1.4"
-# Find a good install program.  We prefer a C program (faster),
-# so one script is as good as another.  But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# ./install, which can be erroneously created by make from ./install.sh.
-echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:559: checking for a BSD compatible install" >&5
-if test -z "$INSTALL"; then
-if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-    IFS="${IFS= 	}"; ac_save_IFS="$IFS"; IFS=":"
-  for ac_dir in $PATH; do
-    # Account for people who put trailing slashes in PATH elements.
-    case "$ac_dir/" in
-    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
-    *)
-      # OSF1 and SCO ODT 3.0 have their own names for install.
-      # Don't use installbsd from OSF since it installs stuff as root
-      # by default.
-      for ac_prog in ginstall scoinst install; do
-        if test -f $ac_dir/$ac_prog; then
-	  if test $ac_prog = install &&
-            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
-	    # AIX install.  It has an incompatible calling convention.
-	    :
-	  else
-	    ac_cv_path_install="$ac_dir/$ac_prog -c"
-	    break 2
-	  fi
-	fi
-      done
-      ;;
-    esac
-  done
-  IFS="$ac_save_IFS"
-
-fi
-  if test "${ac_cv_path_install+set}" = set; then
-    INSTALL="$ac_cv_path_install"
-  else
-    # As a last resort, use the slow shell script.  We don't cache a
-    # path for INSTALL within a source directory, because that will
-    # break other packages using the cache if that directory is
-    # removed, or if the path is relative.
-    INSTALL="$ac_install_sh"
-  fi
-fi
-echo "$ac_t""$INSTALL" 1>&6
-
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-
-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
-
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
-echo "configure:612: checking whether build environment is sane" >&5
-# Just in case
-sleep 1
-echo timestamp > conftestfile
-# Do `set' in a subshell so we don't clobber the current shell's
-# arguments.  Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
-   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
-   if test "$*" = "X"; then
-      # -L didn't work.
-      set X `ls -t $srcdir/configure conftestfile`
-   fi
-   if test "$*" != "X $srcdir/configure conftestfile" \
-      && test "$*" != "X conftestfile $srcdir/configure"; then
-
-      # If neither matched, then we have a broken ls.  This can happen
-      # if, for instance, CONFIG_SHELL is bash and it inherits a
-      # broken ls alias from the environment.  This has actually
-      # happened.  Such a system could not be considered "sane".
-      { echo "configure: error: ls -t appears to fail.  Make sure there is not a broken
-alias in your environment" 1>&2; exit 1; }
-   fi
-
-   test "$2" = conftestfile
-   )
-then
-   # Ok.
-   :
-else
-   { echo "configure: error: newly created file is older than distributed files!
-Check your system clock" 1>&2; exit 1; }
-fi
-rm -f conftest*
-echo "$ac_t""yes" 1>&6
-if test "$program_transform_name" = s,x,x,; then
-  program_transform_name=
-else
-  # Double any \ or $.  echo might interpret backslashes.
-  cat <<\EOF_SED > conftestsed
-s,\\,\\\\,g; s,\$,$$,g
-EOF_SED
-  program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
-  rm -f conftestsed
-fi
-test "$program_prefix" != NONE &&
-  program_transform_name="s,^,${program_prefix},; $program_transform_name"
-# Use a double $ so make ignores it.
-test "$program_suffix" != NONE &&
-  program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
-
-# sed with no file args requires a program.
-test "$program_transform_name" = "" && program_transform_name="s,x,x,"
-
-echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:669: checking whether ${MAKE-make} sets \${MAKE}" >&5
-set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftestmake <<\EOF
-all:
-	@echo 'ac_maketemp="${MAKE}"'
-EOF
-# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
-eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
-if test -n "$ac_maketemp"; then
-  eval ac_cv_prog_make_${ac_make}_set=yes
-else
-  eval ac_cv_prog_make_${ac_make}_set=no
-fi
-rm -f conftestmake
-fi
-if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  SET_MAKE=
-else
-  echo "$ac_t""no" 1>&6
-  SET_MAKE="MAKE=${MAKE-make}"
-fi
-
-
-PACKAGE=libjabber
-
-VERSION=0.1
-
-if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
-  { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
-fi
-cat >> confdefs.h <<EOF
-#define PACKAGE "$PACKAGE"
-EOF
-
-cat >> confdefs.h <<EOF
-#define VERSION "$VERSION"
-EOF
-
-
-
-missing_dir=`cd $ac_aux_dir && pwd`
-echo $ac_n "checking for working aclocal-${am__api_version}""... $ac_c" 1>&6
-echo "configure:715: checking for working aclocal-${am__api_version}" >&5
-# Run test in a subshell; some versions of sh will print an error if
-# an executable is not found, even if stderr is redirected.
-# Redirect stdin to placate older versions of autoconf.  Sigh.
-if (aclocal-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then
-   ACLOCAL=aclocal-${am__api_version}
-   echo "$ac_t""found" 1>&6
-else
-   ACLOCAL="$missing_dir/missing aclocal-${am__api_version}"
-   echo "$ac_t""missing" 1>&6
-fi
-
-echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
-echo "configure:728: checking for working autoconf" >&5
-# Run test in a subshell; some versions of sh will print an error if
-# an executable is not found, even if stderr is redirected.
-# Redirect stdin to placate older versions of autoconf.  Sigh.
-if (autoconf --version) < /dev/null > /dev/null 2>&1; then
-   AUTOCONF=autoconf
-   echo "$ac_t""found" 1>&6
-else
-   AUTOCONF="$missing_dir/missing autoconf"
-   echo "$ac_t""missing" 1>&6
-fi
-
-echo $ac_n "checking for working automake-${am__api_version}""... $ac_c" 1>&6
-echo "configure:741: checking for working automake-${am__api_version}" >&5
-# Run test in a subshell; some versions of sh will print an error if
-# an executable is not found, even if stderr is redirected.
-# Redirect stdin to placate older versions of autoconf.  Sigh.
-if (automake-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then
-   AUTOMAKE=automake-${am__api_version}
-   echo "$ac_t""found" 1>&6
-else
-   AUTOMAKE="$missing_dir/missing automake-${am__api_version}"
-   echo "$ac_t""missing" 1>&6
-fi
-
-echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
-echo "configure:754: checking for working autoheader" >&5
-# Run test in a subshell; some versions of sh will print an error if
-# an executable is not found, even if stderr is redirected.
-# Redirect stdin to placate older versions of autoconf.  Sigh.
-if (autoheader --version) < /dev/null > /dev/null 2>&1; then
-   AUTOHEADER=autoheader
-   echo "$ac_t""found" 1>&6
-else
-   AUTOHEADER="$missing_dir/missing autoheader"
-   echo "$ac_t""missing" 1>&6
-fi
-
-echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
-echo "configure:767: checking for working makeinfo" >&5
-# Run test in a subshell; some versions of sh will print an error if
-# an executable is not found, even if stderr is redirected.
-# Redirect stdin to placate older versions of autoconf.  Sigh.
-if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
-   MAKEINFO=makeinfo
-   echo "$ac_t""found" 1>&6
-else
-   MAKEINFO="$missing_dir/missing makeinfo"
-   echo "$ac_t""missing" 1>&6
-fi
-
-
-
-# Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:784: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test -n "$RANLIB"; then
-  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_prog_RANLIB="ranlib"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
-fi
-fi
-RANLIB="$ac_cv_prog_RANLIB"
-if test -n "$RANLIB"; then
-  echo "$ac_t""$RANLIB" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-# Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:814: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_prog_CC="gcc"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
-  echo "$ac_t""$CC" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:844: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
-  ac_prog_rejected=no
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
-        ac_prog_rejected=yes
-	continue
-      fi
-      ac_cv_prog_CC="cc"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# -gt 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    set dummy "$ac_dir/$ac_word" "$@"
-    shift
-    ac_cv_prog_CC="$@"
-  fi
-fi
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
-  echo "$ac_t""$CC" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-  if test -z "$CC"; then
-    case "`uname -s`" in
-    *win32* | *WIN32*)
-      # Extract the first word of "cl", so it can be a program name with args.
-set dummy cl; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:895: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_prog_CC="cl"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
-  echo "$ac_t""$CC" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
- ;;
-    esac
-  fi
-  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:927: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-cat > conftest.$ac_ext << EOF
-
-#line 938 "configure"
-#include "confdefs.h"
-
-main(){return(0);}
-EOF
-if { (eval echo configure:943: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  ac_cv_prog_cc_works=yes
-  # If we can't run a trivial program, we are probably using a cross compiler.
-  if (./conftest; exit) 2>/dev/null; then
-    ac_cv_prog_cc_cross=no
-  else
-    ac_cv_prog_cc_cross=yes
-  fi
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  ac_cv_prog_cc_works=no
-fi
-rm -fr conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
-if test $ac_cv_prog_cc_works = no; then
-  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
-fi
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:969: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
-echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:974: checking whether we are using GNU C" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.c <<EOF
-#ifdef __GNUC__
-  yes;
-#endif
-EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:983: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
-  ac_cv_prog_gcc=yes
-else
-  ac_cv_prog_gcc=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc" 1>&6
-
-if test $ac_cv_prog_gcc = yes; then
-  GCC=yes
-else
-  GCC=
-fi
-
-ac_test_CFLAGS="${CFLAGS+set}"
-ac_save_CFLAGS="$CFLAGS"
-CFLAGS=
-echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:1002: checking whether ${CC-cc} accepts -g" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  echo 'void f(){}' > conftest.c
-if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
-  ac_cv_prog_cc_g=yes
-else
-  ac_cv_prog_cc_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS="$ac_save_CFLAGS"
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-
-
-# Check whether --enable-jabber or --disable-jabber was given.
-if test "${enable_jabber+set}" = set; then
-  enableval="$enable_jabber"
-  build_jabber="$enableval"
-else
-  build_jabber="yes"
-fi
-
-
-
-if test "x$build_jabber" = xyes; then
-  BUILD_JABBER_TRUE=
-  BUILD_JABBER_FALSE='#'
-else
-  BUILD_JABBER_TRUE='#'
-  BUILD_JABBER_FALSE=
-fi
-
-if test "$build_jabber" = "yes"; then
-    for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
-do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1058: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test -n "$CXX"; then
-  ac_cv_prog_CXX="$CXX" # Let the user override the test.
-else
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_prog_CXX="$ac_prog"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-fi
-fi
-CXX="$ac_cv_prog_CXX"
-if test -n "$CXX"; then
-  echo "$ac_t""$CXX" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-test -n "$CXX" && break
-done
-test -n "$CXX" || CXX="gcc"
-
-
-echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1090: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
-
-ac_ext=C
-# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cxx_cross
-
-cat > conftest.$ac_ext << EOF
-
-#line 1101 "configure"
-#include "confdefs.h"
-
-int main(){return(0);}
-EOF
-if { (eval echo configure:1106: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  ac_cv_prog_cxx_works=yes
-  # If we can't run a trivial program, we are probably using a cross compiler.
-  if (./conftest; exit) 2>/dev/null; then
-    ac_cv_prog_cxx_cross=no
-  else
-    ac_cv_prog_cxx_cross=yes
-  fi
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  ac_cv_prog_cxx_works=no
-fi
-rm -fr conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
-if test $ac_cv_prog_cxx_works = no; then
-  { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
-fi
-echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1132: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
-echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
-cross_compiling=$ac_cv_prog_cxx_cross
-
-echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
-echo "configure:1137: checking whether we are using GNU C++" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.C <<EOF
-#ifdef __GNUC__
-  yes;
-#endif
-EOF
-if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1146: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
-  ac_cv_prog_gxx=yes
-else
-  ac_cv_prog_gxx=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gxx" 1>&6
-
-if test $ac_cv_prog_gxx = yes; then
-  GXX=yes
-else
-  GXX=
-fi
-
-ac_test_CXXFLAGS="${CXXFLAGS+set}"
-ac_save_CXXFLAGS="$CXXFLAGS"
-CXXFLAGS=
-echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
-echo "configure:1165: checking whether ${CXX-g++} accepts -g" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  echo 'void f(){}' > conftest.cc
-if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
-  ac_cv_prog_cxx_g=yes
-else
-  ac_cv_prog_cxx_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
-if test "$ac_test_CXXFLAGS" = set; then
-  CXXFLAGS="$ac_save_CXXFLAGS"
-elif test $ac_cv_prog_cxx_g = yes; then
-  if test "$GXX" = yes; then
-    CXXFLAGS="-g -O2"
-  else
-    CXXFLAGS="-g"
-  fi
-else
-  if test "$GXX" = yes; then
-    CXXFLAGS="-O2"
-  else
-    CXXFLAGS=
-  fi
-fi
-
-fi
-
-trap '' 1 2 15
-cat > confcache <<\EOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs.  It is not useful on other systems.
-# If it contains results you don't want to keep, you may remove or edit it.
-#
-# By default, configure uses ./config.cache as the cache file,
-# creating it if it does not exist already.  You can give configure
-# the --cache-file=FILE option to use a different cache file; that is
-# what configure does when it calls configure scripts in
-# subdirectories, so they share the cache.
-# Giving --cache-file=/dev/null disables caching, for debugging configure.
-# config.status only pays attention to the cache file if you give it the
-# --recheck option to rerun configure.
-#
-EOF
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, don't put newlines in cache variables' values.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(set) 2>&1 |
-  case `(ac_space=' '; set | grep ac_space) 2>&1` in
-  *ac_space=\ *)
-    # `set' does not quote correctly, so add quotes (double-quote substitution
-    # turns \\\\ into \\, and sed turns \\ into \).
-    sed -n \
-      -e "s/'/'\\\\''/g" \
-      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
-    ;;
-  *)
-    # `set' quotes correctly as required by POSIX, so do not add quotes.
-    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
-    ;;
-  esac >> confcache
-if cmp -s $cache_file confcache; then
-  :
-else
-  if test -w $cache_file; then
-    echo "updating cache $cache_file"
-    cat confcache > $cache_file
-  else
-    echo "not updating unwritable cache $cache_file"
-  fi
-fi
-rm -f confcache
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-# Any assignment to VPATH causes Sun make to only execute
-# the first set of double-colon rules, so remove it if not needed.
-# If there is a colon in the path, we need to keep it.
-if test "x$srcdir" = x.; then
-  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
-fi
-
-trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
-
-# Transform confdefs.h into DEFS.
-# Protect against shell expansion while executing Makefile rules.
-# Protect against Makefile macro expansion.
-cat > conftest.defs <<\EOF
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
-s%[ 	`~#$^&*(){}\\|;'"<>?]%\\&%g
-s%\[%\\&%g
-s%\]%\\&%g
-s%\$%$$%g
-EOF
-DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
-rm -f conftest.defs
-
-
-# Without the "./", some shells look in PATH for config.status.
-: ${CONFIG_STATUS=./config.status}
-
-echo creating $CONFIG_STATUS
-rm -f $CONFIG_STATUS
-cat > $CONFIG_STATUS <<EOF
-#! /bin/sh
-# Generated automatically by configure.
-# Run this file to recreate the current configuration.
-# This directory was configured as follows,
-# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-#
-# $0 $ac_configure_args
-#
-# Compiler output produced by configure, useful for debugging
-# configure, is in ./config.log if it exists.
-
-ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
-for ac_option
-do
-  case "\$ac_option" in
-  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
-    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
-    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
-    echo "$CONFIG_STATUS generated by autoconf version 2.13"
-    exit 0 ;;
-  -help | --help | --hel | --he | --h)
-    echo "\$ac_cs_usage"; exit 0 ;;
-  *) echo "\$ac_cs_usage"; exit 1 ;;
-  esac
-done
-
-ac_given_srcdir=$srcdir
-ac_given_INSTALL="$INSTALL"
-
-trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-# Protect against being on the right side of a sed subst in config.status.
-sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
- s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
-$ac_vpsub
-$extrasub
-s%@SHELL@%$SHELL%g
-s%@CFLAGS@%$CFLAGS%g
-s%@CPPFLAGS@%$CPPFLAGS%g
-s%@CXXFLAGS@%$CXXFLAGS%g
-s%@FFLAGS@%$FFLAGS%g
-s%@DEFS@%$DEFS%g
-s%@LDFLAGS@%$LDFLAGS%g
-s%@LIBS@%$LIBS%g
-s%@exec_prefix@%$exec_prefix%g
-s%@prefix@%$prefix%g
-s%@program_transform_name@%$program_transform_name%g
-s%@bindir@%$bindir%g
-s%@sbindir@%$sbindir%g
-s%@libexecdir@%$libexecdir%g
-s%@datadir@%$datadir%g
-s%@sysconfdir@%$sysconfdir%g
-s%@sharedstatedir@%$sharedstatedir%g
-s%@localstatedir@%$localstatedir%g
-s%@libdir@%$libdir%g
-s%@includedir@%$includedir%g
-s%@oldincludedir@%$oldincludedir%g
-s%@infodir@%$infodir%g
-s%@mandir@%$mandir%g
-s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
-s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
-s%@INSTALL_DATA@%$INSTALL_DATA%g
-s%@PACKAGE@%$PACKAGE%g
-s%@VERSION@%$VERSION%g
-s%@ACLOCAL@%$ACLOCAL%g
-s%@AUTOCONF@%$AUTOCONF%g
-s%@AUTOMAKE@%$AUTOMAKE%g
-s%@AUTOHEADER@%$AUTOHEADER%g
-s%@MAKEINFO@%$MAKEINFO%g
-s%@SET_MAKE@%$SET_MAKE%g
-s%@RANLIB@%$RANLIB%g
-s%@CC@%$CC%g
-s%@BUILD_JABBER_TRUE@%$BUILD_JABBER_TRUE%g
-s%@BUILD_JABBER_FALSE@%$BUILD_JABBER_FALSE%g
-s%@CXX@%$CXX%g
-
-CEOF
-EOF
-
-cat >> $CONFIG_STATUS <<\EOF
-
-# Split the substitutions into bite-sized pieces for seds with
-# small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
-ac_file=1 # Number of current file.
-ac_beg=1 # First line for current file.
-ac_end=$ac_max_sed_cmds # Line after last line for current file.
-ac_more_lines=:
-ac_sed_cmds=""
-while $ac_more_lines; do
-  if test $ac_beg -gt 1; then
-    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
-  else
-    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
-  fi
-  if test ! -s conftest.s$ac_file; then
-    ac_more_lines=false
-    rm -f conftest.s$ac_file
-  else
-    if test -z "$ac_sed_cmds"; then
-      ac_sed_cmds="sed -f conftest.s$ac_file"
-    else
-      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
-    fi
-    ac_file=`expr $ac_file + 1`
-    ac_beg=$ac_end
-    ac_end=`expr $ac_end + $ac_max_sed_cmds`
-  fi
-done
-if test -z "$ac_sed_cmds"; then
-  ac_sed_cmds=cat
-fi
-EOF
-
-cat >> $CONFIG_STATUS <<EOF
-
-CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
-  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
-  case "$ac_file" in
-  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
-       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
-  *) ac_file_in="${ac_file}.in" ;;
-  esac
-
-  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
-
-  # Remove last slash and all that follows it.  Not all systems have dirname.
-  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
-  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
-    # The file is in a subdirectory.
-    test ! -d "$ac_dir" && mkdir "$ac_dir"
-    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
-    # A "../" for each directory in $ac_dir_suffix.
-    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
-  else
-    ac_dir_suffix= ac_dots=
-  fi
-
-  case "$ac_given_srcdir" in
-  .)  srcdir=.
-      if test -z "$ac_dots"; then top_srcdir=.
-      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
-  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
-  *) # Relative path.
-    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
-    top_srcdir="$ac_dots$ac_given_srcdir" ;;
-  esac
-
-  case "$ac_given_INSTALL" in
-  [/$]*) INSTALL="$ac_given_INSTALL" ;;
-  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
-  esac
-
-  echo creating "$ac_file"
-  rm -f "$ac_file"
-  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
-  case "$ac_file" in
-  *Makefile*) ac_comsub="1i\\
-# $configure_input" ;;
-  *) ac_comsub= ;;
-  esac
-
-  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
-  sed -e "$ac_comsub
-s%@configure_input@%$configure_input%g
-s%@srcdir@%$srcdir%g
-s%@top_srcdir@%$top_srcdir%g
-s%@INSTALL@%$INSTALL%g
-" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
-fi; done
-rm -f conftest.s*
-
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-
-exit 0
-EOF
-chmod +x $CONFIG_STATUS
-rm -fr confdefs* $ac_clean_files
-test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
-
--- a/mcabber/libjabber/configure.in	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-AC_INIT(aclocal.m4)
-AM_INIT_AUTOMAKE(libjabber, 0.1)
-
-AC_PROG_RANLIB
-AC_PROG_CC
-
-AC_ARG_ENABLE(jabber, [  --disable-jabber   Build without Jabber], build_jabber="$enableval", build_jabber="yes")
-AM_CONDITIONAL(BUILD_JABBER, test "x$build_jabber" = xyes)
-
-if test "$build_jabber" = "yes"; then
-    AC_PROG_CXX
-fi
-
-AC_OUTPUT(Makefile)
--- a/mcabber/libjabber/expat.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,249 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *  Jabber
- *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
- */
-
-#include <libxode.h>
-
-/**
- * callback function used for start elements
- *
- * This function is used internally by expat.c as a callback function
- * given to expat. It will create a new xmlnode and add it to the
- * already created xmlnode tree.
- *
- * @param userdata pointer to the parent xmlnode instance (NULL if this function is called for the root note)
- * @param name name of the starting element
- * @param atts attributes that are contained in the start element
- */
-void expat_startElement(void* userdata, const char* name, const char** atts)
-{
-    /* get the xmlnode pointed to by the userdata */
-    xmlnode *x = userdata;
-    xmlnode current = *x;
-
-    if (current == NULL)
-    {
-        /* allocate a base node */
-        current = xmlnode_new_tag(name);
-        xmlnode_put_expat_attribs(current, atts);
-        *x = current;
-    }
-    else
-    {
-        *x = xmlnode_insert_tag(current, name);
-        xmlnode_put_expat_attribs(*x, atts);
-    }
-}
-
-/**
- * callback function used for end elements
- *
- * This function is used internally by expat.c as a callback function
- * given to expat. It will complete an xmlnode and update the userdata pointer
- * to point to the node that is parent of the next starting element.
- *
- * @param userdata pointer to the current xmlnode
- * @param name name of the ending element (ignored by this function)
- */
-void expat_endElement(void* userdata, const char* name)
-{
-    xmlnode *x = userdata;
-    xmlnode current = *x;
-
-    current->complete = 1;
-    current = xmlnode_get_parent(current);
-
-    /* if it's NULL we've hit the top folks, otherwise back up a level */
-    if(current != NULL)
-        *x = current;
-}
-
-/**
- * callback function for CDATA nodes
- *
- * This function will insert CDATA in an xmlnode
- *
- * @param userdata pointer to the current xmlnode
- * @param s pointer to the CDATA string (not zero terminated!)
- * @param len length of the CDATA string
- */
-void expat_charData(void* userdata, const char* s, int len)
-{
-    xmlnode *x = userdata;
-    xmlnode current = *x;
-
-    xmlnode_insert_cdata(current, s, len);
-}
-
-/**
- * create an xmlnode instance (possibly including other xmlnode instances) by parsing a string
- *
- * This function will parse a string containing an XML document and create an xmlnode graph
- *
- * @param str the string containing the XML document (not necessarily zero terminated)
- * @param len the length of the string (without the zero byte, if present)
- * @return the graph of xmlnodes that represent the parsed document, NULL on failure
- */
-xmlnode xmlnode_str(char *str, int len)
-{
-    XML_Parser p;
-    xmlnode *x, node; /* pointer to an xmlnode */
-
-    if(NULL == str)
-        return NULL;
-
-    x = malloc(sizeof(void *));
-
-    *x = NULL; /* pointer to NULL */
-    p = XML_ParserCreate(NULL);
-    XML_SetUserData(p, x);
-    XML_SetElementHandler(p, expat_startElement, expat_endElement);
-    XML_SetCharacterDataHandler(p, expat_charData);
-    if(!XML_Parse(p, str, len, 1))
-    {
-        /*        jdebug(ZONE,"xmlnode_str_error: %s",(char *)XML_ErrorString(XML_GetErrorCode(p)));*/
-        xmlnode_free(*x);
-        *x = NULL;
-    }
-    node = *x;
-    free(x);
-    XML_ParserFree(p);
-    return node; /* return the xmlnode x points to */
-}
-
-/**
- * create an xmlnode instance (possibly including other xmlnode instances) by parsing a file
- *
- * This function will parse a file containing an XML document and create an xmlnode graph
- *
- * @param file the filename
- * @return the graph of xmlnodes that represent the parsed document, NULL on failure
- */
-xmlnode xmlnode_file(char *file)
-{
-    XML_Parser p;
-    xmlnode *x, node; /* pointer to an xmlnode */
-    char buf[BUFSIZ];
-    int done, fd, len;
-
-    if(NULL == file)
-        return NULL;
-
-    fd = open(file,O_RDONLY);
-    if(fd < 0)
-        return NULL;
-
-    x = malloc(sizeof(void *));
-
-    *x = NULL; /* pointer to NULL */
-    p = XML_ParserCreate(NULL);
-    XML_SetUserData(p, x);
-    XML_SetElementHandler(p, expat_startElement, expat_endElement);
-    XML_SetCharacterDataHandler(p, expat_charData);
-    do{
-        len = read(fd, buf, BUFSIZ);
-        done = len < BUFSIZ;
-        if(!XML_Parse(p, buf, len, done))
-        {
-            /*            jdebug(ZONE,"xmlnode_file_parseerror: %s",(char *)XML_ErrorString(XML_GetErrorCode(p)));*/
-            xmlnode_free(*x);
-            *x = NULL;
-            done = 1;
-        }
-    }while(!done);
-
-    node = *x;
-    XML_ParserFree(p);
-    free(x);
-    close(fd);
-    return node; /* return the xmlnode x points to */
-}
-
-/**
- * write an xmlnode to a file (without a size limit)
- *
- * @param file the target file
- * @param node the xmlnode that should be written
- * @return 1 on success, -1 on failure
- */
-int xmlnode2file(char *file, xmlnode node)
-{
-    return xmlnode2file_limited(file, node, 0);
-}
-
-/**
- * write an xmlnode to a file, limited by size
- *
- * @param file the target file
- * @param node the xmlnode that should be written
- * @param sizelimit the maximum length of the file to be written
- * @return 1 on success, 0 if failed due to size limit, -1 on failure
- */
-int xmlnode2file_limited(char *file, xmlnode node, size_t sizelimit)
-{
-    char *doc, *ftmp;
-    int fd, i;
-    size_t doclen;
-
-    if(file == NULL || node == NULL)
-        return -1;
-
-    ftmp = spools(xmlnode_pool(node),file,".t.m.p",xmlnode_pool(node));
-    fd = open(ftmp, O_CREAT | O_WRONLY | O_TRUNC, 0600);
-    if(fd < 0)
-        return -1;
-
-    doc = xmlnode2str(node);
-    doclen = strlen(doc);
-
-    if (sizelimit > 0 && doclen > sizelimit)
-    {
-	close(fd);
-	return 0;
-    }
-
-    i = write(fd,doc,doclen);
-    if(i < 0)
-        return -1;
-
-    close(fd);
-
-    if(rename(ftmp,file) < 0)
-    {
-        unlink(ftmp);
-        return -1;
-    }
-    return 1;
-}
-
-/**
- * append attributes in the expat format to an existing xmlnode
- *
- * @param owner where to add the attributes
- * @param atts the attributes in expat format (even indexes are the attribute names, odd indexes the values)
- */
-void xmlnode_put_expat_attribs(xmlnode owner, const char** atts)
-{
-    int i = 0;
-    if (atts == NULL) return;
-    while (atts[i] != '\0')
-    {
-        xmlnode_put_attrib(owner, atts[i], atts[i+1]);
-        i += 2;
-    }
-}
--- a/mcabber/libjabber/genhash.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,501 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyrights
- *
- * Portions created by or assigned to Jabber.com, Inc. are 
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- *
- * Acknowledgements
- *
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- *
- */
-#include <libxode.h>
-
-/*****************************************************************************
- * Internal type definitions
- */
-
-typedef struct tagHNODE
-{
-    struct tagHNODE *next;             /* next node in list */
-    const void *key;                   /* key pointer */
-    void *value;                       /* value pointer */
-} HNODE;
-
-#define SLAB_NUM_NODES     64        /* allocate this many nodes per slab */
-
-typedef struct tagHSLAB
-{
-    struct tagHSLAB *next;             /* next slab pointer */
-    HNODE nodes[SLAB_NUM_NODES];       /* the actual nodes */
-} HSLAB;
-
-#define HASH_NUM_BUCKETS   509       /* should be a prime number; see Knuth */
-
-typedef struct tagHASHTABLE_INTERNAL
-{
-    unsigned long sig1;                /* first signature word */
-    KEYHASHFUNC hash;                  /* hash function */
-    KEYCOMPAREFUNC cmp;                /* comparison function */
-    int count;                         /* table entry count */
-    int bcount;                        /* bucket count */
-    HNODE **buckets;                   /* the hash buckets */
-    unsigned long sig2;                /* second signature word */
-
-} HASHTABLE_INTERNAL;
-
-#define HASH_SIG1      0x68736148UL  /* "Hash" */
-#define HASH_SIG2      0x6F627245UL  /* "Erbo" */
-
-#define do_hash(tb,key)     ((*((tb)->hash))(key) % ((tb)->bcount))
-
-static HNODE *s_free_nodes = NULL;   /* free nodes list */
-static HSLAB *s_slabs = NULL;        /* node slabs list */
-
-/*****************************************************************************
- * Internal functions
- */
-
-static HNODE *allocate_node(
-    const void *key,   /* key pointer for this node */
-    void *value)       /* value pointer for this node */
-/*
-    allocate_node allocates a new hash node and fills it.  Returns NULL if the
-    node could not be allocated.
-*/
-{
-    HNODE *rc;   /* return from this function */
-
-    if (!s_free_nodes)
-    { /* allocate a new slabful of nodes and chain them to make a new free list */
-        register int i;  /* loop counter */
-        HSLAB *slab = (HSLAB *)malloc(sizeof(HSLAB));
-        if (!slab)
-            return NULL;
-        memset(slab,0,sizeof(HSLAB));
-        slab->next = s_slabs;
-        for (i=0; i<(SLAB_NUM_NODES-1); i++)
-            slab->nodes[i].next = &(slab->nodes[i+1]);
-        s_free_nodes = &(slab->nodes[0]);
-        s_slabs = slab;
-
-    } /* end if */
-
-    /* grab a node off the fron of the free list and fill it */
-    rc = s_free_nodes;
-    s_free_nodes = rc->next;
-    rc->next = NULL;
-    rc->key = key;
-    rc->value = value;
-    return rc;
-
-} /* end allocate_node */
-
-static void free_node(
-    HNODE *node)   /* node to be freed */
-/*
-    free_node returns a hash node to the list.
-*/
-{
-    /* zap the node contents to avoid problems later */
-    memset(node,0,sizeof(HNODE));
-
-    /* chain it onto the free list */
-    node->next = s_free_nodes;
-    s_free_nodes = node;
-
-} /* end free_node */
-
-static HNODE *find_node(
-    HASHTABLE_INTERNAL *tab,  /* pointer to hash table */
-    const void *key,          /* key value to look up */
-    int bucket)               /* bucket number (-1 to have function compute it) */
-/*
-    find_node walks a hash bucket to find a node whose key matches the named key value.
-    Returns the node pointer, or NULL if it's not found.
-*/
-{
-    register HNODE *p;  /* search pointer/return from this function */
-
-    if (bucket<0)  /* compute hash value if we don't know it already */
-        bucket = do_hash(tab,key);
-
-    /* search through the bucket contents */
-    for (p=tab->buckets[bucket]; p; p=p->next)
-        if ((*(tab->cmp))(key,p->key)==0)
-            return p;  /* found! */
-
-    return NULL;   /* not found */
-
-} /* end find_node */
-
-static HASHTABLE_INTERNAL *handle2ptr(
-    HASHTABLE tbl)  /* hash table handle */
-/*
-    handle2ptr converts a hash table handle into a pointer and checks its signatures
-    to make sure someone's not trying to pull a whizzer on this module.
-*/
-{
-    register HASHTABLE_INTERNAL *rc = (HASHTABLE_INTERNAL *)tbl;
-    if ((rc->sig1==HASH_SIG1) && (rc->sig2==HASH_SIG2))
-        return rc;     /* signatures match */
-    else
-        return NULL;   /* yIkes! */
-}
-
-/*****************************************************************************
- * External functions
- */
-
-HASHTABLE ghash_create(int buckets, KEYHASHFUNC hash, KEYCOMPAREFUNC cmp)
-/*
-    Description:
-        Creates a new hash table.
-
-    Input:
-        Parameters:
-        buckets - Number of buckets to allocate for the hash table; this value
-                  should be a prime number for maximum efficiency.
-        hash - Key hash code function to use.
-        cmp - Key comparison function to use.
-
-    Output:
-        Returns:
-        NULL - Table could not be allocated.
-        Other - Handle to the new hashtable.
-*/
-{
-    HASHTABLE_INTERNAL *tab;  /* new table structure */
-    char *allocated;
-
-    if (!hash || !cmp)
-        return NULL;  /* bogus! */
-
-    if (buckets<=0)
-        buckets = HASH_NUM_BUCKETS;
-
-    /* allocate a hash table structure */
-    allocated = malloc(sizeof(HASHTABLE_INTERNAL) + (buckets * sizeof(HNODE *)));
-    if (!allocated)
-        return NULL;  /* memory error */
-
-    /* fill the fields of the hash table */
-    tab = (HASHTABLE_INTERNAL *)allocated;
-    allocated += sizeof(HASHTABLE_INTERNAL);
-    memset(tab,0,sizeof(HASHTABLE_INTERNAL));
-    memset(allocated,0,buckets * sizeof(HNODE *));
-    tab->sig1 = HASH_SIG1;
-    tab->hash = hash;
-    tab->cmp = cmp;
-    tab->bcount = buckets;
-    tab->buckets = (HNODE **)allocated;
-    tab->sig2 = HASH_SIG2;
-
-    return (HASHTABLE)tab;  /* Qa'pla! */
-
-} /* end ghash_create */
-
-void ghash_destroy(HASHTABLE tbl)
-/*
-    Description:
-        Destroys a hash table.
-
-    Input:
-        Parameters:
-        tbl - Table to be destroyed.
-
-    Output:
-        Returns:
-        Nothing.
-*/
-{
-    HASHTABLE_INTERNAL *tab;  /* new table structure */
-    int i;                    /* loop counter */
-    HNODE *p, *p2;            /* temporary pointers */
-
-    if (!tbl)
-        return;  /* bogus! */
-
-    /* Convert the handle to a table pointer. */
-    tab = handle2ptr(tbl);
-    if (!tab)
-        return;
-
-    /* Nuke the nodes it contains. */
-    for (i=0; i<tab->bcount; i++)
-    { /* free the contents of each bucket */
-        p = tab->buckets[i];
-        while (p)
-        { /* free each node in turn */
-            p2 = p->next;
-            free_node(p);
-            p = p2;
-
-        } /* end while */
-
-    } /* end for */
-
-    free(tab);  /* bye bye now! */
-
-} /* end ghash_destroy */
-
-void *ghash_get(HASHTABLE tbl, const void *key)
-/*
-    Description:
-        Retrieves a value stored in the hash table.
-
-    Input:
-        Parameters:
-        tbl - The hash table to look in.
-        key - The key value to search on.
-
-    Output:
-        Returns:
-        NULL - Value not found.
-        Other - Value corresponding to the specified key.
-*/
-{
-    HASHTABLE_INTERNAL *tab;  /* internal table pointer */
-    HNODE *node;              /* hash node */
-    void *rc = NULL;          /* return from this function */
-
-    if (!tbl || !key)
-        return NULL;  /* bogus! */
-
-    /* Convert the handle to a table pointer. */
-    tab = handle2ptr(tbl);
-    if (!tab)
-        return NULL;  /* error */
-
-    /* Attempt to find the node. */
-    node = find_node(tab,key,-1);
-    if (node)
-        rc = node->value;  /* found it! */
-
-    return rc;
-
-} /* end ghash_get */
-
-int ghash_put(HASHTABLE tbl, const void *key, void *value)
-/*
-    Description:
-        Associates a key with a value in this hash table.
-
-    Input:
-        Parameters:
-        tbl - Hash table to add.
-        key - Key to use for the value in the table.
-        value - Value to add for this key.
-
-    Output:
-        Returns:
-        1 - Success.
-        0 - Failure.
-
-    Notes:
-        If the specified key is already in the hashtable, its value will be replaced.
-*/
-{
-    HASHTABLE_INTERNAL *tab;  /* internal table pointer */
-    int bucket;               /* bucket value goes into */
-    HNODE *node;              /* hash node */
-    int rc = 1;               /* return from this function */
-
-    if (!tbl || !key || !value)
-        return 0;  /* bogus! */
-
-    /* Convert the handle to a table pointer. */
-    tab = handle2ptr(tbl);
-    if (!tab)
-        return 0;  /* error */
-
-
-    /* Compute the hash bucket and try to find an existing node. */
-    bucket = do_hash(tab,key);
-    node = find_node(tab,key,bucket);
-    if (!node)
-    { /* OK, try to allocate a new node. */
-        node = allocate_node(key,value);
-        if (node)
-        { /* Chain the new node into the hash table. */
-            node->next = tab->buckets[bucket];
-            tab->buckets[bucket] = node;
-            tab->count++;
-
-        } /* end if */
-        else  /* allocation error */
-            rc = 0;
-
-    } /* end if */
-    else  /* already in table - just reassign value */
-        node->value = value;
-
-    return rc;
-
-} /* end ghash_put */
-
-int ghash_remove(HASHTABLE tbl, const void *key)
-/*
-    Description:
-        Removes an entry from a hash table, given its key.
-
-    Input:
-        Parameters:
-        tbl - Hash table to remove from.
-        key - Key of value to remove.
-
-    Output:
-        Returns:
-        1 - Success.
-        0 - Failure; key not present in hash table.
-*/
-{
-    HASHTABLE_INTERNAL *tab;  /* internal table pointer */
-    int bucket;               /* bucket value goes into */
-    HNODE *node;              /* hash node */
-    register HNODE *p;        /* removal pointer */
-    int rc = 1;               /* return from this function */
-
-    if (!tbl || !key)
-        return 0;  /* bogus! */
-
-    /* Convert the handle to a table pointer. */
-    tab = handle2ptr(tbl);
-    if (!tab)
-        return 0;  /* error */
-
-
-    /* Compute the hash bucket and try to find an existing node. */
-    bucket = do_hash(tab,key);
-    node = find_node(tab,key,bucket);
-    if (node)
-    { /* look to unchain it from the bucket it's in */
-        if (node==tab->buckets[bucket])
-            tab->buckets[bucket] = node->next;  /* unchain at head */
-        else
-        { /* unchain in middle of list */
-            for (p=tab->buckets[bucket]; p->next!=node; p=p->next) ;
-            p->next = node->next;
-
-        } /* end else */
-
-        free_node(node);  /* bye bye now! */
-        tab->count--;
-
-    } /* end if */
-    else  /* node not found */
-        rc = 0;
-
-    return rc;
-
-} /* end ghash_remove */
-
-int ghash_walk(HASHTABLE tbl, TABLEWALKFUNC func, void *user_data)
-/*
-    Description:
-        "Walks" through a hash table, calling a callback function for each element
-    stored in it.
-
-    Input:
-        Parameters:
-        tbl - Hash table to walk.
-        func - Function to be called for each node.  It takes three parameters,
-                   a user data pointer, a key value pointer, and a data value pointer.
-           It returns 0 to stop the enumeration or 1 to keep it going.
-        user_data - Value to use as the first parameter for the callback
-                    function.
-
-    Output:
-        Returns:
-        0 - Error occurred.
-        Other - Number of nodes visited up to and including the one for which
-                the callback function returned 0, if it did; ranges from 1
-            to the number of nodes in the hashtable.
-*/
-{
-    HASHTABLE_INTERNAL *tab;  /* internal table pointer */
-    int i;                    /* loop counter */
-    int running = 1;          /* we're still running */
-    int count = 0;            /* number of nodes visited before stop node */
-    register HNODE *p, *p2;   /* loop pointer */
-
-    if (!tbl || !func)
-        return -1;  /* bogus values! */
-
-    /* Convert the handle to a table pointer. */
-    tab = handle2ptr(tbl);
-    if (!tab)
-        return -1;  /* error */
-
-
-    for (i=0; running && (i<tab->bcount); i++)
-    { /* visit the contents of each bucket */
-        p = tab->buckets[i];
-        while (running && p)
-        { /* visit each node in turn */
-            p2 = p->next;
-            count++;
-            running = (*func)(user_data,p->key,p->value);
-            p = p2;
-
-        } /* end while */
-
-    } /* end for */
-
-    return count;
-
-} /* end ghash_walk */
-
-int str_hash_code(const char *s)
-/*
-    Description:
-        Generates a hash code for a string.  This function uses the ELF hashing
-        algorithm as reprinted in Andrew Binstock, "Hashing Rehashed," _Dr.
-        Dobb's Journal_, April 1996.
-
-    Input:
-        Parameters:
-            s - The string to be hashed.
-
-    Output:
-        Returns:
-            A hash code for the string.
-*/
-{
-    /* ELF hash uses unsigned chars and unsigned arithmetic for portability */
-    const unsigned char *name = (const unsigned char *)s;
-    unsigned long h = 0, g;
-
-    if (!name)
-        return 0;  /* anti-NULL guard not in the original */
-
-    while (*name)
-    { /* do some fancy bitwanking on the string */
-        h = (h << 4) + (unsigned long)(*name++);
-        if ((g = (h & 0xF0000000UL))!=0)
-            h ^= (g >> 24);
-        h &= ~g;
-
-    } /* end while */
-
-    return (int)h;
-
-}
--- a/mcabber/libjabber/hashtable.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-csompliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-#include "xmldef.h"
-
-#ifdef XML_UNICODE_WCHAR_T
-#ifndef XML_UNICODE
-#define XML_UNICODE
-#endif
-#endif
-
-#include "hashtable.h"
-
-#define INIT_SIZE 64
-
-static
-int keyeq(KEY s1, KEY s2)
-{
-    for (; *s1 == *s2; s1++, s2++)
-        if (*s1 == 0)
-            return 1;
-    return 0;
-}
-
-static
-unsigned long hash(KEY s)
-{
-    unsigned long h = 0;
-    while (*s)
-        h = (h << 5) + h + (unsigned char)*s++;
-    return h;
-}
-
-NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
-{
-    size_t i;
-    if (table->size == 0) {
-        if (!createSize)
-            return 0;
-        table->v = calloc(INIT_SIZE, sizeof(NAMED *));
-        if (!table->v)
-            return 0;
-        table->size = INIT_SIZE;
-        table->usedLim = INIT_SIZE / 2;
-        i = hash(name) & (table->size - 1);
-    }
-    else {
-        unsigned long h = hash(name);
-        for (i = h & (table->size - 1);
-                table->v[i];
-                i == 0 ? i = table->size - 1 : --i) {
-            if (keyeq(name, table->v[i]->name))
-                return table->v[i];
-        }
-        if (!createSize)
-            return 0;
-        if (table->used == table->usedLim) {
-            /* check for overflow */
-            size_t newSize = table->size * 2;
-            NAMED **newV = calloc(newSize, sizeof(NAMED *));
-            if (!newV)
-                return 0;
-            for (i = 0; i < table->size; i++)
-                if (table->v[i]) {
-                    size_t j;
-                    for (j = hash(table->v[i]->name) & (newSize - 1);
-                            newV[j];
-                            j == 0 ? j = newSize - 1 : --j)
-                        ;
-                    newV[j] = table->v[i];
-                }
-            free(table->v);
-            table->v = newV;
-            table->size = newSize;
-            table->usedLim = newSize/2;
-            for (i = h & (table->size - 1);
-                    table->v[i];
-                    i == 0 ? i = table->size - 1 : --i)
-                ;
-        }
-    }
-    table->v[i] = calloc(1, createSize);
-    if (!table->v[i])
-        return 0;
-    table->v[i]->name = name;
-    (table->used)++;
-    return table->v[i];
-}
-
-void hashTableDestroy(HASH_TABLE *table)
-{
-    size_t i;
-    for (i = 0; i < table->size; i++) {
-        NAMED *p = table->v[i];
-        if (p)
-            free(p);
-    }
-    free(table->v);
-}
-
-void hashTableInit(HASH_TABLE *p)
-{
-    p->size = 0;
-    p->usedLim = 0;
-    p->used = 0;
-    p->v = 0;
-}
-
-void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
-{
-    iter->p = table->v;
-    iter->end = iter->p + table->size;
-}
-
-NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
-{
-    while (iter->p != iter->end) {
-        NAMED *tem = *(iter->p)++;
-        if (tem)
-            return tem;
-    }
-    return 0;
-}
-
--- a/mcabber/libjabber/hashtable.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-
-#include <stddef.h>
-
-#ifdef XML_UNICODE
-
-#ifdef XML_UNICODE_WCHAR_T
-typedef const wchar_t *KEY;
-#else /* not XML_UNICODE_WCHAR_T */
-typedef const unsigned short *KEY;
-#endif /* not XML_UNICODE_WCHAR_T */
-
-#else /* not XML_UNICODE */
-
-typedef const char *KEY;
-
-#endif /* not XML_UNICODE */
-
-typedef struct {
-  KEY name;
-} NAMED;
-
-typedef struct {
-  NAMED **v;
-  size_t size;
-  size_t used;
-  size_t usedLim;
-} HASH_TABLE;
-
-NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize);
-void hashTableInit(HASH_TABLE *);
-void hashTableDestroy(HASH_TABLE *);
-
-typedef struct {
-  NAMED **p;
-  NAMED **end;
-} HASH_TABLE_ITER;
-
-void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
-NAMED *hashTableIterNext(HASH_TABLE_ITER *);
--- a/mcabber/libjabber/iasciitab.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
-/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
-/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
-/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
-/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
-/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
-/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
-/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
-/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
-/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
-/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
-/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
--- a/mcabber/libjabber/jabber.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,403 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *  Jabber
- *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <setjmp.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <syslog.h>
-#include <strings.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-#include <time.h>
-
-#include "libxode.h"
-#include "../connwrap/connwrap.h"
-
-#ifndef INCL_JABBER_H
-#define INCL_JABBER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* JID structures & constants                                */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define JID_RESOURCE 1
-#define JID_USER     2
-#define JID_SERVER   4
-
-typedef struct jid_struct
-{
-    pool               p;
-    char*              resource;
-    char*              user;
-    char*              server;
-    char*              full;
-    struct jid_struct *next; /* for lists of jids */
-} *jid;
-
-jid     jid_new(pool p, char *idstr);          /* Creates a jabber id from the idstr */
-
-void    jid_set(jid id, char *str, int item);  /* Individually sets jid components */
-char*   jid_full(jid id);                      /* Builds a string type=user/resource@server from the jid data */
-int     jid_cmp(jid a, jid b);                 /* Compares two jid's, returns 0 for perfect match */
-int     jid_cmpx(jid a, jid b, int parts);     /* Compares just the parts specified as JID_|JID_ */
-jid     jid_append(jid a, jid b);              /* Appending b to a (list), no dups */
-xmlnode jid_xres(jid id);                      /* Returns xmlnode representation of the resource?query=string */
-xmlnode jid_nodescan(jid id, xmlnode x);       /* Scans the children of the node for a matching jid attribute */
-jid     jid_user(jid a);                       /* returns the same jid but just of the user@host part */
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* JPacket structures & constants                            */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define JPACKET_UNKNOWN   0x00
-#define JPACKET_MESSAGE   0x01
-#define JPACKET_PRESENCE  0x02
-#define JPACKET_IQ        0x04
-#define JPACKET_S10N      0x08
-
-#define JPACKET__UNKNOWN      0
-#define JPACKET__NONE         1
-#define JPACKET__ERROR        2
-#define JPACKET__CHAT         3
-#define JPACKET__GROUPCHAT    4
-#define JPACKET__GET          5
-#define JPACKET__SET          6
-#define JPACKET__RESULT       7
-#define JPACKET__SUBSCRIBE    8
-#define JPACKET__SUBSCRIBED   9
-#define JPACKET__UNSUBSCRIBE  10
-#define JPACKET__UNSUBSCRIBED 11
-#define JPACKET__AVAILABLE    12
-#define JPACKET__UNAVAILABLE  13
-#define JPACKET__PROBE        14
-#define JPACKET__HEADLINE     15
-#define JPACKET__INVISIBLE    16
-
-typedef struct jpacket_struct
-{
-    unsigned char type;             /**< stanza type (JPACKET_*) */
-    int           subtype;          /**< subtype of a stanza */
-    int           flag;             /**< used by the session manager to flag messages, that are read from offline storage */
-    void*         aux1;             /**< pointer to data passed around with a jpacket, multiple use inside jsm */
-    xmlnode       x;                /**< xmlnode containing the stanza inside the jpacket */
-    jid           to;               /**< destination of the stanza */
-    jid           from;             /**< source address for the stanza */
-    char*         iqns;             /**< pointer to the namespace inside an IQ stanza */
-    xmlnode       iq;               /**< "content" of an iq stanza, pointer to the element in its own namespace */
-    pool          p;                /**< memory pool used for this stanza */
-} *jpacket, _jpacket;
-
-jpacket jpacket_new(xmlnode x);     /* Creates a jabber packet from the xmlnode */
-jpacket jpacket_reset(jpacket p);   /* Resets the jpacket values based on the xmlnode */
-int     jpacket_subtype(jpacket p); /* Returns the subtype value (looks at xmlnode for it) */
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Presence Proxy DB structures & constants                  */
-/*                                                           */
-/* --------------------------------------------------------- */
-typedef struct ppdb_struct
-{
-    jid     id;                /* entry data */
-    int     pri;
-    xmlnode x;
-    struct ppdb_struct* user;  /* linked list for user@server */
-    pool                p;     /* db-level data */
-    struct ppdb_struct* next;
-} _ppdb, *ppdb;
-
-ppdb    ppdb_insert(ppdb db, jid id, xmlnode x); /* Inserts presence into the proxy */
-xmlnode ppdb_primary(ppdb db, jid id);           /* Fetches the matching primary presence for the id */
-void    ppdb_free(ppdb db);                      /* Frees the db and all entries */
-xmlnode ppdb_get(ppdb db, jid id);               /* Called successively to return each presence xmlnode */
-						 /*   for the id and children, returns NULL at the end */
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Simple Jabber Rate limit functions                        */
-/*                                                           */
-/* --------------------------------------------------------- */
-typedef struct jlimit_struct
-{
-    char *key;
-    int start;
-    int points;
-    int maxt, maxp;
-    pool p;
-} *jlimit, _jlimit;
-
-jlimit jlimit_new(int maxt, int maxp);
-void jlimit_free(jlimit r);
-int jlimit_check(jlimit r, char *key, int points);
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Error structures & constants                              */
-/*                                                           */
-/* --------------------------------------------------------- */
-typedef struct terror_struct
-{
-    int  code;
-    char msg[64];
-} terror;
-
-#define TERROR_BAD           (terror){400,"Bad Request"}
-#define TERROR_AUTH          (terror){401,"Unauthorized"}
-#define TERROR_PAY           (terror){402,"Payment Required"}
-#define TERROR_FORBIDDEN     (terror){403,"Forbidden"}
-#define TERROR_NOTFOUND      (terror){404,"Not Found"}
-#define TERROR_NOTALLOWED    (terror){405,"Not Allowed"}
-#define TERROR_NOTACCEPTABLE (terror){406,"Not Acceptable"}
-#define TERROR_REGISTER      (terror){407,"Registration Required"}
-#define TERROR_REQTIMEOUT    (terror){408,"Request Timeout"}
-#define TERROR_CONFLICT      (terror){409,"Conflict"}
-
-#define TERROR_INTERNAL   (terror){500,"Internal Server Error"}
-#define TERROR_NOTIMPL    (terror){501,"Not Implemented"}
-#define TERROR_EXTERNAL   (terror){502,"Remote Server Error"}
-#define TERROR_UNAVAIL    (terror){503,"Service Unavailable"}
-#define TERROR_EXTTIMEOUT (terror){504,"Remote Server Timeout"}
-#define TERROR_DISCONNECTED (terror){510,"Disconnected"}
-
-/* we define this to signal that we support xterror */
-#define HAS_XTERROR
-
-typedef struct xterror_struct
-{
-    int  code;
-    char msg[256];
-    char type[9];
-    char condition[64];
-} xterror;
-
-#define XTERROR_BAD		(xterror){400,"Bad Request","modify","bad-request"}
-#define XTERROR_CONFLICT	(xterror){409,"Conflict","cancel","conflict"}
-#define XTERROR_NOTIMPL		(xterror){501,"Not Implemented","cancel","feature-not-implemented"}
-#define XTERROR_FORBIDDEN	(xterror){403,"Forbidden","auth","forbidden"}
-#define XTERROR_GONE		(xterror){302,"Gone","modify","gone"}
-#define XTERROR_INTERNAL	(xterror){500,"Internal Server Error","wait","internal-server-error"}
-#define XTERROR_NOTFOUND	(xterror){404,"Not Found","cancel","item-not-found"}
-#define XTERROR_JIDMALFORMED	(xterror){400,"Bad Request","modify","jid-malformed"}
-#define XTERROR_NOTACCEPTABLE	(xterror){406,"Not Acceptable","modify","not-acceptable"}
-#define XTERROR_NOTALLOWED	(xterror){405,"Not Allowed","cancel","not-allowed"}
-#define XTERROR_AUTH		(xterror){401,"Unauthorized","auth","not-authorized"}
-#define XTERROR_PAY		(xterror){402,"Payment Required","auth","payment-required"}
-#define XTERROR_RECIPIENTUNAVAIL (xterror){404,"Receipient Is Unavailable","wait","recipient-unavailable"}
-#define XTERROR_REDIRECT	(xterror){302,"Redirect","modify","redirect"}
-#define XTERROR_REGISTER	(xterror){407,"Registration Required","auth","registration-required"}
-#define XTERROR_REMOTENOTFOUND	(xterror){404,"Remote Server Not Found","cancel","remote-server-not-found"}
-#define XTERROR_REMOTETIMEOUT	(xterror){504,"Remote Server Timeout","wait","remote-server-timeout"}
-#define XTERROR_RESCONSTRAINT	(xterror){500,"Resource Constraint","wait","resource-constraint"}
-#define XTERROR_UNAVAIL		(xterror){503,"Service Unavailable","cancel","service-unavailable"}
-#define XTERROR_SUBSCRIPTIONREQ	(xterror){407,"Subscription Required","auth","subscription-required"}
-#define XTERROR_UNDEF_CANCEL	(xterror){500,NULL,"cancel","undefined-condition"}
-#define XTERROR_UNDEF_CONTINUE	(xterror){500,NULL,"continue","undefined-condition"}
-#define XTERROR_UNDEF_MODIFY	(xterror){500,NULL,"modify","undefined-condition"}
-#define XTERROR_UNDEF_AUTH	(xterror){500,NULL,"auth","undefined-condition"}
-#define XTERROR_UNDEF_WAIT	(xterror){500,NULL,"wait","undefined-condition"}
-#define XTERROR_UNEXPECTED	(xterror){400,"Unexpected Request","wait","unexpected-request"}
-
-#define XTERROR_REQTIMEOUT	(xterror){408,"Request Timeout","wait","remote-server-timeout"}
-#define XTERROR_EXTERNAL	(xterror){502,"Remote Server Error","wait","service-unavailable"}
-#define XTERROR_EXTTIMEOUT	(xterror){504,"Remote Server Timeout","wait","remote-server-timeout"}
-#define XTERROR_DISCONNECTED	(xterror){510,"Disconnected","cancel","service-unavailable"}
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Namespace constants                                       */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define NSCHECK(x,n) (j_strcmp(xmlnode_get_attrib(x,"xmlns"),n) == 0)
-
-#define NS_CLIENT    "jabber:client"
-#define NS_SERVER    "jabber:server"
-#define NS_DIALBACK  "jabber:server:dialback"
-#define NS_AUTH      "jabber:iq:auth"
-#define NS_AUTH_CRYPT "jabber:iq:auth:crypt"
-#define NS_REGISTER  "jabber:iq:register"
-#define NS_ROSTER    "jabber:iq:roster"
-#define NS_OFFLINE   "jabber:x:offline"
-#define NS_AGENT     "jabber:iq:agent"
-#define NS_AGENTS    "jabber:iq:agents"
-#define NS_DELAY     "jabber:x:delay"
-#define NS_VERSION   "jabber:iq:version"
-#define NS_TIME      "jabber:iq:time"
-#define NS_VCARD     "vcard-temp"
-#define NS_PRIVATE   "jabber:iq:private"
-#define NS_SEARCH    "jabber:iq:search"
-#define NS_OOB       "jabber:iq:oob"
-#define NS_XOOB      "jabber:x:oob"
-#define NS_ADMIN     "jabber:iq:admin"
-#define NS_FILTER    "jabber:iq:filter"
-#define NS_AUTH_0K   "jabber:iq:auth:0k"
-#define NS_BROWSE    "jabber:iq:browse"
-#define NS_EVENT     "jabber:x:event"
-#define NS_CONFERENCE "jabber:iq:conference"
-#define NS_SIGNED    "jabber:x:signed"
-#define NS_ENCRYPTED "jabber:x:encrypted"
-#define NS_GATEWAY   "jabber:iq:gateway"
-#define NS_LAST      "jabber:iq:last"
-#define NS_ENVELOPE  "jabber:x:envelope"
-#define NS_EXPIRE    "jabber:x:expire"
-#define NS_XHTML     "http://www.w3.org/1999/xhtml"
-#define NS_DISCO_INFO "http://jabber.org/protocol/disco#info"
-#define NS_DISCO_ITEMS "http://jabber.org/protocol/disco#items"
-#define NS_IQ_AUTH    "http://jabber.org/features/iq-auth"
-#define NS_REGISTER_FEATURE "http://jabber.org/features/iq-register"
-
-#define NS_CAPS       "http://jabber.org/protocol/caps"
-#define NS_CHATSTATES "http://jabber.org/protocol/chatstates"
-#define NS_COMMANDS   "http://jabber.org/protocol/commands"
-#define NS_MUC        "http://jabber.org/protocol/muc"
-
-#define NS_XDBGINSERT "jabber:xdb:ginsert"
-#define NS_XDBNSLIST  "jabber:xdb:nslist"
-
-#define NS_XMPP_STANZAS "urn:ietf:params:xml:ns:xmpp-stanzas"
-#define NS_XMPP_TLS  "urn:ietf:params:xml:ns:xmpp-tls"
-#define NS_XMPP_STREAMS "urn:ietf:params:xml:ns:xmpp-streams"
-
-#define NS_XMPP_DELAY "urn:xmpp:delay"
-#define NS_XMPP_TIME  "urn:xmpp:time"
-#define NS_PING       "urn:xmpp:ping"
-
-#define NS_JABBERD_STOREDPRESENCE "http://jabberd.org/ns/storedpresence"
-#define NS_JABBERD_HISTORY "http://jabberd.org/ns/history"
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Message Types                                             */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define TMSG_NORMAL     "normal"
-#define TMSG_ERROR      "error"
-#define TMSG_CHAT       "chat"
-#define TMSG_GROUPCHAT  "groupchat"
-#define TMSG_HEADLINE   "headline"
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* JUtil functions                                           */
-/*                                                           */
-/* --------------------------------------------------------- */
-xmlnode jutil_presnew(int type, char *to, char *status); /* Create a skeleton presence packet */
-xmlnode jutil_iqnew(int type, char *ns);                 /* Create a skeleton iq packet */
-xmlnode jutil_msgnew(char *type, char *to, char *subj, char *body);
-							 /* Create a skeleton message packet */
-xmlnode jutil_header(char* xmlns, char* server);         /* Create a skeleton stream packet */
-int     jutil_priority(xmlnode x);                       /* Determine priority of this packet */
-void    jutil_tofrom(xmlnode x);                         /* Swaps to/from fields on a packet */
-xmlnode jutil_iqresult(xmlnode x);                       /* Generate a skeleton iq/result, given a iq/query */
-char*   jutil_timestamp(void);                           /* Get stringified timestamp */
-void    jutil_error(xmlnode x, terror E);                /* Append an <error> node to x */
-void    jutil_delay(xmlnode msg, char *reason);          /* Append a delay packet to msg */
-char*   jutil_regkey(char *key, char *seed);             /* pass a seed to generate a key, pass the key again to validate (returns it) */
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* JConn structures & functions                              */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define JCONN_STATE_OFF       0
-#define JCONN_STATE_CONNECTED 1
-#define JCONN_STATE_ON        2
-#define JCONN_STATE_AUTH      3
-#define JCONN_STATE_CONNECTING 4
-
-typedef struct jconn_struct
-{
-    /* Core structure */
-    pool        p;          /* Memory allocation pool */
-    int         state;      /* Connection state flag */
-    int         cw_state;   /* Low level connection state flag */
-    int         fd;         /* Connection file descriptor */
-    char        *server;    /* The server we'll connect too */
-    int         port;
-    int         ssl;
-    jid         user;       /* User info */
-    char        *pass;      /* User passwd */
-
-    /* Stream stuff */
-    int         id;         /* id counter for jab_getid() function */
-    char        idbuf[9];   /* temporary storage for jab_getid() */
-    char        *sid;       /* stream id from server, for digest auth */
-    XML_Parser  parser;     /* Parser instance */
-    xmlnode     current;    /* Current node in parsing instance.. */
-
-    /* Event callback ptrs */
-    void (*on_state)(struct jconn_struct *j, int state);
-    void (*on_packet)(struct jconn_struct *j, jpacket p);
-    void (*logger)(struct jconn_struct *j, int inout, const char *p);
-
-} *jconn, jconn_struct;
-
-typedef void (*jconn_state_h)(jconn j, int state);
-typedef void (*jconn_packet_h)(jconn j, jpacket p);
-typedef void (*jconn_logger)(jconn j, int inout, const char *p);
-
-jconn jab_new(char *user, char *pass, char *server, int port, int ssl);
-void jab_delete(jconn j);
-void jab_state_handler(jconn j, jconn_state_h h);
-void jab_packet_handler(jconn j, jconn_packet_h h);
-void jab_logger(jconn j, jconn_logger h);
-void jab_start(jconn j);
-void jab_stop(jconn j);
-
-int jab_getfd(jconn j);
-jid jab_getjid(jconn j);
-char *jab_getsid(jconn j);
-char *jab_getid(jconn j);
-
-void jab_send(jconn j, xmlnode x);
-void jab_send_raw(jconn j, const char *str);
-void jab_recv(jconn j);
-void jab_poll(jconn j, int timeout);
-
-char *jab_auth(jconn j);
-int   jab_auth_mcabber(jconn j, xmlnode x);
-char *jab_reg(jconn j);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  /* INCL_JABBER_H */
--- a/mcabber/libjabber/jconn.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,601 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *  Jabber
- *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
- */
-
-#include "jabber.h"
-#include "connwrap.h"
-
-#include "../src/logprint.h"  /* For logging */
-
-/* local macros for launching event handlers */
-#define STATE_EVT(arg) if(j->on_state) { (j->on_state)(j, (arg) ); }
-
-/* prototypes of the local functions */
-static void startElement(void *userdata, const char *name, const char **attribs);
-static void endElement(void *userdata, const char *name);
-static void charData(void *userdata, const char *s, int slen);
-
-/*
- *  jab_new -- initialize a new jabber connection
- *
- *  parameters
- *      user -- jabber id of the user
- *      pass -- password of the user
- *
- *  results
- *      a pointer to the connection structure
- *      or NULL if allocations failed
- */
-jconn jab_new(char *user, char *pass, char *server, int port, int ssl)
-{
-    pool p;
-    jconn j;
-
-    if(!user) return(NULL);
-
-    p = pool_new();
-    if(!p) return(NULL);
-    j = pmalloc_x(p, sizeof(jconn_struct), 0);
-    if(!j) return(NULL);
-    j->p = p;
-
-    j->user = jid_new(p, user);
-    j->pass = pstrdup(p, pass);
-    j->port = port;
-    j->server = server;
-
-    j->state = JCONN_STATE_OFF;
-    j->cw_state = 0;
-    j->id = 1;
-    j->fd = -1;
-    j->ssl = ssl;
-
-    return j;
-}
-
-/*
- *  jab_delete -- free a jabber connection
- *
- *  parameters
- *      j -- connection
- *
- */
-void jab_delete(jconn j)
-{
-    if(!j) return;
-
-    jab_stop(j);
-    pool_free(j->p);
-}
-
-/*
- *  jab_state_handler -- set callback handler for state change
- *
- *  parameters
- *      j -- connection
- *      h -- name of the handler function
- */
-void jab_state_handler(jconn j, jconn_state_h h)
-{
-    if(!j) return;
-
-    j->on_state = h;
-}
-
-/*
- *  jab_packet_handler -- set callback handler for incoming packets
- *
- *  parameters
- *      j -- connection
- *      h -- name of the handler function
- */
-void jab_packet_handler(jconn j, jconn_packet_h h)
-{
-    if(!j) return;
-
-    j->on_packet = h;
-}
-
-void jab_logger(jconn j, jconn_logger h)
-{
-    if(!j) return;
-
-    j->logger = h;
-}
-
-
-/*
- *  jab_start -- start connection
- *
- *  parameters
- *      j -- connection
- *
- */
-void jab_start(jconn j)
-{
-    xmlnode x;
-    char *t,*t2;
-
-    if(!j || (j->state != JCONN_STATE_OFF && j->state != JCONN_STATE_CONNECTING) ) return;
-
-    if (!(j->cw_state & CW_CONNECT_WANT_SOMETHING)) { /* same as state != JCONN_STATE_CONNECTING */
-	j->parser = XML_ParserCreate(NULL);
-	XML_SetUserData(j->parser, (void *)j);
-	XML_SetElementHandler(j->parser, startElement, endElement);
-	XML_SetCharacterDataHandler(j->parser, charData);
-
-	if (j->cw_state & CW_CONNECT_BLOCKING)
-	    j->fd = make_netsocket(j->port, j->server, NETSOCKET_CLIENT, j->ssl);
-	else
-	    j->fd = make_nb_netsocket(j->port, j->server, NETSOCKET_CLIENT, j->ssl, &j->cw_state);
-
-	if(j->fd < 0) {
-	    STATE_EVT(JCONN_STATE_OFF);
-	    return;
-	}
-    }
-    else { /* subsequent calls to cw_nb_connect until it finishes negociation */
-	if (cw_nb_connect(j->fd, 0, 0, j->ssl, &j->cw_state)) {
-	    if (cw_get_ssl_error())
-		scr_LogPrint(LPRINT_LOGNORM, "jab_start: SSL negotiation failed: %s", cw_get_ssl_error());
-	    STATE_EVT(JCONN_STATE_OFF);
-	    return;
-	}
-    }
-    if (j->cw_state & CW_CONNECT_WANT_SOMETHING){ /* check if it finished negociation */
-	j->state = JCONN_STATE_CONNECTING;
-	STATE_EVT(JCONN_STATE_CONNECTING);
-	return;
-    }
-    change_socket_to_blocking(j->fd);
-
-    j->state = JCONN_STATE_CONNECTED;
-    STATE_EVT(JCONN_STATE_CONNECTED)
-
-    /* start stream */
-    x = jutil_header(NS_CLIENT, j->user->server);
-    t = xmlnode2str(x);
-    /* this is ugly, we can create the string here instead of jutil_header */
-    /* what do you think about it? -madcat */
-    t2 = strstr(t,"/>");
-    *t2++ = '>';
-    *t2 = '\0';
-    jab_send_raw(j,"<?xml version='1.0'?>");
-    jab_send_raw(j,t);
-    xmlnode_free(x);
-
-    j->state = JCONN_STATE_ON;
-    STATE_EVT(JCONN_STATE_ON)
-
-}
-
-/*
- *  jab_stop -- stop connection
- *
- *  parameters
- *      j -- connection
- */
-void jab_stop(jconn j)
-{
-    if (!j) return;
-    if (j->parser) {
-	XML_ParserFree(j->parser);
-	j->parser = NULL;
-    }
-    j->state = JCONN_STATE_OFF;
-    if (j->fd >= 0) {
-	cw_close(j->fd);
-	j->fd = -1;
-    }
-}
-
-/*
- *  jab_getfd -- get file descriptor of connection socket
- *
- *  parameters
- *      j -- connection
- *
- *  returns
- *      fd of the socket or -1 if socket was not connected
- */
-int jab_getfd(jconn j)
-{
-    if(j)
-	return j->fd;
-    else
-	return -1;
-}
-
-/*
- *  jab_getjid -- get jid structure of user
- *
- *  parameters
- *      j -- connection
- */
-jid jab_getjid(jconn j)
-{
-    if(j)
-	return(j->user);
-    else
-	return NULL;
-}
-
-/*  jab_getsid -- get stream id
- *  This is the id of server's <stream:stream> tag and used for
- *  digest authorization.
- *
- *  parameters
- *      j -- connection
- */
-char *jab_getsid(jconn j)
-{
-    if(j)
-	return(j->sid);
-    else
-	return NULL;
-}
-
-/*
- *  jab_getid -- get a unique id
- *
- *  parameters
- *      j -- connection
- */
-char *jab_getid(jconn j)
-{
-    snprintf(j->idbuf, 8, "%d", j->id++);
-    return &j->idbuf[0];
-}
-
-/*
- *  jab_send -- send xml data
- *
- *  parameters
- *      j -- connection
- *      x -- xmlnode structure
- */
-void jab_send(jconn j, xmlnode x)
-{
-    if (j && j->state != JCONN_STATE_OFF)
-    {
-	    char *buf = xmlnode2str(x);
-	    if (buf) {
-		cw_write(j->fd, buf, strlen(buf), j->ssl);
-		if (j->logger)
-		    (j->logger)(j, 0, buf);
-	    }
-
-#ifdef JDEBUG
-	    printf ("out: %s\n", buf);
-#endif
-    }
-}
-
-/*
- *  jab_send_raw -- send a string
- *
- *  parameters
- *      j -- connection
- *      str -- xml string
- */
-void jab_send_raw(jconn j, const char *str)
-{
-    if (j && j->state != JCONN_STATE_OFF) {
-	cw_write(j->fd, str, strlen(str), j->ssl);
-
-	if (j->logger)
-	    (j->logger)(j, 0, str);
-    }
-
-#ifdef JDEBUG
-    printf ("out: %s\n", str);
-#endif
-}
-
-/*
- *  jab_recv -- read and parse incoming data
- *
- *  parameters
- *      j -- connection
- */
-void jab_recv(jconn j)
-{
-    static char buf[32768];
-    int len;
-
-    if(!j || j->state == JCONN_STATE_OFF)
-	return;
-
-    len = cw_read(j->fd, buf, sizeof(buf)-1, j->ssl);
-    if(len>0)
-    {
-	buf[len] = '\0';
-
-	if (j->logger)
-	    (j->logger)(j, 1, buf);
-
-#ifdef JDEBUG
-	printf (" in: %s\n", buf);
-#endif
-	XML_Parse(j->parser, buf, len, 0);
-    }
-    else if(len<=0)
-    {
-	STATE_EVT(JCONN_STATE_OFF);
-	jab_stop(j);
-    }
-}
-
-/*
- *  jab_poll -- check socket for incoming data
- *
- *  parameters
- *      j -- connection
- *      timeout -- poll timeout
- */
-void jab_poll(jconn j, int timeout)
-{
-    fd_set fds;
-    struct timeval tv;
-    int r;
-
-    if (!j || j->state == JCONN_STATE_OFF)
-	return;
-
-    if (j->fd == -1) {
-	STATE_EVT(JCONN_STATE_OFF);
-	return;
-    }
-
-    FD_ZERO(&fds);
-    FD_SET(j->fd, &fds);
-
-    if(timeout <= 0) {
-	r = select(j->fd + 1, &fds, NULL, NULL, NULL);
-
-    } else {
-	tv.tv_sec = 0;
-	tv.tv_usec = timeout;
-	r = select(j->fd + 1, &fds, NULL, NULL, &tv);
-
-    }
-
-    if(r > 0) {
-	jab_recv(j);
-
-    } else if(r) {
-	/* Don't disconnect for interrupted system call */
-	if(errno == EINTR) return;
-
-	scr_LogPrint(LPRINT_LOGNORM, "jab_poll: select returned errno=%d",
-                     errno);
-	STATE_EVT(JCONN_STATE_OFF);
-	jab_stop(j);
-
-    }
-}
-
-/*
- *  jab_auth -- authorize user
- *
- *  parameters
- *      j -- connection
- *
- *  returns
- *      id of the iq packet
- */
-char *jab_auth(jconn j)
-{
-    xmlnode x,y,z;
-    char *hash, *user, *id;
-
-    if(!j) return(NULL);
-
-    x = jutil_iqnew(JPACKET__SET, NS_AUTH);
-    id = jab_getid(j);
-    xmlnode_put_attrib(x, "id", id);
-    y = xmlnode_get_tag(x,"query");
-
-    user = j->user->user;
-
-    if (user)
-    {
-	z = xmlnode_insert_tag(y, "username");
-	xmlnode_insert_cdata(z, user, -1);
-    }
-
-    z = xmlnode_insert_tag(y, "resource");
-    xmlnode_insert_cdata(z, j->user->resource, -1);
-
-    if (j->sid)
-    {
-	z = xmlnode_insert_tag(y, "digest");
-	hash = pmalloc(x->p, strlen(j->sid)+strlen(j->pass)+1);
-	strcpy(hash, j->sid);
-	strcat(hash, j->pass);
-	hash = shahash(hash);
-	xmlnode_insert_cdata(z, hash, 40);
-    }
-    else
-    {
-	z = xmlnode_insert_tag(y, "password");
-	xmlnode_insert_cdata(z, j->pass, -1);
-    }
-
-    jab_send(j, x);
-    xmlnode_free(x);
-    return id;
-}
-
-/*
- *  jab_auth_mcabber -- authorize user
- *
- *  parameters
- *      j -- connection
- *      x -- xmlnode iq packet
- *
- *  returns
- *      non-zero in case of failure
- */
-int jab_auth_mcabber(jconn j, xmlnode x)
-{
-    xmlnode y,z;
-    char *hash, *user;
-
-    if(!j) return -1;
-
-    y = xmlnode_get_tag(x, "query");
-
-    user = j->user->user;
-
-    if (user)
-    {
-	z = xmlnode_insert_tag(y, "username");
-	xmlnode_insert_cdata(z, user, -1);
-    }
-
-    z = xmlnode_insert_tag(y, "resource");
-    xmlnode_insert_cdata(z, j->user->resource, -1);
-
-    if (j->sid)
-    {
-	z = xmlnode_insert_tag(y, "digest");
-	hash = pmalloc(x->p, strlen(j->sid)+strlen(j->pass)+1);
-	strcpy(hash, j->sid);
-	strcat(hash, j->pass);
-	hash = shahash(hash);
-	xmlnode_insert_cdata(z, hash, 40);
-    }
-    else
-    {
-	z = xmlnode_insert_tag(y, "password");
-	xmlnode_insert_cdata(z, j->pass, -1);
-    }
-    return 0;
-}
-
-/*
- *  jab_reg -- register user
- *
- *  parameters
- *      j -- connection
- *
- *  returns
- *      id of the iq packet
- */
-char *jab_reg(jconn j)
-{
-    xmlnode x,y,z;
-    char *user, *id;
-
-    if (!j) return(NULL);
-
-    x = jutil_iqnew(JPACKET__SET, NS_REGISTER);
-    id = jab_getid(j);
-    xmlnode_put_attrib(x, "id", id);
-    y = xmlnode_get_tag(x,"query");
-
-    user = j->user->user;
-
-    if (user)
-    {
-	z = xmlnode_insert_tag(y, "username");
-	xmlnode_insert_cdata(z, user, -1);
-    }
-
-    z = xmlnode_insert_tag(y, "resource");
-    xmlnode_insert_cdata(z, j->user->resource, -1);
-
-    if (j->pass)
-    {
-	z = xmlnode_insert_tag(y, "password");
-	xmlnode_insert_cdata(z, j->pass, -1);
-    }
-
-    jab_send(j, x);
-    xmlnode_free(x);
-    j->state = JCONN_STATE_ON;
-    STATE_EVT(JCONN_STATE_ON)
-    return id;
-}
-
-
-/* local functions */
-
-static void startElement(void *userdata, const char *name, const char **attribs)
-{
-    xmlnode x;
-    jconn j = (jconn)userdata;
-
-    if(j->current)
-    {
-	/* Append the node to the current one */
-	x = xmlnode_insert_tag(j->current, name);
-	xmlnode_put_expat_attribs(x, attribs);
-
-	j->current = x;
-    }
-    else
-    {
-	x = xmlnode_new_tag(name);
-	xmlnode_put_expat_attribs(x, attribs);
-	if(strcmp(name, "stream:stream") == 0) {
-	    /* special case: name == stream:stream */
-	    /* id attrib of stream is stored for digest auth */
-	    j->sid = xmlnode_get_attrib(x, "id");
-	    /* STATE_EVT(JCONN_STATE_AUTH) */
-	} else {
-	    j->current = x;
-	}
-    }
-}
-
-static void endElement(void *userdata, const char *name)
-{
-    jconn j = (jconn)userdata;
-    xmlnode x;
-    jpacket p;
-
-    if(j->current == NULL) {
-	/* we got </stream:stream> */
-	STATE_EVT(JCONN_STATE_OFF)
-	return;
-    }
-
-    x = xmlnode_get_parent(j->current);
-
-    if(x == NULL)
-    {
-	/* it is time to fire the event */
-	p = jpacket_new(j->current);
-
-	if(j->on_packet)
-	    (j->on_packet)(j, p);
-	xmlnode_free(j->current);
-    }
-
-    j->current = x;
-}
-
-static void charData(void *userdata, const char *s, int slen)
-{
-    jconn j = (jconn)userdata;
-
-    if (j->current)
-	xmlnode_insert_cdata(j->current, s, slen);
-}
--- a/mcabber/libjabber/jid.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,746 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *  Jabber
- *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
- */
-
-/**
- * @file jid.c
- * @brief representation and normalization of JabberIDs
- */
-
-#include "jabber.h"
-
-#ifdef LIBIDN
-
-#  include <stringprep.h>
-
-
-/**
- * @brief datastructure to build the stringprep caches
- */
-typedef struct _jid_prep_entry_st {
-    char *preped;	/**< the result of the preparation, NULL if unchanged */
-    time_t last_used;	/**< when this result has last been successfully used */
-    unsigned int used_count; /**< how often this result has been successfully used */
-    int size;		/**< the min buffer size needed to hold the result (strlen+1) */
-} *_jid_prep_entry_t;
-
-/**
- * @brief string preparation cache
- */
-typedef struct _jid_prep_cache_st {
-    xht hashtable;	/**< the hash table containing the preped strings */
-    pth_mutex_t mutex;	/**< mutex controling the access to the hashtable */
-    const Stringprep_profile *profile;
-    			/**< the stringprep profile used for this cache */
-} *_jid_prep_cache_t;
-
-/**
- * stringprep cache containging already preped nodes
- *
- * we are using global caches here for two reasons:
- * - I do not see why different instances would want
- *   to have different caches as we are always doing
- *   the same
- * - For per instance caches I would have to modify the
- *   interface of the jid_*() functions which would break
- *   compatibility with transports
- */
-_jid_prep_cache_t _jid_prep_cache_node = NULL;
-
-/**
- * stringprep cache containing already preped domains
- */
-_jid_prep_cache_t _jid_prep_cache_domain = NULL;
-
-/**
- * stringprep cache containing already preped resources
- */
-_jid_prep_cache_t _jid_prep_cache_resource = NULL;
-
-/**
- * walker for cleaning up stringprep caches
- *
- * @param h the hash we are walking through
- * @param key the key of this item
- * @param val the value of this item
- * @param arg delete entries older as this unix timestamp
- */
-void _jid_clean_walker(xht h, const char *key, void *val, void *arg) {
-    time_t *keep_newer_as = (time_t*)arg;
-    _jid_prep_entry_t entry = (_jid_prep_entry_t)val;
-
-    if (entry == NULL)
-	return;
-
-    if (entry->last_used <= *keep_newer_as) {
-	xhash_zap(h, key);
-	if (entry->preped != NULL)
-	    free(entry->preped);
-	free(entry);
-
-	/* sorry, I have to cast the const away */
-	/* any idea how I could delete the key else? */
-	if (key != NULL)
-	    free((void*)key);
-    }
-}
-
-/**
- * walk through a single stringprep cache and check which entries have expired
- */
-void _jid_clean_single_cache(_jid_prep_cache_t cache, time_t keep_newer_as) {
-    /* acquire the lock on the cache */
-    pth_mutex_acquire(&(cache->mutex), FALSE, NULL);
-
-    /* walk over all entries */
-    xhash_walk(cache->hashtable, _jid_clean_walker, (void*)&keep_newer_as);
-
-    /* we're done, release the lock on the cache */
-    pth_mutex_release(&(cache->mutex));
-}
-
-/**
- * walk through the stringprep caches and check which entries have expired
- */
-void jid_clean_cache() {
-    /* XXX make this configurable? */
-    time_t keep_newer_as = time(NULL) - 900;
-
-    /* cleanup the nodeprep cache */
-    _jid_clean_single_cache(_jid_prep_cache_node, keep_newer_as);
-    
-    /* cleanup the domain preparation cache */
-    _jid_clean_single_cache(_jid_prep_cache_domain, keep_newer_as);
-    
-    /* cleanup the resourceprep cache */
-    _jid_clean_single_cache(_jid_prep_cache_resource, keep_newer_as);
-}
-
-/**
- * caching wrapper around a stringprep function
- *
- * @param in_out_buffer buffer containing what has to be stringpreped and that gets the result
- * @param max_len size of the buffer
- * @param cache the used cache, defining also the used stringprep profile
- * @return the return code of the stringprep call
- */
-int _jid_cached_stringprep(char *in_out_buffer, int max_len, _jid_prep_cache_t cache) {
-    _jid_prep_entry_t preped;
-    int result = STRINGPREP_OK;
-
-    /* check that the cache already exists
-     * we can not do anything as we don't know which profile has to be used */
-    if (cache == NULL) {
-	return STRINGPREP_UNKNOWN_PROFILE;
-    }
-
-    /* is there something that has to be stringpreped? */
-    if (in_out_buffer == NULL) {
-	return STRINGPREP_OK;
-    }
-
-    /* acquire the lock on the cache */
-    pth_mutex_acquire(&(cache->mutex), FALSE, NULL);
-
-    /* check if the requested preparation has already been done */
-    preped = (_jid_prep_entry_t)xhash_get(cache->hashtable, in_out_buffer);
-    if (preped != NULL) {
-	/* we already prepared this argument */
-	if (preped->size <= max_len) {
-	    /* we can use the result */
-
-	    /* update the statistic */
-	    preped->used_count++;
-	    preped->last_used = time(NULL);
-
-	    /* do we need to copy the result? */
-	    if (preped->preped != NULL) {
-		/* copy the result */
-		strcpy(in_out_buffer, preped->preped);
-	    }
-
-	    result = STRINGPREP_OK;
-	} else {
-	    /* we need a bigger buffer */
-	    result = STRINGPREP_TOO_SMALL_BUFFER;
-	}
-	
-	/* we're done, release the lock on the cache */
-	pth_mutex_release(&(cache->mutex));
-    } else {
-	char *original;
-
-	/* stringprep needs time, release the lock on the cache for the meantime */
-	pth_mutex_release(&(cache->mutex));
-
-	/* we have to keep the key */
-	original = strdup(in_out_buffer);
-	
-	/* try to prepare the string */
-	result = stringprep(in_out_buffer, max_len, STRINGPREP_NO_UNASSIGNED, cache->profile);
-
-	/* did we manage to prepare the string? */
-	if (result == STRINGPREP_OK && original != NULL) {
-	    /* generate an entry for the cache */
-	    preped = (_jid_prep_entry_t)malloc(sizeof(struct _jid_prep_entry_st));
-	    if (preped != NULL) {
-		/* has there been modified something? */
-		if (j_strcmp(in_out_buffer, original) == 0) {
-		    /* no, we don't need to store a copy of the original string */
-		    preped->preped = NULL;
-		} else {
-		    /* yes, store the stringpreped string */
-		    preped->preped = strdup(in_out_buffer);
-		}
-		preped->last_used = time(NULL);
-		preped->used_count = 1;
-		preped->size = strlen(in_out_buffer)+1;
-
-		/* acquire the lock on the cache again */
-		pth_mutex_acquire(&(cache->mutex), FALSE, NULL);
-
-		/* store the entry in the cache */
-		xhash_put(cache->hashtable, original, preped);
-
-		/* we're done, release the lock on the cache */
-		pth_mutex_release(&(cache->mutex));
-	    } else {
-		/* we don't need the copy of the key, if there is no memory to store it */
-		free(original);
-	    }
-	} else {
-	    /* we don't need the copy of the original value */
-	    if (original != NULL)
-		free(original);
-	}
-    }
-
-    return result;
-}
-
-/**
- * free a single stringprep cache
- *
- * @param cache the cache to free
- */
-void _jid_stop_single_cache(_jid_prep_cache_t *cache) {
-    if (*cache == NULL)
-	return;
-
-    _jid_clean_single_cache(*cache, time(NULL));
-    
-    pth_mutex_acquire(&((*cache)->mutex), FALSE, NULL);
-    xhash_free((*cache)->hashtable);
-
-    free(*cache);
-
-    *cache = NULL;
-}
-
-/**
- * init a single stringprep cache
- *
- * @param cache the cache to init
- * @param prime the prime used to init the hashtable
- * @param profile profile used to prepare the strings
- */
-void _jid_init_single_cache(_jid_prep_cache_t *cache, int prime, const Stringprep_profile *profile) {
-    /* do not init a cache twice */
-    if (*cache == NULL) {
-	*cache = (_jid_prep_cache_t)malloc(sizeof(struct _jid_prep_cache_st));
-	pth_mutex_init(&((*cache)->mutex));
-	(*cache)->hashtable = xhash_new(prime);
-	(*cache)->profile = profile;
-    }
-}
-
-/**
- * free the stringprep caches
- */
-void jid_stop_caching() {
-    _jid_stop_single_cache(&_jid_prep_cache_node);
-    _jid_stop_single_cache(&_jid_prep_cache_domain);
-    _jid_stop_single_cache(&_jid_prep_cache_resource);
-}
-
-/**
- * init the stringprep caches
- * (do not call this twice at the same time, we do not have the mutexes yet)
- */
-void jid_init_cache() {
-    /* init the nodeprep cache */
-    _jid_init_single_cache(&_jid_prep_cache_node, 2003, stringprep_xmpp_nodeprep);
-
-    /* init the nameprep cache (domains) */
-    _jid_init_single_cache(&_jid_prep_cache_domain, 2003, stringprep_nameprep);
-
-    /* init the resourceprep cache */
-    _jid_init_single_cache(&_jid_prep_cache_resource, 2003, stringprep_xmpp_resourceprep);
-}
-
-/**
- * nameprep the domain identifier in a JID and check if it is valid
- *
- * @param jid data structure holding the JID
- * @return 0 if JID is valid, non zero otherwise
- */
-int _jid_safe_domain(jid id) {
-    int result=0;
-
-    /* there must be a domain identifier */
-    if (j_strlen(id->server) == 0)
-	return 1;
-
-    /* nameprep the domain identifier */
-    result = _jid_cached_stringprep(id->server, strlen(id->server)+1, _jid_prep_cache_domain);
-    if (result == STRINGPREP_TOO_SMALL_BUFFER) {
-	/* nameprep wants to expand the string, e.g. conversion from &szlig; to ss */
-	size_t biggerbuffersize = 1024;
-	char *biggerbuffer = pmalloc(id->p, biggerbuffersize);
-	if (biggerbuffer == NULL)
-	    return 1;
-	strcpy(biggerbuffer, id->server);
-	result = _jid_cached_stringprep(biggerbuffer, biggerbuffersize, _jid_prep_cache_domain);
-	id->server = biggerbuffer;
-    }
-    if (result != STRINGPREP_OK)
-	return 1;
-
-    /* the namepreped domain must not be longer than 1023 bytes */
-    if (j_strlen(id->server) > 1023)
-	return 1;
-
-    /* if nothing failed, the domain is valid */
-    return 0;
-}
-
-/**
- * nodeprep the node identifier in a JID and check if it is valid
- *
- * @param jid data structure holding the JID
- * @return 0 if JID is valid, non zero otherwise
- */
-int _jid_safe_node(jid id) {
-    int result=0;
-
-    /* it is valid to have no node identifier in the JID */
-    if (id->user == NULL)
-	return 0;
-
-    /* nodeprep */
-    result = _jid_cached_stringprep(id->user, strlen(id->user)+1, _jid_prep_cache_node);
-    if (result == STRINGPREP_TOO_SMALL_BUFFER) {
-	/* nodeprep wants to expand the string, e.g. conversion from &szlig; to ss */
-	size_t biggerbuffersize = 1024;
-	char *biggerbuffer = pmalloc(id->p, biggerbuffersize);
-	if (biggerbuffer == NULL)
-	    return 1;
-	strcpy(biggerbuffer, id->user);
-	result = _jid_cached_stringprep(biggerbuffer, biggerbuffersize, _jid_prep_cache_node);
-	id->user = biggerbuffer;
-    }
-    if (result != STRINGPREP_OK)
-	return 1;
-
-    /* the nodepreped node must not be longer than 1023 bytes */
-    if (j_strlen(id->user) > 1023)
-	return 1;
-
-    /* if nothing failed, the node is valid */
-    return 0;
-}
-
-/**
- * resourceprep the resource identifier in a JID and check if it is valid
- *
- * @param jid data structure holding the JID
- * @return 0 if JID is valid, non zero otherwise
- */
-int _jid_safe_resource(jid id) {
-    int result=0;
-
-    /* it is valid to have no resource identifier in the JID */
-    if (id->resource == NULL)
-	return 0;
-
-    /* resource prep the resource identifier */
-    result = _jid_cached_stringprep(id->resource, strlen(id->resource)+1, _jid_prep_cache_resource);
-    if (result == STRINGPREP_TOO_SMALL_BUFFER) {
-	/* resourceprep wants to expand the string, e.g. conversion from &szlig; to ss */
-	size_t biggerbuffersize = 1024;
-	char *biggerbuffer = pmalloc(id->p, biggerbuffersize);
-	if (biggerbuffer == NULL)
-	    return 1;
-	strcpy(biggerbuffer, id->resource);
-	result = _jid_cached_stringprep(id->resource, strlen(id->resource)+1, _jid_prep_cache_resource);
-	id->resource = biggerbuffer;
-    }
-    if (result != STRINGPREP_OK)
-	return 1;
-
-    /* the resourcepreped node must not be longer than 1023 bytes */
-    if (j_strlen(id->resource) > 1023)
-	return 1;
-
-    /* if nothing failed, the resource is valid */
-    return 0;
-
-}
-
-#else /* no LIBIDN */
-
-/**
- * check if the domain identifier in a JID is valid
- *
- * @param jid data structure holding the JID
- * @return 0 if domain is valid, non zero otherwise
- */
-int _jid_safe_domain(jid id) {
-    char *str;
-
-    /* there must be a domain identifier */
-    if (j_strlen(id->server) == 0)
-	return 1;
-
-    /* and it must not be longer than 1023 bytes */
-    if (strlen(id->server) > 1023)
-	return 1;
-
-    /* lowercase the hostname, make sure it's valid characters */
-    for(str = id->server; *str != '\0'; str++)
-    {
-        *str = tolower(*str);
-        if(!(isalnum(*str) || *str == '.' || *str == '-' || *str == '_')) return 1;
-    }
-
-    /* otherwise it's okay as far as we can tell without LIBIDN */
-    return 0;
-}
-
-/**
- * check if the node identifier in a JID is valid
- *
- * @param jid data structure holding the JID
- * @return 0 if node is valid, non zero otherwise
- */
-int _jid_safe_node(jid id) {
-    char *str;
-
-    /* node identifiers may not be longer than 1023 bytes */
-    if (j_strlen(id->user) > 1023)
-	return 1;
-
-    /* check for low and invalid ascii characters in the username */
-    if(id->user != NULL)
-        for(str = id->user; *str != '\0'; str++)
-            if(*str <= 32 || *str == ':' || *str == '@' || *str == '<' || *str == '>' || *str == '\'' || *str == '"' || *str == '&') return 1;
-
-    /* otherwise it's okay as far as we can tell without LIBIDN */
-    return 0;
-}
-
-/**
- * check if the resource identifier in a JID is valid
- *
- * @param jid data structure holding the JID
- * @return 0 if resource is valid, non zero otherwise
- */
-int _jid_safe_resource(jid id) {
-    /* resources may not be longer than 1023 bytes */
-    if (j_strlen(id->resource) > 1023)
-	return 1;
-
-    /* otherwise it's okay as far as we can tell without LIBIDN */
-    return 0;
-}
-
-#endif
-
-/**
- * nodeprep/nameprep/resourceprep the JID and check if it is valid
- *
- * @param jid data structure holding the JID
- * @return NULL if the JID is invalid, pointer to the jid otherwise
- */
-jid jid_safe(jid id)
-{
-    if (_jid_safe_domain(id))
-	return NULL;
-    if (_jid_safe_node(id))
-	return NULL;
-    if (_jid_safe_resource(id))
-	return NULL;
-
-    return id;
-}
-
-jid jid_new(pool p, char *idstr)
-{
-    char *server, *resource, *type, *str;
-    jid id;
-
-    if(p == NULL || idstr == NULL || strlen(idstr) == 0)
-        return NULL;
-
-    /* user@server/resource */
-
-    str = pstrdup(p, idstr);
-
-    id = pmalloco(p,sizeof(struct jid_struct));
-    id->p = p;
-
-    resource = strstr(str,"/");
-    if(resource != NULL)
-    {
-        *resource = '\0';
-        ++resource;
-        if(strlen(resource) > 0)
-            id->resource = resource;
-    }else{
-        resource = str + strlen(str); /* point to end */
-    }
-
-    type = strstr(str,":");
-    if(type != NULL && type < resource)
-    {
-        *type = '\0';
-        ++type;
-        str = type; /* ignore the type: prefix */
-    }
-
-    server = strstr(str,"@");
-    if(server == NULL || server > resource)
-    { /* if there's no @, it's just the server address */
-        id->server = str;
-    }else{
-        *server = '\0';
-        ++server;
-        id->server = server;
-        if(strlen(str) > 0)
-            id->user = str;
-    }
-
-    return jid_safe(id);
-}
-
-void jid_set(jid id, char *str, int item)
-{
-    char *old;
-
-    if(id == NULL)
-        return;
-
-    /* invalidate the cached copy */
-    id->full = NULL;
-
-    switch(item)
-    {
-    case JID_RESOURCE:
-	old = id->resource;
-        if(str != NULL && strlen(str) != 0)
-            id->resource = pstrdup(id->p, str);
-        else
-            id->resource = NULL;
-        if(_jid_safe_resource(id))
-            id->resource = old; /* revert if invalid */
-        break;
-    case JID_USER:
-        old = id->user;
-        if(str != NULL && strlen(str) != 0)
-            id->user = pstrdup(id->p, str);
-        else
-            id->user = NULL;
-        if(_jid_safe_node(id))
-            id->user = old; /* revert if invalid */
-        break;
-    case JID_SERVER:
-        old = id->server;
-        id->server = pstrdup(id->p, str);
-        if(_jid_safe_domain(id))
-            id->server = old; /* revert if invalid */
-        break;
-    }
-
-}
-
-char *jid_full(jid id)
-{
-    spool s;
-
-    if(id == NULL)
-        return NULL;
-
-    /* use cached copy */
-    if(id->full != NULL)
-        return id->full;
-
-    s = spool_new(id->p);
-
-    if(id->user != NULL)
-        spooler(s, id->user,"@",s);
-
-    spool_add(s, id->server);
-
-    if(id->resource != NULL)
-        spooler(s, "/",id->resource,s);
-
-    id->full = spool_print(s);
-    return id->full;
-}
-
-/* parses a /resource?name=value&foo=bar into an xmlnode representing <resource name="value" foo="bar"/> */
-xmlnode jid_xres(jid id)
-{
-    char *cur, *qmark, *amp, *eq;
-    xmlnode x;
-
-    if(id == NULL || id->resource == NULL) return NULL;
-
-    cur = pstrdup(id->p, id->resource);
-    qmark = strstr(cur, "?");
-    if(qmark == NULL) return NULL;
-    *qmark = '\0';
-    qmark++;
-
-    x = _xmlnode_new(id->p, cur, NTYPE_TAG);
-
-    cur = qmark;
-    while(cur != '\0')
-    {
-        eq = strstr(cur, "=");
-        if(eq == NULL) break;
-        *eq = '\0';
-        eq++;
-
-        amp = strstr(eq, "&");
-        if(amp != NULL)
-        {
-            *amp = '\0';
-            amp++;
-        }
-
-        xmlnode_put_attrib(x,cur,eq);
-
-        if(amp != NULL)
-            cur = amp;
-        else
-            break;
-    }
-
-    return x;
-}
-
-/* local utils */
-int _jid_nullstrcmp(char *a, char *b)
-{
-    if(a == NULL && b == NULL) return 0;
-    if(a == NULL || b == NULL) return -1;
-    return strcmp(a,b);
-}
-int _jid_nullstrcasecmp(char *a, char *b)
-{
-    if(a == NULL && b == NULL) return 0;
-    if(a == NULL || b == NULL) return -1;
-    return strcasecmp(a,b);
-}
-
-int jid_cmp(jid a, jid b)
-{
-    if(a == NULL || b == NULL)
-        return -1;
-
-    if(_jid_nullstrcmp(a->resource, b->resource) != 0) return -1;
-    if(_jid_nullstrcasecmp(a->user, b->user) != 0) return -1;
-    if(_jid_nullstrcmp(a->server, b->server) != 0) return -1;
-
-    return 0;
-}
-
-/* suggested by Anders Qvist <quest@valdez.netg.se> */
-int jid_cmpx(jid a, jid b, int parts)
-{
-    if(a == NULL || b == NULL)
-        return -1;
-
-    if(parts & JID_RESOURCE && _jid_nullstrcmp(a->resource, b->resource) != 0) return -1;
-    if(parts & JID_USER && _jid_nullstrcasecmp(a->user, b->user) != 0) return -1;
-    if(parts & JID_SERVER && _jid_nullstrcmp(a->server, b->server) != 0) return -1;
-
-    return 0;
-}
-
-/* makes a copy of b in a's pool, requires a valid a first! */
-jid jid_append(jid a, jid b)
-{
-    jid next;
-
-    if(a == NULL)
-        return NULL;
-
-    if(b == NULL)
-        return a;
-
-    next = a;
-    while(next != NULL)
-    {
-        /* check for dups */
-        if(jid_cmp(next,b) == 0)
-            break;
-        if(next->next == NULL)
-            next->next = jid_new(a->p,jid_full(b));
-        next = next->next;
-    }
-    return a;
-}
-
-xmlnode jid_nodescan(jid id, xmlnode x)
-{
-    xmlnode cur;
-    pool p;
-    jid tmp;
-
-    if(id == NULL || xmlnode_get_firstchild(x) == NULL) return NULL;
-
-    p = pool_new();
-    for(cur = xmlnode_get_firstchild(x); cur != NULL; cur = xmlnode_get_nextsibling(cur))
-    {
-        if(xmlnode_get_type(cur) != NTYPE_TAG) continue;
-
-        tmp = jid_new(p,xmlnode_get_attrib(cur,"jid"));
-        if(tmp == NULL) continue;
-
-        if(jid_cmp(tmp,id) == 0) break;
-    }
-    pool_free(p);
-
-    return cur;
-}
-
-jid jid_user(jid a)
-{
-    jid ret;
-
-    if(a == NULL || a->resource == NULL) return a;
-
-    ret = pmalloco(a->p,sizeof(struct jid_struct));
-    ret->p = a->p;
-    ret->user = a->user;
-    ret->server = a->server;
-
-    return ret;
-}
--- a/mcabber/libjabber/jpacket.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyrights
- *
- * Portions created by or assigned to Jabber.com, Inc. are
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- *
- * Acknowledgements
- *
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- *
- */
-
-/**
- * @file jpacket.c
- * @brief a jpacket is a wrapper around an xmlnode that contains an XMPP stanza
- *
- * A jpacket adds some variables to an xmlnode that contains a stanza, so that
- * jabberd is able to cache information on the stanza type (message, presence, iq)
- * that is contained in this jpacket and to further classify the presence stanzas.
- * It also adds some pointers to important data inside the xmlnode, that has
- * to be accessed often (e.g. sender and receiver of a stanza).
- */
-
-#include "jabber.h"
-
-/**
- * create a new jpacket by wrapping an xmlnode
- *
- * @param x the xmlnode that should be wrapped
- * @return the newly created jpacket (NULL on failure)
- */
-jpacket jpacket_new(xmlnode x)
-{
-    jpacket p;
-
-    if(x == NULL)
-        return NULL;
-
-    p = pmalloc(xmlnode_pool(x),sizeof(_jpacket));
-    p->x = x;
-
-    return jpacket_reset(p);
-}
-
-/**
- * recalculate the information the jpacket holds about the stanza
- *
- * @param p the packet that should get its information recalculated
- * @return the jpacket (as given as the p parameter)
- */
-jpacket jpacket_reset(jpacket p)
-{
-    char *val;
-    xmlnode x;
-
-    x = p->x;
-    memset(p,0,sizeof(_jpacket));
-    p->x = x;
-    p->p = xmlnode_pool(x);
-
-    if(strncmp(xmlnode_get_name(x),"message",7) == 0) {
-        p->type = JPACKET_MESSAGE;
-    } else if(strncmp(xmlnode_get_name(x),"presence",8) == 0) {
-        p->type = JPACKET_PRESENCE;
-        val = xmlnode_get_attrib(x, "type");
-        if(val == NULL)
-            p->subtype = JPACKET__AVAILABLE;
-        else if(strcmp(val,"unavailable") == 0)
-            p->subtype = JPACKET__UNAVAILABLE;
-        else if(strcmp(val,"probe") == 0)
-            p->subtype = JPACKET__PROBE;
-        else if(strcmp(val,"error") == 0)
-            p->subtype = JPACKET__ERROR;
-        else if(strcmp(val,"invisible") == 0)
-            p->subtype = JPACKET__INVISIBLE;
-        else if(*val == 's' || *val == 'u')
-            p->type = JPACKET_S10N;
-        else if(strcmp(val,"available") == 0) {
-	    /* someone is using type='available' which is frowned upon */
-	    /* XXX better reject this presence? */
-            xmlnode_hide_attrib(x,"type");
-            p->subtype = JPACKET__AVAILABLE;
-        } else
-            p->type = JPACKET_UNKNOWN;
-    } else if(strncmp(xmlnode_get_name(x),"iq",2) == 0) {
-        p->type = JPACKET_IQ;
-        p->iq = xmlnode_get_tag(x,"?xmlns");
-        p->iqns = xmlnode_get_attrib(p->iq,"xmlns");
-    }
-
-    /* set up the jids if any, flag packet as unknown if they are unparseable */
-    val = xmlnode_get_attrib(x,"to");
-    if(val != NULL)
-        if((p->to = jid_new(p->p, val)) == NULL)
-            p->type = JPACKET_UNKNOWN;
-    val = xmlnode_get_attrib(x,"from");
-    if(val != NULL)
-        if((p->from = jid_new(p->p, val)) == NULL)
-            p->type = JPACKET_UNKNOWN;
-
-    return p;
-}
-
-/**
- * get the subtype of a jpacket
- *
- * @param p the jpacket for which the caller wants to know the subtype
- * @return the subtype of the jpacket (one of the JPACKET__* constants)
- */
-int jpacket_subtype(jpacket p)
-{
-    char *type;
-    int ret = p->subtype;
-
-    if(ret != JPACKET__UNKNOWN)
-        return ret;
-
-    ret = JPACKET__NONE; /* default, when no type attrib is specified */
-    type = xmlnode_get_attrib(p->x, "type");
-    if(j_strcmp(type,"error") == 0)
-        ret = JPACKET__ERROR;
-    else
-        switch(p->type)
-        {
-        case JPACKET_MESSAGE:
-            if(j_strcmp(type,"chat") == 0)
-                ret = JPACKET__CHAT;
-            else if(j_strcmp(type,"groupchat") == 0)
-                ret = JPACKET__GROUPCHAT;
-            else if(j_strcmp(type,"headline") == 0)
-                ret = JPACKET__HEADLINE;
-            break;
-        case JPACKET_S10N:
-            if(j_strcmp(type,"subscribe") == 0)
-                ret = JPACKET__SUBSCRIBE;
-            else if(j_strcmp(type,"subscribed") == 0)
-                ret = JPACKET__SUBSCRIBED;
-            else if(j_strcmp(type,"unsubscribe") == 0)
-                ret = JPACKET__UNSUBSCRIBE;
-            else if(j_strcmp(type,"unsubscribed") == 0)
-                ret = JPACKET__UNSUBSCRIBED;
-            break;
-        case JPACKET_IQ:
-            if(j_strcmp(type,"get") == 0)
-                ret = JPACKET__GET;
-            else if(j_strcmp(type,"set") == 0)
-                ret = JPACKET__SET;
-            else if(j_strcmp(type,"result") == 0)
-                ret = JPACKET__RESULT;
-            break;
-        }
-
-    p->subtype = ret;
-    return ret;
-}
--- a/mcabber/libjabber/jutil.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,415 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyrights
- *
- * Portions created by or assigned to Jabber.com, Inc. are
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- *
- * Acknowledgements
- *
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- *
- */
-
-/**
- * @file jutil.c
- * @brief various utilities mainly for handling xmlnodes containing stanzas
- */
-
-#include "jabber.h"
-
-/**
- * utility for making presence stanzas
- *
- * @param type the type of the presence (one of the JPACKET__* contants)
- * @param to to whom the presence should be sent, NULL for a broadcast presence
- * @param status optional status (CDATA for the <status/> element, NULL for now <status/> element)
- * @return the xmlnode containing the created presence stanza
- */
-xmlnode jutil_presnew(int type, char *to, char *status)
-{
-    xmlnode pres;
-
-    pres = xmlnode_new_tag("presence");
-    switch(type)
-    {
-    case JPACKET__SUBSCRIBE:
-        xmlnode_put_attrib(pres,"type","subscribe");
-        break;
-    case JPACKET__UNSUBSCRIBE:
-        xmlnode_put_attrib(pres,"type","unsubscribe");
-        break;
-    case JPACKET__SUBSCRIBED:
-        xmlnode_put_attrib(pres,"type","subscribed");
-        break;
-    case JPACKET__UNSUBSCRIBED:
-        xmlnode_put_attrib(pres,"type","unsubscribed");
-        break;
-    case JPACKET__PROBE:
-        xmlnode_put_attrib(pres,"type","probe");
-        break;
-    case JPACKET__UNAVAILABLE:
-        xmlnode_put_attrib(pres,"type","unavailable");
-        break;
-    case JPACKET__INVISIBLE:
-        xmlnode_put_attrib(pres,"type","invisible");
-        break;
-    }
-    if(to != NULL)
-        xmlnode_put_attrib(pres,"to",to);
-    if(status != NULL)
-        xmlnode_insert_cdata(xmlnode_insert_tag(pres,"status"),status,strlen(status));
-
-    return pres;
-}
-
-/**
- * utility for making IQ stanzas, that contain a <query/> element in a different namespace
- *
- * @note In traditional Jabber protocols the element inside an iq element has the name "query".
- * This util is not able to create IQ stanzas that contain a query which a element that does
- * not have the name "query"
- *
- * @param type the type of the iq stanza (one of JPACKET__GET, JPACKET__SET, JPACKET__RESULT, JPACKET__ERROR)
- * @param ns the namespace of the <query/> element
- * @return the created xmlnode
- */
-xmlnode jutil_iqnew(int type, char *ns)
-{
-    xmlnode iq;
-
-    iq = xmlnode_new_tag("iq");
-    switch(type)
-    {
-    case JPACKET__GET:
-        xmlnode_put_attrib(iq,"type","get");
-        break;
-    case JPACKET__SET:
-        xmlnode_put_attrib(iq,"type","set");
-        break;
-    case JPACKET__RESULT:
-        xmlnode_put_attrib(iq,"type","result");
-        break;
-    case JPACKET__ERROR:
-        xmlnode_put_attrib(iq,"type","error");
-        break;
-    }
-    xmlnode_put_attrib(xmlnode_insert_tag(iq,"query"),"xmlns",ns);
-
-    return iq;
-}
-
-/**
- * utility for making message stanzas
- *
- * @param type the type of the message (as a string!)
- * @param to the recipient of the message
- * @param subj the subject of the message (NULL for no subject element)
- * @param body the body of the message
- * @return the xmlnode containing the new message stanza
- */
-xmlnode jutil_msgnew(char *type, char *to, char *subj, char *body)
-{
-    xmlnode msg;
-
-    msg = xmlnode_new_tag("message");
-
-    if (type != NULL) {
-	xmlnode_put_attrib (msg, "type", type);
-    }
-
-    if (to != NULL) {
-	xmlnode_put_attrib (msg, "to", to);
-    }
-
-    if (subj != NULL) {
-	xmlnode_insert_cdata(xmlnode_insert_tag(msg, "subject"), subj, strlen(subj));
-    }
-
-    if (body != NULL) {
-	xmlnode_insert_cdata(xmlnode_insert_tag(msg, "body"), body, strlen(body));
-    }
-
-    return msg;
-}
-
-/**
- * utility for making stream packets (containing the stream header element)
- *
- * @param xmlns the default namespace of the stream (e.g. jabber:client or jabber:server)
- * @param server the domain of the server
- * @return the xmlnode containing the root element of the stream
- */
-xmlnode jutil_header(char* xmlns, char* server)
-{
-     xmlnode result;
-     if ((xmlns == NULL)||(server == NULL))
-	  return NULL;
-     result = xmlnode_new_tag("stream:stream");
-     xmlnode_put_attrib(result, "xmlns:stream", "http://etherx.jabber.org/streams");
-     xmlnode_put_attrib(result, "xmlns", xmlns);
-     xmlnode_put_attrib(result, "to", server);
-
-     return result;
-}
-
-/**
- * returns the priority on an available presence packet
- *
- * @param xmlnode the xmlnode containing the presence packet
- * @return the presence priority, -129 for unavailable presences and errors
- */
-int jutil_priority(xmlnode x)
-{
-    char *str;
-    int p;
-
-    if(x == NULL)
-        return -129;
-
-    if(xmlnode_get_attrib(x,"type") != NULL)
-        return -129;
-
-    x = xmlnode_get_tag(x,"priority");
-    if(x == NULL)
-        return 0;
-
-    str = xmlnode_get_data((x));
-    if(str == NULL)
-        return 0;
-
-    p = atoi(str);
-    /* xmpp-im section 2.2.2.3 */
-    return p<-128 ? -128 : p>127 ? 127 : p;
-}
-
-/**
- * reverse sender and destination of a packet
- *
- * @param x the xmlnode where sender and receiver should be exchanged
- */
-void jutil_tofrom(xmlnode x)
-{
-    char *to, *from;
-
-    to = xmlnode_get_attrib(x,"to");
-    from = xmlnode_get_attrib(x,"from");
-    xmlnode_put_attrib(x,"from",to);
-    xmlnode_put_attrib(x,"to",from);
-}
-
-/**
- * change and xmlnode to be the result xmlnode for the original iq query
- *
- * @param x the xmlnode that should become the result for itself
- * @return the result xmlnode (same as given as parameter x)
- */
-xmlnode jutil_iqresult(xmlnode x)
-{
-    xmlnode cur;
-
-    jutil_tofrom(x);
-
-    xmlnode_put_attrib(x,"type","result");
-
-    /* hide all children of the iq, they go back empty */
-    for(cur = xmlnode_get_firstchild(x); cur != NULL; cur = xmlnode_get_nextsibling(cur))
-        xmlnode_hide(cur);
-
-    return x;
-}
-
-/**
- * get the present time as a textual timestamp in the format YYYYMMDDTHH:MM:SS
- *
- * @note this function is not thread safe
- *
- * @return pointer to a static (!) buffer containing the timestamp (or NULL on failure)
- */
-char *jutil_timestamp(void)
-{
-    time_t t;
-    struct tm *new_time;
-    static char timestamp[18];
-    int ret;
-
-    t = time(NULL);
-
-    if(t == (time_t)-1)
-        return NULL;
-    new_time = gmtime(&t);
-
-    ret = snprintf(timestamp, 18, "%d%02d%02dT%02d:%02d:%02d", 1900+new_time->tm_year,
-                   new_time->tm_mon+1, new_time->tm_mday, new_time->tm_hour,
-                   new_time->tm_min, new_time->tm_sec);
-
-    if(ret == -1)
-        return NULL;
-
-    return timestamp;
-}
-
-/**
- * map a terror structure to a xterror structure
- *
- * terror structures have been used in jabberd14 up to version 1.4.3 but
- * are not able to hold XMPP compliant stanza errors. The xterror
- * structure has been introduced to be XMPP compliant. This function
- * is to ease writting wrappers that accept terror structures and call
- * the real functions that require now xterror structures
- *
- * @param old the terror struct that should be converted
- * @param mapped pointer to the xterror struct that should be filled with the converted error
- */
-void jutil_error_map(terror old, xterror *mapped)
-{
-    mapped->code = old.code;
-    if (old.msg == NULL)
-	mapped->msg[0] = 0;
-    else
-	strncpy(mapped->msg, old.msg, sizeof(mapped->msg));
-
-    switch (old.code)
-    {
-	case 302:
-	    strcpy(mapped->type, "modify");
-	    strcpy(mapped->condition, "redirect");
-	    break;
-	case 400:
-	    strcpy(mapped->type, "modify");
-	    strcpy(mapped->condition, "bad-request");
-	    break;
-	case 401:
-	    strcpy(mapped->type, "auth");
-	    strcpy(mapped->condition, "not-authorized");
-	    break;
-	case 402:
-	    strcpy(mapped->type, "auth");
-	    strcpy(mapped->condition, "payment-required");
-	    break;
-	case 403:
-	    strcpy(mapped->type, "auth");
-	    strcpy(mapped->condition, "forbidden");
-	    break;
-	case 404:
-	    strcpy(mapped->type, "cancel");
-	    strcpy(mapped->condition, "item-not-found");
-	    break;
-	case 405:
-	    strcpy(mapped->type, "cancel");
-	    strcpy(mapped->condition, "not-allowed");
-	    break;
-	case 406:
-	    strcpy(mapped->type, "modify");
-	    strcpy(mapped->condition, "not-acceptable");
-	    break;
-	case 407:
-	    strcpy(mapped->type, "auth");
-	    strcpy(mapped->condition, "registration-requited");
-	    break;
-	case 408:
-	    strcpy(mapped->type, "wait");
-	    strcpy(mapped->condition, "remote-server-timeout");
-	    break;
-	case 409:
-	    strcpy(mapped->type, "cancel");
-	    strcpy(mapped->condition, "conflict");
-	    break;
-	case 500:
-	    strcpy(mapped->type, "wait");
-	    strcpy(mapped->condition, "internal-server-error");
-	    break;
-	case 501:
-	    strcpy(mapped->type, "cancel");
-	    strcpy(mapped->condition, "feature-not-implemented");
-	    break;
-	case 502:
-	    strcpy(mapped->type, "wait");
-	    strcpy(mapped->condition, "service-unavailable");
-	    break;
-	case 503:
-	    strcpy(mapped->type, "cancel");
-	    strcpy(mapped->condition, "service-unavailable");
-	    break;
-	case 504:
-	    strcpy(mapped->type, "wait");
-	    strcpy(mapped->condition, "remote-server-timeout");
-	    break;
-	case 510:
-	    strcpy(mapped->type, "cancel");
-	    strcpy(mapped->condition, "service-unavailable");
-	    break;
-	default:
-	    strcpy(mapped->type, "wait");
-	    strcpy(mapped->condition, "undefined-condition");
-    }
-}
-
-/**
- * update an xmlnode to be the error stanza for itself
- *
- * @param x the xmlnode that should become an stanza error message
- * @param E the structure that holds the error information
- */
-void jutil_error_xmpp(xmlnode x, xterror E)
-{
-    xmlnode err;
-    char code[4];
-
-    xmlnode_put_attrib(x, "type", "error");
-    err = xmlnode_insert_tag(x, "error");
-
-    snprintf(code, sizeof(code), "%d", E.code);
-    xmlnode_put_attrib(err, "code", code);
-    if (E.type != NULL)
-	xmlnode_put_attrib(err, "type", E.type);
-    if (E.condition != NULL)
-	xmlnode_put_attrib(xmlnode_insert_tag(err, E.condition), "xmlns", NS_XMPP_STANZAS);
-    if (E.msg != NULL)
-    {
-	xmlnode text;
-	text = xmlnode_insert_tag(err, "text");
-	xmlnode_put_attrib(text, "xmlns", NS_XMPP_STANZAS);
-	xmlnode_insert_cdata(text, E.msg, strlen(E.msg));
-    }
-
-    jutil_tofrom(x);
-}
-
-/**
- * add a delayed delivery (JEP-0091) element to a message using the
- * present timestamp.
- * If a reason is given, this reason will be added as CDATA to the
- * inserted element
- *
- * @param msg the message where the element should be added
- * @param reason plain text information why the delayed delivery information has been added
- */
-void jutil_delay(xmlnode msg, char *reason)
-{
-    xmlnode delay;
-
-    delay = xmlnode_insert_tag(msg,"x");
-    xmlnode_put_attrib(delay,"xmlns",NS_DELAY);
-    xmlnode_put_attrib(delay,"from",xmlnode_get_attrib(msg,"to"));
-    xmlnode_put_attrib(delay,"stamp",jutil_timestamp());
-    if(reason != NULL)
-        xmlnode_insert_cdata(delay,reason,strlen(reason));
-}
--- a/mcabber/libjabber/latin1tab.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
-/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
-/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
-/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
--- a/mcabber/libjabber/libxode.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,468 +0,0 @@
-/*
- * jabberd - Jabber Open Source Server
- * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
- *                    Ryan Eatmon, Robert Norris
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
- */
-
-#ifdef HAVE_CONFIG_H
-#   include <config.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <setjmp.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-#include <strings.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <syslog.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-
-#include "xmlparse.h"
-
-/*
-**  Arrange to use either varargs or stdargs
-*/
-
-#define MAXSHORTSTR    203        /* max short string length */
-#define QUAD_T    unsigned long long
-
-#ifdef __STDC__
-
-#include <stdarg.h>
-
-# define VA_LOCAL_DECL  va_list ap;
-# define VA_START(f)    va_start(ap, f)
-# define VA_END         va_end(ap)
-
-#else /* __STDC__ */
-
-# include <varargs.h>
-
-# define VA_LOCAL_DECL  va_list ap;
-# define VA_START(f)    va_start(ap)
-# define VA_END         va_end(ap)
-
-#endif /* __STDC__ */
-
-
-#ifndef INCL_LIBXODE_H
-#define INCL_LIBXODE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#ifndef HAVE_SNPRINTF
-extern int ap_snprintf(char *, size_t, const char *, ...);
-#define snprintf ap_snprintf
-#endif
-
-#ifndef HAVE_VSNPRINTF
-extern int ap_vsnprintf(char *, size_t, const char *, va_list ap);
-#define vsnprintf ap_vsnprintf
-#endif
-
-#define ZONE zonestr(__FILE__,__LINE__)
-char *zonestr(char *file, int line);
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Pool-based memory management routines                     */
-/*                                                           */
-/* --------------------------------------------------------- */
-
-#undef POOL_DEBUG
-/*
- flip these, this should be a prime number for top # of pools debugging
-#define POOL_DEBUG 40009
-*/
-
-/* pheap - singular allocation of memory */
-struct pheap
-{
-    void *block;
-    int size, used;
-};
-
-/* pool_cleaner - callback type which is associated
-   with a pool entry; invoked when the pool entry is
-   free'd */
-typedef void (*pool_cleaner)(void *arg);
-
-/* pfree - a linked list node which stores an
-   allocation chunk, plus a callback */
-struct pfree
-{
-    pool_cleaner f;
-    void *arg;
-    struct pheap *heap;
-    struct pfree *next;
-};
-
-/* pool - base node for a pool. Maintains a linked list
-   of pool entries (pfree) */
-typedef struct pool_struct
-{
-    int size;
-    struct pfree *cleanup;
-    struct pheap *heap;
-#ifdef POOL_DEBUG
-    char name[8], zone[32];
-    int lsize;
-} _pool, *pool;
-#define pool_new() _pool_new(__FILE__,__LINE__)
-#define pool_heap(i) _pool_new_heap(i,__FILE__,__LINE__)
-#else
-} _pool, *pool;
-#define pool_heap(i) _pool_new_heap(i, NULL, 0)
-#define pool_new() _pool_new(NULL, 0)
-#endif
-
-pool _pool_new(char *zone, int line); /* new pool :) */
-pool _pool_new_heap(int size, char *zone, int line); /* creates a new memory pool with an initial heap size */
-void *pmalloc(pool p, int size); /* wrapper around malloc, takes from the pool, cleaned up automatically */
-void *pmalloc_x(pool p, int size, char c); /* Wrapper around pmalloc which prefils buffer with c */
-void *pmalloco(pool p, int size); /* YAPW for zeroing the block */
-char *pstrdup(pool p, const char *src); /* wrapper around strdup, gains mem from pool */
-void pool_stat(int full); /* print to stderr the changed pools and reset */
-char *pstrdupx(pool p, const char *src); /* temp stub */
-void pool_cleanup(pool p, pool_cleaner f, void *arg); /* calls f(arg) before the pool is freed during cleanup */
-void pool_free(pool p); /* calls the cleanup functions, frees all the data on the pool, and deletes the pool itself */
-int pool_size(pool p); /* returns total bytes allocated in this pool */
-
-
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Socket helper stuff                                       */
-/*                                                           */
-/* --------------------------------------------------------- */
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-#define NETSOCKET_SERVER 0
-#define NETSOCKET_CLIENT 1
-#define NETSOCKET_UDP 2
-
-#ifndef WIN32
-int make_netsocket(u_short port, char *host, int type, int ssl);
-int make_nb_netsocket(u_short port, char *host, int type, int ssl, int * state);
-void change_socket_to_blocking(int socket);
-struct in_addr *make_addr(char *host);
-int set_fd_close_on_exec(int fd, int flag);
-#endif
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* String management routines                                */
-/*                                                           */
-/* --------------------------------------------------------- */
-char *j_strdup(const char *str); /* provides NULL safe strdup wrapper */
-char *j_strcat(char *dest, char *txt); /* strcpy() clone */
-int j_strcmp(const char *a, const char *b); /* provides NULL safe strcmp wrapper */
-int j_strcasecmp(const char *a, const char *b); /* provides NULL safe strcasecmp wrapper */
-int j_strncmp(const char *a, const char *b, int i); /* provides NULL safe strncmp wrapper */
-int j_strncasecmp(const char *a, const char *b, int i); /* provides NULL safe strncasecmp wrapper */
-int j_strlen(const char *a); /* provides NULL safe strlen wrapper */
-int j_atoi(const char *a, int def); /* checks for NULL and uses default instead, convienence */
-void str_b64decode(char *str); /* what it says */
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* SHA calculations                                          */
-/*                                                           */
-/* --------------------------------------------------------- */
-#if (SIZEOF_INT == 4)
-typedef unsigned int uint32;
-#elif (SIZEOF_SHORT == 4)
-typedef unsigned short uint32;
-#else
-typedef unsigned int uint32;
-#endif /* HAVEUINT32 */
-
-int sha_hash(int *data, int *hash);
-int sha_init(int *hash);
-char *shahash(char *str);       /* NOT THREAD SAFE */
-void shahash_r(const char* str, char hashbuf[40]); /* USE ME */
-
-int strprintsha(char *dest, int *hashval);
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Hashtable functions                                       */
-/*                                                           */
-/* --------------------------------------------------------- */
-typedef int (*KEYHASHFUNC)(const void *key);
-typedef int (*KEYCOMPAREFUNC)(const void *key1, const void *key2);
-typedef int (*TABLEWALKFUNC)(void *user_data, const void *key, void *data);
-
-typedef void *HASHTABLE;
-
-HASHTABLE ghash_create(int buckets, KEYHASHFUNC hash, KEYCOMPAREFUNC cmp);
-void ghash_destroy(HASHTABLE tbl);
-void *ghash_get(HASHTABLE tbl, const void *key);
-int ghash_put(HASHTABLE tbl, const void *key, void *value);
-int ghash_remove(HASHTABLE tbl, const void *key);
-int ghash_walk(HASHTABLE tbl, TABLEWALKFUNC func, void *user_data);
-int str_hash_code(const char *s);
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* XML escaping utils                                        */
-/*                                                           */
-/* --------------------------------------------------------- */
-char *strescape(pool p, char *buf); /* Escape <>&'" chars */
-char *strunescape(pool p, char *buf);
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* String pools (spool) functions                            */
-/*                                                           */
-/* --------------------------------------------------------- */
-struct spool_node
-{
-    char *c;
-    struct spool_node *next;
-};
-
-typedef struct spool_struct
-{
-    pool p;
-    int len;
-    struct spool_node *last;
-    struct spool_node *first;
-} *spool;
-
-spool spool_new(pool p); /* create a string pool */
-void spooler(spool s, ...); /* append all the char * args to the pool, terminate args with s again */
-char *spool_print(spool s); /* return a big string */
-void spool_add(spool s, char *str); /* add a single string to the pool */
-char *spools(pool p, ...); /* wrap all the spooler stuff in one function, the happy fun ball! */
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* xmlnodes - Document Object Model                          */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define NTYPE_TAG    0
-#define NTYPE_ATTRIB 1
-#define NTYPE_CDATA  2
-
-#define NTYPE_LAST   2
-#define NTYPE_UNDEF  -1
-
-/* --------------------------------------------------------------------------
-   Node structure. Do not use directly! Always use accessor macros
-   and methods!
-   -------------------------------------------------------------------------- */
-typedef struct xmlnode_t
-{
-     char*               name;
-     unsigned short      type;
-     char*               data;
-     int                 data_sz;
-     int                 complete;
-     pool               p;
-     struct xmlnode_t*  parent;
-     struct xmlnode_t*  firstchild;
-     struct xmlnode_t*  lastchild;
-     struct xmlnode_t*  prev;
-     struct xmlnode_t*  next;
-     struct xmlnode_t*  firstattrib;
-     struct xmlnode_t*  lastattrib;
-} _xmlnode, *xmlnode;
-
-/* Node creation routines */
-xmlnode  xmlnode_wrap(xmlnode x,const char* wrapper);
-xmlnode  xmlnode_new_tag(const char* name);
-xmlnode  xmlnode_new_tag_pool(pool p, const char* name);
-xmlnode  xmlnode_insert_tag(xmlnode parent, const char* name);
-xmlnode  xmlnode_insert_cdata(xmlnode parent, const char* CDATA, unsigned int size);
-xmlnode  xmlnode_insert_tag_node(xmlnode parent, xmlnode node);
-void     xmlnode_insert_node(xmlnode parent, xmlnode node);
-xmlnode  xmlnode_str(char *str, int len);
-xmlnode  xmlnode_file(char *file);
-xmlnode  xmlnode_dup(xmlnode x); /* duplicate x */
-xmlnode  xmlnode_dup_pool(pool p, xmlnode x);
-
-/* Node Memory Pool */
-pool xmlnode_pool(xmlnode node);
-xmlnode _xmlnode_new(pool p, const char *name, unsigned int type);
-
-/* Node editing */
-void xmlnode_hide(xmlnode child);
-void xmlnode_hide_attrib(xmlnode parent, const char *name);
-
-/* Node deletion routine, also frees the node pool! */
-void xmlnode_free(xmlnode node);
-
-/* Locates a child tag by name and returns it */
-xmlnode  xmlnode_get_tag(xmlnode parent, const char* name);
-char* xmlnode_get_tag_data(xmlnode parent, const char* name);
-
-/* Attribute accessors */
-void     xmlnode_put_attrib(xmlnode owner, const char* name, const char* value);
-char*    xmlnode_get_attrib(xmlnode owner, const char* name);
-void     xmlnode_put_expat_attribs(xmlnode owner, const char** atts);
-
-/* Bastard am I, but these are fun for internal use ;-) */
-void     xmlnode_put_vattrib(xmlnode owner, const char* name, void *value);
-void*    xmlnode_get_vattrib(xmlnode owner, const char* name);
-
-/* Node traversal routines */
-xmlnode  xmlnode_get_firstattrib(xmlnode parent);
-xmlnode  xmlnode_get_firstchild(xmlnode parent);
-xmlnode  xmlnode_get_lastchild(xmlnode parent);
-xmlnode  xmlnode_get_nextsibling(xmlnode sibling);
-xmlnode  xmlnode_get_prevsibling(xmlnode sibling);
-xmlnode  xmlnode_get_parent(xmlnode node);
-
-/* Node information routines */
-char*    xmlnode_get_name(xmlnode node);
-char*    xmlnode_get_data(xmlnode node);
-int      xmlnode_get_datasz(xmlnode node);
-int      xmlnode_get_type(xmlnode node);
-
-int      xmlnode_has_children(xmlnode node);
-int      xmlnode_has_attribs(xmlnode node);
-
-/* Node-to-string translation */
-char*    xmlnode2str(xmlnode node);
-
-/* Node-to-terminated-string translation
-   -- useful for interfacing w/ scripting langs */
-char*    xmlnode2tstr(xmlnode node);
-
-int      xmlnode_cmp(xmlnode a, xmlnode b); /* compares a and b for equality */
-
-int      xmlnode2file(char *file, xmlnode node); /* writes node to file */
-int xmlnode2file_limited(char *file, xmlnode node, size_t sizelimit);
-
-/* Expat callbacks */
-void expat_startElement(void* userdata, const char* name, const char** atts);
-void expat_endElement(void* userdata, const char* name);
-void expat_charData(void* userdata, const char* s, int len);
-
-/***********************
- * XSTREAM Section
- ***********************/
-
-#define XSTREAM_MAXNODE 1000000
-#define XSTREAM_MAXDEPTH 100
-
-#define XSTREAM_ROOT        0 /* root element */
-#define XSTREAM_NODE        1 /* normal node */
-#define XSTREAM_CLOSE       2 /* closed </stream:stream> */
-#define XSTREAM_ERR         4 /* parser error */
-
-typedef void (*xstream_onNode)(int type, xmlnode x, void *arg); /* xstream event handler */
-
-typedef struct xstream_struct
-{
-    XML_Parser parser;
-    xmlnode node;
-    char *cdata;
-    int cdata_len;
-    pool p;
-    xstream_onNode f;
-    void *arg;
-    int status;
-    int depth;
-} *xstream, _xstream;
-
-xstream xstream_new(pool p, xstream_onNode f, void *arg); /* create a new xstream */
-int xstream_eat(xstream xs, char *buff, int len); /* parse new data for this xstream, returns last XSTREAM_* status */
-
-/* convience functions */
-xmlnode xstream_header(char *nspace, char *to, char *from);
-char *xstream_header_char(xmlnode x);
-
-/* SHA.H */
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is SHA 180-1 Header File
- *
- * The Initial Developer of the Original Code is Paul Kocher of
- * Cryptography Research.  Portions created by Paul Kocher are
- * Copyright (C) 1995-9 by Cryptography Research, Inc.  All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- *     Paul Kocher
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above.  If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL.  If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-
-typedef struct {
-  uint32_t H[5];
-  uint32_t W[80];
-  int lenW;
-  uint32_t sizeHi,sizeLo;
-} SHA_CTX;
-
-
-void shaInit(SHA_CTX *ctx);
-void shaUpdate(SHA_CTX *ctx, unsigned char *dataIn, int len);
-void shaFinal(SHA_CTX *ctx, unsigned char hashout[20]);
-void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]);
-
-
-/* END SHA.H */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* INCL_LIBXODE_H */
--- a/mcabber/libjabber/log.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *  Jabber
- *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
- */
-
-#include "jabber.h"
-#include "log.h"
-
-#ifdef DEBUG
-
-void jdebug(char *zone, const char *msgfmt, ...)
-{
-    va_list ap;
-    static char loghdr[LOGSIZE_HDR];
-    static char logmsg[LOGSIZE_TAIL];
-    static int size;
-
-    /* XXX: We may want to check the sizes eventually */
-    size = snprintf(loghdr, LOGSIZE_HDR, "debug/%s %s\n", zone, msgfmt);
-
-    va_start(ap, msgfmt);
-    size = vsnprintf(logmsg, LOGSIZE_TAIL, loghdr, ap);
-
-    fprintf(stderr,"%s",logmsg);
-
-    return;
-}
-
-
-#endif  /* DEBUG */
--- a/mcabber/libjabber/log.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *  Jabber
- *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
- */
-
-#ifndef INCL_LOG_H
-#define INCL_LOG_H
-
-#define LOGSIZE_HDR 1024
-#define LOGSIZE_TAIL 2048
-
-
-#ifdef DEBUG
-	void jdebug(char *zone, const char *msgfmt, ...);
-#else
-	#define jdebug if(0) warn
-#endif
-
-
-
-#endif	/* INCL_LOG_H */
-
--- a/mcabber/libjabber/nametab.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-static const unsigned namingBitmap[] = {
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
-0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
-0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
-0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
-0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
-0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
-0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
-0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
-0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
-0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
-0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
-0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
-0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
-0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
-0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
-0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
-0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
-0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
-0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
-0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
-0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
-0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
-0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
-0x40000000, 0xF580C900, 0x00000007, 0x02010800,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
-0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
-0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
-0x00000000, 0x00004C40, 0x00000000, 0x00000000,
-0x00000007, 0x00000000, 0x00000000, 0x00000000,
-0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
-0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
-0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
-0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
-0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
-0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
-0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
-0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
-0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
-0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
-0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
-0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
-0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
-0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
-0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
-0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
-0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
-0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
-0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
-0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
-0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
-0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
-0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
-0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
-0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
-0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
-0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
-0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
-};
-static const unsigned char nmstrtPages[] = {
-0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
-0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
-0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-static const unsigned char namePages[] = {
-0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
-0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
-0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
-0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
--- a/mcabber/libjabber/pool.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,474 +0,0 @@
-/*
- *  pool.c
- * This code comes from jabberd - Jabber Open Source Server
- *  Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
- *                    Ryan Eatmon, Robert Norris
- *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
- *
- * Copyrights
- *
- * Portions created by or assigned to Jabber.com, Inc. are
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- *
- * Acknowledgements
- *
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- *
- */
-
-/**
- * @file pool.c
- * @brief Handling of memory pools
- *
- * Jabberd handles its memory allocations in pools. You create a pool, can
- * allocate memory from it and all allocations will be freed if you free
- * the pool. Therefore you don't have to care that each malloc is freed,
- * you only have to take care that the pool is freed.
- *
- * The normal call-flow for pools is:
- *
- * pool p = pool_new();
- * struct mystruct *allocation1 = pmalloc(sizeof(struct mystruct));
- * struct myotherstruct *allocation2 = pmalloc(sizeof(struct myotherstruct));
- * ...
- * pool_free(p);
- */
-
-#include "libxode.h"
-
-#define MAX_MALLOC_TRIES 10 /**< how many seconds we try to allocate memory */
-
-#ifdef POOL_DEBUG
-int pool__total = 0;		/**< how many memory blocks are allocated */
-int pool__ltotal = 0;
-xht pool__disturbed = NULL;
-
-inline void *_retried__malloc(size_t size);
-
-/**
- * create a new memory allocation and increment the pool__total counter
- *
- * only used if POOL_DEBUG is defined, else it is an alias for malloc
- *
- * @param size size of the memory to allocate
- * @return pointer to the allocated memory
- */
-void *_pool__malloc(size_t size)
-{
-    pool__total++;
-    return malloc(size);
-}
-
-/**
- * free memory and decrement the pool__total counter
- *
- * only used if POOL_DEBUG is defined, else it is an alias for free
- *
- * @param block pointer to the memory allocation that should be freed
- */
-void _pool__free(void *block)
-{
-    pool__total--;
-    free(block);
-}
-#else
-#define _pool__malloc malloc	/**< _pool__malloc updates pool__total counter if POOL_DEBUG is defined */
-#define _pool__free free	/**< _pool__free updates pool__total counter if POOL_DEBUG is defined */
-#endif
-
-/**
- * try to allocate memory
- *
- * If allocation fails, it will be retries for MAX_MALLOC_TRIES seconds.
- * If it still fails, we exit the process
- *
- * @param size how many bytes of memory we allocate
- * @return pointer to the allocated memory
- */
-void *_retried__malloc(size_t size) {
-    void *allocated_memory;
-    int malloc_tries = 0;
-
-    while ((allocated_memory=_pool__malloc(size)) == NULL) {
-	if (malloc_tries++ > MAX_MALLOC_TRIES) {
-	    exit(999);
-	}
-
-	sleep(1); //pth_sleep(1);
-    }
-
-    return allocated_memory;
-}
-
-/**
- * make an empty pool
- *
- * Use the macro pool_new() instead of a direct call to this function. The
- * macro will create the parameters for you.
- *
- * @param zone the file in which the pool_new macro is called
- * @param line the line in the file in which the pool_new macro is called
- * @return the new allocated memory pool
- */
-pool _pool_new(char *zone, int line)
-{
-    // int malloc_tries = 0;
-#ifdef POOL_DEBUG
-    int old__pool__total;
-#endif
-
-    pool p = _retried__malloc(sizeof(_pool));
-
-    p->cleanup = NULL;
-    p->heap = NULL;
-    p->size = 0;
-
-#ifdef POOL_DEBUG
-    p->lsize = -1;
-    p->zone[0] = '\0';
-    strcat(p->zone,zone);
-    snprintf(p->zone, sizeof(p->zone), "%s:%i", zone, line);
-    snprintf(p->name, sizeof(p->name), "%X", p);
-
-    if(pool__disturbed == NULL)
-    {
-        pool__disturbed = (xht)1; /* reentrancy flag! */
-        pool__disturbed = ghash_create(POOL_DEBUG,(KEYHASHFUNC)str_hash_code,(KEYCOMPAREFUNC)j_strcmp);
-    }
-    if(pool__disturbed != (xht)1)
-        ghash_put(pool__disturbed,p->name,p);
-#endif
-
-    return p;
-}
-
-/**
- * free a memory heap (struct pheap)
- *
- * @param arg which heep should be freed
- */
-void _pool_heap_free(void *arg)
-{
-    struct pheap *h = (struct pheap *)arg;
-
-    _pool__free(h->block);
-    _pool__free(h);
-}
-
-/**
- * append a pool_cleaner function (callback) to a pool
- *
- * mem should always be freed last
- *
- * All appended pool_cleaner functions will be called if a pool is freed.
- * This might be used to clean logically subpools.
- *
- * @param p to which pool the pool_cleaner should be added
- * @param pf structure containing the reference to the pool_cleaner and links for the list
- */
-void _pool_cleanup_append(pool p, struct pfree *pf)
-{
-    struct pfree *cur;
-
-    if(p->cleanup == NULL)
-    {
-        p->cleanup = pf;
-        return;
-    }
-
-    /* fast forward to end of list */
-    for(cur = p->cleanup; cur->next != NULL; cur = cur->next);
-
-    cur->next = pf;
-}
-
-/**
- * create a cleanup tracker
- *
- * this function is used to create a pfree structure that can be passed to _pool_cleanup_append()
- *
- * @param p the pool to which the pool_cleaner should be added
- * @param f the function that should be called if the pool is freed
- * @param arg the parameter that should be passed to the pool_cleaner function
- * @return pointer to the new pfree structure
- */
-struct pfree *_pool_free(pool p, pool_cleaner f, void *arg)
-{
-    struct pfree *ret;
-
-    /* make the storage for the tracker */
-    ret = _retried__malloc(sizeof(struct pfree));
-    ret->f = f;
-    ret->arg = arg;
-    ret->next = NULL;
-
-    return ret;
-}
-
-/**
- * create a heap and make sure it get's cleaned up
- *
- * pheaps are used by memory pools internally to handle the memory allocations
- *
- * @note the macro pool_heap calls _pool_new_heap and NOT _pool_heap
- *
- * @param p for which pool the heap should be created
- * @param size how big the pool should be
- * @return pointer to the new pheap
- */
-struct pheap *_pool_heap(pool p, int size)
-{
-    struct pheap *ret;
-    struct pfree *clean;
-
-    /* make the return heap */
-    ret = _retried__malloc(sizeof(struct pheap));
-    ret->block = _retried__malloc(size);
-    ret->size = size;
-    p->size += size;
-    ret->used = 0;
-
-    /* append to the cleanup list */
-    clean = _pool_free(p, _pool_heap_free, (void *)ret);
-    clean->heap = ret; /* for future use in finding used mem for pstrdup */
-    _pool_cleanup_append(p, clean);
-
-    return ret;
-}
-
-/**
- * create a new memory pool and set the initial heap size
- *
- * @note you should not call this function but use the macro pool_heap instead which fills zone and line automatically
- *
- * @param size the initial size of the memory pool
- * @param zone the file where this function is called (for debugging)
- * @param line the line in the file where this function is called
- * @return the new memory pool
- */
-pool _pool_new_heap(int size, char *zone, int line)
-{
-    pool p;
-    p = _pool_new(zone, line);
-    p->heap = _pool_heap(p,size);
-    return p;
-}
-
-/**
- * allocate memory from a memory pool
- *
- * @param p the pool to use
- * @param size how much memory to allocate
- * @return pointer to the allocated memory
- */
-void *pmalloc(pool p, int size)
-{
-    void *block;
-
-    if(p == NULL)
-    {
-        fprintf(stderr,"Memory Leak! [pmalloc received NULL pool, unable to track allocation, exiting]\n");
-        abort();
-    }
-
-    /* if there is no heap for this pool or it's a big request, just raw, I like how we clean this :) */
-    if(p->heap == NULL || size > (p->heap->size / 2))
-    {
-	block = _retried__malloc(size);
-        p->size += size;
-        _pool_cleanup_append(p, _pool_free(p, _pool__free, block));
-        return block;
-    }
-
-    /* we have to preserve boundaries, long story :) */
-    if(size >= 4)
-        while(p->heap->used&7) p->heap->used++;
-
-    /* if we don't fit in the old heap, replace it */
-    if(size > (p->heap->size - p->heap->used))
-        p->heap = _pool_heap(p, p->heap->size);
-
-    /* the current heap has room */
-    block = (char *)p->heap->block + p->heap->used;
-    p->heap->used += size;
-    return block;
-}
-
-/**
- * allocate memory and initialize the memory with the given char c
- *
- * @deprecated jabberd does use pmalloco instead, this function will be removed
- *
- * @param p which pool to use
- * @param size the size of the allocation
- * @param c the initialization character
- * @return pointer to the allocated memory
- */
-void *pmalloc_x(pool p, int size, char c)
-{
-   void* result = pmalloc(p, size);
-   if (result != NULL)
-           memset(result, c, size);
-   return result;
-}
-
-/**
- * allocate memory and initialize the memory with zero bytes
- *
- * easy safety utility (for creating blank mem for structs, etc)
- *
- * @param p which pool to use
- * @param size the size of the allocation
- * @return pointer to the allocated memory
- */
-void *pmalloco(pool p, int size)
-{
-    void *block = pmalloc(p, size);
-    memset(block, 0, size);
-    return block;
-}
-
-/**
- * duplicate a string and allocate memory for it
- *
- * @todo efficient: move this to const char* and then loop through the existing heaps to see if src is within a block in this pool
- *
- * @param p the pool to use
- * @param src the string that should be duplicated
- * @return the duplicated string
- */
-char *pstrdup(pool p, const char *src)
-{
-    char *ret;
-
-    if(src == NULL)
-        return NULL;
-
-    ret = pmalloc(p,strlen(src) + 1);
-    strcpy(ret,src);
-
-    return ret;
-}
-
-/**
- * when pstrdup() is moved to "const char*", this one would actually return a new block
- */
-char *pstrdupx(pool p, const char *src)
-{
-    return pstrdup(p, src);
-}
-
-/**
- * get the size of a memory pool
- *
- * @param p the pool
- * @return the size
- */
-int pool_size(pool p)
-{
-    if(p == NULL) return 0;
-
-    return p->size;
-}
-
-/**
- * free a pool (and all memory that is allocated in it)
- *
- * @param p which pool to free
- */
-void pool_free(pool p)
-{
-    struct pfree *cur, *stub;
-
-    if(p == NULL) return;
-
-    cur = p->cleanup;
-    while(cur != NULL)
-    {
-        (*cur->f)(cur->arg);
-        stub = cur->next;
-        _pool__free(cur);
-        cur = stub;
-    }
-
-#ifdef POOL_DEBUG
-    ghash_remove(pool__disturbed,p->name);
-#endif
-
-    _pool__free(p);
-
-}
-
-/**
- * public cleanup utils, insert in a way that they are run FIFO, before mem frees
- */
-void pool_cleanup(pool p, pool_cleaner f, void *arg)
-{
-    struct pfree *clean;
-
-    clean = _pool_free(p, f, arg);
-    clean->next = p->cleanup;
-    p->cleanup = clean;
-}
-
-#ifdef POOL_DEBUG
-void debug_log(char *zone, const char *msgfmt, ...);
-void _pool_stat(xht h, const char *key, void *data, void *arg)
-{
-    pool p = (pool)data;
-
-    if(p->lsize == -1)
-        debug_log("pool_debug","%s: %s is a new pool",p->zone, p->name);
-    else if(p->size > p->lsize)
-        debug_log("pool_debug","%s: %s grew %d",p->zone, p->name, p->size - p->lsize);
-    else if((int)arg)
-        debug_log("pool_debug","%s: %s exists %d",p->zone,p->name, p->size);
-    p->lsize = p->size;
-}
-
-/**
- * print memory pool statistics (for debugging purposes)
- *
- * @param full make a full report? (0 = no, 1 = yes)
- */
-void pool_stat(int full)
-{
-    if (pool__disturbed == NULL || pool__disturbed == (xht)1)
-	return;
-
-    ghash_walk(pool__disturbed,_pool_stat,(void *)full);
-    if(pool__total != pool__ltotal)
-        debug_log("pool_debug","%d\ttotal missed mallocs",pool__total);
-    pool__ltotal = pool__total;
-
-    return;
-}
-#else
-/**
- * dummy implementation: print memory pool statistics (for debugging purposes, real implementation if POOL_DEBUG is defined)
- *
- * @param full make a full report? (0 = no, 1 = yes)
- */
-void pool_stat(int full)
-{
-    return;
-}
-#endif
--- a/mcabber/libjabber/pproxy.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,212 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyrights
- *
- * Portions created by or assigned to Jabber.com, Inc. are
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- *
- * Acknowledgements
- *
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- *
- *
- */
-
-/**
- * @file pproxy.c
- * @brief presence proxy database - DEPRECATED
- *
- * @deprecated these functions are not used by jabberd itself (but aim-t uses them), they will be removed from jabberd
- *
- * The presence proxy database is used to store presences for different resources of a JID.
- *
- * these aren't the most efficient things in the world, a hash optimized for tiny spaces would be far better
- */
-
-#include "jabber.h"
-
-/* these aren't the most efficient things in the world, a hash optimized for tiny spaces would be far better */
-
-ppdb _ppdb_new(pool p, jid id)
-{
-    ppdb ret;
-    ret = pmalloc(p,sizeof(_ppdb));
-    ret->p = p;
-    ret->pri = -1;
-    ret->next = NULL;
-    ret->user = NULL;
-    ret->x = NULL;
-    ret->id = jid_new(p,jid_full(id));
-
-    return ret;
-}
-
-ppdb _ppdb_get(ppdb db, jid id)
-{
-    ppdb cur;
-
-    if(db == NULL || id == NULL) return NULL;
-
-    for(cur = db->next; cur != NULL; cur = cur->next)
-        if(jid_cmp(cur->id,id) == 0) return cur;
-
-    return NULL;
-}
-
-ppdb ppdb_insert(ppdb db, jid id, xmlnode x)
-{
-    ppdb cur, curu;
-    pool p;
-
-    if(id == NULL || id->server == NULL || x == NULL)
-        return db;
-
-    /* new ppdb list dummy holder */
-    if(db == NULL)
-    {
-        p = pool_heap(1024);
-        db = _ppdb_new(p,NULL);
-    }
-
-    cur = _ppdb_get(db,id);
-
-    /* just update it */
-    if(cur != NULL)
-    {
-        xmlnode_free(cur->x);
-        cur->x = xmlnode_dup(x);
-        cur->pri = jutil_priority(x);
-        return db;
-    }
-
-    /* make an entry for it */
-    cur = _ppdb_new(db->p,id);
-    cur->x = xmlnode_dup(x);
-    cur->pri = jutil_priority(x);
-    cur->next = db->next;
-    db->next = cur;
-
-    /* if this is a user's resource presence, get the the user entry */
-    if(id->user != NULL && (curu = _ppdb_get(db,jid_user(id))) != cur)
-    {
-        /* no user entry, make one */
-        if(curu == NULL)
-        {
-            curu = _ppdb_new(db->p,jid_user(id));
-            curu->next = db->next;
-            db->next = curu;
-        }
-
-        /* insert this resource into the user list */
-        cur->user = curu->user;
-        curu->user = cur;
-    }
-
-    return db;
-}
-
-xmlnode ppdb_primary(ppdb db, jid id)
-{
-    ppdb cur, top;
-
-    if(db == NULL || id == NULL) return NULL;
-
-    cur = _ppdb_get(db,id);
-
-    if(cur == NULL) return NULL;
-
-    /* not user@host check, just return */
-    if(id->user == NULL || id->resource != NULL) return cur->x;
-
-    top = cur;
-    for(cur = cur->user; cur != NULL; cur = cur->user)
-        if(cur->pri >= top->pri) top = cur;
-
-    if(top != NULL && top->pri >= 0) return top->x;
-
-    return NULL;
-}
-
-/* return the presence for the id, successive calls return all of the known resources for a user@host address */
-xmlnode ppdb_get(ppdb db, jid id)
-{
-    static ppdb last = NULL;
-    ppdb cur;
-
-    if(db == NULL || id == NULL) return NULL;
-
-    /* MODE: if this is NOT just user@host addy, return just the single entry */
-    if(id->user == NULL || id->resource != NULL)
-    {
-        /* we were just here, return now */
-        if(last != NULL)
-        {
-            last = NULL;
-            return NULL;
-        }
-
-        last = _ppdb_get(db,id);
-        if(last != NULL)
-            return last->x;
-        else
-            return NULL;
-    }
-
-    /* handle looping for user@host */
-
-    /* we're already in the loop */
-    if(last != NULL)
-    {
-        /* this is the last entry in the list */
-        if(last->user == NULL)
-        {
-            last = NULL;
-            return NULL;
-        }
-
-        last = last->user;
-        return last->x;
-    }
-
-    /* start a new loop */
-    cur = _ppdb_get(db,id);
-
-    if(cur == NULL) return NULL;
-
-    last = cur->user;
-    if(last != NULL)
-        return last->x;
-    else
-        return NULL;
-}
-
-
-void ppdb_free(ppdb db)
-{
-    ppdb cur;
-
-    if(db == NULL) return;
-
-    for(cur = db; cur != NULL; cur = cur->next)
-        xmlnode_free(cur->x);
-
-    pool_free(db->p);
-}
-
--- a/mcabber/libjabber/rate.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyrights
- *
- * Portions created by or assigned to Jabber.com, Inc. are
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- *
- * Acknowledgements
- *
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- *
- */
-
-/**
- * create a new instance of jlimit that is used to limit events
- *
- * limit the events to maxp points per maxt seconds
- *
- * @param maxt time interval (in seconds) after which the points are cleared
- * @param maxp maximum number of points available for the time interval given in maxt
- * @return new instance of jlimit (has to be freed with jlimit_free if not used anymore)
- */
-
-#include "jabber.h"
-
-jlimit jlimit_new(int maxt, int maxp)
-{
-    pool p;
-    jlimit r;
-
-    p = pool_new();
-    r = pmalloc(p,sizeof(_jlimit));
-    r->key = NULL;
-    r->start = r->points = 0;
-    r->maxt = maxt;
-    r->maxp = maxp;
-    r->p = p;
-
-    return r;
-}
-
-/**
- * free a jlimit instance
- *
- * @param r the jlimit instance that should be freed
- */
-void jlimit_free(jlimit r)
-{
-    if(r != NULL)
-    {
-        if(r->key != NULL) free(r->key);
-        pool_free(r->p);
-    }
-}
-
-/**
- * update/check a key in a jlimit instance
- *
- * Each jlimit instance can track many limits (that have the same setup).
- * The limit is selected by the key, which can be an IP address.
- *
- * @param r the jlimit instance
- * @param key for which key the limit should be checked
- * @param points how many points of the limit should be consumed
- * @return 1 if limit reached, 0 if we are still within the rate limit
- */
-int jlimit_check(jlimit r, char *key, int points)
-{
-    int now = time(NULL);
-
-    if(r == NULL) return 0;
-
-    /* make sure we didn't go over the time frame or get a null/new key */
-    if((now - r->start) > r->maxt || key == NULL || j_strcmp(key,r->key) != 0)
-    { /* start a new key */
-        free(r->key);
-        if(key != NULL)
-          /* We use strdup instead of pstrdup since r->key needs to be free'd before
-             and more often than the rest of the rlimit structure */
-            r->key = strdup(key);
-        else
-            r->key = NULL;
-        r->start = now;
-        r->points = 0;
-    }
-
-    r->points += points;
-
-    /* if we're within the time frame and over the point limit */
-    if(r->points > r->maxp && (now - r->start) < r->maxt)
-    {
-        return 1; /* we don't reset the rate here, so that it remains rated until the time runs out */
-    }
-
-    return 0;
-}
--- a/mcabber/libjabber/sha.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,206 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is SHA 180-1 Reference Implementation (Compact version)
- *
- * The Initial Developer of the Original Code is Paul Kocher of
- * Cryptography Research.  Portions created by Paul Kocher are
- * Copyright (C) 1995-9 by Cryptography Research, Inc.  All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- *     Paul Kocher
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above.  If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL.  If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-
-#include "libxode.h"
-
-static void shaHashBlock(SHA_CTX *ctx);
-
-void shaInit(SHA_CTX *ctx) {
-  int i;
-
-  ctx->lenW = 0;
-  ctx->sizeHi = ctx->sizeLo = 0;
-
-  /* Initialize H with the magic constants (see FIPS180 for constants)
-   */
-  ctx->H[0] = 0x67452301L;
-  ctx->H[1] = 0xefcdab89L;
-  ctx->H[2] = 0x98badcfeL;
-  ctx->H[3] = 0x10325476L;
-  ctx->H[4] = 0xc3d2e1f0L;
-
-  for (i = 0; i < 80; i++)
-    ctx->W[i] = 0;
-}
-
-
-void shaUpdate(SHA_CTX *ctx, unsigned char *dataIn, int len) {
-  int i;
-
-  /* Read the data into W and process blocks as they get full
-   */
-  for (i = 0; i < len; i++) {
-    ctx->W[ctx->lenW / 4] <<= 8;
-    ctx->W[ctx->lenW / 4] |= (uint32_t)dataIn[i];
-    if ((++ctx->lenW) % 64 == 0) {
-      shaHashBlock(ctx);
-      ctx->lenW = 0;
-    }
-    ctx->sizeLo += 8;
-    ctx->sizeHi += (ctx->sizeLo < 8);
-  }
-}
-
-
-void shaFinal(SHA_CTX *ctx, unsigned char hashout[20]) {
-  unsigned char pad0x80 = 0x80;
-  unsigned char pad0x00 = 0x00;
-  unsigned char padlen[8];
-  int i;
-
-  /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length
-   */
-  padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255);
-  padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255);
-  padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255);
-  padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255);
-  padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255);
-  padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255);
-  padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255);
-  padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255);
-  shaUpdate(ctx, &pad0x80, 1);
-  while (ctx->lenW != 56)
-    shaUpdate(ctx, &pad0x00, 1);
-  shaUpdate(ctx, padlen, 8);
-
-  /* Output hash
-   */
-  for (i = 0; i < 20; i++) {
-    hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24);
-    ctx->H[i / 4] <<= 8;
-  }
-
-  /*
-   *  Re-initialize the context (also zeroizes contents)
-   */
-  shaInit(ctx);
-}
-
-
-void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]) {
-  SHA_CTX ctx;
-
-  shaInit(&ctx);
-  shaUpdate(&ctx, dataIn, len);
-  shaFinal(&ctx, hashout);
-}
-
-
-#define SHA_ROTL(X,n) (((X) << (n)) | ((X) >> (32-(n))))
-
-static void shaHashBlock(SHA_CTX *ctx) {
-  int t;
-  uint32_t A,B,C,D,E,TEMP;
-
-  for (t = 16; t <= 79; t++)
-    ctx->W[t] =
-      SHA_ROTL(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1);
-
-  A = ctx->H[0];
-  B = ctx->H[1];
-  C = ctx->H[2];
-  D = ctx->H[3];
-  E = ctx->H[4];
-
-  for (t = 0; t <= 19; t++) {
-    TEMP = SHA_ROTL(A,5) + (((C^D)&B)^D)     + E + ctx->W[t] + 0x5a827999L;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-  for (t = 20; t <= 39; t++) {
-    TEMP = SHA_ROTL(A,5) + (B^C^D)           + E + ctx->W[t] + 0x6ed9eba1L;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-  for (t = 40; t <= 59; t++) {
-    TEMP = SHA_ROTL(A,5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdcL;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-  for (t = 60; t <= 79; t++) {
-    TEMP = SHA_ROTL(A,5) + (B^C^D)           + E + ctx->W[t] + 0xca62c1d6L;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-
-  ctx->H[0] += A;
-  ctx->H[1] += B;
-  ctx->H[2] += C;
-  ctx->H[3] += D;
-  ctx->H[4] += E;
-}
-
-/*----------------------------------------------------------------------------
- *
- * This code added by Thomas "temas" Muldowney for Jabber compatability
- *
- *---------------------------------------------------------------------------*/
-char *shahash(char *str)
-{
-    static char final[41];
-    char *pos;
-    unsigned char hashval[20];
-    int x;
-
-    if(!str || strlen(str) == 0)
-        return NULL;
-
-    shaBlock((unsigned char *)str, strlen(str), hashval);
-
-    pos = final;
-    for(x=0;x<20;x++)
-    {
-        snprintf(pos, 3, "%02x", hashval[x]);
-        pos += 2;
-    }
-    return (char *)final;
-}
-
-void shahash_r(const char* str, char hashbuf[41])
-{
-    int x;
-    char *pos;
-    unsigned char hashval[20];
-
-    if(!str || strlen(str) == 0)
-        return;
-
-    shaBlock((unsigned char *)str, strlen(str), hashval);
-
-    pos = hashbuf;
-    for(x=0;x<20;x++)
-    {
-        snprintf(pos, 3, "%02x", hashval[x]);
-        pos += 2;
-    }
-
-    return;
-}
--- a/mcabber/libjabber/snprintf.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,945 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1998 The Apache Group.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the Apache Group
- *    for use in the Apache HTTP server project (http://www.apache.org/)."
- *
- * 4. The names "Apache Server" and "Apache Group" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission.
- *
- * 5. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the Apache Group
- *    for use in the Apache HTTP server project (http://www.apache.org/)."
- *
- * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Group and was originally based
- * on public domain software written at the National Center for
- * Supercomputing Applications, University of Illinois, Urbana-Champaign.
- * For more information on the Apache Group and the Apache HTTP server
- * project, please see <http://www.apache.org/>.
- *
- * This code is based on, and used with the permission of, the
- * SIO stdio-replacement strx_* functions by Panos Tsirigotis
- * <panos@alumni.cs.colorado.edu> for xinetd.
- */
-
-/**
- * @file snprintf.c
- * @brief implement snprintf if not present in the libc
- *
- * snprintf is not implemented by all libc implementations, this file implements this
- * function, if it is not already present. You should not call any of the functions
- * in this file directly!
- */
-
-#include <libxode.h>
-
-#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
-
-#include <stdio.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-
-
-#ifdef HAVE_GCVT
-
-#define ap_ecvt ecvt
-#define ap_fcvt fcvt
-#define ap_gcvt gcvt
-
-#else
-
-/*
-* cvt.c - IEEE floating point formatting routines for FreeBSD
-* from GNU libc-4.6.27
-*/
-
-/*
-*    ap_ecvt converts to decimal
-*      the number of digits is specified by ndigit
-*      decpt is set to the position of the decimal point
-*      sign is set to 0 for positive, 1 for negative
-*/
-
-#define NDIG    80
-
-static char *
-ap_cvt(double arg, int ndigits, int *decpt, int *sign, int eflag)
-{
-    register int r2;
-    double fi, fj;
-    register char *p, *p1;
-    static char buf[NDIG];
-
-    if (ndigits >= NDIG - 1)
-        ndigits = NDIG - 2;
-    r2 = 0;
-    *sign = 0;
-    p = &buf[0];
-    if (arg < 0) {
-        *sign = 1;
-        arg = -arg;
-    }
-    arg = modf(arg, &fi);
-    p1 = &buf[NDIG];
-    /*
-    * Do integer part
-    */
-    if (fi != 0) {
-        p1 = &buf[NDIG];
-        while (fi != 0) {
-            fj = modf(fi / 10, &fi);
-            *--p1 = (int) ((fj + .03) * 10) + '0';
-            r2++;
-        }
-        while (p1 < &buf[NDIG])
-            *p++ = *p1++;
-    } else if (arg > 0) {
-        while ((fj = arg * 10) < 1) {
-            arg = fj;
-            r2--;
-        }
-    }
-    p1 = &buf[ndigits];
-    if (eflag == 0)
-        p1 += r2;
-    *decpt = r2;
-    if (p1 < &buf[0]) {
-        buf[0] = '\0';
-        return (buf);
-    }
-    while (p <= p1 && p < &buf[NDIG]) {
-        arg *= 10;
-        arg = modf(arg, &fj);
-        *p++ = (int) fj + '0';
-    }
-    if (p1 >= &buf[NDIG]) {
-        buf[NDIG - 1] = '\0';
-        return (buf);
-    }
-    p = p1;
-    *p1 += 5;
-    while (*p1 > '9') {
-        *p1 = '0';
-        if (p1 > buf)
-            ++ * --p1;
-        else {
-            *p1 = '1';
-            (*decpt)++;
-            if (eflag == 0) {
-                if (p > buf)
-                    *p = '0';
-                p++;
-            }
-        }
-    }
-    *p = '\0';
-    return (buf);
-}
-
-static char *
-ap_ecvt(double arg, int ndigits, int *decpt, int *sign)
-{
-    return (ap_cvt(arg, ndigits, decpt, sign, 1));
-}
-
-static char *
-ap_fcvt(double arg, int ndigits, int *decpt, int *sign)
-{
-    return (ap_cvt(arg, ndigits, decpt, sign, 0));
-}
-
-/*
-* ap_gcvt  - Floating output conversion to
-* minimal length string
-*/
-
-static char *
-ap_gcvt(double number, int ndigit, char *buf)
-{
-    int sign, decpt;
-    register char *p1, *p2;
-    int i;
-
-    p1 = ap_ecvt(number, ndigit, &decpt, &sign);
-    p2 = buf;
-    if (sign)
-        *p2++ = '-';
-    for (i = ndigit - 1; i > 0 && p1[i] == '0'; i--)
-        ndigit--;
-    if ((decpt >= 0 && decpt - ndigit > 4)
-            || (decpt < 0 && decpt < -3)) {     /* use E-style */
-        decpt--;
-        *p2++ = *p1++;
-        *p2++ = '.';
-        for (i = 1; i < ndigit; i++)
-            *p2++ = *p1++;
-        *p2++ = 'e';
-        if (decpt < 0) {
-            decpt = -decpt;
-            *p2++ = '-';
-        } else
-            *p2++ = '+';
-        if (decpt / 100 > 0)
-            *p2++ = decpt / 100 + '0';
-        if (decpt / 10 > 0)
-            *p2++ = (decpt % 100) / 10 + '0';
-        *p2++ = decpt % 10 + '0';
-    } else {
-        if (decpt <= 0) {
-            if (*p1 != '0')
-                *p2++ = '.';
-            while (decpt < 0) {
-                decpt++;
-                *p2++ = '0';
-            }
-        }
-        for (i = 1; i <= ndigit; i++) {
-            *p2++ = *p1++;
-            if (i == decpt)
-                *p2++ = '.';
-        }
-        if (ndigit < decpt) {
-            while (ndigit++ < decpt)
-                *p2++ = '0';
-            *p2++ = '.';
-        }
-    }
-    if (p2[-1] == '.')
-        p2--;
-    *p2 = '\0';
-    return (buf);
-}
-
-#endif                          /* HAVE_CVT */
-
-typedef enum {
-    NO = 0, YES = 1
-} boolean_e;
-
-#ifndef FALSE
-#  define FALSE           0
-#endif
-#ifndef TRUE
-#  define TRUE            1
-#endif
-#define NUL         '\0'
-#define INT_NULL        ((int *)0)
-#define WIDE_INT        long
-
-typedef WIDE_INT wide_int;
-typedef unsigned WIDE_INT u_wide_int;
-typedef int bool_int;
-
-#define S_NULL          "(null)"
-#define S_NULL_LEN      6
-
-#define FLOAT_DIGITS        6
-#define EXPONENT_LENGTH     10
-
-/*
- * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions
- *
- * XXX: this is a magic number; do not decrease it
- */
-#define NUM_BUF_SIZE        512
-
-
-/*
- * Descriptor for buffer area
- */
-struct buf_area {
-    char *buf_end;
-    char *nextb;                /* pointer to next byte to read/write   */
-};
-
-typedef struct buf_area buffy;
-
-/*
- * The INS_CHAR macro inserts a character in the buffer and writes
- * the buffer back to disk if necessary
- * It uses the char pointers sp and bep:
- *      sp points to the next available character in the buffer
- *      bep points to the end-of-buffer+1
- * While using this macro, note that the nextb pointer is NOT updated.
- *
- * NOTE: Evaluation of the c argument should not have any side-effects
- */
-#define INS_CHAR( c, sp, bep, cc )  \
-        {               \
-        if ( sp < bep )     \
-        {           \
-            *sp++ = c ;     \
-            cc++ ;      \
-        }           \
-        }
-
-#define NUM( c )            ( c - '0' )
-
-#define STR_TO_DEC( str, num )      \
-    num = NUM( *str++ ) ;       \
-    while ( isdigit((int)*str ) )       \
-    {                   \
-    num *= 10 ;         \
-    num += NUM( *str++ ) ;      \
-    }
-
-/*
- * This macro does zero padding so that the precision
- * requirement is satisfied. The padding is done by
- * adding '0's to the left of the string that is going
- * to be printed.
- */
-#define FIX_PRECISION( adjust, precision, s, s_len )    \
-    if ( adjust )                   \
-    while ( s_len < precision )         \
-    {                       \
-        *--s = '0' ;                \
-        s_len++ ;                   \
-    }
-
-/*
- * Macro that does padding. The padding is done by printing
- * the character ch.
- */
-#define PAD( width, len, ch )   do      \
-    {                   \
-        INS_CHAR( ch, sp, bep, cc ) ;   \
-        width-- ;               \
-    }                   \
-    while ( width > len )
-
-/*
- * Prefix the character ch to the string str
- * Increase length
- * Set the has_prefix flag
- */
-#define PREFIX( str, length, ch )    *--str = ch ; length++ ; has_prefix = YES
-
-
-/*
- * Convert num to its decimal format.
- * Return value:
- *   - a pointer to a string containing the number (no sign)
- *   - len contains the length of the string
- *   - is_negative is set to TRUE or FALSE depending on the sign
- *     of the number (always set to FALSE if is_unsigned is TRUE)
- *
- * The caller provides a buffer for the string: that is the buf_end argument
- * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
- * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
- */
-static char *
-conv_10(register wide_int num, register bool_int is_unsigned,
-        register bool_int * is_negative, char *buf_end, register int *len)
-{
-    register char *p = buf_end;
-    register u_wide_int magnitude;
-
-    if (is_unsigned) {
-        magnitude = (u_wide_int) num;
-        *is_negative = FALSE;
-    } else {
-        *is_negative = (num < 0);
-
-        /*
-         * On a 2's complement machine, negating the most negative integer
-         * results in a number that cannot be represented as a signed integer.
-         * Here is what we do to obtain the number's magnitude:
-         *      a. add 1 to the number
-         *      b. negate it (becomes positive)
-         *      c. convert it to unsigned
-         *      d. add 1
-         */
-        if (*is_negative) {
-            wide_int t = num + 1;
-
-            magnitude = ((u_wide_int) - t) + 1;
-        } else
-            magnitude = (u_wide_int) num;
-    }
-
-    /*
-     * We use a do-while loop so that we write at least 1 digit
-     */
-    do {
-        register u_wide_int new_magnitude = magnitude / 10;
-
-        *--p = magnitude - new_magnitude * 10 + '0';
-        magnitude = new_magnitude;
-    }
-    while (magnitude);
-
-    *len = buf_end - p;
-    return (p);
-}
-
-
-
-/*
- * Convert a floating point number to a string formats 'f', 'e' or 'E'.
- * The result is placed in buf, and len denotes the length of the string
- * The sign is returned in the is_negative argument (and is not placed
- * in buf).
- */
-static char *
-conv_fp(register char format, register double num,
-        boolean_e add_dp, int precision, bool_int * is_negative, char *buf, int *len)
-{
-    register char *s = buf;
-    register char *p;
-    int decimal_point;
-
-    if (format == 'f')
-        p = ap_fcvt(num, precision, &decimal_point, is_negative);
-    else                        /* either e or E format */
-        p = ap_ecvt(num, precision + 1, &decimal_point, is_negative);
-
-    /*
-     * Check for Infinity and NaN
-     */
-    if (isalpha((int)*p)) {
-        *len = strlen(strcpy(buf, p));
-        *is_negative = FALSE;
-        return (buf);
-    }
-    if (format == 'f') {
-        if (decimal_point <= 0) {
-            *s++ = '0';
-            if (precision > 0) {
-                *s++ = '.';
-                while (decimal_point++ < 0)
-                    *s++ = '0';
-            } else if (add_dp) {
-                *s++ = '.';
-            }
-        } else {
-            while (decimal_point-- > 0) {
-                *s++ = *p++;
-            }
-            if (precision > 0 || add_dp) {
-                *s++ = '.';
-            }
-        }
-    } else {
-        *s++ = *p++;
-        if (precision > 0 || add_dp)
-            *s++ = '.';
-    }
-
-    /*
-     * copy the rest of p, the NUL is NOT copied
-     */
-    while (*p)
-        *s++ = *p++;
-
-    if (format != 'f') {
-        char temp[EXPONENT_LENGTH];     /* for exponent conversion */
-        int t_len;
-        bool_int exponent_is_negative;
-
-        *s++ = format;          /* either e or E */
-        decimal_point--;
-        if (decimal_point != 0) {
-            p = conv_10((wide_int) decimal_point, FALSE, &exponent_is_negative,
-                        &temp[EXPONENT_LENGTH], &t_len);
-            *s++ = exponent_is_negative ? '-' : '+';
-
-            /*
-             * Make sure the exponent has at least 2 digits
-             */
-            if (t_len == 1)
-                *s++ = '0';
-            while (t_len--)
-                *s++ = *p++;
-        } else {
-            *s++ = '+';
-            *s++ = '0';
-            *s++ = '0';
-        }
-    }
-    *len = s - buf;
-    return (buf);
-}
-
-
-/*
- * Convert num to a base X number where X is a power of 2. nbits determines X.
- * For example, if nbits is 3, we do base 8 conversion
- * Return value:
- *      a pointer to a string containing the number
- *
- * The caller provides a buffer for the string: that is the buf_end argument
- * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
- * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
- */
-static char *
-conv_p2(register u_wide_int num, register int nbits,
-        char format, char *buf_end, register int *len)
-{
-    register int mask = (1 << nbits) - 1;
-    register char *p = buf_end;
-    static char low_digits[] = "0123456789abcdef";
-    static char upper_digits[] = "0123456789ABCDEF";
-    register char *digits = (format == 'X') ? upper_digits : low_digits;
-
-    do {
-        *--p = digits[num & mask];
-        num >>= nbits;
-    }
-    while (num);
-
-    *len = buf_end - p;
-    return (p);
-}
-
-
-/*
- * Do format conversion placing the output in buffer
- */
-static int format_converter(register buffy * odp, const char *fmt,
-                            va_list ap)
-{
-    register char *sp;
-    register char *bep;
-    register int cc = 0;
-    register int i;
-
-    register char *s = NULL;
-    char *q;
-    int s_len;
-
-    register int min_width = 0;
-    int precision = 0;
-    enum {
-        LEFT, RIGHT
-    } adjust;
-    char pad_char;
-    char prefix_char;
-
-    double fp_num;
-    wide_int i_num = (wide_int) 0;
-    u_wide_int ui_num;
-
-    char num_buf[NUM_BUF_SIZE];
-    char char_buf[2];           /* for printing %% and %<unknown> */
-
-    /*
-     * Flag variables
-     */
-    boolean_e is_long;
-    boolean_e alternate_form;
-    boolean_e print_sign;
-    boolean_e print_blank;
-    boolean_e adjust_precision;
-    boolean_e adjust_width;
-    bool_int is_negative;
-
-    sp = odp->nextb;
-    bep = odp->buf_end;
-
-    while (*fmt) {
-        if (*fmt != '%') {
-            INS_CHAR(*fmt, sp, bep, cc);
-        } else {
-            /*
-             * Default variable settings
-             */
-            adjust = RIGHT;
-            alternate_form = print_sign = print_blank = NO;
-            pad_char = ' ';
-            prefix_char = NUL;
-
-            fmt++;
-
-            /*
-             * Try to avoid checking for flags, width or precision
-             */
-            if (isascii((int)*fmt) && !islower((int)*fmt)) {
-                /*
-                 * Recognize flags: -, #, BLANK, +
-                 */
-                for (;; fmt++) {
-                    if (*fmt == '-')
-                        adjust = LEFT;
-                    else if (*fmt == '+')
-                        print_sign = YES;
-                    else if (*fmt == '#')
-                        alternate_form = YES;
-                    else if (*fmt == ' ')
-                        print_blank = YES;
-                    else if (*fmt == '0')
-                        pad_char = '0';
-                    else
-                        break;
-                }
-
-                /*
-                 * Check if a width was specified
-                 */
-                if (isdigit((int)*fmt)) {
-                    STR_TO_DEC(fmt, min_width);
-                    adjust_width = YES;
-                } else if (*fmt == '*') {
-                    min_width = va_arg(ap, int);
-                    fmt++;
-                    adjust_width = YES;
-                    if (min_width < 0) {
-                        adjust = LEFT;
-                        min_width = -min_width;
-                    }
-                } else
-                    adjust_width = NO;
-
-                /*
-                 * Check if a precision was specified
-                 *
-                 * XXX: an unreasonable amount of precision may be specified
-                 * resulting in overflow of num_buf. Currently we
-                 * ignore this possibility.
-                 */
-                if (*fmt == '.') {
-                    adjust_precision = YES;
-                    fmt++;
-                    if (isdigit((int)*fmt)) {
-                        STR_TO_DEC(fmt, precision);
-                    } else if (*fmt == '*') {
-                        precision = va_arg(ap, int);
-                        fmt++;
-                        if (precision < 0)
-                            precision = 0;
-                    } else
-                        precision = 0;
-                } else
-                    adjust_precision = NO;
-            } else
-                adjust_precision = adjust_width = NO;
-
-            /*
-             * Modifier check
-             */
-            if (*fmt == 'l') {
-                is_long = YES;
-                fmt++;
-            } else
-                is_long = NO;
-
-            /*
-             * Argument extraction and printing.
-             * First we determine the argument type.
-             * Then, we convert the argument to a string.
-             * On exit from the switch, s points to the string that
-             * must be printed, s_len has the length of the string
-             * The precision requirements, if any, are reflected in s_len.
-             *
-             * NOTE: pad_char may be set to '0' because of the 0 flag.
-             *   It is reset to ' ' by non-numeric formats
-             */
-            switch (*fmt) {
-            case 'u':
-                if (is_long)
-                    i_num = va_arg(ap, u_wide_int);
-                else
-                    i_num = (wide_int) va_arg(ap, unsigned int);
-                /*
-                 * The rest also applies to other integer formats, so fall
-                 * into that case.
-                 */
-            case 'd':
-            case 'i':
-                /*
-                 * Get the arg if we haven't already.
-                 */
-                if ((*fmt) != 'u') {
-                    if (is_long)
-                        i_num = va_arg(ap, wide_int);
-                    else
-                        i_num = (wide_int) va_arg(ap, int);
-                };
-                s = conv_10(i_num, (*fmt) == 'u', &is_negative,
-                            &num_buf[NUM_BUF_SIZE], &s_len);
-                FIX_PRECISION(adjust_precision, precision, s, s_len);
-
-                if (*fmt != 'u') {
-                    if (is_negative)
-                        prefix_char = '-';
-                    else if (print_sign)
-                        prefix_char = '+';
-                    else if (print_blank)
-                        prefix_char = ' ';
-                }
-                break;
-
-
-            case 'o':
-                if (is_long)
-                    ui_num = va_arg(ap, u_wide_int);
-                else
-                    ui_num = (u_wide_int) va_arg(ap, unsigned int);
-                s = conv_p2(ui_num, 3, *fmt,
-                            &num_buf[NUM_BUF_SIZE], &s_len);
-                FIX_PRECISION(adjust_precision, precision, s, s_len);
-                if (alternate_form && *s != '0') {
-                    *--s = '0';
-                    s_len++;
-                }
-                break;
-
-
-            case 'x':
-            case 'X':
-                if (is_long)
-                    ui_num = (u_wide_int) va_arg(ap, u_wide_int);
-                else
-                    ui_num = (u_wide_int) va_arg(ap, unsigned int);
-                s = conv_p2(ui_num, 4, *fmt,
-                            &num_buf[NUM_BUF_SIZE], &s_len);
-                FIX_PRECISION(adjust_precision, precision, s, s_len);
-                if (alternate_form && i_num != 0) {
-                    *--s = *fmt;    /* 'x' or 'X' */
-                    *--s = '0';
-                    s_len += 2;
-                }
-                break;
-
-
-            case 's':
-                s = va_arg(ap, char *);
-                if (s != NULL) {
-                    s_len = strlen(s);
-                    if (adjust_precision && precision < s_len)
-                        s_len = precision;
-                } else {
-                    s = S_NULL;
-                    s_len = S_NULL_LEN;
-                }
-                pad_char = ' ';
-                break;
-
-
-            case 'f':
-            case 'e':
-            case 'E':
-                fp_num = va_arg(ap, double);
-
-                s = conv_fp(*fmt, fp_num, alternate_form,
-                            (adjust_precision == NO) ? FLOAT_DIGITS : precision,
-                            &is_negative, &num_buf[1], &s_len);
-                if (is_negative)
-                    prefix_char = '-';
-                else if (print_sign)
-                    prefix_char = '+';
-                else if (print_blank)
-                    prefix_char = ' ';
-                break;
-
-
-            case 'g':
-            case 'G':
-                if (adjust_precision == NO)
-                    precision = FLOAT_DIGITS;
-                else if (precision == 0)
-                    precision = 1;
-                /*
-                 * * We use &num_buf[ 1 ], so that we have room for the sign
-                 */
-                s = ap_gcvt(va_arg(ap, double), precision, &num_buf[1]);
-                if (*s == '-')
-                    prefix_char = *s++;
-                else if (print_sign)
-                    prefix_char = '+';
-                else if (print_blank)
-                    prefix_char = ' ';
-
-                s_len = strlen(s);
-
-                if (alternate_form && (q = strchr(s, '.')) == NULL)
-                    s[s_len++] = '.';
-                if (*fmt == 'G' && (q = strchr(s, 'e')) != NULL)
-                    *q = 'E';
-                break;
-
-
-            case 'c':
-                char_buf[0] = (char) (va_arg(ap, int));
-                s = &char_buf[0];
-                s_len = 1;
-                pad_char = ' ';
-                break;
-
-
-            case '%':
-                char_buf[0] = '%';
-                s = &char_buf[0];
-                s_len = 1;
-                pad_char = ' ';
-                break;
-
-
-            case 'n':
-                *(va_arg(ap, int *)) = cc;
-                break;
-
-                /*
-                 * Always extract the argument as a "char *" pointer. We
-                 * should be using "void *" but there are still machines
-                 * that don't understand it.
-                 * If the pointer size is equal to the size of an unsigned
-                 * integer we convert the pointer to a hex number, otherwise
-                 * we print "%p" to indicate that we don't handle "%p".
-                 */
-            case 'p':
-                ui_num = (u_wide_int) va_arg(ap, char *);
-
-                if (sizeof(char *) <= sizeof(u_wide_int))
-                    s = conv_p2(ui_num, 4, 'x',
-                                &num_buf[NUM_BUF_SIZE], &s_len);
-                else {
-                    s = "%p";
-                    s_len = 2;
-                }
-                pad_char = ' ';
-                break;
-
-
-            case NUL:
-                /*
-                 * The last character of the format string was %.
-                 * We ignore it.
-                 */
-                continue;
-
-
-                /*
-                 * The default case is for unrecognized %'s.
-                 * We print %<char> to help the user identify what
-                 * option is not understood.
-                 * This is also useful in case the user wants to pass
-                 * the output of format_converter to another function
-                 * that understands some other %<char> (like syslog).
-                 * Note that we can't point s inside fmt because the
-                 * unknown <char> could be preceded by width etc.
-                 */
-            default:
-                char_buf[0] = '%';
-                char_buf[1] = *fmt;
-                s = char_buf;
-                s_len = 2;
-                pad_char = ' ';
-                break;
-            }
-
-            if (prefix_char != NUL) {
-                *--s = prefix_char;
-                s_len++;
-            }
-            if (adjust_width && adjust == RIGHT && min_width > s_len) {
-                if (pad_char == '0' && prefix_char != NUL) {
-                    INS_CHAR(*s, sp, bep, cc)
-                    s++;
-                    s_len--;
-                    min_width--;
-                }
-                PAD(min_width, s_len, pad_char);
-            }
-            /*
-             * Print the string s.
-             */
-            for (i = s_len; i != 0; i--) {
-                INS_CHAR(*s, sp, bep, cc);
-                s++;
-            }
-
-            if (adjust_width && adjust == LEFT && min_width > s_len)
-                PAD(min_width, s_len, pad_char);
-        }
-        fmt++;
-    }
-    odp->nextb = sp;
-    return (cc);
-}
-
-
-/*
- * This is the general purpose conversion function.
- */
-static void strx_printv(int *ccp, char *buf, size_t len, const char *format,
-                        va_list ap)
-{
-    buffy od;
-    int cc;
-
-    /*
-     * First initialize the descriptor
-     * Notice that if no length is given, we initialize buf_end to the
-     * highest possible address.
-     */
-    od.buf_end = len ? &buf[len] : (char *) ~0;
-    od.nextb = buf;
-
-    /*
-     * Do the conversion
-     */
-    cc = format_converter(&od, format, ap);
-    if (len == 0 || od.nextb <= od.buf_end)
-        *(od.nextb) = '\0';
-    if (ccp)
-        *ccp = cc;
-}
-
-
-int ap_snprintf(char *buf, size_t len, const char *format,...)
-{
-    int cc;
-    va_list ap;
-
-    va_start(ap, format);
-    strx_printv(&cc, buf, (len - 1), format, ap);
-    va_end(ap);
-    return (cc);
-}
-
-
-int ap_vsnprintf(char *buf, size_t len, const char *format, va_list ap)
-{
-    int cc;
-
-    strx_printv(&cc, buf, (len - 1), format, ap);
-    return (cc);
-}
-
-#endif                          /* HAVE_SNPRINTF */
--- a/mcabber/libjabber/socket.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,256 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyrights
- *
- * Portions created by or assigned to Jabber.com, Inc. are
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- *
- * Acknowledgements
- *
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- *
- */
-
-/**
- * @file socket.c
- * @brief some misc functions to handle sockets
- */
-
-#include "libxode.h"
-#include "connwrap.h"
-
-/**
- * Simple wrapper to make socket creation easy.
- *
- * @param port port number of the socket
- * @param host hostname where to connect to or listen on
- * @param type type of socket (NETSOCKET_SERVER, NETSOCKET_CLIENT; or NETSOCKET_UDP)
- * @return file handle of the new socket
- *
- * NETSOCKET_SERVER is local listening socket
- * NETSOCKET_CLIENT is connection socket
- */
-int make_netsocket(u_short port, char *host, int type, int ssl)
-{
-    int s, flag = 1;
-    struct sockaddr_in sa;
-    struct in_addr *saddr;
-    int socket_type;
-
-    /* is this a UDP socket or a TCP socket? */
-    socket_type = (type == NETSOCKET_UDP)?SOCK_DGRAM:SOCK_STREAM;
-
-    bzero((void *)&sa,sizeof(struct sockaddr_in));
-
-    if((s = socket(AF_INET,socket_type,0)) < 0)
-        return(-1);
-    if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(flag)) < 0)
-        return(-1);
-
-    saddr = make_addr(host);
-    if(saddr == NULL)
-        return(-1);
-    sa.sin_family = AF_INET;
-    sa.sin_port = htons(port);
-
-    if(type == NETSOCKET_SERVER)
-    {
-        /* bind to specific address if specified */
-        if(host != NULL)
-            sa.sin_addr.s_addr = saddr->s_addr;
-
-        if(bind(s,(struct sockaddr*)&sa,sizeof sa) < 0)
-        {
-            close(s);
-            return(-1);
-        }
-    }
-    if(type == NETSOCKET_CLIENT)
-    {
-        sa.sin_addr.s_addr = saddr->s_addr;
-        if(cw_connect(s,(struct sockaddr*)&sa,sizeof sa,ssl) < 0)
-        {
-            close(s);
-            return(-1);
-        }
-    }
-    if(type == NETSOCKET_UDP)
-    {
-        /* bind to all addresses for now */
-        if(bind(s,(struct sockaddr*)&sa,sizeof sa) < 0)
-        {
-            close(s);
-            return(-1);
-        }
-
-        /* specify default recipient for read/write */
-        sa.sin_addr.s_addr = saddr->s_addr;
-        if(cw_connect(s,(struct sockaddr*)&sa,sizeof sa,ssl) < 0)
-        {
-            close(s);
-            return(-1);
-        }
-    }
-
-
-    return(s);
-}
-
-void change_socket_to_blocking(int s)
-     /* make socket blocking */
-{
-    int val;
-    val = fcntl(s, F_GETFL, 0);
-    fcntl(s, F_SETFL, val & (~O_NONBLOCK));
-}
-
-void change_socket_to_nonblocking(int s)
-     /* make socket non-blocking */
-{
-    int val;
-    val = fcntl(s, F_GETFL, 0);
-    fcntl(s, F_SETFL, val | O_NONBLOCK);
-}
-
-/* socket.c
- *
- * Simple wrapper to make non-blocking client socket creation easy.
- * type = NETSOCKET_SERVER is local listening socket
- * type = NETSOCKET_CLIENT is connection socket
- * type = NETSOCKET_UDP
- */
-
-int make_nb_netsocket(u_short port, char *host, int type, int ssl, int* state)
-{
-    int s, flag = 1;
-    struct sockaddr_in sa;
-    struct in_addr *saddr;
-    int socket_type;
-
-    /* is this a UDP socket or a TCP socket? */
-    socket_type = (type == NETSOCKET_UDP)?SOCK_DGRAM:SOCK_STREAM;
-
-    bzero((void *)&sa,sizeof(struct sockaddr_in));
-
-    if((s = socket(AF_INET,socket_type,0)) < 0)
-        return(-1);
-    if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(flag)) < 0)
-        return(-1);
-    change_socket_to_nonblocking(s);
-
-    saddr = make_addr(host);
-    if(saddr == NULL)
-        return(-1);
-    sa.sin_family = AF_INET;
-    sa.sin_port = htons(port);
-
-    if(type == NETSOCKET_SERVER)
-    {
-        /* bind to specific address if specified */
-        if(host != NULL)
-            sa.sin_addr.s_addr = saddr->s_addr;
-
-        if(bind(s,(struct sockaddr*)&sa,sizeof sa) < 0)
-        {
-            close(s);
-            return(-1);
-        }
-    }
-    if(type == NETSOCKET_CLIENT)
-    {
-        int rc;
-        sa.sin_addr.s_addr = saddr->s_addr;
-        rc = cw_nb_connect(s,(struct sockaddr*)&sa,sizeof sa,ssl, state);
-        if (rc == -1 )
-        {
-            close(s);
-            return(-1);
-        }
-    }
-    if(type == NETSOCKET_UDP)
-    {
-        /* bind to all addresses for now */
-        if(bind(s,(struct sockaddr*)&sa,sizeof sa) < 0)
-        {
-            close(s);
-            return(-1);
-        }
-
-        /* specify default recipient for read/write */
-        sa.sin_addr.s_addr = saddr->s_addr;
-        if(cw_connect(s,(struct sockaddr*)&sa,sizeof sa,ssl) < 0)
-        {
-            close(s);
-            return(-1);
-        }
-    }
-
-
-    return(s);
-}
-
-struct in_addr *make_addr(char *host)
-{
-    struct hostent *hp;
-    static struct in_addr addr;
-    char myname[MAXHOSTNAMELEN + 1];
-
-    if (host == NULL || strlen(host) == 0) {
-        gethostname(myname,MAXHOSTNAMELEN);
-        hp = gethostbyname(myname);
-        if(hp != NULL) {
-            return (struct in_addr *) *hp->h_addr_list;
-        }
-    } else {
-        addr.s_addr = inet_addr(host);
-        if(addr.s_addr != (in_addr_t)-1) {
-            return &addr;
-        }
-        hp = gethostbyname(host);
-        if(hp != NULL) {
-            return (struct in_addr *) *hp->h_addr_list;
-        }
-    }
-    return NULL;
-}
-
-/**
- * Sets a file descriptor to close on exec.
- *
- * @param fd the file descriptor
- * @param flag 1 to close on exec, 0 to leave open across exec
- *
- * @deprecated this function is not used by jabberd14 and might be removed in future versions
- */
-int set_fd_close_on_exec(int fd, int flag)
-{
-    int oldflags = fcntl(fd,F_GETFL);
-    int newflags;
-
-    if(flag)
-        newflags = oldflags | FD_CLOEXEC;
-    else
-        newflags = oldflags & (~FD_CLOEXEC);
-
-    if(newflags==oldflags)
-        return 0;
-    return fcntl(fd,F_SETFL,(long)newflags);
-}
-
--- a/mcabber/libjabber/str.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,414 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyrights
- *
- * Portions created by or assigned to Jabber.com, Inc. are
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- *
- * Acknowledgements
- *
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- *
- */
-
-/**
- * @file str.c
- * @brief utilities for string handling
- *
- * This file contains utility functions for string handling:
- * - NULL pointer save versions of many functions in string.c
- * - string spools
- * - functions to (un)escape strings for XML usage
- *
- * String spools allow to create a string by concatenating several smaller strings
- * and the spool implementation is allocating the neccessary memory using memory pools.
- */
-
-#include "libxode.h"
-
-/**
- * NULL pointer save version of strdup()
- *
- * @param str the string the should be duplicated
- * @return the duplicated string
- */
-char *j_strdup(const char *str)
-{
-    if(str == NULL)
-        return NULL;
-    else
-        return strdup(str);
-}
-
-/**
- * NULL pointer save version of strcat()
- *
- * @note the return value of j_strcat() is not compatible with the return value of strcat()
- *
- * @todo check if the behaviour of the return value is intended
- *
- * @param dest where to append the string
- * @param txt what to append
- * @return dest if txt contains a NULL pointer, pointer to the terminating zero byte of the result else
- */
-char *j_strcat(char *dest, char *txt)
-{
-    if(!txt) return(dest);
-
-    while(*txt)
-        *dest++ = *txt++;
-    *dest = '\0';
-
-    return(dest);
-}
-
-/**
- * NULL pointer save version of strcmp
- *
- * If one of the parameters contains a NULL pointer, the string is considered to be unequal.
- *
- * @note the return value is not compatible with strcmp()
- *
- * @param a the one string
- * @param b the other string
- * @return 0 if the strings are equal, -1 if the strings are not equal
- */
-int j_strcmp(const char *a, const char *b)
-{
-    if(a == NULL || b == NULL)
-        return -1;
-
-    while(*a == *b && *a != '\0' && *b != '\0'){ a++; b++; }
-
-    if(*a == *b) return 0;
-
-    return -1;
-}
-
-/**
- * NULL pointer save version of strcasecmp()
- *
- * If one of the parameters contains a NULL pointer, the string is considered to be unequal
- *
- * @param a the one string
- * @param b the other string
- * @return 0 if the strings are equal, non zero else
- */
-int j_strcasecmp(const char *a, const char *b)
-{
-    if(a == NULL || b == NULL)
-        return -1;
-    else
-        return strcasecmp(a, b);
-}
-
-/**
- * NULL pointer save version of strncmp()
- *
- * If one of the parameters contains a NULL pointer, the string is considered to be unequal
- *
- * @param a the first string
- * @param b the second string
- * @param i how many characters to compare at most
- * @return 0 if the strings are equal (within the given length limitation), non zero else
- */
-int j_strncmp(const char *a, const char *b, int i)
-{
-    if(a == NULL || b == NULL)
-        return -1;
-    else
-        return strncmp(a, b, i);
-}
-
-/**
- * NULL pointer save version of strncasecmp()
- *
- * If one of the parameters contains a NULL pointer, the string is considered to be unequal
- *
- * @param a the first string
- * @param b the second string
- * @param i how many characters to compare at most
- * @return 0 if the strings are equal (within the given length limitation), non zero else
- */
-int j_strncasecmp(const char *a, const char *b, int i)
-{
-    if(a == NULL || b == NULL)
-        return -1;
-    else
-        return strncasecmp(a, b, i);
-}
-
-/**
- * NULL pointer save version of strlen
- *
- * If the parameter contains a NULL pointer, 0 is returned
- *
- * @param a the string for which the length should be calculated
- * @return 0 if a==NULL, length of the string else
- */
-int j_strlen(const char *a)
-{
-    if(a == NULL)
-        return 0;
-    else
-        return strlen(a);
-}
-
-int j_atoi(const char *a, int def)
-{
-    if(a == NULL)
-        return def;
-    else
-        return atoi(a);
-}
-
-spool spool_new(pool p)
-{
-    spool s;
-
-    s = pmalloc(p, sizeof(struct spool_struct));
-    s->p = p;
-    s->len = 0;
-    s->last = NULL;
-    s->first = NULL;
-    return s;
-}
-
-void spool_add(spool s, char *str)
-{
-    struct spool_node *sn;
-    int len;
-
-    if(str == NULL)
-        return;
-
-    len = strlen(str);
-    if(len == 0)
-        return;
-
-    sn = pmalloc(s->p, sizeof(struct spool_node));
-    sn->c = pstrdup(s->p, str);
-    sn->next = NULL;
-
-    s->len += len;
-    if(s->last != NULL)
-        s->last->next = sn;
-    s->last = sn;
-    if(s->first == NULL)
-        s->first = sn;
-}
-
-void spooler(spool s, ...)
-{
-    va_list ap;
-    char *arg = NULL;
-
-    if(s == NULL)
-        return;
-
-    va_start(ap, s);
-
-    /* loop till we hit our end flag, the first arg */
-    while(1)
-    {
-        arg = va_arg(ap,char *);
-        if((spool)arg == s)
-            break;
-        else
-            spool_add(s, arg);
-    }
-
-    va_end(ap);
-}
-
-char *spool_print(spool s)
-{
-    char *ret,*tmp;
-    struct spool_node *next;
-
-    if(s == NULL || s->len == 0 || s->first == NULL)
-        return NULL;
-
-    ret = pmalloc(s->p, s->len + 1);
-    *ret = '\0';
-
-    next = s->first;
-    tmp = ret;
-    while(next != NULL)
-    {
-        tmp = j_strcat(tmp,next->c);
-        next = next->next;
-    }
-
-    return ret;
-}
-
-/* convenience :) */
-char *spools(pool p, ...)
-{
-    va_list ap;
-    spool s;
-    char *arg = NULL;
-
-    if(p == NULL)
-        return NULL;
-
-    s = spool_new(p);
-
-    va_start(ap, p);
-
-    /* loop till we hit our end flag, the first arg */
-    while(1)
-    {
-        arg = va_arg(ap,char *);
-        if((pool)arg == p)
-            break;
-        else
-            spool_add(s, arg);
-    }
-
-    va_end(ap);
-
-    return spool_print(s);
-}
-
-
-char *strunescape(pool p, char *buf)
-{
-    int i,j=0;
-    char *temp;
-
-    if (p == NULL || buf == NULL) return(NULL);
-
-    if (strchr(buf,'&') == NULL) return(buf);
-
-    temp = pmalloc(p,strlen(buf)+1);
-
-    if (temp == NULL) return(NULL);
-
-    for(i=0;i<(int)strlen(buf);i++)
-    {
-        if (buf[i]=='&')
-        {
-            if (strncmp(&buf[i],"&amp;",5)==0)
-            {
-                temp[j] = '&';
-                i += 4;
-            } else if (strncmp(&buf[i],"&quot;",6)==0) {
-                temp[j] = '\"';
-                i += 5;
-            } else if (strncmp(&buf[i],"&apos;",6)==0) {
-                temp[j] = '\'';
-                i += 5;
-            } else if (strncmp(&buf[i],"&lt;",4)==0) {
-                temp[j] = '<';
-                i += 3;
-            } else if (strncmp(&buf[i],"&gt;",4)==0) {
-                temp[j] = '>';
-                i += 3;
-            }
-        } else {
-            temp[j]=buf[i];
-        }
-        j++;
-    }
-    temp[j]='\0';
-    return(temp);
-}
-
-
-char *strescape(pool p, char *buf)
-{
-    int i,j,oldlen,newlen;
-    char *temp;
-
-    if (p == NULL || buf == NULL) return(NULL);
-
-    oldlen = newlen = strlen(buf);
-    for(i=0;i<oldlen;i++)
-    {
-        switch(buf[i])
-        {
-        case '&':
-            newlen+=5;
-            break;
-        case '\'':
-            newlen+=6;
-            break;
-        case '\"':
-            newlen+=6;
-            break;
-        case '<':
-            newlen+=4;
-            break;
-        case '>':
-            newlen+=4;
-            break;
-        }
-    }
-
-    if(oldlen == newlen) return buf;
-
-    temp = pmalloc(p,newlen+1);
-
-    if (temp==NULL) return(NULL);
-
-    for(i=j=0;i<oldlen;i++)
-    {
-        switch(buf[i])
-        {
-        case '&':
-            memcpy(&temp[j],"&amp;",5);
-            j += 5;
-            break;
-        case '\'':
-            memcpy(&temp[j],"&apos;",6);
-            j += 6;
-            break;
-        case '\"':
-            memcpy(&temp[j],"&quot;",6);
-            j += 6;
-            break;
-        case '<':
-            memcpy(&temp[j],"&lt;",4);
-            j += 4;
-            break;
-        case '>':
-            memcpy(&temp[j],"&gt;",4);
-            j += 4;
-            break;
-        default:
-            temp[j++] = buf[i];
-        }
-    }
-    temp[j] = '\0';
-    return temp;
-}
-
-char *zonestr(char *file, int line)
-{
-    static char buff[64];
-    int i;
-
-    i = snprintf(buff,63,"%s:%d",file,line);
-    buff[i] = '\0';
-
-    return buff;
-}
--- a/mcabber/libjabber/utf8tab.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-
-/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
-/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
--- a/mcabber/libjabber/xmldef.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-#include <string.h>
-
-#ifdef XML_WINLIB
-
-#define WIN32_LEAN_AND_MEAN
-#define STRICT
-#include <windows.h>
-
-#define malloc(x) HeapAlloc(GetProcessHeap(), 0, (x))
-#define calloc(x, y) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (x)*(y))
-#define free(x) HeapFree(GetProcessHeap(), 0, (x))
-#define realloc(x, y) HeapReAlloc(GetProcessHeap(), 0, x, y)
-#define abort() /* as nothing */
-
-#else /* not XML_WINLIB */
-
-#include <stdlib.h>
-
-#endif /* not XML_WINLIB */
-
-/* This file can be used for any definitions needed in
-particular environments. */
-
-#ifdef MOZILLA
-
-#include "nspr.h"
-#define malloc(x) PR_Malloc(x)
-#define realloc(x, y) PR_Realloc((x), (y))
-#define calloc(x, y) PR_Calloc((x),(y))
-#define free(x) PR_Free(x)
-#define int int32
-
-#endif /* MOZILLA */
--- a/mcabber/libjabber/xmlnode.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,834 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyrights
- *
- * Portions created by or assigned to Jabber.com, Inc. are
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- *
- * Acknowledgements
- *
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- *
- */
-
-#include "libxode.h"
-
-/* Internal routines */
-xmlnode _xmlnode_new(pool p, const char* name, unsigned int type)
-{
-    xmlnode result = NULL;
-    if (type > NTYPE_LAST)
-        return NULL;
-
-    if (type != NTYPE_CDATA && name == NULL)
-        return NULL;
-
-    if (p == NULL)
-    {
-        p = pool_heap(1*1024);
-    }
-
-    /* Allocate & zero memory */
-    result = (xmlnode)pmalloco(p, sizeof(_xmlnode));
-
-    /* Initialize fields */
-    if (type != NTYPE_CDATA)
-        result->name = pstrdup(p,name);
-    result->type = type;
-    result->p = p;
-    return result;
-}
-
-static xmlnode _xmlnode_append_sibling(xmlnode lastsibling, const char* name, unsigned int type)
-{
-    xmlnode result;
-
-    result = _xmlnode_new(xmlnode_pool(lastsibling), name, type);
-    if (result != NULL)
-    {
-        /* Setup sibling pointers */
-        result->prev = lastsibling;
-        lastsibling->next = result;
-    }
-    return result;
-}
-
-static xmlnode _xmlnode_insert(xmlnode parent, const char* name, unsigned int type)
-{
-    xmlnode result;
-
-    if(parent == NULL || (type != NTYPE_CDATA && name == NULL)) return NULL;
-
-    /* If parent->firstchild is NULL, simply create a new node for the first child */
-    if (parent->firstchild == NULL)
-    {
-        result = _xmlnode_new(parent->p, name, type);
-        parent->firstchild = result;
-    }
-    /* Otherwise, append this to the lastchild */
-    else
-    {
-        result= _xmlnode_append_sibling(parent->lastchild, name, type);
-    }
-    result->parent = parent;
-    parent->lastchild = result;
-    return result;
-
-}
-
-static xmlnode _xmlnode_search(xmlnode firstsibling, const char* name, unsigned int type)
-{
-    xmlnode current;
-
-    /* Walk the sibling list, looking for a NTYPE_TAG xmlnode with
-    the specified name */
-    current = firstsibling;
-    while (current != NULL)
-    {
-        if ((current->type == type) && (j_strcmp(current->name, name) == 0))
-            return current;
-        else
-            current = current->next;
-    }
-    return NULL;
-}
-
-void _xmlnode_merge(xmlnode data)
-{
-    xmlnode cur;
-    char *merge, *scur;
-    int imerge;
-
-    /* get total size of all merged cdata */
-    imerge = 0;
-    for(cur = data; cur != NULL && cur->type == NTYPE_CDATA; cur = cur->next)
-        imerge += cur->data_sz;
-
-    /* copy in current data and then spin through all of them and merge */
-    scur = merge = pmalloc(data->p,imerge + 1);
-    for(cur = data; cur != NULL && cur->type == NTYPE_CDATA; cur = cur->next)
-    {
-        memcpy(scur,cur->data,cur->data_sz);
-        scur += cur->data_sz;
-    }
-    *scur = '\0';
-
-    /* this effectively hides all of the merged-in chunks */
-    data->next = cur;
-    if(cur == NULL)
-        data->parent->lastchild = data;
-    else
-        cur->prev = data;
-
-    /* reset data */
-    data->data = merge;
-    data->data_sz = imerge;
-}
-
-static void _xmlnode_hide_sibling(xmlnode child)
-{
-    if(child == NULL)
-        return;
-
-    if(child->prev != NULL)
-        child->prev->next = child->next;
-    if(child->next != NULL)
-        child->next->prev = child->prev;
-}
-
-void _xmlnode_tag2str(spool s, xmlnode node, int flag)
-{
-    xmlnode tmp;
-
-    if(flag==0 || flag==1)
-    {
-	    spooler(s,"<",xmlnode_get_name(node),s);
-	    tmp = xmlnode_get_firstattrib(node);
-	    while(tmp) {
-	        spooler(s," ",xmlnode_get_name(tmp),"='",strescape(xmlnode_pool(node),xmlnode_get_data(tmp)),"'",s);
-	        tmp = xmlnode_get_nextsibling(tmp);
-	    }
-	    if(flag==0)
-	        spool_add(s,"/>");
-	    else
-	        spool_add(s,">");
-    }
-    else
-    {
-	    spooler(s,"</",xmlnode_get_name(node),">",s);
-    }
-}
-
-spool _xmlnode2spool(xmlnode node)
-{
-    spool s;
-    int level=0,dir=0;
-    xmlnode tmp;
-
-    if(!node || xmlnode_get_type(node)!=NTYPE_TAG)
-        return NULL;
-
-    s = spool_new(xmlnode_pool(node));
-    if(!s) return(NULL);
-
-    while(1)
-    {
-        if(dir==0)
-        {
-            if(xmlnode_get_type(node) == NTYPE_TAG)
-            {
-                if(xmlnode_has_children(node))
-                {
-                    _xmlnode_tag2str(s,node,1);
-                    node = xmlnode_get_firstchild(node);
-                    level++;
-                    continue;
-                }else{
-                    _xmlnode_tag2str(s,node,0);
-                }
-            }else{
-                spool_add(s,strescape(xmlnode_pool(node),xmlnode_get_data(node)));
-            }
-        }
-
-        tmp = xmlnode_get_nextsibling(node);
-        if(!tmp)
-        {
-            node = xmlnode_get_parent(node);
-            level--;
-            if(level>=0) _xmlnode_tag2str(s,node,2);
-            if(level<1) break;
-            dir = 1;
-        }else{
-            node = tmp;
-            dir = 0;
-        }
-    }
-
-    return s;
-}
-
-
-/* External routines */
-
-
-/*
- *  xmlnode_new_tag -- create a tag node
- *  Automatically creates a memory pool for the node.
- *
- *  parameters
- *      name -- name of the tag
- *
- *  returns
- *      a pointer to the tag node
- *      or NULL if it was unsuccessfull
- */
-xmlnode xmlnode_new_tag(const char* name)
-{
-    return _xmlnode_new(NULL, name, NTYPE_TAG);
-}
-
-
-/*
- *  xmlnode_new_tag_pool -- create a tag node within given pool
- *
- *  parameters
- *      p -- previously created memory pool
- *      name -- name of the tag
- *
- *  returns
- *      a pointer to the tag node
- *      or NULL if it was unsuccessfull
- */
-xmlnode xmlnode_new_tag_pool(pool p, const char* name)
-{
-    return _xmlnode_new(p, name, NTYPE_TAG);
-}
-
-
-/*
- *  xmlnode_insert_tag -- append a child tag to a tag
- *
- *  parameters
- *      parent -- pointer to the parent tag
- *      name -- name of the child tag
- *
- *  returns
- *      a pointer to the child tag node
- *      or NULL if it was unsuccessfull
- */
-xmlnode xmlnode_insert_tag(xmlnode parent, const char* name)
-{
-    return _xmlnode_insert(parent, name, NTYPE_TAG);
-}
-
-
-/*
- *  xmlnode_insert_cdata -- append character data to a tag
- *
- *  parameters
- *      parent -- parent tag
- *      CDATA -- character data
- *      size -- size of CDATA
- *              or -1 for null-terminated CDATA strings
- *
- *  returns
- *      a pointer to the child CDATA node
- *      or NULL if it was unsuccessfull
- */
-xmlnode xmlnode_insert_cdata(xmlnode parent, const char* CDATA, unsigned int size)
-{
-    xmlnode result;
-
-    if(CDATA == NULL || parent == NULL)
-        return NULL;
-
-    if(size == (unsigned int)-1)
-        size = strlen(CDATA);
-
-    result = _xmlnode_insert(parent, NULL, NTYPE_CDATA);
-    if (result != NULL)
-    {
-        result->data = (char*)pmalloc(result->p, size + 1);
-        memcpy(result->data, CDATA, size);
-        result->data[size] = '\0';
-        result->data_sz = size;
-    }
-
-    return result;
-}
-
-
-/*
- *  xmlnode_get_tag -- find given tag in an xmlnode tree
- *
- *  parameters
- *      parent -- pointer to the parent tag
- *      name -- "name" for the child tag of that name
- *              "name/name" for a sub child (recurses)
- *              "?attrib" to match the first tag with that attrib defined
- *              "?attrib=value" to match the first tag with that attrib and value
- *              "=cdata" to match the cdata contents of the child
- *              or any combination: "name/name/?attrib", "name=cdata", etc
- *
- *  results
- *      a pointer to the tag matching search criteria
- *      or NULL if search was unsuccessfull
- */
-xmlnode xmlnode_get_tag(xmlnode parent, const char* name)
-{
-    char *str, *slash, *qmark, *equals;
-    xmlnode step, ret;
-
-
-    if(parent == NULL || parent->firstchild == NULL || name == NULL || name == '\0') return NULL;
-
-    if(strstr(name, "/") == NULL && strstr(name,"?") == NULL && strstr(name, "=") == NULL)
-        return _xmlnode_search(parent->firstchild, name, NTYPE_TAG);
-
-    str = strdup(name);
-    slash = strstr(str, "/");
-    qmark = strstr(str, "?");
-    equals = strstr(str, "=");
-
-    if(equals != NULL && (slash == NULL || equals < slash) && (qmark == NULL || equals < qmark))
-    { /* of type =cdata */
-
-        *equals = '\0';
-        equals++;
-
-        for(step = parent->firstchild; step != NULL; step = xmlnode_get_nextsibling(step))
-        {
-            if(xmlnode_get_type(step) != NTYPE_TAG)
-                continue;
-
-            if(*str != '\0')
-                if(j_strcmp(xmlnode_get_name(step),str) != 0)
-                    continue;
-
-            if(j_strcmp(xmlnode_get_data(step),equals) != 0)
-                continue;
-
-            break;
-        }
-
-        free(str);
-        return step;
-    }
-
-
-    if(qmark != NULL && (slash == NULL || qmark < slash))
-    { /* of type ?attrib */
-
-        *qmark = '\0';
-        qmark++;
-        if(equals != NULL)
-        {
-            *equals = '\0';
-            equals++;
-        }
-
-        for(step = parent->firstchild; step != NULL; step = xmlnode_get_nextsibling(step))
-        {
-            if(xmlnode_get_type(step) != NTYPE_TAG)
-                continue;
-
-            if(*str != '\0')
-                if(j_strcmp(xmlnode_get_name(step),str) != 0)
-                    continue;
-
-            if(xmlnode_get_attrib(step,qmark) == NULL)
-                continue;
-
-            if(equals != NULL && j_strcmp(xmlnode_get_attrib(step,qmark),equals) != 0)
-                continue;
-
-            break;
-        }
-
-        free(str);
-        return step;
-    }
-
-
-    *slash = '\0';
-    ++slash;
-
-    for(step = parent->firstchild; step != NULL; step = xmlnode_get_nextsibling(step))
-    {
-        if(xmlnode_get_type(step) != NTYPE_TAG) continue;
-
-        if(j_strcmp(xmlnode_get_name(step),str) != 0)
-            continue;
-
-        ret = xmlnode_get_tag(step, slash);
-        if(ret != NULL)
-        {
-            free(str);
-            return ret;
-        }
-    }
-
-    free(str);
-    return NULL;
-}
-
-
-/* return the cdata from any tag */
-char *xmlnode_get_tag_data(xmlnode parent, const char *name)
-{
-    xmlnode tag;
-
-    tag = xmlnode_get_tag(parent, name);
-    if(tag == NULL) return NULL;
-
-    return xmlnode_get_data(tag);
-}
-
-
-void xmlnode_put_attrib(xmlnode owner, const char* name, const char* value)
-{
-    xmlnode attrib;
-
-    if(owner == NULL || name == NULL || value == NULL) return;
-
-    /* If there are no existing attributs, allocate a new one to start
-    the list */
-    if (owner->firstattrib == NULL)
-    {
-        attrib = _xmlnode_new(owner->p, name, NTYPE_ATTRIB);
-        owner->firstattrib = attrib;
-        owner->lastattrib  = attrib;
-    }
-    else
-    {
-        attrib = _xmlnode_search(owner->firstattrib, name, NTYPE_ATTRIB);
-        if(attrib == NULL)
-        {
-            attrib = _xmlnode_append_sibling(owner->lastattrib, name, NTYPE_ATTRIB);
-            owner->lastattrib = attrib;
-        }
-    }
-    /* Update the value of the attribute */
-    attrib->data_sz = strlen(value);
-    attrib->data    = pstrdup(owner->p, value);
-
-}
-
-char* xmlnode_get_attrib(xmlnode owner, const char* name)
-{
-    xmlnode attrib;
-
-    if (owner != NULL && owner->firstattrib != NULL)
-    {
-        attrib = _xmlnode_search(owner->firstattrib, name, NTYPE_ATTRIB);
-        if (attrib != NULL)
-            return (char*)attrib->data;
-    }
-    return NULL;
-}
-
-void xmlnode_put_vattrib(xmlnode owner, const char* name, void *value)
-{
-    xmlnode attrib;
-
-    if (owner != NULL)
-    {
-        attrib = _xmlnode_search(owner->firstattrib, name, NTYPE_ATTRIB);
-        if (attrib == NULL)
-        {
-            xmlnode_put_attrib(owner, name, "");
-            attrib = _xmlnode_search(owner->firstattrib, name, NTYPE_ATTRIB);
-        }
-        if (attrib != NULL)
-            attrib->firstchild = (xmlnode)value;
-    }
-}
-
-void* xmlnode_get_vattrib(xmlnode owner, const char* name)
-{
-    xmlnode attrib;
-
-    if (owner != NULL && owner->firstattrib != NULL)
-    {
-        attrib = _xmlnode_search(owner->firstattrib, name, NTYPE_ATTRIB);
-        if (attrib != NULL)
-            return (void*)attrib->firstchild;
-    }
-    return NULL;
-}
-
-xmlnode xmlnode_get_firstattrib(xmlnode parent)
-{
-    if (parent != NULL)
-        return parent->firstattrib;
-    return NULL;
-}
-
-xmlnode xmlnode_get_firstchild(xmlnode parent)
-{
-    if (parent != NULL)
-        return parent->firstchild;
-    return NULL;
-}
-
-xmlnode xmlnode_get_lastchild(xmlnode parent)
-{
-    if (parent != NULL)
-        return parent->lastchild;
-    return NULL;
-}
-
-xmlnode xmlnode_get_nextsibling(xmlnode sibling)
-{
-    if (sibling != NULL)
-        return sibling->next;
-    return NULL;
-}
-
-xmlnode xmlnode_get_prevsibling(xmlnode sibling)
-{
-    if (sibling != NULL)
-        return sibling->prev;
-    return NULL;
-}
-
-xmlnode xmlnode_get_parent(xmlnode node)
-{
-    if (node != NULL)
-        return node->parent;
-    return NULL;
-}
-
-char* xmlnode_get_name(xmlnode node)
-{
-    if (node != NULL)
-        return node->name;
-    return NULL;
-}
-
-char* xmlnode_get_data(xmlnode node)
-{
-    if(xmlnode_get_type(node) == NTYPE_TAG) /* loop till we find a CDATA in the children */
-        for(node = xmlnode_get_firstchild(node); node != NULL; node = xmlnode_get_nextsibling(node))
-            if(xmlnode_get_type(node) == NTYPE_CDATA) break;
-
-    if(node == NULL) return NULL;
-
-    /* check for a dirty node w/ unassembled cdata chunks */
-    if(xmlnode_get_type(node->next) == NTYPE_CDATA)
-        _xmlnode_merge(node);
-
-    return node->data;
-}
-
-int xmlnode_get_datasz(xmlnode node)
-{
-    if(xmlnode_get_type(node) != NTYPE_CDATA) return 0;
-
-    /* check for a dirty node w/ unassembled cdata chunks */
-    if(xmlnode_get_type(node->next) == NTYPE_CDATA)
-        _xmlnode_merge(node);
-    return node->data_sz;
-}
-
-int xmlnode_get_type(xmlnode node)
-{
-    if (node != NULL)
-        return node->type;
-    return NTYPE_UNDEF;
-}
-
-int xmlnode_has_children(xmlnode node)
-{
-    if ((node != NULL) && (node->firstchild != NULL))
-        return 1;
-    return 0;
-}
-
-int xmlnode_has_attribs(xmlnode node)
-{
-    if ((node != NULL) && (node->firstattrib != NULL))
-        return 1;
-    return 0;
-}
-
-pool xmlnode_pool(xmlnode node)
-{
-    if (node != NULL)
-        return node->p;
-    return (pool)NULL;
-}
-
-void xmlnode_hide(xmlnode child)
-{
-    xmlnode parent;
-
-    if(child == NULL || child->parent == NULL)
-        return;
-
-    parent = child->parent;
-
-    /* first fix up at the child level */
-    _xmlnode_hide_sibling(child);
-
-    /* next fix up at the parent level */
-    if(parent->firstchild == child)
-        parent->firstchild = child->next;
-    if(parent->lastchild == child)
-        parent->lastchild = child->prev;
-}
-
-void xmlnode_hide_attrib(xmlnode parent, const char *name)
-{
-    xmlnode attrib;
-
-    if(parent == NULL || parent->firstattrib == NULL || name == NULL)
-        return;
-
-    attrib = _xmlnode_search(parent->firstattrib, name, NTYPE_ATTRIB);
-    if(attrib == NULL)
-        return;
-
-    /* first fix up at the child level */
-    _xmlnode_hide_sibling(attrib);
-
-    /* next fix up at the parent level */
-    if(parent->firstattrib == attrib)
-        parent->firstattrib = attrib->next;
-    if(parent->lastattrib == attrib)
-        parent->lastattrib = attrib->prev;
-}
-
-
-
-/*
- *  xmlnode2str -- convert given xmlnode tree into a string
- *
- *  parameters
- *      node -- pointer to the xmlnode structure
- *
- *  results
- *      a pointer to the created string
- *      or NULL if it was unsuccessfull
- */
-char *xmlnode2str(xmlnode node)
-{
-     return spool_print(_xmlnode2spool(node));
-}
-
-/*
- *  xmlnode2tstr -- convert given xmlnode tree into a newline terminated string
- *
- *  parameters
- *      node -- pointer to the xmlnode structure
- *
- *  results
- *      a pointer to the created string
- *      or NULL if it was unsuccessfull
- */
-char*    xmlnode2tstr(xmlnode node)
-{
-     spool s = _xmlnode2spool(node);
-     if (s != NULL)
-	  spool_add(s, "\n");
-    return spool_print(s);
-}
-
-
-/* loop through both a and b comparing everything, attribs, cdata, children, etc */
-int xmlnode_cmp(xmlnode a, xmlnode b)
-{
-    int ret = 0;
-
-    while(1)
-    {
-        if(a == NULL && b == NULL)
-            return 0;
-
-        if(a == NULL || b == NULL)
-            return -1;
-
-        if(xmlnode_get_type(a) != xmlnode_get_type(b))
-            return -1;
-
-        switch(xmlnode_get_type(a))
-        {
-        case NTYPE_ATTRIB:
-            ret = j_strcmp(xmlnode_get_name(a), xmlnode_get_name(b));
-            if(ret != 0)
-                return -1;
-            ret = j_strcmp(xmlnode_get_data(a), xmlnode_get_data(b));
-            if(ret != 0)
-                return -1;
-            break;
-        case NTYPE_TAG:
-            ret = j_strcmp(xmlnode_get_name(a), xmlnode_get_name(b));
-            if(ret != 0)
-                return -1;
-            ret = xmlnode_cmp(xmlnode_get_firstattrib(a), xmlnode_get_firstattrib(b));
-            if(ret != 0)
-                return -1;
-            ret = xmlnode_cmp(xmlnode_get_firstchild(a), xmlnode_get_firstchild(b));
-            if(ret != 0)
-                return -1;
-            break;
-        case NTYPE_CDATA:
-            ret = j_strcmp(xmlnode_get_data(a), xmlnode_get_data(b));
-            if(ret != 0)
-                return -1;
-        }
-        a = xmlnode_get_nextsibling(a);
-        b = xmlnode_get_nextsibling(b);
-    }
-}
-
-
-xmlnode xmlnode_insert_tag_node(xmlnode parent, xmlnode node)
-{
-    xmlnode child;
-
-    child = xmlnode_insert_tag(parent, xmlnode_get_name(node));
-    if (xmlnode_has_attribs(node))
-        xmlnode_insert_node(child, xmlnode_get_firstattrib(node));
-    if (xmlnode_has_children(node))
-        xmlnode_insert_node(child, xmlnode_get_firstchild(node));
-
-    return child;
-}
-
-/* places copy of node and node's siblings in parent */
-void xmlnode_insert_node(xmlnode parent, xmlnode node)
-{
-    if(node == NULL || parent == NULL)
-        return;
-
-    while(node != NULL)
-    {
-        switch(xmlnode_get_type(node))
-        {
-        case NTYPE_ATTRIB:
-            xmlnode_put_attrib(parent, xmlnode_get_name(node), xmlnode_get_data(node));
-            break;
-        case NTYPE_TAG:
-            xmlnode_insert_tag_node(parent, node);
-            break;
-        case NTYPE_CDATA:
-            xmlnode_insert_cdata(parent, xmlnode_get_data(node), xmlnode_get_datasz(node));
-        }
-        node = xmlnode_get_nextsibling(node);
-    }
-}
-
-
-/* produce full duplicate of x with a new pool, x must be a tag! */
-xmlnode xmlnode_dup(xmlnode x)
-{
-    xmlnode x2;
-
-    if(x == NULL)
-        return NULL;
-
-    x2 = xmlnode_new_tag(xmlnode_get_name(x));
-
-    if (xmlnode_has_attribs(x))
-        xmlnode_insert_node(x2, xmlnode_get_firstattrib(x));
-    if (xmlnode_has_children(x))
-        xmlnode_insert_node(x2, xmlnode_get_firstchild(x));
-
-    return x2;
-}
-
-xmlnode xmlnode_dup_pool(pool p, xmlnode x)
-{
-    xmlnode x2;
-
-    if(x == NULL)
-        return NULL;
-
-    x2 = xmlnode_new_tag_pool(p, xmlnode_get_name(x));
-
-    if (xmlnode_has_attribs(x))
-        xmlnode_insert_node(x2, xmlnode_get_firstattrib(x));
-    if (xmlnode_has_children(x))
-        xmlnode_insert_node(x2, xmlnode_get_firstchild(x));
-
-    return x2;
-}
-
-xmlnode xmlnode_wrap(xmlnode x,const char *wrapper)
-{
-    xmlnode wrap;
-    if(x==NULL||wrapper==NULL) return NULL;
-    wrap=xmlnode_new_tag_pool(xmlnode_pool(x),wrapper);
-    if(wrap==NULL) return NULL;
-    wrap->firstchild=x;
-    wrap->lastchild=x;
-    x->parent=wrap;
-    return wrap;
-}
-
-void xmlnode_free(xmlnode node)
-{
-    if(node == NULL)
-        return;
-
-    pool_free(node->p);
-}
--- a/mcabber/libjabber/xmlparse.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3252 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-#include "xmldef.h"
-#include "xmlparse.h"
-
-#ifdef XML_UNICODE
-#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
-#define XmlConvert XmlUtf16Convert
-#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
-#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
-#define XmlEncode XmlUtf16Encode
-#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
-typedef unsigned short ICHAR;
-#else
-#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
-#define XmlConvert XmlUtf8Convert
-#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
-#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
-#define XmlEncode XmlUtf8Encode
-#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
-typedef char ICHAR;
-#endif
-
-
-#ifndef XML_NS
-
-#define XmlInitEncodingNS XmlInitEncoding
-#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
-#undef XmlGetInternalEncodingNS
-#define XmlGetInternalEncodingNS XmlGetInternalEncoding
-#define XmlParseXmlDeclNS XmlParseXmlDecl
-
-#endif
-
-
-#ifdef XML_UNICODE_WCHAR_T
-#define XML_T(x) L ## x
-#else
-#define XML_T(x) x
-#endif
-
-/* Round up n to be a multiple of sz, where sz is a power of 2. */
-#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
-
-#include "xmltok.h"
-#include "xmlrole.h"
-#include "hashtable.h"
-
-#define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
-#define INIT_DATA_BUF_SIZE 1024
-#define INIT_ATTS_SIZE 16
-#define INIT_BLOCK_SIZE 1024
-#define INIT_BUFFER_SIZE 1024
-
-#define EXPAND_SPARE 24
-
-typedef struct binding {
-    struct prefix *prefix;
-    struct binding *nextTagBinding;
-    struct binding *prevPrefixBinding;
-    const struct attribute_id *attId;
-    XML_Char *uri;
-    int uriLen;
-    int uriAlloc;
-} BINDING;
-
-typedef struct prefix {
-    const XML_Char *name;
-    BINDING *binding;
-} PREFIX;
-
-typedef struct {
-    const XML_Char *str;
-    const XML_Char *localPart;
-    int uriLen;
-} TAG_NAME;
-
-typedef struct tag {
-    struct tag *parent;
-    const char *rawName;
-    int rawNameLength;
-    TAG_NAME name;
-    char *buf;
-    char *bufEnd;
-    BINDING *bindings;
-} TAG;
-
-typedef struct {
-    const XML_Char *name;
-    const XML_Char *textPtr;
-    int textLen;
-    const XML_Char *systemId;
-    const XML_Char *base;
-    const XML_Char *publicId;
-    const XML_Char *notation;
-    char open;
-} ENTITY;
-
-typedef struct block {
-    struct block *next;
-    int size;
-    XML_Char s[1];
-} BLOCK;
-
-typedef struct {
-    BLOCK *blocks;
-    BLOCK *freeBlocks;
-    const XML_Char *end;
-    XML_Char *ptr;
-    XML_Char *start;
-} STRING_POOL;
-
-/* The XML_Char before the name is used to determine whether
-an attribute has been specified. */
-typedef struct attribute_id {
-    XML_Char *name;
-    PREFIX *prefix;
-    char maybeTokenized;
-    char xmlns;
-} ATTRIBUTE_ID;
-
-typedef struct {
-    const ATTRIBUTE_ID *id;
-    char isCdata;
-    const XML_Char *value;
-} DEFAULT_ATTRIBUTE;
-
-typedef struct {
-    const XML_Char *name;
-    PREFIX *prefix;
-    int nDefaultAtts;
-    int allocDefaultAtts;
-    DEFAULT_ATTRIBUTE *defaultAtts;
-} ELEMENT_TYPE;
-
-typedef struct {
-    HASH_TABLE generalEntities;
-    HASH_TABLE elementTypes;
-    HASH_TABLE attributeIds;
-    HASH_TABLE prefixes;
-    STRING_POOL pool;
-    int complete;
-    int standalone;
-    const XML_Char *base;
-    PREFIX defaultPrefix;
-} DTD;
-
-typedef struct open_internal_entity {
-    const char *internalEventPtr;
-    const char *internalEventEndPtr;
-    struct open_internal_entity *next;
-    ENTITY *entity;
-} OPEN_INTERNAL_ENTITY;
-
-typedef enum XML_Error Processor(XML_Parser parser,
-                                 const char *start,
-                                 const char *end,
-                                 const char **endPtr);
-
-static Processor prologProcessor;
-static Processor prologInitProcessor;
-static Processor contentProcessor;
-static Processor cdataSectionProcessor;
-static Processor epilogProcessor;
-/* static Processor errorProcessor; */
-static Processor externalEntityInitProcessor;
-static Processor externalEntityInitProcessor2;
-static Processor externalEntityInitProcessor3;
-static Processor externalEntityContentProcessor;
-
-static enum XML_Error
-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
-static enum XML_Error
-processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
-static enum XML_Error
-initializeEncoding(XML_Parser parser);
-static enum XML_Error
-doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
-          const char *start, const char *end, const char **endPtr);
-static enum XML_Error
-doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
-static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s,
-                                TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
-static
-int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr);
-static int
-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, int isCdata, const XML_Char *dfltValue);
-static enum XML_Error
-storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
-                    STRING_POOL *);
-static enum XML_Error
-appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
-                     STRING_POOL *);
-static ATTRIBUTE_ID *
-getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
-static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
-static enum XML_Error
-storeEntityValue(XML_Parser parser, const char *start, const char *end);
-static int
-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
-static int
-reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
-static void
-reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
-
-static const XML_Char *getContext(XML_Parser parser);
-static int setContext(XML_Parser parser, const XML_Char *context);
-static void normalizePublicId(XML_Char *s);
-static int dtdInit(DTD *);
-static void dtdDestroy(DTD *);
-static int dtdCopy(DTD *newDtd, const DTD *oldDtd);
-static void poolInit(STRING_POOL *);
-static void poolClear(STRING_POOL *);
-static void poolDestroy(STRING_POOL *);
-static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
-                            const char *ptr, const char *end);
-static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
-                                 const char *ptr, const char *end);
-static int poolGrow(STRING_POOL *pool);
-static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
-static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
-
-#define poolStart(pool) ((pool)->start)
-#define poolEnd(pool) ((pool)->ptr)
-#define poolLength(pool) ((pool)->ptr - (pool)->start)
-#define poolChop(pool) ((void)--(pool->ptr))
-#define poolLastChar(pool) (((pool)->ptr)[-1])
-#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
-#define poolFinish(pool) ((pool)->start = (pool)->ptr)
-#define poolAppendChar(pool, c) \
-  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
-   ? 0 \
-   : ((*((pool)->ptr)++ = c), 1))
-
-typedef struct {
-    /* The first member must be userData so that the XML_GetUserData macro works. */
-    void *m_userData;
-    void *m_handlerArg;
-    char *m_buffer;
-    /* first character to be parsed */
-    const char *m_bufferPtr;
-    /* past last character to be parsed */
-    char *m_bufferEnd;
-    /* allocated end of buffer */
-    const char *m_bufferLim;
-    long m_parseEndByteIndex;
-    const char *m_parseEndPtr;
-    XML_Char *m_dataBuf;
-    XML_Char *m_dataBufEnd;
-    XML_StartElementHandler m_startElementHandler;
-    XML_EndElementHandler m_endElementHandler;
-    XML_CharacterDataHandler m_characterDataHandler;
-    XML_ProcessingInstructionHandler m_processingInstructionHandler;
-    XML_CommentHandler m_commentHandler;
-    XML_StartCdataSectionHandler m_startCdataSectionHandler;
-    XML_EndCdataSectionHandler m_endCdataSectionHandler;
-    XML_DefaultHandler m_defaultHandler;
-    XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
-    XML_NotationDeclHandler m_notationDeclHandler;
-    XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
-    XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
-    XML_NotStandaloneHandler m_notStandaloneHandler;
-    XML_ExternalEntityRefHandler m_externalEntityRefHandler;
-    void *m_externalEntityRefHandlerArg;
-    XML_UnknownEncodingHandler m_unknownEncodingHandler;
-    const ENCODING *m_encoding;
-    INIT_ENCODING m_initEncoding;
-    const XML_Char *m_protocolEncodingName;
-    int m_ns;
-    void *m_unknownEncodingMem;
-    void *m_unknownEncodingData;
-    void *m_unknownEncodingHandlerData;
-    void (*m_unknownEncodingRelease)(void *);
-    PROLOG_STATE m_prologState;
-    Processor *m_processor;
-    enum XML_Error m_errorCode;
-    const char *m_eventPtr;
-    const char *m_eventEndPtr;
-    const char *m_positionPtr;
-    OPEN_INTERNAL_ENTITY *m_openInternalEntities;
-    int m_defaultExpandInternalEntities;
-    int m_tagLevel;
-    ENTITY *m_declEntity;
-    const XML_Char *m_declNotationName;
-    const XML_Char *m_declNotationPublicId;
-    ELEMENT_TYPE *m_declElementType;
-    ATTRIBUTE_ID *m_declAttributeId;
-    char m_declAttributeIsCdata;
-    DTD m_dtd;
-    TAG *m_tagStack;
-    TAG *m_freeTagList;
-    BINDING *m_inheritedBindings;
-    BINDING *m_freeBindingList;
-    int m_attsSize;
-    int m_nSpecifiedAtts;
-    ATTRIBUTE *m_atts;
-    POSITION m_position;
-    STRING_POOL m_tempPool;
-    STRING_POOL m_temp2Pool;
-    char *m_groupConnector;
-    unsigned m_groupSize;
-    int m_hadExternalDoctype;
-    XML_Char m_namespaceSeparator;
-} Parser;
-
-#define userData (((Parser *)parser)->m_userData)
-#define handlerArg (((Parser *)parser)->m_handlerArg)
-#define startElementHandler (((Parser *)parser)->m_startElementHandler)
-#define endElementHandler (((Parser *)parser)->m_endElementHandler)
-#define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
-#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
-#define commentHandler (((Parser *)parser)->m_commentHandler)
-#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
-#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
-#define defaultHandler (((Parser *)parser)->m_defaultHandler)
-#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
-#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
-#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
-#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
-#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
-#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
-#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
-#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
-#define encoding (((Parser *)parser)->m_encoding)
-#define initEncoding (((Parser *)parser)->m_initEncoding)
-#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
-#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
-#define unknownEncodingHandlerData \
-  (((Parser *)parser)->m_unknownEncodingHandlerData)
-#define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
-#define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
-#define ns (((Parser *)parser)->m_ns)
-#define prologState (((Parser *)parser)->m_prologState)
-#define processor (((Parser *)parser)->m_processor)
-#define errorCode (((Parser *)parser)->m_errorCode)
-#define eventPtr (((Parser *)parser)->m_eventPtr)
-#define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
-#define positionPtr (((Parser *)parser)->m_positionPtr)
-#define position (((Parser *)parser)->m_position)
-#define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
-#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
-#define tagLevel (((Parser *)parser)->m_tagLevel)
-#define buffer (((Parser *)parser)->m_buffer)
-#define bufferPtr (((Parser *)parser)->m_bufferPtr)
-#define bufferEnd (((Parser *)parser)->m_bufferEnd)
-#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
-#define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
-#define bufferLim (((Parser *)parser)->m_bufferLim)
-#define dataBuf (((Parser *)parser)->m_dataBuf)
-#define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
-#define dtd (((Parser *)parser)->m_dtd)
-#define declEntity (((Parser *)parser)->m_declEntity)
-#define declNotationName (((Parser *)parser)->m_declNotationName)
-#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
-#define declElementType (((Parser *)parser)->m_declElementType)
-#define declAttributeId (((Parser *)parser)->m_declAttributeId)
-#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
-#define freeTagList (((Parser *)parser)->m_freeTagList)
-#define freeBindingList (((Parser *)parser)->m_freeBindingList)
-#define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
-#define tagStack (((Parser *)parser)->m_tagStack)
-#define atts (((Parser *)parser)->m_atts)
-#define attsSize (((Parser *)parser)->m_attsSize)
-#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
-#define tempPool (((Parser *)parser)->m_tempPool)
-#define temp2Pool (((Parser *)parser)->m_temp2Pool)
-#define groupConnector (((Parser *)parser)->m_groupConnector)
-#define groupSize (((Parser *)parser)->m_groupSize)
-#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
-#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
-
-#ifdef _MSC_VER
-#ifdef _DEBUG
-Parser *asParser(XML_Parser parser)
-{
-    return parser;
-}
-#endif
-#endif
-
-XML_Parser XML_ParserCreate(const XML_Char *encodingName)
-{
-    XML_Parser parser = malloc(sizeof(Parser));
-    if (!parser)
-        return parser;
-    processor = prologInitProcessor;
-    XmlPrologStateInit(&prologState);
-    userData = 0;
-    handlerArg = 0;
-    startElementHandler = 0;
-    endElementHandler = 0;
-    characterDataHandler = 0;
-    processingInstructionHandler = 0;
-    commentHandler = 0;
-    startCdataSectionHandler = 0;
-    endCdataSectionHandler = 0;
-    defaultHandler = 0;
-    unparsedEntityDeclHandler = 0;
-    notationDeclHandler = 0;
-    startNamespaceDeclHandler = 0;
-    endNamespaceDeclHandler = 0;
-    notStandaloneHandler = 0;
-    externalEntityRefHandler = 0;
-    externalEntityRefHandlerArg = parser;
-    unknownEncodingHandler = 0;
-    buffer = 0;
-    bufferPtr = 0;
-    bufferEnd = 0;
-    parseEndByteIndex = 0;
-    parseEndPtr = 0;
-    bufferLim = 0;
-    declElementType = 0;
-    declAttributeId = 0;
-    declEntity = 0;
-    declNotationName = 0;
-    declNotationPublicId = 0;
-    memset(&position, 0, sizeof(POSITION));
-    errorCode = XML_ERROR_NONE;
-    eventPtr = 0;
-    eventEndPtr = 0;
-    positionPtr = 0;
-    openInternalEntities = 0;
-    tagLevel = 0;
-    tagStack = 0;
-    freeTagList = 0;
-    freeBindingList = 0;
-    inheritedBindings = 0;
-    attsSize = INIT_ATTS_SIZE;
-    atts = malloc(attsSize * sizeof(ATTRIBUTE));
-    nSpecifiedAtts = 0;
-    dataBuf = malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
-    groupSize = 0;
-    groupConnector = 0;
-    hadExternalDoctype = 0;
-    unknownEncodingMem = 0;
-    unknownEncodingRelease = 0;
-    unknownEncodingData = 0;
-    unknownEncodingHandlerData = 0;
-    namespaceSeparator = '!';
-    ns = 0;
-    poolInit(&tempPool);
-    poolInit(&temp2Pool);
-    protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
-    if (!dtdInit(&dtd) || !atts || !dataBuf
-            || (encodingName && !protocolEncodingName)) {
-        XML_ParserFree(parser);
-        return 0;
-    }
-    dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
-    XmlInitEncoding(&initEncoding, &encoding, 0);
-    return parser;
-}
-
-XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
-{
-    static
-    const XML_Char implicitContext[] = {
-        XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
-        XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
-        XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
-        XML_T('.'), XML_T('w'), XML_T('3'),
-        XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
-        XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
-        XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
-        XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
-        XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
-        XML_T('\0')
-    };
-
-    XML_Parser parser = XML_ParserCreate(encodingName);
-    if (parser) {
-        XmlInitEncodingNS(&initEncoding, &encoding, 0);
-        ns = 1;
-        namespaceSeparator = nsSep;
-    }
-    if (!setContext(parser, implicitContext)) {
-        XML_ParserFree(parser);
-        return 0;
-    }
-    return parser;
-}
-
-int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
-{
-    if (!encodingName)
-        protocolEncodingName = 0;
-    else {
-        protocolEncodingName = poolCopyString(&tempPool, encodingName);
-        if (!protocolEncodingName)
-            return 0;
-    }
-    return 1;
-}
-
-XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
-        const XML_Char *context,
-        const XML_Char *encodingName)
-{
-    XML_Parser parser = oldParser;
-    DTD *oldDtd = &dtd;
-    XML_StartElementHandler oldStartElementHandler = startElementHandler;
-    XML_EndElementHandler oldEndElementHandler = endElementHandler;
-    XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
-    XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
-    XML_CommentHandler oldCommentHandler = commentHandler;
-    XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
-    XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
-    XML_DefaultHandler oldDefaultHandler = defaultHandler;
-    XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
-    XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
-    XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
-    XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
-    XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
-    void *oldUserData = userData;
-    void *oldHandlerArg = handlerArg;
-    int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
-    void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
-
-    parser = (ns
-              ? XML_ParserCreateNS(encodingName, namespaceSeparator)
-              : XML_ParserCreate(encodingName));
-    if (!parser)
-        return 0;
-    startElementHandler = oldStartElementHandler;
-    endElementHandler = oldEndElementHandler;
-    characterDataHandler = oldCharacterDataHandler;
-    processingInstructionHandler = oldProcessingInstructionHandler;
-    commentHandler = oldCommentHandler;
-    startCdataSectionHandler = oldStartCdataSectionHandler;
-    endCdataSectionHandler = oldEndCdataSectionHandler;
-    defaultHandler = oldDefaultHandler;
-    startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
-    endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
-    notStandaloneHandler = oldNotStandaloneHandler;
-    externalEntityRefHandler = oldExternalEntityRefHandler;
-    unknownEncodingHandler = oldUnknownEncodingHandler;
-    userData = oldUserData;
-    if (oldUserData == oldHandlerArg)
-        handlerArg = userData;
-    else
-        handlerArg = parser;
-    if (oldExternalEntityRefHandlerArg != oldParser)
-        externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
-    defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
-    if (!dtdCopy(&dtd, oldDtd) || !setContext(parser, context)) {
-        XML_ParserFree(parser);
-        return 0;
-    }
-    processor = externalEntityInitProcessor;
-    return parser;
-}
-
-static
-void destroyBindings(BINDING *bindings)
-{
-    for (;;) {
-        BINDING *b = bindings;
-        if (!b)
-            break;
-        bindings = b->nextTagBinding;
-        free(b->uri);
-        free(b);
-    }
-}
-
-void XML_ParserFree(XML_Parser parser)
-{
-    for (;;) {
-        TAG *p;
-        if (tagStack == 0) {
-            if (freeTagList == 0)
-                break;
-            tagStack = freeTagList;
-            freeTagList = 0;
-        }
-        p = tagStack;
-        tagStack = tagStack->parent;
-        free(p->buf);
-        destroyBindings(p->bindings);
-        free(p);
-    }
-    destroyBindings(freeBindingList);
-    destroyBindings(inheritedBindings);
-    poolDestroy(&tempPool);
-    poolDestroy(&temp2Pool);
-    dtdDestroy(&dtd);
-    free((void *)atts);
-    free(groupConnector);
-    free(buffer);
-    free(dataBuf);
-    free(unknownEncodingMem);
-    if (unknownEncodingRelease)
-        unknownEncodingRelease(unknownEncodingData);
-    free(parser);
-}
-
-void XML_UseParserAsHandlerArg(XML_Parser parser)
-{
-    handlerArg = parser;
-}
-
-void XML_SetUserData(XML_Parser parser, void *p)
-{
-    if (handlerArg == userData)
-        handlerArg = userData = p;
-    else
-        userData = p;
-}
-
-int XML_SetBase(XML_Parser parser, const XML_Char *p)
-{
-    if (p) {
-        p = poolCopyString(&dtd.pool, p);
-        if (!p)
-            return 0;
-        dtd.base = p;
-    }
-    else
-        dtd.base = 0;
-    return 1;
-}
-
-const XML_Char *XML_GetBase(XML_Parser parser)
-{
-    return dtd.base;
-}
-
-int XML_GetSpecifiedAttributeCount(XML_Parser parser)
-{
-    return nSpecifiedAtts;
-}
-
-void XML_SetElementHandler(XML_Parser parser,
-                           XML_StartElementHandler start,
-                           XML_EndElementHandler end)
-{
-    startElementHandler = start;
-    endElementHandler = end;
-}
-
-void XML_SetCharacterDataHandler(XML_Parser parser,
-                                 XML_CharacterDataHandler handler)
-{
-    characterDataHandler = handler;
-}
-
-void XML_SetProcessingInstructionHandler(XML_Parser parser,
-        XML_ProcessingInstructionHandler handler)
-{
-    processingInstructionHandler = handler;
-}
-
-void XML_SetCommentHandler(XML_Parser parser,
-                           XML_CommentHandler handler)
-{
-    commentHandler = handler;
-}
-
-void XML_SetCdataSectionHandler(XML_Parser parser,
-                                XML_StartCdataSectionHandler start,
-                                XML_EndCdataSectionHandler end)
-{
-    startCdataSectionHandler = start;
-    endCdataSectionHandler = end;
-}
-
-void XML_SetDefaultHandler(XML_Parser parser,
-                           XML_DefaultHandler handler)
-{
-    defaultHandler = handler;
-    defaultExpandInternalEntities = 0;
-}
-
-void XML_SetDefaultHandlerExpand(XML_Parser parser,
-                                 XML_DefaultHandler handler)
-{
-    defaultHandler = handler;
-    defaultExpandInternalEntities = 1;
-}
-
-void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
-                                      XML_UnparsedEntityDeclHandler handler)
-{
-    unparsedEntityDeclHandler = handler;
-}
-
-void XML_SetNotationDeclHandler(XML_Parser parser,
-                                XML_NotationDeclHandler handler)
-{
-    notationDeclHandler = handler;
-}
-
-void XML_SetNamespaceDeclHandler(XML_Parser parser,
-                                 XML_StartNamespaceDeclHandler start,
-                                 XML_EndNamespaceDeclHandler end)
-{
-    startNamespaceDeclHandler = start;
-    endNamespaceDeclHandler = end;
-}
-
-void XML_SetNotStandaloneHandler(XML_Parser parser,
-                                 XML_NotStandaloneHandler handler)
-{
-    notStandaloneHandler = handler;
-}
-
-void XML_SetExternalEntityRefHandler(XML_Parser parser,
-                                     XML_ExternalEntityRefHandler handler)
-{
-    externalEntityRefHandler = handler;
-}
-
-void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
-{
-    if (arg)
-        externalEntityRefHandlerArg = arg;
-    else
-        externalEntityRefHandlerArg = parser;
-}
-
-void XML_SetUnknownEncodingHandler(XML_Parser parser,
-                                   XML_UnknownEncodingHandler handler,
-                                   void *data)
-{
-    unknownEncodingHandler = handler;
-    unknownEncodingHandlerData = data;
-}
-
-int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
-{
-    if (len == 0) {
-        if (!isFinal)
-            return 1;
-        positionPtr = bufferPtr;
-        errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
-        if (errorCode == XML_ERROR_NONE)
-            return 1;
-        eventEndPtr = eventPtr;
-        return 0;
-    }
-    else if (bufferPtr == bufferEnd) {
-        const char *end;
-        int nLeftOver;
-        parseEndByteIndex += len;
-        positionPtr = s;
-        if (isFinal) {
-            errorCode = processor(parser, s, parseEndPtr = s + len, 0);
-            if (errorCode == XML_ERROR_NONE)
-                return 1;
-            eventEndPtr = eventPtr;
-            return 0;
-        }
-        errorCode = processor(parser, s, parseEndPtr = s + len, &end);
-        if (errorCode != XML_ERROR_NONE) {
-            eventEndPtr = eventPtr;
-            return 0;
-        }
-        XmlUpdatePosition(encoding, positionPtr, end, &position);
-        nLeftOver = s + len - end;
-        if (nLeftOver) {
-            if (buffer == 0 || nLeftOver > bufferLim - buffer) {
-                /* FIXME avoid integer overflow */
-                buffer = buffer == 0 ? malloc(len * 2) : realloc(buffer, len * 2);
-                if (!buffer) {
-                    errorCode = XML_ERROR_NO_MEMORY;
-                    eventPtr = eventEndPtr = 0;
-                    return 0;
-                }
-                bufferLim = buffer + len * 2;
-            }
-            memcpy(buffer, end, nLeftOver);
-            bufferPtr = buffer;
-            bufferEnd = buffer + nLeftOver;
-        }
-        return 1;
-    }
-    else {
-        memcpy(XML_GetBuffer(parser, len), s, len);
-        return XML_ParseBuffer(parser, len, isFinal);
-    }
-}
-
-int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
-{
-    const char *start = bufferPtr;
-    positionPtr = start;
-    bufferEnd += len;
-    parseEndByteIndex += len;
-    errorCode = processor(parser, start, parseEndPtr = bufferEnd,
-                          isFinal ? (const char **)0 : &bufferPtr);
-    if (errorCode == XML_ERROR_NONE) {
-        if (!isFinal)
-            XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
-        return 1;
-    }
-    else {
-        eventEndPtr = eventPtr;
-        return 0;
-    }
-}
-
-void *XML_GetBuffer(XML_Parser parser, int len)
-{
-    if (len > bufferLim - bufferEnd) {
-        /* FIXME avoid integer overflow */
-        int neededSize = len + (bufferEnd - bufferPtr);
-        if (neededSize  <= bufferLim - buffer) {
-            memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
-            bufferEnd = buffer + (bufferEnd - bufferPtr);
-            bufferPtr = buffer;
-        }
-        else {
-            char *newBuf;
-            int bufferSize = bufferLim - bufferPtr;
-            if (bufferSize == 0)
-                bufferSize = INIT_BUFFER_SIZE;
-            do {
-                bufferSize *= 2;
-            } while (bufferSize < neededSize);
-            newBuf = malloc(bufferSize);
-            if (newBuf == 0) {
-                errorCode = XML_ERROR_NO_MEMORY;
-                return 0;
-            }
-            bufferLim = newBuf + bufferSize;
-            if (bufferPtr) {
-                memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
-                free(buffer);
-            }
-            bufferEnd = newBuf + (bufferEnd - bufferPtr);
-            bufferPtr = buffer = newBuf;
-        }
-    }
-    return bufferEnd;
-}
-
-enum XML_Error XML_GetErrorCode(XML_Parser parser)
-{
-    return errorCode;
-}
-
-long XML_GetCurrentByteIndex(XML_Parser parser)
-{
-    if (eventPtr)
-        return parseEndByteIndex - (parseEndPtr - eventPtr);
-    return -1;
-}
-
-int XML_GetCurrentByteCount(XML_Parser parser)
-{
-    if (eventEndPtr && eventPtr)
-        return eventEndPtr - eventPtr;
-    return 0;
-}
-
-int XML_GetCurrentLineNumber(XML_Parser parser)
-{
-    if (eventPtr) {
-        XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
-        positionPtr = eventPtr;
-    }
-    return position.lineNumber + 1;
-}
-
-int XML_GetCurrentColumnNumber(XML_Parser parser)
-{
-    if (eventPtr) {
-        XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
-        positionPtr = eventPtr;
-    }
-    return position.columnNumber;
-}
-
-void XML_DefaultCurrent(XML_Parser parser)
-{
-    if (defaultHandler) {
-        if (openInternalEntities)
-            reportDefault(parser,
-                          ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(),
-                          openInternalEntities->internalEventPtr,
-                          openInternalEntities->internalEventEndPtr);
-        else
-            reportDefault(parser, encoding, eventPtr, eventEndPtr);
-    }
-}
-
-const XML_LChar *XML_ErrorString(int code)
-{
-    static const XML_LChar *message[] = {
-        0,
-        XML_T("out of memory"),
-        XML_T("syntax error"),
-        XML_T("no element found"),
-        XML_T("not well-formed"),
-        XML_T("unclosed token"),
-        XML_T("unclosed token"),
-        XML_T("mismatched tag"),
-        XML_T("duplicate attribute"),
-        XML_T("junk after document element"),
-        XML_T("illegal parameter entity reference"),
-        XML_T("undefined entity"),
-        XML_T("recursive entity reference"),
-        XML_T("asynchronous entity"),
-        XML_T("reference to invalid character number"),
-        XML_T("reference to binary entity"),
-        XML_T("reference to external entity in attribute"),
-        XML_T("xml processing instruction not at start of external entity"),
-        XML_T("unknown encoding"),
-        XML_T("encoding specified in XML declaration is incorrect"),
-        XML_T("unclosed CDATA section"),
-        XML_T("error in processing external entity reference"),
-        XML_T("document is not standalone")
-    };
-    if (code > 0 && code < (int)(sizeof(message)/sizeof(message[0])))
-        return message[code];
-    return 0;
-}
-
-static
-enum XML_Error contentProcessor(XML_Parser parser,
-                                const char *start,
-                                const char *end,
-                                const char **endPtr)
-{
-    return doContent(parser, 0, encoding, start, end, endPtr);
-}
-
-static
-enum XML_Error externalEntityInitProcessor(XML_Parser parser,
-        const char *start,
-        const char *end,
-        const char **endPtr)
-{
-    enum XML_Error result = initializeEncoding(parser);
-    if (result != XML_ERROR_NONE)
-        return result;
-    processor = externalEntityInitProcessor2;
-    return externalEntityInitProcessor2(parser, start, end, endPtr);
-}
-
-static
-enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
-        const char *start,
-        const char *end,
-        const char **endPtr)
-{
-    const char *next;
-    int tok = XmlContentTok(encoding, start, end, &next);
-    switch (tok) {
-    case XML_TOK_BOM:
-        start = next;
-        break;
-    case XML_TOK_PARTIAL:
-        if (endPtr) {
-            *endPtr = start;
-            return XML_ERROR_NONE;
-        }
-        eventPtr = start;
-        return XML_ERROR_UNCLOSED_TOKEN;
-    case XML_TOK_PARTIAL_CHAR:
-        if (endPtr) {
-            *endPtr = start;
-            return XML_ERROR_NONE;
-        }
-        eventPtr = start;
-        return XML_ERROR_PARTIAL_CHAR;
-    }
-    processor = externalEntityInitProcessor3;
-    return externalEntityInitProcessor3(parser, start, end, endPtr);
-}
-
-static
-enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
-        const char *start,
-        const char *end,
-        const char **endPtr)
-{
-    const char *next;
-    int tok = XmlContentTok(encoding, start, end, &next);
-    switch (tok) {
-    case XML_TOK_XML_DECL:
-        {
-            enum XML_Error result = processXmlDecl(parser, 1, start, next);
-            if (result != XML_ERROR_NONE)
-                return result;
-            start = next;
-        }
-        break;
-    case XML_TOK_PARTIAL:
-        if (endPtr) {
-            *endPtr = start;
-            return XML_ERROR_NONE;
-        }
-        eventPtr = start;
-        return XML_ERROR_UNCLOSED_TOKEN;
-    case XML_TOK_PARTIAL_CHAR:
-        if (endPtr) {
-            *endPtr = start;
-            return XML_ERROR_NONE;
-        }
-        eventPtr = start;
-        return XML_ERROR_PARTIAL_CHAR;
-    }
-    processor = externalEntityContentProcessor;
-    tagLevel = 1;
-    return doContent(parser, 1, encoding, start, end, endPtr);
-}
-
-static
-enum XML_Error externalEntityContentProcessor(XML_Parser parser,
-        const char *start,
-        const char *end,
-        const char **endPtr)
-{
-    return doContent(parser, 1, encoding, start, end, endPtr);
-}
-
-static enum XML_Error
-doContent(XML_Parser parser,
-          int startTagLevel,
-          const ENCODING *enc,
-          const char *s,
-          const char *end,
-          const char **nextPtr)
-{
-    const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding();
-    const char **eventPP;
-    const char **eventEndPP;
-    if (enc == encoding) {
-        eventPP = &eventPtr;
-        eventEndPP = &eventEndPtr;
-    }
-    else {
-        eventPP = &(openInternalEntities->internalEventPtr);
-        eventEndPP = &(openInternalEntities->internalEventEndPtr);
-    }
-    *eventPP = s;
-    for (;;) {
-        const char *next = s; /* XmlContentTok doesn't always set the last arg */
-        int tok = XmlContentTok(enc, s, end, &next);
-        *eventEndPP = next;
-        switch (tok) {
-        case XML_TOK_TRAILING_CR:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            *eventEndPP = end;
-            if (characterDataHandler) {
-                XML_Char c = 0xA;
-                characterDataHandler(handlerArg, &c, 1);
-            }
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, end);
-            if (startTagLevel == 0)
-                return XML_ERROR_NO_ELEMENTS;
-            if (tagLevel != startTagLevel)
-                return XML_ERROR_ASYNC_ENTITY;
-            return XML_ERROR_NONE;
-        case XML_TOK_NONE:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            if (startTagLevel > 0) {
-                if (tagLevel != startTagLevel)
-                    return XML_ERROR_ASYNC_ENTITY;
-                return XML_ERROR_NONE;
-            }
-            return XML_ERROR_NO_ELEMENTS;
-        case XML_TOK_INVALID:
-            *eventPP = next;
-            return XML_ERROR_INVALID_TOKEN;
-        case XML_TOK_PARTIAL:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            return XML_ERROR_UNCLOSED_TOKEN;
-        case XML_TOK_PARTIAL_CHAR:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            return XML_ERROR_PARTIAL_CHAR;
-        case XML_TOK_ENTITY_REF:
-            {
-                const XML_Char *name;
-                ENTITY *entity;
-                XML_Char ch = XmlPredefinedEntityName(enc,
-                                                      s + enc->minBytesPerChar,
-                                                      next - enc->minBytesPerChar);
-                if (ch) {
-                    if (characterDataHandler)
-                        characterDataHandler(handlerArg, &ch, 1);
-                    else if (defaultHandler)
-                        reportDefault(parser, enc, s, next);
-                    break;
-                }
-                name = poolStoreString(&dtd.pool, enc,
-                                       s + enc->minBytesPerChar,
-                                       next - enc->minBytesPerChar);
-                if (!name)
-                    return XML_ERROR_NO_MEMORY;
-                entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
-                poolDiscard(&dtd.pool);
-                if (!entity) {
-                    if (dtd.complete || dtd.standalone)
-                        return XML_ERROR_UNDEFINED_ENTITY;
-                    if (defaultHandler)
-                        reportDefault(parser, enc, s, next);
-                    break;
-                }
-                if (entity->open)
-                    return XML_ERROR_RECURSIVE_ENTITY_REF;
-                if (entity->notation)
-                    return XML_ERROR_BINARY_ENTITY_REF;
-                if (entity) {
-                    if (entity->textPtr) {
-                        enum XML_Error result;
-                        OPEN_INTERNAL_ENTITY openEntity;
-                        if (defaultHandler && !defaultExpandInternalEntities) {
-                            reportDefault(parser, enc, s, next);
-                            break;
-                        }
-                        entity->open = 1;
-                        openEntity.next = openInternalEntities;
-                        openInternalEntities = &openEntity;
-                        openEntity.entity = entity;
-                        openEntity.internalEventPtr = 0;
-                        openEntity.internalEventEndPtr = 0;
-                        result = doContent(parser,
-                                           tagLevel,
-                                           internalEnc,
-                                           (char *)entity->textPtr,
-                                           (char *)(entity->textPtr + entity->textLen),
-                                           0);
-                        entity->open = 0;
-                        openInternalEntities = openEntity.next;
-                        if (result)
-                            return result;
-                    }
-                    else if (externalEntityRefHandler) {
-                        const XML_Char *context;
-                        entity->open = 1;
-                        context = getContext(parser);
-                        entity->open = 0;
-                        if (!context)
-                            return XML_ERROR_NO_MEMORY;
-                        if (!externalEntityRefHandler(externalEntityRefHandlerArg,
-                                                      context,
-                                                      dtd.base,
-                                                      entity->systemId,
-                                                      entity->publicId))
-                            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
-                        poolDiscard(&tempPool);
-                    }
-                    else if (defaultHandler)
-                        reportDefault(parser, enc, s, next);
-                }
-                break;
-            }
-        case XML_TOK_START_TAG_WITH_ATTS:
-            if (!startElementHandler) {
-                enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
-                if (result)
-                    return result;
-            }
-            /* fall through */
-        case XML_TOK_START_TAG_NO_ATTS:
-            {
-                TAG *tag;
-                if (freeTagList) {
-                    tag = freeTagList;
-                    freeTagList = freeTagList->parent;
-                }
-                else {
-                    tag = malloc(sizeof(TAG));
-                    if (!tag)
-                        return XML_ERROR_NO_MEMORY;
-                    tag->buf = malloc(INIT_TAG_BUF_SIZE);
-                    if (!tag->buf)
-                        return XML_ERROR_NO_MEMORY;
-                    tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
-                }
-                tag->bindings = 0;
-                tag->parent = tagStack;
-                tagStack = tag;
-                tag->name.localPart = 0;
-                tag->rawName = s + enc->minBytesPerChar;
-                tag->rawNameLength = XmlNameLength(enc, tag->rawName);
-                if (nextPtr) {
-                    /* Need to guarantee that:
-                       tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
-                    if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
-                        int bufSize = tag->rawNameLength * 4;
-                        bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
-                        tag->buf = realloc(tag->buf, bufSize);
-                        if (!tag->buf)
-                            return XML_ERROR_NO_MEMORY;
-                        tag->bufEnd = tag->buf + bufSize;
-                    }
-                    memcpy(tag->buf, tag->rawName, tag->rawNameLength);
-                    tag->rawName = tag->buf;
-                }
-                ++tagLevel;
-                if (startElementHandler) {
-                    enum XML_Error result;
-                    XML_Char *toPtr;
-                    for (;;) {
-                        const char *rawNameEnd = tag->rawName + tag->rawNameLength;
-                        const char *fromPtr = tag->rawName;
-                        int bufSize;
-                        if (nextPtr)
-                            toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
-                        else
-                            toPtr = (XML_Char *)tag->buf;
-                        tag->name.str = toPtr;
-                        XmlConvert(enc,
-                                   &fromPtr, rawNameEnd,
-                                   (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
-                        if (fromPtr == rawNameEnd)
-                            break;
-                        bufSize = (tag->bufEnd - tag->buf) << 1;
-                        tag->buf = realloc(tag->buf, bufSize);
-                        if (!tag->buf)
-                            return XML_ERROR_NO_MEMORY;
-                        tag->bufEnd = tag->buf + bufSize;
-                        if (nextPtr)
-                            tag->rawName = tag->buf;
-                    }
-                    *toPtr = XML_T('\0');
-                    result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
-                    if (result)
-                        return result;
-                    startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
-                    poolClear(&tempPool);
-                }
-                else {
-                    tag->name.str = 0;
-                    if (defaultHandler)
-                        reportDefault(parser, enc, s, next);
-                }
-                break;
-            }
-        case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
-            if (!startElementHandler) {
-                enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
-                if (result)
-                    return result;
-            }
-            /* fall through */
-        case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
-            if (startElementHandler || endElementHandler) {
-                const char *rawName = s + enc->minBytesPerChar;
-                enum XML_Error result;
-                BINDING *bindings = 0;
-                TAG_NAME name;
-                name.str = poolStoreString(&tempPool, enc, rawName,
-                                           rawName + XmlNameLength(enc, rawName));
-                if (!name.str)
-                    return XML_ERROR_NO_MEMORY;
-                poolFinish(&tempPool);
-                result = storeAtts(parser, enc, s, &name, &bindings);
-                if (result)
-                    return result;
-                poolFinish(&tempPool);
-                if (startElementHandler)
-                    startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
-                if (endElementHandler) {
-                    if (startElementHandler)
-                        *eventPP = *eventEndPP;
-                    endElementHandler(handlerArg, name.str);
-                }
-                poolClear(&tempPool);
-                while (bindings) {
-                    BINDING *b = bindings;
-                    if (endNamespaceDeclHandler)
-                        endNamespaceDeclHandler(handlerArg, b->prefix->name);
-                    bindings = bindings->nextTagBinding;
-                    b->nextTagBinding = freeBindingList;
-                    freeBindingList = b;
-                    b->prefix->binding = b->prevPrefixBinding;
-                }
-            }
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, next);
-            if (tagLevel == 0)
-                return epilogProcessor(parser, next, end, nextPtr);
-            break;
-        case XML_TOK_END_TAG:
-            if (tagLevel == startTagLevel)
-                return XML_ERROR_ASYNC_ENTITY;
-            else {
-                int len;
-                const char *rawName;
-                TAG *tag = tagStack;
-                tagStack = tag->parent;
-                tag->parent = freeTagList;
-                freeTagList = tag;
-                rawName = s + enc->minBytesPerChar*2;
-                len = XmlNameLength(enc, rawName);
-                if (len != tag->rawNameLength
-                        || memcmp(tag->rawName, rawName, len) != 0) {
-                    *eventPP = rawName;
-                    return XML_ERROR_TAG_MISMATCH;
-                }
-                --tagLevel;
-                if (endElementHandler && tag->name.str) {
-                    if (tag->name.localPart) {
-                        XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
-                        const XML_Char *from = tag->name.localPart;
-                        while ((*to++ = *from++) != 0)
-                            ;
-                    }
-                    endElementHandler(handlerArg, tag->name.str);
-                }
-                else if (defaultHandler)
-                    reportDefault(parser, enc, s, next);
-                while (tag->bindings) {
-                    BINDING *b = tag->bindings;
-                    if (endNamespaceDeclHandler)
-                        endNamespaceDeclHandler(handlerArg, b->prefix->name);
-                    tag->bindings = tag->bindings->nextTagBinding;
-                    b->nextTagBinding = freeBindingList;
-                    freeBindingList = b;
-                    b->prefix->binding = b->prevPrefixBinding;
-                }
-                if (tagLevel == 0)
-                    return epilogProcessor(parser, next, end, nextPtr);
-            }
-            break;
-        case XML_TOK_CHAR_REF:
-            {
-                int n = XmlCharRefNumber(enc, s);
-                if (n < 0)
-                    return XML_ERROR_BAD_CHAR_REF;
-                if (characterDataHandler) {
-                    XML_Char buf[XML_ENCODE_MAX];
-                    characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
-                }
-                else if (defaultHandler)
-                    reportDefault(parser, enc, s, next);
-            }
-            break;
-        case XML_TOK_XML_DECL:
-            return XML_ERROR_MISPLACED_XML_PI;
-        case XML_TOK_DATA_NEWLINE:
-            if (characterDataHandler) {
-                XML_Char c = 0xA;
-                characterDataHandler(handlerArg, &c, 1);
-            }
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, next);
-            break;
-        case XML_TOK_CDATA_SECT_OPEN:
-            {
-                enum XML_Error result;
-                if (startCdataSectionHandler)
-                    startCdataSectionHandler(handlerArg);
-#if 0
-                /* Suppose you doing a transformation on a document that involves
-                   changing only the character data.  You set up a defaultHandler
-                   and a characterDataHandler.  The defaultHandler simply copies
-                   characters through.  The characterDataHandler does the transformation
-                   and writes the characters out escaping them as necessary.  This case
-                   will fail to work if we leave out the following two lines (because &
-                   and < inside CDATA sections will be incorrectly escaped).
-
-                   However, now we have a start/endCdataSectionHandler, so it seems
-                   easier to let the user deal with this. */
-
-                else if (characterDataHandler)
-                    characterDataHandler(handlerArg, dataBuf, 0);
-#endif
-                else if (defaultHandler)
-                    reportDefault(parser, enc, s, next);
-                result = doCdataSection(parser, enc, &next, end, nextPtr);
-                if (!next) {
-                    processor = cdataSectionProcessor;
-                    return result;
-                }
-            }
-            break;
-        case XML_TOK_TRAILING_RSQB:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            if (characterDataHandler) {
-                if (MUST_CONVERT(enc, s)) {
-                    ICHAR *dataPtr = (ICHAR *)dataBuf;
-                    XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
-                    characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
-                }
-                else
-                    characterDataHandler(handlerArg,
-                                         (XML_Char *)s,
-                                         (XML_Char *)end - (XML_Char *)s);
-            }
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, end);
-            if (startTagLevel == 0) {
-                *eventPP = end;
-                return XML_ERROR_NO_ELEMENTS;
-            }
-            if (tagLevel != startTagLevel) {
-                *eventPP = end;
-                return XML_ERROR_ASYNC_ENTITY;
-            }
-            return XML_ERROR_NONE;
-        case XML_TOK_DATA_CHARS:
-            if (characterDataHandler) {
-                if (MUST_CONVERT(enc, s)) {
-                    for (;;) {
-                        ICHAR *dataPtr = (ICHAR *)dataBuf;
-                        XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
-                        *eventEndPP = s;
-                        characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
-                        if (s == next)
-                            break;
-                        *eventPP = s;
-                    }
-                }
-                else
-                    characterDataHandler(handlerArg,
-                                         (XML_Char *)s,
-                                         (XML_Char *)next - (XML_Char *)s);
-            }
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, next);
-            break;
-        case XML_TOK_PI:
-            if (!reportProcessingInstruction(parser, enc, s, next))
-                return XML_ERROR_NO_MEMORY;
-            break;
-        case XML_TOK_COMMENT:
-            if (!reportComment(parser, enc, s, next))
-                return XML_ERROR_NO_MEMORY;
-            break;
-        default:
-            if (defaultHandler)
-                reportDefault(parser, enc, s, next);
-            break;
-        }
-        *eventPP = s = next;
-    }
-    /* not reached */
-}
-
-/* If tagNamePtr is non-null, build a real list of attributes,
-otherwise just check the attributes for well-formedness. */
-
-static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
-                                const char *s, TAG_NAME *tagNamePtr,
-                                BINDING **bindingsPtr)
-{
-    ELEMENT_TYPE *elementType = 0;
-    int nDefaultAtts = 0;
-    const XML_Char **appAtts;
-    int attIndex = 0;
-    int i;
-    int n;
-    int nPrefixes = 0;
-    BINDING *binding;
-    const XML_Char *localPart;
-
-    if (tagNamePtr) {
-        elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, 0);
-        if (!elementType) {
-            tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
-            if (!tagNamePtr->str)
-                return XML_ERROR_NO_MEMORY;
-            elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
-            if (!elementType)
-                return XML_ERROR_NO_MEMORY;
-            if (ns && !setElementTypePrefix(parser, elementType))
-                return XML_ERROR_NO_MEMORY;
-        }
-        nDefaultAtts = elementType->nDefaultAtts;
-    }
-    n = XmlGetAttributes(enc, s, attsSize, atts);
-    if (n + nDefaultAtts > attsSize) {
-        int oldAttsSize = attsSize;
-        attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
-        atts = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE));
-        if (!atts)
-            return XML_ERROR_NO_MEMORY;
-        if (n > oldAttsSize)
-            XmlGetAttributes(enc, s, n, atts);
-    }
-    appAtts = (const XML_Char **)atts;
-    for (i = 0; i < n; i++) {
-        ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
-                                             atts[i].name
-                                             + XmlNameLength(enc, atts[i].name));
-        if (!attId)
-            return XML_ERROR_NO_MEMORY;
-        if ((attId->name)[-1]) {
-            if (enc == encoding)
-                eventPtr = atts[i].name;
-            return XML_ERROR_DUPLICATE_ATTRIBUTE;
-        }
-        (attId->name)[-1] = 1;
-        appAtts[attIndex++] = attId->name;
-        if (!atts[i].normalized) {
-            enum XML_Error result;
-            int isCdata = 1;
-
-            if (attId->maybeTokenized) {
-                int j;
-                for (j = 0; j < nDefaultAtts; j++) {
-                    if (attId == elementType->defaultAtts[j].id) {
-                        isCdata = elementType->defaultAtts[j].isCdata;
-                        break;
-                    }
-                }
-            }
-
-            result = storeAttributeValue(parser, enc, isCdata,
-                                         atts[i].valuePtr, atts[i].valueEnd,
-                                         &tempPool);
-            if (result)
-                return result;
-            if (tagNamePtr) {
-                appAtts[attIndex] = poolStart(&tempPool);
-                poolFinish(&tempPool);
-            }
-            else
-                poolDiscard(&tempPool);
-        }
-        else if (tagNamePtr) {
-            appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
-            if (appAtts[attIndex] == 0)
-                return XML_ERROR_NO_MEMORY;
-            poolFinish(&tempPool);
-        }
-        if (attId->prefix && tagNamePtr) {
-            if (attId->xmlns) {
-                if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
-                    return XML_ERROR_NO_MEMORY;
-                --attIndex;
-            }
-            else {
-                attIndex++;
-                nPrefixes++;
-                (attId->name)[-1] = 2;
-            }
-        }
-        else
-            attIndex++;
-    }
-    nSpecifiedAtts = attIndex;
-    if (tagNamePtr) {
-        int j;
-        for (j = 0; j < nDefaultAtts; j++) {
-            const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
-            if (!(da->id->name)[-1] && da->value) {
-                if (da->id->prefix) {
-                    if (da->id->xmlns) {
-                        if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
-                            return XML_ERROR_NO_MEMORY;
-                    }
-                    else {
-                        (da->id->name)[-1] = 2;
-                        nPrefixes++;
-                        appAtts[attIndex++] = da->id->name;
-                        appAtts[attIndex++] = da->value;
-                    }
-                }
-                else {
-                    (da->id->name)[-1] = 1;
-                    appAtts[attIndex++] = da->id->name;
-                    appAtts[attIndex++] = da->value;
-                }
-            }
-        }
-        appAtts[attIndex] = 0;
-    }
-    i = 0;
-    if (nPrefixes) {
-        for (; i < attIndex; i += 2) {
-            if (appAtts[i][-1] == 2) {
-                ATTRIBUTE_ID *id;
-                ((XML_Char *)(appAtts[i]))[-1] = 0;
-                id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
-                if (id->prefix->binding) {
-                    int j;
-                    const BINDING *b = id->prefix->binding;
-                    const XML_Char *s = appAtts[i];
-                    for (j = 0; j < b->uriLen; j++) {
-                        if (!poolAppendChar(&tempPool, b->uri[j]))
-                            return XML_ERROR_NO_MEMORY;
-                    }
-                    while (*s++ != ':')
-                        ;
-                    do {
-                        if (!poolAppendChar(&tempPool, *s))
-                            return XML_ERROR_NO_MEMORY;
-                    } while (*s++);
-                    appAtts[i] = poolStart(&tempPool);
-                    poolFinish(&tempPool);
-                }
-                if (!--nPrefixes)
-                    break;
-            }
-            else
-                ((XML_Char *)(appAtts[i]))[-1] = 0;
-        }
-    }
-    for (; i < attIndex; i += 2)
-        ((XML_Char *)(appAtts[i]))[-1] = 0;
-    if (!tagNamePtr)
-        return XML_ERROR_NONE;
-    for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
-        binding->attId->name[-1] = 0;
-    if (elementType->prefix) {
-        binding = elementType->prefix->binding;
-        if (!binding)
-            return XML_ERROR_NONE;
-        localPart = tagNamePtr->str;
-        while (*localPart++ != XML_T(':'))
-            ;
-    }
-    else if (dtd.defaultPrefix.binding) {
-        binding = dtd.defaultPrefix.binding;
-        localPart = tagNamePtr->str;
-    }
-    else
-        return XML_ERROR_NONE;
-    tagNamePtr->localPart = localPart;
-    tagNamePtr->uriLen = binding->uriLen;
-    i = binding->uriLen;
-    do {
-        if (i == binding->uriAlloc) {
-            binding->uri = realloc(binding->uri, binding->uriAlloc *= 2);
-            if (!binding->uri)
-                return XML_ERROR_NO_MEMORY;
-        }
-        binding->uri[i++] = *localPart;
-    } while (*localPart++);
-    tagNamePtr->str = binding->uri;
-    return XML_ERROR_NONE;
-}
-
-static
-int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
-{
-    BINDING *b;
-    int len;
-    for (len = 0; uri[len]; len++)
-        ;
-    if (namespaceSeparator)
-        len++;
-    if (freeBindingList) {
-        b = freeBindingList;
-        if (len > b->uriAlloc) {
-            b->uri = realloc(b->uri, len + EXPAND_SPARE);
-            if (!b->uri)
-                return 0;
-            b->uriAlloc = len + EXPAND_SPARE;
-        }
-        freeBindingList = b->nextTagBinding;
-    }
-    else {
-        b = malloc(sizeof(BINDING));
-        if (!b)
-            return 0;
-        b->uri = malloc(sizeof(XML_Char) * len + EXPAND_SPARE);
-        if (!b->uri) {
-            free(b);
-            return 0;
-        }
-        b->uriAlloc = len;
-    }
-    b->uriLen = len;
-    memcpy(b->uri, uri, len * sizeof(XML_Char));
-    if (namespaceSeparator)
-        b->uri[len - 1] = namespaceSeparator;
-    b->prefix = prefix;
-    b->attId = attId;
-    b->prevPrefixBinding = prefix->binding;
-    if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
-        prefix->binding = 0;
-    else
-        prefix->binding = b;
-    b->nextTagBinding = *bindingsPtr;
-    *bindingsPtr = b;
-    if (startNamespaceDeclHandler)
-        startNamespaceDeclHandler(handlerArg, prefix->name,
-                                  prefix->binding ? uri : 0);
-    return 1;
-}
-
-/* The idea here is to avoid using stack for each CDATA section when
-the whole file is parsed with one call. */
-
-static
-enum XML_Error cdataSectionProcessor(XML_Parser parser,
-                                     const char *start,
-                                     const char *end,
-                                     const char **endPtr)
-{
-    enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
-    if (start) {
-        processor = contentProcessor;
-        return contentProcessor(parser, start, end, endPtr);
-    }
-    return result;
-}
-
-/* startPtr gets set to non-null is the section is closed, and to null if
-the section is not yet closed. */
-
-static
-enum XML_Error doCdataSection(XML_Parser parser,
-                              const ENCODING *enc,
-                              const char **startPtr,
-                              const char *end,
-                              const char **nextPtr)
-{
-    const char *s = *startPtr;
-    const char **eventPP;
-    const char **eventEndPP;
-    if (enc == encoding) {
-        eventPP = &eventPtr;
-        *eventPP = s;
-        eventEndPP = &eventEndPtr;
-    }
-    else {
-        eventPP = &(openInternalEntities->internalEventPtr);
-        eventEndPP = &(openInternalEntities->internalEventEndPtr);
-    }
-    *eventPP = s;
-    *startPtr = 0;
-    for (;;) {
-        const char *next;
-        int tok = XmlCdataSectionTok(enc, s, end, &next);
-        *eventEndPP = next;
-        switch (tok) {
-        case XML_TOK_CDATA_SECT_CLOSE:
-            if (endCdataSectionHandler)
-                endCdataSectionHandler(handlerArg);
-#if 0
-            /* see comment under XML_TOK_CDATA_SECT_OPEN */
-            else if (characterDataHandler)
-                characterDataHandler(handlerArg, dataBuf, 0);
-#endif
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, next);
-            *startPtr = next;
-            return XML_ERROR_NONE;
-        case XML_TOK_DATA_NEWLINE:
-            if (characterDataHandler) {
-                XML_Char c = 0xA;
-                characterDataHandler(handlerArg, &c, 1);
-            }
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, next);
-            break;
-        case XML_TOK_DATA_CHARS:
-            if (characterDataHandler) {
-                if (MUST_CONVERT(enc, s)) {
-                    for (;;) {
-                        ICHAR *dataPtr = (ICHAR *)dataBuf;
-                        XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
-                        *eventEndPP = next;
-                        characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
-                        if (s == next)
-                            break;
-                        *eventPP = s;
-                    }
-                }
-                else
-                    characterDataHandler(handlerArg,
-                                         (XML_Char *)s,
-                                         (XML_Char *)next - (XML_Char *)s);
-            }
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, next);
-            break;
-        case XML_TOK_INVALID:
-            *eventPP = next;
-            return XML_ERROR_INVALID_TOKEN;
-        case XML_TOK_PARTIAL_CHAR:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            return XML_ERROR_PARTIAL_CHAR;
-        case XML_TOK_PARTIAL:
-        case XML_TOK_NONE:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            return XML_ERROR_UNCLOSED_CDATA_SECTION;
-        default:
-            abort();
-        }
-        *eventPP = s = next;
-    }
-    /* not reached */
-}
-
-static enum XML_Error
-initializeEncoding(XML_Parser parser)
-{
-    const char *s;
-#ifdef XML_UNICODE
-    char encodingBuf[128];
-    if (!protocolEncodingName)
-        s = 0;
-    else {
-        int i;
-        for (i = 0; protocolEncodingName[i]; i++) {
-            if (i == sizeof(encodingBuf) - 1
-                    || protocolEncodingName[i] >= 0x80
-                    || protocolEncodingName[i] < 0) {
-                encodingBuf[0] = '\0';
-                break;
-            }
-            encodingBuf[i] = (char)protocolEncodingName[i];
-        }
-        encodingBuf[i] = '\0';
-        s = encodingBuf;
-    }
-#else
-s = protocolEncodingName;
-#endif
-    if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
-        return XML_ERROR_NONE;
-    return handleUnknownEncoding(parser, protocolEncodingName);
-}
-
-static enum XML_Error
-processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
-               const char *s, const char *next)
-{
-    const char *encodingName = 0;
-    const ENCODING *newEncoding = 0;
-    const char *version;
-    int standalone = -1;
-    if (!(ns
-            ? XmlParseXmlDeclNS
-            : XmlParseXmlDecl)(isGeneralTextEntity,
-                               encoding,
-                               s,
-                               next,
-                               &eventPtr,
-                               &version,
-                               &encodingName,
-                               &newEncoding,
-                               &standalone))
-        return XML_ERROR_SYNTAX;
-    if (!isGeneralTextEntity && standalone == 1)
-        dtd.standalone = 1;
-    if (defaultHandler)
-        reportDefault(parser, encoding, s, next);
-    if (!protocolEncodingName) {
-        if (newEncoding) {
-            if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
-                eventPtr = encodingName;
-                return XML_ERROR_INCORRECT_ENCODING;
-            }
-            encoding = newEncoding;
-        }
-        else if (encodingName) {
-            enum XML_Error result;
-            const XML_Char *s = poolStoreString(&tempPool,
-                                                encoding,
-                                                encodingName,
-                                                encodingName
-                                                + XmlNameLength(encoding, encodingName));
-            if (!s)
-                return XML_ERROR_NO_MEMORY;
-            result = handleUnknownEncoding(parser, s);
-            poolDiscard(&tempPool);
-            if (result == XML_ERROR_UNKNOWN_ENCODING)
-                eventPtr = encodingName;
-            return result;
-        }
-    }
-    return XML_ERROR_NONE;
-}
-
-static enum XML_Error
-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
-{
-    if (unknownEncodingHandler) {
-        XML_Encoding info;
-        int i;
-        for (i = 0; i < 256; i++)
-            info.map[i] = -1;
-        info.convert = 0;
-        info.data = 0;
-        info.release = 0;
-        if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
-            ENCODING *enc;
-            unknownEncodingMem = malloc(XmlSizeOfUnknownEncoding());
-            if (!unknownEncodingMem) {
-                if (info.release)
-                    info.release(info.data);
-                return XML_ERROR_NO_MEMORY;
-            }
-            enc = (ns
-                   ? XmlInitUnknownEncodingNS
-                   : XmlInitUnknownEncoding)(unknownEncodingMem,
-                                             info.map,
-                                             info.convert,
-                                             info.data);
-            if (enc) {
-                unknownEncodingData = info.data;
-                unknownEncodingRelease = info.release;
-                encoding = enc;
-                return XML_ERROR_NONE;
-            }
-        }
-        if (info.release)
-            info.release(info.data);
-    }
-    return XML_ERROR_UNKNOWN_ENCODING;
-}
-
-static enum XML_Error
-prologInitProcessor(XML_Parser parser,
-                    const char *s,
-                    const char *end,
-                    const char **nextPtr)
-{
-    enum XML_Error result = initializeEncoding(parser);
-    if (result != XML_ERROR_NONE)
-        return result;
-    processor = prologProcessor;
-    return prologProcessor(parser, s, end, nextPtr);
-}
-
-static enum XML_Error
-prologProcessor(XML_Parser parser,
-                const char *s,
-                const char *end,
-                const char **nextPtr)
-{
-    for (;;) {
-        const char *next;
-        int tok = XmlPrologTok(encoding, s, end, &next);
-        if (tok <= 0) {
-            if (nextPtr != 0 && tok != XML_TOK_INVALID) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            switch (tok) {
-            case XML_TOK_INVALID:
-                eventPtr = next;
-                return XML_ERROR_INVALID_TOKEN;
-            case XML_TOK_NONE:
-                return XML_ERROR_NO_ELEMENTS;
-            case XML_TOK_PARTIAL:
-                return XML_ERROR_UNCLOSED_TOKEN;
-            case XML_TOK_PARTIAL_CHAR:
-                return XML_ERROR_PARTIAL_CHAR;
-            case XML_TOK_TRAILING_CR:
-                eventPtr = s + encoding->minBytesPerChar;
-                return XML_ERROR_NO_ELEMENTS;
-            default:
-                abort();
-            }
-        }
-        switch (XmlTokenRole(&prologState, tok, s, next, encoding)) {
-        case XML_ROLE_XML_DECL:
-            {
-                enum XML_Error result = processXmlDecl(parser, 0, s, next);
-                if (result != XML_ERROR_NONE)
-                    return result;
-            }
-            break;
-        case XML_ROLE_DOCTYPE_SYSTEM_ID:
-            if (!dtd.standalone
-                    && notStandaloneHandler
-                    && !notStandaloneHandler(handlerArg))
-                return XML_ERROR_NOT_STANDALONE;
-            hadExternalDoctype = 1;
-            break;
-        case XML_ROLE_DOCTYPE_PUBLIC_ID:
-        case XML_ROLE_ENTITY_PUBLIC_ID:
-            if (!XmlIsPublicId(encoding, s, next, &eventPtr))
-                return XML_ERROR_SYNTAX;
-            if (declEntity) {
-                XML_Char *tem = poolStoreString(&dtd.pool,
-                                                encoding,
-                                                s + encoding->minBytesPerChar,
-                                                next - encoding->minBytesPerChar);
-                if (!tem)
-                    return XML_ERROR_NO_MEMORY;
-                normalizePublicId(tem);
-                declEntity->publicId = tem;
-                poolFinish(&dtd.pool);
-            }
-            break;
-        case XML_ROLE_INSTANCE_START:
-            processor = contentProcessor;
-            if (hadExternalDoctype)
-                dtd.complete = 0;
-            return contentProcessor(parser, s, end, nextPtr);
-        case XML_ROLE_ATTLIST_ELEMENT_NAME:
-            {
-                const XML_Char *name = poolStoreString(&dtd.pool, encoding, s, next);
-                if (!name)
-                    return XML_ERROR_NO_MEMORY;
-                declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
-                if (!declElementType)
-                    return XML_ERROR_NO_MEMORY;
-                if (declElementType->name != name)
-                    poolDiscard(&dtd.pool);
-                else {
-                    poolFinish(&dtd.pool);
-                    if (!setElementTypePrefix(parser, declElementType))
-                        return XML_ERROR_NO_MEMORY;
-                }
-                break;
-            }
-        case XML_ROLE_ATTRIBUTE_NAME:
-            declAttributeId = getAttributeId(parser, encoding, s, next);
-            if (!declAttributeId)
-                return XML_ERROR_NO_MEMORY;
-            declAttributeIsCdata = 0;
-            break;
-        case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
-            declAttributeIsCdata = 1;
-            break;
-        case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
-        case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
-            if (dtd.complete
-                    && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0))
-                return XML_ERROR_NO_MEMORY;
-            break;
-        case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
-        case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
-            {
-                const XML_Char *attVal;
-                enum XML_Error result
-                = storeAttributeValue(parser, encoding, declAttributeIsCdata,
-                                      s + encoding->minBytesPerChar,
-                                      next - encoding->minBytesPerChar,
-                                      &dtd.pool);
-                if (result)
-                    return result;
-                attVal = poolStart(&dtd.pool);
-                poolFinish(&dtd.pool);
-                if (dtd.complete
-                        && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, attVal))
-                    return XML_ERROR_NO_MEMORY;
-                break;
-            }
-        case XML_ROLE_ENTITY_VALUE:
-            {
-                enum XML_Error result = storeEntityValue(parser, s, next);
-                if (result != XML_ERROR_NONE)
-                    return result;
-            }
-            break;
-        case XML_ROLE_ENTITY_SYSTEM_ID:
-            if (declEntity) {
-                declEntity->systemId = poolStoreString(&dtd.pool, encoding,
-                                                       s + encoding->minBytesPerChar,
-                                                       next - encoding->minBytesPerChar);
-                if (!declEntity->systemId)
-                    return XML_ERROR_NO_MEMORY;
-                declEntity->base = dtd.base;
-                poolFinish(&dtd.pool);
-            }
-            break;
-        case XML_ROLE_ENTITY_NOTATION_NAME:
-            if (declEntity) {
-                declEntity->notation = poolStoreString(&dtd.pool, encoding, s, next);
-                if (!declEntity->notation)
-                    return XML_ERROR_NO_MEMORY;
-                poolFinish(&dtd.pool);
-                if (unparsedEntityDeclHandler) {
-                    eventPtr = eventEndPtr = s;
-                    unparsedEntityDeclHandler(handlerArg,
-                                              declEntity->name,
-                                              declEntity->base,
-                                              declEntity->systemId,
-                                              declEntity->publicId,
-                                              declEntity->notation);
-                }
-
-            }
-            break;
-        case XML_ROLE_GENERAL_ENTITY_NAME:
-            {
-                const XML_Char *name;
-                if (XmlPredefinedEntityName(encoding, s, next)) {
-                    declEntity = 0;
-                    break;
-                }
-                name = poolStoreString(&dtd.pool, encoding, s, next);
-                if (!name)
-                    return XML_ERROR_NO_MEMORY;
-                if (dtd.complete) {
-                    declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
-                    if (!declEntity)
-                        return XML_ERROR_NO_MEMORY;
-                    if (declEntity->name != name) {
-                        poolDiscard(&dtd.pool);
-                        declEntity = 0;
-                    }
-                    else
-                        poolFinish(&dtd.pool);
-                }
-                else {
-                    poolDiscard(&dtd.pool);
-                    declEntity = 0;
-                }
-            }
-            break;
-        case XML_ROLE_PARAM_ENTITY_NAME:
-            declEntity = 0;
-            break;
-        case XML_ROLE_NOTATION_NAME:
-            declNotationPublicId = 0;
-            declNotationName = 0;
-            if (notationDeclHandler) {
-                declNotationName = poolStoreString(&tempPool, encoding, s, next);
-                if (!declNotationName)
-                    return XML_ERROR_NO_MEMORY;
-                poolFinish(&tempPool);
-            }
-            break;
-        case XML_ROLE_NOTATION_PUBLIC_ID:
-            if (!XmlIsPublicId(encoding, s, next, &eventPtr))
-                return XML_ERROR_SYNTAX;
-            if (declNotationName) {
-                XML_Char *tem = poolStoreString(&tempPool,
-                                                encoding,
-                                                s + encoding->minBytesPerChar,
-                                                next - encoding->minBytesPerChar);
-                if (!tem)
-                    return XML_ERROR_NO_MEMORY;
-                normalizePublicId(tem);
-                declNotationPublicId = tem;
-                poolFinish(&tempPool);
-            }
-            break;
-        case XML_ROLE_NOTATION_SYSTEM_ID:
-            if (declNotationName && notationDeclHandler) {
-                const XML_Char *systemId
-                = poolStoreString(&tempPool, encoding,
-                                  s + encoding->minBytesPerChar,
-                                  next - encoding->minBytesPerChar);
-                if (!systemId)
-                    return XML_ERROR_NO_MEMORY;
-                eventPtr = eventEndPtr = s;
-                notationDeclHandler(handlerArg,
-                                    declNotationName,
-                                    dtd.base,
-                                    systemId,
-                                    declNotationPublicId);
-            }
-            poolClear(&tempPool);
-            break;
-        case XML_ROLE_NOTATION_NO_SYSTEM_ID:
-            if (declNotationPublicId && notationDeclHandler) {
-                eventPtr = eventEndPtr = s;
-                notationDeclHandler(handlerArg,
-                                    declNotationName,
-                                    dtd.base,
-                                    0,
-                                    declNotationPublicId);
-            }
-            poolClear(&tempPool);
-            break;
-        case XML_ROLE_ERROR:
-            eventPtr = s;
-            switch (tok) {
-            case XML_TOK_PARAM_ENTITY_REF:
-                return XML_ERROR_PARAM_ENTITY_REF;
-            case XML_TOK_XML_DECL:
-                return XML_ERROR_MISPLACED_XML_PI;
-            default:
-                return XML_ERROR_SYNTAX;
-            }
-        case XML_ROLE_GROUP_OPEN:
-            if (prologState.level >= groupSize) {
-                if (groupSize)
-                    groupConnector = realloc(groupConnector, groupSize *= 2);
-                else
-                    groupConnector = malloc(groupSize = 32);
-                if (!groupConnector)
-                    return XML_ERROR_NO_MEMORY;
-            }
-            groupConnector[prologState.level] = 0;
-            break;
-        case XML_ROLE_GROUP_SEQUENCE:
-            if (groupConnector[prologState.level] == '|') {
-                eventPtr = s;
-                return XML_ERROR_SYNTAX;
-            }
-            groupConnector[prologState.level] = ',';
-            break;
-        case XML_ROLE_GROUP_CHOICE:
-            if (groupConnector[prologState.level] == ',') {
-                eventPtr = s;
-                return XML_ERROR_SYNTAX;
-            }
-            groupConnector[prologState.level] = '|';
-            break;
-        case XML_ROLE_PARAM_ENTITY_REF:
-            if (!dtd.standalone
-                    && notStandaloneHandler
-                    && !notStandaloneHandler(handlerArg))
-                return XML_ERROR_NOT_STANDALONE;
-            dtd.complete = 0;
-            break;
-        case XML_ROLE_NONE:
-            switch (tok) {
-            case XML_TOK_PI:
-                eventPtr = s;
-                eventEndPtr = next;
-                if (!reportProcessingInstruction(parser, encoding, s, next))
-                    return XML_ERROR_NO_MEMORY;
-                break;
-            case XML_TOK_COMMENT:
-                eventPtr = s;
-                eventEndPtr = next;
-                if (!reportComment(parser, encoding, s, next))
-                    return XML_ERROR_NO_MEMORY;
-                break;
-            }
-            break;
-        }
-        if (defaultHandler) {
-            switch (tok) {
-            case XML_TOK_PI:
-            case XML_TOK_COMMENT:
-            case XML_TOK_BOM:
-            case XML_TOK_XML_DECL:
-                break;
-            default:
-                eventPtr = s;
-                eventEndPtr = next;
-                reportDefault(parser, encoding, s, next);
-            }
-        }
-        s = next;
-    }
-    /* not reached */
-}
-
-static
-enum XML_Error epilogProcessor(XML_Parser parser,
-                               const char *s,
-                               const char *end,
-                               const char **nextPtr)
-{
-    processor = epilogProcessor;
-    eventPtr = s;
-    for (;;) {
-        const char *next;
-        int tok = XmlPrologTok(encoding, s, end, &next);
-        eventEndPtr = next;
-        switch (tok) {
-        case XML_TOK_TRAILING_CR:
-            if (defaultHandler) {
-                eventEndPtr = end;
-                reportDefault(parser, encoding, s, end);
-            }
-            /* fall through */
-        case XML_TOK_NONE:
-            if (nextPtr)
-                *nextPtr = end;
-            return XML_ERROR_NONE;
-        case XML_TOK_PROLOG_S:
-            if (defaultHandler)
-                reportDefault(parser, encoding, s, next);
-            break;
-        case XML_TOK_PI:
-            if (!reportProcessingInstruction(parser, encoding, s, next))
-                return XML_ERROR_NO_MEMORY;
-            break;
-        case XML_TOK_COMMENT:
-            if (!reportComment(parser, encoding, s, next))
-                return XML_ERROR_NO_MEMORY;
-            break;
-        case XML_TOK_INVALID:
-            eventPtr = next;
-            return XML_ERROR_INVALID_TOKEN;
-        case XML_TOK_PARTIAL:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            return XML_ERROR_UNCLOSED_TOKEN;
-        case XML_TOK_PARTIAL_CHAR:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            return XML_ERROR_PARTIAL_CHAR;
-        default:
-            return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
-        }
-        eventPtr = s = next;
-    }
-}
-
-/*
-static
-enum XML_Error errorProcessor(XML_Parser parser,
-                              const char *s,
-                              const char *end,
-                              const char **nextPtr)
-{
-    return errorCode;
-}
-*/
-
-static enum XML_Error
-storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
-                    const char *ptr, const char *end,
-                    STRING_POOL *pool)
-{
-    enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
-    if (result)
-        return result;
-    if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
-        poolChop(pool);
-    if (!poolAppendChar(pool, XML_T('\0')))
-        return XML_ERROR_NO_MEMORY;
-    return XML_ERROR_NONE;
-}
-
-static enum XML_Error
-appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
-                     const char *ptr, const char *end,
-                     STRING_POOL *pool)
-{
-    const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding();
-    for (;;) {
-        const char *next;
-        int tok = XmlAttributeValueTok(enc, ptr, end, &next);
-        switch (tok) {
-        case XML_TOK_NONE:
-            return XML_ERROR_NONE;
-        case XML_TOK_INVALID:
-            if (enc == encoding)
-                eventPtr = next;
-            return XML_ERROR_INVALID_TOKEN;
-        case XML_TOK_PARTIAL:
-            if (enc == encoding)
-                eventPtr = ptr;
-            return XML_ERROR_INVALID_TOKEN;
-        case XML_TOK_CHAR_REF:
-            {
-                XML_Char buf[XML_ENCODE_MAX];
-                int i;
-                int n = XmlCharRefNumber(enc, ptr);
-                if (n < 0) {
-                    if (enc == encoding)
-                        eventPtr = ptr;
-                    return XML_ERROR_BAD_CHAR_REF;
-                }
-                if (!isCdata
-                        && n == 0x20 /* space */
-                        && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
-                    break;
-                n = XmlEncode(n, (ICHAR *)buf);
-                if (!n) {
-                    if (enc == encoding)
-                        eventPtr = ptr;
-                    return XML_ERROR_BAD_CHAR_REF;
-                }
-                for (i = 0; i < n; i++) {
-                    if (!poolAppendChar(pool, buf[i]))
-                        return XML_ERROR_NO_MEMORY;
-                }
-            }
-            break;
-        case XML_TOK_DATA_CHARS:
-            if (!poolAppend(pool, enc, ptr, next))
-                return XML_ERROR_NO_MEMORY;
-            break;
-            break;
-        case XML_TOK_TRAILING_CR:
-            next = ptr + enc->minBytesPerChar;
-            /* fall through */
-        case XML_TOK_ATTRIBUTE_VALUE_S:
-        case XML_TOK_DATA_NEWLINE:
-            if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
-                break;
-            if (!poolAppendChar(pool, 0x20))
-                return XML_ERROR_NO_MEMORY;
-            break;
-        case XML_TOK_ENTITY_REF:
-            {
-                const XML_Char *name;
-                ENTITY *entity;
-                XML_Char ch = XmlPredefinedEntityName(enc,
-                                                      ptr + enc->minBytesPerChar,
-                                                      next - enc->minBytesPerChar);
-                if (ch) {
-                    if (!poolAppendChar(pool, ch))
-                        return XML_ERROR_NO_MEMORY;
-                    break;
-                }
-                name = poolStoreString(&temp2Pool, enc,
-                                       ptr + enc->minBytesPerChar,
-                                       next - enc->minBytesPerChar);
-                if (!name)
-                    return XML_ERROR_NO_MEMORY;
-                entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
-                poolDiscard(&temp2Pool);
-                if (!entity) {
-                    if (dtd.complete) {
-                        if (enc == encoding)
-                            eventPtr = ptr;
-                        return XML_ERROR_UNDEFINED_ENTITY;
-                    }
-                }
-                else if (entity->open) {
-                    if (enc == encoding)
-                        eventPtr = ptr;
-                    return XML_ERROR_RECURSIVE_ENTITY_REF;
-                }
-                else if (entity->notation) {
-                    if (enc == encoding)
-                        eventPtr = ptr;
-                    return XML_ERROR_BINARY_ENTITY_REF;
-                }
-                else if (!entity->textPtr) {
-                    if (enc == encoding)
-                        eventPtr = ptr;
-                    return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
-                }
-                else {
-                    enum XML_Error result;
-                    const XML_Char *textEnd = entity->textPtr + entity->textLen;
-                    entity->open = 1;
-                    result = appendAttributeValue(parser, internalEnc, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
-                    entity->open = 0;
-                    if (result)
-                        return result;
-                }
-            }
-            break;
-        default:
-            abort();
-        }
-        ptr = next;
-    }
-    /* not reached */
-}
-
-static
-enum XML_Error storeEntityValue(XML_Parser parser,
-                                const char *entityTextPtr,
-                                const char *entityTextEnd)
-{
-    /* const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(); */
-    STRING_POOL *pool = &(dtd.pool);
-    entityTextPtr += encoding->minBytesPerChar;
-    entityTextEnd -= encoding->minBytesPerChar;
-    for (;;) {
-        const char *next;
-        int tok = XmlEntityValueTok(encoding, entityTextPtr, entityTextEnd, &next);
-        switch (tok) {
-        case XML_TOK_PARAM_ENTITY_REF:
-            eventPtr = entityTextPtr;
-            return XML_ERROR_SYNTAX;
-        case XML_TOK_NONE:
-            if (declEntity) {
-                declEntity->textPtr = pool->start;
-                declEntity->textLen = pool->ptr - pool->start;
-                poolFinish(pool);
-            }
-            else
-                poolDiscard(pool);
-            return XML_ERROR_NONE;
-        case XML_TOK_ENTITY_REF:
-        case XML_TOK_DATA_CHARS:
-            if (!poolAppend(pool, encoding, entityTextPtr, next))
-                return XML_ERROR_NO_MEMORY;
-            break;
-        case XML_TOK_TRAILING_CR:
-            next = entityTextPtr + encoding->minBytesPerChar;
-            /* fall through */
-        case XML_TOK_DATA_NEWLINE:
-            if (pool->end == pool->ptr && !poolGrow(pool))
-                return XML_ERROR_NO_MEMORY;
-            *(pool->ptr)++ = 0xA;
-            break;
-        case XML_TOK_CHAR_REF:
-            {
-                XML_Char buf[XML_ENCODE_MAX];
-                int i;
-                int n = XmlCharRefNumber(encoding, entityTextPtr);
-                if (n < 0) {
-                    eventPtr = entityTextPtr;
-                    return XML_ERROR_BAD_CHAR_REF;
-                }
-                n = XmlEncode(n, (ICHAR *)buf);
-                if (!n) {
-                    eventPtr = entityTextPtr;
-                    return XML_ERROR_BAD_CHAR_REF;
-                }
-                for (i = 0; i < n; i++) {
-                    if (pool->end == pool->ptr && !poolGrow(pool))
-                        return XML_ERROR_NO_MEMORY;
-                    *(pool->ptr)++ = buf[i];
-                }
-            }
-            break;
-        case XML_TOK_PARTIAL:
-            eventPtr = entityTextPtr;
-            return XML_ERROR_INVALID_TOKEN;
-        case XML_TOK_INVALID:
-            eventPtr = next;
-            return XML_ERROR_INVALID_TOKEN;
-        default:
-            abort();
-        }
-        entityTextPtr = next;
-    }
-    /* not reached */
-}
-
-static void
-normalizeLines(XML_Char *s)
-{
-    XML_Char *p;
-    for (;; s++) {
-        if (*s == XML_T('\0'))
-            return;
-        if (*s == 0xD)
-            break;
-    }
-    p = s;
-    do {
-        if (*s == 0xD) {
-            *p++ = 0xA;
-            if (*++s == 0xA)
-                s++;
-        }
-        else
-            *p++ = *s++;
-    } while (*s);
-    *p = XML_T('\0');
-}
-
-static int
-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
-{
-    const XML_Char *target;
-    XML_Char *data;
-    const char *tem;
-    if (!processingInstructionHandler) {
-        if (defaultHandler)
-            reportDefault(parser, enc, start, end);
-        return 1;
-    }
-    start += enc->minBytesPerChar * 2;
-    tem = start + XmlNameLength(enc, start);
-    target = poolStoreString(&tempPool, enc, start, tem);
-    if (!target)
-        return 0;
-    poolFinish(&tempPool);
-    data = poolStoreString(&tempPool, enc,
-                           XmlSkipS(enc, tem),
-                           end - enc->minBytesPerChar*2);
-    if (!data)
-        return 0;
-    normalizeLines(data);
-    processingInstructionHandler(handlerArg, target, data);
-    poolClear(&tempPool);
-    return 1;
-}
-
-static int
-reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
-{
-    XML_Char *data;
-    if (!commentHandler) {
-        if (defaultHandler)
-            reportDefault(parser, enc, start, end);
-        return 1;
-    }
-    data = poolStoreString(&tempPool,
-                           enc,
-                           start + enc->minBytesPerChar * 4,
-                           end - enc->minBytesPerChar * 3);
-    if (!data)
-        return 0;
-    normalizeLines(data);
-    commentHandler(handlerArg, data);
-    poolClear(&tempPool);
-    return 1;
-}
-
-static void
-reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end)
-{
-    if (MUST_CONVERT(enc, s)) {
-        const char **eventPP;
-        const char **eventEndPP;
-        if (enc == encoding) {
-            eventPP = &eventPtr;
-            eventEndPP = &eventEndPtr;
-        }
-        else {
-            eventPP = &(openInternalEntities->internalEventPtr);
-            eventEndPP = &(openInternalEntities->internalEventEndPtr);
-        }
-        do {
-            ICHAR *dataPtr = (ICHAR *)dataBuf;
-            XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
-            *eventEndPP = s;
-            defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
-            *eventPP = s;
-        } while (s != end);
-    }
-    else
-        defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
-}
-
-
-static int
-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, const XML_Char *value)
-{
-    DEFAULT_ATTRIBUTE *att;
-    if (type->nDefaultAtts == type->allocDefaultAtts) {
-        if (type->allocDefaultAtts == 0) {
-            type->allocDefaultAtts = 8;
-            type->defaultAtts = malloc(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
-        }
-        else {
-            type->allocDefaultAtts *= 2;
-            type->defaultAtts = realloc(type->defaultAtts,
-                                        type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
-        }
-        if (!type->defaultAtts)
-            return 0;
-    }
-    att = type->defaultAtts + type->nDefaultAtts;
-    att->id = attId;
-    att->value = value;
-    att->isCdata = isCdata;
-    if (!isCdata)
-        attId->maybeTokenized = 1;
-    type->nDefaultAtts += 1;
-    return 1;
-}
-
-static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
-{
-    const XML_Char *name;
-    for (name = elementType->name; *name; name++) {
-        if (*name == XML_T(':')) {
-            PREFIX *prefix;
-            const XML_Char *s;
-            for (s = elementType->name; s != name; s++) {
-                if (!poolAppendChar(&dtd.pool, *s))
-                    return 0;
-            }
-            if (!poolAppendChar(&dtd.pool, XML_T('\0')))
-                return 0;
-            prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
-            if (!prefix)
-                return 0;
-            if (prefix->name == poolStart(&dtd.pool))
-                poolFinish(&dtd.pool);
-            else
-                poolDiscard(&dtd.pool);
-            elementType->prefix = prefix;
-
-        }
-    }
-    return 1;
-}
-
-static ATTRIBUTE_ID *
-getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
-{
-    ATTRIBUTE_ID *id;
-    const XML_Char *name;
-    if (!poolAppendChar(&dtd.pool, XML_T('\0')))
-        return 0;
-    name = poolStoreString(&dtd.pool, enc, start, end);
-    if (!name)
-        return 0;
-    ++name;
-    id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
-    if (!id)
-        return 0;
-    if (id->name != name)
-        poolDiscard(&dtd.pool);
-    else {
-        poolFinish(&dtd.pool);
-        if (!ns)
-            ;
-        else if (name[0] == 'x'
-                 && name[1] == 'm'
-                 && name[2] == 'l'
-                 && name[3] == 'n'
-                 && name[4] == 's'
-                 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
-            if (name[5] == '\0')
-                id->prefix = &dtd.defaultPrefix;
-            else
-                id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
-            id->xmlns = 1;
-        }
-        else {
-            int i;
-            for (i = 0; name[i]; i++) {
-                if (name[i] == XML_T(':')) {
-                    int j;
-                    for (j = 0; j < i; j++) {
-                        if (!poolAppendChar(&dtd.pool, name[j]))
-                            return 0;
-                    }
-                    if (!poolAppendChar(&dtd.pool, XML_T('\0')))
-                        return 0;
-                    id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
-                    if (id->prefix->name == poolStart(&dtd.pool))
-                        poolFinish(&dtd.pool);
-                    else
-                        poolDiscard(&dtd.pool);
-                    break;
-                }
-            }
-        }
-    }
-    return id;
-}
-
-#define CONTEXT_SEP XML_T('\f')
-
-static
-const XML_Char *getContext(XML_Parser parser)
-{
-    HASH_TABLE_ITER iter;
-    int needSep = 0;
-
-    if (dtd.defaultPrefix.binding) {
-        int i;
-        int len;
-        if (!poolAppendChar(&tempPool, XML_T('=')))
-            return 0;
-        len = dtd.defaultPrefix.binding->uriLen;
-        if (namespaceSeparator != XML_T('\0'))
-            len--;
-        for (i = 0; i < len; i++)
-            if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
-                return 0;
-        needSep = 1;
-    }
-
-    hashTableIterInit(&iter, &(dtd.prefixes));
-    for (;;) {
-        int i;
-        int len;
-        const XML_Char *s;
-        PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
-        if (!prefix)
-            break;
-        if (!prefix->binding)
-            continue;
-        if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
-            return 0;
-        for (s = prefix->name; *s; s++)
-            if (!poolAppendChar(&tempPool, *s))
-                return 0;
-        if (!poolAppendChar(&tempPool, XML_T('=')))
-            return 0;
-        len = prefix->binding->uriLen;
-        if (namespaceSeparator != XML_T('\0'))
-            len--;
-        for (i = 0; i < len; i++)
-            if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
-                return 0;
-        needSep = 1;
-    }
-
-
-    hashTableIterInit(&iter, &(dtd.generalEntities));
-    for (;;) {
-        const XML_Char *s;
-        ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
-        if (!e)
-            break;
-        if (!e->open)
-            continue;
-        if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
-            return 0;
-        for (s = e->name; *s; s++)
-            if (!poolAppendChar(&tempPool, *s))
-                return 0;
-        needSep = 1;
-    }
-
-    if (!poolAppendChar(&tempPool, XML_T('\0')))
-        return 0;
-    return tempPool.start;
-}
-
-static
-int setContext(XML_Parser parser, const XML_Char *context)
-{
-    const XML_Char *s = context;
-
-    while (*context != XML_T('\0')) {
-        if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
-            ENTITY *e;
-            if (!poolAppendChar(&tempPool, XML_T('\0')))
-                return 0;
-            e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
-            if (e)
-                e->open = 1;
-            if (*s != XML_T('\0'))
-                s++;
-            context = s;
-            poolDiscard(&tempPool);
-        }
-        else if (*s == '=') {
-            PREFIX *prefix;
-            if (poolLength(&tempPool) == 0)
-                prefix = &dtd.defaultPrefix;
-            else {
-                if (!poolAppendChar(&tempPool, XML_T('\0')))
-                    return 0;
-                prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
-                if (!prefix)
-                    return 0;
-                if (prefix->name == poolStart(&tempPool))
-                    poolFinish(&tempPool);
-                else
-                    poolDiscard(&tempPool);
-            }
-            for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
-                if (!poolAppendChar(&tempPool, *context))
-                    return 0;
-            if (!poolAppendChar(&tempPool, XML_T('\0')))
-                return 0;
-            if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
-                return 0;
-            poolDiscard(&tempPool);
-            if (*context != XML_T('\0'))
-                ++context;
-            s = context;
-        }
-        else {
-            if (!poolAppendChar(&tempPool, *s))
-                return 0;
-            s++;
-        }
-    }
-    return 1;
-}
-
-
-static
-void normalizePublicId(XML_Char *publicId)
-{
-    XML_Char *p = publicId;
-    XML_Char *s;
-    for (s = publicId; *s; s++) {
-        switch (*s) {
-        case 0x20:
-        case 0xD:
-        case 0xA:
-            if (p != publicId && p[-1] != 0x20)
-                *p++ = 0x20;
-            break;
-        default:
-            *p++ = *s;
-        }
-    }
-    if (p != publicId && p[-1] == 0x20)
-        --p;
-    *p = XML_T('\0');
-}
-
-static int dtdInit(DTD *p)
-{
-    poolInit(&(p->pool));
-    hashTableInit(&(p->generalEntities));
-    hashTableInit(&(p->elementTypes));
-    hashTableInit(&(p->attributeIds));
-    hashTableInit(&(p->prefixes));
-    p->complete = 1;
-    p->standalone = 0;
-    p->base = 0;
-    p->defaultPrefix.name = 0;
-    p->defaultPrefix.binding = 0;
-    return 1;
-}
-
-static void dtdDestroy(DTD *p)
-{
-    HASH_TABLE_ITER iter;
-    hashTableIterInit(&iter, &(p->elementTypes));
-    for (;;) {
-        ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
-        if (!e)
-            break;
-        if (e->allocDefaultAtts != 0)
-            free(e->defaultAtts);
-    }
-    hashTableDestroy(&(p->generalEntities));
-    hashTableDestroy(&(p->elementTypes));
-    hashTableDestroy(&(p->attributeIds));
-    hashTableDestroy(&(p->prefixes));
-    poolDestroy(&(p->pool));
-}
-
-/* Do a deep copy of the DTD.  Return 0 for out of memory; non-zero otherwise.
-The new DTD has already been initialized. */
-
-static int dtdCopy(DTD *newDtd, const DTD *oldDtd)
-{
-    HASH_TABLE_ITER iter;
-
-    if (oldDtd->base) {
-        const XML_Char *tem = poolCopyString(&(newDtd->pool), oldDtd->base);
-        if (!tem)
-            return 0;
-        newDtd->base = tem;
-    }
-
-    /* Copy the prefix table. */
-
-    hashTableIterInit(&iter, &(oldDtd->prefixes));
-    for (;;) {
-        const XML_Char *name;
-        const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
-        if (!oldP)
-            break;
-        name = poolCopyString(&(newDtd->pool), oldP->name);
-        if (!name)
-            return 0;
-        if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
-            return 0;
-    }
-
-    hashTableIterInit(&iter, &(oldDtd->attributeIds));
-
-    /* Copy the attribute id table. */
-
-    for (;;) {
-        ATTRIBUTE_ID *newA;
-        const XML_Char *name;
-        const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
-
-        if (!oldA)
-            break;
-        /* Remember to allocate the scratch byte before the name. */
-        if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
-            return 0;
-        name = poolCopyString(&(newDtd->pool), oldA->name);
-        if (!name)
-            return 0;
-        ++name;
-        newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
-        if (!newA)
-            return 0;
-        newA->maybeTokenized = oldA->maybeTokenized;
-        if (oldA->prefix) {
-            newA->xmlns = oldA->xmlns;
-            if (oldA->prefix == &oldDtd->defaultPrefix)
-                newA->prefix = &newDtd->defaultPrefix;
-            else
-                newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
-        }
-    }
-
-    /* Copy the element type table. */
-
-    hashTableIterInit(&iter, &(oldDtd->elementTypes));
-
-    for (;;) {
-        int i;
-        ELEMENT_TYPE *newE;
-        const XML_Char *name;
-        const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
-        if (!oldE)
-            break;
-        name = poolCopyString(&(newDtd->pool), oldE->name);
-        if (!name)
-            return 0;
-        newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
-        if (!newE)
-            return 0;
-        if (oldE->nDefaultAtts) {
-            newE->defaultAtts = (DEFAULT_ATTRIBUTE *)malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
-            if (!newE->defaultAtts)
-                return 0;
-        }
-        newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
-        if (oldE->prefix)
-            newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
-        for (i = 0; i < newE->nDefaultAtts; i++) {
-            newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
-            newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
-            if (oldE->defaultAtts[i].value) {
-                newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
-                if (!newE->defaultAtts[i].value)
-                    return 0;
-            }
-            else
-                newE->defaultAtts[i].value = 0;
-        }
-    }
-
-    /* Copy the entity table. */
-
-    hashTableIterInit(&iter, &(oldDtd->generalEntities));
-
-    for (;;) {
-        ENTITY *newE;
-        const XML_Char *name;
-        const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
-        if (!oldE)
-            break;
-        name = poolCopyString(&(newDtd->pool), oldE->name);
-        if (!name)
-            return 0;
-        newE = (ENTITY *)lookup(&(newDtd->generalEntities), name, sizeof(ENTITY));
-        if (!newE)
-            return 0;
-        if (oldE->systemId) {
-            const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->systemId);
-            if (!tem)
-                return 0;
-            newE->systemId = tem;
-            if (oldE->base) {
-                if (oldE->base == oldDtd->base)
-                    newE->base = newDtd->base;
-                tem = poolCopyString(&(newDtd->pool), oldE->base);
-                if (!tem)
-                    return 0;
-                newE->base = tem;
-            }
-        }
-        else {
-            const XML_Char *tem = poolCopyStringN(&(newDtd->pool), oldE->textPtr, oldE->textLen);
-            if (!tem)
-                return 0;
-            newE->textPtr = tem;
-            newE->textLen = oldE->textLen;
-        }
-        if (oldE->notation) {
-            const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->notation);
-            if (!tem)
-                return 0;
-            newE->notation = tem;
-        }
-    }
-
-    newDtd->complete = oldDtd->complete;
-    newDtd->standalone = oldDtd->standalone;
-    return 1;
-}
-
-static
-void poolInit(STRING_POOL *pool)
-{
-    pool->blocks = 0;
-    pool->freeBlocks = 0;
-    pool->start = 0;
-    pool->ptr = 0;
-    pool->end = 0;
-}
-
-static
-void poolClear(STRING_POOL *pool)
-{
-    if (!pool->freeBlocks)
-        pool->freeBlocks = pool->blocks;
-    else {
-        BLOCK *p = pool->blocks;
-        while (p) {
-            BLOCK *tem = p->next;
-            p->next = pool->freeBlocks;
-            pool->freeBlocks = p;
-            p = tem;
-        }
-    }
-    pool->blocks = 0;
-    pool->start = 0;
-    pool->ptr = 0;
-    pool->end = 0;
-}
-
-static
-void poolDestroy(STRING_POOL *pool)
-{
-    BLOCK *p = pool->blocks;
-    while (p) {
-        BLOCK *tem = p->next;
-        free(p);
-        p = tem;
-    }
-    pool->blocks = 0;
-    p = pool->freeBlocks;
-    while (p) {
-        BLOCK *tem = p->next;
-        free(p);
-        p = tem;
-    }
-    pool->freeBlocks = 0;
-    pool->ptr = 0;
-    pool->start = 0;
-    pool->end = 0;
-}
-
-static
-XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
-                     const char *ptr, const char *end)
-{
-    if (!pool->ptr && !poolGrow(pool))
-        return 0;
-    for (;;) {
-        XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
-        if (ptr == end)
-            break;
-        if (!poolGrow(pool))
-            return 0;
-    }
-    return pool->start;
-}
-
-static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
-{
-    do {
-        if (!poolAppendChar(pool, *s))
-            return 0;
-    } while (*s++);
-    s = pool->start;
-    poolFinish(pool);
-    return s;
-}
-
-static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
-{
-    if (!pool->ptr && !poolGrow(pool))
-        return 0;
-    for (; n > 0; --n, s++) {
-        if (!poolAppendChar(pool, *s))
-            return 0;
-
-    }
-    s = pool->start;
-    poolFinish(pool);
-    return s;
-}
-
-static
-XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
-                          const char *ptr, const char *end)
-{
-    if (!poolAppend(pool, enc, ptr, end))
-        return 0;
-    if (pool->ptr == pool->end && !poolGrow(pool))
-        return 0;
-    *(pool->ptr)++ = 0;
-    return pool->start;
-}
-
-static
-int poolGrow(STRING_POOL *pool)
-{
-    if (pool->freeBlocks) {
-        if (pool->start == 0) {
-            pool->blocks = pool->freeBlocks;
-            pool->freeBlocks = pool->freeBlocks->next;
-            pool->blocks->next = 0;
-            pool->start = pool->blocks->s;
-            pool->end = pool->start + pool->blocks->size;
-            pool->ptr = pool->start;
-            return 1;
-        }
-        if (pool->end - pool->start < pool->freeBlocks->size) {
-            BLOCK *tem = pool->freeBlocks->next;
-            pool->freeBlocks->next = pool->blocks;
-            pool->blocks = pool->freeBlocks;
-            pool->freeBlocks = tem;
-            memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char));
-            pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
-            pool->start = pool->blocks->s;
-            pool->end = pool->start + pool->blocks->size;
-            return 1;
-        }
-    }
-    if (pool->blocks && pool->start == pool->blocks->s) {
-        int blockSize = (pool->end - pool->start)*2;
-        pool->blocks = realloc(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
-        if (!pool->blocks)
-            return 0;
-        pool->blocks->size = blockSize;
-        pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
-        pool->start = pool->blocks->s;
-        pool->end = pool->start + blockSize;
-    }
-    else {
-        BLOCK *tem;
-        int blockSize = pool->end - pool->start;
-        if (blockSize < INIT_BLOCK_SIZE)
-            blockSize = INIT_BLOCK_SIZE;
-        else
-            blockSize *= 2;
-        tem = malloc(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
-        if (!tem)
-            return 0;
-        tem->size = blockSize;
-        tem->next = pool->blocks;
-        pool->blocks = tem;
-        memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
-        pool->ptr = tem->s + (pool->ptr - pool->start);
-        pool->start = tem->s;
-        pool->end = tem->s + blockSize;
-    }
-    return 1;
-}
--- a/mcabber/libjabber/xmlparse.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,482 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-#ifndef XmlParse_INCLUDED
-#define XmlParse_INCLUDED 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef XMLPARSEAPI
-#define XMLPARSEAPI /* as nothing */
-#endif
-
-typedef void *XML_Parser;
-
-#ifdef XML_UNICODE_WCHAR_T
-
-/* XML_UNICODE_WCHAR_T will work only if sizeof(wchar_t) == 2 and wchar_t
-uses Unicode. */
-/* Information is UTF-16 encoded as wchar_ts */
-
-#ifndef XML_UNICODE
-#define XML_UNICODE
-#endif
-
-#include <stddef.h>
-typedef wchar_t XML_Char;
-typedef wchar_t XML_LChar;
-
-#else /* not XML_UNICODE_WCHAR_T */
-
-#ifdef XML_UNICODE
-
-/* Information is UTF-16 encoded as unsigned shorts */
-typedef unsigned short XML_Char;
-typedef char XML_LChar;
-
-#else /* not XML_UNICODE */
-
-/* Information is UTF-8 encoded. */
-typedef char XML_Char;
-typedef char XML_LChar;
-
-#endif /* not XML_UNICODE */
-
-#endif /* not XML_UNICODE_WCHAR_T */
-
-
-/* Constructs a new parser; encoding is the encoding specified by the external
-protocol or null if there is none specified. */
-
-XML_Parser XMLPARSEAPI
-XML_ParserCreate(const XML_Char *encoding);
-
-/* Constructs a new parser and namespace processor.  Element type names
-and attribute names that belong to a namespace will be expanded;
-unprefixed attribute names are never expanded; unprefixed element type
-names are expanded only if there is a default namespace. The expanded
-name is the concatenation of the namespace URI, the namespace separator character,
-and the local part of the name.  If the namespace separator is '\0' then
-the namespace URI and the local part will be concatenated without any
-separator.  When a namespace is not declared, the name and prefix will be
-passed through without expansion. */
-
-XML_Parser XMLPARSEAPI
-XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
-
-
-/* atts is array of name/value pairs, terminated by 0;
-   names and values are 0 terminated. */
-
-typedef void (*XML_StartElementHandler)(void *userData,
-					const XML_Char *name,
-					const XML_Char **atts);
-
-typedef void (*XML_EndElementHandler)(void *userData,
-				      const XML_Char *name);
-
-/* s is not 0 terminated. */
-typedef void (*XML_CharacterDataHandler)(void *userData,
-					 const XML_Char *s,
-					 int len);
-
-/* target and data are 0 terminated */
-typedef void (*XML_ProcessingInstructionHandler)(void *userData,
-						 const XML_Char *target,
-						 const XML_Char *data);
-
-/* data is 0 terminated */
-typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data);
-
-typedef void (*XML_StartCdataSectionHandler)(void *userData);
-typedef void (*XML_EndCdataSectionHandler)(void *userData);
-
-/* This is called for any characters in the XML document for
-which there is no applicable handler.  This includes both
-characters that are part of markup which is of a kind that is
-not reported (comments, markup declarations), or characters
-that are part of a construct which could be reported but
-for which no handler has been supplied. The characters are passed
-exactly as they were in the XML document except that
-they will be encoded in UTF-8.  Line boundaries are not normalized.
-Note that a byte order mark character is not passed to the default handler.
-There are no guarantees about how characters are divided between calls
-to the default handler: for example, a comment might be split between
-multiple calls. */
-
-typedef void (*XML_DefaultHandler)(void *userData,
-				   const XML_Char *s,
-				   int len);
-
-/* This is called for a declaration of an unparsed (NDATA)
-entity.  The base argument is whatever was set by XML_SetBase.
-The entityName, systemId and notationName arguments will never be null.
-The other arguments may be. */
-
-typedef void (*XML_UnparsedEntityDeclHandler)(void *userData,
-					      const XML_Char *entityName,
-					      const XML_Char *base,
-					      const XML_Char *systemId,
-					      const XML_Char *publicId,
-					      const XML_Char *notationName);
-
-/* This is called for a declaration of notation.
-The base argument is whatever was set by XML_SetBase.
-The notationName will never be null.  The other arguments can be. */
-
-typedef void (*XML_NotationDeclHandler)(void *userData,
-					const XML_Char *notationName,
-					const XML_Char *base,
-					const XML_Char *systemId,
-					const XML_Char *publicId);
-
-/* When namespace processing is enabled, these are called once for
-each namespace declaration. The call to the start and end element
-handlers occur between the calls to the start and end namespace
-declaration handlers. For an xmlns attribute, prefix will be null.
-For an xmlns="" attribute, uri will be null. */
-
-typedef void (*XML_StartNamespaceDeclHandler)(void *userData,
-					      const XML_Char *prefix,
-					      const XML_Char *uri);
-
-typedef void (*XML_EndNamespaceDeclHandler)(void *userData,
-					    const XML_Char *prefix);
-
-/* This is called if the document is not standalone (it has an
-external subset or a reference to a parameter entity, but does not
-have standalone="yes"). If this handler returns 0, then processing
-will not continue, and the parser will return a
-XML_ERROR_NOT_STANDALONE error. */
-
-typedef int (*XML_NotStandaloneHandler)(void *userData);
-
-/* This is called for a reference to an external parsed general entity.
-The referenced entity is not automatically parsed.
-The application can parse it immediately or later using
-XML_ExternalEntityParserCreate.
-The parser argument is the parser parsing the entity containing the reference;
-it can be passed as the parser argument to XML_ExternalEntityParserCreate.
-The systemId argument is the system identifier as specified in the entity declaration;
-it will not be null.
-The base argument is the system identifier that should be used as the base for
-resolving systemId if systemId was relative; this is set by XML_SetBase;
-it may be null.
-The publicId argument is the public identifier as specified in the entity declaration,
-or null if none was specified; the whitespace in the public identifier
-will have been normalized as required by the XML spec.
-The context argument specifies the parsing context in the format
-expected by the context argument to
-XML_ExternalEntityParserCreate; context is valid only until the handler
-returns, so if the referenced entity is to be parsed later, it must be copied.
-The handler should return 0 if processing should not continue because of
-a fatal error in the handling of the external entity.
-In this case the calling parser will return an XML_ERROR_EXTERNAL_ENTITY_HANDLING
-error.
-Note that unlike other handlers the first argument is the parser, not userData. */
-
-typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser,
-					    const XML_Char *context,
-					    const XML_Char *base,
-					    const XML_Char *systemId,
-					    const XML_Char *publicId);
-
-/* This structure is filled in by the XML_UnknownEncodingHandler
-to provide information to the parser about encodings that are unknown
-to the parser.
-The map[b] member gives information about byte sequences
-whose first byte is b.
-If map[b] is c where c is >= 0, then b by itself encodes the Unicode scalar value c.
-If map[b] is -1, then the byte sequence is malformed.
-If map[b] is -n, where n >= 2, then b is the first byte of an n-byte
-sequence that encodes a single Unicode scalar value.
-The data member will be passed as the first argument to the convert function.
-The convert function is used to convert multibyte sequences;
-s will point to a n-byte sequence where map[(unsigned char)*s] == -n.
-The convert function must return the Unicode scalar value
-represented by this byte sequence or -1 if the byte sequence is malformed.
-The convert function may be null if the encoding is a single-byte encoding,
-that is if map[b] >= -1 for all bytes b.
-When the parser is finished with the encoding, then if release is not null,
-it will call release passing it the data member;
-once release has been called, the convert function will not be called again.
-
-Expat places certain restrictions on the encodings that are supported
-using this mechanism.
-
-1. Every ASCII character that can appear in a well-formed XML document,
-other than the characters
-
-  $@\^`{}~
-
-must be represented by a single byte, and that byte must be the
-same byte that represents that character in ASCII.
-
-2. No character may require more than 4 bytes to encode.
-
-3. All characters encoded must have Unicode scalar values <= 0xFFFF,
-(ie characters that would be encoded by surrogates in UTF-16
-are  not allowed).  Note that this restriction doesn't apply to
-the built-in support for UTF-8 and UTF-16.
-
-4. No Unicode character may be encoded by more than one distinct sequence
-of bytes. */
-
-typedef struct {
-  int map[256];
-  void *data;
-  int (*convert)(void *data, const char *s);
-  void (*release)(void *data);
-} XML_Encoding;
-
-/* This is called for an encoding that is unknown to the parser.
-The encodingHandlerData argument is that which was passed as the
-second argument to XML_SetUnknownEncodingHandler.
-The name argument gives the name of the encoding as specified in
-the encoding declaration.
-If the callback can provide information about the encoding,
-it must fill in the XML_Encoding structure, and return 1.
-Otherwise it must return 0.
-If info does not describe a suitable encoding,
-then the parser will return an XML_UNKNOWN_ENCODING error. */
-
-typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData,
-					  const XML_Char *name,
-					  XML_Encoding *info);
-
-void XMLPARSEAPI
-XML_SetElementHandler(XML_Parser parser,
-		      XML_StartElementHandler start,
-		      XML_EndElementHandler end);
-
-void XMLPARSEAPI
-XML_SetCharacterDataHandler(XML_Parser parser,
-			    XML_CharacterDataHandler handler);
-
-void XMLPARSEAPI
-XML_SetProcessingInstructionHandler(XML_Parser parser,
-				    XML_ProcessingInstructionHandler handler);
-void XMLPARSEAPI
-XML_SetCommentHandler(XML_Parser parser,
-                      XML_CommentHandler handler);
-
-void XMLPARSEAPI
-XML_SetCdataSectionHandler(XML_Parser parser,
-			   XML_StartCdataSectionHandler start,
-			   XML_EndCdataSectionHandler end);
-
-/* This sets the default handler and also inhibits expansion of internal entities.
-The entity reference will be passed to the default handler. */
-
-void XMLPARSEAPI
-XML_SetDefaultHandler(XML_Parser parser,
-		      XML_DefaultHandler handler);
-
-/* This sets the default handler but does not inhibit expansion of internal entities.
-The entity reference will not be passed to the default handler. */
-
-void XMLPARSEAPI
-XML_SetDefaultHandlerExpand(XML_Parser parser,
-		            XML_DefaultHandler handler);
-
-void XMLPARSEAPI
-XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
-				 XML_UnparsedEntityDeclHandler handler);
-
-void XMLPARSEAPI
-XML_SetNotationDeclHandler(XML_Parser parser,
-			   XML_NotationDeclHandler handler);
-
-void XMLPARSEAPI
-XML_SetNamespaceDeclHandler(XML_Parser parser,
-			    XML_StartNamespaceDeclHandler start,
-			    XML_EndNamespaceDeclHandler end);
-
-void XMLPARSEAPI
-XML_SetNotStandaloneHandler(XML_Parser parser,
-			    XML_NotStandaloneHandler handler);
-
-void XMLPARSEAPI
-XML_SetExternalEntityRefHandler(XML_Parser parser,
-				XML_ExternalEntityRefHandler handler);
-
-/* If a non-null value for arg is specified here, then it will be passed
-as the first argument to the external entity ref handler instead
-of the parser object. */
-void XMLPARSEAPI
-XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg);
-
-void XMLPARSEAPI
-XML_SetUnknownEncodingHandler(XML_Parser parser,
-			      XML_UnknownEncodingHandler handler,
-			      void *encodingHandlerData);
-
-/* This can be called within a handler for a start element, end element,
-processing instruction or character data.  It causes the corresponding
-markup to be passed to the default handler. */
-void XMLPARSEAPI XML_DefaultCurrent(XML_Parser parser);
-
-/* This value is passed as the userData argument to callbacks. */
-void XMLPARSEAPI
-XML_SetUserData(XML_Parser parser, void *userData);
-
-/* Returns the last value set by XML_SetUserData or null. */
-#define XML_GetUserData(parser) (*(void **)(parser))
-
-/* This is equivalent to supplying an encoding argument
-to XML_CreateParser. It must not be called after XML_Parse
-or XML_ParseBuffer. */
-
-int XMLPARSEAPI
-XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
-
-/* If this function is called, then the parser will be passed
-as the first argument to callbacks instead of userData.
-The userData will still be accessible using XML_GetUserData. */
-
-void XMLPARSEAPI
-XML_UseParserAsHandlerArg(XML_Parser parser);
-
-/* Sets the base to be used for resolving relative URIs in system identifiers in
-declarations.  Resolving relative identifiers is left to the application:
-this value will be passed through as the base argument to the
-XML_ExternalEntityRefHandler, XML_NotationDeclHandler
-and XML_UnparsedEntityDeclHandler. The base argument will be copied.
-Returns zero if out of memory, non-zero otherwise. */
-
-int XMLPARSEAPI
-XML_SetBase(XML_Parser parser, const XML_Char *base);
-
-const XML_Char XMLPARSEAPI *
-XML_GetBase(XML_Parser parser);
-
-/* Returns the number of the attributes passed in last call to the
-XML_StartElementHandler that were specified in the start-tag rather
-than defaulted. */
-
-int XMLPARSEAPI XML_GetSpecifiedAttributeCount(XML_Parser parser);
-
-/* Parses some input. Returns 0 if a fatal error is detected.
-The last call to XML_Parse must have isFinal true;
-len may be zero for this call (or any other). */
-int XMLPARSEAPI
-XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
-
-void XMLPARSEAPI *
-XML_GetBuffer(XML_Parser parser, int len);
-
-int XMLPARSEAPI
-XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
-
-/* Creates an XML_Parser object that can parse an external general entity;
-context is a '\0'-terminated string specifying the parse context;
-encoding is a '\0'-terminated string giving the name of the externally specified encoding,
-or null if there is no externally specified encoding.
-The context string consists of a sequence of tokens separated by formfeeds (\f);
-a token consisting of a name specifies that the general entity of the name
-is open; a token of the form prefix=uri specifies the namespace for a particular
-prefix; a token of the form =uri specifies the default namespace.
-This can be called at any point after the first call to an ExternalEntityRefHandler
-so longer as the parser has not yet been freed.
-The new parser is completely independent and may safely be used in a separate thread.
-The handlers and userData are initialized from the parser argument.
-Returns 0 if out of memory.  Otherwise returns a new XML_Parser object. */
-XML_Parser XMLPARSEAPI
-XML_ExternalEntityParserCreate(XML_Parser parser,
-			       const XML_Char *context,
-			       const XML_Char *encoding);
-
-enum XML_Error {
-  XML_ERROR_NONE,
-  XML_ERROR_NO_MEMORY,
-  XML_ERROR_SYNTAX,
-  XML_ERROR_NO_ELEMENTS,
-  XML_ERROR_INVALID_TOKEN,
-  XML_ERROR_UNCLOSED_TOKEN,
-  XML_ERROR_PARTIAL_CHAR,
-  XML_ERROR_TAG_MISMATCH,
-  XML_ERROR_DUPLICATE_ATTRIBUTE,
-  XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
-  XML_ERROR_PARAM_ENTITY_REF,
-  XML_ERROR_UNDEFINED_ENTITY,
-  XML_ERROR_RECURSIVE_ENTITY_REF,
-  XML_ERROR_ASYNC_ENTITY,
-  XML_ERROR_BAD_CHAR_REF,
-  XML_ERROR_BINARY_ENTITY_REF,
-  XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
-  XML_ERROR_MISPLACED_XML_PI,
-  XML_ERROR_UNKNOWN_ENCODING,
-  XML_ERROR_INCORRECT_ENCODING,
-  XML_ERROR_UNCLOSED_CDATA_SECTION,
-  XML_ERROR_EXTERNAL_ENTITY_HANDLING,
-  XML_ERROR_NOT_STANDALONE
-};
-
-/* If XML_Parse or XML_ParseBuffer have returned 0, then XML_GetErrorCode
-returns information about the error. */
-
-enum XML_Error XMLPARSEAPI XML_GetErrorCode(XML_Parser parser);
-
-/* These functions return information about the current parse location.
-They may be called when XML_Parse or XML_ParseBuffer return 0;
-in this case the location is the location of the character at which
-the error was detected.
-They may also be called from any other callback called to report
-some parse event; in this the location is the location of the first
-of the sequence of characters that generated the event. */
-
-int XMLPARSEAPI XML_GetCurrentLineNumber(XML_Parser parser);
-int XMLPARSEAPI XML_GetCurrentColumnNumber(XML_Parser parser);
-long XMLPARSEAPI XML_GetCurrentByteIndex(XML_Parser parser);
-
-/* Return the number of bytes in the current event.
-Returns 0 if the event is in an internal entity. */
-
-int XMLPARSEAPI XML_GetCurrentByteCount(XML_Parser parser);
-
-/* For backwards compatibility with previous versions. */
-#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
-#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
-#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
-
-/* Frees memory used by the parser. */
-void XMLPARSEAPI
-XML_ParserFree(XML_Parser parser);
-
-/* Returns a string describing the error. */
-const XML_LChar XMLPARSEAPI *XML_ErrorString(int code);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not XmlParse_INCLUDED */
--- a/mcabber/libjabber/xmlrole.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1113 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-#include "xmldef.h"
-#include "xmlrole.h"
-
-/* Doesn't check:
-
- that ,| are not mixed in a model group
- content of literals
-
-*/
-
-#ifndef MIN_BYTES_PER_CHAR
-#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
-#endif
-
-typedef int PROLOG_HANDLER(struct prolog_state *state,
-                           int tok,
-                           const char *ptr,
-                           const char *end,
-                           const ENCODING *enc);
-
-static PROLOG_HANDLER
-prolog0, prolog1, prolog2,
-doctype0, doctype1, doctype2, doctype3, doctype4, doctype5,
-internalSubset,
-entity0, entity1, entity2, entity3, entity4, entity5, entity6,
-entity7, entity8, entity9,
-notation0, notation1, notation2, notation3, notation4,
-attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6,
-attlist7, attlist8, attlist9,
-element0, element1, element2, element3, element4, element5, element6,
-element7,
-declClose,
-error;
-
-static
-int syntaxError(PROLOG_STATE *);
-
-static
-int prolog0(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        state->handler = prolog1;
-        return XML_ROLE_NONE;
-    case XML_TOK_XML_DECL:
-        state->handler = prolog1;
-        return XML_ROLE_XML_DECL;
-    case XML_TOK_PI:
-        state->handler = prolog1;
-        return XML_ROLE_NONE;
-    case XML_TOK_COMMENT:
-        state->handler = prolog1;
-    case XML_TOK_BOM:
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_OPEN:
-        if (!XmlNameMatchesAscii(enc,
-                                 ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                                 "DOCTYPE"))
-            break;
-        state->handler = doctype0;
-        return XML_ROLE_NONE;
-    case XML_TOK_INSTANCE_START:
-        state->handler = error;
-        return XML_ROLE_INSTANCE_START;
-    }
-    return syntaxError(state);
-}
-
-static
-int prolog1(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_PI:
-    case XML_TOK_COMMENT:
-    case XML_TOK_BOM:
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_OPEN:
-        if (!XmlNameMatchesAscii(enc,
-                                 ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                                 "DOCTYPE"))
-            break;
-        state->handler = doctype0;
-        return XML_ROLE_NONE;
-    case XML_TOK_INSTANCE_START:
-        state->handler = error;
-        return XML_ROLE_INSTANCE_START;
-    }
-    return syntaxError(state);
-}
-
-static
-int prolog2(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_PI:
-    case XML_TOK_COMMENT:
-        return XML_ROLE_NONE;
-    case XML_TOK_INSTANCE_START:
-        state->handler = error;
-        return XML_ROLE_INSTANCE_START;
-    }
-    return syntaxError(state);
-}
-
-static
-int doctype0(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = doctype1;
-        return XML_ROLE_DOCTYPE_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int doctype1(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_OPEN_BRACKET:
-        state->handler = internalSubset;
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_CLOSE:
-        state->handler = prolog2;
-        return XML_ROLE_DOCTYPE_CLOSE;
-    case XML_TOK_NAME:
-        if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) {
-            state->handler = doctype3;
-            return XML_ROLE_NONE;
-        }
-        if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) {
-            state->handler = doctype2;
-            return XML_ROLE_NONE;
-        }
-        break;
-    }
-    return syntaxError(state);
-}
-
-static
-int doctype2(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = doctype3;
-        return XML_ROLE_DOCTYPE_PUBLIC_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int doctype3(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = doctype4;
-        return XML_ROLE_DOCTYPE_SYSTEM_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int doctype4(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_OPEN_BRACKET:
-        state->handler = internalSubset;
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_CLOSE:
-        state->handler = prolog2;
-        return XML_ROLE_DOCTYPE_CLOSE;
-    }
-    return syntaxError(state);
-}
-
-static
-int doctype5(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_CLOSE:
-        state->handler = prolog2;
-        return XML_ROLE_DOCTYPE_CLOSE;
-    }
-    return syntaxError(state);
-}
-
-static
-int internalSubset(PROLOG_STATE *state,
-                   int tok,
-                   const char *ptr,
-                   const char *end,
-                   const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_OPEN:
-        if (XmlNameMatchesAscii(enc,
-                                ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                                "ENTITY")) {
-            state->handler = entity0;
-            return XML_ROLE_NONE;
-        }
-        if (XmlNameMatchesAscii(enc,
-                                ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                                "ATTLIST")) {
-            state->handler = attlist0;
-            return XML_ROLE_NONE;
-        }
-        if (XmlNameMatchesAscii(enc,
-                                ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                                "ELEMENT")) {
-            state->handler = element0;
-            return XML_ROLE_NONE;
-        }
-        if (XmlNameMatchesAscii(enc,
-                                ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                                "NOTATION")) {
-            state->handler = notation0;
-            return XML_ROLE_NONE;
-        }
-        break;
-    case XML_TOK_PI:
-    case XML_TOK_COMMENT:
-        return XML_ROLE_NONE;
-    case XML_TOK_PARAM_ENTITY_REF:
-        return XML_ROLE_PARAM_ENTITY_REF;
-    case XML_TOK_CLOSE_BRACKET:
-        state->handler = doctype5;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity0(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_PERCENT:
-        state->handler = entity1;
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        state->handler = entity2;
-        return XML_ROLE_GENERAL_ENTITY_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity1(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        state->handler = entity7;
-        return XML_ROLE_PARAM_ENTITY_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity2(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) {
-            state->handler = entity4;
-            return XML_ROLE_NONE;
-        }
-        if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) {
-            state->handler = entity3;
-            return XML_ROLE_NONE;
-        }
-        break;
-    case XML_TOK_LITERAL:
-        state->handler = declClose;
-        return XML_ROLE_ENTITY_VALUE;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity3(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = entity4;
-        return XML_ROLE_ENTITY_PUBLIC_ID;
-    }
-    return syntaxError(state);
-}
-
-
-static
-int entity4(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = entity5;
-        return XML_ROLE_ENTITY_SYSTEM_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity5(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_CLOSE:
-        state->handler = internalSubset;
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        if (XmlNameMatchesAscii(enc, ptr, "NDATA")) {
-            state->handler = entity6;
-            return XML_ROLE_NONE;
-        }
-        break;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity6(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        state->handler = declClose;
-        return XML_ROLE_ENTITY_NOTATION_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity7(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) {
-            state->handler = entity9;
-            return XML_ROLE_NONE;
-        }
-        if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) {
-            state->handler = entity8;
-            return XML_ROLE_NONE;
-        }
-        break;
-    case XML_TOK_LITERAL:
-        state->handler = declClose;
-        return XML_ROLE_ENTITY_VALUE;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity8(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = entity9;
-        return XML_ROLE_ENTITY_PUBLIC_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity9(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = declClose;
-        return XML_ROLE_ENTITY_SYSTEM_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int notation0(PROLOG_STATE *state,
-              int tok,
-              const char *ptr,
-              const char *end,
-              const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        state->handler = notation1;
-        return XML_ROLE_NOTATION_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int notation1(PROLOG_STATE *state,
-              int tok,
-              const char *ptr,
-              const char *end,
-              const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) {
-            state->handler = notation3;
-            return XML_ROLE_NONE;
-        }
-        if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) {
-            state->handler = notation2;
-            return XML_ROLE_NONE;
-        }
-        break;
-    }
-    return syntaxError(state);
-}
-
-static
-int notation2(PROLOG_STATE *state,
-              int tok,
-              const char *ptr,
-              const char *end,
-              const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = notation4;
-        return XML_ROLE_NOTATION_PUBLIC_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int notation3(PROLOG_STATE *state,
-              int tok,
-              const char *ptr,
-              const char *end,
-              const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = declClose;
-        return XML_ROLE_NOTATION_SYSTEM_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int notation4(PROLOG_STATE *state,
-              int tok,
-              const char *ptr,
-              const char *end,
-              const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = declClose;
-        return XML_ROLE_NOTATION_SYSTEM_ID;
-    case XML_TOK_DECL_CLOSE:
-        state->handler = internalSubset;
-        return XML_ROLE_NOTATION_NO_SYSTEM_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist0(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = attlist1;
-        return XML_ROLE_ATTLIST_ELEMENT_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist1(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_CLOSE:
-        state->handler = internalSubset;
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = attlist2;
-        return XML_ROLE_ATTRIBUTE_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist2(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        {
-            static const char *types[] = {
-                "CDATA",
-                "ID",
-                "IDREF",
-                "IDREFS",
-                "ENTITY",
-                "ENTITIES",
-                "NMTOKEN",
-                "NMTOKENS",
-            };
-            int i;
-            for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)
-                if (XmlNameMatchesAscii(enc, ptr, types[i])) {
-                    state->handler = attlist8;
-                    return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
-                }
-        }
-        if (XmlNameMatchesAscii(enc, ptr, "NOTATION")) {
-            state->handler = attlist5;
-            return XML_ROLE_NONE;
-        }
-        break;
-    case XML_TOK_OPEN_PAREN:
-        state->handler = attlist3;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist3(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NMTOKEN:
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = attlist4;
-        return XML_ROLE_ATTRIBUTE_ENUM_VALUE;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist4(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_CLOSE_PAREN:
-        state->handler = attlist8;
-        return XML_ROLE_NONE;
-    case XML_TOK_OR:
-        state->handler = attlist3;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist5(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_OPEN_PAREN:
-        state->handler = attlist6;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-
-static
-int attlist6(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        state->handler = attlist7;
-        return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist7(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_CLOSE_PAREN:
-        state->handler = attlist8;
-        return XML_ROLE_NONE;
-    case XML_TOK_OR:
-        state->handler = attlist6;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-/* default value */
-static
-int attlist8(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_POUND_NAME:
-        if (XmlNameMatchesAscii(enc,
-                                ptr + MIN_BYTES_PER_CHAR(enc),
-                                "IMPLIED")) {
-            state->handler = attlist1;
-            return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
-        }
-        if (XmlNameMatchesAscii(enc,
-                                ptr + MIN_BYTES_PER_CHAR(enc),
-                                "REQUIRED")) {
-            state->handler = attlist1;
-            return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
-        }
-        if (XmlNameMatchesAscii(enc,
-                                ptr + MIN_BYTES_PER_CHAR(enc),
-                                "FIXED")) {
-            state->handler = attlist9;
-            return XML_ROLE_NONE;
-        }
-        break;
-    case XML_TOK_LITERAL:
-        state->handler = attlist1;
-        return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist9(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = attlist1;
-        return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
-    }
-    return syntaxError(state);
-}
-
-static
-int element0(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = element1;
-        return XML_ROLE_ELEMENT_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int element1(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        if (XmlNameMatchesAscii(enc, ptr, "EMPTY")) {
-            state->handler = declClose;
-            return XML_ROLE_CONTENT_EMPTY;
-        }
-        if (XmlNameMatchesAscii(enc, ptr, "ANY")) {
-            state->handler = declClose;
-            return XML_ROLE_CONTENT_ANY;
-        }
-        break;
-    case XML_TOK_OPEN_PAREN:
-        state->handler = element2;
-        state->level = 1;
-        return XML_ROLE_GROUP_OPEN;
-    }
-    return syntaxError(state);
-}
-
-static
-int element2(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_POUND_NAME:
-        if (XmlNameMatchesAscii(enc,
-                                ptr + MIN_BYTES_PER_CHAR(enc),
-                                "PCDATA")) {
-            state->handler = element3;
-            return XML_ROLE_CONTENT_PCDATA;
-        }
-        break;
-    case XML_TOK_OPEN_PAREN:
-        state->level = 2;
-        state->handler = element6;
-        return XML_ROLE_GROUP_OPEN;
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT;
-    case XML_TOK_NAME_QUESTION:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT_OPT;
-    case XML_TOK_NAME_ASTERISK:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT_REP;
-    case XML_TOK_NAME_PLUS:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT_PLUS;
-    }
-    return syntaxError(state);
-}
-
-static
-int element3(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_CLOSE_PAREN:
-    case XML_TOK_CLOSE_PAREN_ASTERISK:
-        state->handler = declClose;
-        return XML_ROLE_GROUP_CLOSE_REP;
-    case XML_TOK_OR:
-        state->handler = element4;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-static
-int element4(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = element5;
-        return XML_ROLE_CONTENT_ELEMENT;
-    }
-    return syntaxError(state);
-}
-
-static
-int element5(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_CLOSE_PAREN_ASTERISK:
-        state->handler = declClose;
-        return XML_ROLE_GROUP_CLOSE_REP;
-    case XML_TOK_OR:
-        state->handler = element4;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-static
-int element6(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_OPEN_PAREN:
-        state->level += 1;
-        return XML_ROLE_GROUP_OPEN;
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT;
-    case XML_TOK_NAME_QUESTION:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT_OPT;
-    case XML_TOK_NAME_ASTERISK:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT_REP;
-    case XML_TOK_NAME_PLUS:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT_PLUS;
-    }
-    return syntaxError(state);
-}
-
-static
-int element7(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_CLOSE_PAREN:
-        state->level -= 1;
-        if (state->level == 0)
-            state->handler = declClose;
-        return XML_ROLE_GROUP_CLOSE;
-    case XML_TOK_CLOSE_PAREN_ASTERISK:
-        state->level -= 1;
-        if (state->level == 0)
-            state->handler = declClose;
-        return XML_ROLE_GROUP_CLOSE_REP;
-    case XML_TOK_CLOSE_PAREN_QUESTION:
-        state->level -= 1;
-        if (state->level == 0)
-            state->handler = declClose;
-        return XML_ROLE_GROUP_CLOSE_OPT;
-    case XML_TOK_CLOSE_PAREN_PLUS:
-        state->level -= 1;
-        if (state->level == 0)
-            state->handler = declClose;
-        return XML_ROLE_GROUP_CLOSE_PLUS;
-    case XML_TOK_COMMA:
-        state->handler = element6;
-        return XML_ROLE_GROUP_SEQUENCE;
-    case XML_TOK_OR:
-        state->handler = element6;
-        return XML_ROLE_GROUP_CHOICE;
-    }
-    return syntaxError(state);
-}
-
-static
-int declClose(PROLOG_STATE *state,
-              int tok,
-              const char *ptr,
-              const char *end,
-              const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_CLOSE:
-        state->handler = internalSubset;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-#if 0
-
-static
-int ignore(PROLOG_STATE *state,
-           int tok,
-           const char *ptr,
-           const char *end,
-           const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_DECL_CLOSE:
-        state->handler = internalSubset;
-        return 0;
-    default:
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-#endif
-
-static
-int error(PROLOG_STATE *state,
-          int tok,
-          const char *ptr,
-          const char *end,
-          const ENCODING *enc)
-{
-    return XML_ROLE_NONE;
-}
-
-static
-int syntaxError(PROLOG_STATE *state)
-{
-    state->handler = error;
-    return XML_ROLE_ERROR;
-}
-
-void XmlPrologStateInit(PROLOG_STATE *state)
-{
-    state->handler = prolog0;
-}
--- a/mcabber/libjabber/xmlrole.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-#ifndef XmlRole_INCLUDED
-#define XmlRole_INCLUDED 1
-
-#include "xmltok.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum {
-  XML_ROLE_ERROR = -1,
-  XML_ROLE_NONE = 0,
-  XML_ROLE_XML_DECL,
-  XML_ROLE_INSTANCE_START,
-  XML_ROLE_DOCTYPE_NAME,
-  XML_ROLE_DOCTYPE_SYSTEM_ID,
-  XML_ROLE_DOCTYPE_PUBLIC_ID,
-  XML_ROLE_DOCTYPE_CLOSE,
-  XML_ROLE_GENERAL_ENTITY_NAME,
-  XML_ROLE_PARAM_ENTITY_NAME,
-  XML_ROLE_ENTITY_VALUE,
-  XML_ROLE_ENTITY_SYSTEM_ID,
-  XML_ROLE_ENTITY_PUBLIC_ID,
-  XML_ROLE_ENTITY_NOTATION_NAME,
-  XML_ROLE_NOTATION_NAME,
-  XML_ROLE_NOTATION_SYSTEM_ID,
-  XML_ROLE_NOTATION_NO_SYSTEM_ID,
-  XML_ROLE_NOTATION_PUBLIC_ID,
-  XML_ROLE_ATTRIBUTE_NAME,
-  XML_ROLE_ATTRIBUTE_TYPE_CDATA,
-  XML_ROLE_ATTRIBUTE_TYPE_ID,
-  XML_ROLE_ATTRIBUTE_TYPE_IDREF,
-  XML_ROLE_ATTRIBUTE_TYPE_IDREFS,
-  XML_ROLE_ATTRIBUTE_TYPE_ENTITY,
-  XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,
-  XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,
-  XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
-  XML_ROLE_ATTRIBUTE_ENUM_VALUE,
-  XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
-  XML_ROLE_ATTLIST_ELEMENT_NAME,
-  XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
-  XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
-  XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
-  XML_ROLE_FIXED_ATTRIBUTE_VALUE,
-  XML_ROLE_ELEMENT_NAME,
-  XML_ROLE_CONTENT_ANY,
-  XML_ROLE_CONTENT_EMPTY,
-  XML_ROLE_CONTENT_PCDATA,
-  XML_ROLE_GROUP_OPEN,
-  XML_ROLE_GROUP_CLOSE,
-  XML_ROLE_GROUP_CLOSE_REP,
-  XML_ROLE_GROUP_CLOSE_OPT,
-  XML_ROLE_GROUP_CLOSE_PLUS,
-  XML_ROLE_GROUP_CHOICE,
-  XML_ROLE_GROUP_SEQUENCE,
-  XML_ROLE_CONTENT_ELEMENT,
-  XML_ROLE_CONTENT_ELEMENT_REP,
-  XML_ROLE_CONTENT_ELEMENT_OPT,
-  XML_ROLE_CONTENT_ELEMENT_PLUS,
-  XML_ROLE_PARAM_ENTITY_REF
-};
-
-typedef struct prolog_state {
-  int (*handler)(struct prolog_state *state,
-	         int tok,
-		 const char *ptr,
-		 const char *end,
-		 const ENCODING *enc);
-  unsigned level;
-} PROLOG_STATE;
-
-void XMLTOKAPI XmlPrologStateInit(PROLOG_STATE *);
-
-#define XmlTokenRole(state, tok, ptr, end, enc) \
- (((state)->handler)(state, tok, ptr, end, enc))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not XmlRole_INCLUDED */
--- a/mcabber/libjabber/xmltok.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1527 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-#include "xmldef.h"
-#include "xmltok.h"
-#include "nametab.h"
-
-#define VTABLE1 \
-  { PREFIX(prologTok), PREFIX(contentTok), PREFIX(cdataSectionTok) }, \
-  { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \
-  PREFIX(sameName), \
-  PREFIX(nameMatchesAscii), \
-  PREFIX(nameLength), \
-  PREFIX(skipS), \
-  PREFIX(getAtts), \
-  PREFIX(charRefNumber), \
-  PREFIX(predefinedEntityName), \
-  PREFIX(updatePosition), \
-  PREFIX(isPublicId)
-
-#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
-
-#define UCS2_GET_NAMING(pages, hi, lo) \
-   (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
-
-/* A 2 byte UTF-8 representation splits the characters 11 bits
-between the bottom 5 and 6 bits of the bytes.
-We need 8 bits to index into pages, 3 bits to add to that index and
-5 bits to generate the mask. */
-#define UTF8_GET_NAMING2(pages, byte) \
-    (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
-		      + ((((byte)[0]) & 3) << 1) \
-		      + ((((byte)[1]) >> 5) & 1)] \
-	 & (1 << (((byte)[1]) & 0x1F)))
-
-/* A 3 byte UTF-8 representation splits the characters 16 bits
-between the bottom 4, 6 and 6 bits of the bytes.
-We need 8 bits to index into pages, 3 bits to add to that index and
-5 bits to generate the mask. */
-#define UTF8_GET_NAMING3(pages, byte) \
-  (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
-			     + ((((byte)[1]) >> 2) & 0xF)] \
-	       << 3) \
-		      + ((((byte)[1]) & 3) << 1) \
-		      + ((((byte)[2]) >> 5) & 1)] \
-	 & (1 << (((byte)[2]) & 0x1F)))
-
-#define UTF8_GET_NAMING(pages, p, n) \
-  ((n) == 2 \
-  ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
-  : ((n) == 3 \
-     ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
-     : 0))
-
-#define UTF8_INVALID3(p) \
-  ((*p) == 0xED \
-  ? (((p)[1] & 0x20) != 0) \
-  : ((*p) == 0xEF \
-     ? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) \
-     : 0))
-
-#define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0)
-
-static
-int isNever(const ENCODING *enc, const char *p)
-{
-    return 0;
-}
-
-static
-int utf8_isName2(const ENCODING *enc, const char *p)
-{
-    return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
-}
-
-static
-int utf8_isName3(const ENCODING *enc, const char *p)
-{
-    return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
-}
-
-#define utf8_isName4 isNever
-
-static
-int utf8_isNmstrt2(const ENCODING *enc, const char *p)
-{
-    return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
-}
-
-static
-int utf8_isNmstrt3(const ENCODING *enc, const char *p)
-{
-    return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
-}
-
-#define utf8_isNmstrt4 isNever
-
-#define utf8_isInvalid2 isNever
-
-static
-int utf8_isInvalid3(const ENCODING *enc, const char *p)
-{
-    return UTF8_INVALID3((const unsigned char *)p);
-}
-
-static
-int utf8_isInvalid4(const ENCODING *enc, const char *p)
-{
-    return UTF8_INVALID4((const unsigned char *)p);
-}
-
-struct normal_encoding {
-    ENCODING enc;
-    unsigned char type[256];
-#ifdef XML_MIN_SIZE
-    int (*byteType)(const ENCODING *, const char *);
-    int (*isNameMin)(const ENCODING *, const char *);
-    int (*isNmstrtMin)(const ENCODING *, const char *);
-    int (*byteToAscii)(const ENCODING *, const char *);
-    int (*charMatches)(const ENCODING *, const char *, int);
-#endif /* XML_MIN_SIZE */
-    int (*isName2)(const ENCODING *, const char *);
-    int (*isName3)(const ENCODING *, const char *);
-    int (*isName4)(const ENCODING *, const char *);
-    int (*isNmstrt2)(const ENCODING *, const char *);
-    int (*isNmstrt3)(const ENCODING *, const char *);
-    int (*isNmstrt4)(const ENCODING *, const char *);
-    int (*isInvalid2)(const ENCODING *, const char *);
-    int (*isInvalid3)(const ENCODING *, const char *);
-    int (*isInvalid4)(const ENCODING *, const char *);
-};
-
-#ifdef XML_MIN_SIZE
-
-#define STANDARD_VTABLE(E) \
- E ## byteType, \
- E ## isNameMin, \
- E ## isNmstrtMin, \
- E ## byteToAscii, \
- E ## charMatches,
-
-#else
-
-#define STANDARD_VTABLE(E) /* as nothing */
-
-#endif
-
-#define NORMAL_VTABLE(E) \
- E ## isName2, \
- E ## isName3, \
- E ## isName4, \
- E ## isNmstrt2, \
- E ## isNmstrt3, \
- E ## isNmstrt4, \
- E ## isInvalid2, \
- E ## isInvalid3, \
- E ## isInvalid4
-
-static int checkCharRefNumber(int);
-
-#include "xmltok_impl.h"
-
-#ifdef XML_MIN_SIZE
-#define sb_isNameMin isNever
-#define sb_isNmstrtMin isNever
-#endif
-
-#ifdef XML_MIN_SIZE
-#define MINBPC(enc) ((enc)->minBytesPerChar)
-#else
-/* minimum bytes per character */
-#define MINBPC(enc) 1
-#endif
-
-#define SB_BYTE_TYPE(enc, p) \
-  (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
-
-#ifdef XML_MIN_SIZE
-static
-int sb_byteType(const ENCODING *enc, const char *p)
-{
-    return SB_BYTE_TYPE(enc, p);
-}
-#define BYTE_TYPE(enc, p) \
- (((const struct normal_encoding *)(enc))->byteType(enc, p))
-#else
-#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
-#endif
-
-#ifdef XML_MIN_SIZE
-#define BYTE_TO_ASCII(enc, p) \
- (((const struct normal_encoding *)(enc))->byteToAscii(enc, p))
-static
-int sb_byteToAscii(const ENCODING *enc, const char *p)
-{
-    return *p;
-}
-#else
-#define BYTE_TO_ASCII(enc, p) (*p)
-#endif
-
-#define IS_NAME_CHAR(enc, p, n) \
- (((const struct normal_encoding *)(enc))->isName ## n(enc, p))
-#define IS_NMSTRT_CHAR(enc, p, n) \
- (((const struct normal_encoding *)(enc))->isNmstrt ## n(enc, p))
-#define IS_INVALID_CHAR(enc, p, n) \
- (((const struct normal_encoding *)(enc))->isInvalid ## n(enc, p))
-
-#ifdef XML_MIN_SIZE
-#define IS_NAME_CHAR_MINBPC(enc, p) \
- (((const struct normal_encoding *)(enc))->isNameMin(enc, p))
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
- (((const struct normal_encoding *)(enc))->isNmstrtMin(enc, p))
-#else
-#define IS_NAME_CHAR_MINBPC(enc, p) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
-#endif
-
-#ifdef XML_MIN_SIZE
-#define CHAR_MATCHES(enc, p, c) \
- (((const struct normal_encoding *)(enc))->charMatches(enc, p, c))
-static
-int sb_charMatches(const ENCODING *enc, const char *p, int c)
-{
-    return *p == c;
-}
-#else
-/* c is an ASCII character */
-#define CHAR_MATCHES(enc, p, c) (*(p) == c)
-#endif
-
-#define PREFIX(ident) normal_ ## ident
-#include "xmltok_impl_c.h"
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
-
-enum {  /* UTF8_cvalN is value of masked first byte of N byte sequence */
-    UTF8_cval1 = 0x00,
-    UTF8_cval2 = 0xc0,
-    UTF8_cval3 = 0xe0,
-    UTF8_cval4 = 0xf0
-};
-
-static
-void utf8_toUtf8(const ENCODING *enc,
-		 const char **fromP, const char *fromLim,
-		 char **toP, const char *toLim)
-{
-    char *to;
-    const char *from;
-    if (fromLim - *fromP > toLim - *toP) {
-	/* Avoid copying partial characters. */
-	for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
-	    if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
-		break;
-    }
-    for (to = *toP, from = *fromP; from != fromLim; from++, to++)
-	*to = *from;
-    *fromP = from;
-    *toP = to;
-}
-
-static
-void utf8_toUtf16(const ENCODING *enc,
-		  const char **fromP, const char *fromLim,
-		  unsigned short **toP, const unsigned short *toLim)
-{
-    unsigned short *to = *toP;
-    const char *from = *fromP;
-    while (from != fromLim && to != toLim) {
-	switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
-	case BT_LEAD2:
-	    *to++ = ((from[0] & 0x1f) << 6) | (from[1] & 0x3f);
-	    from += 2;
-	    break;
-	case BT_LEAD3:
-	    *to++ = ((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f);
-	    from += 3;
-	    break;
-	case BT_LEAD4:
-	    {
-		unsigned long n;
-		if (to + 1 == toLim)
-		    break;
-		n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
-		n -= 0x10000;
-		to[0] = (unsigned short)((n >> 10) | 0xD800);
-		to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
-		to += 2;
-		from += 4;
-	    }
-	    break;
-	default:
-	    *to++ = *from++;
-	    break;
-	}
-    }
-    *fromP = from;
-    *toP = to;
-}
-
-#ifdef XML_NS
-static const struct normal_encoding utf8_encoding_ns = {
-	{ VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
-	    {
-#include "asciitab.h"
-#include "utf8tab.h"
-	    },
-	    STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-	};
-#endif
-
-static const struct normal_encoding utf8_encoding = {
-	{ VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
-	    {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "utf8tab.h"
-	    },
-	    STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-	};
-
-#ifdef XML_NS
-
-static const struct normal_encoding internal_utf8_encoding_ns = {
-	{ VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
-	    {
-#include "iasciitab.h"
-#include "utf8tab.h"
-	    },
-	    STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-	};
-
-#endif
-
-static const struct normal_encoding internal_utf8_encoding = {
-	{ VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
-	    {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "utf8tab.h"
-	    },
-	    STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-	};
-
-static
-void latin1_toUtf8(const ENCODING *enc,
-		   const char **fromP, const char *fromLim,
-		   char **toP, const char *toLim)
-{
-    for (;;) {
-	unsigned char c;
-	if (*fromP == fromLim)
-	    break;
-	c = (unsigned char)**fromP;
-	if (c & 0x80) {
-	    if (toLim - *toP < 2)
-		break;
-	    *(*toP)++ = ((c >> 6) | UTF8_cval2);
-	    *(*toP)++ = ((c & 0x3f) | 0x80);
-	    (*fromP)++;
-	}
-	else {
-	    if (*toP == toLim)
-		break;
-	    *(*toP)++ = *(*fromP)++;
-	}
-    }
-}
-
-static
-void latin1_toUtf16(const ENCODING *enc,
-		    const char **fromP, const char *fromLim,
-		    unsigned short **toP, const unsigned short *toLim)
-{
-    while (*fromP != fromLim && *toP != toLim)
-	*(*toP)++ = (unsigned char)*(*fromP)++;
-}
-
-#ifdef XML_NS
-
-static const struct normal_encoding latin1_encoding_ns = {
-	{ VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
-	    {
-#include "asciitab.h"
-#include "latin1tab.h"
-	    },
-	    STANDARD_VTABLE(sb_)
-	};
-
-#endif
-
-static const struct normal_encoding latin1_encoding = {
-	{ VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
-	    {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
-	    },
-	    STANDARD_VTABLE(sb_)
-	};
-
-static
-void ascii_toUtf8(const ENCODING *enc,
-		  const char **fromP, const char *fromLim,
-		  char **toP, const char *toLim)
-{
-    while (*fromP != fromLim && *toP != toLim)
-	*(*toP)++ = *(*fromP)++;
-}
-
-#ifdef XML_NS
-
-static const struct normal_encoding ascii_encoding_ns = {
-	{ VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
-	    {
-#include "asciitab.h"
-		/* BT_NONXML == 0 */
-	    },
-	    STANDARD_VTABLE(sb_)
-	};
-
-#endif
-
-static const struct normal_encoding ascii_encoding = {
-	{ VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
-	    {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-		/* BT_NONXML == 0 */
-	    },
-	    STANDARD_VTABLE(sb_)
-	};
-
-static int unicode_byte_type(char hi, char lo)
-{
-    switch ((unsigned char)hi) {
-case 0xD8: case 0xD9: case 0xDA: case 0xDB:
-	return BT_LEAD4;
-case 0xDC: case 0xDD: case 0xDE: case 0xDF:
-	return BT_TRAIL;
-    case 0xFF:
-	switch ((unsigned char)lo) {
-	case 0xFF:
-	case 0xFE:
-	    return BT_NONXML;
-	}
-	break;
-    }
-    return BT_NONASCII;
-}
-
-#define DEFINE_UTF16_TO_UTF8(E) \
-static \
-void E ## toUtf8(const ENCODING *enc, \
-	 const char **fromP, const char *fromLim, \
-	 char **toP, const char *toLim) \
-{ \
-  const char *from; \
-  for (from = *fromP; from != fromLim; from += 2) { \
-    int plane; \
-    unsigned char lo2; \
-    unsigned char lo = GET_LO(from); \
-    unsigned char hi = GET_HI(from); \
-    switch (hi) { \
-    case 0: \
-      if (lo < 0x80) { \
-	if (*toP == toLim) { \
-	  *fromP = from; \
-      return; \
-	} \
-	*(*toP)++ = lo; \
-	break; \
-      } \
-      /* fall through */ \
-    case 0x1: case 0x2: case 0x3: \
-    case 0x4: case 0x5: case 0x6: case 0x7: \
-      if (toLim -  *toP < 2) { \
-	*fromP = from; \
-    return; \
-      } \
-      *(*toP)++ = ((lo >> 6) | (hi << 2) |  UTF8_cval2); \
-      *(*toP)++ = ((lo & 0x3f) | 0x80); \
-      break; \
-    default: \
-      if (toLim -  *toP < 3)  { \
-	*fromP = from; \
-    return; \
-      } \
-      /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
-      *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
-      *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
-      *(*toP)++ = ((lo & 0x3f) | 0x80); \
-      break; \
-    case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
-      if (toLim -  *toP < 4) { \
-    *fromP = from; \
-    return; \
-      } \
-      plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
-      *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
-      *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
-      from += 2; \
-      lo2 = GET_LO(from); \
-      *(*toP)++ = (((lo & 0x3) << 4) \
-	       | ((GET_HI(from) & 0x3) << 2) \
-	   | (lo2 >> 6) \
-	   | 0x80); \
-      *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
-      break; \
-    } \
-  } \
-  *fromP = from; \
-}
-
-#define DEFINE_UTF16_TO_UTF16(E) \
-static \
-void E ## toUtf16(const ENCODING *enc, \
-	  const char **fromP, const char *fromLim, \
-	  unsigned short **toP, const unsigned short *toLim) \
-{ \
-  /* Avoid copying first half only of surrogate */ \
-  if (fromLim - *fromP > ((toLim - *toP) << 1) \
-      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \
-    fromLim -= 2; \
-  for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \
-    *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
-}
-
-#define SET2(ptr, ch) \
-  (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
-#define GET_LO(ptr) ((unsigned char)(ptr)[0])
-#define GET_HI(ptr) ((unsigned char)(ptr)[1])
-
-DEFINE_UTF16_TO_UTF8(little2_)
-DEFINE_UTF16_TO_UTF16(little2_)
-
-#undef SET2
-#undef GET_LO
-#undef GET_HI
-
-#define SET2(ptr, ch) \
-  (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
-#define GET_LO(ptr) ((unsigned char)(ptr)[1])
-#define GET_HI(ptr) ((unsigned char)(ptr)[0])
-
-DEFINE_UTF16_TO_UTF8(big2_)
-DEFINE_UTF16_TO_UTF16(big2_)
-
-#undef SET2
-#undef GET_LO
-#undef GET_HI
-
-#define LITTLE2_BYTE_TYPE(enc, p) \
- ((p)[1] == 0 \
-  ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
-  : unicode_byte_type((p)[1], (p)[0]))
-#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)
-#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)
-#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \
-  UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
-#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
-  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
-
-#ifdef XML_MIN_SIZE
-
-static
-int little2_byteType(const ENCODING *enc, const char *p)
-{
-    return LITTLE2_BYTE_TYPE(enc, p);
-}
-
-static
-int little2_byteToAscii(const ENCODING *enc, const char *p)
-{
-    return LITTLE2_BYTE_TO_ASCII(enc, p);
-}
-
-static
-int little2_charMatches(const ENCODING *enc, const char *p, int c)
-{
-    return LITTLE2_CHAR_MATCHES(enc, p, c);
-}
-
-static
-int little2_isNameMin(const ENCODING *enc, const char *p)
-{
-    return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
-}
-
-static
-int little2_isNmstrtMin(const ENCODING *enc, const char *p)
-{
-    return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);
-}
-
-#undef VTABLE
-#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
-
-#else /* not XML_MIN_SIZE */
-
-#undef PREFIX
-#define PREFIX(ident) little2_ ## ident
-#define MINBPC(enc) 2
-/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
-#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
-#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p)
-#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)
-#define IS_NAME_CHAR(enc, p, n) 0
-#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)
-#define IS_NMSTRT_CHAR(enc, p, n) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p)
-
-#include "xmltok_impl_c.h"
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
-
-#endif /* not XML_MIN_SIZE */
-
-#ifdef XML_NS
-
-static const struct normal_encoding little2_encoding_ns = {
-	    { VTABLE, 2, 0,
-#if XML_BYTE_ORDER == 12
-		1
-#else
-0
-#endif
-	    },
-	    {
-#include "asciitab.h"
-#include "latin1tab.h"
-	    },
-	    STANDARD_VTABLE(little2_)
-	};
-
-#endif
-
-static const struct normal_encoding little2_encoding = {
-	    { VTABLE, 2, 0,
-#if XML_BYTE_ORDER == 12
-		1
-#else
-		0
-#endif
-	    },
-	    {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
-	    },
-	    STANDARD_VTABLE(little2_)
-	};
-
-#if XML_BYTE_ORDER != 21
-
-#ifdef XML_NS
-
-static const struct normal_encoding internal_little2_encoding_ns = {
-	{ VTABLE, 2, 0, 1 },
-	    {
-#include "iasciitab.h"
-#include "latin1tab.h"
-	    },
-	    STANDARD_VTABLE(little2_)
-	};
-
-#endif
-
-static const struct normal_encoding internal_little2_encoding = {
-	{ VTABLE, 2, 0, 1 },
-	    {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
-	    },
-	    STANDARD_VTABLE(little2_)
-	};
-
-#endif
-
-
-#define BIG2_BYTE_TYPE(enc, p) \
- ((p)[0] == 0 \
-  ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
-  : unicode_byte_type((p)[0], (p)[1]))
-#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
-#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
-#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \
-  UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
-#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
-  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
-
-#ifdef XML_MIN_SIZE
-
-static
-int big2_byteType(const ENCODING *enc, const char *p)
-{
-    return BIG2_BYTE_TYPE(enc, p);
-}
-
-static
-int big2_byteToAscii(const ENCODING *enc, const char *p)
-{
-    return BIG2_BYTE_TO_ASCII(enc, p);
-}
-
-static
-int big2_charMatches(const ENCODING *enc, const char *p, int c)
-{
-    return BIG2_CHAR_MATCHES(enc, p, c);
-}
-
-static
-int big2_isNameMin(const ENCODING *enc, const char *p)
-{
-    return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
-}
-
-static
-int big2_isNmstrtMin(const ENCODING *enc, const char *p)
-{
-    return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);
-}
-
-#undef VTABLE
-#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
-
-#else /* not XML_MIN_SIZE */
-
-#undef PREFIX
-#define PREFIX(ident) big2_ ## ident
-#define MINBPC(enc) 2
-/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
-#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
-#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p)
-#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)
-#define IS_NAME_CHAR(enc, p, n) 0
-#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)
-#define IS_NMSTRT_CHAR(enc, p, n) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p)
-
-#include "xmltok_impl_c.h"
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
-
-#endif /* not XML_MIN_SIZE */
-
-#ifdef XML_NS
-
-static const struct normal_encoding big2_encoding_ns = {
-	    { VTABLE, 2, 0,
-#if XML_BYTE_ORDER == 21
-		1
-#else
-0
-#endif
-	    },
-	    {
-#include "asciitab.h"
-#include "latin1tab.h"
-	    },
-	    STANDARD_VTABLE(big2_)
-	};
-
-#endif
-
-static const struct normal_encoding big2_encoding = {
-	    { VTABLE, 2, 0,
-#if XML_BYTE_ORDER == 21
-		1
-#else
-		0
-#endif
-	    },
-	    {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
-	    },
-	    STANDARD_VTABLE(big2_)
-	};
-
-#if XML_BYTE_ORDER != 12
-
-#ifdef XML_NS
-
-static const struct normal_encoding internal_big2_encoding_ns = {
-	{ VTABLE, 2, 0, 1 },
-	    {
-#include "iasciitab.h"
-#include "latin1tab.h"
-	    },
-	    STANDARD_VTABLE(big2_)
-	};
-
-#endif
-
-static const struct normal_encoding internal_big2_encoding = {
-	{ VTABLE, 2, 0, 1 },
-	    {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
-	    },
-	    STANDARD_VTABLE(big2_)
-	};
-
-#endif
-
-#undef PREFIX
-
-static
-int streqci(const char *s1, const char *s2)
-{
-    for (;;) {
-	char c1 = *s1++;
-	char c2 = *s2++;
-	if ('a' <= c1 && c1 <= 'z')
-	    c1 += 'A' - 'a';
-	if ('a' <= c2 && c2 <= 'z')
-	    c2 += 'A' - 'a';
-	if (c1 != c2)
-	    return 0;
-	if (!c1)
-	    break;
-    }
-    return 1;
-}
-
-static
-void initUpdatePosition(const ENCODING *enc, const char *ptr,
-			const char *end, POSITION *pos)
-{
-    normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
-}
-
-static
-int toAscii(const ENCODING *enc, const char *ptr, const char *end)
-{
-    char buf[1];
-    char *p = buf;
-    XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
-    if (p == buf)
-	return -1;
-    else
-	return buf[0];
-}
-
-static
-int isSpace(int c)
-{
-    switch (c) {
-    case 0x20:
-    case 0xD:
-    case 0xA:
-    case 0x9:
-	return 1;
-    }
-    return 0;
-}
-
-/* Return 1 if there's just optional white space
-or there's an S followed by name=val. */
-static
-int parsePseudoAttribute(const ENCODING *enc,
-			 const char *ptr,
-			 const char *end,
-			 const char **namePtr,
-			 const char **valPtr,
-			 const char **nextTokPtr)
-{
-    int c;
-    char open;
-    if (ptr == end) {
-	*namePtr = 0;
-	return 1;
-    }
-    if (!isSpace(toAscii(enc, ptr, end))) {
-	*nextTokPtr = ptr;
-	return 0;
-    }
-    do {
-	ptr += enc->minBytesPerChar;
-    } while (isSpace(toAscii(enc, ptr, end)));
-    if (ptr == end) {
-	*namePtr = 0;
-	return 1;
-    }
-    *namePtr = ptr;
-    for (;;) {
-	c = toAscii(enc, ptr, end);
-	if (c == -1) {
-	    *nextTokPtr = ptr;
-	    return 0;
-	}
-	if (c == '=')
-	    break;
-	if (isSpace(c)) {
-	    do {
-		ptr += enc->minBytesPerChar;
-	    } while (isSpace(c = toAscii(enc, ptr, end)));
-	    if (c != '=') {
-		*nextTokPtr = ptr;
-		return 0;
-	    }
-	    break;
-	}
-	ptr += enc->minBytesPerChar;
-    }
-    if (ptr == *namePtr) {
-	*nextTokPtr = ptr;
-	return 0;
-    }
-    ptr += enc->minBytesPerChar;
-    c = toAscii(enc, ptr, end);
-    while (isSpace(c)) {
-	ptr += enc->minBytesPerChar;
-	c = toAscii(enc, ptr, end);
-    }
-    if (c != '"' && c != '\'') {
-	*nextTokPtr = ptr;
-	return 0;
-    }
-    open = c;
-    ptr += enc->minBytesPerChar;
-    *valPtr = ptr;
-    for (;; ptr += enc->minBytesPerChar) {
-	c = toAscii(enc, ptr, end);
-	if (c == open)
-	    break;
-	if (!('a' <= c && c <= 'z')
-		&& !('A' <= c && c <= 'Z')
-		&& !('0' <= c && c <= '9')
-		&& c != '.'
-		&& c != '-'
-		&& c != '_') {
-	    *nextTokPtr = ptr;
-	    return 0;
-	}
-    }
-    *nextTokPtr = ptr + enc->minBytesPerChar;
-    return 1;
-}
-
-static
-int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
-		   const char *,
-		   const char *),
-		   int isGeneralTextEntity,
-		   const ENCODING *enc,
-		   const char *ptr,
-		   const char *end,
-		   const char **badPtr,
-		   const char **versionPtr,
-		   const char **encodingName,
-		   const ENCODING **encoding,
-		   int *standalone)
-{
-    const char *val = 0;
-    const char *name = 0;
-    ptr += 5 * enc->minBytesPerChar;
-    end -= 2 * enc->minBytesPerChar;
-    if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr) || !name) {
-	*badPtr = ptr;
-	return 0;
-    }
-    if (!XmlNameMatchesAscii(enc, name, "version")) {
-	if (!isGeneralTextEntity) {
-	    *badPtr = name;
-	    return 0;
-	}
-    }
-    else {
-	if (versionPtr)
-	    *versionPtr = val;
-	if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr)) {
-	    *badPtr = ptr;
-	    return 0;
-	}
-	if (!name) {
-	    if (isGeneralTextEntity) {
-		/* a TextDecl must have an EncodingDecl */
-		*badPtr = ptr;
-		return 0;
-	    }
-	    return 1;
-	}
-    }
-    if (XmlNameMatchesAscii(enc, name, "encoding")) {
-	int c = toAscii(enc, val, end);
-	if (!('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z')) {
-	    *badPtr = val;
-	    return 0;
-	}
-	if (encodingName)
-	    *encodingName = val;
-	if (encoding)
-	    *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
-	if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr)) {
-	    *badPtr = ptr;
-	    return 0;
-	}
-	if (!name)
-	    return 1;
-    }
-    if (!XmlNameMatchesAscii(enc, name, "standalone") || isGeneralTextEntity) {
-	*badPtr = name;
-	return 0;
-    }
-    if (XmlNameMatchesAscii(enc, val, "yes")) {
-	if (standalone)
-	    *standalone = 1;
-    }
-    else if (XmlNameMatchesAscii(enc, val, "no")) {
-	if (standalone)
-	    *standalone = 0;
-    }
-    else {
-	*badPtr = val;
-	return 0;
-    }
-    while (isSpace(toAscii(enc, ptr, end)))
-	ptr += enc->minBytesPerChar;
-    if (ptr != end) {
-	*badPtr = ptr;
-	return 0;
-    }
-    return 1;
-}
-
-static
-int checkCharRefNumber(int result)
-{
-    switch (result >> 8) {
-case 0xD8: case 0xD9: case 0xDA: case 0xDB:
-case 0xDC: case 0xDD: case 0xDE: case 0xDF:
-	return -1;
-    case 0:
-	if (latin1_encoding.type[result] == BT_NONXML)
-	    return -1;
-	break;
-    case 0xFF:
-	if (result == 0xFFFE || result == 0xFFFF)
-	    return -1;
-	break;
-    }
-    return result;
-}
-
-int XmlUtf8Encode(int c, char *buf)
-{
-    enum {
-	/* minN is minimum legal resulting value for N byte sequence */
-	min2 = 0x80,
-	min3 = 0x800,
-	min4 = 0x10000
-    };
-
-    if (c < 0)
-	return 0;
-    if (c < min2) {
-	buf[0] = (c | UTF8_cval1);
-	return 1;
-    }
-    if (c < min3) {
-	buf[0] = ((c >> 6) | UTF8_cval2);
-	buf[1] = ((c & 0x3f) | 0x80);
-	return 2;
-    }
-    if (c < min4) {
-	buf[0] = ((c >> 12) | UTF8_cval3);
-	buf[1] = (((c >> 6) & 0x3f) | 0x80);
-	buf[2] = ((c & 0x3f) | 0x80);
-	return 3;
-    }
-    if (c < 0x110000) {
-	buf[0] = ((c >> 18) | UTF8_cval4);
-	buf[1] = (((c >> 12) & 0x3f) | 0x80);
-	buf[2] = (((c >> 6) & 0x3f) | 0x80);
-	buf[3] = ((c & 0x3f) | 0x80);
-	return 4;
-    }
-    return 0;
-}
-
-int XmlUtf16Encode(int charNum, unsigned short *buf)
-{
-    if (charNum < 0)
-	return 0;
-    if (charNum < 0x10000) {
-	buf[0] = charNum;
-	return 1;
-    }
-    if (charNum < 0x110000) {
-	charNum -= 0x10000;
-	buf[0] = (charNum >> 10) + 0xD800;
-	buf[1] = (charNum & 0x3FF) + 0xDC00;
-	return 2;
-    }
-    return 0;
-}
-
-struct unknown_encoding {
-    struct normal_encoding normal;
-    int (*convert)(void *userData, const char *p);
-    void *userData;
-    unsigned short utf16[256];
-    char utf8[256][4];
-};
-
-int XmlSizeOfUnknownEncoding()
-{
-    return sizeof(struct unknown_encoding);
-}
-
-static
-int unknown_isName(const ENCODING *enc, const char *p)
-{
-    int c = ((const struct unknown_encoding *)enc)
-	    ->convert(((const struct unknown_encoding *)enc)->userData, p);
-    if (c & ~0xFFFF)
-	return 0;
-    return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
-}
-
-static
-int unknown_isNmstrt(const ENCODING *enc, const char *p)
-{
-    int c = ((const struct unknown_encoding *)enc)
-	    ->convert(((const struct unknown_encoding *)enc)->userData, p);
-    if (c & ~0xFFFF)
-	return 0;
-    return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
-}
-
-static
-int unknown_isInvalid(const ENCODING *enc, const char *p)
-{
-    int c = ((const struct unknown_encoding *)enc)
-	    ->convert(((const struct unknown_encoding *)enc)->userData, p);
-    return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
-}
-
-static
-void unknown_toUtf8(const ENCODING *enc,
-		    const char **fromP, const char *fromLim,
-		    char **toP, const char *toLim)
-{
-    char buf[XML_UTF8_ENCODE_MAX];
-    for (;;) {
-	const char *utf8;
-	int n;
-	if (*fromP == fromLim)
-	    break;
-	utf8 = ((const struct unknown_encoding *)enc)->utf8[(unsigned char)**fromP];
-	n = *utf8++;
-	if (n == 0) {
-	    int c = ((const struct unknown_encoding *)enc)
-		    ->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
-	    n = XmlUtf8Encode(c, buf);
-	    if (n > toLim - *toP)
-		break;
-	    utf8 = buf;
-	    *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
-		      - (BT_LEAD2 - 2);
-	}
-	else {
-	    if (n > toLim - *toP)
-		break;
-	    (*fromP)++;
-	}
-	do {
-	    *(*toP)++ = *utf8++;
-	} while (--n != 0);
-    }
-}
-
-static
-void unknown_toUtf16(const ENCODING *enc,
-		     const char **fromP, const char *fromLim,
-		     unsigned short **toP, const unsigned short *toLim)
-{
-    while (*fromP != fromLim && *toP != toLim) {
-	unsigned short c
-	= ((const struct unknown_encoding *)enc)->utf16[(unsigned char)**fromP];
-	if (c == 0) {
-	    c = (unsigned short)((const struct unknown_encoding *)enc)
-		->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
-	    *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
-		      - (BT_LEAD2 - 2);
-	}
-	else
-	    (*fromP)++;
-	*(*toP)++ = c;
-    }
-}
-
-ENCODING *
-XmlInitUnknownEncoding(void *mem,
-		       int *table,
-		       int (*convert)(void *userData, const char *p),
-		       void *userData)
-{
-    int i;
-    struct unknown_encoding *e = mem;
-    for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
-	((char *)mem)[i] = ((char *)&latin1_encoding)[i];
-    for (i = 0; i < 128; i++)
-	if (latin1_encoding.type[i] != BT_OTHER
-		&& latin1_encoding.type[i] != BT_NONXML
-		&& table[i] != i)
-	    return 0;
-    for (i = 0; i < 256; i++) {
-	int c = table[i];
-	if (c == -1) {
-	    e->normal.type[i] = BT_MALFORM;
-	    /* This shouldn't really get used. */
-	    e->utf16[i] = 0xFFFF;
-	    e->utf8[i][0] = 1;
-	    e->utf8[i][1] = 0;
-	}
-	else if (c < 0) {
-	    if (c < -4)
-		return 0;
-	    e->normal.type[i] = BT_LEAD2 - (c + 2);
-	    e->utf8[i][0] = 0;
-	    e->utf16[i] = 0;
-	}
-	else if (c < 0x80) {
-	    if (latin1_encoding.type[c] != BT_OTHER
-		    && latin1_encoding.type[c] != BT_NONXML
-		    && c != i)
-		return 0;
-	    e->normal.type[i] = latin1_encoding.type[c];
-	    e->utf8[i][0] = 1;
-	    e->utf8[i][1] = (char)c;
-	    e->utf16[i] = c == 0 ? 0xFFFF : c;
-	}
-	else if (checkCharRefNumber(c) < 0) {
-	    e->normal.type[i] = BT_NONXML;
-	    /* This shouldn't really get used. */
-	    e->utf16[i] = 0xFFFF;
-	    e->utf8[i][0] = 1;
-	    e->utf8[i][1] = 0;
-	}
-	else {
-	    if (c > 0xFFFF)
-		return 0;
-	    if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
-		e->normal.type[i] = BT_NMSTRT;
-	    else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
-		e->normal.type[i] = BT_NAME;
-	    else
-		e->normal.type[i] = BT_OTHER;
-	    e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
-	    e->utf16[i] = c;
-	}
-    }
-    e->userData = userData;
-    e->convert = convert;
-    if (convert) {
-	e->normal.isName2 = unknown_isName;
-	e->normal.isName3 = unknown_isName;
-	e->normal.isName4 = unknown_isName;
-	e->normal.isNmstrt2 = unknown_isNmstrt;
-	e->normal.isNmstrt3 = unknown_isNmstrt;
-	e->normal.isNmstrt4 = unknown_isNmstrt;
-	e->normal.isInvalid2 = unknown_isInvalid;
-	e->normal.isInvalid3 = unknown_isInvalid;
-	e->normal.isInvalid4 = unknown_isInvalid;
-    }
-    e->normal.enc.utf8Convert = unknown_toUtf8;
-    e->normal.enc.utf16Convert = unknown_toUtf16;
-    return &(e->normal.enc);
-}
-
-/* If this enumeration is changed, getEncodingIndex and encodings
-must also be changed. */
-enum {
-    UNKNOWN_ENC = -1,
-    ISO_8859_1_ENC = 0,
-    US_ASCII_ENC,
-    UTF_8_ENC,
-    UTF_16_ENC,
-    UTF_16BE_ENC,
-    UTF_16LE_ENC,
-    /* must match encodingNames up to here */
-    NO_ENC
-};
-
-static
-int getEncodingIndex(const char *name)
-{
-    static const char *encodingNames[] = {
-	"ISO-8859-1",
-	"US-ASCII",
-	"UTF-8",
-	"UTF-16",
-	"UTF-16BE"
-	"UTF-16LE",
-    };
-    int i;
-    if (name == 0)
-	return NO_ENC;
-    for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++)
-	if (streqci(name, encodingNames[i]))
-	    return i;
-    return UNKNOWN_ENC;
-}
-
-/* For binary compatibility, we store the index of the encoding specified
-at initialization in the isUtf16 member. */
-
-#define INIT_ENC_INDEX(enc) ((enc)->initEnc.isUtf16)
-
-/* This is what detects the encoding.
-encodingTable maps from encoding indices to encodings;
-INIT_ENC_INDEX(enc) is the index of the external (protocol) specified encoding;
-state is XML_CONTENT_STATE if we're parsing an external text entity,
-and XML_PROLOG_STATE otherwise.
-*/
-
-
-static
-int initScan(const ENCODING **encodingTable,
-	     const INIT_ENCODING *enc,
-	     int state,
-	     const char *ptr,
-	     const char *end,
-	     const char **nextTokPtr)
-{
-    const ENCODING **encPtr;
-
-    if (ptr == end)
-	return XML_TOK_NONE;
-    encPtr = enc->encPtr;
-    if (ptr + 1 == end) {
-	/* only a single byte available for auto-detection */
-	/* a well-formed document entity must have more than one byte */
-	if (state != XML_CONTENT_STATE)
-	    return XML_TOK_PARTIAL;
-	/* so we're parsing an external text entity... */
-	/* if UTF-16 was externally specified, then we need at least 2 bytes */
-	switch (INIT_ENC_INDEX(enc)) {
-	case UTF_16_ENC:
-	case UTF_16LE_ENC:
-	case UTF_16BE_ENC:
-	    return XML_TOK_PARTIAL;
-	}
-	switch ((unsigned char)*ptr) {
-	case 0xFE:
-	case 0xFF:
-	case 0xEF: /* possibly first byte of UTF-8 BOM */
-	    if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
-		    && state == XML_CONTENT_STATE)
-		break;
-	    /* fall through */
-	case 0x00:
-	case 0x3C:
-	    return XML_TOK_PARTIAL;
-	}
-    }
-    else {
-	switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
-	case 0xFEFF:
-	    if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
-		    && state == XML_CONTENT_STATE)
-		break;
-	    *nextTokPtr = ptr + 2;
-	    *encPtr = encodingTable[UTF_16BE_ENC];
-	    return XML_TOK_BOM;
-	    /* 00 3C is handled in the default case */
-	case 0x3C00:
-	    if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
-		    || INIT_ENC_INDEX(enc) == UTF_16_ENC)
-		    && state == XML_CONTENT_STATE)
-		break;
-	    *encPtr = encodingTable[UTF_16LE_ENC];
-	    return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
-	case 0xFFFE:
-	    if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
-		    && state == XML_CONTENT_STATE)
-		break;
-	    *nextTokPtr = ptr + 2;
-	    *encPtr = encodingTable[UTF_16LE_ENC];
-	    return XML_TOK_BOM;
-	case 0xEFBB:
-	    /* Maybe a UTF-8 BOM (EF BB BF) */
-	    /* If there's an explicitly specified (external) encoding
-	       of ISO-8859-1 or some flavour of UTF-16
-	       and this is an external text entity,
-	    don't look for the BOM,
-	       because it might be a legal data. */
-	    if (state == XML_CONTENT_STATE) {
-		int e = INIT_ENC_INDEX(enc);
-		if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC || e == UTF_16_ENC)
-		    break;
-	    }
-	    if (ptr + 2 == end)
-		return XML_TOK_PARTIAL;
-	    if ((unsigned char)ptr[2] == 0xBF) {
-		*encPtr = encodingTable[UTF_8_ENC];
-		return XML_TOK_BOM;
-	    }
-	    break;
-	default:
-	    if (ptr[0] == '\0') {
-		/* 0 isn't a legal data character. Furthermore a document entity can only
-		   start with ASCII characters.  So the only way this can fail to be big-endian
-		   UTF-16 if it it's an external parsed general entity that's labelled as
-		   UTF-16LE. */
-		if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
-		    break;
-		*encPtr = encodingTable[UTF_16BE_ENC];
-		return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
-	    }
-	    else if (ptr[1] == '\0') {
-		/* We could recover here in the case:
-		    - parsing an external entity
-		    - second byte is 0
-		    - no externally specified encoding
-		    - no encoding declaration
-		   by assuming UTF-16LE.  But we don't, because this would mean when
-		   presented just with a single byte, we couldn't reliably determine
-		   whether we needed further bytes. */
-		if (state == XML_CONTENT_STATE)
-		    break;
-		*encPtr = encodingTable[UTF_16LE_ENC];
-		return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
-	    }
-	    break;
-	}
-    }
-    *encPtr = encodingTable[(int)INIT_ENC_INDEX(enc)];
-    return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
-}
-
-
-#define NS(x) x
-#define ns(x) x
-#include "xmltok_ns_c.h"
-#undef NS
-#undef ns
-
-#ifdef XML_NS
-
-#define NS(x) x ## NS
-#define ns(x) x ## _ns
-
-#include "xmltok_ns_c.h"
-
-#undef NS
-#undef ns
-
-ENCODING *
-XmlInitUnknownEncodingNS(void *mem,
-			 int *table,
-			 int (*convert)(void *userData, const char *p),
-			 void *userData)
-{
-    ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
-    if (enc)
-	((struct normal_encoding *)enc)->type[':'] = BT_COLON;
-    return enc;
-}
-
-#endif /* XML_NS */
--- a/mcabber/libjabber/xmltok.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,307 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-#ifndef XmlTok_INCLUDED
-#define XmlTok_INCLUDED 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef XMLTOKAPI
-#define XMLTOKAPI /* as nothing */
-#endif
-
-/* The following token may be returned by XmlContentTok */
-#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be start of
-                                    illegal ]]> sequence */
-/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
-#define XML_TOK_NONE -4    /* The string to be scanned is empty */
-#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
-                                  might be part of CRLF sequence */ 
-#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
-#define XML_TOK_PARTIAL -1 /* only part of a token */
-#define XML_TOK_INVALID 0
-
-/* The following tokens are returned by XmlContentTok; some are also
-  returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok */
-
-#define XML_TOK_START_TAG_WITH_ATTS 1
-#define XML_TOK_START_TAG_NO_ATTS 2
-#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
-#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
-#define XML_TOK_END_TAG 5
-#define XML_TOK_DATA_CHARS 6
-#define XML_TOK_DATA_NEWLINE 7
-#define XML_TOK_CDATA_SECT_OPEN 8
-#define XML_TOK_ENTITY_REF 9
-#define XML_TOK_CHAR_REF 10     /* numeric character reference */
-
-/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
-#define XML_TOK_PI 11      /* processing instruction */
-#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
-#define XML_TOK_COMMENT 13
-#define XML_TOK_BOM 14     /* Byte order mark */
-
-/* The following tokens are returned only by XmlPrologTok */
-#define XML_TOK_PROLOG_S 15
-#define XML_TOK_DECL_OPEN 16 /* <!foo */
-#define XML_TOK_DECL_CLOSE 17 /* > */
-#define XML_TOK_NAME 18
-#define XML_TOK_NMTOKEN 19
-#define XML_TOK_POUND_NAME 20 /* #name */
-#define XML_TOK_OR 21 /* | */
-#define XML_TOK_PERCENT 22
-#define XML_TOK_OPEN_PAREN 23
-#define XML_TOK_CLOSE_PAREN 24
-#define XML_TOK_OPEN_BRACKET 25
-#define XML_TOK_CLOSE_BRACKET 26
-#define XML_TOK_LITERAL 27
-#define XML_TOK_PARAM_ENTITY_REF 28
-#define XML_TOK_INSTANCE_START 29
-
-/* The following occur only in element type declarations */
-#define XML_TOK_NAME_QUESTION 30 /* name? */
-#define XML_TOK_NAME_ASTERISK 31 /* name* */
-#define XML_TOK_NAME_PLUS 32 /* name+ */
-#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
-#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
-#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
-#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
-#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
-#define XML_TOK_COMMA 38
-
-/* The following token is returned only by XmlAttributeValueTok */
-#define XML_TOK_ATTRIBUTE_VALUE_S 39
-
-/* The following token is returned only by XmlCdataSectionTok */
-#define XML_TOK_CDATA_SECT_CLOSE 40
-
-/* With namespace processing this is returned by XmlPrologTok
-   for a name with a colon. */
-#define XML_TOK_PREFIXED_NAME 41
-
-#define XML_N_STATES 3
-#define XML_PROLOG_STATE 0
-#define XML_CONTENT_STATE 1
-#define XML_CDATA_SECTION_STATE 2
-
-#define XML_N_LITERAL_TYPES 2
-#define XML_ATTRIBUTE_VALUE_LITERAL 0
-#define XML_ENTITY_VALUE_LITERAL 1
-
-/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
-#define XML_UTF8_ENCODE_MAX 4
-/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
-#define XML_UTF16_ENCODE_MAX 2
-
-typedef struct position {
-  /* first line and first column are 0 not 1 */
-  unsigned long lineNumber;
-  unsigned long columnNumber;
-} POSITION;
-
-typedef struct {
-  const char *name;
-  const char *valuePtr;
-  const char *valueEnd;
-  char normalized;
-} ATTRIBUTE;
-
-struct encoding;
-typedef struct encoding ENCODING;
-
-struct encoding {
-  int (*scanners[XML_N_STATES])(const ENCODING *,
-			        const char *,
-			        const char *,
-			        const char **);
-  int (*literalScanners[XML_N_LITERAL_TYPES])(const ENCODING *,
-					      const char *,
-					      const char *,
-					      const char **);
-  int (*sameName)(const ENCODING *,
-	          const char *, const char *);
-  int (*nameMatchesAscii)(const ENCODING *,
-			  const char *, const char *);
-  int (*nameLength)(const ENCODING *, const char *);
-  const char *(*skipS)(const ENCODING *, const char *);
-  int (*getAtts)(const ENCODING *enc, const char *ptr,
-	         int attsMax, ATTRIBUTE *atts);
-  int (*charRefNumber)(const ENCODING *enc, const char *ptr);
-  int (*predefinedEntityName)(const ENCODING *, const char *, const char *);
-  void (*updatePosition)(const ENCODING *,
-			 const char *ptr,
-			 const char *end,
-			 POSITION *);
-  int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
-		    const char **badPtr);
-  void (*utf8Convert)(const ENCODING *enc,
-		      const char **fromP,
-		      const char *fromLim,
-		      char **toP,
-		      const char *toLim);
-  void (*utf16Convert)(const ENCODING *enc,
-		       const char **fromP,
-		       const char *fromLim,
-		       unsigned short **toP,
-		       const unsigned short *toLim);
-  int minBytesPerChar;
-  char isUtf8;
-  char isUtf16;
-};
-
-/*
-Scan the string starting at ptr until the end of the next complete token,
-but do not scan past eptr.  Return an integer giving the type of token.
-
-Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
-
-Return XML_TOK_PARTIAL when the string does not contain a complete token;
-nextTokPtr will not be set.
-
-Return XML_TOK_INVALID when the string does not start a valid token; nextTokPtr
-will be set to point to the character which made the token invalid.
-
-Otherwise the string starts with a valid token; nextTokPtr will be set to point
-to the character following the end of that token.
-
-Each data character counts as a single token, but adjacent data characters
-may be returned together.  Similarly for characters in the prolog outside
-literals, comments and processing instructions.
-*/
-
-
-#define XmlTok(enc, state, ptr, end, nextTokPtr) \
-  (((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
-
-#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
-   XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
-
-#define XmlContentTok(enc, ptr, end, nextTokPtr) \
-   XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
-
-#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
-   XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
-
-/* This is used for performing a 2nd-level tokenization on
-the content of a literal that has already been returned by XmlTok. */ 
-
-#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
-  (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
-
-#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
-   XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
-
-#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
-   XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
-
-#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
-
-#define XmlNameMatchesAscii(enc, ptr1, ptr2) \
-  (((enc)->nameMatchesAscii)(enc, ptr1, ptr2))
-
-#define XmlNameLength(enc, ptr) \
-  (((enc)->nameLength)(enc, ptr))
-
-#define XmlSkipS(enc, ptr) \
-  (((enc)->skipS)(enc, ptr))
-
-#define XmlGetAttributes(enc, ptr, attsMax, atts) \
-  (((enc)->getAtts)(enc, ptr, attsMax, atts))
-
-#define XmlCharRefNumber(enc, ptr) \
-  (((enc)->charRefNumber)(enc, ptr))
-
-#define XmlPredefinedEntityName(enc, ptr, end) \
-  (((enc)->predefinedEntityName)(enc, ptr, end))
-
-#define XmlUpdatePosition(enc, ptr, end, pos) \
-  (((enc)->updatePosition)(enc, ptr, end, pos))
-
-#define XmlIsPublicId(enc, ptr, end, badPtr) \
-  (((enc)->isPublicId)(enc, ptr, end, badPtr))
-
-#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
-  (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
-
-#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
-  (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
-
-typedef struct {
-  ENCODING initEnc;
-  const ENCODING **encPtr;
-} INIT_ENCODING;
-
-int XMLTOKAPI XmlParseXmlDecl(int isGeneralTextEntity,
-			      const ENCODING *enc,
-			      const char *ptr,
-	  		      const char *end,
-			      const char **badPtr,
-			      const char **versionPtr,
-			      const char **encodingNamePtr,
-			      const ENCODING **namedEncodingPtr,
-			      int *standalonePtr);
-
-int XMLTOKAPI XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
-const ENCODING XMLTOKAPI *XmlGetUtf8InternalEncoding();
-const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncoding();
-int XMLTOKAPI XmlUtf8Encode(int charNumber, char *buf);
-int XMLTOKAPI XmlUtf16Encode(int charNumber, unsigned short *buf);
-
-int XMLTOKAPI XmlSizeOfUnknownEncoding();
-ENCODING XMLTOKAPI *
-XmlInitUnknownEncoding(void *mem,
-		       int *table,
-		       int (*conv)(void *userData, const char *p),
-		       void *userData);
-
-int XMLTOKAPI XmlParseXmlDeclNS(int isGeneralTextEntity,
-			        const ENCODING *enc,
-			        const char *ptr,
-	  		        const char *end,
-			        const char **badPtr,
-			        const char **versionPtr,
-			        const char **encodingNamePtr,
-			        const ENCODING **namedEncodingPtr,
-			        int *standalonePtr);
-int XMLTOKAPI XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
-const ENCODING XMLTOKAPI *XmlGetUtf8InternalEncodingNS();
-const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncodingNS();
-ENCODING XMLTOKAPI *
-XmlInitUnknownEncodingNS(void *mem,
-		         int *table,
-		         int (*conv)(void *userData, const char *p),
-		         void *userData);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not XmlTok_INCLUDED */
--- a/mcabber/libjabber/xmltok_impl.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-enum {
-  BT_NONXML,
-  BT_MALFORM,
-  BT_LT,
-  BT_AMP,
-  BT_RSQB,
-  BT_LEAD2,
-  BT_LEAD3,
-  BT_LEAD4,
-  BT_TRAIL,
-  BT_CR,
-  BT_LF,
-  BT_GT,
-  BT_QUOT,
-  BT_APOS,
-  BT_EQUALS,
-  BT_QUEST,
-  BT_EXCL,
-  BT_SOL,
-  BT_SEMI,
-  BT_NUM,
-  BT_LSQB,
-  BT_S,
-  BT_NMSTRT,
-  BT_COLON,
-  BT_HEX,
-  BT_DIGIT,
-  BT_NAME,
-  BT_MINUS,
-  BT_OTHER, /* known not to be a name or name start character */
-  BT_NONASCII, /* might be a name or name start character */
-  BT_PERCNT,
-  BT_LPAR,
-  BT_RPAR,
-  BT_AST,
-  BT_PLUS,
-  BT_COMMA,
-  BT_VERBAR
-};
-
-#include <stddef.h>
--- a/mcabber/libjabber/xmltok_impl_c.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1746 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-#ifndef IS_INVALID_CHAR
-#define IS_INVALID_CHAR(enc, ptr, n) (0)
-#endif
-
-#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
-    case BT_LEAD ## n: \
-      if (end - ptr < n) \
-    return XML_TOK_PARTIAL_CHAR; \
-      if (IS_INVALID_CHAR(enc, ptr, n)) { \
-        *(nextTokPtr) = (ptr); \
-        return XML_TOK_INVALID; \
-      } \
-      ptr += n; \
-      break;
-
-#define INVALID_CASES(ptr, nextTokPtr) \
-  INVALID_LEAD_CASE(2, ptr, nextTokPtr) \
-  INVALID_LEAD_CASE(3, ptr, nextTokPtr) \
-  INVALID_LEAD_CASE(4, ptr, nextTokPtr) \
-  case BT_NONXML: \
-  case BT_MALFORM: \
-  case BT_TRAIL: \
-    *(nextTokPtr) = (ptr); \
-    return XML_TOK_INVALID;
-
-#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \
-   case BT_LEAD ## n: \
-     if (end - ptr < n) \
-       return XML_TOK_PARTIAL_CHAR; \
-     if (!IS_NAME_CHAR(enc, ptr, n)) { \
-       *nextTokPtr = ptr; \
-       return XML_TOK_INVALID; \
-     } \
-     ptr += n; \
-     break;
-
-#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \
-  case BT_NONASCII: \
-    if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \
-      *nextTokPtr = ptr; \
-      return XML_TOK_INVALID; \
-    } \
-  case BT_NMSTRT: \
-  case BT_HEX: \
-  case BT_DIGIT: \
-  case BT_NAME: \
-  case BT_MINUS: \
-    ptr += MINBPC(enc); \
-    break; \
-  CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \
-  CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \
-  CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
-
-#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
-   case BT_LEAD ## n: \
-     if (end - ptr < n) \
-       return XML_TOK_PARTIAL_CHAR; \
-     if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
-       *nextTokPtr = ptr; \
-       return XML_TOK_INVALID; \
-     } \
-     ptr += n; \
-     break;
-
-#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
-  case BT_NONASCII: \
-    if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
-      *nextTokPtr = ptr; \
-      return XML_TOK_INVALID; \
-    } \
-  case BT_NMSTRT: \
-  case BT_HEX: \
-    ptr += MINBPC(enc); \
-    break; \
-  CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
-  CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
-  CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
-
-#ifndef PREFIX
-#define PREFIX(ident) ident
-#endif
-
-/* ptr points to character following "<!-" */
-
-static
-int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end,
-                        const char **nextTokPtr)
-{
-    if (ptr != end) {
-        if (!CHAR_MATCHES(enc, ptr, '-')) {
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-        ptr += MINBPC(enc);
-        while (ptr != end) {
-            switch (BYTE_TYPE(enc, ptr)) {
-                INVALID_CASES(ptr, nextTokPtr)
-            case BT_MINUS:
-                if ((ptr += MINBPC(enc)) == end)
-                    return XML_TOK_PARTIAL;
-                if (CHAR_MATCHES(enc, ptr, '-')) {
-                    if ((ptr += MINBPC(enc)) == end)
-                        return XML_TOK_PARTIAL;
-                    if (!CHAR_MATCHES(enc, ptr, '>')) {
-                        *nextTokPtr = ptr;
-                        return XML_TOK_INVALID;
-                    }
-                    *nextTokPtr = ptr + MINBPC(enc);
-                    return XML_TOK_COMMENT;
-                }
-                break;
-            default:
-                ptr += MINBPC(enc);
-                break;
-            }
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "<!" */
-
-static
-int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end,
-                     const char **nextTokPtr)
-{
-    if (ptr == end)
-        return XML_TOK_PARTIAL;
-    switch (BYTE_TYPE(enc, ptr)) {
-    case BT_MINUS:
-        return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-    case BT_LSQB:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_COND_SECT_OPEN;
-    case BT_NMSTRT:
-    case BT_HEX:
-        ptr += MINBPC(enc);
-        break;
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-        case BT_PERCNT:
-            if (ptr + MINBPC(enc) == end)
-                return XML_TOK_PARTIAL;
-            /* don't allow <!ENTITY% foo "whatever"> */
-            switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
-case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            /* fall through */
-case BT_S: case BT_CR: case BT_LF:
-            *nextTokPtr = ptr;
-            return XML_TOK_DECL_OPEN;
-        case BT_NMSTRT:
-        case BT_HEX:
-            ptr += MINBPC(enc);
-            break;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-static
-int PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end, int *tokPtr)
-{
-    int upper = 0;
-    *tokPtr = XML_TOK_PI;
-    if (end - ptr != MINBPC(enc)*3)
-        return 1;
-    switch (BYTE_TO_ASCII(enc, ptr)) {
-    case 'x':
-        break;
-    case 'X':
-        upper = 1;
-        break;
-    default:
-        return 1;
-    }
-    ptr += MINBPC(enc);
-    switch (BYTE_TO_ASCII(enc, ptr)) {
-    case 'm':
-        break;
-    case 'M':
-        upper = 1;
-        break;
-    default:
-        return 1;
-    }
-    ptr += MINBPC(enc);
-    switch (BYTE_TO_ASCII(enc, ptr)) {
-    case 'l':
-        break;
-    case 'L':
-        upper = 1;
-        break;
-    default:
-        return 1;
-    }
-    if (upper)
-        return 0;
-    *tokPtr = XML_TOK_XML_DECL;
-    return 1;
-}
-
-/* ptr points to character following "<?" */
-
-static
-int PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end,
-                   const char **nextTokPtr)
-{
-    int tok;
-    const char *target = ptr;
-    if (ptr == end)
-        return XML_TOK_PARTIAL;
-    switch (BYTE_TYPE(enc, ptr)) {
-        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-case BT_S: case BT_CR: case BT_LF:
-            if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            ptr += MINBPC(enc);
-            while (ptr != end) {
-                switch (BYTE_TYPE(enc, ptr)) {
-                    INVALID_CASES(ptr, nextTokPtr)
-                case BT_QUEST:
-                    ptr += MINBPC(enc);
-                    if (ptr == end)
-                        return XML_TOK_PARTIAL;
-                    if (CHAR_MATCHES(enc, ptr, '>')) {
-                        *nextTokPtr = ptr + MINBPC(enc);
-                        return tok;
-                    }
-                    break;
-                default:
-                    ptr += MINBPC(enc);
-                    break;
-                }
-            }
-            return XML_TOK_PARTIAL;
-        case BT_QUEST:
-            if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            ptr += MINBPC(enc);
-            if (ptr == end)
-                return XML_TOK_PARTIAL;
-            if (CHAR_MATCHES(enc, ptr, '>')) {
-                *nextTokPtr = ptr + MINBPC(enc);
-                return tok;
-            }
-            /* fall through */
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-
-static
-int PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, const char *end,
-                             const char **nextTokPtr)
-{
-    int i;
-    /* CDATA[ */
-    if (end - ptr < 6 * MINBPC(enc))
-        return XML_TOK_PARTIAL;
-    for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
-        if (!CHAR_MATCHES(enc, ptr, "CDATA["[i])) {
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    *nextTokPtr = ptr;
-    return XML_TOK_CDATA_SECT_OPEN;
-}
-
-static
-int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
-                            const char **nextTokPtr)
-{
-    if (ptr == end)
-        return XML_TOK_NONE;
-    if (MINBPC(enc) > 1) {
-        size_t n = end - ptr;
-        if (n & (MINBPC(enc) - 1)) {
-            n &= ~(MINBPC(enc) - 1);
-            if (n == 0)
-                return XML_TOK_PARTIAL;
-            end = ptr + n;
-        }
-    }
-    switch (BYTE_TYPE(enc, ptr)) {
-    case BT_RSQB:
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_PARTIAL;
-        if (!CHAR_MATCHES(enc, ptr, ']'))
-            break;
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_PARTIAL;
-        if (!CHAR_MATCHES(enc, ptr, '>')) {
-            ptr -= MINBPC(enc);
-            break;
-        }
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_CDATA_SECT_CLOSE;
-    case BT_CR:
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_PARTIAL;
-        if (BYTE_TYPE(enc, ptr) == BT_LF)
-            ptr += MINBPC(enc);
-        *nextTokPtr = ptr;
-        return XML_TOK_DATA_NEWLINE;
-    case BT_LF:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_DATA_NEWLINE;
-        INVALID_CASES(ptr, nextTokPtr)
-    default:
-        ptr += MINBPC(enc);
-        break;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: \
-      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
-    *nextTokPtr = ptr; \
-    return XML_TOK_DATA_CHARS; \
-      } \
-      ptr += n; \
-      break;
-            LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-        case BT_NONXML:
-        case BT_MALFORM:
-        case BT_TRAIL:
-        case BT_CR:
-        case BT_LF:
-        case BT_RSQB:
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        default:
-            ptr += MINBPC(enc);
-            break;
-        }
-    }
-    *nextTokPtr = ptr;
-    return XML_TOK_DATA_CHARS;
-}
-
-/* ptr points to character following "</" */
-
-static
-int PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end,
-                       const char **nextTokPtr)
-{
-    if (ptr == end)
-        return XML_TOK_PARTIAL;
-    switch (BYTE_TYPE(enc, ptr)) {
-        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-case BT_S: case BT_CR: case BT_LF:
-            for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
-                switch (BYTE_TYPE(enc, ptr)) {
-        case BT_S: case BT_CR: case BT_LF:
-                    break;
-                case BT_GT:
-                    *nextTokPtr = ptr + MINBPC(enc);
-                    return XML_TOK_END_TAG;
-                default:
-                    *nextTokPtr = ptr;
-                    return XML_TOK_INVALID;
-                }
-            }
-            return XML_TOK_PARTIAL;
-#ifdef XML_NS
-        case BT_COLON:
-            /* no need to check qname syntax here, since end-tag must match exactly */
-            ptr += MINBPC(enc);
-            break;
-#endif
-        case BT_GT:
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_END_TAG;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "&#X" */
-
-static
-int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end,
-                           const char **nextTokPtr)
-{
-    if (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-        case BT_DIGIT:
-        case BT_HEX:
-            break;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-        for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
-            switch (BYTE_TYPE(enc, ptr)) {
-            case BT_DIGIT:
-            case BT_HEX:
-                break;
-            case BT_SEMI:
-                *nextTokPtr = ptr + MINBPC(enc);
-                return XML_TOK_CHAR_REF;
-            default:
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "&#" */
-
-static
-int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end,
-                        const char **nextTokPtr)
-{
-    if (ptr != end) {
-        if (CHAR_MATCHES(enc, ptr, 'x'))
-            return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-        switch (BYTE_TYPE(enc, ptr)) {
-        case BT_DIGIT:
-            break;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-        for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
-            switch (BYTE_TYPE(enc, ptr)) {
-            case BT_DIGIT:
-                break;
-            case BT_SEMI:
-                *nextTokPtr = ptr + MINBPC(enc);
-                return XML_TOK_CHAR_REF;
-            default:
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "&" */
-
-static
-int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
-                    const char **nextTokPtr)
-{
-    if (ptr == end)
-        return XML_TOK_PARTIAL;
-    switch (BYTE_TYPE(enc, ptr)) {
-        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-    case BT_NUM:
-        return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-        case BT_SEMI:
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_ENTITY_REF;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following first character of attribute name */
-
-static
-int PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
-                     const char **nextTokPtr)
-{
-#ifdef XML_NS
-    int hadColon = 0;
-#endif
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-#ifdef XML_NS
-        case BT_COLON:
-            if (hadColon) {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            hadColon = 1;
-            ptr += MINBPC(enc);
-            if (ptr == end)
-                return XML_TOK_PARTIAL;
-            switch (BYTE_TYPE(enc, ptr)) {
-                CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-            default:
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            break;
-#endif
-case BT_S: case BT_CR: case BT_LF:
-            for (;;) {
-                int t;
-
-                ptr += MINBPC(enc);
-                if (ptr == end)
-                    return XML_TOK_PARTIAL;
-                t = BYTE_TYPE(enc, ptr);
-                if (t == BT_EQUALS)
-                    break;
-                switch (t) {
-                case BT_S:
-                case BT_LF:
-                case BT_CR:
-                    break;
-                default:
-                    *nextTokPtr = ptr;
-                    return XML_TOK_INVALID;
-                }
-            }
-            /* fall through */
-        case BT_EQUALS:
-            {
-                int open;
-#ifdef XML_NS
-                hadColon = 0;
-#endif
-                for (;;) {
-
-                    ptr += MINBPC(enc);
-                    if (ptr == end)
-                        return XML_TOK_PARTIAL;
-                    open = BYTE_TYPE(enc, ptr);
-                    if (open == BT_QUOT || open == BT_APOS)
-                        break;
-                    switch (open) {
-                    case BT_S:
-                    case BT_LF:
-                    case BT_CR:
-                        break;
-                    default:
-                        *nextTokPtr = ptr;
-                        return XML_TOK_INVALID;
-                    }
-                }
-                ptr += MINBPC(enc);
-                /* in attribute value */
-                for (;;) {
-                    int t;
-                    if (ptr == end)
-                        return XML_TOK_PARTIAL;
-                    t = BYTE_TYPE(enc, ptr);
-                    if (t == open)
-                        break;
-                    switch (t) {
-                        INVALID_CASES(ptr, nextTokPtr)
-                    case BT_AMP:
-                        {
-                            int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
-                            if (tok <= 0) {
-                                if (tok == XML_TOK_INVALID)
-                                    *nextTokPtr = ptr;
-                                return tok;
-                            }
-                            break;
-                        }
-                    case BT_LT:
-                        *nextTokPtr = ptr;
-                        return XML_TOK_INVALID;
-                    default:
-                        ptr += MINBPC(enc);
-                        break;
-                    }
-                }
-                ptr += MINBPC(enc);
-                if (ptr == end)
-                    return XML_TOK_PARTIAL;
-                switch (BYTE_TYPE(enc, ptr)) {
-                case BT_S:
-                case BT_CR:
-                case BT_LF:
-                    break;
-                case BT_SOL:
-                    goto sol;
-                case BT_GT:
-                    goto gt;
-                default:
-                    *nextTokPtr = ptr;
-                    return XML_TOK_INVALID;
-                }
-                /* ptr points to closing quote */
-                for (;;) {
-                    ptr += MINBPC(enc);
-                    if (ptr == end)
-                        return XML_TOK_PARTIAL;
-                    switch (BYTE_TYPE(enc, ptr)) {
-                        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-            case BT_S: case BT_CR: case BT_LF:
-                        continue;
-                    case BT_GT:
-gt:
-                        *nextTokPtr = ptr + MINBPC(enc);
-                        return XML_TOK_START_TAG_WITH_ATTS;
-                    case BT_SOL:
-sol:
-                        ptr += MINBPC(enc);
-                        if (ptr == end)
-                            return XML_TOK_PARTIAL;
-                        if (!CHAR_MATCHES(enc, ptr, '>')) {
-                            *nextTokPtr = ptr;
-                            return XML_TOK_INVALID;
-                        }
-                        *nextTokPtr = ptr + MINBPC(enc);
-                        return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
-                    default:
-                        *nextTokPtr = ptr;
-                        return XML_TOK_INVALID;
-                    }
-                    break;
-                }
-                break;
-            }
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "<" */
-
-static
-int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
-                   const char **nextTokPtr)
-{
-#ifdef XML_NS
-    int hadColon;
-#endif
-    if (ptr == end)
-        return XML_TOK_PARTIAL;
-    switch (BYTE_TYPE(enc, ptr)) {
-        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-    case BT_EXCL:
-        if ((ptr += MINBPC(enc)) == end)
-            return XML_TOK_PARTIAL;
-        switch (BYTE_TYPE(enc, ptr)) {
-        case BT_MINUS:
-            return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-        case BT_LSQB:
-            return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-        }
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    case BT_QUEST:
-        return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-    case BT_SOL:
-        return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-#ifdef XML_NS
-    hadColon = 0;
-#endif
-    /* we have a start-tag */
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-#ifdef XML_NS
-        case BT_COLON:
-            if (hadColon) {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            hadColon = 1;
-            ptr += MINBPC(enc);
-            if (ptr == end)
-                return XML_TOK_PARTIAL;
-            switch (BYTE_TYPE(enc, ptr)) {
-                CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-            default:
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            break;
-#endif
-case BT_S: case BT_CR: case BT_LF:
-            {
-                ptr += MINBPC(enc);
-                while (ptr != end) {
-                    switch (BYTE_TYPE(enc, ptr)) {
-                        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-                    case BT_GT:
-                        goto gt;
-                    case BT_SOL:
-                        goto sol;
-            case BT_S: case BT_CR: case BT_LF:
-                        ptr += MINBPC(enc);
-                        continue;
-                    default:
-                        *nextTokPtr = ptr;
-                        return XML_TOK_INVALID;
-                    }
-                    return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
-                }
-                return XML_TOK_PARTIAL;
-            }
-        case BT_GT:
-gt:
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_START_TAG_NO_ATTS;
-        case BT_SOL:
-sol:
-            ptr += MINBPC(enc);
-            if (ptr == end)
-                return XML_TOK_PARTIAL;
-            if (!CHAR_MATCHES(enc, ptr, '>')) {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-static
-int PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
-                       const char **nextTokPtr)
-{
-    if (ptr == end)
-        return XML_TOK_NONE;
-    if (MINBPC(enc) > 1) {
-        size_t n = end - ptr;
-        if (n & (MINBPC(enc) - 1)) {
-            n &= ~(MINBPC(enc) - 1);
-            if (n == 0)
-                return XML_TOK_PARTIAL;
-            end = ptr + n;
-        }
-    }
-    switch (BYTE_TYPE(enc, ptr)) {
-    case BT_LT:
-        return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-    case BT_AMP:
-        return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-    case BT_CR:
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_TRAILING_CR;
-        if (BYTE_TYPE(enc, ptr) == BT_LF)
-            ptr += MINBPC(enc);
-        *nextTokPtr = ptr;
-        return XML_TOK_DATA_NEWLINE;
-    case BT_LF:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_DATA_NEWLINE;
-    case BT_RSQB:
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_TRAILING_RSQB;
-        if (!CHAR_MATCHES(enc, ptr, ']'))
-            break;
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_TRAILING_RSQB;
-        if (!CHAR_MATCHES(enc, ptr, '>')) {
-            ptr -= MINBPC(enc);
-            break;
-        }
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-        INVALID_CASES(ptr, nextTokPtr)
-    default:
-        ptr += MINBPC(enc);
-        break;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: \
-      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
-    *nextTokPtr = ptr; \
-    return XML_TOK_DATA_CHARS; \
-      } \
-      ptr += n; \
-      break;
-            LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-        case BT_RSQB:
-            if (ptr + MINBPC(enc) != end) {
-                if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ']')) {
-                    ptr += MINBPC(enc);
-                    break;
-                }
-                if (ptr + 2*MINBPC(enc) != end) {
-                    if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), '>')) {
-                        ptr += MINBPC(enc);
-                        break;
-                    }
-                    *nextTokPtr = ptr + 2*MINBPC(enc);
-                    return XML_TOK_INVALID;
-                }
-            }
-            /* fall through */
-        case BT_AMP:
-        case BT_LT:
-        case BT_NONXML:
-        case BT_MALFORM:
-        case BT_TRAIL:
-        case BT_CR:
-        case BT_LF:
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        default:
-            ptr += MINBPC(enc);
-            break;
-        }
-    }
-    *nextTokPtr = ptr;
-    return XML_TOK_DATA_CHARS;
-}
-
-/* ptr points to character following "%" */
-
-static
-int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
-                        const char **nextTokPtr)
-{
-    if (ptr == end)
-        return XML_TOK_PARTIAL;
-    switch (BYTE_TYPE(enc, ptr)) {
-        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
-        *nextTokPtr = ptr;
-        return XML_TOK_PERCENT;
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-        case BT_SEMI:
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_PARAM_ENTITY_REF;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-static
-int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
-                          const char **nextTokPtr)
-{
-    if (ptr == end)
-        return XML_TOK_PARTIAL;
-    switch (BYTE_TYPE(enc, ptr)) {
-        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-case BT_CR: case BT_LF: case BT_S:
-case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
-            *nextTokPtr = ptr;
-            return XML_TOK_POUND_NAME;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-static
-int PREFIX(scanLit)(int open, const ENCODING *enc,
-                    const char *ptr, const char *end,
-                    const char **nextTokPtr)
-{
-    while (ptr != end) {
-        int t = BYTE_TYPE(enc, ptr);
-        switch (t) {
-            INVALID_CASES(ptr, nextTokPtr)
-        case BT_QUOT:
-        case BT_APOS:
-            ptr += MINBPC(enc);
-            if (t != open)
-                break;
-            if (ptr == end)
-                return XML_TOK_PARTIAL;
-            *nextTokPtr = ptr;
-            switch (BYTE_TYPE(enc, ptr)) {
-    case BT_S: case BT_CR: case BT_LF:
-    case BT_GT: case BT_PERCNT: case BT_LSQB:
-                return XML_TOK_LITERAL;
-            default:
-                return XML_TOK_INVALID;
-            }
-        default:
-            ptr += MINBPC(enc);
-            break;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-static
-int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
-                      const char **nextTokPtr)
-{
-    int tok;
-    if (ptr == end)
-        return XML_TOK_NONE;
-    if (MINBPC(enc) > 1) {
-        size_t n = end - ptr;
-        if (n & (MINBPC(enc) - 1)) {
-            n &= ~(MINBPC(enc) - 1);
-            if (n == 0)
-                return XML_TOK_PARTIAL;
-            end = ptr + n;
-        }
-    }
-    switch (BYTE_TYPE(enc, ptr)) {
-    case BT_QUOT:
-        return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
-    case BT_APOS:
-        return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
-    case BT_LT:
-        {
-            ptr += MINBPC(enc);
-            if (ptr == end)
-                return XML_TOK_PARTIAL;
-            switch (BYTE_TYPE(enc, ptr)) {
-            case BT_EXCL:
-                return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-            case BT_QUEST:
-                return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-            case BT_NMSTRT:
-            case BT_HEX:
-            case BT_NONASCII:
-            case BT_LEAD2:
-            case BT_LEAD3:
-            case BT_LEAD4:
-                *nextTokPtr = ptr - MINBPC(enc);
-                return XML_TOK_INSTANCE_START;
-            }
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    case BT_CR:
-        if (ptr + MINBPC(enc) == end)
-            return XML_TOK_TRAILING_CR;
-        /* fall through */
-case BT_S: case BT_LF:
-        for (;;) {
-            ptr += MINBPC(enc);
-            if (ptr == end)
-                break;
-            switch (BYTE_TYPE(enc, ptr)) {
-        case BT_S: case BT_LF:
-                break;
-            case BT_CR:
-                /* don't split CR/LF pair */
-                if (ptr + MINBPC(enc) != end)
-                    break;
-                /* fall through */
-            default:
-                *nextTokPtr = ptr;
-                return XML_TOK_PROLOG_S;
-            }
-        }
-        *nextTokPtr = ptr;
-        return XML_TOK_PROLOG_S;
-    case BT_PERCNT:
-        return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-    case BT_COMMA:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_COMMA;
-    case BT_LSQB:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_OPEN_BRACKET;
-    case BT_RSQB:
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_PARTIAL;
-        if (CHAR_MATCHES(enc, ptr, ']')) {
-            if (ptr + MINBPC(enc) == end)
-                return XML_TOK_PARTIAL;
-            if (CHAR_MATCHES(enc, ptr + MINBPC(enc), '>')) {
-                *nextTokPtr = ptr + 2*MINBPC(enc);
-                return XML_TOK_COND_SECT_CLOSE;
-            }
-        }
-        *nextTokPtr = ptr;
-        return XML_TOK_CLOSE_BRACKET;
-    case BT_LPAR:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_OPEN_PAREN;
-    case BT_RPAR:
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_PARTIAL;
-        switch (BYTE_TYPE(enc, ptr)) {
-        case BT_AST:
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_CLOSE_PAREN_ASTERISK;
-        case BT_QUEST:
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_CLOSE_PAREN_QUESTION;
-        case BT_PLUS:
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_CLOSE_PAREN_PLUS;
-case BT_CR: case BT_LF: case BT_S:
-case BT_GT: case BT_COMMA: case BT_VERBAR:
-        case BT_RPAR:
-            *nextTokPtr = ptr;
-            return XML_TOK_CLOSE_PAREN;
-        }
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    case BT_VERBAR:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_OR;
-    case BT_GT:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_DECL_CLOSE;
-    case BT_NUM:
-        return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-#define LEAD_CASE(n) \
-  case BT_LEAD ## n: \
-    if (end - ptr < n) \
-      return XML_TOK_PARTIAL_CHAR; \
-    if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
-      ptr += n; \
-      tok = XML_TOK_NAME; \
-      break; \
-    } \
-    if (IS_NAME_CHAR(enc, ptr, n)) { \
-      ptr += n; \
-      tok = XML_TOK_NMTOKEN; \
-      break; \
-    } \
-    *nextTokPtr = ptr; \
-    return XML_TOK_INVALID;
-        LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-    case BT_NMSTRT:
-    case BT_HEX:
-        tok = XML_TOK_NAME;
-        ptr += MINBPC(enc);
-        break;
-    case BT_DIGIT:
-    case BT_NAME:
-    case BT_MINUS:
-#ifdef XML_NS
-    case BT_COLON:
-#endif
-        tok = XML_TOK_NMTOKEN;
-        ptr += MINBPC(enc);
-        break;
-    case BT_NONASCII:
-        if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {
-            ptr += MINBPC(enc);
-            tok = XML_TOK_NAME;
-            break;
-        }
-        if (IS_NAME_CHAR_MINBPC(enc, ptr)) {
-            ptr += MINBPC(enc);
-            tok = XML_TOK_NMTOKEN;
-            break;
-        }
-        /* fall through */
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-case BT_GT: case BT_RPAR: case BT_COMMA:
-case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
-case BT_S: case BT_CR: case BT_LF:
-            *nextTokPtr = ptr;
-            return tok;
-#ifdef XML_NS
-        case BT_COLON:
-            ptr += MINBPC(enc);
-            switch (tok) {
-            case XML_TOK_NAME:
-                if (ptr == end)
-                    return XML_TOK_PARTIAL;
-                tok = XML_TOK_PREFIXED_NAME;
-                switch (BYTE_TYPE(enc, ptr)) {
-                    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-                default:
-                    tok = XML_TOK_NMTOKEN;
-                    break;
-                }
-                break;
-            case XML_TOK_PREFIXED_NAME:
-                tok = XML_TOK_NMTOKEN;
-                break;
-            }
-            break;
-#endif
-        case BT_PLUS:
-            if (tok == XML_TOK_NMTOKEN)  {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_NAME_PLUS;
-        case BT_AST:
-            if (tok == XML_TOK_NMTOKEN)  {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_NAME_ASTERISK;
-        case BT_QUEST:
-            if (tok == XML_TOK_NMTOKEN)  {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_NAME_QUESTION;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-static
-int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end,
-                              const char **nextTokPtr)
-{
-    const char *start;
-    if (ptr == end)
-        return XML_TOK_NONE;
-    start = ptr;
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: ptr += n; break;
-            LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-        case BT_AMP:
-            if (ptr == start)
-                return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        case BT_LT:
-            /* this is for inside entity references */
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        case BT_LF:
-            if (ptr == start) {
-                *nextTokPtr = ptr + MINBPC(enc);
-                return XML_TOK_DATA_NEWLINE;
-            }
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        case BT_CR:
-            if (ptr == start) {
-                ptr += MINBPC(enc);
-                if (ptr == end)
-                    return XML_TOK_TRAILING_CR;
-                if (BYTE_TYPE(enc, ptr) == BT_LF)
-                    ptr += MINBPC(enc);
-                *nextTokPtr = ptr;
-                return XML_TOK_DATA_NEWLINE;
-            }
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        case BT_S:
-            if (ptr == start) {
-                *nextTokPtr = ptr + MINBPC(enc);
-                return XML_TOK_ATTRIBUTE_VALUE_S;
-            }
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        default:
-            ptr += MINBPC(enc);
-            break;
-        }
-    }
-    *nextTokPtr = ptr;
-    return XML_TOK_DATA_CHARS;
-}
-
-static
-int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end,
-                           const char **nextTokPtr)
-{
-    const char *start;
-    if (ptr == end)
-        return XML_TOK_NONE;
-    start = ptr;
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: ptr += n; break;
-            LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-        case BT_AMP:
-            if (ptr == start)
-                return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        case BT_PERCNT:
-            if (ptr == start)
-                return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        case BT_LF:
-            if (ptr == start) {
-                *nextTokPtr = ptr + MINBPC(enc);
-                return XML_TOK_DATA_NEWLINE;
-            }
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        case BT_CR:
-            if (ptr == start) {
-                ptr += MINBPC(enc);
-                if (ptr == end)
-                    return XML_TOK_TRAILING_CR;
-                if (BYTE_TYPE(enc, ptr) == BT_LF)
-                    ptr += MINBPC(enc);
-                *nextTokPtr = ptr;
-                return XML_TOK_DATA_NEWLINE;
-            }
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        default:
-            ptr += MINBPC(enc);
-            break;
-        }
-    }
-    *nextTokPtr = ptr;
-    return XML_TOK_DATA_CHARS;
-}
-
-static
-int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
-                       const char **badPtr)
-{
-    ptr += MINBPC(enc);
-    end -= MINBPC(enc);
-    for (; ptr != end; ptr += MINBPC(enc)) {
-        switch (BYTE_TYPE(enc, ptr)) {
-        case BT_DIGIT:
-        case BT_HEX:
-        case BT_MINUS:
-        case BT_APOS:
-        case BT_LPAR:
-        case BT_RPAR:
-        case BT_PLUS:
-        case BT_COMMA:
-        case BT_SOL:
-        case BT_EQUALS:
-        case BT_QUEST:
-        case BT_CR:
-        case BT_LF:
-        case BT_SEMI:
-        case BT_EXCL:
-        case BT_AST:
-        case BT_PERCNT:
-        case BT_NUM:
-#ifdef XML_NS
-        case BT_COLON:
-#endif
-            break;
-        case BT_S:
-            if (CHAR_MATCHES(enc, ptr, '\t')) {
-                *badPtr = ptr;
-                return 0;
-            }
-            break;
-        case BT_NAME:
-        case BT_NMSTRT:
-            if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
-                break;
-        default:
-            switch (BYTE_TO_ASCII(enc, ptr)) {
-            case 0x24: /* $ */
-            case 0x40: /* @ */
-                break;
-            default:
-                *badPtr = ptr;
-                return 0;
-            }
-            break;
-        }
-    }
-    return 1;
-}
-
-/* This must only be called for a well-formed start-tag or empty element tag.
-Returns the number of attributes.  Pointers to the first attsMax attributes 
-are stored in atts. */
-
-static
-int PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
-                    int attsMax, ATTRIBUTE *atts)
-{
-    enum { other, inName, inValue } state = inName;
-    int nAtts = 0;
-    int open = 0;
-
-    for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
-        switch (BYTE_TYPE(enc, ptr)) {
-#define START_NAME \
-      if (state == other) { \
-    if (nAtts < attsMax) { \
-      atts[nAtts].name = ptr; \
-      atts[nAtts].normalized = 1; \
-    } \
-    state = inName; \
-      }
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;
-            LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-        case BT_NONASCII:
-        case BT_NMSTRT:
-        case BT_HEX:
-            START_NAME
-            break;
-#undef START_NAME
-        case BT_QUOT:
-            if (state != inValue) {
-                if (nAtts < attsMax)
-                    atts[nAtts].valuePtr = ptr + MINBPC(enc);
-                state = inValue;
-                open = BT_QUOT;
-            }
-            else if (open == BT_QUOT) {
-                state = other;
-                if (nAtts < attsMax)
-                    atts[nAtts].valueEnd = ptr;
-                nAtts++;
-            }
-            break;
-        case BT_APOS:
-            if (state != inValue) {
-                if (nAtts < attsMax)
-                    atts[nAtts].valuePtr = ptr + MINBPC(enc);
-                state = inValue;
-                open = BT_APOS;
-            }
-            else if (open == BT_APOS) {
-                state = other;
-                if (nAtts < attsMax)
-                    atts[nAtts].valueEnd = ptr;
-                nAtts++;
-            }
-            break;
-        case BT_AMP:
-            if (nAtts < attsMax)
-                atts[nAtts].normalized = 0;
-            break;
-        case BT_S:
-            if (state == inName)
-                state = other;
-            else if (state == inValue
-                     && nAtts < attsMax
-                     && atts[nAtts].normalized
-                     && (ptr == atts[nAtts].valuePtr
-                         || BYTE_TO_ASCII(enc, ptr) != ' '
-                         || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ' '
-                         || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
-                atts[nAtts].normalized = 0;
-            break;
-    case BT_CR: case BT_LF:
-            /* This case ensures that the first attribute name is counted
-               Apart from that we could just change state on the quote. */
-            if (state == inName)
-                state = other;
-            else if (state == inValue && nAtts < attsMax)
-                atts[nAtts].normalized = 0;
-            break;
-        case BT_GT:
-        case BT_SOL:
-            if (state != inValue)
-                return nAtts;
-            break;
-        default:
-            break;
-        }
-    }
-    /* not reached */
-}
-
-static
-int PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
-{
-    int result = 0;
-    /* skip &# */
-    ptr += 2*MINBPC(enc);
-    if (CHAR_MATCHES(enc, ptr, 'x')) {
-        for (ptr += MINBPC(enc); !CHAR_MATCHES(enc, ptr, ';'); ptr += MINBPC(enc)) {
-            int c = BYTE_TO_ASCII(enc, ptr);
-            switch (c) {
-case '0': case '1': case '2': case '3': case '4':
-case '5': case '6': case '7': case '8': case '9':
-                result <<= 4;
-                result |= (c - '0');
-                break;
-case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
-                result <<= 4;
-                result += 10 + (c - 'A');
-                break;
-case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
-                result <<= 4;
-                result += 10 + (c - 'a');
-                break;
-            }
-            if (result >= 0x110000)
-                return -1;
-        }
-    }
-    else {
-        for (; !CHAR_MATCHES(enc, ptr, ';'); ptr += MINBPC(enc)) {
-            int c = BYTE_TO_ASCII(enc, ptr);
-            result *= 10;
-            result += (c - '0');
-            if (result >= 0x110000)
-                return -1;
-        }
-    }
-    return checkCharRefNumber(result);
-}
-
-static
-int PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, const char *end)
-{
-    switch ((end - ptr)/MINBPC(enc)) {
-    case 2:
-        if (CHAR_MATCHES(enc, ptr + MINBPC(enc), 't')) {
-            switch (BYTE_TO_ASCII(enc, ptr)) {
-            case 'l':
-                return '<';
-            case 'g':
-                return '>';
-            }
-        }
-        break;
-    case 3:
-        if (CHAR_MATCHES(enc, ptr, 'a')) {
-            ptr += MINBPC(enc);
-            if (CHAR_MATCHES(enc, ptr, 'm')) {
-                ptr += MINBPC(enc);
-                if (CHAR_MATCHES(enc, ptr, 'p'))
-                    return '&';
-            }
-        }
-        break;
-    case 4:
-        switch (BYTE_TO_ASCII(enc, ptr)) {
-        case 'q':
-            ptr += MINBPC(enc);
-            if (CHAR_MATCHES(enc, ptr, 'u')) {
-                ptr += MINBPC(enc);
-                if (CHAR_MATCHES(enc, ptr, 'o')) {
-                    ptr += MINBPC(enc);
-                    if (CHAR_MATCHES(enc, ptr, 't'))
-                        return '"';
-                }
-            }
-            break;
-        case 'a':
-            ptr += MINBPC(enc);
-            if (CHAR_MATCHES(enc, ptr, 'p')) {
-                ptr += MINBPC(enc);
-                if (CHAR_MATCHES(enc, ptr, 'o')) {
-                    ptr += MINBPC(enc);
-                    if (CHAR_MATCHES(enc, ptr, 's'))
-                        return '\'';
-                }
-            }
-            break;
-        }
-    }
-    return 0;
-}
-
-static
-int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
-{
-    for (;;) {
-        switch (BYTE_TYPE(enc, ptr1)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: \
-      if (*ptr1++ != *ptr2++) \
-    return 0;
-            LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
-#undef LEAD_CASE
-            /* fall through */
-            if (*ptr1++ != *ptr2++)
-                return 0;
-            break;
-        case BT_NONASCII:
-        case BT_NMSTRT:
-#ifdef XML_NS
-        case BT_COLON:
-#endif
-        case BT_HEX:
-        case BT_DIGIT:
-        case BT_NAME:
-        case BT_MINUS:
-            if (*ptr2++ != *ptr1++)
-                return 0;
-            if (MINBPC(enc) > 1) {
-                if (*ptr2++ != *ptr1++)
-                    return 0;
-                if (MINBPC(enc) > 2) {
-                    if (*ptr2++ != *ptr1++)
-                        return 0;
-                    if (MINBPC(enc) > 3) {
-                        if (*ptr2++ != *ptr1++)
-                            return 0;
-                    }
-                }
-            }
-            break;
-        default:
-            if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
-                return 1;
-            switch (BYTE_TYPE(enc, ptr2)) {
-            case BT_LEAD2:
-            case BT_LEAD3:
-            case BT_LEAD4:
-            case BT_NONASCII:
-            case BT_NMSTRT:
-#ifdef XML_NS
-            case BT_COLON:
-#endif
-            case BT_HEX:
-            case BT_DIGIT:
-            case BT_NAME:
-            case BT_MINUS:
-                return 0;
-            default:
-                return 1;
-            }
-        }
-    }
-    /* not reached */
-}
-
-static
-int PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, const char *ptr2)
-{
-    for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
-        if (!CHAR_MATCHES(enc, ptr1, *ptr2))
-            return 0;
-    }
-    switch (BYTE_TYPE(enc, ptr1)) {
-    case BT_LEAD2:
-    case BT_LEAD3:
-    case BT_LEAD4:
-    case BT_NONASCII:
-    case BT_NMSTRT:
-#ifdef XML_NS
-    case BT_COLON:
-#endif
-    case BT_HEX:
-    case BT_DIGIT:
-    case BT_NAME:
-    case BT_MINUS:
-        return 0;
-    default:
-        return 1;
-    }
-}
-
-static
-int PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
-{
-    const char *start = ptr;
-    for (;;) {
-        switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: ptr += n; break;
-            LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-        case BT_NONASCII:
-        case BT_NMSTRT:
-#ifdef XML_NS
-        case BT_COLON:
-#endif
-        case BT_HEX:
-        case BT_DIGIT:
-        case BT_NAME:
-        case BT_MINUS:
-            ptr += MINBPC(enc);
-            break;
-        default:
-            return ptr - start;
-        }
-    }
-}
-
-static
-const char *PREFIX(skipS)(const ENCODING *enc, const char *ptr)
-{
-    for (;;) {
-        switch (BYTE_TYPE(enc, ptr)) {
-        case BT_LF:
-        case BT_CR:
-        case BT_S:
-            ptr += MINBPC(enc);
-            break;
-        default:
-            return ptr;
-        }
-    }
-}
-
-static
-void PREFIX(updatePosition)(const ENCODING *enc,
-                            const char *ptr,
-                            const char *end,
-                            POSITION *pos)
-{
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: \
-      ptr += n; \
-      break;
-            LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-        case BT_LF:
-            pos->columnNumber = (unsigned)-1;
-            pos->lineNumber++;
-            ptr += MINBPC(enc);
-            break;
-        case BT_CR:
-            pos->lineNumber++;
-            ptr += MINBPC(enc);
-            if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
-                ptr += MINBPC(enc);
-            pos->columnNumber = (unsigned)-1;
-            break;
-        default:
-            ptr += MINBPC(enc);
-            break;
-        }
-        pos->columnNumber++;
-    }
-}
-
-#undef DO_LEAD_CASE
-#undef MULTIBYTE_CASES
-#undef INVALID_CASES
-#undef CHECK_NAME_CASE
-#undef CHECK_NAME_CASES
-#undef CHECK_NMSTRT_CASE
-#undef CHECK_NMSTRT_CASES
--- a/mcabber/libjabber/xmltok_ns_c.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *  Jabber
- *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
- */
-
-const ENCODING *NS(XmlGetUtf8InternalEncoding)()
-{
-    return &ns(internal_utf8_encoding).enc;
-}
-
-const ENCODING *NS(XmlGetUtf16InternalEncoding)()
-{
-#if XML_BYTE_ORDER == 12
-    return &ns(internal_little2_encoding).enc;
-#elif XML_BYTE_ORDER == 21
-return &ns(internal_big2_encoding).enc;
-#else
-const short n = 1;
-    return *(const char *)&n ? &ns(internal_little2_encoding).enc : &ns(internal_big2_encoding).enc;
-#endif
-}
-
-static
-const ENCODING *NS(encodings)[] = {
-    &ns(latin1_encoding).enc,
-    &ns(ascii_encoding).enc,
-    &ns(utf8_encoding).enc,
-    &ns(big2_encoding).enc,
-    &ns(big2_encoding).enc,
-    &ns(little2_encoding).enc,
-    &ns(utf8_encoding).enc /* NO_ENC */
-};
-
-static
-int NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
-                       const char **nextTokPtr)
-{
-    return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, ptr, end, nextTokPtr);
-}
-
-static
-int NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
-                        const char **nextTokPtr)
-{
-    return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, ptr, end, nextTokPtr);
-}
-
-int NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, const char *name)
-{
-    int i = getEncodingIndex(name);
-    if (i == UNKNOWN_ENC)
-        return 0;
-    INIT_ENC_INDEX(p) = (char)i;
-    p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
-    p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
-    p->initEnc.updatePosition = initUpdatePosition;
-    p->encPtr = encPtr;
-    *encPtr = &(p->initEnc);
-    return 1;
-}
-
-static
-const ENCODING *NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
-{
-#define ENCODING_MAX 128
-    char buf[ENCODING_MAX];
-    char *p = buf;
-    int i;
-    XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
-    if (ptr != end)
-        return 0;
-    *p = 0;
-    if (streqci(buf, "UTF-16") && enc->minBytesPerChar == 2)
-        return enc;
-    i = getEncodingIndex(buf);
-    if (i == UNKNOWN_ENC)
-        return 0;
-    return NS(encodings)[i];
-}
-
-int NS(XmlParseXmlDecl)(int isGeneralTextEntity,
-                        const ENCODING *enc,
-                        const char *ptr,
-                        const char *end,
-                        const char **badPtr,
-                        const char **versionPtr,
-                        const char **encodingName,
-                        const ENCODING **encoding,
-                        int *standalone)
-{
-    return doParseXmlDecl(NS(findEncoding),
-                          isGeneralTextEntity,
-                          enc,
-                          ptr,
-                          end,
-                          badPtr,
-                          versionPtr,
-                          encodingName,
-                          encoding,
-                          standalone);
-}
--- a/mcabber/libjabber/xstream.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyrights
- *
- * Portions created by or assigned to Jabber.com, Inc. are
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- *
- * Acknowledgements
- *
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- *
- */
-
-/**
- * @file xstream.c
- * @brief handling of incoming XML stream based events
- *
- * xstream is a way to have a consistent method of handling incoming XML stream based events ...
- * it doesn't handle the generation of an XML stream, but provides some facilities to help doing that
- */
-
-#include <time.h>
-#include <libxode.h>
-
-/* ========== internal expat callbacks =========== */
-
-/**
- * internal expat callback for read start tags of an element
- */
-void _xstream_startElement(xstream xs, const char* name, const char** atts)
-{
-    pool p;
-
-    /* if xstream is bad, get outa here */
-    if(xs->status > XSTREAM_NODE) return;
-
-    if(xs->node == NULL)
-    {
-        p = pool_heap(5*1024); /* 5k, typically 1-2k each plus copy of self and workspace */
-        xs->node = xmlnode_new_tag_pool(p,name);
-        xmlnode_put_expat_attribs(xs->node, atts);
-
-        if(xs->status == XSTREAM_ROOT)
-        {
-            xs->status = XSTREAM_NODE; /* flag status that we're processing nodes now */
-            (xs->f)(XSTREAM_ROOT, xs->node, xs->arg); /* send the root, f must free all nodes */
-            xs->node = NULL;
-        }
-    }else{
-        xs->node = xmlnode_insert_tag(xs->node, name);
-        xmlnode_put_expat_attribs(xs->node, atts);
-    }
-
-    /* depth check */
-    xs->depth++;
-    if(xs->depth > XSTREAM_MAXDEPTH)
-        xs->status = XSTREAM_ERR;
-}
-
-/**
- * internal expat callback for read end tags of an element
- */
-void _xstream_endElement(xstream xs, const char* name)
-{
-    xmlnode parent;
-
-    /* if xstream is bad, get outa here */
-    if(xs->status > XSTREAM_NODE) return;
-
-    /* if it's already NULL we've received </stream>, tell the app and we're outta here */
-    if(xs->node == NULL)
-    {
-        xs->status = XSTREAM_CLOSE;
-        (xs->f)(XSTREAM_CLOSE, NULL, xs->arg);
-    }else{
-        parent = xmlnode_get_parent(xs->node);
-
-        /* we are the top-most node, feed to the app who is responsible to delete it */
-        if(parent == NULL)
-            (xs->f)(XSTREAM_NODE, xs->node, xs->arg);
-
-        xs->node = parent;
-    }
-    xs->depth--;
-}
-
-/**
- * internal expat callback for read CDATA
- */
-void _xstream_charData(xstream xs, const char *str, int len)
-{
-    /* if xstream is bad, get outa here */
-    if(xs->status > XSTREAM_NODE) return;
-
-    if(xs->node == NULL)
-    {
-        /* we must be in the root of the stream where CDATA is irrelevant */
-        return;
-    }
-
-    xmlnode_insert_cdata(xs->node, str, len);
-}
-
-/**
- * internal function to be registered as pool cleaner, frees a stream if the associated memory pool is freed
- *
- * @param pointer to the xstream to free
- */
-void _xstream_cleanup(void *arg)
-{
-    xstream xs = (xstream)arg;
-
-    xmlnode_free(xs->node); /* cleanup anything left over */
-    XML_ParserFree(xs->parser);
-}
-
-
-/**
- * creates a new xstream with given pool, xstream will be cleaned up w/ pool
- *
- * @param p the memory pool to use for the stream
- * @param f function pointer to the event handler function
- * @param arg parameter to pass to the event handler function
- * @return the created xstream
- */
-xstream xstream_new(pool p, xstream_onNode f, void *arg)
-{
-    xstream newx;
-
-    if(p == NULL || f == NULL)
-    {
-        fprintf(stderr,"Fatal Programming Error: xstream_new() was improperly called with NULL.\n");
-        return NULL;
-    }
-
-    newx = pmalloco(p, sizeof(_xstream));
-    newx->p = p;
-    newx->f = f;
-    newx->arg = arg;
-
-    /* create expat parser and ensure cleanup */
-    newx->parser = XML_ParserCreate(NULL);
-    XML_SetUserData(newx->parser, (void *)newx);
-    XML_SetElementHandler(newx->parser,
-                          (XML_StartElementHandler)_xstream_startElement,
-                          (XML_EndElementHandler)_xstream_endElement);
-    XML_SetCharacterDataHandler(newx->parser,
-                                (XML_CharacterDataHandler)_xstream_charData);
-    pool_cleanup(p, _xstream_cleanup, (void *)newx);
-
-    return newx;
-}
-
-/**
- * attempts to parse the buff onto this stream firing events to the handler
- *
- * @param xs the xstream to parse the data on
- * @param buff the new data
- * @param len length of the data
- * @return last known xstream status
- */
-int xstream_eat(xstream xs, char *buff, int len)
-{
-    char *err;
-    xmlnode xerr;
-    static char maxerr[] = "maximum node size reached";
-    static char deeperr[] = "maximum node depth reached";
-
-    if(xs == NULL)
-    {
-        fprintf(stderr,"Fatal Programming Error: xstream_eat() was improperly called with NULL.\n");
-        return XSTREAM_ERR;
-    }
-
-    if(len == 0 || buff == NULL)
-        return xs->status;
-
-    if(len == -1) /* easy for hand-fed eat calls */
-        len = strlen(buff);
-
-    if(!XML_Parse(xs->parser, buff, len, 0))
-    {
-        err = (char *)XML_ErrorString(XML_GetErrorCode(xs->parser));
-        xs->status = XSTREAM_ERR;
-    }else if(pool_size(xmlnode_pool(xs->node)) > XSTREAM_MAXNODE || xs->cdata_len > XSTREAM_MAXNODE){
-        err = maxerr;
-        xs->status = XSTREAM_ERR;
-    }else if(xs->status == XSTREAM_ERR){ /* set within expat handlers */
-        err = deeperr;
-    }
-
-    /* fire parsing error event, make a node containing the error string */
-    if(xs->status == XSTREAM_ERR)
-    {
-        xerr = xmlnode_new_tag("error");
-        xmlnode_insert_cdata(xerr,err,-1);
-        (xs->f)(XSTREAM_ERR, xerr, xs->arg);
-    }
-
-    return xs->status;
-}
-
-
-/* STREAM CREATION UTILITIES */
-
-/** give a standard template xmlnode to work from 
- *
- * @param namespace ("jabber:client", "jabber:server", ...)
- * @param to where the stream is sent to
- * @param from where we are (source of the stream)
- * @return the xmlnode that has been generated as the template
- */
-xmlnode xstream_header(char *namespace, char *to, char *from)
-{
-    xmlnode x;
-    char id[11];
-
-    sprintf(id,"%X",(int)time(NULL));
-
-    x = xmlnode_new_tag("stream:stream");
-    xmlnode_put_attrib(x, "xmlns:stream", "http://etherx.jabber.org/streams");
-    xmlnode_put_attrib(x, "id", id);
-    if(namespace != NULL)
-        xmlnode_put_attrib(x, "xmlns", namespace);
-    if(to != NULL)
-        xmlnode_put_attrib(x, "to", to);
-    if(from != NULL)
-        xmlnode_put_attrib(x, "from", from);
-
-    return x;
-}
-
-/**
- * trim the xmlnode to only the opening header :)
- *
- * @note NO CHILDREN ALLOWED
- *
- * @param x the xmlnode
- * @return string representation of the start tag
- */
-char *xstream_header_char(xmlnode x)
-{
-    spool s;
-    char *fixr, *head;
-
-    if(xmlnode_has_children(x)) {
-        fprintf(stderr,"Fatal Programming Error: xstream_header_char() was sent a header with children!\n");
-        return NULL;
-    }
-
-    s = spool_new(xmlnode_pool(x));
-    spooler(s,"<?xml version='1.0'?>",xmlnode2str(x),s);
-    head = spool_print(s);
-    fixr = strstr(head,"/>");
-    *fixr = '>';
-    ++fixr;
-    *fixr = '\0';
-
-    return head;
-}
-
--- a/mcabber/mcabberrc.example	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/mcabberrc.example	Sun Oct 11 15:38:32 2009 +0200
@@ -34,26 +34,23 @@
 # presence in your roster (default: 0).
 set ignore_self_presence = 1
 
-# SSL options:
-# Set ssl non-zero to use SSL (this also sets the default port to 5223).
-# * Please note that certificate verification is NOT yet supported if
-#   mcabber is compiled with GnuTLS (only works with OpenSSL).
-#   You can use mcabber -V to check.
-# Set ssl_verify to 0 to disable certificate verification, or non-zero
-# to set desired maximum CA verification depth. Use -1 to specify an
-# unlimited depth.
-# NOTE: You probably need to set ssl_capath for SSL cert verification to work!
-# Set ssl_cafile to a path to a CA certificate file (may contain multiple
-# CA certificates).
-# Set ssl_capath to a directory containing CA certificates (use c_rehash
-# to generate hash links).
-# Set ssl_ciphers to a list of desired SSL ciphers (run "openssl ciphers"
-# for candidate values).
+# SSL/TLS options:
+# TLS is now regarded as the default encryption for connecting to jabber.
+# You can require TLS by setting tls to 1. If your jabber server
+# still doesn't support TLS, you can use the old-style SSL by setting
+# ssl to 1. It's not possible to use old-style SSL and TLS together.
 set ssl = 0
-#set ssl_verify = -1
-#set ssl_cafile = /usr/share/ssl/certs/ca-bundle.crt
-#set ssl_capath =
-#set ssl_ciphers =
+set tls = 1
+# Moreover, it's possible to check whether the fingerprint of the
+# ssl certificate matches ssl_fingerprint.
+# You can get the fingerprint of your server either with gnutls or openssl:
+# 1. gnutls-cli -p 5223 $your_server
+# 2. openssl s_client -connect $your_server:5223 | \
+#    openssl x509 -fingerprint -md5 -noout
+set ssl_fingerprint = 97:5C:00:3F:1D:77:45:25:E2:C5:70:EC:83:C8:87:EE
+# Set ssl_ignore_checks to 1 to disable all certificate checks except the
+# fingerprint check.
+#set ssl_ignore_checks = 0
 
 # PGP support
 # Set pgp to 1 to enable OpenPGP.
--- a/mcabber/src/Makefile.am	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/Makefile.am	Sun Oct 11 15:38:32 2009 +0200
@@ -1,29 +1,27 @@
 bin_PROGRAMS = mcabber
 mcabber_SOURCES = main.c roster.c roster.h events.c events.h \
-		  jabglue.c jabglue.h jab_iq.c jab_priv.h \
 		  commands.c commands.h compl.c compl.h \
 		  hbuf.c hbuf.h screen.c screen.h logprint.h \
 		  settings.c settings.h hooks.c hooks.h utf8.c utf8.h \
 		  histolog.c histolog.h utils.c utils.h pgp.c pgp.h \
-		  fifo.c fifo.h help.c help.h
+		  fifo.c fifo.h help.c help.h \
+		  xmpp.c xmpp.h xmpp_helper.h
 
 if OTR
 mcabber_SOURCES += otr.c otr.h nohtml.c nohtml.h
 endif
 
-LDADD = $(GLIB_LIBS) $(GPGME_LIBS) $(LIBOTR_LIBS) $(ENCHANT_LIBS) \
-	../libjabber/liblibjabber.a ../connwrap/libconnwrap.a
+LDADD = $(GLIB_LIBS) $(LOUDMOUTH_LIBS) $(GPGME_LIBS) $(LIBOTR_LIBS) \
+				$(ENCHANT_LIBS)
 
-AM_CPPFLAGS = $(GLIB_CFLAGS) $(GPGME_CFLAGS) $(LIBOTR_CFLAGS) $(ENCHANT_CFLAGS)
+AM_CPPFLAGS = $(GLIB_CFLAGS) $(LOUDMOUTH_CFLAGS) $(GPGME_CFLAGS) \
+				$(LIBOTR_CFLAGS) $(ENCHANT_CFLAGS)
 
 CLEANFILES = hgcset.h
 
 if HGCSET
 BUILT_SOURCES = hgcset.h
 
-#mcabber_DEPENDENCIES = hgcset.h \
-#	../libjabber/liblibjabber.a ../connwrap/libconnwrap.a
-
 hgcset.h:
 	../hgcset.sh
 
--- a/mcabber/src/commands.c	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/commands.c	Sun Oct 11 15:38:32 2009 +0200
@@ -20,13 +20,13 @@
  */
 
 #include <string.h>
+#include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
 
 #include "commands.h"
 #include "help.h"
-#include "jabglue.h"
 #include "roster.h"
 #include "screen.h"
 #include "compl.h"
@@ -37,6 +37,7 @@
 #include "events.h"
 #include "otr.h"
 #include "utf8.h"
+#include "xmpp.h"
 
 #define IMSTATUS_AWAY           "away"
 #define IMSTATUS_ONLINE         "online"
@@ -575,7 +576,7 @@
 static void display_all_annotations(void)
 {
   GSList *notes;
-  notes = jb_get_all_storage_rosternotes();
+  notes = xmpp_get_all_storage_rosternotes();
 
   if (!notes)
     return;
@@ -620,10 +621,10 @@
       notetxt = NULL; // delete note
     else
       notetxt = msg;
-    jb_set_storage_rosternotes(bjid, notetxt);
+    xmpp_set_storage_rosternotes(bjid, notetxt);
     g_free(msg);
   } else {      // Display a note
-    struct annotation *note = jb_get_storage_rosternotes(bjid, FALSE);
+    struct annotation *note = xmpp_get_storage_rosternotes(bjid, FALSE);
     if (note) {
       display_and_free_note(note, bjid);
     } else {
@@ -819,7 +820,7 @@
   char *msg;
   enum imstatus st;
 
-  if (!jb_getonline()) {
+  if (!lm_connection_is_authenticated(lconnection)) {
     scr_LogPrint(LPRINT_NORMAL, "You are not connected.");
     return;
   }
@@ -854,7 +855,7 @@
       free_arg_lst(paramlst);
       return;
     }
-    st = jb_getstatus();  // Preserve current status
+    st = xmpp_getstatus();  // Preserve current status
   } else {
     scr_LogPrint(LPRINT_NORMAL, "Unrecognized status!");
     free_arg_lst(paramlst);
@@ -870,7 +871,7 @@
   if (recipient && !msg)
     msg = "";
 
-  jb_setstatus(st, recipient, msg, FALSE);
+  xmpp_setstatus(st, recipient, msg, FALSE);
 
   free_arg_lst(paramlst);
 }
@@ -878,9 +879,9 @@
 static void do_status(char *arg)
 {
   if (!*arg) {
-    const char *sm = jb_getstatusmsg();
+    const char *sm = xmpp_getstatusmsg();
     scr_LogPrint(LPRINT_NORMAL, "Your status is: [%c] %s",
-                 imstatus2char[jb_getstatus()],
+                 imstatus2char[xmpp_getstatus()],
                  (sm ? sm : ""));
     return;
   }
@@ -953,7 +954,7 @@
   char *id, *nick;
   char *jid_utf8 = NULL;
 
-  if (!jb_getonline()) {
+  if (!lm_connection_is_authenticated(lconnection)) {
     scr_LogPrint(LPRINT_NORMAL, "You are not connected.");
     return;
   }
@@ -992,7 +993,7 @@
 
   if (id) {
     // 2nd parameter = optional nickname
-    jb_addbuddy(id, nick, NULL);
+    xmpp_addbuddy(id, nick, NULL);
     scr_LogPrint(LPRINT_LOGNORM, "Sent presence notification request to <%s>.",
                  id);
   }
@@ -1030,7 +1031,7 @@
   scr_BufferPurge(1, NULL);
 
   scr_LogPrint(LPRINT_LOGNORM, "Removing <%s>...", bjid);
-  jb_delbuddy(bjid);
+  xmpp_delbuddy(bjid);
   scr_UpdateBuddyWindow();
 }
 
@@ -1106,7 +1107,7 @@
 }
 
 static int send_message_to(const char *fjid, const char *msg, const char *subj,
-                           const char *type_overwrite, bool quiet)
+                           LmMessageSubType type_overwrite, bool quiet)
 {
   char *bare_jid, *rp;
   char *hmsg;
@@ -1114,7 +1115,7 @@
   gint retval = 0;
   int isroom;
 
-  if (!jb_getonline()) {
+  if (!lm_connection_is_authenticated(lconnection)) {
     scr_LogPrint(LPRINT_NORMAL, "You are not connected.");
     return 1;
   }
@@ -1160,8 +1161,8 @@
     hmsg = (char*)msg;
 
   // Network part
-  jb_send_msg(fjid, msg, (isroom ? ROSTER_TYPE_ROOM : ROSTER_TYPE_USER),
-              subj, NULL, &crypted, type_overwrite);
+  xmpp_send_msg(fjid, msg, (isroom ? ROSTER_TYPE_ROOM : ROSTER_TYPE_USER),
+                subj, FALSE, &crypted, type_overwrite);
 
   if (crypted == -1) {
     scr_LogPrint(LPRINT_LOGNORM, "Encryption error.  Message was not sent.");
@@ -1183,7 +1184,7 @@
 // Write the message in the buddy's window and send the message on
 // the network.
 static void send_message(const char *msg, const char *subj,
-                         const char *type_overwrite)
+                         LmMessageSubType type_overwrite)
 {
   const char *bjid;
 
@@ -1201,19 +1202,19 @@
   send_message_to(bjid, msg, subj, type_overwrite, FALSE);
 }
 
-static const char *scan_mtype(char **arg)
+static LmMessageSubType scan_mtype(char **arg)
 {
   //Try splitting it
   char **parlist = split_arg(*arg, 2, 1);
-  const char *result = NULL;
+  LmMessageSubType result = LM_MESSAGE_SUB_TYPE_NOT_SET;
   //Is it any good parameter?
   if (parlist && *parlist) {
     if (!strcmp("-n", *parlist)) {
-      result = TMSG_NORMAL;
+      result = LM_MESSAGE_SUB_TYPE_NORMAL;
     } else if (!strcmp("-h", *parlist)) {
-      result = TMSG_HEADLINE;
+      result = LM_MESSAGE_SUB_TYPE_HEADLINE;
     }
-    if (result || (!strcmp("--", *parlist)))
+    if (result != LM_MESSAGE_SUB_TYPE_NOT_SET || (!strcmp("--", *parlist)))
       *arg += strlen(*arg) - (parlist[1] ? strlen(parlist[1]) : 0);
   }
   //Anything found? -> skip it
@@ -1224,7 +1225,7 @@
 static void do_say_internal(char *arg, int parse_flags)
 {
   gpointer bud;
-  const char *msgtype = NULL;
+  LmMessageSubType msgtype = LM_MESSAGE_SUB_TYPE_NOT_SET;
 
   scr_set_chatmode(TRUE);
   scr_ShowBuddyWindow();
@@ -1330,7 +1331,7 @@
   if (!strcasecmp(subcmd, "send_to")) {
     int err = FALSE;
     gchar *msg_utf8;
-    const char *msg_type = scan_mtype(&arg);
+    LmMessageSubType msg_type = scan_mtype(&arg);
     // Let's send to the specified JID.  We leave now if there
     // has been an error (so we don't leave multi-line mode).
     arg = to_utf8(arg);
@@ -1456,10 +1457,10 @@
   char **paramlst;
   char *fjid, *msg;
   char *file = NULL;
-  const char *msg_type = NULL;
+  LmMessageSubType msg_type = LM_MESSAGE_SUB_TYPE_NOT_SET;
   bool quiet = FALSE;
 
-  if (!jb_getonline()) {
+  if (!lm_connection_is_authenticated(lconnection)) {
     scr_LogPrint(LPRINT_NORMAL, "You are not connected.");
     return;
   }
@@ -1799,7 +1800,7 @@
   if (type == ROSTER_TYPE_USER ||
       type == ROSTER_TYPE_ROOM ||
       type == ROSTER_TYPE_AGENT) {
-    struct annotation *note = jb_get_storage_rosternotes(bjid, TRUE);
+    struct annotation *note = xmpp_get_storage_rosternotes(bjid, TRUE);
     if (note) {
       // We do not display the note, we just tell the user.
       g_free(note->text);
@@ -1908,7 +1909,7 @@
   bjid = buddy_getjid(bud);
   name = buddy_getname(bud);
 
-  jb_updatebuddy(bjid, name, *groupname ? groupname : NULL);
+  xmpp_updatebuddy(bjid, name, *groupname ? groupname : NULL);
 }
 
 static void do_rename(char *arg)
@@ -1942,7 +1943,7 @@
     scr_LogPrint(LPRINT_NORMAL,
                  "Note: this item will be added to your server roster.");
     // If this is a MUC room w/o bookmark, let's give a small hint...
-    if (!jb_is_bookmarked(bjid)) {
+    if (!xmpp_is_bookmarked(bjid)) {
       scr_LogPrint(LPRINT_NORMAL,
                    "You should add a room bookmark or it will not be "
                    "recognized as a MUC room next time you run mcabber.");
@@ -1970,7 +1971,7 @@
     if (!*newname || !strcmp(arg, "-"))
       del_name = TRUE;
     buddy_setname(bud, (del_name ? (char*)bjid : name_utf8));
-    jb_updatebuddy(bjid, (del_name ? NULL : name_utf8), group);
+    xmpp_updatebuddy(bjid, (del_name ? NULL : name_utf8), group);
   }
 
   g_free(name_utf8);
@@ -2016,7 +2017,7 @@
   if (strcmp(oldgroupname, group_utf8)) {
     guint msgflag;
 
-    jb_updatebuddy(bjid, name, *group_utf8 ? group_utf8 : NULL);
+    xmpp_updatebuddy(bjid, name, *group_utf8 ? group_utf8 : NULL);
     scr_RosterUpDown(-1, 1);
 
     // If the buddy has a pending message flag,
@@ -2167,7 +2168,7 @@
   char **paramlst;
   char *subcmd;
 
-  if (!jb_getonline()) {
+  if (!lm_connection_is_authenticated(lconnection)) {
     scr_LogPrint(LPRINT_NORMAL, "You are not connected.");
     return;
   }
@@ -2198,7 +2199,7 @@
     buffer = to_utf8(arg);
     if (buffer) {
       scr_LogPrint(LPRINT_NORMAL, "Sending XML string");
-      jb_send_raw(buffer);
+      lm_connection_send_raw(lconnection, buffer, NULL);
       g_free(buffer);
     } else {
       scr_LogPrint(LPRINT_NORMAL, "Conversion error in XML string.");
@@ -2290,7 +2291,7 @@
 
   pass_utf8 = to_utf8(pass);
 
-  jb_room_join(roomname, nick, pass_utf8);
+  xmpp_room_join(roomname, nick, pass_utf8);
 
   scr_LogPrint(LPRINT_LOGNORM, "Sent a join request to <%s>...", roomname);
 
@@ -2324,7 +2325,7 @@
 
   roomname = buddy_getjid(bud);
   reason_utf8 = to_utf8(arg);
-  jb_room_invite(roomname, fjid, reason_utf8);
+  xmpp_room_invite(roomname, fjid, reason_utf8);
   scr_LogPrint(LPRINT_LOGNORM, "Invitation sent to <%s>.", fjid);
   g_free(reason_utf8);
   free_arg_lst(paramlst);
@@ -2358,7 +2359,7 @@
     gchar *jid_utf8, *reason_utf8;
     jid_utf8 = to_utf8(fjid);
     reason_utf8 = to_utf8(arg);
-    jb_room_setattrib(roomid, jid_utf8, NULL, ra, reason_utf8);
+    xmpp_room_setattrib(roomid, jid_utf8, NULL, ra, reason_utf8);
     g_free(jid_utf8);
     g_free(reason_utf8);
   } else
@@ -2395,7 +2396,7 @@
     gchar *jid_utf8, *reason_utf8;
     jid_utf8 = to_utf8(fjid);
     reason_utf8 = to_utf8(arg);
-    jb_room_setattrib(roomid, jid_utf8, NULL, ra, reason_utf8);
+    xmpp_room_setattrib(roomid, jid_utf8, NULL, ra, reason_utf8);
     g_free(jid_utf8);
     g_free(reason_utf8);
   } else
@@ -2451,7 +2452,7 @@
   scr_LogPrint(LPRINT_NORMAL, "Requesting a ban for %s", banjid);
 
   reason_utf8 = to_utf8(arg);
-  jb_room_setattrib(roomid, banjid, NULL, ra, reason_utf8);
+  xmpp_room_setattrib(roomid, banjid, NULL, ra, reason_utf8);
   g_free(reason_utf8);
 
 room_ban_return:
@@ -2477,7 +2478,7 @@
   ra.val.affil = affil_none;
 
   jid_utf8 = to_utf8(fjid);
-  jb_room_setattrib(roomid, jid_utf8, NULL, ra, NULL);
+  xmpp_room_setattrib(roomid, jid_utf8, NULL, ra, NULL);
   g_free(jid_utf8);
 }
 
@@ -2505,7 +2506,7 @@
 
   nick_utf8 = to_utf8(nick);
   reason_utf8 = to_utf8(arg);
-  jb_room_setattrib(roomid, NULL, nick_utf8, ra, reason_utf8);
+  xmpp_room_setattrib(roomid, NULL, nick_utf8, ra, reason_utf8);
   g_free(nick_utf8);
   g_free(reason_utf8);
 
@@ -2525,7 +2526,7 @@
 
   roomid = g_strdup_printf("%s/%s", buddy_getjid(bud), nickname);
   desc = to_utf8(arg);
-  jb_setstatus(offline, roomid, desc, TRUE);
+  xmpp_setstatus(offline, roomid, desc, TRUE);
   g_free(desc);
   g_free(roomid);
 }
@@ -2553,7 +2554,7 @@
     nick = to_utf8(arg);
     strip_arg_special_chars(nick);
 
-    jb_room_join(roomname, nick, NULL);
+    xmpp_room_join(roomname, nick, NULL);
     g_free(roomname);
     g_free(nick);
   }
@@ -2578,7 +2579,7 @@
   fjid = g_strdup_printf("%s/%s", buddy_getjid(bud), nick);
   fjid_utf8 = to_utf8(fjid);
   msg = to_utf8(arg);
-  send_message_to(fjid_utf8, msg, NULL, NULL, FALSE);
+  send_message_to(fjid_utf8, msg, NULL, LM_MESSAGE_SUB_TYPE_NOT_SET, FALSE);
   g_free(fjid);
   g_free(fjid_utf8);
   g_free(msg);
@@ -2628,8 +2629,8 @@
 
   arg = to_utf8(arg);
   // Set the topic
-  jb_send_msg(buddy_getjid(bud), NULL, ROSTER_TYPE_ROOM, arg ? arg : "",
-              NULL, NULL, NULL);
+  xmpp_send_msg(buddy_getjid(bud), NULL, ROSTER_TYPE_ROOM, arg ? arg : "",
+                FALSE, NULL, LM_MESSAGE_SUB_TYPE_NOT_SET);
   g_free(arg);
 }
 
@@ -2642,7 +2643,7 @@
   else
     msg = NULL;
 
-  jb_room_destroy(buddy_getjid(bud), NULL, msg);
+  xmpp_room_destroy(buddy_getjid(bud), NULL, msg);
   g_free(msg);
 }
 
@@ -2653,7 +2654,7 @@
     return;
   }
 
-  jb_room_unlock(buddy_getjid(bud));
+  xmpp_room_unlock(buddy_getjid(bud));
 }
 
 static void room_setopt(gpointer bud, char *arg)
@@ -2848,8 +2849,8 @@
     autowhois   = buddy_getautowhois(bud);
   }
 
-  jb_set_storage_bookmark(roomid, name, nick, NULL, autojoin,
-                          printstatus, autowhois);
+  xmpp_set_storage_bookmark(roomid, name, nick, NULL, autojoin,
+                            printstatus, autowhois);
 }
 
 static void display_all_bookmarks(void)
@@ -2858,7 +2859,7 @@
   GString *sbuf;
   struct bookmark *bm_elt;
 
-  bm = jb_get_all_storage_bookmarks();
+  bm = xmpp_get_all_storage_bookmarks();
 
   if (!bm)
     return;
@@ -2897,7 +2898,7 @@
   char *subcmd;
   gpointer bud;
 
-  if (!jb_getonline()) {
+  if (!lm_connection_is_authenticated(lconnection)) {
     scr_LogPrint(LPRINT_NORMAL, "You are not connected.");
     return;
   }
@@ -2994,7 +2995,7 @@
   char *subcmd;
   char *jid_utf8;
 
-  if (!jb_getonline()) {
+  if (!lm_connection_is_authenticated(lconnection)) {
     scr_LogPrint(LPRINT_NORMAL, "You are not connected.");
     return;
   }
@@ -3042,21 +3043,21 @@
   }
 
   if (!strcasecmp(subcmd, "allow"))  {
-    jb_subscr_send_auth(jid_utf8);
+    xmpp_send_s10n(jid_utf8, LM_MESSAGE_SUB_TYPE_SUBSCRIBED);
     scr_LogPrint(LPRINT_LOGNORM,
                  "<%s> is now allowed to receive your presence updates.",
                  jid_utf8);
   } else if (!strcasecmp(subcmd, "cancel"))  {
-    jb_subscr_cancel_auth(jid_utf8);
+    xmpp_send_s10n(jid_utf8, LM_MESSAGE_SUB_TYPE_UNSUBSCRIBED);
     scr_LogPrint(LPRINT_LOGNORM,
                  "<%s> will no longer receive your presence updates.",
                  jid_utf8);
   } else if (!strcasecmp(subcmd, "request"))  {
-    jb_subscr_request_auth(jid_utf8);
+    xmpp_send_s10n(jid_utf8, LM_MESSAGE_SUB_TYPE_SUBSCRIBE);
     scr_LogPrint(LPRINT_LOGNORM,
                  "Sent presence notification request to <%s>.", jid_utf8);
   } else if (!strcasecmp(subcmd, "request_unsubscribe"))  {
-    jb_subscr_request_cancel(jid_utf8);
+    xmpp_send_s10n(jid_utf8, LM_MESSAGE_SUB_TYPE_UNSUBSCRIBE);
     scr_LogPrint(LPRINT_LOGNORM,
                  "Sent presence notification unsubscription request to <%s>.",
                  jid_utf8);
@@ -3099,12 +3100,6 @@
       numtype = iqreq_last;
     else if (!strcasecmp(type, "vcard"))
       numtype = iqreq_vcard;
-    else if (!strcasecmp(type, "show_list")) {
-      // Undocumented command, for debugging purposes only
-      jb_iqs_display_list();
-      free_arg_lst(paramlst);
-      return;
-    }
   }
 
   if (!type || !numtype) {
@@ -3114,7 +3109,7 @@
     return;
   }
 
-  if (!jb_getonline()) {
+  if (!lm_connection_is_authenticated(lconnection)) {
     scr_LogPrint(LPRINT_NORMAL, "You are not connected.");
     free_arg_lst(paramlst);
     return;
@@ -3151,7 +3146,7 @@
       case iqreq_time:
       case iqreq_last:
       case iqreq_vcard:
-          jb_request(fjid, numtype);
+          xmpp_request(fjid, numtype);
           break;
       default:
           break;
@@ -3462,7 +3457,7 @@
 }
 
 #ifdef HAVE_LIBOTR
-static char * string_for_otrpolicy(enum otr_policy p)
+static char *string_for_otrpolicy(enum otr_policy p)
 {
   switch (p) {
     case plain:         return "plain";
@@ -3473,7 +3468,7 @@
   }
 }
 
-static void dump_otrpolicy(char * k, char * v, void * nothing)
+static void dump_otrpolicy(char *k, char *v, void *nothing)
 {
   scr_LogPrint(LPRINT_NORMAL|LPRINT_NOTUTF8, "otrpolicy for %s: %s", k,
                string_for_otrpolicy(*(enum otr_policy*)v));
@@ -3670,13 +3665,12 @@
 
 static void do_connect(char *arg)
 {
-  mcabber_connect();
+  xmpp_connect();
 }
 
 static void do_disconnect(char *arg)
 {
-  jb_disconnect();
-  AutoConnection = FALSE;
+  xmpp_disconnect();
 }
 
 static void do_help(char *arg)
--- a/mcabber/src/commands.h	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/commands.h	Sun Oct 11 15:38:32 2009 +0200
@@ -18,7 +18,6 @@
 char *expandalias(const char *line);
 
 extern char *mcabber_version(void);
-extern void mcabber_connect(void);
 extern void mcabber_set_terminate_ui(void);
 
 void cmd_room_whois(gpointer bud, char *nick_locale, guint interactive);
--- a/mcabber/src/events.c	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/events.c	Sun Oct 11 15:38:32 2009 +0200
@@ -20,6 +20,7 @@
  */
 
 #include <glib.h>
+#include <string.h>
 #include "events.h"
 #include "logprint.h"
 
@@ -54,6 +55,8 @@
   new_evs->type = type;
   new_evs->id = stridn;
 
+  if(!g_slist_length(evs_list))
+    g_timeout_add_seconds(20, evs_check_timeout, NULL);
   evs_list = g_slist_append(evs_list, new_evs);
   return new_evs;
 }
@@ -72,7 +75,6 @@
   }
   if (p) {
     g_free(i->id);
-    if (i->xmldata) xmlnode_free(i->xmldata);
     g_free(i->data);
     g_free(i->desc);
     g_free(i);
@@ -116,12 +118,16 @@
   return 0;
 }
 
-void evs_check_timeout(time_t now_t)
+gboolean evs_check_timeout()
 {
+  time_t now_t;
   GSList *p;
   eviqs *i;
 
+  time(&now_t);
   p = evs_list;
+  if (!p)
+    return FALSE;
   while (p) {
     i = p->data;
     // We must get next IQ eviqs element now because the current one
@@ -133,6 +139,7 @@
       evs_callback(i->id, EVS_CONTEXT_TIMEOUT);
     }
   }
+  return TRUE;
 }
 
 void evs_display_list(void)
--- a/mcabber/src/events.h	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/events.h	Sun Oct 11 15:38:32 2009 +0200
@@ -1,7 +1,7 @@
 #ifndef __EVENTS_H__
 #define __EVENTS_H__ 1
 
-#include "jabglue.h"
+#include "xmpp.h"
 
 
 #define EVS_DEFAULT_TIMEOUT 90
@@ -24,7 +24,6 @@
   guint8 type;
   gpointer data;
   int (*callback)();
-  xmlnode xmldata;
   char *desc;
 } eviqs;
 
@@ -35,12 +34,12 @@
   char* reason;
 } event_muc_invitation;
 
-eviqs  *evs_new(guint8 type, time_t timeout);
-int     evs_del(const char *evid);
-int     evs_callback(const char *evid, guint evcontext);
-void    evs_check_timeout(time_t now_t);
-void    evs_display_list(void);
-GSList *evs_geteventslist(int forcompl);
+eviqs   *evs_new(guint8 type, time_t timeout);
+int      evs_del(const char *evid);
+int      evs_callback(const char *evid, guint evcontext);
+gboolean evs_check_timeout();
+void     evs_display_list(void);
+GSList  *evs_geteventslist(int forcompl);
 
 #endif /* __EVENTS_H__ */
 
--- a/mcabber/src/fifo.c	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/fifo.c	Sun Oct 11 15:38:32 2009 +0200
@@ -20,6 +20,7 @@
  */
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <glib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
--- a/mcabber/src/histolog.c	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/histolog.c	Sun Oct 11 15:38:32 2009 +0200
@@ -19,23 +19,24 @@
  * USA
  */
 
-#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
 #include <stdlib.h>
-#include <time.h>
-#include <ctype.h>
+#include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <fcntl.h>
+#include <time.h>
 #include <unistd.h>
 
 #include "histolog.h"
 #include "hbuf.h"
-#include "jabglue.h"
 #include "utils.h"
 #include "screen.h"
 #include "settings.h"
 #include "utils.h"
 #include "roster.h"
+#include "xmpp.h"
 
 static guint UseFileLogging;
 static guint FileLoadLogs;
@@ -76,7 +77,7 @@
     if (S_ISLNK(bufstat.st_mode)) {
       g_free(log_jid);
       log_jid = g_new0(char, bufstat.st_size+1);
-      readlink(path, log_jid, bufstat.st_size);
+      if (readlink(path, log_jid, bufstat.st_size) < 0) return NULL;
       g_free(path);
       path = user_histo_file(log_jid);
     } else
@@ -444,7 +445,7 @@
     goto hlog_save_state_return;
   }
 
-  if (!jb_getonline()) {
+  if (!lm_connection_is_authenticated(lconnection)) {
     // We're not connected.  Let's use the unread_jids hash.
     GList *unread_jid = unread_jid_get_list();
     unread_ptr = unread_jid;
--- a/mcabber/src/histolog.h	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/histolog.h	Sun Oct 11 15:38:32 2009 +0200
@@ -3,7 +3,7 @@
 
 #include <glib.h>
 
-#include "jabglue.h"
+#include "xmpp.h"
 
 void hlog_enable(guint enable, const char *root_dir, guint loadfile);
 char *hlog_get_log_jid(const char *bjid);
--- a/mcabber/src/hooks.c	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/hooks.c	Sun Oct 11 15:38:32 2009 +0200
@@ -19,9 +19,11 @@
  * USA
  */
 
+#include <loudmouth/loudmouth.h>
+#include <stdlib.h>
+#include <string.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <stdlib.h>
 
 #include "hooks.h"
 #include "screen.h"
@@ -55,8 +57,8 @@
 }
 
 void hk_message_in(const char *bjid, const char *resname,
-                          time_t timestamp, const char *msg, const char *type,
-                          guint encrypted)
+                   time_t timestamp, const char *msg, LmMessageSubType type,
+                   guint encrypted)
 {
   int new_guy = FALSE;
   int is_groupchat = FALSE; // groupchat message
@@ -75,7 +77,7 @@
   else if (encrypted == ENCRYPTED_OTR)
     message_flags |= HBB_PREFIX_OTRCRYPT;
 
-  if (type && !strcmp(type, "groupchat")) {
+  if (type == LM_MESSAGE_SUB_TYPE_GROUPCHAT) {
     rtype = ROSTER_TYPE_ROOM;
     is_groupchat = TRUE;
     log_muc_conf = settings_opt_get_int("log_muc_conf");
@@ -172,7 +174,7 @@
     }
   }
 
-  if (type && !strcmp(type, "error")) {
+  if (type  == LM_MESSAGE_SUB_TYPE_ERROR) {
     message_flags = HBB_PREFIX_ERR | HBB_PREFIX_IN;
     scr_LogPrint(LPRINT_LOGNORM, "Error message received from <%s>", bjid);
   }
@@ -292,8 +294,8 @@
 }
 
 void hk_statuschange(const char *bjid, const char *resname, gchar prio,
-                            time_t timestamp, enum imstatus status,
-                            const char *status_msg)
+                     time_t timestamp, enum imstatus status,
+                     const char *status_msg)
 {
   int st_in_buf;
   enum imstatus oldstat;
@@ -477,8 +479,15 @@
       scr_LogPrint(LPRINT_LOGNORM,
                    "Unable to create temp file for external command.");
     } else {
-      write(fd, data_locale, strlen(data_locale));
-      write(fd, "\n", 1);
+      size_t data_locale_len = strlen(data_locale);
+      ssize_t a = write(fd, data_locale, data_locale_len);
+      ssize_t b = write(fd, "\n", 1);
+      if (a != data_locale_len || b != 1) {
+        g_free(datafname);
+        datafname = NULL;
+        scr_LogPrint(LPRINT_LOGNORM,
+                     "Unable to write to temp file for external command.");
+      }
       close(fd);
       arg_data = datafname;
     }
--- a/mcabber/src/hooks.h	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/hooks.h	Sun Oct 11 15:38:32 2009 +0200
@@ -2,7 +2,8 @@
 #define __HOOKS_H__ 1
 
 #include <time.h>
-#include "jabglue.h"
+#include <loudmouth/loudmouth.h>
+#include "xmpp.h"
 
 // These two defines are used by hk_message_{in,out} arguments
 #define ENCRYPTED_PGP   1
@@ -10,13 +11,13 @@
 
 void hk_mainloop(void);
 void hk_message_in(const char *bjid, const char *resname,
-                          time_t timestamp, const char *msg, const char *type,
-                          guint encrypted);
+                   time_t timestamp, const char *msg, LmMessageSubType type,
+                   guint encrypted);
 void hk_message_out(const char *bjid, const char *nickname,
                            time_t timestamp, const char *msg, guint encrypted);
 void hk_statuschange(const char *bjid, const char *resname, gchar prio,
-                            time_t timestamp, enum imstatus status,
-                            char const *status_msg);
+                     time_t timestamp, enum imstatus status,
+                     char const *status_msg);
 void hk_mystatuschange(time_t timestamp,
                               enum imstatus old_status,
                               enum imstatus new_status, const char *msg);
--- a/mcabber/src/jab_iq.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1801 +0,0 @@
-/*
- * jab_iq.c     -- Jabber protocol IQ-related fonctions
- *
- * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
- * Some parts initially came from the centericq project:
- * Copyright (C) 2002-2005 by Konstantin Klyagin <konst@konst.org.ua>
- * Some small parts come from the Pidgin project <http://pidgin.im/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#include <sys/utsname.h>
-#include <glib.h>
-
-#include "jabglue.h"
-#include "jab_priv.h"
-#include "roster.h"
-#include "utils.h"
-#include "screen.h"
-#include "settings.h"
-#include "hbuf.h"
-#include "commands.h"
-#include "hooks.h"
-
-#ifdef ENABLE_HGCSET
-# include "hgcset.h"
-#endif
-
-
-// Bookmarks for IQ:private storage
-xmlnode bookmarks;
-// Roster notes for IQ:private storage
-xmlnode rosternotes;
-
-static GSList *iqs_list;
-
-time_t iqlast; // last message/status change time
-
-// Enum for vCard attributes
-enum vcard_attr {
-  vcard_home    = 1<<0,
-  vcard_work    = 1<<1,
-  vcard_postal  = 1<<2,
-  vcard_voice   = 1<<3,
-  vcard_fax     = 1<<4,
-  vcard_cell    = 1<<5,
-  vcard_inet    = 1<<6,
-  vcard_pref    = 1<<7,
-};
-
-static void handle_iq_command_set_status(jconn conn, char *from,
-                                         const char *id, xmlnode xmldata);
-
-static void handle_iq_command_leave_groupchats(jconn conn, char *from,
-                                               const char *id, xmlnode xmldata);
-
-typedef void (*adhoc_command_callback)(jconn, char*, const char*, xmlnode);
-
-inline double seconds_since_last_use(void);
-
-struct adhoc_command {
-  char *name;
-  char *description;
-  bool only_for_self;
-  adhoc_command_callback callback;
-};
-
-const struct adhoc_command adhoc_command_list[] = {
-  { "http://jabber.org/protocol/rc#set-status",
-    "Change client status",
-    1,
-    &handle_iq_command_set_status },
-  { "http://jabber.org/protocol/rc#leave-groupchats",
-    "Leave groupchat(s)",
-    1,
-    &handle_iq_command_leave_groupchats },
-  { NULL, NULL, 0, NULL },
-};
-
-struct adhoc_status {
-  char *name;   // the name used by adhoc
-  char *description;
-  char *status; // the string, used by setstus
-};
-
-const struct adhoc_status adhoc_status_list[] = {
-  {"online", "Online", "avail"},
-  {"chat", "Chat", "free"},
-  {"away", "Away", "away"},
-  {"xd", "Extended away", "notavail"},
-  {"dnd", "Do not disturb", "dnd"},
-  {"invisible", "Invisible", "invisible"},
-  {"offline", "Offline", "offline"},
-  {NULL, NULL, NULL},
-};
-
-//  entity_version()
-// Return a static version string for Entity Capabilities.
-// It should be specific to the client version, please change the id
-// if you alter mcabber's disco support (or add something to the version
-// number) so that it doesn't conflict with the official client.
-const char *entity_version(void)
-{
-  static char *ver;
-  const char *PVERSION = PACKAGE_VERSION; // "+xxx";
-
-  if (ver)
-    return ver;
-
-#ifdef HGCSET
-  ver = g_strdup_printf("%s-%s", PVERSION, HGCSET);
-#else
-  ver = g_strdup(PVERSION);
-#endif
-
-  return ver;
-}
-
-//  iqs_new(type, namespace, prefix, timeout)
-// Create a query (GET, SET) IQ structure.  This function should not be used
-// for RESULT packets.
-eviqs *iqs_new(guint8 type, const char *ns, const char *prefix, time_t tmout)
-{
-  static guint iqs_idn;
-  eviqs *new_iqs;
-  time_t now_t;
-
-  iqs_idn++;
-
-  new_iqs = g_new0(eviqs, 1);
-  time(&now_t);
-  new_iqs->ts_create = now_t;
-  if (tmout)
-    new_iqs->ts_expire = now_t + tmout;
-  new_iqs->type = type;
-  new_iqs->xmldata = jutil_iqnew(type, (char*)ns);
-  if (prefix)
-    new_iqs->id = g_strdup_printf("%s_%d", prefix, iqs_idn);
-  else
-    new_iqs->id = g_strdup_printf("%d", iqs_idn);
-  xmlnode_put_attrib(new_iqs->xmldata, "id", new_iqs->id);
-
-  iqs_list = g_slist_append(iqs_list, new_iqs);
-  return new_iqs;
-}
-
-int iqs_del(const char *iqid)
-{
-  GSList *p;
-  eviqs *i;
-
-  if (!iqid) return 1;
-
-  for (p = iqs_list; p; p = g_slist_next(p)) {
-    i = p->data;
-    if (!strcmp(iqid, i->id))
-      break;
-  }
-  if (p) {
-    g_free(i->id);
-    xmlnode_free(i->xmldata);
-    g_free(i->data);
-    g_free(i);
-    iqs_list = g_slist_remove(iqs_list, p->data);
-    return 0; // Ok, deleted
-  }
-  return -1;  // Not found
-}
-
-static eviqs *iqs_find(const char *iqid)
-{
-  GSList *p;
-  eviqs *i;
-
-  if (!iqid) return NULL;
-
-  for (p = iqs_list; p; p = g_slist_next(p)) {
-    i = p->data;
-    if (!strcmp(iqid, i->id))
-      return i;
-  }
-  return NULL;
-}
-
-//  iqs_callback(iqid, xml_result, iqcontext)
-// Callback processing for the iqid message.
-// If we've received an answer, xml_result should point to the xmldata packet.
-// If this is a timeout, xml_result should be NULL.
-// Return 0 in case of success, -1 if the iqid hasn't been found.
-int iqs_callback(const char *iqid, xmlnode xml_result, guint iqcontext)
-{
-  eviqs *i;
-  int retval = 0;
-
-  i = iqs_find(iqid);
-  if (!i) return -1;
-
-  // IQ processing
-  // Note: If xml_result is NULL, this is a timeout
-  if (i->callback)
-    retval = (*i->callback)(i, xml_result, iqcontext);
-
-  iqs_del(iqid);
-  return retval;
-}
-
-void iqs_check_timeout(time_t now_t)
-{
-  GSList *p;
-  eviqs *i;
-
-  p = iqs_list;
-  while (p) {
-    i = p->data;
-    // We must get next IQ eviqs element now because the current one
-    // could be freed.
-    p = g_slist_next(p);
-
-    if ((!i->ts_expire && now_t > i->ts_create + (time_t)IQS_MAX_TIMEOUT) ||
-        (i->ts_expire && now_t > i->ts_expire)) {
-      iqs_callback(i->id, NULL, IQS_CONTEXT_TIMEOUT);
-    }
-  }
-}
-
-void jb_iqs_display_list(void)
-{
-  GSList *p;
-  eviqs *i;
-
-  scr_LogPrint(LPRINT_LOGNORM, "IQ list:");
-  for (p = iqs_list; p; p = g_slist_next(p)) {
-    i = p->data;
-    scr_LogPrint(LPRINT_LOGNORM, "Id [%s]", i->id);
-  }
-  scr_LogPrint(LPRINT_LOGNORM, "End of IQ list.");
-}
-
-static void handle_iq_roster(xmlnode x)
-{
-  xmlnode y;
-  const char *fjid, *name, *group, *sub, *ask;
-  char *cleanalias;
-  enum subscr esub;
-  int need_refresh = FALSE;
-  guint roster_type;
-
-  for (y = xmlnode_get_tag(x, "item"); y; y = xmlnode_get_nextsibling(y)) {
-    char *name_tmp = NULL;
-
-    fjid = xmlnode_get_attrib(y, "jid");
-    name = xmlnode_get_attrib(y, "name");
-    sub = xmlnode_get_attrib(y, "subscription");
-    ask = xmlnode_get_attrib(y, "ask");
-
-    group = xmlnode_get_tag_data(y, "group");
-
-    if (!fjid)
-      continue;
-
-    cleanalias = jidtodisp(fjid);
-
-    esub = sub_none;
-    if (sub) {
-      if (!strcmp(sub, "to"))          esub = sub_to;
-      else if (!strcmp(sub, "from"))   esub = sub_from;
-      else if (!strcmp(sub, "both"))   esub = sub_both;
-      else if (!strcmp(sub, "remove")) esub = sub_remove;
-    }
-
-    if (esub == sub_remove) {
-      roster_del_user(cleanalias);
-      scr_LogPrint(LPRINT_LOGNORM, "Buddy <%s> has been removed "
-                   "from the roster", cleanalias);
-      g_free(cleanalias);
-      need_refresh = TRUE;
-      continue;
-    }
-
-    if (ask && !strcmp(ask, "subscribe"))
-      esub |= sub_pending;
-
-    if (!name) {
-      if (!settings_opt_get_int("roster_hide_domain")) {
-        name = cleanalias;
-      } else {
-        char *p;
-        name = name_tmp = g_strdup(cleanalias);
-        p = strchr(name_tmp, JID_DOMAIN_SEPARATOR);
-        if (p)  *p = '\0';
-      }
-    }
-
-    // Tricky... :-\  My guess is that if there is no JID_DOMAIN_SEPARATOR,
-    // this is an agent.
-    if (strchr(cleanalias, JID_DOMAIN_SEPARATOR))
-      roster_type = ROSTER_TYPE_USER;
-    else
-      roster_type = ROSTER_TYPE_AGENT;
-
-    roster_add_user(cleanalias, name, group, roster_type, esub, 1);
-
-    g_free(name_tmp);
-    g_free(cleanalias);
-  }
-
-  buddylist_build();
-  update_roster = TRUE;
-  if (need_refresh)
-    scr_UpdateBuddyWindow();
-}
-
-//  This callback is reached when mcabber receives the first roster update
-// after the connection.
-static int iqscallback_gotroster(eviqs *iqp, xmlnode xml_result, guint iqcontext)
-{
-  xmlnode x;
-  char *ns;
-
-  // Leave now if we cannot process xml_result
-  if (!xml_result || iqcontext) return -1;
-
-  // Only execute the hook if the roster has been successfully retrieved
-  if (iqcontext != IQS_CONTEXT_RESULT)
-    return 0;
-
-  x = xmlnode_get_tag(xml_result, "query");
-  if (!x)
-    return -1;
-
-  ns = xmlnode_get_attrib(x, "xmlns");
-  if (ns && !strcmp(ns, NS_ROSTER))
-    handle_iq_roster(x);
-
-  // Post-login stuff
-  jb_setprevstatus();
-  hook_execute_internal("hook-post-connect");
-
-  return 0;
-}
-
-static void request_roster(void)
-{
-  eviqs *iqn = iqs_new(JPACKET__GET, NS_ROSTER, "Roster", IQS_DEFAULT_TIMEOUT);
-  iqn->callback = &iqscallback_gotroster;
-  jab_send(jc, iqn->xmldata);
-}
-
-static int iqscallback_version(eviqs *iqp, xmlnode xml_result, guint iqcontext)
-{
-  xmlnode ansqry;
-  char *p;
-  char *bjid;
-  char *buf;
-
-  // Leave now if we cannot process xml_result
-  if (!xml_result || iqcontext) return -1;
-
-  ansqry = xmlnode_get_tag(xml_result, "query");
-  if (!ansqry) {
-    scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:version result!");
-    return 0;
-  }
-  // Display IQ result sender...
-  p = xmlnode_get_attrib(xml_result, "from");
-  if (!p) {
-    scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:version result (no sender name).");
-    return 0;
-  }
-  bjid = p;
-
-  buf = g_strdup_printf("Received IQ:version result from <%s>", bjid);
-  scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
-
-  // bjid should now really be the "bare JID", let's strip the resource
-  p = strchr(bjid, JID_RESOURCE_SEPARATOR);
-  if (p) *p = '\0';
-
-  scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0);
-  g_free(buf);
-
-  // Get result data...
-  p = xmlnode_get_tag_data(ansqry, "name");
-  if (p) {
-    buf = g_strdup_printf("Name:    %s", p);
-    scr_WriteIncomingMessage(bjid, buf,
-                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
-    g_free(buf);
-  }
-  p = xmlnode_get_tag_data(ansqry, "version");
-  if (p) {
-    buf = g_strdup_printf("Version: %s", p);
-    scr_WriteIncomingMessage(bjid, buf,
-                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
-    g_free(buf);
-  }
-  p = xmlnode_get_tag_data(ansqry, "os");
-  if (p) {
-    buf = g_strdup_printf("OS:      %s", p);
-    scr_WriteIncomingMessage(bjid, buf,
-                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
-    g_free(buf);
-  }
-  return 0;
-}
-
-void request_version(const char *fulljid)
-{
-  eviqs *iqn;
-
-  iqn = iqs_new(JPACKET__GET, NS_VERSION, "version", IQS_DEFAULT_TIMEOUT);
-  xmlnode_put_attrib(iqn->xmldata, "to", fulljid);
-  iqn->callback = &iqscallback_version;
-  jab_send(jc, iqn->xmldata);
-}
-
-static int iqscallback_time(eviqs *iqp, xmlnode xml_result, guint iqcontext)
-{
-  xmlnode ansqry;
-  char *p;
-  char *bjid;
-  char *buf;
-
-  // Leave now if we cannot process xml_result
-  if (!xml_result || iqcontext) return -1;
-
-  ansqry = xmlnode_get_tag(xml_result, "query");
-  if (!ansqry) {
-    scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:time result!");
-    return 0;
-  }
-  // Display IQ result sender...
-  p = xmlnode_get_attrib(xml_result, "from");
-  if (!p) {
-    scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:time result (no sender name).");
-    return 0;
-  }
-  bjid = p;
-
-  buf = g_strdup_printf("Received IQ:time result from <%s>", bjid);
-  scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
-
-  // bjid should now really be the "bare JID", let's strip the resource
-  p = strchr(bjid, JID_RESOURCE_SEPARATOR);
-  if (p) *p = '\0';
-
-  scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0);
-  g_free(buf);
-
-  // Get result data...
-  p = xmlnode_get_tag_data(ansqry, "utc");
-  if (p) {
-    buf = g_strdup_printf("UTC:  %s", p);
-    scr_WriteIncomingMessage(bjid, buf,
-                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
-    g_free(buf);
-  }
-  p = xmlnode_get_tag_data(ansqry, "tz");
-  if (p) {
-    buf = g_strdup_printf("TZ:   %s", p);
-    scr_WriteIncomingMessage(bjid, buf,
-                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
-    g_free(buf);
-  }
-  p = xmlnode_get_tag_data(ansqry, "display");
-  if (p) {
-    buf = g_strdup_printf("Time: %s", p);
-    scr_WriteIncomingMessage(bjid, buf,
-                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
-    g_free(buf);
-  }
-  return 0;
-}
-
-void request_time(const char *fulljid)
-{
-  eviqs *iqn;
-
-  iqn = iqs_new(JPACKET__GET, NS_TIME, "time", IQS_DEFAULT_TIMEOUT);
-  xmlnode_put_attrib(iqn->xmldata, "to", fulljid);
-  iqn->callback = &iqscallback_time;
-  jab_send(jc, iqn->xmldata);
-}
-
-static int iqscallback_last(eviqs *iqp, xmlnode xml_result, guint iqcontext)
-{
-  xmlnode ansqry;
-  char *p;
-  char *bjid;
-  char *buf;
-
-  // Leave now if we cannot process xml_result
-  if (!xml_result || iqcontext) return -1;
-
-  ansqry = xmlnode_get_tag(xml_result, "query");
-  if (!ansqry) {
-    scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:last result!");
-    return 0;
-  }
-  // Display IQ result sender...
-  p = xmlnode_get_attrib(xml_result, "from");
-  if (!p) {
-    scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:last result (no sender name).");
-    return 0;
-  }
-  bjid = p;
-
-  buf = g_strdup_printf("Received IQ:last result from <%s>", bjid);
-  scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
-
-  // bjid should now really be the "bare JID", let's strip the resource
-  p = strchr(bjid, JID_RESOURCE_SEPARATOR);
-  if (p) *p = '\0';
-
-  scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0);
-  g_free(buf);
-
-  // Get result data...
-  p = xmlnode_get_attrib(ansqry, "seconds");
-  if (p) {
-    long int s;
-    GString *sbuf;
-    sbuf = g_string_new("Idle time: ");
-    s = atol(p);
-    // Days
-    if (s > 86400L) {
-      g_string_append_printf(sbuf, "%ldd ", s/86400L);
-      s %= 86400L;
-    }
-    // hh:mm:ss
-    g_string_append_printf(sbuf, "%02ld:", s/3600L);
-    s %= 3600L;
-    g_string_append_printf(sbuf, "%02ld:%02ld", s/60L, s%60L);
-    scr_WriteIncomingMessage(bjid, sbuf->str,
-                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
-    g_string_free(sbuf, TRUE);
-  } else {
-    scr_WriteIncomingMessage(bjid, "No idle time reported.",
-                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
-  }
-  p = xmlnode_get_data(ansqry);
-  if (p) {
-    buf = g_strdup_printf("Status message: %s", p);
-    scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0);
-    g_free(buf);
-  }
-  return 0;
-}
-
-void request_last(const char *fulljid)
-{
-  eviqs *iqn;
-
-  iqn = iqs_new(JPACKET__GET, NS_LAST, "last", IQS_DEFAULT_TIMEOUT);
-  xmlnode_put_attrib(iqn->xmldata, "to", fulljid);
-  iqn->callback = &iqscallback_last;
-  jab_send(jc, iqn->xmldata);
-}
-
-static void display_vcard_item(const char *bjid, const char *label,
-                               enum vcard_attr vcard_attrib, const char *text)
-{
-  char *buf;
-
-  if (!text || !bjid || !label)
-    return;
-
-  buf = g_strdup_printf("%s: %s%s%s%s%s%s%s%s%s%s", label,
-                        (vcard_attrib & vcard_home ? "[home]" : ""),
-                        (vcard_attrib & vcard_work ? "[work]" : ""),
-                        (vcard_attrib & vcard_postal ? "[postal]" : ""),
-                        (vcard_attrib & vcard_voice ? "[voice]" : ""),
-                        (vcard_attrib & vcard_fax  ? "[fax]"  : ""),
-                        (vcard_attrib & vcard_cell ? "[cell]" : ""),
-                        (vcard_attrib & vcard_inet ? "[inet]" : ""),
-                        (vcard_attrib & vcard_pref ? "[pref]" : ""),
-                        (vcard_attrib ? " " : ""),
-                        text);
-  scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
-  g_free(buf);
-}
-
-static void handle_vcard_node(const char *barejid, xmlnode vcardnode)
-{
-  xmlnode x;
-  const char *p;
-
-  x = xmlnode_get_firstchild(vcardnode);
-  for ( ; x; x = xmlnode_get_nextsibling(x)) {
-    const char *data;
-    enum vcard_attr vcard_attrib = 0;
-
-    p = xmlnode_get_name(x);
-    data = xmlnode_get_data(x);
-    if (!p || !data)
-      continue;
-
-    if (!strcmp(p, "FN"))
-      display_vcard_item(barejid, "Name", vcard_attrib, data);
-    else if (!strcmp(p, "NICKNAME"))
-      display_vcard_item(barejid, "Nickname", vcard_attrib, data);
-    else if (!strcmp(p, "URL"))
-      display_vcard_item(barejid, "URL", vcard_attrib, data);
-    else if (!strcmp(p, "BDAY"))
-      display_vcard_item(barejid, "Birthday", vcard_attrib, data);
-    else if (!strcmp(p, "TZ"))
-      display_vcard_item(barejid, "Timezone", vcard_attrib, data);
-    else if (!strcmp(p, "TITLE"))
-      display_vcard_item(barejid, "Title", vcard_attrib, data);
-    else if (!strcmp(p, "ROLE"))
-      display_vcard_item(barejid, "Role", vcard_attrib, data);
-    else if (!strcmp(p, "DESC"))
-      display_vcard_item(barejid, "Comment", vcard_attrib, data);
-    else if (!strcmp(p, "N")) {
-      data = xmlnode_get_tag_data(x, "FAMILY");
-      display_vcard_item(barejid, "Family Name", vcard_attrib, data);
-      data = xmlnode_get_tag_data(x, "GIVEN");
-      display_vcard_item(barejid, "Given Name", vcard_attrib, data);
-      data = xmlnode_get_tag_data(x, "MIDDLE");
-      display_vcard_item(barejid, "Middle Name", vcard_attrib, data);
-    } else if (!strcmp(p, "ORG")) {
-      data = xmlnode_get_tag_data(x, "ORGNAME");
-      display_vcard_item(barejid, "Organisation name", vcard_attrib, data);
-      data = xmlnode_get_tag_data(x, "ORGUNIT");
-      display_vcard_item(barejid, "Organisation unit", vcard_attrib, data);
-    } else {
-      // The HOME, WORK and PREF attributes are common to the remaining fields
-      // (ADR, TEL & EMAIL)
-      if (xmlnode_get_tag(x, "HOME"))
-        vcard_attrib |= vcard_home;
-      if (xmlnode_get_tag(x, "WORK"))
-        vcard_attrib |= vcard_work;
-      if (xmlnode_get_tag(x, "PREF"))
-        vcard_attrib |= vcard_pref;
-      if (!strcmp(p, "ADR")) {          // Address
-        if (xmlnode_get_tag(x, "POSTAL"))
-          vcard_attrib |= vcard_postal;
-        data = xmlnode_get_tag_data(x, "EXTADD");
-        display_vcard_item(barejid, "Addr (ext)", vcard_attrib, data);
-        data = xmlnode_get_tag_data(x, "STREET");
-        display_vcard_item(barejid, "Street", vcard_attrib, data);
-        data = xmlnode_get_tag_data(x, "LOCALITY");
-        display_vcard_item(barejid, "Locality", vcard_attrib, data);
-        data = xmlnode_get_tag_data(x, "REGION");
-        display_vcard_item(barejid, "Region", vcard_attrib, data);
-        data = xmlnode_get_tag_data(x, "PCODE");
-        display_vcard_item(barejid, "Postal code", vcard_attrib, data);
-        data = xmlnode_get_tag_data(x, "CTRY");
-        display_vcard_item(barejid, "Country", vcard_attrib, data);
-      } else if (!strcmp(p, "TEL")) {   // Telephone
-        data = xmlnode_get_tag_data(x, "NUMBER");
-        if (data) {
-          if (xmlnode_get_tag(x, "VOICE"))
-            vcard_attrib |= vcard_voice;
-          if (xmlnode_get_tag(x, "FAX"))
-            vcard_attrib |= vcard_fax;
-          if (xmlnode_get_tag(x, "CELL"))
-            vcard_attrib |= vcard_cell;
-          display_vcard_item(barejid, "Phone", vcard_attrib, data);
-        }
-      } else if (!strcmp(p, "EMAIL")) { // Email
-        if (xmlnode_get_tag(x, "INTERNET"))
-          vcard_attrib |= vcard_inet;
-        data = xmlnode_get_tag_data(x, "USERID");
-        display_vcard_item(barejid, "Email", vcard_attrib, data);
-      }
-    }
-  }
-}
-
-static int iqscallback_vcard(eviqs *iqp, xmlnode xml_result, guint iqcontext)
-{
-  xmlnode ansqry;
-  char *p;
-  char *bjid;
-  char *buf;
-
-  // Leave now if we cannot process xml_result
-  if (!xml_result || iqcontext) return -1;
-
-  // Display IQ result sender...
-  p = xmlnode_get_attrib(xml_result, "from");
-  if (!p) {
-    scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:vCard result (no sender name).");
-    return 0;
-  }
-  bjid = p;
-
-  buf = g_strdup_printf("Received IQ:vCard result from <%s>", bjid);
-  scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
-
-  // Get the vCard node
-  ansqry = xmlnode_get_tag(xml_result, "vCard");
-  if (!ansqry) {
-    scr_LogPrint(LPRINT_LOGNORM, "Empty IQ:vCard result!");
-    g_free(buf);
-    return 0;
-  }
-
-  // bjid should really be the "bare JID", let's strip the resource
-  p = strchr(bjid, JID_RESOURCE_SEPARATOR);
-  if (p) *p = '\0';
-
-  scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0);
-  g_free(buf);
-
-  // Get result data...
-  handle_vcard_node(bjid, ansqry);
-  return 0;
-}
-
-void request_vcard(const char *bjid)
-{
-  eviqs *iqn;
-
-  // Create a new IQ structure.  We use NULL for the namespace because
-  // we'll have to use a special tag, not the usual "query" one.
-  iqn = iqs_new(JPACKET__GET, NULL, "vcard", IQS_DEFAULT_TIMEOUT);
-  xmlnode_put_attrib(iqn->xmldata, "to", bjid);
-  // Remove the useless <query/> tag, and insert a vCard one.
-  xmlnode_hide(xmlnode_get_tag(iqn->xmldata, "query"));
-  xmlnode_put_attrib(xmlnode_insert_tag(iqn->xmldata, "vCard"),
-                     "xmlns", NS_VCARD);
-  iqn->callback = &iqscallback_vcard;
-  jab_send(jc, iqn->xmldata);
-}
-
-static void storage_bookmarks_parse_conference(xmlnode xmldata)
-{
-  const char *fjid, *name, *autojoin;
-  const char *pstatus, *awhois;
-  char *bjid;
-  GSList *room_elt;
-
-  fjid = xmlnode_get_attrib(xmldata, "jid");
-  if (!fjid)
-    return;
-  name = xmlnode_get_attrib(xmldata, "name");
-  autojoin = xmlnode_get_attrib(xmldata, "autojoin");
-  awhois = xmlnode_get_attrib(xmldata, "autowhois");
-  pstatus = xmlnode_get_tag_data(xmldata, "print_status");
-
-  bjid = jidtodisp(fjid); // Bare jid
-
-  // Make sure this is a room (it can be a conversion user->room)
-  room_elt = roster_find(bjid, jidsearch, 0);
-  if (!room_elt) {
-    room_elt = roster_add_user(bjid, name, NULL, ROSTER_TYPE_ROOM,
-                               sub_none, -1);
-  } else {
-    buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
-    /*
-    // If the name is available, should we use it?
-    // I don't think so, it would be confusing because this item is already
-    // in the roster.
-    if (name)
-      buddy_setname(room_elt->data, name);
-    */
-  }
-
-  // Set the print_status and auto_whois values
-  if (pstatus) {
-    enum room_printstatus i;
-    for (i = status_none; i <= status_all; i++)
-      if (!strcasecmp(pstatus, strprintstatus[i]))
-        break;
-    if (i <= status_all)
-      buddy_setprintstatus(room_elt->data, i);
-  }
-  if (awhois) {
-    enum room_autowhois i = autowhois_default;
-    if (!strcmp(awhois, "1"))
-      i = autowhois_on;
-    else if (!strcmp(awhois, "0"))
-      i = autowhois_off;
-    if (i != autowhois_default)
-      buddy_setautowhois(room_elt->data, i);
-  }
-
-  // Is autojoin set?
-  // If it is, we'll look up for more information (nick? password?) and
-  // try to join the room.
-  if (autojoin && !strcmp(autojoin, "1")) {
-    char *nick, *passwd;
-    char *tmpnick = NULL;
-    nick = xmlnode_get_tag_data(xmldata, "nick");
-    passwd = xmlnode_get_tag_data(xmldata, "password");
-    if (!nick || !*nick)
-      nick = tmpnick = default_muc_nickname(NULL);
-    // Let's join now
-    scr_LogPrint(LPRINT_LOGNORM, "Auto-join bookmark <%s>", bjid);
-    jb_room_join(bjid, nick, passwd);
-    g_free(tmpnick);
-  }
-  g_free(bjid);
-}
-
-static int iqscallback_storage_bookmarks(eviqs *iqp, xmlnode xml_result,
-                                         guint iqcontext)
-{
-  xmlnode x, ansqry;
-  char *p;
-
-  if (iqcontext == IQS_CONTEXT_ERROR) {
-    // No server support, or no bookmarks?
-    p = xmlnode_get_name(xmlnode_get_firstchild(xml_result));
-    if (p && !strcmp(p, "item-not-found")) {
-      // item-no-found means the server has Private Storage, but it's
-      // currently empty.
-      xmlnode_free(bookmarks);
-      bookmarks = xmlnode_new_tag("storage");
-      xmlnode_put_attrib(bookmarks, "xmlns", "storage:bookmarks");
-      // We return 0 so that the IQ error message be
-      // not displayed, as it isn't a real error.
-      return 0;
-    }
-    return -1; // Unhandled error
-  }
-
-  // Leave now if we cannot process xml_result
-  if (!xml_result || iqcontext) return 0;
-
-  ansqry = xmlnode_get_tag(xml_result, "query");
-  ansqry = xmlnode_get_tag(ansqry, "storage");
-  if (!ansqry) {
-    scr_LogPrint(LPRINT_LOG, "Invalid IQ:private result! (storage:bookmarks)");
-    return 0;
-  }
-
-  // Walk through the storage tags
-  x = xmlnode_get_firstchild(ansqry);
-  for ( ; x; x = xmlnode_get_nextsibling(x)) {
-    p = xmlnode_get_name(x);
-    // If the current node is a conference item, parse it and update the roster
-    if (p && !strcmp(p, "conference"))
-      storage_bookmarks_parse_conference(x);
-  }
-  // Copy the bookmarks node
-  xmlnode_free(bookmarks);
-  bookmarks = xmlnode_dup(ansqry);
-  return 0;
-}
-
-static void request_storage_bookmarks(void)
-{
-  eviqs *iqn;
-  xmlnode x;
-
-  iqn = iqs_new(JPACKET__GET, NS_PRIVATE, "storage", IQS_DEFAULT_TIMEOUT);
-
-  x = xmlnode_insert_tag(xmlnode_get_tag(iqn->xmldata, "query"), "storage");
-  xmlnode_put_attrib(x, "xmlns", "storage:bookmarks");
-
-  iqn->callback = &iqscallback_storage_bookmarks;
-  jab_send(jc, iqn->xmldata);
-}
-
-static int iqscallback_storage_rosternotes(eviqs *iqp, xmlnode xml_result,
-                                           guint iqcontext)
-{
-  xmlnode ansqry;
-
-  if (iqcontext == IQS_CONTEXT_ERROR) {
-    const char *p;
-    // No server support, or no roster notes?
-    p = xmlnode_get_name(xmlnode_get_firstchild(xml_result));
-    if (p && !strcmp(p, "item-not-found")) {
-      // item-no-found means the server has Private Storage, but it's
-      // currently empty.
-      xmlnode_free(rosternotes);
-      rosternotes = xmlnode_new_tag("storage");
-      xmlnode_put_attrib(rosternotes, "xmlns", "storage:rosternotes");
-      // We return 0 so that the IQ error message be
-      // not displayed, as it isn't a real error.
-      return 0;
-    }
-    return -1; // Unhandled error
-  }
-
-  // Leave now if we cannot process xml_result
-  if (!xml_result || iqcontext) return 0;
-
-  ansqry = xmlnode_get_tag(xml_result, "query");
-  ansqry = xmlnode_get_tag(ansqry, "storage");
-  if (!ansqry) {
-    scr_LogPrint(LPRINT_LOG, "Invalid IQ:private result! "
-                 "(storage:rosternotes)");
-    return 0;
-  }
-  // Copy the rosternotes node
-  xmlnode_free(rosternotes);
-  rosternotes = xmlnode_dup(ansqry);
-  return 0;
-}
-
-static void request_storage_rosternotes(void)
-{
-  eviqs *iqn;
-  xmlnode x;
-
-  iqn = iqs_new(JPACKET__GET, NS_PRIVATE, "storage", IQS_DEFAULT_TIMEOUT);
-
-  x = xmlnode_insert_tag(xmlnode_get_tag(iqn->xmldata, "query"), "storage");
-  xmlnode_put_attrib(x, "xmlns", "storage:rosternotes");
-
-  iqn->callback = &iqscallback_storage_rosternotes;
-  jab_send(jc, iqn->xmldata);
-}
-
-int iqscallback_auth(eviqs *iqp, xmlnode xml_result, guint iqcontext)
-{
-  if (iqcontext == IQS_CONTEXT_ERROR)
-    return -1;
-
-  if (jstate == STATE_GETAUTH) {
-    eviqs *iqn;
-
-    if (xml_result) {
-      xmlnode x = xmlnode_get_tag(xml_result, "query");
-      if (x && !xmlnode_get_tag(x, "digest"))
-        jc->sid = 0;
-    }
-
-    iqn = iqs_new(JPACKET__SET, NS_AUTH, "auth", IQS_DEFAULT_TIMEOUT);
-    iqn->callback = &iqscallback_auth;
-    jab_auth_mcabber(jc, iqn->xmldata);
-    jab_send(jc, iqn->xmldata);
-    jstate = STATE_SENDAUTH;
-  } else if (jstate == STATE_SENDAUTH) {
-    request_roster();
-    request_storage_bookmarks();
-    request_storage_rosternotes();
-    jstate = STATE_LOGGED;
-  }
-  return 0;
-}
-
-static void handle_iq_result(jconn conn, char *from, xmlnode xmldata)
-{
-  char *id = xmlnode_get_attrib(xmldata, "id");
-
-  if (!id) {
-    scr_LogPrint(LPRINT_LOG, "IQ result stanza with no ID, ignored.");
-    return;
-  }
-
-  (void)iqs_callback(id, xmldata, IQS_CONTEXT_RESULT);
-}
-
-// FIXME  highly duplicated code
-static void send_iq_not_implemented(jconn conn, char *from, xmlnode xmldata)
-{
-  xmlnode x, y, z;
-  // Not implemented.
-  x = xmlnode_dup(xmldata);
-  xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
-  xmlnode_hide_attrib(x, "from");
-
-  xmlnode_put_attrib(x, "type", TMSG_ERROR);
-  y = xmlnode_insert_tag(x, TMSG_ERROR);
-  xmlnode_put_attrib(y, "code", "501");
-  xmlnode_put_attrib(y, "type", "cancel");
-  z = xmlnode_insert_tag(y, "feature-not-implemented");
-  xmlnode_put_attrib(z, "xmlns", NS_XMPP_STANZAS);
-
-  jab_send(conn, x);
-  xmlnode_free(x);
-}
-
-// FIXME  highly duplicated code
-static void send_iq_not_available(jconn conn, char *from, xmlnode xmldata)
-{
-  xmlnode x, y, z;
-  // Not available.
-  x = xmlnode_dup(xmldata);
-  xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
-  xmlnode_hide_attrib(x, "from");
-
-  xmlnode_put_attrib(x, "type", TMSG_ERROR);
-  y = xmlnode_insert_tag(x, TMSG_ERROR);
-  xmlnode_put_attrib(y, "code", "503");
-  xmlnode_put_attrib(y, "type", "cancel");
-  z = xmlnode_insert_tag(y, "service-unavailable");
-  xmlnode_put_attrib(z, "xmlns", NS_XMPP_STANZAS);
-
-  jab_send(conn, x);
-  xmlnode_free(x);
-}
-
-/*
-static void send_iq_commands_bad_action(jconn conn, char *from, xmlnode xmldata)
-{
-  xmlnode x, y, z;
-
-  x = xmlnode_dup(xmldata);
-  xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
-  xmlnode_hide_attrib(x, "from");
-
-  xmlnode_put_attrib(x, "type", TMSG_ERROR);
-  y = xmlnode_insert_tag(x, TMSG_ERROR);
-  xmlnode_put_attrib(y, "code", "400");
-  xmlnode_put_attrib(y, "type", "modify");
-  z = xmlnode_insert_tag(y, "bad-request");
-  xmlnode_put_attrib(z, "xmlns", NS_XMPP_STANZAS);
-  z = xmlnode_insert_tag(y, "bad-action");
-  xmlnode_put_attrib(z, "xmlns", NS_COMMANDS);
-
-  jab_send(conn, x);
-  xmlnode_free(x);
-}
-*/
-
-static void send_iq_forbidden(jconn conn, char *from, xmlnode xmldata)
-{
-  xmlnode x, y, z;
-
-  x = xmlnode_dup(xmldata);
-  xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
-  xmlnode_hide_attrib(x, "from");
-
-  xmlnode_put_attrib(x, "type", TMSG_ERROR);
-  y = xmlnode_insert_tag(x, TMSG_ERROR);
-  xmlnode_put_attrib(y, "code", "403");
-  xmlnode_put_attrib(y, "type", "cancel");
-  z = xmlnode_insert_tag(y, "forbidden");
-  xmlnode_put_attrib(z, "xmlns", NS_XMPP_STANZAS);
-
-  jab_send(conn, x);
-  xmlnode_free(x);
-}
-
-static void send_iq_commands_malformed_action(jconn conn, char *from,
-                                              xmlnode xmldata)
-{
-  xmlnode x, y, z;
-
-  x = xmlnode_dup(xmldata);
-  xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
-  xmlnode_hide_attrib(x, "from");
-
-  xmlnode_put_attrib(x, "type", TMSG_ERROR);
-  y = xmlnode_insert_tag(x, TMSG_ERROR);
-  xmlnode_put_attrib(y, "code", "400");
-  xmlnode_put_attrib(y, "type", "modify");
-  z = xmlnode_insert_tag(y, "bad-request");
-  xmlnode_put_attrib(z, "xmlns", NS_XMPP_STANZAS);
-  z = xmlnode_insert_tag(y, "malformed-action");
-  xmlnode_put_attrib(z, "xmlns", NS_COMMANDS);
-
-  jab_send(conn, x);
-  xmlnode_free(x);
-}
-
-static void handle_iq_commands_list(jconn conn, char *from, const char *id,
-                                    xmlnode xmldata)
-{
-  xmlnode x;
-  xmlnode myquery;
-  jid requester_jid;
-  const struct adhoc_command *command;
-  const char *node;
-  bool from_self;
-
-  x = jutil_iqnew(JPACKET__RESULT, NS_DISCO_ITEMS);
-  xmlnode_put_attrib(x, "id", id);
-  xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
-  myquery = xmlnode_get_tag(x, "query");
-
-  node = xmlnode_get_attrib(xmlnode_get_tag(xmldata, "query"), "node");
-  if (node)
-    xmlnode_put_attrib(myquery, "node", node);
-
-  requester_jid = jid_new(conn->p, xmlnode_get_attrib(xmldata, "from"));
-  from_self = !jid_cmpx(conn->user, requester_jid, JID_USER | JID_SERVER);
-
-  for (command = adhoc_command_list ; command->name ; command++) {
-    if (!command->only_for_self || from_self) {
-      xmlnode item;
-      item = xmlnode_insert_tag(myquery, "item");
-      xmlnode_put_attrib(item, "node", command->name);
-      xmlnode_put_attrib(item, "name", command->description);
-      xmlnode_put_attrib(item, "jid", jid_full(conn->user));
-    }
-  }
-
-  jab_send(jc, x);
-  xmlnode_free(x);
-}
-
-static void xmlnode_insert_dataform_result_message(xmlnode node, char *message)
-{
-  xmlnode x, field, value;
-
-  x = xmlnode_insert_tag(node, "x");
-  xmlnode_put_attrib(x, "type", "result");
-  xmlnode_put_attrib(x, "xmlns", "jabber:x:data");
-
-  field = xmlnode_insert_tag(x, "field");
-  xmlnode_put_attrib(field, "type", "text-single");
-  xmlnode_put_attrib(field, "var", "message");
-
-  value = xmlnode_insert_tag(field, "value");
-  xmlnode_insert_cdata(value, message, -1);
-}
-
-static char *generate_session_id(char *prefix)
-{
-  char *result;
-  static int counter = 0;
-  counter++;
-  // TODO better use timestamp?
-  result = g_strdup_printf("%s-%i", prefix, counter);
-  return result;
-}
-
-static void handle_iq_command_set_status(jconn conn, char *from, const char *id,
-                                          xmlnode xmldata)
-{
-  char *action, *node, *sessionid;
-  xmlnode iq, command, x, y;
-  const struct adhoc_status *s;
-
-  x = xmlnode_get_tag(xmldata, "command");
-  action = xmlnode_get_attrib(x, "action");
-  node = xmlnode_get_attrib(x, "node");
-  sessionid = xmlnode_get_attrib(x, "sessionid");
-
-  iq = xmlnode_new_tag("iq");
-  command = xmlnode_insert_tag(iq, "command");
-  xmlnode_put_attrib(command, "node", node);
-  xmlnode_put_attrib(command, "xmlns", NS_COMMANDS);
-
-  if (!sessionid) {
-    xmlnode value;
-
-    sessionid = generate_session_id("set-status");
-    xmlnode_put_attrib(command, "sessionid", sessionid);
-    g_free(sessionid);
-    sessionid = NULL;
-    xmlnode_put_attrib(command, "status", "executing");
-
-    x = xmlnode_insert_tag(command, "x");
-    xmlnode_put_attrib(x, "type", "form");
-    xmlnode_put_attrib(x, "xmlns", "jabber:x:data");
-
-    y = xmlnode_insert_tag(x, "title");
-    xmlnode_insert_cdata(y, "Change Status", -1);
-
-    y = xmlnode_insert_tag(x, "instructions");
-    xmlnode_insert_cdata(y, "Choose the status and status message", -1);
-
-    // TODO see if factorisation is possible
-    // (with xmlnode_insert_dataform_result_message)
-    y = xmlnode_insert_tag(x, "field");
-    xmlnode_put_attrib(y, "type", "hidden");
-    xmlnode_put_attrib(y, "var", "FORM_TYPE");
-
-    value = xmlnode_insert_tag(y, "value");
-    xmlnode_insert_cdata(value, "http://jabber.org/protocol/rc", -1);
-
-    y = xmlnode_insert_tag(x, "field");
-    xmlnode_put_attrib(y, "type", "list-single");
-    xmlnode_put_attrib(y, "var", "status");
-    xmlnode_put_attrib(y, "label", "Status");
-    xmlnode_insert_tag(y, "required");
-
-    value = xmlnode_insert_tag(y, "value");
-    // TODO current status
-    xmlnode_insert_cdata(value, "online", -1);
-    for (s = adhoc_status_list; s->name; s++) {
-        xmlnode option = xmlnode_insert_tag(y, "option");
-        value = xmlnode_insert_tag(option, "value");
-        xmlnode_insert_cdata(value, s->name, -1);
-        xmlnode_put_attrib(option, "label", s->description);
-    }
-    // TODO add priority ?
-    // I do not think this is useful, user should not have to care of the
-    // priority like gossip and gajim do (misc)
-    y = xmlnode_insert_tag(x, "field");
-    xmlnode_put_attrib(y, "type", "text-single");
-    xmlnode_put_attrib(y, "var", "status-message");
-    xmlnode_put_attrib(y, "label", "Message");
-  } else if (action && !strcmp(action, "cancel")) {
-    xmlnode_put_attrib(command, "status", "canceled");
-  } else  { // (if sessionid and not canceled)
-    y = xmlnode_get_tag(x, "x?xmlns=jabber:x:data");
-    if (y) {
-      char *value, *message;
-      value = xmlnode_get_tag_data(xmlnode_get_tag(y, "field?var=status"),
-                                   "value");
-      message = xmlnode_get_tag_data(xmlnode_get_tag(y,
-                                   "field?var=status-message"), "value");
-      if (value) {
-        for (s = adhoc_status_list; s->name && strcmp(s->name, value); s++);
-        if (s->name) {
-          char *status = g_strdup_printf("%s %s", s->status,
-                                         message ? message : "");
-          cmd_setstatus(NULL, status);
-          g_free(status);
-          xmlnode_put_attrib(command, "status", "completed");
-          xmlnode_put_attrib(iq, "type", "result");
-          xmlnode_insert_dataform_result_message(command,
-                                                 "Status has been changed");
-        }
-      }
-    }
-  }
-  if (sessionid)
-    xmlnode_put_attrib(command, "sessionid", sessionid);
-  xmlnode_put_attrib(iq, "to", xmlnode_get_attrib(xmldata, "from"));
-  xmlnode_put_attrib(iq, "id", id);
-  jab_send(jc, iq);
-  xmlnode_free(iq);
-}
-
-static void _callback_foreach_buddy_groupchat(gpointer rosterdata, void *param)
-{
-  xmlnode value, option;
-  xmlnode *field;
-  const char *room_jid, *nickname;
-  char *desc;
-
-  room_jid = buddy_getjid(rosterdata);
-  if (!room_jid) return;
-  nickname = buddy_getnickname(rosterdata);
-  if (!nickname) return;
-  field = param;
-
-  option = xmlnode_insert_tag(*field, "option");
-  value = xmlnode_insert_tag(option, "value");
-  xmlnode_insert_cdata(value, room_jid, -1);
-  desc = g_strdup_printf("%s on %s", nickname, room_jid);
-  xmlnode_put_attrib(option, "label", desc);
-  g_free(desc);
-}
-
-static void handle_iq_command_leave_groupchats(jconn conn, char *from,
-                                               const char *id, xmlnode xmldata)
-{
-  char *action, *node, *sessionid;
-  xmlnode iq, command, x;
-
-  x = xmlnode_get_tag(xmldata, "command");
-  action = xmlnode_get_attrib(x, "action");
-  node = xmlnode_get_attrib(x, "node");
-  sessionid = xmlnode_get_attrib(x, "sessionid");
-
-  iq = xmlnode_new_tag("iq");
-  command = xmlnode_insert_tag(iq, "command");
-  xmlnode_put_attrib(command, "node", node);
-  xmlnode_put_attrib(command, "xmlns", NS_COMMANDS);
-
-  if (!sessionid) {
-    xmlnode title, instructions, field, value;
-
-    sessionid = generate_session_id("leave-groupchats");
-    xmlnode_put_attrib(command, "sessionid", sessionid);
-    g_free(sessionid);
-    sessionid = NULL;
-    xmlnode_put_attrib(command, "status", "executing");
-
-    x = xmlnode_insert_tag(command, "x");
-    xmlnode_put_attrib(x, "type", "form");
-    xmlnode_put_attrib(x, "xmlns", "jabber:x:data");
-
-    title = xmlnode_insert_tag(x, "title");
-    xmlnode_insert_cdata(title, "Leave groupchat(s)", -1);
-
-    instructions = xmlnode_insert_tag(x, "instructions");
-    xmlnode_insert_cdata(instructions, "What groupchats do you want to leave?",
-                         -1);
-
-    field = xmlnode_insert_tag(x, "field");
-    xmlnode_put_attrib(field, "type", "hidden");
-    xmlnode_put_attrib(field, "var", "FORM_TYPE");
-
-    value = xmlnode_insert_tag(field, "value");
-    xmlnode_insert_cdata(value, "http://jabber.org/protocol/rc", -1);
-
-    field = xmlnode_insert_tag(x, "field");
-    xmlnode_put_attrib(field, "type", "list-multi");
-    xmlnode_put_attrib(field, "var", "groupchats");
-    xmlnode_put_attrib(field, "label", "Groupchats: ");
-    xmlnode_insert_tag(field, "required");
-
-    foreach_buddy(ROSTER_TYPE_ROOM, &_callback_foreach_buddy_groupchat, &field);
-  } else if (action && !strcmp(action, "cancel")) {
-    xmlnode_put_attrib(command, "status", "canceled");
-  } else  { // (if sessionid and not canceled)
-    xmlnode form = xmlnode_get_tag(x, "x?xmlns=jabber:x:data");
-    if (form) {
-      xmlnode x, gc;
-
-      xmlnode_put_attrib(command, "status", "completed");
-      gc = xmlnode_get_tag(form, "field?var=groupchats");
-
-      for (x = xmlnode_get_firstchild(gc) ; x ; x = xmlnode_get_nextsibling(x))
-      {
-        char* to_leave = xmlnode_get_tag_data(x, "value");
-        if (to_leave) {
-          GList* b = buddy_search_jid(to_leave);
-          if (b)
-            cmd_room_leave(b->data, "Requested by remote command");
-        }
-      }
-      xmlnode_put_attrib(iq, "type", "result");
-      xmlnode_insert_dataform_result_message(command,
-                                             "Groupchats have been left");
-    }
-  }
-  if (sessionid)
-    xmlnode_put_attrib(command, "sessionid", sessionid);
-  xmlnode_put_attrib(iq, "to", xmlnode_get_attrib(xmldata, "from"));
-  xmlnode_put_attrib(iq, "id", id);
-  jab_send(jc, iq);
-  xmlnode_free(iq);
-}
-
-static void handle_iq_commands(jconn conn, char *from, const char *id,
-                               xmlnode xmldata)
-{
-  jid requester_jid;
-  xmlnode x;
-  const struct adhoc_command *command;
-
-  requester_jid = jid_new(conn->p, xmlnode_get_attrib(xmldata, "from"));
-  x = xmlnode_get_tag(xmldata, "command");
-  if (!jid_cmpx(conn->user, requester_jid, JID_USER | JID_SERVER) ) {
-    char *action, *node;
-    action = xmlnode_get_attrib(x, "action");
-    node = xmlnode_get_attrib(x, "node");
-    // action can be NULL, in which case it seems to take the default,
-    // ie execute
-    if (!action || !strcmp(action, "execute") || !strcmp(action, "cancel")
-        || !strcmp(action, "next") || !strcmp(action, "complete")) {
-      for (command = adhoc_command_list; command->name; command++) {
-        if (!strcmp(node, command->name))
-          command->callback(conn, from, id, xmldata);
-      }
-      // "prev" action will get there, as we do not implement it,
-      // and do not authorize it
-    } else {
-      send_iq_commands_malformed_action(conn, from, xmldata);
-    }
-  } else {
-    send_iq_forbidden(conn, from, xmldata);
-  }
-}
-
-static void handle_iq_disco_items(jconn conn, char *from, const char *id,
-                                  xmlnode xmldata)
-{
-  xmlnode x;
-  const char *node;
-  x = xmlnode_get_tag(xmldata, "query");
-  node = xmlnode_get_attrib(x, "node");
-  if (node) {
-    if (!strcmp(node, NS_COMMANDS)) {
-      handle_iq_commands_list(conn, from, id, xmldata);
-    } else {
-      send_iq_not_implemented(conn, from, xmldata);
-    }
-  } else {
-    // not sure about this one
-    send_iq_not_implemented(conn, from, xmldata);
-  }
-}
-
-//  disco_info_set_ext(ansquery, ext)
-// Add features attributes to ansquery for extension ext.
-static void disco_info_set_ext(xmlnode ansquery, const char *ext)
-{
-  char *nodename;
-  nodename = g_strdup_printf("%s#%s", MCABBER_CAPS_NODE, ext);
-  xmlnode_put_attrib(ansquery, "node", nodename);
-  g_free(nodename);
-  if (!strcasecmp(ext, "csn")) {
-    // I guess it's ok to send this even if it's not compiled in.
-    xmlnode_put_attrib(xmlnode_insert_tag(ansquery, "feature"),
-                       "var", NS_CHATSTATES);
-  }
-  if (!strcasecmp(ext, "iql")) {
-    // I guess it's ok to send this even if it's not compiled in.
-    xmlnode_put_attrib(xmlnode_insert_tag(ansquery, "feature"),
-                       "var", NS_LAST);
-  }
-}
-
-//  disco_info_set_default(ansquery, entitycaps)
-// Add features attributes to ansquery.  If entitycaps is TRUE, assume
-// that we're answering an Entity Caps request (if not, the request was
-// a basic discovery query).
-// Please change the entity version string if you modify mcabber disco
-// source code, so that it doesn't conflict with the upstream client.
-static void disco_info_set_default(xmlnode ansquery, guint entitycaps)
-{
-  xmlnode y;
-  char *eversion;
-
-  eversion = g_strdup_printf("%s#%s", MCABBER_CAPS_NODE, entity_version());
-  xmlnode_put_attrib(ansquery, "node", eversion);
-  g_free(eversion);
-
-  y = xmlnode_insert_tag(ansquery, "identity");
-  xmlnode_put_attrib(y, "category", "client");
-  xmlnode_put_attrib(y, "type", "pc");
-  xmlnode_put_attrib(y, "name", PACKAGE_NAME);
-
-  xmlnode_put_attrib(xmlnode_insert_tag(ansquery, "feature"),
-                     "var", NS_DISCO_INFO);
-  xmlnode_put_attrib(xmlnode_insert_tag(ansquery, "feature"),
-                     "var", NS_MUC);
-#ifdef JEP0085
-  // Advertise ChatStates only if we're not using Entity Capabilities
-  if (!entitycaps)
-    xmlnode_put_attrib(xmlnode_insert_tag(ansquery, "feature"),
-                       "var", NS_CHATSTATES);
-#endif
-  xmlnode_put_attrib(xmlnode_insert_tag(ansquery, "feature"),
-                     "var", NS_TIME);
-  xmlnode_put_attrib(xmlnode_insert_tag(ansquery, "feature"),
-                     "var", NS_XMPP_TIME);
-  xmlnode_put_attrib(xmlnode_insert_tag(ansquery, "feature"),
-                     "var", NS_VERSION);
-  xmlnode_put_attrib(xmlnode_insert_tag(ansquery, "feature"),
-                     "var", NS_PING);
-  xmlnode_put_attrib(xmlnode_insert_tag(ansquery, "feature"),
-                     "var", NS_COMMANDS);
-  if (!entitycaps)
-    xmlnode_put_attrib(xmlnode_insert_tag(ansquery, "feature"),
-                       "var", NS_LAST);
-}
-
-static void handle_iq_disco_info(jconn conn, char *from, const char *id,
-                                 xmlnode xmldata)
-{
-  xmlnode x;
-  xmlnode myquery;
-  char *node;
-
-  x = jutil_iqnew(JPACKET__RESULT, NS_DISCO_INFO);
-  xmlnode_put_attrib(x, "id", id);
-  xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
-  myquery = xmlnode_get_tag(x, "query");
-
-  node = xmlnode_get_attrib(xmlnode_get_tag(xmldata, "query"), "node");
-  if (node && startswith(node, MCABBER_CAPS_NODE "#", FALSE)) {
-    const char *param = node+strlen(MCABBER_CAPS_NODE)+1;
-    if (!strcmp(param, entity_version()))
-      disco_info_set_default(myquery, TRUE);  // client#version
-    else
-      disco_info_set_ext(myquery, param);     // client#extension
-  } else {
-    // Basic discovery request
-    disco_info_set_default(myquery, FALSE);
-  }
-
-  jab_send(jc, x);
-  xmlnode_free(x);
-}
-
-double seconds_since_last_use(void)
-{
-  return difftime(time(NULL), iqlast);
-}
-
-static void handle_iq_last(jconn conn, char *from, const char *id,
-                           xmlnode xmldata)
-{
-  xmlnode x;
-  xmlnode myquery;
-  char *seconds;
-
-  if (!settings_opt_get_int("iq_hide_requests")) {
-    scr_LogPrint(LPRINT_LOGNORM, "Received an IQ last time request from <%s>",
-                 from);
-  }
-
-  x = jutil_iqnew(JPACKET__RESULT, NS_LAST);
-  xmlnode_put_attrib(x, "id", id);
-  xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
-  myquery = xmlnode_get_tag(x, "query");
-  seconds = g_strdup_printf("%.0f", seconds_since_last_use());
-  xmlnode_put_attrib(myquery, "seconds", seconds);
-  g_free(seconds);
-
-  jab_send(jc, x);
-  xmlnode_free(x);
-}
-
-static void handle_iq_ping(jconn conn, char *from, const char *id,
-                           xmlnode xmldata)
-{
-  xmlnode x;
-  x = jutil_iqresult(xmldata);
-  jab_send(jc, x);
-}
-
-static void handle_iq_version(jconn conn, char *from, const char *id,
-                              xmlnode xmldata)
-{
-  xmlnode x;
-  xmlnode myquery;
-  char *os = NULL;
-  char *ver = mcabber_version();
-
-  if (!settings_opt_get_int("iq_hide_requests")) {
-    scr_LogPrint(LPRINT_LOGNORM, "Received an IQ version request from <%s>",
-                 from);
-  }
-
-  if (!settings_opt_get_int("iq_version_hide_os")) {
-    struct utsname osinfo;
-    uname(&osinfo);
-    os = g_strdup_printf("%s %s %s", osinfo.sysname, osinfo.release,
-                         osinfo.machine);
-  }
-
-  x = jutil_iqnew(JPACKET__RESULT, NS_VERSION);
-  xmlnode_put_attrib(x, "id", id);
-  xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
-  myquery = xmlnode_get_tag(x, "query");
-
-  xmlnode_insert_cdata(xmlnode_insert_tag(myquery, "name"), PACKAGE_NAME, -1);
-  xmlnode_insert_cdata(xmlnode_insert_tag(myquery, "version"), ver, -1);
-  if (os) {
-    xmlnode_insert_cdata(xmlnode_insert_tag(myquery, "os"), os, -1);
-    g_free(os);
-  }
-
-  g_free(ver);
-  jab_send(jc, x);
-  xmlnode_free(x);
-}
-
-// This function borrows some code from the Pidgin project
-static void handle_iq_time(jconn conn, char *from, const char *id,
-                           xmlnode xmldata)
-{
-  xmlnode x;
-  xmlnode myquery;
-  char *buf, *utf8_buf;
-  time_t now_t;
-  struct tm *now;
-
-  time(&now_t);
-
-  if (!settings_opt_get_int("iq_hide_requests")) {
-    scr_LogPrint(LPRINT_LOGNORM, "Received an IQ time request from <%s>", from);
-  }
-
-  buf = g_new0(char, 512);
-
-  x = jutil_iqnew(JPACKET__RESULT, NS_TIME);
-  xmlnode_put_attrib(x, "id", id);
-  xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
-  myquery = xmlnode_get_tag(x, "query");
-
-  now = gmtime(&now_t);
-
-  strftime(buf, 512, "%Y%m%dT%T", now);
-  xmlnode_insert_cdata(xmlnode_insert_tag(myquery, "utc"), buf, -1);
-
-  now = localtime(&now_t);
-
-  strftime(buf, 512, "%Z", now);
-  if ((utf8_buf = to_utf8(buf))) {
-    xmlnode_insert_cdata(xmlnode_insert_tag(myquery, "tz"), utf8_buf, -1);
-    g_free(utf8_buf);
-  }
-
-  strftime(buf, 512, "%d %b %Y %T", now);
-  if ((utf8_buf = to_utf8(buf))) {
-    xmlnode_insert_cdata(xmlnode_insert_tag(myquery, "display"), utf8_buf, -1);
-    g_free(utf8_buf);
-  }
-
-  jab_send(jc, x);
-  xmlnode_free(x);
-  g_free(buf);
-}
-
-// This function borrows some code from the Pidgin project
-static void handle_iq_time202(jconn conn, char *from, const char *id,
-                              xmlnode xmldata)
-{
-  xmlnode x;
-  xmlnode myquery;
-  char *buf, *utf8_buf;
-  time_t now_t;
-  struct tm *now;
-  char const *sign;
-  int diff = 0;
-
-  time(&now_t);
-
-  if (!settings_opt_get_int("iq_hide_requests")) {
-    scr_LogPrint(LPRINT_LOGNORM, "Received an IQ time request from <%s>", from);
-  }
-
-  buf = g_new0(char, 512);
-
-  x = jutil_iqnew(JPACKET__RESULT, NULL);
-  xmlnode_hide(xmlnode_get_tag(x, "query"));
-  xmlnode_put_attrib(xmlnode_insert_tag(x, "time"), "xmlns", NS_XMPP_TIME);
-  xmlnode_put_attrib(x, "id", id);
-  xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
-  myquery = xmlnode_get_tag(x, "time");
-
-  now = localtime(&now_t);
-
-  if (now->tm_isdst >= 0) {
-#if defined HAVE_TM_GMTOFF
-    diff = now->tm_gmtoff;
-#elif defined HAVE_TIMEZONE
-    tzset();
-    diff = -timezone;
-#endif
-  }
-
-  if (diff < 0) {
-    sign = "-";
-    diff = -diff;
-  } else {
-    sign = "+";
-  }
-  diff /= 60;
-  snprintf(buf, 512, "%c%02d:%02d", *sign, diff / 60, diff % 60);
-  if ((utf8_buf = to_utf8(buf))) {
-    xmlnode_insert_cdata(xmlnode_insert_tag(myquery, "tzo"), utf8_buf, -1);
-    g_free(utf8_buf);
-  }
-
-  now = gmtime(&now_t);
-
-  strftime(buf, 512, "%Y-%m-%dT%TZ", now);
-  xmlnode_insert_cdata(xmlnode_insert_tag(myquery, "utc"), buf, -1);
-
-  jab_send(jc, x);
-  xmlnode_free(x);
-  g_free(buf);
-}
-
-// This function borrows some code from the Pidgin project
-static void handle_iq_get(jconn conn, char *from, xmlnode xmldata)
-{
-  const char *id, *ns;
-  xmlnode x;
-  guint iq_not_implemented = FALSE;
-
-  id = xmlnode_get_attrib(xmldata, "id");
-  if (!id) {
-    scr_LogPrint(LPRINT_LOG, "IQ get stanza with no ID, ignored.");
-    return;
-  }
-
-  x = xmlnode_get_tag(xmldata, "ping");
-  ns = xmlnode_get_attrib(x, "xmlns");
-  if (ns && !strcmp(ns, NS_PING)) {
-    handle_iq_ping(conn, from, id, xmldata);
-    return;
-  }
-
-  x = xmlnode_get_tag(xmldata, "time");
-  ns = xmlnode_get_attrib(x, "xmlns");
-  if (ns && !strcmp(ns, NS_XMPP_TIME)) {
-    handle_iq_time202(conn, from, id, xmldata);
-    return;
-  }
-
-  x = xmlnode_get_tag(xmldata, "query");
-  ns = xmlnode_get_attrib(x, "xmlns");
-  if (ns && !strcmp(ns, NS_DISCO_INFO)) {
-    handle_iq_disco_info(conn, from, id, xmldata);
-  } else if (ns && !strcmp(ns, NS_DISCO_ITEMS)) {
-    handle_iq_disco_items(conn, from, id, xmldata);
-  } else if (ns && !strcmp(ns, NS_VERSION)) {
-    handle_iq_version(conn, from, id, xmldata);
-  } else if (ns && !strcmp(ns, NS_LAST)) {
-    if (!settings_opt_get_int("iq_last_disable") &&
-        (!settings_opt_get_int("iq_last_disable_when_notavail") ||
-         jb_getstatus() != notavail))
-      handle_iq_last(conn, from, id, xmldata);
-    else
-      send_iq_not_available(conn, from, xmldata);
-  } else if (ns && !strcmp(ns, NS_TIME)) {
-    handle_iq_time(conn, from, id, xmldata);
-  } else {
-    iq_not_implemented = TRUE;
-  }
-
-  if (!iq_not_implemented)
-    return;
-
-  send_iq_not_implemented(conn, from, xmldata);
-}
-
-static void handle_iq_set(jconn conn, char *from, xmlnode xmldata)
-{
-  const char *id, *ns;
-  xmlnode x;
-  guint iq_not_implemented = FALSE;
-
-  id = xmlnode_get_attrib(xmldata, "id");
-  if (!id)
-    scr_LogPrint(LPRINT_LOG, "IQ set stanza with no ID...");
-
-  x = xmlnode_get_tag(xmldata, "query");
-  ns = xmlnode_get_attrib(x, "xmlns");
-  if (ns && !strcmp(ns, NS_ROSTER)) {
-    handle_iq_roster(x);
-  } else {
-    x = xmlnode_get_tag(xmldata, "command");
-    ns = xmlnode_get_attrib(x, "xmlns");
-    if (ns && !strcmp(ns, NS_COMMANDS)) {
-      handle_iq_commands(conn, from, id, xmldata);
-      return;
-    } else {
-      iq_not_implemented = TRUE;
-    }
-  }
-
-  if (!id) return;
-
-  if (!iq_not_implemented) {
-    x = xmlnode_new_tag("iq");
-    xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
-    xmlnode_put_attrib(x, "type", "result");
-    xmlnode_put_attrib(x, "id", id);
-    jab_send(conn, x);
-    xmlnode_free(x);
-  } else {
-    send_iq_not_implemented(conn, from, xmldata);
-  }
-}
-
-void handle_packet_iq(jconn conn, char *type, char *from, xmlnode xmldata)
-{
-  if (!type)
-    return;
-
-  if (!strcmp(type, "result")) {
-    handle_iq_result(conn, from, xmldata);
-  } else if (!strcmp(type, "get")) {
-    handle_iq_get(conn, from, xmldata);
-  } else if (!strcmp(type, "set")) {
-    handle_iq_set(conn, from, xmldata);
-  } else if (!strcmp(type, TMSG_ERROR)) {
-    // Display a message only if the error isn't caught by a callback.
-    xmlnode x = xmlnode_get_tag(xmldata, TMSG_ERROR);
-    if (iqs_callback(xmlnode_get_attrib(xmldata, "id"), x, IQS_CONTEXT_ERROR))
-      display_server_error(x);
-  }
-}
-
-//  send_storage_bookmarks()
-// Send the current bookmarks node to update the server.
-// Note: the sender should check we're online.
-void send_storage_bookmarks(void)
-{
-  eviqs *iqn;
-
-  if (!bookmarks) return;
-
-  iqn = iqs_new(JPACKET__SET, NS_PRIVATE, "storage", IQS_DEFAULT_TIMEOUT);
-  xmlnode_insert_node(xmlnode_get_tag(iqn->xmldata, "query"), bookmarks);
-
-  jab_send(jc, iqn->xmldata);
-  iqs_del(iqn->id); // XXX
-}
-
-//  send_storage_rosternotes()
-// Send the current rosternotes node to update the server.
-// Note: the sender should check we're online.
-void send_storage_rosternotes(void)
-{
-  eviqs *iqn;
-
-  if (!rosternotes) return;
-
-  iqn = iqs_new(JPACKET__SET, NS_PRIVATE, "storage", IQS_DEFAULT_TIMEOUT);
-  xmlnode_insert_node(xmlnode_get_tag(iqn->xmldata, "query"), rosternotes);
-
-  jab_send(jc, iqn->xmldata);
-  iqs_del(iqn->id); // XXX
-}
-
-/* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */
--- a/mcabber/src/jab_priv.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-#ifndef __JAB_PRIV_H__
-#define __JAB_PRIV_H__ 1
-
-/* This header file declares functions used by jab*.c only. */
-
-#include "jabglue.h"
-#include "events.h"
-
-/* XEP-0115 (Entity Capabilities) node */
-#define MCABBER_CAPS_NODE   "http://mcabber.com/caps"
-
-#define JABBER_AGENT_GROUP  "Jabber Agents"
-
-enum enum_jstate {
-  STATE_CONNECTING,
-  STATE_GETAUTH,
-  STATE_SENDAUTH,
-  STATE_LOGGED
-};
-
-struct T_presence {
-  enum imstatus st;
-  const char *msg;
-};
-
-
-#define IQS_DEFAULT_TIMEOUT 90U
-#define IQS_MAX_TIMEOUT     600U
-
-#define IQS_CONTEXT_RESULT  0U  /* Normal result should be zero */
-#define IQS_CONTEXT_TIMEOUT 1U
-#define IQS_CONTEXT_ERROR   2U
-
-extern enum enum_jstate jstate;
-extern xmlnode bookmarks, rosternotes;
-
-const char *entity_version(void);
-
-extern time_t iqlast;           /* last message/status change time */
-
-void handle_packet_iq(jconn conn, char *type, char *from, xmlnode xmldata);
-void display_server_error(xmlnode x);
-eviqs *iqs_new(guint8 type, const char *ns, const char *prefix, time_t timeout);
-int  iqs_del(const char *iqid);
-int  iqs_callback(const char *iqid, xmlnode xml_result, guint iqcontext);
-void iqs_check_timeout(time_t now_t);
-int  iqscallback_auth(eviqs *iqp, xmlnode xml_result, guint iqcontext);
-void request_version(const char *fulljid);
-void request_time(const char *fulljid);
-void request_last(const char *fulljid);
-void request_vcard(const char *barejid);
-void send_storage_bookmarks(void);
-void send_storage_rosternotes(void);
-
-#endif /* __JAB_PRIV_H__ */
-
-/* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */
--- a/mcabber/src/jabglue.c	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3041 +0,0 @@
-/*
- * jabglue.c    -- Jabber protocol handling
- *
- * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
- * Parts come from the centericq project:
- * Copyright (C) 2002-2005 by Konstantin Klyagin <konst@konst.org.ua>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#include "../libjabber/jabber.h"
-#include "jabglue.h"
-#include "jab_priv.h"
-#include "roster.h"
-#include "screen.h"
-#include "hooks.h"
-#include "utils.h"
-#include "settings.h"
-#include "hbuf.h"
-#include "histolog.h"
-#include "commands.h"
-#include "pgp.h"
-#include "otr.h"
-#include "fifo.h"
-
-#define JABBERPORT      5222
-#define JABBERSSLPORT   5223
-
-#define RECONNECTION_TIMEOUT    60L
-
-jconn jc;
-guint AutoConnection;
-enum enum_jstate jstate;
-
-char imstatus2char[imstatus_size+1] = {
-    '_', 'o', 'f', 'd', 'n', 'a', 'i', '\0'
-};
-
-static char *imstatus_showmap[] = {
-  "",
-  "",
-  "chat",
-  "dnd",
-  "xa",
-  "away",
-  ""
-};
-
-static time_t LastPingTime;
-static unsigned int KeepaliveDelay;
-static enum imstatus mystatus = offline;
-static enum imstatus mywantedstatus = available;
-static gchar *mystatusmsg;
-static unsigned char online;
-
-static void statehandler(jconn, int);
-static void packethandler(jconn, jpacket);
-static void handle_state_events(char* from, xmlnode xmldata);
-
-static int evscallback_invitation(eviqs *evp, guint evcontext);
-
-inline void update_last_use(void);
-
-
-static void logger(jconn j, int io, const char *buf)
-{
-  scr_LogPrint(LPRINT_DEBUG, "%03s: %s", ((io == 0) ? "OUT" : "IN"), buf);
-}
-
-//  jidtodisp(jid)
-// Strips the resource part from the jid
-// The caller should g_free the result after use.
-char *jidtodisp(const char *fjid)
-{
-  char *ptr;
-  char *alias;
-
-  alias = g_strdup(fjid);
-
-  if ((ptr = strchr(alias, JID_RESOURCE_SEPARATOR)) != NULL) {
-    *ptr = 0;
-  }
-  return alias;
-}
-
-char *compose_jid(const char *username, const char *servername,
-                  const char *resource)
-{
-  char *fjid;
-
-  if (!strchr(username, JID_DOMAIN_SEPARATOR)) {
-    fjid = g_strdup_printf("%s%c%s%c%s", username,
-                           JID_DOMAIN_SEPARATOR, servername,
-                           JID_RESOURCE_SEPARATOR, resource);
-  } else {
-    fjid = g_strdup_printf("%s%c%s", username,
-                           JID_RESOURCE_SEPARATOR, resource);
-  }
-  return fjid;
-}
-
-unsigned char jb_getonline(void)
-{
-  return online;
-}
-
-jconn jb_connect(const char *fjid, const char *server, unsigned int port,
-                 int ssl, const char *pass)
-{
-  if (!port) {
-    if (ssl)
-      port = JABBERSSLPORT;
-    else
-      port = JABBERPORT;
-  }
-
-  jb_disconnect();
-
-  if (!fjid) return jc;
-
-  jc = jab_new((char*)fjid, (char*)pass, (char*)server, port, ssl);
-
-  /* These 3 functions can deal with a NULL jc, no worry... */
-  jab_logger(jc, logger);
-  jab_packet_handler(jc, &packethandler);
-  jab_state_handler(jc, &statehandler);
-
-  if (jc && jc->user) {
-    online = TRUE;
-    jstate = STATE_CONNECTING;
-    statehandler(0, -1);
-    jab_start(jc);
-  }
-
-  return jc;
-}
-
-void jb_disconnect(void)
-{
-  if (!jc) return;
-
-  if (online) {
-    // Launch pre-disconnect internal hook
-    hook_execute_internal("hook-pre-disconnect");
-    // Announce it to  everyone else
-    jb_setstatus(offline, NULL, "", FALSE);
-    // End the XML flow
-    jb_send_raw("</stream:stream>");
-    /*
-    // Free status message
-    g_free(mystatusmsg);
-    mystatusmsg = NULL;
-    */
-  }
-
-  // Announce it to the user
-  statehandler(jc, JCONN_STATE_OFF);
-
-  jab_delete(jc);
-  jc = NULL;
-}
-
-inline void jb_reset_keepalive()
-{
-  time(&LastPingTime);
-}
-
-void jb_send_raw(const char *str)
-{
-  if (jc && online && str)
-    jab_send_raw(jc, str);
-}
-
-void jb_keepalive()
-{
-  if (jc && online)
-    jab_send_raw(jc, "  \t  ");
-  jb_reset_keepalive();
-}
-
-void jb_set_keepalive_delay(unsigned int delay)
-{
-  KeepaliveDelay = delay;
-}
-
-//  check_connection()
-// Check if we've been disconnected for a while (predefined timeout),
-// and if so try to reconnect.
-static void check_connection(void)
-{
-  static time_t disconnection_timestamp = 0L;
-  time_t now;
-
-  // Maybe we're voluntarily offline...
-  if (!AutoConnection)
-    return;
-
-  // Are we totally disconnected?
-  if (jc && jc->state != JCONN_STATE_OFF) {
-    disconnection_timestamp = 0L;
-    return;
-  }
-
-  time(&now);
-  if (!disconnection_timestamp) {
-    disconnection_timestamp = now;
-    return;
-  }
-
-  // If the reconnection_timeout is reached, try to reconnect.
-  if (now > disconnection_timestamp + RECONNECTION_TIMEOUT) {
-    mcabber_connect();
-    disconnection_timestamp = 0L;
-  }
-}
-
-void jb_main()
-{
-  time_t now;
-  fd_set fds;
-  long tmout;
-  struct timeval tv;
-  static time_t last_eviqs_check = 0L;
-  int maxfd = 0;
-  int fifofd;
-
-  FD_ZERO(&fds);
-  FD_SET(0, &fds);
-  if (jc && jc->fd > 0) {
-    FD_SET(jc->fd, &fds);
-    maxfd = jc->fd;
-  }
-
-  fifofd = fifo_get_fd();
-  if (fifofd > 0) {
-    FD_SET(fifofd, &fds);
-    maxfd = MAX(maxfd, fifofd);
-  }
-
-  tv.tv_sec = 60;
-  tv.tv_usec = 0;
-
-  if (!online || (jc && jc->state == JCONN_STATE_CONNECTING)) {
-    if (online) {
-      // We're connecting and we need to reduce the timeout.
-      tv.tv_sec = 0;
-      tv.tv_usec = 250000;
-    } else {
-      tv.tv_sec = 30;
-      // Let's first update the screen, we could sleep for a long time...
-      scr_DoUpdate();
-    }
-    // If we're not connected, sleep for a while...
-    if (!online) {
-      select(1, &fds, NULL, NULL, &tv);
-      check_connection();
-    } else {
-      select(maxfd + 1, &fds, NULL, NULL, &tv);
-      jab_start(jc);
-    }
-    return;
-  }
-
-  time(&now);
-
-  if (KeepaliveDelay) {
-    if (now >= LastPingTime + (time_t)KeepaliveDelay)
-      tv.tv_sec = 0;
-    else
-      tv.tv_sec = LastPingTime + (time_t)KeepaliveDelay - now;
-  }
-
-  // Check auto-away timeout
-  tmout = scr_GetAutoAwayTimeout(now);
-  if (tv.tv_sec > tmout)
-    tv.tv_sec = tmout;
-
-#if defined JEP0022 || defined JEP0085
-  // Check composing timeout
-  tmout = scr_GetChatStatesTimeout(now);
-  if (tv.tv_sec > tmout)
-    tv.tv_sec = tmout;
-#endif
-
-  if (!tv.tv_sec)
-    tv.tv_usec = 350000;
-
-  scr_DoUpdate();
-  if (select(maxfd + 1, &fds, NULL, NULL, &tv) > 0) {
-    if (FD_ISSET(jc->fd, &fds))
-      jab_poll(jc, 0);
-  }
-
-  if (jstate == STATE_CONNECTING) {
-    if (jc) {
-      eviqs *iqn;
-      xmlnode z;
-
-      iqn = iqs_new(JPACKET__GET, NS_AUTH, "auth", IQS_DEFAULT_TIMEOUT);
-      iqn->callback = &iqscallback_auth;
-
-      z = xmlnode_insert_tag(xmlnode_get_tag(iqn->xmldata, "query"),
-                             "username");
-      xmlnode_insert_cdata(z, jc->user->user, (unsigned) -1);
-      jab_send(jc, iqn->xmldata);
-
-      jstate = STATE_GETAUTH;
-    }
-
-    if (!jc || jc->state == JCONN_STATE_OFF) {
-      scr_LogPrint(LPRINT_LOGNORM, "Unable to connect to the server");
-      online = FALSE;
-    }
-  }
-
-  if (!jc) {
-    statehandler(jc, JCONN_STATE_OFF);
-  } else if (jc->state == JCONN_STATE_OFF || jc->fd == -1) {
-    statehandler(jc, JCONN_STATE_OFF);
-  }
-
-  time(&now);
-
-  // Check for EV & IQ requests timeouts
-  if (now > last_eviqs_check + 20) {
-    iqs_check_timeout(now);
-    evs_check_timeout(now);
-    last_eviqs_check = now;
-  }
-
-  // Keepalive
-  if (KeepaliveDelay) {
-    if (now > LastPingTime + (time_t)KeepaliveDelay)
-      jb_keepalive();
-  }
-}
-
-inline enum imstatus jb_getstatus()
-{
-  return mystatus;
-}
-
-inline const char *jb_getstatusmsg()
-{
-  return mystatusmsg;
-}
-
-void update_last_use(void)
-{
-  iqlast = time(NULL);
-}
-
-//  insert_entity_capabilities(presence_stanza)
-// Entity Capabilities (XEP-0115)
-static void insert_entity_capabilities(xmlnode x)
-{
-  xmlnode y;
-  const char *ver = entity_version();
-  char *exts, *exts2;
-
-  exts = NULL;
-
-  y = xmlnode_insert_tag(x, "c");
-  xmlnode_put_attrib(y, "xmlns", NS_CAPS);
-  xmlnode_put_attrib(y, "node", MCABBER_CAPS_NODE);
-  xmlnode_put_attrib(y, "ver", ver);
-#ifdef JEP0085
-  if (!chatstates_disabled) {
-    exts2 = g_strjoin(" ", "csn", exts, NULL);
-    g_free(exts);
-    exts = exts2;
-  }
-#endif
-  if (!settings_opt_get_int("iq_last_disable")) {
-    exts2 = g_strjoin(" ", "iql", exts, NULL);
-    g_free(exts);
-    exts = exts2;
-  }
-  if (exts) {
-    xmlnode_put_attrib(y, "ext", exts);
-    g_free(exts);
-  }
-}
-
-static void roompresence(gpointer room, void *presencedata)
-{
-  const char *bjid;
-  const char *nickname;
-  char *to;
-  struct T_presence *pres = presencedata;
-
-  if (!buddy_getinsideroom(room))
-    return;
-
-  bjid = buddy_getjid(room);
-  if (!bjid) return;
-  nickname = buddy_getnickname(room);
-  if (!nickname) return;
-
-  to = g_strdup_printf("%s/%s", bjid, nickname);
-  jb_setstatus(pres->st, to, pres->msg, TRUE);
-  g_free(to);
-}
-
-//  presnew(status, recipient, message)
-// Create an xmlnode with default presence attributes
-// Note: the caller must free the node after use
-static xmlnode presnew(enum imstatus st, const char *recipient,
-                       const char *msg)
-{
-  unsigned int prio;
-  xmlnode x;
-
-  x = jutil_presnew(JPACKET__UNKNOWN, 0, 0);
-
-  if (recipient) {
-    xmlnode_put_attrib(x, "to", recipient);
-  }
-
-  switch(st) {
-    case away:
-    case notavail:
-    case dontdisturb:
-    case freeforchat:
-        xmlnode_insert_cdata(xmlnode_insert_tag(x, "show"),
-                             imstatus_showmap[st], (unsigned) -1);
-        break;
-
-    case invisible:
-        xmlnode_put_attrib(x, "type", "invisible");
-        break;
-
-    case offline:
-        xmlnode_put_attrib(x, "type", "unavailable");
-        break;
-
-    default:
-        break;
-  }
-
-  if (st == away || st == notavail)
-    prio = settings_opt_get_int("priority_away");
-  else
-    prio = settings_opt_get_int("priority");
-
-  if (prio) {
-    char strprio[8];
-    snprintf(strprio, 8, "%d", (int)prio);
-    xmlnode_insert_cdata(xmlnode_insert_tag(x, "priority"),
-                         strprio, (unsigned) -1);
-  }
-
-  if (msg)
-    xmlnode_insert_cdata(xmlnode_insert_tag(x, "status"), msg, (unsigned) -1);
-
-  return x;
-}
-
-void jb_setstatus(enum imstatus st, const char *recipient, const char *msg,
-                  int do_not_sign)
-{
-  xmlnode x;
-
-  if (msg) {
-    // The status message has been specified.  We'll use it, unless it is
-    // "-" which is a special case (option meaning "no status message").
-    if (!strcmp(msg, "-"))
-      msg = "";
-  } else {
-    // No status message specified; we'll use:
-    // a) the default status message (if provided by the user);
-    // b) the current status message;
-    // c) no status message (i.e. an empty one).
-    msg = settings_get_status_msg(st);
-    if (!msg) {
-      if (mystatusmsg)
-        msg = mystatusmsg;
-      else
-        msg = "";
-    }
-  }
-
-  // Only send the packet if we're online.
-  // (But we want to update internal status even when disconnected,
-  // in order to avoid some problems during network failures)
-  if (online) {
-    const char *s_msg = (st != invisible ? msg : NULL);
-    x = presnew(st, recipient, s_msg);
-    insert_entity_capabilities(x); // Entity Capabilities (XEP-0115)
-#ifdef HAVE_GPGME
-    if (!do_not_sign && gpg_enabled()) {
-      char *signature;
-      signature = gpg_sign(s_msg ? s_msg : "");
-      if (signature) {
-        xmlnode y;
-        y = xmlnode_insert_tag(x, "x");
-        xmlnode_put_attrib(y, "xmlns", NS_SIGNED);
-        xmlnode_insert_cdata(y, signature, (unsigned) -1);
-        g_free(signature);
-      }
-    }
-#endif
-    jab_send(jc, x);
-    xmlnode_free(x);
-  }
-
-  // If we didn't change our _global_ status, we are done
-  if (recipient) return;
-
-  if (online) {
-    // Send presence to chatrooms
-    if (st != invisible) {
-      struct T_presence room_presence;
-      room_presence.st = st;
-      room_presence.msg = msg;
-      foreach_buddy(ROSTER_TYPE_ROOM, &roompresence, &room_presence);
-    }
-
-    // We'll have to update the roster if we switch to/from offline because
-    // we don't know the presences of buddies when offline...
-    if (mystatus == offline || st == offline)
-      update_roster = TRUE;
-
-    hk_mystatuschange(0, mystatus, st, (st != invisible ? msg : ""));
-    mystatus = st;
-  }
-
-  if (st)
-    mywantedstatus = st;
-
-  if (msg != mystatusmsg) {
-    g_free(mystatusmsg);
-    if (*msg)
-      mystatusmsg = g_strdup(msg);
-    else
-      mystatusmsg = NULL;
-  }
-
-  if (!Autoaway)
-    update_last_use();
-
-  // Update status line
-  scr_UpdateMainStatus(TRUE);
-}
-
-//  jb_setprevstatus()
-// Set previous status.  This wrapper function is used after a disconnection.
-inline void jb_setprevstatus(void)
-{
-  jb_setstatus(mywantedstatus, NULL, mystatusmsg, FALSE);
-}
-
-//  new_msgid()
-// Generate a new id string.  The caller should free it.
-// The caller must free the string when no longer needed.
-static char *new_msgid(void)
-{
-  static guint msg_idn;
-  time_t now;
-  time(&now);
-#if HAVE_ARC4RANDOM
-  msg_idn += 1U + (unsigned int) (9.0 * (arc4random() / 4294967296.0));
-#else
-  if (!msg_idn)
-    srand(now);
-  msg_idn += 1U + (unsigned int) (9.0 * (rand() / (RAND_MAX + 1.0)));
-#endif
-  return g_strdup_printf("%u%d", msg_idn, (int)(now%10L));
-}
-
-//  jb_send_msg(jid, text, type, subject, msgid, *encrypted, type_overwrite)
-// When encrypted is not NULL, the function set *encrypted to 1 if the
-// message has been PGP-encrypted.  If encryption enforcement is set and
-// encryption fails, *encrypted is set to -1.
-void jb_send_msg(const char *fjid, const char *text, int type,
-                 const char *subject, const char *msgid, gint *encrypted,
-                 const char *type_overwrite)
-{
-  xmlnode x;
-  const gchar *strtype;
-#ifdef HAVE_LIBOTR
-  int otr_msg = 0;
-#endif
-#if defined HAVE_GPGME || defined JEP0022 || defined JEP0085
-  char *rname, *barejid;
-  GSList *sl_buddy;
-#endif
-#if defined JEP0022 || defined JEP0085
-  xmlnode event;
-  guint use_jep85 = 0;
-  struct jep0085 *jep85 = NULL;
-#endif
-#if defined JEP0022
-  gchar *nmsgid = NULL;
-#endif
-  gchar *enc = NULL;
-
-  if (encrypted)
-    *encrypted = 0;
-
-  if (!online)
-    return;
-
-  if (!text && type == ROSTER_TYPE_USER)
-    return;
-
-  if (type_overwrite)
-    strtype = type_overwrite;
-  else {
-    if (type == ROSTER_TYPE_ROOM)
-      strtype = TMSG_GROUPCHAT;
-    else
-      strtype = TMSG_CHAT;
-  }
-
-#if defined HAVE_GPGME || defined HAVE_LIBOTR || defined JEP0022 || defined JEP0085
-  rname = strchr(fjid, JID_RESOURCE_SEPARATOR);
-  barejid = jidtodisp(fjid);
-  sl_buddy = roster_find(barejid, jidsearch, ROSTER_TYPE_USER);
-
-  // If we can get a resource name, we use it.  Else we use NULL,
-  // which hopefully will give us the most likely resource.
-  if (rname)
-    rname++;
-
-#ifdef HAVE_LIBOTR
-  if (otr_enabled()) {
-    if (msgid && strcmp(msgid, "otrinject") == 0)
-      msgid = NULL;
-    else if (type == ROSTER_TYPE_USER) {
-      otr_msg = otr_send((char **)&text, barejid);
-      if (!text) {
-        g_free(barejid);
-        if (encrypted)
-          *encrypted = -1;
-        return;
-      }
-    }
-    if (otr_msg && encrypted)
-      *encrypted = ENCRYPTED_OTR;
-  }
-#endif
-
-#ifdef HAVE_GPGME
-  if (type == ROSTER_TYPE_USER && sl_buddy && gpg_enabled()) {
-    if (!settings_pgp_getdisabled(barejid)) { // not disabled for this contact?
-      guint force;
-      struct pgp_data *res_pgpdata;
-      force = settings_pgp_getforce(barejid);
-      res_pgpdata = buddy_resource_pgp(sl_buddy->data, rname);
-      if (force || (res_pgpdata && res_pgpdata->sign_keyid)) {
-        /* Remote client has PGP support (we have a signature)
-         * OR encryption is enforced (force = TRUE).
-         * If the contact has a specific KeyId, we'll use it;
-         * if not, we'll use the key used for the signature.
-         * Both keys should match, in theory (cf. XEP-0027). */
-        const char *key;
-        key = settings_pgp_getkeyid(barejid);
-        if (!key && res_pgpdata)
-          key = res_pgpdata->sign_keyid;
-        if (key)
-          enc = gpg_encrypt(text, key);
-        if (!enc && force) {
-          if (encrypted)
-            *encrypted = -1;
-          g_free(barejid);
-          return;
-        }
-      }
-    }
-  }
-#endif // HAVE_GPGME
-
-  g_free(barejid);
-#endif // HAVE_GPGME || defined JEP0022 || defined JEP0085
-
-  x = jutil_msgnew((char*)strtype, (char*)fjid, NULL,
-                   (enc ? "This message is PGP-encrypted." : (char*)text));
-  if (subject) {
-    xmlnode y;
-    y = xmlnode_insert_tag(x, "subject");
-    xmlnode_insert_cdata(y, subject, (unsigned) -1);
-  }
-  if (enc) {
-    xmlnode y;
-    y = xmlnode_insert_tag(x, "x");
-    xmlnode_put_attrib(y, "xmlns", NS_ENCRYPTED);
-    xmlnode_insert_cdata(y, enc, (unsigned) -1);
-    if (encrypted)
-      *encrypted = ENCRYPTED_PGP;
-    g_free(enc);
-  }
-
-#if defined JEP0022 || defined JEP0085
-  // If typing notifications are disabled, we can skip all this stuff...
-  if (chatstates_disabled || type == ROSTER_TYPE_ROOM)
-    goto jb_send_msg_no_chatstates;
-
-  if (sl_buddy)
-    jep85 = buddy_resource_jep85(sl_buddy->data, rname);
-#endif
-
-#ifdef JEP0085
-  /* JEP-0085 5.1
-   * "Until receiving a reply to the initial content message (or a standalone
-   * notification) from the Contact, the User MUST NOT send subsequent chat
-   * state notifications to the Contact."
-   * In our implementation support is initially "unknown", then it's "probed"
-   * and can become "ok".
-   */
-  if (jep85 && (jep85->support == CHATSTATES_SUPPORT_OK ||
-                jep85->support == CHATSTATES_SUPPORT_UNKNOWN)) {
-    event = xmlnode_insert_tag(x, "active");
-    xmlnode_put_attrib(event, "xmlns", NS_CHATSTATES);
-    if (jep85->support == CHATSTATES_SUPPORT_UNKNOWN)
-      jep85->support = CHATSTATES_SUPPORT_PROBED;
-    else
-      use_jep85 = 1;
-    jep85->last_state_sent = ROSTER_EVENT_ACTIVE;
-  }
-#endif
-#ifdef JEP0022
-  /* JEP-22
-   * If the Contact supports JEP-0085, we do not use JEP-0022.
-   * If not, we try to fall back to JEP-0022.
-   */
-  if (!use_jep85) {
-    struct jep0022 *jep22 = NULL;
-    event = xmlnode_insert_tag(x, "x");
-    xmlnode_put_attrib(event, "xmlns", NS_EVENT);
-    xmlnode_insert_tag(event, "composing");
-
-    if (sl_buddy)
-      jep22 = buddy_resource_jep22(sl_buddy->data, rname);
-    if (jep22)
-      jep22->last_state_sent = ROSTER_EVENT_ACTIVE;
-
-    // An id is mandatory when using JEP-0022.
-    if (!msgid && (text || subject)) {
-      msgid = nmsgid = new_msgid();
-      // Let's update last_msgid_sent
-      // (We do not update it when the msgid is provided by the caller,
-      // because this is probably a special message...)
-      if (jep22) {
-        g_free(jep22->last_msgid_sent);
-        jep22->last_msgid_sent = g_strdup(msgid);
-      }
-    }
-  }
-#endif
-
-jb_send_msg_no_chatstates:
-  xmlnode_put_attrib(x, "id", msgid);
-
-  if (mystatus != invisible)
-    update_last_use();
-  jab_send(jc, x);
-  xmlnode_free(x);
-#if defined JEP0022
-  g_free(nmsgid);
-#endif
-
-  jb_reset_keepalive();
-}
-
-
-#ifdef JEP0085
-//  jb_send_jep85_chatstate()
-// Send a JEP-85 chatstate.
-static void jb_send_jep85_chatstate(const char *bjid, const char *resname,
-                                    guint state)
-{
-  xmlnode x;
-  xmlnode event;
-  GSList *sl_buddy;
-  const char *chattag;
-  char *rjid, *fjid = NULL;
-  struct jep0085 *jep85 = NULL;
-
-  if (!online) return;
-
-  sl_buddy = roster_find(bjid, jidsearch, ROSTER_TYPE_USER);
-
-  // If we have a resource name, we use it.  Else we use NULL,
-  // which hopefully will give us the most likely resource.
-  if (sl_buddy)
-    jep85 = buddy_resource_jep85(sl_buddy->data, resname);
-
-  if (!jep85 || (jep85->support != CHATSTATES_SUPPORT_OK))
-    return;
-
-  if (state == jep85->last_state_sent)
-    return;
-
-  if (state == ROSTER_EVENT_ACTIVE)
-    chattag = "active";
-  else if (state == ROSTER_EVENT_COMPOSING)
-    chattag = "composing";
-  else if (state == ROSTER_EVENT_PAUSED)
-    chattag = "paused";
-  else {
-    scr_LogPrint(LPRINT_LOGNORM, "Error: unsupported JEP-85 state (%d)", state);
-    return;
-  }
-
-  jep85->last_state_sent = state;
-
-  if (resname)
-    fjid = g_strdup_printf("%s/%s", bjid, resname);
-
-  rjid = resname ? fjid : (char*)bjid;
-  x = jutil_msgnew(TMSG_CHAT, rjid, NULL, NULL);
-
-  event = xmlnode_insert_tag(x, chattag);
-  xmlnode_put_attrib(event, "xmlns", NS_CHATSTATES);
-
-  jab_send(jc, x);
-  xmlnode_free(x);
-
-  g_free(fjid);
-  jb_reset_keepalive();
-}
-#endif
-
-#ifdef JEP0022
-//  jb_send_jep22_event()
-// Send a JEP-22 message event (delivered, composing...).
-static void jb_send_jep22_event(const char *fjid, guint type)
-{
-  xmlnode x;
-  xmlnode event;
-  const char *msgid;
-  char *rname, *barejid;
-  GSList *sl_buddy;
-  struct jep0022 *jep22 = NULL;
-  guint jep22_state;
-
-  if (!online) return;
-
-  rname = strchr(fjid, JID_RESOURCE_SEPARATOR);
-  barejid = jidtodisp(fjid);
-  sl_buddy = roster_find(barejid, jidsearch, ROSTER_TYPE_USER);
-  g_free(barejid);
-
-  // If we can get a resource name, we use it.  Else we use NULL,
-  // which hopefully will give us the most likely resource.
-  if (rname)
-    rname++;
-  if (sl_buddy)
-    jep22 = buddy_resource_jep22(sl_buddy->data, rname);
-
-  if (!jep22)
-    return; // XXX Maybe we could try harder (other resources?)
-
-  msgid = jep22->last_msgid_rcvd;
-
-  // For composing events (composing, active, inactive, paused...),
-  // JEP22 only has 2 states; we'll use composing and active.
-  if (type == ROSTER_EVENT_COMPOSING)
-    jep22_state = ROSTER_EVENT_COMPOSING;
-  else if (type == ROSTER_EVENT_ACTIVE ||
-           type == ROSTER_EVENT_PAUSED)
-    jep22_state = ROSTER_EVENT_ACTIVE;
-  else
-    jep22_state = 0; // ROSTER_EVENT_NONE
-
-  if (jep22_state) {
-    // Do not re-send a same event
-    if (jep22_state == jep22->last_state_sent)
-      return;
-    jep22->last_state_sent = jep22_state;
-  }
-
-  x = jutil_msgnew(TMSG_CHAT, (char*)fjid, NULL, NULL);
-
-  event = xmlnode_insert_tag(x, "x");
-  xmlnode_put_attrib(event, "xmlns", NS_EVENT);
-  if (type == ROSTER_EVENT_DELIVERED)
-    xmlnode_insert_tag(event, "delivered");
-  else if (type == ROSTER_EVENT_COMPOSING)
-    xmlnode_insert_tag(event, "composing");
-  xmlnode_put_attrib(event, "id", msgid);
-
-  jab_send(jc, x);
-  xmlnode_free(x);
-
-  jb_reset_keepalive();
-}
-#endif
-
-//  jb_send_chatstate(buddy, state)
-// Send a chatstate or event (JEP-22/85) according to the buddy's capabilities.
-// The message is sent to one of the resources with the highest priority.
-#if defined JEP0022 || defined JEP0085
-void jb_send_chatstate(gpointer buddy, guint chatstate)
-{
-  const char *bjid;
-#ifdef JEP0085
-  GSList *resources, *p_res, *p_next;
-  struct jep0085 *jep85 = NULL;
-#endif
-#ifdef JEP0022
-  struct jep0022 *jep22;
-#endif
-
-  bjid = buddy_getjid(buddy);
-  if (!bjid) return;
-
-#ifdef JEP0085
-  /* Send the chatstate to the last resource (which should have the highest
-     priority).
-     If chatstate is "active", send an "active" state to all resources
-     which do not curently have this state.
-   */
-  resources = buddy_getresources(buddy);
-  for (p_res = resources ; p_res ; p_res = p_next) {
-    p_next = g_slist_next(p_res);
-    jep85 = buddy_resource_jep85(buddy, p_res->data);
-    if (jep85 && jep85->support == CHATSTATES_SUPPORT_OK) {
-      // If p_next is NULL, this is the highest (prio) resource, i.e.
-      // the one we are probably writing to.
-      if (!p_next || (jep85->last_state_sent != ROSTER_EVENT_ACTIVE &&
-                      chatstate == ROSTER_EVENT_ACTIVE))
-        jb_send_jep85_chatstate(bjid, p_res->data, chatstate);
-    }
-    g_free(p_res->data);
-  }
-  g_slist_free(resources);
-  // If the last resource had chatstates support when can return now,
-  // we don't want to send a JEP22 event.
-  if (jep85 && jep85->support == CHATSTATES_SUPPORT_OK)
-    return;
-#endif
-#ifdef JEP0022
-  jep22 = buddy_resource_jep22(buddy, NULL);
-  if (jep22 && jep22->support == CHATSTATES_SUPPORT_OK) {
-    jb_send_jep22_event(bjid, chatstate);
-  }
-#endif
-}
-#endif
-
-//  chatstates_reset_probed(fulljid)
-// If the JEP has been probed for this contact, set it back to unknown so
-// that we probe it again.  The parameter must be a full jid (w/ resource).
-#if defined JEP0022 || defined JEP0085
-static void chatstates_reset_probed(const char *fulljid)
-{
-  char *rname, *barejid;
-  GSList *sl_buddy;
-  struct jep0085 *jep85;
-  struct jep0022 *jep22;
-
-  rname = strchr(fulljid, JID_RESOURCE_SEPARATOR);
-  if (!rname++)
-    return;
-
-  barejid = jidtodisp(fulljid);
-  sl_buddy = roster_find(barejid, jidsearch, ROSTER_TYPE_USER);
-  g_free(barejid);
-
-  if (!sl_buddy)
-    return;
-
-  jep85 = buddy_resource_jep85(sl_buddy->data, rname);
-  jep22 = buddy_resource_jep22(sl_buddy->data, rname);
-
-  if (jep85 && jep85->support == CHATSTATES_SUPPORT_PROBED)
-    jep85->support = CHATSTATES_SUPPORT_UNKNOWN;
-  if (jep22 && jep22->support == CHATSTATES_SUPPORT_PROBED)
-    jep22->support = CHATSTATES_SUPPORT_UNKNOWN;
-}
-#endif
-
-//  jb_subscr_send_auth(jid)
-// Allow jid to receive our presence updates
-void jb_subscr_send_auth(const char *bjid)
-{
-  xmlnode x;
-
-  x = jutil_presnew(JPACKET__SUBSCRIBED, (char *)bjid, NULL);
-  jab_send(jc, x);
-  xmlnode_free(x);
-}
-
-//  jb_subscr_cancel_auth(jid)
-// Cancel jid's subscription to our presence updates
-void jb_subscr_cancel_auth(const char *bjid)
-{
-  xmlnode x;
-
-  x = jutil_presnew(JPACKET__UNSUBSCRIBED, (char *)bjid, NULL);
-  jab_send(jc, x);
-  xmlnode_free(x);
-}
-
-//  jb_subscr_request_auth(jid)
-// Request a subscription to jid's presence updates
-void jb_subscr_request_auth(const char *bjid)
-{
-  xmlnode x;
-
-  x = jutil_presnew(JPACKET__SUBSCRIBE, (char *)bjid, NULL);
-  jab_send(jc, x);
-  xmlnode_free(x);
-}
-
-//  jb_subscr_request_cancel(jid)
-// Request to cancel jour subscription to jid's presence updates
-void jb_subscr_request_cancel(const char *bjid)
-{
-  xmlnode x;
-
-  x = jutil_presnew(JPACKET__UNSUBSCRIBE, (char *)bjid, NULL);
-  jab_send(jc, x);
-  xmlnode_free(x);
-}
-
-// Note: the caller should check the jid is correct
-void jb_addbuddy(const char *bjid, const char *name, const char *group)
-{
-  xmlnode y, z;
-  eviqs *iqn;
-  char *cleanjid;
-
-  if (!online) return;
-
-  cleanjid = jidtodisp(bjid); // Stripping resource, just in case...
-
-  // We don't check if the jabber user already exists in the roster,
-  // because it allows to re-ask for notification.
-
-  iqn = iqs_new(JPACKET__SET, NS_ROSTER, NULL, IQS_DEFAULT_TIMEOUT);
-  y = xmlnode_insert_tag(xmlnode_get_tag(iqn->xmldata, "query"), "item");
-
-  xmlnode_put_attrib(y, "jid", cleanjid);
-
-  if (name)
-    xmlnode_put_attrib(y, "name", name);
-
-  if (group) {
-    z = xmlnode_insert_tag(y, "group");
-    xmlnode_insert_cdata(z, group, (unsigned) -1);
-  }
-
-  jab_send(jc, iqn->xmldata);
-  iqs_del(iqn->id); // XXX
-
-  jb_subscr_request_auth(cleanjid);
-
-  roster_add_user(cleanjid, name, group, ROSTER_TYPE_USER, sub_pending, -1);
-  g_free(cleanjid);
-  buddylist_build();
-
-  update_roster = TRUE;
-}
-
-void jb_delbuddy(const char *bjid)
-{
-  xmlnode y, z;
-  eviqs *iqn;
-  char *cleanjid;
-
-  if (!online) return;
-
-  cleanjid = jidtodisp(bjid); // Stripping resource, just in case...
-
-  // If the current buddy is an agent, unsubscribe from it
-  if (roster_gettype(cleanjid) == ROSTER_TYPE_AGENT) {
-    scr_LogPrint(LPRINT_LOGNORM, "Unregistering from the %s agent", cleanjid);
-
-    iqn = iqs_new(JPACKET__SET, NS_REGISTER, NULL, IQS_DEFAULT_TIMEOUT);
-    xmlnode_put_attrib(iqn->xmldata, "to", cleanjid);
-    y = xmlnode_get_tag(iqn->xmldata, "query");
-    xmlnode_insert_tag(y, "remove");
-    jab_send(jc, iqn->xmldata);
-    iqs_del(iqn->id); // XXX
-  }
-
-  // Cancel the subscriptions
-  jb_subscr_cancel_auth(cleanjid);    // Cancel "from"
-  jb_subscr_request_cancel(cleanjid); // Cancel "to"
-
-  // Ask for removal from roster
-  iqn = iqs_new(JPACKET__SET, NS_ROSTER, NULL, IQS_DEFAULT_TIMEOUT);
-  y = xmlnode_get_tag(iqn->xmldata, "query");
-  z = xmlnode_insert_tag(y, "item");
-  xmlnode_put_attrib(z, "jid", cleanjid);
-  xmlnode_put_attrib(z, "subscription", "remove");
-  jab_send(jc, iqn->xmldata);
-  iqs_del(iqn->id); // XXX
-
-  roster_del_user(cleanjid);
-  g_free(cleanjid);
-  buddylist_build();
-
-  update_roster = TRUE;
-}
-
-void jb_updatebuddy(const char *bjid, const char *name, const char *group)
-{
-  xmlnode y;
-  eviqs *iqn;
-  char *cleanjid;
-
-  if (!online) return;
-
-  // XXX We should check name's and group's correctness
-
-  cleanjid = jidtodisp(bjid); // Stripping resource, just in case...
-
-  iqn = iqs_new(JPACKET__SET, NS_ROSTER, NULL, IQS_DEFAULT_TIMEOUT);
-  y = xmlnode_insert_tag(xmlnode_get_tag(iqn->xmldata, "query"), "item");
-  xmlnode_put_attrib(y, "jid", cleanjid);
-  xmlnode_put_attrib(y, "name", name);
-
-  if (group) {
-    y = xmlnode_insert_tag(y, "group");
-    xmlnode_insert_cdata(y, group, (unsigned) -1);
-  }
-
-  jab_send(jc, iqn->xmldata);
-  iqs_del(iqn->id); // XXX
-  g_free(cleanjid);
-}
-
-void jb_request(const char *fjid, enum iqreq_type reqtype)
-{
-  GSList *resources, *p_res;
-  GSList *roster_elt;
-  void (*request_fn)(const char *);
-  const char *strreqtype;
-
-  if (!online) return;
-
-  if (reqtype == iqreq_version) {
-    request_fn = &request_version;
-    strreqtype = "version";
-  } else if (reqtype == iqreq_time) {
-    request_fn = &request_time;
-    strreqtype = "time";
-  } else if (reqtype == iqreq_last) {
-    request_fn = &request_last;
-    strreqtype = "last";
-  } else if (reqtype == iqreq_vcard) {
-    // Special case
-  } else
-    return;
-
-  // vCard request
-  if (reqtype == iqreq_vcard) {
-    request_vcard(fjid);
-    scr_LogPrint(LPRINT_NORMAL, "Sent vCard request to <%s>", fjid);
-    return;
-  }
-
-  if (strchr(fjid, JID_RESOURCE_SEPARATOR)) {
-    // This is a full JID
-    (*request_fn)(fjid);
-    scr_LogPrint(LPRINT_NORMAL, "Sent %s request to <%s>", strreqtype, fjid);
-    return;
-  }
-
-  // The resource has not been specified
-  roster_elt = roster_find(fjid, jidsearch, ROSTER_TYPE_USER|ROSTER_TYPE_ROOM);
-  if (!roster_elt) {
-    scr_LogPrint(LPRINT_NORMAL, "No known resource for <%s>...", fjid);
-    (*request_fn)(fjid); // Let's send a request anyway...
-    scr_LogPrint(LPRINT_NORMAL, "Sent %s request to <%s>", strreqtype, fjid);
-    return;
-  }
-
-  // Send a request to each resource
-  resources = buddy_getresources(roster_elt->data);
-  if (!resources) {
-    scr_LogPrint(LPRINT_NORMAL, "No known resource for <%s>...", fjid);
-    (*request_fn)(fjid); // Let's send a request anyway...
-    scr_LogPrint(LPRINT_NORMAL, "Sent %s request to <%s>", strreqtype, fjid);
-  }
-  for (p_res = resources ; p_res ; p_res = g_slist_next(p_res)) {
-    gchar *fulljid;
-    fulljid = g_strdup_printf("%s/%s", fjid, (char*)p_res->data);
-    (*request_fn)(fulljid);
-    scr_LogPrint(LPRINT_NORMAL, "Sent %s request to <%s>", strreqtype, fulljid);
-    g_free(fulljid);
-    g_free(p_res->data);
-  }
-  g_slist_free(resources);
-}
-
-// Join a MUC room
-void jb_room_join(const char *room, const char *nickname, const char *passwd)
-{
-  xmlnode x, y;
-  gchar *roomid;
-  GSList *room_elt;
-
-  if (!online || !room) return;
-  if (!nickname)        return;
-
-  roomid = g_strdup_printf("%s/%s", room, nickname);
-  if (check_jid_syntax(roomid)) {
-    scr_LogPrint(LPRINT_NORMAL, "<%s/%s> is not a valid Jabber room", room,
-                 nickname);
-    g_free(roomid);
-    return;
-  }
-
-  room_elt = roster_find(room, jidsearch, ROSTER_TYPE_USER|ROSTER_TYPE_ROOM);
-  // Add room if it doesn't already exist
-  if (!room_elt) {
-    room_elt = roster_add_user(room, NULL, NULL, ROSTER_TYPE_ROOM,
-                               sub_none, -1);
-  } else {
-    // Make sure this is a room (it can be a conversion user->room)
-    buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
-  }
-  // If insideroom is TRUE, this is a nickname change and we don't care here
-  if (!buddy_getinsideroom(room_elt->data)) {
-    // We're trying to enter a room
-    buddy_setnickname(room_elt->data, nickname);
-  }
-
-  // Send the XML request
-  x = presnew(mystatus, roomid, mystatusmsg);
-  y = xmlnode_insert_tag(x, "x");
-  xmlnode_put_attrib(y, "xmlns", "http://jabber.org/protocol/muc");
-  if (passwd) {
-    xmlnode_insert_cdata(xmlnode_insert_tag(y, "password"), passwd,
-                         (unsigned) -1);
-  }
-
-  jab_send(jc, x);
-  xmlnode_free(x);
-  jb_reset_keepalive();
-  g_free(roomid);
-}
-
-// Unlock a MUC room
-// room syntax: "room@server"
-void jb_room_unlock(const char *room)
-{
-  xmlnode y, z;
-  eviqs *iqn;
-
-  if (!online || !room) return;
-
-  iqn = iqs_new(JPACKET__SET, "http://jabber.org/protocol/muc#owner",
-                "unlock", IQS_DEFAULT_TIMEOUT);
-  xmlnode_put_attrib(iqn->xmldata, "to", room);
-  y = xmlnode_get_tag(iqn->xmldata, "query");
-  z = xmlnode_insert_tag(y, "x");
-  xmlnode_put_attrib(z, "xmlns", "jabber:x:data");
-  xmlnode_put_attrib(z, "type", "submit");
-
-  jab_send(jc, iqn->xmldata);
-  iqs_del(iqn->id); // XXX
-  jb_reset_keepalive();
-}
-
-// Destroy a MUC room
-// room syntax: "room@server"
-void jb_room_destroy(const char *room, const char *venue, const char *reason)
-{
-  xmlnode y, z;
-  eviqs *iqn;
-
-  if (!online || !room) return;
-
-  iqn = iqs_new(JPACKET__SET, "http://jabber.org/protocol/muc#owner",
-                "destroy", IQS_DEFAULT_TIMEOUT);
-  xmlnode_put_attrib(iqn->xmldata, "to", room);
-  y = xmlnode_get_tag(iqn->xmldata, "query");
-  z = xmlnode_insert_tag(y, "destroy");
-
-  if (venue && *venue)
-    xmlnode_put_attrib(z, "jid", venue);
-
-  if (reason) {
-    y = xmlnode_insert_tag(z, "reason");
-    xmlnode_insert_cdata(y, reason, (unsigned) -1);
-  }
-
-  jab_send(jc, iqn->xmldata);
-  iqs_del(iqn->id); // XXX
-  jb_reset_keepalive();
-}
-
-// Change role or affiliation of a MUC user
-// room syntax: "room@server"
-// Either the jid or the nickname must be set (when banning, only the jid is
-// allowed)
-// ra: new role or affiliation
-//     (ex. role none for kick, affil outcast for ban...)
-// The reason can be null
-// Return 0 if everything is ok
-int jb_room_setattrib(const char *roomid, const char *fjid, const char *nick,
-                      struct role_affil ra, const char *reason)
-{
-  xmlnode y, z;
-  eviqs *iqn;
-
-  if (!online || !roomid) return 1;
-  if (!fjid && !nick) return 1;
-
-  if (check_jid_syntax((char*)roomid)) {
-    scr_LogPrint(LPRINT_NORMAL, "<%s> is not a valid Jabber id", roomid);
-    return 1;
-  }
-  if (fjid && check_jid_syntax((char*)fjid)) {
-    scr_LogPrint(LPRINT_NORMAL, "<%s> is not a valid Jabber id", fjid);
-    return 1;
-  }
-
-  if (ra.type == type_affil && ra.val.affil == affil_outcast && !fjid)
-    return 1; // Shouldn't happen (jid mandatory when banning)
-
-  iqn = iqs_new(JPACKET__SET, "http://jabber.org/protocol/muc#admin",
-                "roleaffil", IQS_DEFAULT_TIMEOUT);
-  xmlnode_put_attrib(iqn->xmldata, "to", roomid);
-  xmlnode_put_attrib(iqn->xmldata, "type", "set");
-  y = xmlnode_get_tag(iqn->xmldata, "query");
-  z = xmlnode_insert_tag(y, "item");
-
-  if (fjid) {
-    xmlnode_put_attrib(z, "jid", fjid);
-  } else { // nickname
-    xmlnode_put_attrib(z, "nick", nick);
-  }
-
-  if (ra.type == type_affil)
-    xmlnode_put_attrib(z, "affiliation", straffil[ra.val.affil]);
-  else if (ra.type == type_role)
-    xmlnode_put_attrib(z, "role", strrole[ra.val.role]);
-
-  if (reason) {
-    y = xmlnode_insert_tag(z, "reason");
-    xmlnode_insert_cdata(y, reason, (unsigned) -1);
-  }
-
-  jab_send(jc, iqn->xmldata);
-  iqs_del(iqn->id); // XXX
-  jb_reset_keepalive();
-
-  return 0;
-}
-
-// Invite a user to a MUC room
-// room syntax: "room@server"
-// reason can be null.
-void jb_room_invite(const char *room, const char *fjid, const char *reason)
-{
-  xmlnode x, y, z;
-
-  if (!online || !room || !fjid) return;
-
-  x = jutil_msgnew(NULL, (char*)room, NULL, NULL);
-
-  y = xmlnode_insert_tag(x, "x");
-  xmlnode_put_attrib(y, "xmlns", "http://jabber.org/protocol/muc#user");
-
-  z = xmlnode_insert_tag(y, "invite");
-  xmlnode_put_attrib(z, "to", fjid);
-
-  if (reason) {
-    y = xmlnode_insert_tag(z, "reason");
-    xmlnode_insert_cdata(y, reason, (unsigned) -1);
-  }
-
-  jab_send(jc, x);
-  xmlnode_free(x);
-  jb_reset_keepalive();
-}
-
-//  jb_is_bookmarked(roomjid)
-// Return TRUE if there's a bookmark for the given jid.
-guint jb_is_bookmarked(const char *bjid)
-{
-  xmlnode x;
-
-  if (!bookmarks)
-    return FALSE;
-
-  // Walk through the storage bookmark tags
-  x = xmlnode_get_firstchild(bookmarks);
-  for ( ; x; x = xmlnode_get_nextsibling(x)) {
-    const char *p = xmlnode_get_name(x);
-    // If the node is a conference item, check the jid.
-    if (p && !strcmp(p, "conference")) {
-      const char *fjid = xmlnode_get_attrib(x, "jid");
-      if (fjid && !strcasecmp(bjid, fjid))
-        return TRUE;
-    }
-  }
-  return FALSE;
-}
-
-//  jb_get_bookmark_nick(roomjid)
-// Return the room nickname if it is present in a bookmark.
-const char *jb_get_bookmark_nick(const char *bjid)
-{
-  xmlnode x;
-
-  if (!bookmarks || !bjid)
-    return NULL;
-
-  // Walk through the storage bookmark tags
-  x = xmlnode_get_firstchild(bookmarks);
-  for ( ; x; x = xmlnode_get_nextsibling(x)) {
-    const char *p = xmlnode_get_name(x);
-    // If the node is a conference item, check the jid.
-    if (p && !strcmp(p, "conference")) {
-      const char *fjid = xmlnode_get_attrib(x, "jid");
-      if (fjid && !strcasecmp(bjid, fjid))
-        return xmlnode_get_tag_data(x, "nick");
-    }
-  }
-  return NULL;
-}
-
-
-//  jb_get_all_storage_bookmarks()
-// Return a GSList with all storage bookmarks.
-// The caller should g_free the list and its contents.
-GSList *jb_get_all_storage_bookmarks(void)
-{
-  xmlnode x;
-  GSList *sl_bookmarks = NULL;
-
-  // If we have no bookmarks, probably the server doesn't support them.
-  if (!bookmarks)
-    return NULL;
-
-  // Walk through the storage bookmark tags
-  x = xmlnode_get_firstchild(bookmarks);
-  for ( ; x; x = xmlnode_get_nextsibling(x)) {
-    const char *p = xmlnode_get_name(x);
-    // If the node is a conference item, let's add the note to our list.
-    if (p && !strcmp(p, "conference")) {
-      struct bookmark *bm_elt;
-      const char *autojoin, *name, *nick;
-      const char *fjid = xmlnode_get_attrib(x, "jid");
-      if (!fjid)
-        continue;
-      bm_elt = g_new0(struct bookmark, 1);
-      bm_elt->roomjid = g_strdup(fjid);
-      autojoin = xmlnode_get_attrib(x, "autojoin");
-      nick = xmlnode_get_attrib(x, "nick");
-      name = xmlnode_get_attrib(x, "name");
-      if (autojoin && !strcmp(autojoin, "1"))
-        bm_elt->autojoin = 1;
-      if (nick)
-        bm_elt->nick = g_strdup(nick);
-      if (name)
-        bm_elt->name = g_strdup(name);
-      sl_bookmarks = g_slist_append(sl_bookmarks, bm_elt);
-    }
-  }
-  return sl_bookmarks;
-}
-
-//  jb_set_storage_bookmark(roomid, name, nick, passwd, autojoin,
-//                          printstatus, autowhois)
-// Update the private storage bookmarks: add a conference room.
-// If name is nil, we remove the bookmark.
-void jb_set_storage_bookmark(const char *roomid, const char *name,
-                             const char *nick, const char *passwd,
-                             int autojoin, enum room_printstatus pstatus,
-                             enum room_autowhois awhois)
-{
-  xmlnode x;
-  bool changed = FALSE;
-
-  if (!roomid)
-    return;
-
-  // If we have no bookmarks, probably the server doesn't support them.
-  if (!bookmarks) {
-    scr_LogPrint(LPRINT_NORMAL,
-                 "Sorry, your server doesn't seem to support private storage.");
-    return;
-  }
-
-  // Walk through the storage tags
-  x = xmlnode_get_firstchild(bookmarks);
-  for ( ; x; x = xmlnode_get_nextsibling(x)) {
-    const char *p = xmlnode_get_name(x);
-    // If the current node is a conference item, see if we have to replace it.
-    if (p && !strcmp(p, "conference")) {
-      const char *fjid = xmlnode_get_attrib(x, "jid");
-      if (!fjid)
-        continue;
-      if (!strcmp(fjid, roomid)) {
-        // We've found a bookmark for this room.  Let's hide it and we'll
-        // create a new one.
-        xmlnode_hide(x);
-        changed = TRUE;
-        if (!name)
-          scr_LogPrint(LPRINT_LOGNORM, "Deleting bookmark...");
-      }
-    }
-  }
-
-  // Let's create a node/bookmark for this roomid, if the name is not NULL.
-  if (name) {
-    x = xmlnode_insert_tag(bookmarks, "conference");
-    xmlnode_put_attrib(x, "jid", roomid);
-    xmlnode_put_attrib(x, "name", name);
-    xmlnode_put_attrib(x, "autojoin", autojoin ? "1" : "0");
-    if (nick)
-      xmlnode_insert_cdata(xmlnode_insert_tag(x, "nick"), nick, -1);
-    if (passwd)
-      xmlnode_insert_cdata(xmlnode_insert_tag(x, "password"), passwd, -1);
-    if (pstatus)
-      xmlnode_insert_cdata(xmlnode_insert_tag(x, "print_status"),
-                           strprintstatus[pstatus], -1);
-    if (awhois)
-      xmlnode_put_attrib(x, "autowhois", (awhois == autowhois_on ? "1" : "0"));
-    changed = TRUE;
-    scr_LogPrint(LPRINT_LOGNORM, "Updating bookmarks...");
-  }
-
-  if (!changed)
-    return;
-
-  if (online)
-    send_storage_bookmarks();
-  else
-    scr_LogPrint(LPRINT_LOGNORM,
-                 "Warning: you're not connected to the server.");
-}
-
-static struct annotation *parse_storage_rosternote(xmlnode notenode)
-{
-  const char *p;
-  struct annotation *note = g_new0(struct annotation, 1);
-  p = xmlnode_get_attrib(notenode, "cdate");
-  if (p)
-    note->cdate = from_iso8601(p, 1);
-  p = xmlnode_get_attrib(notenode, "mdate");
-  if (p)
-    note->mdate = from_iso8601(p, 1);
-  note->text = g_strdup(xmlnode_get_data(notenode));
-  note->jid = g_strdup(xmlnode_get_attrib(notenode, "jid"));
-  return note;
-}
-
-//  jb_get_all_storage_rosternotes()
-// Return a GSList with all storage annotations.
-// The caller should g_free the list and its contents.
-GSList *jb_get_all_storage_rosternotes(void)
-{
-  xmlnode x;
-  GSList *sl_notes = NULL;
-
-  // If we have no rosternotes, probably the server doesn't support them.
-  if (!rosternotes)
-    return NULL;
-
-  // Walk through the storage rosternotes tags
-  x = xmlnode_get_firstchild(rosternotes);
-  for ( ; x; x = xmlnode_get_nextsibling(x)) {
-    const char *p;
-    struct annotation *note;
-    p = xmlnode_get_name(x);
-
-    // We want a note item
-    if (!p || strcmp(p, "note"))
-      continue;
-    // Just in case, check the jid...
-    if (!xmlnode_get_attrib(x, "jid"))
-      continue;
-    // Ok, let's add the note to our list
-    note = parse_storage_rosternote(x);
-    sl_notes = g_slist_append(sl_notes, note);
-  }
-  return sl_notes;
-}
-
-//  jb_get_storage_rosternotes(barejid, silent)
-// Return the annotation associated with this jid.
-// If silent is TRUE, no warning is displayed when rosternotes is disabled
-// The caller should g_free the string and structure after use.
-struct annotation *jb_get_storage_rosternotes(const char *barejid, int silent)
-{
-  xmlnode x;
-
-  if (!barejid)
-    return NULL;
-
-  // If we have no rosternotes, probably the server doesn't support them.
-  if (!rosternotes) {
-    if (!silent)
-      scr_LogPrint(LPRINT_NORMAL, "Sorry, "
-                   "your server doesn't seem to support private storage.");
-    return NULL;
-  }
-
-  // Walk through the storage rosternotes tags
-  x = xmlnode_get_firstchild(rosternotes);
-  for ( ; x; x = xmlnode_get_nextsibling(x)) {
-    const char *fjid;
-    const char *p;
-    p = xmlnode_get_name(x);
-    // We want a note item
-    if (!p || strcmp(p, "note"))
-      continue;
-    // Just in case, check the jid...
-    fjid = xmlnode_get_attrib(x, "jid");
-    if (fjid && !strcmp(fjid, barejid)) // We've found a note for this contact.
-      return parse_storage_rosternote(x);
-  }
-  return NULL;  // No note found
-}
-
-//  jb_set_storage_rosternotes(barejid, note)
-// Update the private storage rosternotes: add/delete a note.
-// If note is nil, we remove the existing note.
-void jb_set_storage_rosternotes(const char *barejid, const char *note)
-{
-  xmlnode x;
-  bool changed = FALSE;
-  const char *cdate = NULL;
-
-  if (!barejid)
-    return;
-
-  // If we have no rosternotes, probably the server doesn't support them.
-  if (!rosternotes) {
-    scr_LogPrint(LPRINT_NORMAL,
-                 "Sorry, your server doesn't seem to support private storage.");
-    return;
-  }
-
-  // Walk through the storage tags
-  x = xmlnode_get_firstchild(rosternotes);
-  for ( ; x; x = xmlnode_get_nextsibling(x)) {
-    const char *p = xmlnode_get_name(x);
-    // If the current node is a conference item, see if we have to replace it.
-    if (p && !strcmp(p, "note")) {
-      const char *fjid = xmlnode_get_attrib(x, "jid");
-      if (!fjid)
-        continue;
-      if (!strcmp(fjid, barejid)) {
-        // We've found a note for this jid.  Let's hide it and we'll
-        // create a new one.
-        cdate = xmlnode_get_attrib(x, "cdate");
-        xmlnode_hide(x);
-        changed = TRUE;
-        break;
-      }
-    }
-  }
-
-  // Let's create a node for this jid, if the note is not NULL.
-  if (note) {
-    char mdate[20];
-    time_t now;
-    time(&now);
-    to_iso8601(mdate, now);
-    if (!cdate)
-      cdate = mdate;
-    x = xmlnode_insert_tag(rosternotes, "note");
-    xmlnode_put_attrib(x, "jid", barejid);
-    xmlnode_put_attrib(x, "cdate", cdate);
-    xmlnode_put_attrib(x, "mdate", mdate);
-    xmlnode_insert_cdata(x, note, -1);
-    changed = TRUE;
-  }
-
-  if (!changed)
-    return;
-
-  if (online)
-    send_storage_rosternotes();
-  else
-    scr_LogPrint(LPRINT_LOGNORM,
-                 "Warning: you're not connected to the server.");
-}
-
-#ifdef HAVE_GPGME
-//  keys_mismatch(key, expectedkey)
-// Return TRUE if both keys are non-null and "expectedkey" doesn't match
-// the end of "key".
-// If one of the keys is null, return FALSE.
-// If expectedkey is less than 8 bytes long, return TRUE.
-//
-// Example: keys_mismatch("C9940A9BB0B92210", "B0B92210") will return FALSE.
-static bool keys_mismatch(const char *key, const char *expectedkey)
-{
-  int lk, lek;
-
-  if (!expectedkey || !key)
-    return FALSE;
-
-  lk = strlen(key);
-  lek = strlen(expectedkey);
-
-  // If the expectedkey is less than 8 bytes long, this is probably a
-  // user mistake so we consider it's a mismatch.
-  if (lek < 8)
-    return TRUE;
-
-  if (lek < lk)
-    key += lk - lek;
-
-  return strcasecmp(key, expectedkey);
-}
-#endif
-
-//  check_signature(barejid, resourcename, xmldata, text)
-// Verify the signature (in xmldata) of "text" for the contact
-// barejid/resourcename.
-// xmldata is the 'jabber:x:signed' stanza.
-// If the key id is found, the contact's PGP data are updated.
-static void check_signature(const char *barejid, const char *rname,
-                            xmlnode xmldata, const char *text)
-{
-#ifdef HAVE_GPGME
-  char *p, *key;
-  GSList *sl_buddy;
-  struct pgp_data *res_pgpdata;
-  gpgme_sigsum_t sigsum;
-
-  // All parameters must be valid
-  if (!(xmldata && barejid && rname && text))
-    return;
-
-  if (!gpg_enabled())
-    return;
-
-  // Get the resource PGP data structure
-  sl_buddy = roster_find(barejid, jidsearch, ROSTER_TYPE_USER);
-  if (!sl_buddy)
-    return;
-  res_pgpdata = buddy_resource_pgp(sl_buddy->data, rname);
-  if (!res_pgpdata)
-    return;
-
-  p = xmlnode_get_name(xmldata);
-  if (!p || strcmp(p, "x"))
-    return; // We expect "<x xmlns='jabber:x:signed'>"
-
-  // Get signature
-  p = xmlnode_get_data(xmldata);
-  if (!p)
-    return;
-
-  key = gpg_verify(p, text, &sigsum);
-  if (key) {
-    const char *expectedkey;
-    char *buf;
-    g_free(res_pgpdata->sign_keyid);
-    res_pgpdata->sign_keyid = key;
-    res_pgpdata->last_sigsum = sigsum;
-    if (sigsum & GPGME_SIGSUM_RED) {
-      buf = g_strdup_printf("Bad signature from <%s/%s>", barejid, rname);
-      scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_INFO, 0);
-      scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
-      g_free(buf);
-    }
-    // Verify that the key id is the one we expect.
-    expectedkey = settings_pgp_getkeyid(barejid);
-    if (keys_mismatch(key, expectedkey)) {
-      buf = g_strdup_printf("Warning: The KeyId from <%s/%s> doesn't match "
-                            "the key you set up", barejid, rname);
-      scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_INFO, 0);
-      scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
-      g_free(buf);
-    }
-  }
-#endif
-}
-
-static void gotmessage(char *type, const char *from, const char *body,
-                       const char *enc, const char *subject, time_t timestamp,
-                       xmlnode xmldata_signed)
-{
-  char *bjid;
-  const char *rname, *s;
-  char *decrypted_pgp = NULL;
-  char *decrypted_otr = NULL;
-  int otr_msg = 0, free_msg = 0;
-
-  bjid = jidtodisp(from);
-
-  rname = strchr(from, JID_RESOURCE_SEPARATOR);
-  if (rname) rname++;
-
-#ifdef HAVE_GPGME
-  if (enc && gpg_enabled()) {
-    decrypted_pgp = gpg_decrypt(enc);
-    if (decrypted_pgp) {
-      body = decrypted_pgp;
-    }
-  }
-  // Check signature of an unencrypted message
-  if (xmldata_signed && gpg_enabled())
-    check_signature(bjid, rname, xmldata_signed, decrypted_pgp);
-#endif
-
-#ifdef HAVE_LIBOTR
-  if (otr_enabled()) {
-    decrypted_otr = (char*)body;
-    otr_msg = otr_receive(&decrypted_otr, bjid, &free_msg);
-    if (!decrypted_otr) {
-      goto gotmessage_return;
-    }
-    body = decrypted_otr;
-  }
-#endif
-
-  // Check for unexpected groupchat messages
-  // If we receive a groupchat message from a room we're not a member of,
-  // this is probably a server issue and the best we can do is to send
-  // a type unavailable.
-  if (type && !strcmp(type, "groupchat") && !roster_getnickname(bjid)) {
-    // It shouldn't happen, probably a server issue
-    GSList *room_elt;
-    char *mbuf;
-
-    mbuf = g_strdup_printf("Unexpected groupchat packet!");
-    scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf);
-    scr_WriteIncomingMessage(bjid, mbuf, 0, HBB_PREFIX_INFO, 0);
-    g_free(mbuf);
-
-    // Send back an unavailable packet
-    jb_setstatus(offline, bjid, "", TRUE);
-
-    // MUC
-    // Make sure this is a room (it can be a conversion user->room)
-    room_elt = roster_find(bjid, jidsearch, 0);
-    if (!room_elt) {
-      room_elt = roster_add_user(bjid, NULL, NULL, ROSTER_TYPE_ROOM,
-                                 sub_none, -1);
-    } else {
-      buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
-    }
-
-    buddylist_build();
-    scr_DrawRoster();
-    goto gotmessage_return;
-  }
-
-  // We don't call the message_in hook if 'block_unsubscribed' is true and
-  // this is a regular message from an unsubscribed user.
-  // System messages (from our server) are allowed.
-  if (!settings_opt_get_int("block_unsubscribed") ||
-      (roster_getsubscription(bjid) & sub_from) ||
-      (type && strcmp(type, "chat")) ||
-      ((s = settings_opt_get("server")) != NULL && !strcasecmp(bjid, s))) {
-    gchar *fullbody = NULL;
-    guint encrypted;
-
-    if (decrypted_pgp)
-      encrypted = ENCRYPTED_PGP;
-    else if (otr_msg)
-      encrypted = ENCRYPTED_OTR;
-    else
-      encrypted = 0;
-
-    if (subject) {
-      if (body)
-        fullbody = g_strdup_printf("[%s]\n%s", subject, body);
-      else
-        fullbody = g_strdup_printf("[%s]\n", subject);
-      body = fullbody;
-    }
-    hk_message_in(bjid, rname, timestamp, body, type, encrypted);
-    g_free(fullbody);
-  } else {
-    scr_LogPrint(LPRINT_LOGNORM, "Blocked a message from <%s>", bjid);
-  }
-
-gotmessage_return:
-  // Clean up and exit
-  g_free(bjid);
-  g_free(decrypted_pgp);
-  if (free_msg)
-    g_free(decrypted_otr);
-}
-
-static const char *defaulterrormsg(int code)
-{
-  const char *desc;
-
-  switch(code) {
-    case 401: desc = "Unauthorized";
-              break;
-    case 302: desc = "Redirect";
-              break;
-    case 400: desc = "Bad request";
-              break;
-    case 402: desc = "Payment Required";
-              break;
-    case 403: desc = "Forbidden";
-              break;
-    case 404: desc = "Not Found";
-              break;
-    case 405: desc = "Not Allowed";
-              break;
-    case 406: desc = "Not Acceptable";
-              break;
-    case 407: desc = "Registration Required";
-              break;
-    case 408: desc = "Request Timeout";
-              break;
-    case 409: desc = "Conflict";
-              break;
-    case 500: desc = "Internal Server Error";
-              break;
-    case 501: desc = "Not Implemented";
-              break;
-    case 502: desc = "Remote Server Error";
-              break;
-    case 503: desc = "Service Unavailable";
-              break;
-    case 504: desc = "Remote Server Timeout";
-              break;
-    default:
-              desc = NULL;
-  }
-
-  return desc;
-}
-
-//  display_server_error(x)
-// Display the error to the user
-// x: error tag xmlnode pointer
-void display_server_error(xmlnode x)
-{
-  const char *desc = NULL;
-  char *sdesc;
-  int code = 0;
-  char *s;
-  const char *p;
-
-  if (!x) return;
-
-  /* RFC3920:
-   *    The <error/> element:
-   *       o  MUST contain a child element corresponding to one of the defined
-   *          stanza error conditions specified below; this element MUST be
-   *          qualified by the 'urn:ietf:params:xml:ns:xmpp-stanzas' namespace.
-   */
-  p = xmlnode_get_name(xmlnode_get_firstchild(x));
-  if (p)
-    scr_LogPrint(LPRINT_LOGNORM, "Received error packet [%s]", p);
-
-  // For backward compatibility
-  if ((s = xmlnode_get_attrib(x, "code")) != NULL) {
-    code = atoi(s);
-    // Default message
-    desc = defaulterrormsg(code);
-  }
-
-  // Error tag data is better, if available
-  s = xmlnode_get_data(x);
-  if (s && *s) desc = s;
-
-  // And sometimes there is a text message
-  s = xmlnode_get_tag_data(x, "text");
-  if (s && *s) desc = s;
-
-  // If we still have no description, let's give up
-  if (!desc)
-    return;
-
-  // Strip trailing newlines
-  sdesc = g_strdup(desc);
-  for (s = sdesc; *s; s++) ;
-  if (s > sdesc)
-    s--;
-  while (s >= sdesc && (*s == '\n' || *s == '\r'))
-    *s-- = '\0';
-
-  scr_LogPrint(LPRINT_LOGNORM, "Error code from server: %d %s", code, sdesc);
-  g_free(sdesc);
-}
-
-static void statehandler(jconn conn, int state)
-{
-  static int previous_state = -1;
-
-  scr_LogPrint(LPRINT_DEBUG, "StateHandler called (state=%d).", state);
-
-  switch(state) {
-    case JCONN_STATE_OFF:
-        if (previous_state != JCONN_STATE_OFF)
-          scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Not connected to the server");
-
-        // Sometimes the state isn't correctly updated
-        if (jc)
-          jc->state = JCONN_STATE_OFF;
-        online = FALSE;
-        mystatus = offline;
-        // Free bookmarks
-        xmlnode_free(bookmarks);
-        bookmarks = NULL;
-        // Free roster
-        roster_free();
-        xmlnode_free(rosternotes);
-        rosternotes = NULL;
-        // Update display
-        update_roster = TRUE;
-        scr_UpdateBuddyWindow();
-        break;
-
-    case JCONN_STATE_CONNECTED:
-        scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Connected to the server");
-        break;
-
-    case JCONN_STATE_AUTH:
-        scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Authenticating to the server");
-        break;
-
-    case JCONN_STATE_ON:
-        scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Communication with the server "
-                     "established");
-        online = TRUE;
-        update_last_use();
-        // We set AutoConnection to true after the 1st successful connection
-        AutoConnection = TRUE;
-        break;
-
-    case JCONN_STATE_CONNECTING:
-        if (previous_state != state)
-          scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Connecting to the server");
-        break;
-
-    default:
-        break;
-  }
-  previous_state = state;
-}
-
-inline static xmlnode xml_get_xmlns(xmlnode xmldata, const char *xmlns)
-{
-  xmlnode x;
-  char *p;
-
-  x = xmlnode_get_firstchild(xmldata);
-  for ( ; x; x = xmlnode_get_nextsibling(x)) {
-    if ((p = xmlnode_get_attrib(x, "xmlns")) && !strcmp(p, xmlns))
-      break;
-  }
-  return x;
-}
-
-static time_t xml_get_timestamp(xmlnode xmldata)
-{
-  xmlnode x;
-  char *p;
-
-  x = xml_get_xmlns(xmldata, NS_XMPP_DELAY);
-  if (x && !strcmp(xmlnode_get_name(x), "delay") &&
-      (p = xmlnode_get_attrib(x, "stamp")) != NULL)
-    return from_iso8601(p, 1);
-  x = xml_get_xmlns(xmldata, NS_DELAY);
-  if ((p = xmlnode_get_attrib(x, "stamp")) != NULL)
-    return from_iso8601(p, 1);
-  return 0;
-}
-
-//  muc_get_item_info(...)
-// Get room member's information from xmlndata.
-// The variables must be initialized before calling this function,
-// because they are not touched if the relevant information is missing.
-static void muc_get_item_info(const char *from, xmlnode xmldata,
-                              enum imrole *mbrole, enum imaffiliation *mbaffil,
-                              const char **mbjid, const char **mbnick,
-                              const char **actorjid, const char **reason)
-{
-  xmlnode y, z;
-  char *p;
-
-  y = xmlnode_get_tag(xmldata, "item");
-  if (!y)
-    return;
-
-  p = xmlnode_get_attrib(y, "affiliation");
-  if (p) {
-    if (!strcmp(p, "owner"))        *mbaffil = affil_owner;
-    else if (!strcmp(p, "admin"))   *mbaffil = affil_admin;
-    else if (!strcmp(p, "member"))  *mbaffil = affil_member;
-    else if (!strcmp(p, "outcast")) *mbaffil = affil_outcast;
-    else if (!strcmp(p, "none"))    *mbaffil = affil_none;
-    else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown affiliation \"%s\"",
-                      from, p);
-  }
-  p = xmlnode_get_attrib(y, "role");
-  if (p) {
-    if (!strcmp(p, "moderator"))        *mbrole = role_moderator;
-    else if (!strcmp(p, "participant")) *mbrole = role_participant;
-    else if (!strcmp(p, "visitor"))     *mbrole = role_visitor;
-    else if (!strcmp(p, "none"))        *mbrole = role_none;
-    else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown role \"%s\"",
-                      from, p);
-  }
-  *mbjid = xmlnode_get_attrib(y, "jid");
-  *mbnick = xmlnode_get_attrib(y, "nick");
-  // For kick/ban, there can be actor and reason tags
-  *reason = xmlnode_get_tag_data(y, "reason");
-  z = xmlnode_get_tag(y, "actor");
-  if (z)
-    *actorjid = xmlnode_get_attrib(z, "jid");
-}
-
-//  muc_handle_join(...)
-// Handle a join event in a MUC room.
-// This function will return the new_member value TRUE if somebody else joins
-// the room (and FALSE if _we_ are joining the room).
-static bool muc_handle_join(const GSList *room_elt, const char *rname,
-                            const char *roomjid, const char *ournick,
-                            enum room_printstatus printstatus,
-                            time_t usttime, int log_muc_conf)
-{
-  bool new_member = FALSE; // True if somebody else joins the room (not us)
-  gchar *mbuf;
-
-  if (!buddy_getinsideroom(room_elt->data)) {
-    // We weren't inside the room yet.  Now we are.
-    // However, this could be a presence packet from another room member
-
-    buddy_setinsideroom(room_elt->data, TRUE);
-    // Set the message flag unless we're already in the room buffer window
-    scr_setmsgflag_if_needed(roomjid, FALSE);
-    // Add a message to the tracelog file
-    mbuf = g_strdup_printf("You have joined %s as \"%s\"", roomjid, ournick);
-    scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf);
-    g_free(mbuf);
-    mbuf = g_strdup_printf("You have joined as \"%s\"", ournick);
-
-    // The 1st presence message could be for another room member
-    if (strcmp(ournick, rname)) {
-      // Display current mbuf and create a new message for the member
-      // Note: the usttime timestamp is related to the other member,
-      //       so we use 0 here.
-      scr_WriteIncomingMessage(roomjid, mbuf, 0,
-                               HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
-      if (log_muc_conf)
-        hlog_write_message(roomjid, 0, -1, mbuf);
-      g_free(mbuf);
-      if (printstatus != status_none)
-        mbuf = g_strdup_printf("%s has joined", rname);
-      else
-        mbuf = NULL;
-      new_member = TRUE;
-    }
-  } else {
-    mbuf = NULL;
-    if (strcmp(ournick, rname)) {
-      if (printstatus != status_none)
-        mbuf = g_strdup_printf("%s has joined", rname);
-      new_member = TRUE;
-    }
-  }
-
-  if (mbuf) {
-    guint msgflags = HBB_PREFIX_INFO;
-    if (!settings_opt_get_int("muc_flag_joins"))
-      msgflags |= HBB_PREFIX_NOFLAG;
-    scr_WriteIncomingMessage(roomjid, mbuf, usttime, msgflags, 0);
-    if (log_muc_conf)
-      hlog_write_message(roomjid, 0, -1, mbuf);
-    g_free(mbuf);
-  }
-
-  return new_member;
-}
-
-static void handle_presence_muc(const char *from, xmlnode xmldata,
-                                const char *roomjid, const char *rname,
-                                enum imstatus ust, char *ustmsg,
-                                time_t usttime, char bpprio)
-{
-  xmlnode y;
-  char *p;
-  char *mbuf;
-  const char *ournick;
-  enum imrole mbrole = role_none;
-  enum imaffiliation mbaffil = affil_none;
-  enum room_printstatus printstatus;
-  enum room_autowhois autowhois;
-  const char *mbjid = NULL, *mbnick = NULL;
-  const char *actorjid = NULL, *reason = NULL;
-  bool new_member = FALSE; // True if somebody else joins the room (not us)
-  guint statuscode = 0;
-  guint nickchange = 0;
-  GSList *room_elt;
-  int log_muc_conf;
-  guint msgflags;
-
-  log_muc_conf = settings_opt_get_int("log_muc_conf");
-
-  room_elt = roster_find(roomjid, jidsearch, 0);
-  if (!room_elt) {
-    // Add room if it doesn't already exist
-    // It shouldn't happen, there is probably something wrong (server or
-    // network issue?)
-    room_elt = roster_add_user(roomjid, NULL, NULL, ROSTER_TYPE_ROOM,
-                               sub_none, -1);
-    scr_LogPrint(LPRINT_LOGNORM, "Strange MUC presence message");
-  } else {
-    // Make sure this is a room (it can be a conversion user->room)
-    buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
-  }
-
-  // Get room member's information
-  muc_get_item_info(from, xmldata, &mbrole, &mbaffil, &mbjid, &mbnick,
-                    &actorjid, &reason);
-
-  // Get our room nickname
-  ournick = buddy_getnickname(room_elt->data);
-
-  if (!ournick) {
-    // It shouldn't happen, probably a server issue
-    mbuf = g_strdup_printf("Unexpected groupchat packet!");
-
-    scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf);
-    scr_WriteIncomingMessage(roomjid, mbuf, 0, HBB_PREFIX_INFO, 0);
-    g_free(mbuf);
-    // Send back an unavailable packet
-    jb_setstatus(offline, roomjid, "", TRUE);
-    scr_DrawRoster();
-    return;
-  }
-
-  // Get the status code
-  // 201: a room has been created
-  // 301: the user has been banned from the room
-  // 303: new room nickname
-  // 307: the user has been kicked from the room
-  // 321,322,332: the user has been removed from the room
-  y = xmlnode_get_tag(xmldata, "status");
-  if (y) {
-    p = xmlnode_get_attrib(y, "code");
-    if (p)
-      statuscode = atoi(p);
-  }
-
-  // Get the room's "print_status" settings
-  printstatus = buddy_getprintstatus(room_elt->data);
-  if (printstatus == status_default) {
-    printstatus = (guint) settings_opt_get_int("muc_print_status");
-    if (printstatus > 3)
-      printstatus = status_default;
-  }
-
-  // A new room has been created; accept MUC default config
-  if (statuscode == 201)
-    jb_room_unlock(roomjid);
-
-  // Check for nickname change
-  if (statuscode == 303 && mbnick) {
-    mbuf = g_strdup_printf("%s is now known as %s", rname, mbnick);
-    scr_WriteIncomingMessage(roomjid, mbuf, usttime,
-                             HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
-    if (log_muc_conf)
-      hlog_write_message(roomjid, 0, -1, mbuf);
-    g_free(mbuf);
-    buddy_resource_setname(room_elt->data, rname, mbnick);
-    // Maybe it's _our_ nickname...
-    if (ournick && !strcmp(rname, ournick))
-      buddy_setnickname(room_elt->data, mbnick);
-    nickchange = TRUE;
-  }
-
-  // Check for departure/arrival
-  if (!mbnick && ust == offline) {
-    // Somebody is leaving
-    enum { leave=0, kick, ban } how = leave;
-    bool we_left = FALSE;
-
-    if (statuscode == 307)
-      how = kick;
-    else if (statuscode == 301)
-      how = ban;
-
-    // If this is a leave, check if it is ourself
-    if (ournick && !strcmp(rname, ournick)) {
-      we_left = TRUE; // _We_ have left! (kicked, banned, etc.)
-      buddy_setinsideroom(room_elt->data, FALSE);
-      buddy_setnickname(room_elt->data, NULL);
-      buddy_del_all_resources(room_elt->data);
-      buddy_settopic(room_elt->data, NULL);
-      scr_UpdateChatStatus(FALSE);
-      update_roster = TRUE;
-    }
-
-    // The message depends on _who_ left, and _how_
-    if (how) {
-      gchar *mbuf_end;
-      // Forced leave
-      if (actorjid) {
-        mbuf_end = g_strdup_printf("%s from %s by <%s>.\nReason: %s",
-                                   (how == ban ? "banned" : "kicked"),
-                                   roomjid, actorjid, reason);
-      } else {
-        mbuf_end = g_strdup_printf("%s from %s.",
-                                   (how == ban ? "banned" : "kicked"),
-                                   roomjid);
-      }
-      if (we_left)
-        mbuf = g_strdup_printf("You have been %s", mbuf_end);
-      else
-        mbuf = g_strdup_printf("%s has been %s", rname, mbuf_end);
-
-      g_free(mbuf_end);
-    } else {
-      // Natural leave
-      if (we_left) {
-        xmlnode destroynode = xmlnode_get_tag(xmldata, "destroy");
-        if (destroynode) {
-          if ((reason = xmlnode_get_tag_data(destroynode, "reason"))) {
-            mbuf = g_strdup_printf("You have left %s, "
-                                   "the room has been destroyed: %s",
-                                   roomjid, reason);
-          } else {
-            mbuf = g_strdup_printf("You have left %s, "
-                                   "the room has been destroyed", roomjid);
-          }
-        } else {
-          mbuf = g_strdup_printf("You have left %s", roomjid);
-        }
-      } else {
-        if (ust != offline) {
-          // This can happen when a network failure occurs,
-          // this isn't an official leave but the user isn't there anymore.
-          mbuf = g_strdup_printf("%s has disappeared!", rname);
-          ust = offline;
-        } else {
-          if (ustmsg)
-            mbuf = g_strdup_printf("%s has left: %s", rname, ustmsg);
-          else
-            mbuf = g_strdup_printf("%s has left", rname);
-        }
-      }
-    }
-
-    // Display the mbuf message if we're concerned
-    // or if the print_status isn't set to none.
-    if (we_left || printstatus != status_none) {
-      msgflags = HBB_PREFIX_INFO;
-      if (!we_left && settings_opt_get_int("muc_flag_joins") != 2)
-        msgflags |= HBB_PREFIX_NOFLAG;
-      scr_WriteIncomingMessage(roomjid, mbuf, usttime, msgflags, 0);
-    }
-
-    if (log_muc_conf)
-      hlog_write_message(roomjid, 0, -1, mbuf);
-
-    if (we_left) {
-      scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf);
-      g_free(mbuf);
-      return;
-    }
-    g_free(mbuf);
-  } else if (buddy_getstatus(room_elt->data, rname) == offline &&
-             ust != offline) {
-    // Somebody is joining
-    new_member = muc_handle_join(room_elt, rname, roomjid, ournick,
-                                 printstatus, usttime, log_muc_conf);
-  } else {
-    // This is a simple member status change
-
-    if (printstatus == status_all && !nickchange) {
-      mbuf = g_strdup_printf("Member status has changed: %s [%c] %s", rname,
-                             imstatus2char[ust], ((ustmsg) ? ustmsg : ""));
-      scr_WriteIncomingMessage(roomjid, mbuf, usttime,
-                               HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
-      g_free(mbuf);
-    }
-  }
-
-  // Sanity check, shouldn't happen...
-  if (!rname)
-    return;
-
-  // Update room member status
-  roster_setstatus(roomjid, rname, bpprio, ust, ustmsg, usttime,
-                   mbrole, mbaffil, mbjid);
-
-  autowhois = buddy_getautowhois(room_elt->data);
-  if (autowhois == autowhois_default)
-    autowhois = (settings_opt_get_int("muc_auto_whois") ?
-                 autowhois_on : autowhois_off);
-
-  if (new_member && autowhois == autowhois_on) {
-    // FIXME: This will fail for some UTF-8 nicknames.
-    gchar *joiner_nick = from_utf8(rname);
-    cmd_room_whois(room_elt->data, joiner_nick, FALSE);
-    g_free(joiner_nick);
-  }
-
-  scr_DrawRoster();
-}
-
-static void handle_packet_presence(jconn conn, char *type, char *from,
-                                   xmlnode xmldata)
-{
-  char *p, *r;
-  char *ustmsg;
-  const char *rname;
-  enum imstatus ust;
-  char bpprio;
-  time_t timestamp = 0L;
-  xmlnode muc_packet;
-
-  rname = strchr(from, JID_RESOURCE_SEPARATOR);
-  if (rname) rname++;
-
-  if (settings_opt_get_int("ignore_self_presence")) {
-    const char *self_fjid = jid_full(jc->user);
-    if (self_fjid && !strcasecmp(self_fjid, from)) {
-      return; // Ignoring self presence
-    }
-  }
-
-  r = jidtodisp(from);
-
-  // Check for MUC presence packet
-  muc_packet = xml_get_xmlns(xmldata, "http://jabber.org/protocol/muc#user");
-
-  if (type && !strcmp(type, TMSG_ERROR)) {
-    xmlnode x;
-    scr_LogPrint(LPRINT_LOGNORM, "Error presence packet from <%s>", r);
-    x = xmlnode_get_tag(xmldata, TMSG_ERROR);
-    display_server_error(x);
-
-    // Let's check it isn't a nickname conflict.
-    // XXX Note: We should handle the <conflict/> string condition.
-    if ((p = xmlnode_get_attrib(x, "code")) != NULL) {
-      if (atoi(p) == 409) {
-        // 409 = conlict (nickname is in use or registered by another user)
-        // If we are not inside this room, we should reset the nickname
-        GSList *room_elt = roster_find(r, jidsearch, 0);
-        if (room_elt && !buddy_getinsideroom(room_elt->data))
-          buddy_setnickname(room_elt->data, NULL);
-      }
-    }
-
-    g_free(r);
-    return;
-  }
-
-  p = xmlnode_get_tag_data(xmldata, "priority");
-  if (p && *p) bpprio = (gchar)atoi(p);
-  else         bpprio = 0;
-
-  ust = available;
-  p = xmlnode_get_tag_data(xmldata, "show");
-  if (p) {
-    if (!strcmp(p, "away"))      ust = away;
-    else if (!strcmp(p, "dnd"))  ust = dontdisturb;
-    else if (!strcmp(p, "xa"))   ust = notavail;
-    else if (!strcmp(p, "chat")) ust = freeforchat;
-  }
-
-  if (type && !strcmp(type, "unavailable"))
-    ust = offline;
-
-  ustmsg = xmlnode_get_tag_data(xmldata, "status");
-
-  // Timestamp?
-  timestamp = xml_get_timestamp(xmldata);
-
-  if (muc_packet) {
-    // This is a MUC presence message
-    handle_presence_muc(from, muc_packet, r, rname,
-                        ust, ustmsg, timestamp, bpprio);
-  } else {
-    // Not a MUC message, so this is a regular buddy...
-    // Call hk_statuschange() if status has changed or if the
-    // status message is different
-    const char *m;
-    m = roster_getstatusmsg(r, rname);
-    if ((ust != roster_getstatus(r, rname)) ||
-        (!ustmsg && m && m[0]) || (ustmsg && (!m || strcmp(ustmsg, m))))
-      hk_statuschange(r, rname, bpprio, timestamp, ust, ustmsg);
-    // Presence signature processing
-    if (!ustmsg)
-      ustmsg = ""; // Some clients omit the <status/> element :-(
-    check_signature(r, rname, xml_get_xmlns(xmldata, NS_SIGNED), ustmsg);
-  }
-
-  g_free(r);
-}
-
-//  got_invite(from, to, reason, passwd)
-// This function should be called when receiving an invitation from user
-// "from", to enter the room "to".  Optional reason and room password can
-// be provided.
-static void got_invite(char* from, char *to, char* reason, char* passwd)
-{
-  eviqs *evn;
-  event_muc_invitation *invitation;
-  GString *sbuf;
-  char *barejid;
-  GSList *room_elt;
-
-  sbuf = g_string_new("");
-  if (reason) {
-    g_string_printf(sbuf,
-                    "Received an invitation to <%s>, from <%s>, reason: %s",
-                    to, from, reason);
-  } else {
-    g_string_printf(sbuf, "Received an invitation to <%s>, from <%s>",
-                    to, from);
-  }
-
-  barejid = jidtodisp(from);
-  scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0);
-  scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str);
-
-  evn = evs_new(EVS_TYPE_INVITATION, EVS_MAX_TIMEOUT);
-  if (evn) {
-    evn->callback = &evscallback_invitation;
-    invitation = g_new(event_muc_invitation, 1);
-    invitation->to = g_strdup(to);
-    invitation->from = g_strdup(from);
-    invitation->passwd = g_strdup(passwd);
-    invitation->reason = g_strdup(reason);
-    evn->data = invitation;
-    evn->desc = g_strdup_printf("<%s> invites you to %s ", from, to);
-    g_string_printf(sbuf, "Please use /event %s accept|reject", evn->id);
-  } else {
-    g_string_printf(sbuf, "Unable to create a new event!");
-  }
-  scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0);
-  scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str);
-  g_string_free(sbuf, TRUE);
-  g_free(barejid);
-
-  // Make sure the MUC room barejid is a room in the roster
-  barejid = jidtodisp(to);
-  room_elt = roster_find(barejid, jidsearch, 0);
-  if (room_elt)
-    buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
-
-  g_free(barejid);
-}
-
-// Specific MUC message handling (for example invitation processing)
-static void got_muc_message(char *from, xmlnode x)
-{
-  xmlnode invite = xmlnode_get_tag(x, "invite");
-  if (invite)
-  {
-    char* invite_from;
-    char *reason = NULL;
-    char *password = NULL;
-    xmlnode r;
-
-    invite_from = xmlnode_get_attrib(invite, "from");
-    r = xmlnode_get_tag(invite, "reason");
-    if (r)
-      reason = xmlnode_get_tag_data(r, NULL);
-    r = xmlnode_get_tag(invite, "password");
-    if (r)
-      password = xmlnode_get_tag_data(r, NULL);
-    if (invite_from)
-      got_invite(invite_from, from, reason, password);
-  }
-  // TODO
-  // handle status code = 100 ( not anonymous )
-  // handle status code = 170 ( changement de config )
-  // 10.2.1 Notification of Configuration Changes
-  // declined invitation
-}
-
-static void handle_packet_message(jconn conn, char *type, char *from,
-                                  xmlnode xmldata)
-{
-  char *p, *r, *s;
-  xmlnode x;
-  char *body = NULL;
-  char *enc = NULL;
-  char *subject = NULL;
-  time_t timestamp = 0L;
-
-  body = xmlnode_get_tag_data(xmldata, "body");
-
-  x = xml_get_xmlns(xmldata, NS_ENCRYPTED);
-  if (x && (p = xmlnode_get_data(x)) != NULL)
-    enc = p;
-
-  p = xmlnode_get_tag_data(xmldata, "subject");
-
-  if (xmlnode_get_tag(xmldata, "subject")) {
-    if (!type || strcmp(type, TMSG_GROUPCHAT)) {  // Chat message
-      subject = p;
-    } else {                                      // Room topic
-      GSList *roombuddy;
-      gchar *mbuf = NULL;
-      gchar *subj = p;
-
-      // In a groupchat message, the subject can be NULL when
-      // the topic is cleared!
-      if (!p)
-        p = "";
-
-      // Get the room (s) and the nickname (r)
-      s = g_strdup(from);
-      r = strchr(s, JID_RESOURCE_SEPARATOR);
-      if (r) *r++ = 0;
-      else   r = s;
-      // Set the new topic
-      roombuddy = roster_find(s, jidsearch, 0);
-      if (roombuddy)
-        buddy_settopic(roombuddy->data, subj);
-      // Display inside the room window
-      if (r == s) {
-        // No specific resource (this is certainly history)
-        if (subj && *subj)
-          mbuf = g_strdup_printf("The topic has been set to: %s", subj);
-      } else {
-        if (subj)
-          mbuf = g_strdup_printf("%s has set the topic to: %s", r, subj);
-        else
-          mbuf = g_strdup_printf("%s has cleared the topic", r);
-      }
-      if (mbuf) {
-        scr_WriteIncomingMessage(s, mbuf, 0,
-                                 HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
-        if (settings_opt_get_int("log_muc_conf"))
-          hlog_write_message(s, 0, -1, mbuf);
-        g_free(mbuf);
-      }
-      g_free(s);
-      // The topic is displayed in the chat status line, so refresh now.
-      scr_UpdateChatStatus(TRUE);
-    }
-  }
-
-  // Timestamp?
-  timestamp = xml_get_timestamp(xmldata);
-
-  if (type && !strcmp(type, TMSG_ERROR)) {
-    x = xmlnode_get_tag(xmldata, TMSG_ERROR);
-    display_server_error(x);
-#if defined JEP0022 || defined JEP0085
-    // If the JEP85/22 support is probed, set it back to unknown so that
-    // we probe it again.
-    chatstates_reset_probed(from);
-#endif
-  } else {
-    handle_state_events(from, xmldata);
-  }
-  if (from && (body || subject))
-    gotmessage(type, from, body, enc, subject, timestamp,
-               xml_get_xmlns(xmldata, NS_SIGNED));
-
-  if (from) {
-    x = xml_get_xmlns(xmldata, "http://jabber.org/protocol/muc#user");
-    if (x && !strcmp(xmlnode_get_name(x), "x"))
-      got_muc_message(from, x);
-  }
-}
-
-static void handle_state_events(char *from, xmlnode xmldata)
-{
-#if defined JEP0022 || defined JEP0085
-  xmlnode state_ns = NULL;
-  const char *body;
-  char *rname, *bjid;
-  GSList *sl_buddy;
-  guint events;
-  struct jep0022 *jep22 = NULL;
-  struct jep0085 *jep85 = NULL;
-  enum {
-    JEP_none,
-    JEP_85,
-    JEP_22
-  } which_jep = JEP_none;
-
-  rname = strchr(from, JID_RESOURCE_SEPARATOR);
-  if (rname)
-    ++rname;
-  else
-    rname = from + strlen(from);
-  bjid  = jidtodisp(from);
-  sl_buddy = roster_find(bjid, jidsearch, ROSTER_TYPE_USER);
-  g_free(bjid);
-
-  /* XXX Actually that's wrong, since it filters out server "offline"
-     messages (for JEP-0022).  This JEP is (almost) deprecated so
-     we don't really care. */
-  if (!sl_buddy) {
-    return;
-  }
-
-  /* Let's see chich JEP the contact uses.  If possible, we'll use
-     JEP-85, if not we'll look for JEP-22 support. */
-  events = buddy_resource_getevents(sl_buddy->data, rname);
-
-  jep85 = buddy_resource_jep85(sl_buddy->data, rname);
-  if (jep85) {
-    state_ns = xml_get_xmlns(xmldata, NS_CHATSTATES);
-    if (state_ns)
-      which_jep = JEP_85;
-  }
-
-  if (which_jep != JEP_85) { /* Fall back to JEP-0022 */
-    jep22 = buddy_resource_jep22(sl_buddy->data, rname);
-    if (jep22) {
-      state_ns = xml_get_xmlns(xmldata, NS_EVENT);
-      if (state_ns)
-        which_jep = JEP_22;
-    }
-  }
-
-  if (!which_jep) { /* Sender does not use chat states */
-    return;
-  }
-
-  body = xmlnode_get_tag_data(xmldata, "body");
-
-  if (which_jep == JEP_85) { /* JEP-0085 */
-    const char *p;
-    jep85->support = CHATSTATES_SUPPORT_OK;
-
-    p = xmlnode_get_name(state_ns);
-    if (!strcmp(p, "composing")) {
-      jep85->last_state_rcvd = ROSTER_EVENT_COMPOSING;
-    } else if (!strcmp(p, "active")) {
-      jep85->last_state_rcvd = ROSTER_EVENT_ACTIVE;
-    } else if (!strcmp(p, "paused")) {
-      jep85->last_state_rcvd = ROSTER_EVENT_PAUSED;
-    } else if (!strcmp(p, "inactive")) {
-      jep85->last_state_rcvd = ROSTER_EVENT_INACTIVE;
-    } else if (!strcmp(p, "gone")) {
-      jep85->last_state_rcvd = ROSTER_EVENT_GONE;
-    }
-    events = jep85->last_state_rcvd;
-  } else {              /* JEP-0022 */
-#ifdef JEP0022
-    const char *msgid;
-    jep22->support = CHATSTATES_SUPPORT_OK;
-    jep22->last_state_rcvd = ROSTER_EVENT_NONE;
-
-    msgid = xmlnode_get_attrib(xmldata, "id");
-
-    if (xmlnode_get_tag(state_ns, "composing")) {
-      // Clear composing if the message contains a body
-      if (body)
-        events &= ~ROSTER_EVENT_COMPOSING;
-      else
-        events |= ROSTER_EVENT_COMPOSING;
-      jep22->last_state_rcvd |= ROSTER_EVENT_COMPOSING;
-
-    } else {
-      events &= ~ROSTER_EVENT_COMPOSING;
-    }
-
-    // Cache the message id
-    g_free(jep22->last_msgid_rcvd);
-    if (msgid)
-      jep22->last_msgid_rcvd = g_strdup(msgid);
-    else
-      jep22->last_msgid_rcvd = NULL;
-
-    if (xmlnode_get_tag(state_ns, "delivered")) {
-      jep22->last_state_rcvd |= ROSTER_EVENT_DELIVERED;
-
-      // Do we have to send back an ACK?
-      if (body)
-        jb_send_jep22_event(from, ROSTER_EVENT_DELIVERED);
-    }
-#endif
-  }
-
-  buddy_resource_setevents(sl_buddy->data, rname, events);
-
-  update_roster = TRUE;
-#endif
-}
-
-static int evscallback_subscription(eviqs *evp, guint evcontext)
-{
-  char *barejid;
-  char *buf;
-
-  if (evcontext == EVS_CONTEXT_TIMEOUT) {
-    scr_LogPrint(LPRINT_LOGNORM, "Event %s timed out, cancelled.",
-                 evp->id);
-    return 0;
-  }
-  if (evcontext == EVS_CONTEXT_CANCEL) {
-    scr_LogPrint(LPRINT_LOGNORM, "Event %s cancelled.", evp->id);
-    return 0;
-  }
-  if (!(evcontext & EVS_CONTEXT_USER))
-    return 0;
-
-  // Sanity check
-  if (!evp->data) {
-    // Shouldn't happen, data should be set to the barejid.
-    scr_LogPrint(LPRINT_LOGNORM, "Error in evs callback.");
-    return 0;
-  }
-
-  // Ok, let's work now.
-  // evcontext: 0, 1 == reject, accept
-
-  barejid = evp->data;
-
-  if (evcontext & ~EVS_CONTEXT_USER) {
-    // Accept subscription request
-    jb_subscr_send_auth(barejid);
-    buf = g_strdup_printf("<%s> is allowed to receive your presence updates",
-                          barejid);
-  } else {
-    // Reject subscription request
-    jb_subscr_cancel_auth(barejid);
-    buf = g_strdup_printf("<%s> won't receive your presence updates", barejid);
-    if (settings_opt_get_int("delete_on_reject")) {
-      // Remove the buddy from the roster if there is no current subscription
-      if (roster_getsubscription(barejid) == sub_none)
-        jb_delbuddy(barejid);
-    }
-  }
-  scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_INFO, 0);
-  scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
-  g_free(buf);
-  return 0;
-}
-
-static void decline_invitation(event_muc_invitation *invitation, char *reason)
-{
-  // cut and paste from jb_room_invite
-  xmlnode x,y,z;
-
-  if (!invitation) return;
-  if (!invitation->to || !invitation->from) return;
-
-  x = jutil_msgnew(NULL, (char*)invitation->to, NULL, NULL);
-
-  y = xmlnode_insert_tag(x, "x");
-  xmlnode_put_attrib(y, "xmlns", "http://jabber.org/protocol/muc#user");
-
-  z = xmlnode_insert_tag(y, "decline");
-  xmlnode_put_attrib(z, "to", invitation->from);
-
-  if (reason) {
-    y = xmlnode_insert_tag(z, "reason");
-    xmlnode_insert_cdata(y, reason, (unsigned) -1);
-  }
-
-  jab_send(jc, x);
-  xmlnode_free(x);
-  jb_reset_keepalive();
-}
-
-static int evscallback_invitation(eviqs *evp, guint evcontext)
-{
-  event_muc_invitation *invitation = evp->data;
-
-  // Sanity check
-  if (!invitation) {
-    // Shouldn't happen.
-    scr_LogPrint(LPRINT_LOGNORM, "Error in evs callback.");
-    return 0;
-  }
-
-  if (evcontext == EVS_CONTEXT_TIMEOUT) {
-    scr_LogPrint(LPRINT_LOGNORM, "Event %s timed out, cancelled.", evp->id);
-    goto evscallback_invitation_free;
-  }
-  if (evcontext == EVS_CONTEXT_CANCEL) {
-    scr_LogPrint(LPRINT_LOGNORM, "Event %s cancelled.", evp->id);
-    goto evscallback_invitation_free;
-  }
-  if (!(evcontext & EVS_CONTEXT_USER))
-    goto evscallback_invitation_free;
-  // Ok, let's work now.
-  // evcontext: 0, 1 == reject, accept
-
-  if (evcontext & ~EVS_CONTEXT_USER) {
-    char *nickname = default_muc_nickname(invitation->to);
-    jb_room_join(invitation->to, nickname, invitation->passwd);
-    g_free(nickname);
-  } else {
-    scr_LogPrint(LPRINT_LOGNORM, "Invitation to %s refused.", invitation->to);
-    decline_invitation(invitation, NULL);
-  }
-
-evscallback_invitation_free:
-  g_free(invitation->to);
-  g_free(invitation->from);
-  g_free(invitation->passwd);
-  g_free(invitation->reason);
-  g_free(invitation);
-  evp->data = NULL;
-  return 0;
-}
-
-static void handle_packet_s10n(jconn conn, char *type, char *from,
-                               xmlnode xmldata)
-{
-  char *r;
-  char *buf;
-  int newbuddy;
-
-  r = jidtodisp(from);
-
-  newbuddy = !roster_find(r, jidsearch, 0);
-
-  if (!strcmp(type, "subscribe")) {
-    /* The sender wishes to subscribe to our presence */
-    char *msg;
-    int isagent;
-    eviqs *evn;
-
-    isagent = (roster_gettype(r) & ROSTER_TYPE_AGENT) != 0;
-    msg = xmlnode_get_tag_data(xmldata, "status");
-
-    buf = g_strdup_printf("<%s> wants to subscribe to your presence updates",
-                          from);
-    scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0);
-    scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
-    g_free(buf);
-
-    if (msg) {
-      buf = g_strdup_printf("<%s> said: %s", from, msg);
-      scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0);
-      replace_nl_with_dots(buf);
-      scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
-      g_free(buf);
-    }
-
-    // Create a new event item
-    evn = evs_new(EVS_TYPE_SUBSCRIPTION, EVS_MAX_TIMEOUT);
-    if (evn) {
-      evn->callback = &evscallback_subscription;
-      evn->data = g_strdup(r);
-      evn->desc = g_strdup_printf("<%s> wants to subscribe to your "
-                                  "presence updates", r);
-      buf = g_strdup_printf("Please use /event %s accept|reject", evn->id);
-    } else {
-      buf = g_strdup_printf("Unable to create a new event!");
-    }
-    scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0);
-    scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
-    g_free(buf);
-  } else if (!strcmp(type, "unsubscribe")) {
-    /* The sender is unsubscribing from our presence */
-    jb_subscr_cancel_auth(from);
-    buf = g_strdup_printf("<%s> is unsubscribing from your "
-                          "presence updates", from);
-    scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0);
-    scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
-    g_free(buf);
-  } else if (!strcmp(type, "subscribed")) {
-    /* The sender has allowed us to receive their presence */
-    buf = g_strdup_printf("<%s> has allowed you to receive their "
-                          "presence updates", from);
-    scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0);
-    scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
-    g_free(buf);
-  } else if (!strcmp(type, "unsubscribed")) {
-    /* The subscription request has been denied or a previously-granted
-       subscription has been cancelled */
-    roster_unsubscribed(from);
-    update_roster = TRUE;
-    buf = g_strdup_printf("<%s> has cancelled your subscription to "
-                          "their presence updates", from);
-    scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0);
-    scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
-    g_free(buf);
-  } else {
-    scr_LogPrint(LPRINT_LOGNORM, "Received unrecognized packet from <%s>, "
-                 "type=%s", from, (type ? type : ""));
-    newbuddy = FALSE;
-  }
-
-  if (newbuddy)
-    update_roster = TRUE;
-  g_free(r);
-}
-
-static void packethandler(jconn conn, jpacket packet)
-{
-  char *p;
-  char *from=NULL, *type=NULL;
-
-  jb_reset_keepalive(); // reset keepalive timeout
-  jpacket_reset(packet);
-
-  if (!packet->type) {
-    scr_LogPrint(LPRINT_LOG, "Packet type = 0");
-    return;
-  }
-
-  p = xmlnode_get_attrib(packet->x, "type");
-  if (p) type = p;
-
-  p = xmlnode_get_attrib(packet->x, "from");
-  if (p) from = p;
-
-  if (!from && packet->type != JPACKET_IQ) {
-    scr_LogPrint(LPRINT_LOGNORM, "Error in stream packet");
-    return;
-  }
-
-  switch (packet->type) {
-    case JPACKET_MESSAGE:
-        handle_packet_message(conn, type, from, packet->x);
-        break;
-
-    case JPACKET_IQ:
-        handle_packet_iq(conn, type, from, packet->x);
-        break;
-
-    case JPACKET_PRESENCE:
-        handle_packet_presence(conn, type, from, packet->x);
-        break;
-
-    case JPACKET_S10N:
-        handle_packet_s10n(conn, type, from, packet->x);
-        break;
-
-    default:
-        scr_LogPrint(LPRINT_LOG, "Unhandled packet type (%d)", packet->type);
-  }
-}
-
-/* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */
--- a/mcabber/src/jabglue.h	Thu Oct 08 19:40:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-#ifndef __JABGLUE_H__
-#define __JABGLUE_H__ 1
-
-#include <glib.h>
-
-#include "roster.h"
-#include "../libjabber/jabber.h"
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if ! HAVE_DECL_STRPTIME
- extern char *strptime ();
-#endif
-
-extern jconn jc;
-extern guint AutoConnection;
-
-extern char imstatus2char[];
-// Status chars: '_', 'o', 'i', 'f', 'd', 'n', 'a'
-
-enum agtype {
-  unknown,
-  groupchat,
-  transport,
-  search
-};
-
-enum iqreq_type {
-  iqreq_none,
-  iqreq_version,
-  iqreq_time,
-  iqreq_last,
-  iqreq_vcard
-};
-
-struct annotation {
-  time_t cdate;
-  time_t mdate;
-  gchar *jid;
-  gchar *text;
-};
-
-struct bookmark {
-  gchar *roomjid;
-  gchar *name;
-  gchar *nick;
-  guint autojoin;
-  /* enum room_printstatus pstatus; */
-  /* enum room_autowhois awhois; */
-};
-
-char *jidtodisp(const char *fjid);
-char *compose_jid(const char *username, const char *servername,
-                  const char *resource);
-jconn jb_connect(const char *fjid, const char *server, unsigned int port,
-                 int ssl, const char *pass);
-unsigned char jb_getonline(void);
-void jb_disconnect(void);
-void jb_main(void);
-void jb_subscr_send_auth(const char *bjid);
-void jb_subscr_cancel_auth(const char *bjid);
-void jb_subscr_request_auth(const char *bjid);
-void jb_subscr_request_cancel(const char *bjid);
-void jb_addbuddy(const char *bjid, const char *name, const char *group);
-void jb_delbuddy(const char *bjid);
-void jb_updatebuddy(const char *bjid, const char *name, const char *group);
-enum imstatus jb_getstatus(void);
-const char *jb_getstatusmsg(void);
-void jb_setstatus(enum imstatus st, const char *recipient, const char *msg,
-                  int do_not_sign);
-void jb_setprevstatus(void);
-void jb_send_msg(const char *fjid, const char *text, int type,
-                 const char *subject, const char *id, gint *encrypted,
-                 const char *type_overwrite);
-void jb_send_raw(const char *str);
-void jb_send_chatstate(gpointer buddy, guint chatstate);
-void jb_keepalive(void);
-void jb_reset_keepalive(void);
-void jb_set_keepalive_delay(unsigned int delay);
-void jb_room_join(const char *room, const char *nickname, const char *passwd);
-void jb_room_unlock(const char *room);
-void jb_room_destroy(const char *room, const char *venue, const char *reason);
-void jb_room_invite(const char *room, const char *fjid, const char *reason);
-int  jb_room_setattrib(const char *roomid, const char *fjid, const char *nick,
-                       struct role_affil ra, const char *reason);
-void jb_iqs_display_list(void);
-void jb_request(const char *fjid, enum iqreq_type reqtype);
-guint jb_is_bookmarked(const char *bjid);
-const char *jb_get_bookmark_nick(const char *bjid);
-GSList *jb_get_all_storage_bookmarks(void);
-void jb_set_storage_bookmark(const char *roomid, const char *name,
-                             const char *nick, const char *passwd,
-                             int autojoin, enum room_printstatus pstatus,
-                             enum room_autowhois awhois);
-struct annotation *jb_get_storage_rosternotes(const char *barejid, int silent);
-GSList *jb_get_all_storage_rosternotes(void);
-void jb_set_storage_rosternotes(const char *barejid, const char *note);
-
-#endif /* __JABGLUE_H__ */
-
-/* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */
--- a/mcabber/src/main.c	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/main.c	Sun Oct 11 15:38:32 2009 +0200
@@ -31,7 +31,6 @@
 #include <glib.h>
 #include <config.h>
 
-#include "jabglue.h"
 #include "screen.h"
 #include "settings.h"
 #include "roster.h"
@@ -42,6 +41,7 @@
 #include "pgp.h"
 #include "otr.h"
 #include "fifo.h"
+#include "xmpp.h"
 
 #ifdef ENABLE_HGCSET
 # include "hgcset.h"
@@ -52,6 +52,7 @@
 #endif
 
 static unsigned int terminate_ui;
+GMainLoop *main_loop = NULL;
 
 static struct termios *backup_termios;
 
@@ -66,135 +67,10 @@
   return ver;
 }
 
-void mcabber_connect(void)
-{
-  const char *username, *password, *resource, *servername;
-  const char *proxy_host;
-  const char *resource_prefix = PACKAGE_NAME;
-  char *dynresource = NULL;
-  char *fjid;
-  int ssl;
-  int sslverify = -1;
-  const char *sslvopt = NULL, *cafile = NULL, *capath = NULL, *ciphers = NULL;
-  static char *cafile_xp, *capath_xp;
-  unsigned int port;
-
-  servername = settings_opt_get("server");
-  username   = settings_opt_get("username");
-  password   = settings_opt_get("password");
-  resource   = settings_opt_get("resource");
-  proxy_host = settings_opt_get("proxy_host");
-
-  // Free the ca*_xp strings if they've already been set.
-  g_free(cafile_xp);
-  g_free(capath_xp);
-  cafile_xp = capath_xp = NULL;
-
-  if (!servername) {
-    scr_LogPrint(LPRINT_NORMAL, "Server name has not been specified!");
-    return;
-  }
-  if (!username) {
-    scr_LogPrint(LPRINT_NORMAL, "User name has not been specified!");
-    return;
-  }
-  if (!password) {
-    scr_LogPrint(LPRINT_NORMAL, "Password has not been specified!");
-    return;
-  }
-
-  port    = (unsigned int) settings_opt_get_int("port");
-
-  ssl     = settings_opt_get_int("ssl");
-  sslvopt = settings_opt_get("ssl_verify");
-  if (sslvopt)
-    sslverify = settings_opt_get_int("ssl_verify");
-  cafile  = settings_opt_get("ssl_cafile");
-  capath  = settings_opt_get("ssl_capath");
-  ciphers = settings_opt_get("ssl_ciphers");
-
-#if !defined(HAVE_OPENSSL) && !defined(HAVE_GNUTLS)
-  if (ssl) {
-    scr_LogPrint(LPRINT_LOGNORM, "** Error: SSL is NOT available, "
-                 "do not set the option 'ssl'.");
-    return;
-  } else if (sslvopt || cafile || capath || ciphers) {
-    scr_LogPrint(LPRINT_LOGNORM, "** Warning: SSL is NOT available, "
-                 "ignoring ssl-related settings");
-    ssl = sslverify = 0;
-    cafile = capath = ciphers = NULL;
-  }
-#elif defined HAVE_GNUTLS
-  if (ssl && sslverify != 0) {
-    scr_LogPrint(LPRINT_LOGNORM, "** Error: SSL certificate checking "
-                 "is not supported yet with GnuTLS.");
-    scr_LogPrint(LPRINT_LOGNORM,
-                 " * Please set 'ssl_verify' to 0 explicitly!");
-    return;
-  }
-#endif
-  cafile_xp = expand_filename(cafile);
-  capath_xp = expand_filename(capath);
-  cw_set_ssl_options(sslverify, cafile_xp, capath_xp, ciphers, servername);
-  // We can't free the ca*_xp variables now, because they're not duplicated
-  // in cw_set_ssl_options().
-
-  if (!resource)
-    resource = resource_prefix;
-
-  if (!settings_opt_get("disable_random_resource")) {
-#if HAVE_ARC4RANDOM
-    dynresource = g_strdup_printf("%s.%08x", resource, arc4random());
-#else
-    unsigned int tab[2];
-    srand(time(NULL));
-    tab[0] = (unsigned int) (0xffff * (rand() / (RAND_MAX + 1.0)));
-    tab[1] = (unsigned int) (0xffff * (rand() / (RAND_MAX + 1.0)));
-    dynresource = g_strdup_printf("%s.%04x%04x", resource, tab[0], tab[1]);
-#endif
-    resource = dynresource;
-  }
-
-  /* Connect to server */
-  scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, "Connecting to server: %s",
-               servername);
-  if (port)
-    scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, " using port %d", port);
-  scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, " resource %s", resource);
-
-  if (proxy_host) {
-    int proxy_port = settings_opt_get_int("proxy_port");
-    if (proxy_port <= 0 || proxy_port > 65535) {
-      scr_LogPrint(LPRINT_LOGNORM, "Invalid proxy port: %d", proxy_port);
-    } else {
-      const char *proxy_user, *proxy_pass;
-      proxy_user = settings_opt_get("proxy_user");
-      proxy_pass = settings_opt_get("proxy_pass");
-      // Proxy initialization
-      cw_setproxy(proxy_host, proxy_port, proxy_user, proxy_pass);
-      scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, " using proxy %s:%d",
-                   proxy_host, proxy_port);
-    }
-  }
-
-  fjid = compose_jid(username, servername, resource);
-#if defined(HAVE_LIBOTR)
-  otr_init(fjid);
-#endif
-  jc = jb_connect(fjid, servername, port, ssl, password);
-  g_free(fjid);
-  g_free(dynresource);
-
-  if (!jc)
-    scr_LogPrint(LPRINT_LOGNORM, "Error connecting to (%s)", servername);
-
-  jb_reset_keepalive();
-}
-
 static void mcabber_terminate(const char *msg)
 {
   fifo_deinit();
-  jb_disconnect();
+  xmpp_disconnect();
   scr_TerminateCurses();
 
   // Restore term settings, if needed.
@@ -259,7 +135,7 @@
 
   /* Read the password. */
   printf("Please enter %s: ", what);
-  fgets(password, passsize, stdin);
+  if (fgets(password, passsize, stdin) == NULL) return NULL;
 
   /* Restore terminal. */
   tcsetattr(fileno(stdin), TCSAFLUSH, &orig);
@@ -289,11 +165,6 @@
 #ifdef HAVE_UNICODE
   puts("Compiled with unicode support.");
 #endif
-#ifdef HAVE_OPENSSL
-  puts("Compiled with OpenSSL support.");
-#elif defined HAVE_GNUTLS
-  puts("Compiled with GnuTLS support.");
-#endif
 #ifdef HAVE_GPGME
   puts("Compiled with GPG support.");
 #endif
@@ -376,14 +247,36 @@
   terminate_ui = TRUE;
 }
 
+gboolean mcabber_loop()
+{
+  keycode kcode;
+
+  if (terminate_ui) {
+    g_main_loop_quit(main_loop);
+    return FALSE;
+  }
+  scr_DoUpdate();
+  scr_Getch(&kcode);
+
+  if (kcode.value != ERR) {
+    process_key(kcode);
+  } else {
+    scr_CheckAutoAway(FALSE);
+
+    if (update_roster)
+      scr_DrawRoster();
+
+    hk_mainloop();
+  }
+  return TRUE;
+}
+
 int main(int argc, char **argv)
 {
   char *configFile = NULL;
   const char *optstring;
   int optval, optval2;
-  unsigned int ping;
   int ret;
-  keycode kcode;
 
   credits();
 
@@ -484,12 +377,6 @@
   if (optstring)
     hk_ext_cmd_init(optstring);
 
-  ping = 40;
-  if (settings_opt_get("pinginterval"))
-    ping = (unsigned int) settings_opt_get_int("pinginterval");
-  jb_set_keepalive_delay(ping);
-  scr_LogPrint(LPRINT_DEBUG, "Ping interval established: %d secs", ping);
-
   if (settings_opt_get_int("hide_offline_buddies") > 0) { // XXX Deprecated
     scr_RosterDisplay("ofdna");
     scr_LogPrint(LPRINT_LOGNORM,
@@ -511,39 +398,27 @@
   /* Load previous roster state */
   hlog_load_state();
 
+  main_loop = g_main_loop_new(NULL, TRUE);
+
   if (ret < 0) {
     scr_LogPrint(LPRINT_NORMAL, "No configuration file has been found.");
     scr_ShowBuddyWindow();
   } else {
     /* Connection */
-    mcabber_connect();
+    xmpp_connect();
   }
 
   scr_LogPrint(LPRINT_DEBUG, "Entering into main loop...");
 
-  while (!terminate_ui) {
-    scr_DoUpdate();
-    scr_Getch(&kcode);
-
-    if (kcode.value != ERR) {
-      process_key(kcode);
-    } else {
-      scr_CheckAutoAway(FALSE);
-
-      if (update_roster)
-        scr_DrawRoster();
-
-      jb_main();
-      hk_mainloop();
-    }
-  }
+  g_timeout_add(10, mcabber_loop, NULL);
+  g_main_loop_run(main_loop);
 
   scr_TerminateCurses();
   fifo_deinit();
 #ifdef HAVE_LIBOTR
   otr_terminate();
 #endif
-  jb_disconnect();
+  xmpp_disconnect();
 #ifdef HAVE_GPGME
   gpg_terminate();
 #endif
--- a/mcabber/src/otr.c	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/otr.c	Sun Oct 11 15:38:32 2009 +0200
@@ -24,22 +24,22 @@
 
 #ifdef HAVE_LIBOTR
 
-#include "otr.h"
+#include "hbuf.h"
 #include "logprint.h"
-#include "hbuf.h"
-#include "jab_priv.h"
+#include "nohtml.h"
+#include "otr.h"
 #include "roster.h"
-#include "utils.h"
 #include "screen.h"
 #include "settings.h"
-#include "nohtml.h"
+#include "utils.h"
+#include "xmpp.h"
 
 #define OTR_PROTOCOL_NAME "jabber"
 
 static OtrlUserState userstate = NULL;
-static char * account = NULL;
-static char * keyfile = NULL;
-static char * fprfile = NULL;
+static char *account = NULL;
+static char *keyfile = NULL;
+static char *fprfile = NULL;
 
 static int otr_is_enabled = FALSE;
 
@@ -109,11 +109,11 @@
 };
 
 static void otr_message_disconnect(ConnContext *ctx);
-static ConnContext * otr_get_context(const char *buddy);
-static void otr_startstop(const char * buddy, int start);
-static void otr_handle_smp_tlvs(OtrlTLV * tlvs, ConnContext * ctx);
+static ConnContext *otr_get_context(const char *buddy);
+static void otr_startstop(const char *buddy, int start);
+static void otr_handle_smp_tlvs(OtrlTLV *tlvs, ConnContext *ctx);
 
-static char * otr_get_dir(void);
+static char *otr_get_dir(void);
 
 void otr_init(const char *fjid)
 {
@@ -149,7 +149,7 @@
 
 void otr_terminate(void)
 {
-  ConnContext * ctx;
+  ConnContext *ctx;
 
   if (!otr_is_enabled)
     return;
@@ -167,7 +167,7 @@
    * This is reported to be a bug in libgcrypt :-/
    * Mikael
    */
-#if defined(HAVE_GNUTLS) && !defined(HAVE_OPENSSL)
+#if defined(HAVE_GNUTLS) && !defined(HAVE_OPENSSL) //TODO: broken now
   if (!settings_opt_get_int("ssl"))
 #endif
   otrl_userstate_free(userstate);
@@ -177,7 +177,7 @@
   keyfile = NULL;
 }
 
-static char * otr_get_dir(void)
+static char *otr_get_dir(void)
 {
   const char *configured_dir = settings_opt_get("otr_dir");
 
@@ -198,11 +198,11 @@
   }
 }
 
-static ConnContext * otr_get_context(const char *buddy)
+static ConnContext *otr_get_context(const char *buddy)
 {
   int null = 0;
-  ConnContext * ctx;
-  char * lowcasebuddy = g_strdup(buddy);
+  ConnContext *ctx;
+  char *lowcasebuddy = g_strdup(buddy);
 
   mc_strtolower(lowcasebuddy);
   ctx = otrl_context_find(userstate, lowcasebuddy, account, OTR_PROTOCOL_NAME,
@@ -219,9 +219,9 @@
                           ctx->protocol, ctx->username);
 }
 
-static void otr_startstop(const char * buddy, int start)
+static void otr_startstop(const char *buddy, int start)
 {
-  char * msg = NULL;
+  char *msg = NULL;
   ConnContext *ctx = otr_get_context(buddy);
 
   if (!userstate || !ctx)
@@ -251,12 +251,12 @@
   otr_startstop(buddy, 1);
 }
 
-void otr_disconnect(const char * buddy)
+void otr_disconnect(const char *buddy)
 {
   otr_startstop(buddy, 0);
 }
 
-void otr_fingerprint(const char * buddy, const char * trust)
+void otr_fingerprint(const char *buddy, const char *trust)
 {
   char fpr[45], *tr;
   ConnContext *ctx = otr_get_context(buddy);
@@ -283,7 +283,7 @@
   cb_write_fingerprints(NULL);
 }
 
-static void otr_handle_smp_tlvs(OtrlTLV * tlvs, ConnContext * ctx)
+static void otr_handle_smp_tlvs(OtrlTLV *tlvs, ConnContext *ctx)
 {
   OtrlTLV *tlv = NULL;
   char *sbuf = NULL;
@@ -358,13 +358,13 @@
  * returns whether a otr_message was received
  * sets *otr_data to NULL, when it was an internal otr message
  */
-int otr_receive(char **otr_data, const char * buddy, int * free_msg)
+int otr_receive(char **otr_data, const char *buddy, int *free_msg)
 {
   int ignore_message;
   char *newmessage = NULL;
   OtrlTLV *tlvs = NULL;
   OtrlTLV *tlv = NULL;
-  ConnContext * ctx;
+  ConnContext *ctx;
 
   ctx = otr_get_context(buddy);
   *free_msg = 0;
@@ -406,7 +406,7 @@
   gcry_error_t err;
   char *newmessage = NULL;
   char *htmlmsg;
-  ConnContext * ctx = otr_get_context(buddy);
+  ConnContext *ctx = otr_get_context(buddy);
 
   if (ctx->msgstate == OTRL_MSGSTATE_PLAINTEXT)
     err = otrl_message_sending(userstate, &ops, NULL, ctx->accountname,
@@ -434,10 +434,10 @@
 }
 
 /* Prints OTR connection state */
-void otr_print_info(const char * buddy)
+void otr_print_info(const char *buddy)
 {
   const char *state, *auth, *policy;
-  ConnContext * ctx = otr_get_context(buddy);
+  ConnContext *ctx = otr_get_context(buddy);
   OtrlPolicy p = cb_policy(ctx->app_data, ctx);
 
   if (!userstate || !ctx)
@@ -491,9 +491,9 @@
                ctx->username, state, auth, policy);
 }
 
-static ConnContext * otr_context_encrypted(const char * buddy)
+static ConnContext *otr_context_encrypted(const char *buddy)
 {
-  ConnContext * ctx = otr_get_context(buddy);
+  ConnContext *ctx = otr_get_context(buddy);
 
   if (!userstate || !ctx  || ctx->msgstate != OTRL_MSGSTATE_ENCRYPTED){
     scr_LogPrint(LPRINT_LOGNORM,
@@ -505,9 +505,9 @@
   return ctx;
 }
 
-void otr_smp_query(const char * buddy, const char * secret)
+void otr_smp_query(const char *buddy, const char *secret)
 {
-  ConnContext * ctx = otr_context_encrypted(buddy);
+  ConnContext *ctx = otr_context_encrypted(buddy);
 
   if (!secret) {
     scr_LogPrint(LPRINT_LOGNORM,
@@ -525,9 +525,9 @@
   }
 }
 
-void otr_smp_respond(const char * buddy, const char * secret)
+void otr_smp_respond(const char *buddy, const char *secret)
 {
-  ConnContext * ctx = otr_context_encrypted(buddy);
+  ConnContext *ctx = otr_context_encrypted(buddy);
 
   if (!secret) {
     scr_LogPrint(LPRINT_LOGNORM,
@@ -551,9 +551,9 @@
   }
 }
 
-void otr_smp_abort(const char * buddy)
+void otr_smp_abort(const char *buddy)
 {
-  ConnContext * ctx = otr_context_encrypted(buddy);
+  ConnContext *ctx = otr_context_encrypted(buddy);
 
   if (ctx) {
     otrl_message_abort_smp(userstate, &ops, NULL, ctx);
@@ -565,7 +565,7 @@
 
 void otr_key(void)
 {
-  OtrlPrivKey * key;
+  OtrlPrivKey *key;
   char readable[45] = "";
 
   if(!userstate)
@@ -606,7 +606,7 @@
                               const char *protocol)
 {
   gcry_error_t e;
-  char * root;
+  char *root;
 
   scr_LogPrint(LPRINT_LOGNORM,
                "Generating new OTR key for %s. This may take a while...",
@@ -643,10 +643,9 @@
                               const char *protocol, const char *recipient,
                               const char *message)
 {
-  char * id = g_strdup("otrinject");
   if (roster_gettype(recipient) == ROSTER_TYPE_USER)
-    jb_send_msg(recipient, message, ROSTER_TYPE_USER, "", id, NULL, NULL);
-  g_free(id);
+    xmpp_send_msg(recipient, message, ROSTER_TYPE_USER, "", TRUE, NULL,
+                  LM_MESSAGE_SUB_TYPE_NOT_SET);
 }
 
 /* Display a notification message for a particular
@@ -656,7 +655,7 @@
                       const char *username, const char *title,
                       const char *primary, const char *secondary)
 {
-  char * type;
+  char *type;
   char *sbuf = NULL;
   switch (level) {
     case OTRL_NOTIFY_ERROR:   type = "error";   break;
--- a/mcabber/src/pgp.c	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/pgp.c	Sun Oct 11 15:38:32 2009 +0200
@@ -150,6 +150,9 @@
   return g_strndup(p, q-p);
 }
 
+// GCC ignores casts to void, thus we need to hack around that
+static inline void ignore(void*x) {}
+
 //  passphrase_cb()
 // GPGME passphrase callback function.
 static gpgme_error_t passphrase_cb(void *hook, const char *uid_hint,
@@ -159,7 +162,8 @@
 
   // Abort if we do not have the password.
   if (!gpg.passphrase) {
-    write(fd, "\n", 1);
+    ignore((void*)write(fd, "\n", 1)); // We have an error anyway, thus it does
+                                       // not matter if we fail again.
     return gpg_error(GPG_ERR_CANCELED);
   }
 
--- a/mcabber/src/screen.c	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/screen.c	Sun Oct 11 15:38:32 2009 +0200
@@ -58,6 +58,7 @@
 #include "histolog.h"
 #include "settings.h"
 #include "utils.h"
+#include "xmpp.h"
 
 #define get_color(col)  (COLOR_PAIR(col)|COLOR_ATTRIB[col])
 #define compose_color(col)  (COLOR_PAIR(col->color_pair)|col->color_attrib)
@@ -138,6 +139,7 @@
 static int    chatstate; /* (0=active, 1=composing, 2=paused) */
 static bool   lock_chatstate;
 static time_t chatstate_timestamp;
+static guint  chatstate_timeout_id = 0;
 int chatstates_disabled;
 
 #define MAX_KEYSEQ_LENGTH 8
@@ -159,9 +161,9 @@
                        unsigned int prefix_flags, int force_show,
                        unsigned mucnicklen);
 
-inline void scr_WriteMessage(const char *bjid, const char *text,
-                             time_t timestamp, guint prefix_flags,
-                             unsigned mucnicklen);
+void scr_WriteMessage(const char *bjid, const char *text,
+                      time_t timestamp, guint prefix_flags,
+                      unsigned mucnicklen, gpointer xep184);
 inline void scr_UpdateBuddyWindow(void);
 inline void scr_set_chatmode(int enable);
 
@@ -184,7 +186,7 @@
 
 typedef struct {
   char *status, *wildcard;
-  ccolor * color;
+  ccolor *color;
   GPatternSpec *compiled;
 } rostercolor;
 
@@ -194,7 +196,7 @@
 
 typedef struct {
   bool manual; // Manually set?
-  ccolor * color;
+  ccolor *color;
 } nickcolor;
 
 static int nickcolcount = 0;
@@ -235,11 +237,11 @@
   return -1;
 }
 
-static ccolor * get_user_color(const char *color)
+static ccolor *get_user_color(const char *color)
 {
   bool isbright = FALSE;
   int cl;
-  ccolor * ccol;
+  ccolor *ccol;
   if (!strncmp(color, "bright", 6)) {
     isbright = TRUE;
     color += 6;
@@ -317,7 +319,7 @@
     g_free(mnick);
     need_update = TRUE;
   } else {
-    ccolor * cl = get_user_color(color);
+    ccolor *cl = get_user_color(color);
     if (!cl) {
       scr_LogPrint(LPRINT_NORMAL, "No such color name");
       g_free(snick);
@@ -389,7 +391,7 @@
       return FALSE;
     }
   } else {
-    ccolor * cl = get_user_color(color);
+    ccolor *cl = get_user_color(color);
     if (!cl) {
       scr_LogPrint(LPRINT_NORMAL, "No such color name");
       return FALSE;
@@ -520,7 +522,7 @@
           ncolors++;
         } else {
           char *end = ncolors;
-          ccolor * cl;
+          ccolor *cl;
           while (*end && (*end != ' ') && (*end != '\t'))
             end++;
           *end = '\0';
@@ -1381,7 +1383,7 @@
 // Redraw the main (bottom) status line.
 void scr_UpdateMainStatus(int forceupdate)
 {
-  char *sm = from_utf8(jb_getstatusmsg());
+  char *sm = from_utf8(xmpp_getstatusmsg());
   const char *info = settings_opt_get("info");
 
   werase(mainstatusWnd);
@@ -1389,13 +1391,13 @@
     char *info_locale = from_utf8(info);
     mvwprintw(mainstatusWnd, 0, 0, "%c[%c] %s: %s",
               (unread_msg(NULL) ? '#' : ' '),
-              imstatus2char[jb_getstatus()],
+              imstatus2char[xmpp_getstatus()],
               info_locale, (sm ? sm : ""));
     g_free(info_locale);
   } else
     mvwprintw(mainstatusWnd, 0, 0, "%c[%c] %s",
               (unread_msg(NULL) ? '#' : ' '),
-              imstatus2char[jb_getstatus()], (sm ? sm : ""));
+              imstatus2char[xmpp_getstatus()], (sm ? sm : ""));
   if (forceupdate) {
     top_panel(inputPanel);
     update_panels();
@@ -1730,7 +1732,7 @@
       status = 'C';
     else
       status = 'x';
-  } else if (jb_getstatus() != offline) {
+  } else if (xmpp_getstatus() != offline) {
     enum imstatus budstate;
     budstate = buddy_getstatus(BUDDATA(current_buddy), NULL);
     if (budstate < imstatus_size)
@@ -1813,7 +1815,7 @@
   int rOffset;
   int cursor_backup;
   char status, pending;
-  enum imstatus currentstatus = jb_getstatus();
+  enum imstatus currentstatus = xmpp_getstatus();
   int x_pos;
 
   // We can reset update_roster
@@ -1964,7 +1966,7 @@
       name[0] = 0;
 
     if (isgrp) {
-      if (ishid){
+      if (ishid) {
         int group_count = 0;
         foreach_group_member(BUDDATA(buddy), increment_if_buddy_not_filtered,
                              &group_count);
@@ -2102,21 +2104,21 @@
 
   if (setaway) {
     const char *msg, *prevmsg;
-    oldstatus = jb_getstatus();
+    oldstatus = xmpp_getstatus();
     if (oldmsg) {
       g_free(oldmsg);
       oldmsg = NULL;
     }
-    prevmsg = jb_getstatusmsg();
+    prevmsg = xmpp_getstatusmsg();
     msg = settings_opt_get("message_autoaway");
     if (!msg)
       msg = prevmsg;
     if (prevmsg)
       oldmsg = g_strdup(prevmsg);
-    jb_setstatus(away, NULL, msg, FALSE);
+    xmpp_setstatus(away, NULL, msg, FALSE);
   } else {
     // Back
-    jb_setstatus(oldstatus, NULL, (oldmsg ? oldmsg : ""), FALSE);
+    xmpp_setstatus(oldstatus, NULL, (oldmsg ? oldmsg : ""), FALSE);
     if (oldmsg) {
       g_free(oldmsg);
       oldmsg = NULL;
@@ -2124,28 +2126,9 @@
   }
 }
 
-long int scr_GetAutoAwayTimeout(time_t now)
-{
-  enum imstatus cur_st;
-  unsigned int autoaway_timeout = settings_opt_get_int("autoaway");
-
-  if (Autoaway || !autoaway_timeout)
-    return 86400;
-
-  cur_st = jb_getstatus();
-  // Auto-away is disabled for the following states
-  if ((cur_st != available) && (cur_st != freeforchat))
-    return 86400;
-
-  if (now >= LastActivity + (time_t)autoaway_timeout)
-    return 0;
-  else
-    return LastActivity + (time_t)autoaway_timeout - now;
-}
-
 //  set_chatstate(state)
 // Set the current chat state (0=active, 1=composing, 2=paused)
-// If the chat state has changed, call jb_send_chatstate()
+// If the chat state has changed, call xmpp_send_chatstate()
 static inline void set_chatstate(int state)
 {
 #if defined JEP0022 || defined JEP0085
@@ -2158,13 +2141,18 @@
     if (current_buddy &&
         buddy_gettype(BUDDATA(current_buddy)) == ROSTER_TYPE_USER) {
       guint jep_state;
-      if (chatstate == 1)
+      if (chatstate == 1) {
+        if (chatstate_timeout_id == 0)
+          chatstate_timeout_id = g_timeout_add_seconds(1,
+                                                       scr_ChatStatesTimeout,
+                                                       NULL);
         jep_state = ROSTER_EVENT_COMPOSING;
+      }
       else if (chatstate == 2)
         jep_state = ROSTER_EVENT_PAUSED;
       else
         jep_state = ROSTER_EVENT_ACTIVE;
-      jb_send_chatstate(BUDDATA(current_buddy), jep_state);
+      xmpp_send_chatstate(BUDDATA(current_buddy), jep_state);
     }
     if (!chatstate)
       chatstate_timestamp = 0;
@@ -2173,20 +2161,24 @@
 }
 
 #if defined JEP0022 || defined JEP0085
-long int scr_GetChatStatesTimeout(time_t now)
+gboolean scr_ChatStatesTimeout(void)
 {
+  time_t now;
+  time(&now);
   // Check if we're currently composing...
-  if (chatstate != 1 || !chatstate_timestamp)
-    return 86400;
+  if (chatstate != 1 || !chatstate_timestamp) {
+    chatstate_timeout_id = 0;
+    return FALSE;
+  }
 
   // If the timeout is reached, let's change the state right now.
   if (now >= chatstate_timestamp + COMPOSING_TIMEOUT) {
     chatstate_timestamp = now;
     set_chatstate(2);
-    return 86400;
+    chatstate_timeout_id = 0;
+    return FALSE;
   }
-
- return chatstate_timestamp + COMPOSING_TIMEOUT - now;
+  return TRUE;
 }
 #endif
 
@@ -2200,7 +2192,7 @@
   if (!autoaway_timeout) return;
   if (!LastActivity || activity) time(&LastActivity);
 
-  cur_st = jb_getstatus();
+  cur_st = xmpp_getstatus();
   // Auto-away is disabled for the following states
   if ((cur_st != available) && (cur_st != freeforchat))
     return;
--- a/mcabber/src/screen.h	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/screen.h	Sun Oct 11 15:38:32 2009 +0200
@@ -22,6 +22,7 @@
 
 #include "hbuf.h"
 #include "logprint.h"
+#include "roster.h"
 
 #define INPUTLINE_LENGTH  1024
 
@@ -119,11 +120,10 @@
 
 bool Autoaway;
 
-long int scr_GetAutoAwayTimeout(time_t now);
 void scr_CheckAutoAway(int activity);
 
 #if defined JEP0022 || defined JEP0085
-long int scr_GetChatStatesTimeout(time_t now);
+gboolean scr_ChatStatesTimeout();
 #endif
 int chatstates_disabled;
 
--- a/mcabber/src/settings.c	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/settings.c	Sun Oct 11 15:38:32 2009 +0200
@@ -19,15 +19,16 @@
  * USA
  */
 
-#include <strings.h>
+#include <stdio.h>
 #include <stdlib.h>
-#include <ctype.h>
+#include <string.h>
 
 #include "settings.h"
 #include "commands.h"
-#include "utils.h"
 #include "logprint.h"
 #include "otr.h"
+#include "utils.h"
+#include "xmpp.h"
 
 // Maximum line length
 // (probably best to use the same value as INPUTLINE_LENGTH)
@@ -392,7 +393,7 @@
 {
   char *nick;
 
-  nick = (char*)jb_get_bookmark_nick(roomid);
+  nick = (char*)xmpp_get_bookmark_nick(roomid);
   if (nick)
     return g_strdup(nick);
 
@@ -537,7 +538,7 @@
 /* otr settings */
 
 #ifdef HAVE_LIBOTR
-static void remove_default_policies(char * k, char * policy, void * defaultp)
+static void remove_default_policies(char *k, char *policy, void *defaultp)
 {
   if (*(enum otr_policy *)policy == *(enum otr_policy *)defaultp) {
     g_free((enum otr_policy *) policy);
@@ -578,7 +579,7 @@
 guint settings_otr_getpolicy(const char *bjid)
 {
 #ifdef HAVE_LIBOTR
-  enum otr_policy * otrdata;
+  enum otr_policy *otrdata;
   if (!bjid)
     return default_policy;
 
--- a/mcabber/src/settings.h	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/settings.h	Sun Oct 11 15:38:32 2009 +0200
@@ -4,7 +4,7 @@
 #include <ctype.h>
 #include <glib.h>
 
-#include "jabglue.h"
+#include "roster.h"
 
 #ifndef isblank
 # define isblank(c)  ((c) == 0x20 || (c) == 0x09)
--- a/mcabber/src/utils.c	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/utils.c	Sun Oct 11 15:38:32 2009 +0200
@@ -26,6 +26,8 @@
 #include <string.h>
 #include <stdarg.h>
 
+#include <glib/gprintf.h>
+
 /* For Cygwin (thanks go to Yitzchak Scott-Thoennes) */
 #ifdef __CYGWIN__
 #  define timezonevar
@@ -45,6 +47,55 @@
 static int DebugEnabled;
 static char *FName;
 
+//  jidtodisp(jid)
+// Strips the resource part from the jid
+// The caller should g_free the result after use.
+char *jidtodisp(const char *fjid)
+{
+  char *ptr;
+  char *alias;
+
+  alias = g_strdup(fjid);
+
+  if ((ptr = strchr(alias, JID_RESOURCE_SEPARATOR)) != NULL) {
+    *ptr = 0;
+  }
+  return alias;
+}
+
+char *compose_jid(const char *username, const char *servername,
+                  const char *resource)
+{
+  char *fjid;
+
+  if (!strchr(username, JID_DOMAIN_SEPARATOR)) {
+    fjid = g_strdup_printf("%s%c%s%c%s", username,
+                           JID_DOMAIN_SEPARATOR, servername,
+                           JID_RESOURCE_SEPARATOR, resource);
+  } else {
+    fjid = g_strdup_printf("%s%c%s", username,
+                           JID_RESOURCE_SEPARATOR, resource);
+  }
+  return fjid;
+}
+
+gboolean jid_equal(const char *jid1, const char *jid2)
+{
+  char *a,*b;
+  int ret;
+  if (!jid1 && !jid2)
+    return TRUE;
+  if (!jid1 || !jid2)
+    return FALSE;
+
+  a = jidtodisp(jid1);
+  b = jidtodisp(jid2);
+  ret = strcasecmp(a, b);
+  g_free(a);
+  g_free(b);
+  return (ret == 0) ? TRUE : FALSE;
+}
+
 //  expand_filename(filename)
 // Expand "~/" with the $HOME env. variable in a file name.
 // The caller must free the string after use.
@@ -60,6 +111,29 @@
   return g_strdup(fname);
 }
 
+void fingerprint_to_hex(const unsigned char *fpr, char hex[49])
+{
+  int i;
+  char *p;
+
+  for (p = hex, i = 0; i < 15; i++, p+=3)
+    g_sprintf(p, "%02X:", fpr[i]);
+  g_sprintf(p, "%02X", fpr[i]);
+  hex[48] = '\0';
+}
+
+gboolean hex_to_fingerprint(const char *hex, char fpr[16])
+{
+  int i;
+  char *p;
+
+  if (strlen(hex) != 47)
+    return FALSE;
+  for (i = 0, p = (char*)hex; *p && *(p+1); i++, p += 3)
+    fpr[i] = (char) g_ascii_strtoull (p, NULL, 16);
+  return TRUE;
+}
+
 void ut_InitDebug(int level, const char *filename)
 {
   FILE *fp;
--- a/mcabber/src/utils.h	Thu Oct 08 19:40:23 2009 +0200
+++ b/mcabber/src/utils.h	Sun Oct 11 15:38:32 2009 +0200
@@ -14,6 +14,14 @@
 #define JID_DOMAIN_SEPARATOR        '@'
 #define JID_DOMAIN_SEPARATORSTR     "@"
 
+char *jidtodisp(const char *fjid);
+char *compose_jid(const char *username, const char *servername,
+                  const char *resource);
+gboolean jid_equal(const char *jid1, const char *jid2);
+
+void fingerprint_to_hex(const unsigned char *fpr, char hex[49]);
+gboolean hex_to_fingerprint(const char * hex, char fpr[16]);
+
 void ut_InitDebug(int level, const char *file);
 void ut_WriteLog(unsigned int flag, const char *data);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/xmpp.c	Sun Oct 11 15:38:32 2009 +0200
@@ -0,0 +1,2154 @@
+/*
+ * xmpp.c    -- Jabber protocol handling
+ *
+ * Copyright (C) 2008 Frank Zschockelt <mcabber@freakysoft.de>
+ * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
+ * Parts come from the centericq project:
+ * Copyright (C) 2002-2005 by Konstantin Klyagin <konst@konst.org.ua>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <sys/utsname.h>
+
+#include "commands.h"
+#include "events.h"
+#include "histolog.h"
+#include "hooks.h"
+#include "logprint.h"
+#include "otr.h"
+#include "roster.h"
+#include "screen.h"
+#include "settings.h"
+#include "utils.h"
+#include "xmpp.h"
+#include "xmpp_helper.h"
+#include "xmpp_defines.h"
+
+#define RECONNECTION_TIMEOUT    60L
+
+LmConnection* lconnection;
+static guint AutoConnection;
+
+inline void update_last_use(void);
+inline gboolean xmpp_reconnect();
+
+static enum imstatus mystatus = offline;
+static enum imstatus mywantedstatus = available;
+static gchar *mystatusmsg;
+
+char imstatus2char[imstatus_size+1] = {
+    '_', 'o', 'f', 'd', 'n', 'a', 'i', '\0'
+};
+
+static char *imstatus_showmap[] = {
+  "",
+  "",
+  "chat",
+  "dnd",
+  "xa",
+  "away",
+  ""
+};
+
+static LmMessageNode *bookmarks = NULL;
+static LmMessageNode *rosternotes = NULL;
+
+struct xmpp_error {
+  guint code;
+  const char *code_str;
+  const char *meaning;
+  const char *condition;
+  const char *type;
+} xmpp_errors[] = {
+  {XMPP_ERROR_REDIRECT,              "302",
+    "Redirect",              "redirect",                "modify"},
+  {XMPP_ERROR_BAD_REQUEST,           "400",
+    "Bad Request",           "bad-request",             "modify"},
+  {XMPP_ERROR_NOT_AUTHORIZED,        "401",
+    "Not Authorized",        "not-authorized",          "auth"},
+  {XMPP_ERROR_PAYMENT_REQUIRED,      "402",
+    "Payment Required",      "payment-required",        "auth"},
+  {XMPP_ERROR_FORBIDDEN,             "403",
+    "Forbidden",             "forbidden",               "auth"},
+  {XMPP_ERROR_NOT_FOUND,             "404",
+    "Not Found",             "item-not-found",          "cancel"},
+  {XMPP_ERROR_NOT_ALLOWED,           "405",
+    "Not Allowed",           "not-allowed",             "cancel"},
+  {XMPP_ERROR_NOT_ACCEPTABLE,        "406",
+    "Not Acceptable",        "not-acceptable",          "modify"},
+  {XMPP_ERROR_REGISTRATION_REQUIRED, "407",
+    "Registration required", "registration-required",   "auth"},
+  {XMPP_ERROR_REQUEST_TIMEOUT,       "408",
+    "Request Timeout",       "remote-server-timeout",   "wait"},
+  {XMPP_ERROR_CONFLICT,              "409",
+    "Conflict",               "conflict",               "cancel"},
+  {XMPP_ERROR_INTERNAL_SERVER_ERROR, "500",
+    "Internal Server Error", "internal-server-error",   "wait"},
+  {XMPP_ERROR_NOT_IMPLEMENTED,       "501",
+    "Not Implemented",       "feature-not-implemented", "cancel"},
+  {XMPP_ERROR_REMOTE_SERVER_ERROR,   "502",
+    "Remote Server Error",   "service-unavailable",     "wait"},
+  {XMPP_ERROR_SERVICE_UNAVAILABLE,   "503",
+    "Service Unavailable",   "service-unavailable",     "cancel"},
+  {XMPP_ERROR_REMOTE_SERVER_TIMEOUT, "504",
+    "Remote Server Timeout", "remote-server-timeout",   "wait"},
+  {XMPP_ERROR_DISCONNECTED,          "510",
+    "Disconnected",          "service-unavailable",     "cancel"},
+  {0, NULL, NULL, NULL, NULL}
+};
+
+#include "xmpp_helper.c"
+#include "xmpp_iq.c"
+#include "xmpp_iqrequest.c"
+#include "xmpp_muc.c"
+#include "xmpp_s10n.c"
+
+static struct IqHandlers
+{
+  const gchar *xmlns;
+  LmHandleMessageFunction handler;
+} iq_handlers[] = {
+  {NS_PING,       &handle_iq_ping},
+  {NS_VERSION,    &handle_iq_version},
+  {NS_TIME,       &handle_iq_time},
+  {NS_ROSTER,     &handle_iq_roster},
+  {NS_XMPP_TIME,  &handle_iq_time202},
+  {NS_LAST,       &handle_iq_last},
+  {NS_DISCO_INFO, &handle_iq_disco_info},
+  {NS_DISCO_ITEMS,&handle_iq_disco_items},
+  {NS_COMMANDS,   &handle_iq_commands},
+  {NULL, NULL}
+};
+
+void update_last_use(void)
+{
+  iqlast = time(NULL);
+}
+
+// Note: the caller should check the jid is correct
+void xmpp_addbuddy(const char *bjid, const char *name, const char *group)
+{
+  LmMessageNode *query, *y;
+  LmMessage *iq;
+  char *cleanjid;
+
+  if (!lm_connection_is_authenticated(lconnection)) return;
+
+  cleanjid = jidtodisp(bjid); // Stripping resource, just in case...
+
+  // We don't check if the jabber user already exists in the roster,
+  // because it allows to re-ask for notification.
+
+  iq = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_IQ,
+                                    LM_MESSAGE_SUB_TYPE_SET);
+  query = lm_message_node_add_child(iq->node, "query", NULL);
+  lm_message_node_set_attribute(query, "xmlns", NS_ROSTER);
+  y = lm_message_node_add_child(query, "item", NULL);
+  lm_message_node_set_attribute(y, "jid", cleanjid);
+
+  if (name)
+    lm_message_node_set_attribute(y, "name", name);
+
+  if (group)
+    lm_message_node_add_child(y, "group", group);
+
+  lm_connection_send(lconnection, iq, NULL);
+  lm_message_unref(iq);
+
+  xmpp_send_s10n(cleanjid, LM_MESSAGE_SUB_TYPE_SUBSCRIBE);
+
+  roster_add_user(cleanjid, name, group, ROSTER_TYPE_USER, sub_pending, -1);
+  g_free(cleanjid);
+  buddylist_build();
+
+  update_roster = TRUE;
+}
+
+void xmpp_updatebuddy(const char *bjid, const char *name, const char *group)
+{
+  LmMessage *iq;
+  LmMessageNode *x;
+  char *cleanjid;
+
+  if (!lm_connection_is_authenticated(lconnection)) return;
+
+  // XXX We should check name's and group's correctness
+
+  cleanjid = jidtodisp(bjid); // Stripping resource, just in case...
+
+  iq = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_IQ,
+                                    LM_MESSAGE_SUB_TYPE_SET);
+  x = lm_message_node_add_child(iq->node, "query", NULL);
+  lm_message_node_set_attribute(x, "xmlns", NS_ROSTER);
+  x = lm_message_node_add_child(x, "item", NULL);
+  lm_message_node_set_attributes(x,
+                                 "jid", cleanjid,
+                                 "name", name,
+                                 NULL);
+
+  if (group)
+    lm_message_node_add_child(x, "group", group);
+
+  lm_connection_send(lconnection, iq, NULL);
+  lm_message_unref(iq);
+  g_free(cleanjid);
+}
+
+void xmpp_delbuddy(const char *bjid)
+{
+  LmMessageNode *y, *z;
+  LmMessage *iq;
+  char *cleanjid;
+
+  if (!lm_connection_is_authenticated(lconnection)) return;
+
+  cleanjid = jidtodisp(bjid); // Stripping resource, just in case...
+
+  // If the current buddy is an agent, unsubscribe from it
+  if (roster_gettype(cleanjid) == ROSTER_TYPE_AGENT) {
+    scr_LogPrint(LPRINT_LOGNORM, "Unregistering from the %s agent", cleanjid);
+
+    iq = lm_message_new_with_sub_type(cleanjid, LM_MESSAGE_TYPE_IQ,
+                                      LM_MESSAGE_SUB_TYPE_SET);
+    y = lm_message_node_add_child(iq->node, "query", NULL);
+    lm_message_node_set_attribute(y, "xmlns", NS_REGISTER);
+    lm_message_node_add_child(y, "remove", NULL);
+    lm_connection_send(lconnection, iq, NULL);
+    lm_message_unref(iq);
+  }
+
+  // Cancel the subscriptions
+  xmpp_send_s10n(cleanjid, LM_MESSAGE_SUB_TYPE_UNSUBSCRIBED); //cancel "from"
+  xmpp_send_s10n(cleanjid, LM_MESSAGE_SUB_TYPE_UNSUBSCRIBE);  //cancel "to"
+
+  // Ask for removal from roster
+  iq = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_IQ,
+                                    LM_MESSAGE_SUB_TYPE_SET);
+
+  y = lm_message_node_add_child(iq->node, "query", NULL);
+  lm_message_node_set_attribute(y, "xmlns", NS_ROSTER);
+  z = lm_message_node_add_child(y, "item", NULL);
+  lm_message_node_set_attributes(z,
+                                 "jid", cleanjid,
+                                 "subscription", "remove",
+                                 NULL);
+  lm_connection_send(lconnection, iq, NULL);
+  lm_message_unref(iq);
+
+  roster_del_user(cleanjid);
+  g_free(cleanjid);
+  buddylist_build();
+
+  update_roster = TRUE;
+}
+
+void xmpp_request(const char *fjid, enum iqreq_type reqtype)
+{
+  GSList *resources, *p_res;
+  GSList *roster_elt;
+  const char *strreqtype, *xmlns;
+
+  if (reqtype == iqreq_version) {
+    xmlns = NS_VERSION;
+    strreqtype = "version";
+  } else if (reqtype == iqreq_time) {
+    xmlns = NS_TIME;
+    strreqtype = "time";
+  } else if (reqtype == iqreq_last) {
+    xmlns = NS_LAST;
+    strreqtype = "last";
+  } else if (reqtype == iqreq_vcard) {
+    xmlns = NS_VCARD;
+    strreqtype = "vCard";
+    // Special case
+  } else
+    return;
+
+  if (strchr(fjid, JID_RESOURCE_SEPARATOR)) {
+    // This is a full JID
+    xmpp_iq_request(fjid, xmlns);
+    scr_LogPrint(LPRINT_NORMAL, "Sent %s request to <%s>", strreqtype, fjid);
+    return;
+  }
+
+  // The resource has not been specified
+  roster_elt = roster_find(fjid, jidsearch, ROSTER_TYPE_USER|ROSTER_TYPE_ROOM);
+  if (!roster_elt) {
+    scr_LogPrint(LPRINT_NORMAL, "No known resource for <%s>...", fjid);
+    xmpp_iq_request(fjid, xmlns); // Let's send a request anyway...
+    scr_LogPrint(LPRINT_NORMAL, "Sent %s request to <%s>", strreqtype, fjid);
+    return;
+  }
+
+  // Send a request to each resource
+  resources = buddy_getresources(roster_elt->data);
+  if (!resources) {
+    scr_LogPrint(LPRINT_NORMAL, "No known resource for <%s>...", fjid);
+    xmpp_iq_request(fjid, xmlns); // Let's send a request anyway...
+    scr_LogPrint(LPRINT_NORMAL, "Sent %s request to <%s>", strreqtype, fjid);
+  }
+  for (p_res = resources ; p_res ; p_res = g_slist_next(p_res)) {
+    gchar *fulljid;
+    fulljid = g_strdup_printf("%s/%s", fjid, (char*)p_res->data);
+    xmpp_iq_request(fulljid, xmlns);
+    scr_LogPrint(LPRINT_NORMAL, "Sent %s request to <%s>", strreqtype, fulljid);
+    g_free(fulljid);
+    g_free(p_res->data);
+  }
+  g_slist_free(resources);
+}
+
+//  xmpp_send_msg(jid, text, type, subject,
+//                otrinject, *encrypted, type_overwrite)
+// When encrypted is not NULL, the function set *encrypted to 1 if the
+// message has been PGP-encrypted.  If encryption enforcement is set and
+// encryption fails, *encrypted is set to -1.
+void xmpp_send_msg(const char *fjid, const char *text, int type,
+                   const char *subject, gboolean otrinject, gint *encrypted,
+                   LmMessageSubType type_overwrite)
+{
+  LmMessage *x;
+  LmMessageSubType subtype;
+#ifdef HAVE_LIBOTR
+  int otr_msg = 0;
+#endif
+#if defined HAVE_GPGME || defined JEP0022 || defined JEP0085
+  char *rname, *barejid;
+  GSList *sl_buddy;
+#endif
+#if defined JEP0022 || defined JEP0085
+  LmMessageNode *event;
+  guint use_jep85 = 0;
+  struct jep0085 *jep85 = NULL;
+#endif
+  gchar *enc = NULL;
+
+  if (encrypted)
+    *encrypted = 0;
+
+  if (!lm_connection_is_authenticated(lconnection))
+    return;
+
+  if (!text && type == ROSTER_TYPE_USER)
+    return;
+
+  if (type_overwrite != LM_MESSAGE_SUB_TYPE_NOT_SET)
+    subtype = type_overwrite;
+  else {
+    if (type == ROSTER_TYPE_ROOM)
+      subtype = LM_MESSAGE_SUB_TYPE_GROUPCHAT;
+    else
+      subtype = LM_MESSAGE_SUB_TYPE_CHAT;
+  }
+
+#if defined HAVE_GPGME || defined HAVE_LIBOTR || \
+    defined JEP0022 || defined JEP0085
+  rname = strchr(fjid, JID_RESOURCE_SEPARATOR);
+  barejid = jidtodisp(fjid);
+  sl_buddy = roster_find(barejid, jidsearch, ROSTER_TYPE_USER);
+
+  // If we can get a resource name, we use it.  Else we use NULL,
+  // which hopefully will give us the most likely resource.
+  if (rname)
+    rname++;
+
+#ifdef HAVE_LIBOTR
+  if (otr_enabled() && !otrinject) {
+    if (type == ROSTER_TYPE_USER) {
+      otr_msg = otr_send((char **)&text, barejid);
+      if (!text) {
+        g_free(barejid);
+        if (encrypted)
+          *encrypted = -1;
+        return;
+      }
+    }
+    if (otr_msg && encrypted)
+      *encrypted = ENCRYPTED_OTR;
+  }
+#endif
+
+#ifdef HAVE_GPGME
+  if (type == ROSTER_TYPE_USER && sl_buddy && gpg_enabled()) {
+    if (!settings_pgp_getdisabled(barejid)) { // not disabled for this contact?
+      guint force;
+      struct pgp_data *res_pgpdata;
+      force = settings_pgp_getforce(barejid);
+      res_pgpdata = buddy_resource_pgp(sl_buddy->data, rname);
+      if (force || (res_pgpdata && res_pgpdata->sign_keyid)) {
+        /* Remote client has PGP support (we have a signature)
+         * OR encryption is enforced (force = TRUE).
+         * If the contact has a specific KeyId, we'll use it;
+         * if not, we'll use the key used for the signature.
+         * Both keys should match, in theory (cf. XEP-0027). */
+        const char *key;
+        key = settings_pgp_getkeyid(barejid);
+        if (!key && res_pgpdata)
+          key = res_pgpdata->sign_keyid;
+        if (key)
+          enc = gpg_encrypt(text, key);
+        if (!enc && force) {
+          if (encrypted)
+            *encrypted = -1;
+          g_free(barejid);
+          return;
+        }
+      }
+    }
+  }
+#endif // HAVE_GPGME
+
+  g_free(barejid);
+#endif // HAVE_GPGME || defined JEP0022 || defined JEP0085
+
+  x = lm_message_new_with_sub_type(fjid, LM_MESSAGE_TYPE_MESSAGE, subtype);
+  lm_message_node_add_child(x->node, "body",
+                            enc ? "This message is PGP-encrypted." : text);
+
+  if (subject)
+    lm_message_node_add_child(x->node, "subject", subject);
+
+  if (enc) {
+    LmMessageNode *y;
+    y = lm_message_node_add_child(x->node, "x", enc);
+    lm_message_node_set_attribute(y, "xmlns", NS_ENCRYPTED);
+    if (encrypted)
+      *encrypted = ENCRYPTED_PGP;
+    g_free(enc);
+  }
+
+#if defined JEP0022 || defined JEP0085
+  // If typing notifications are disabled, we can skip all this stuff...
+  if (chatstates_disabled || type == ROSTER_TYPE_ROOM)
+    goto xmpp_send_msg_no_chatstates;
+
+  if (sl_buddy)
+    jep85 = buddy_resource_jep85(sl_buddy->data, rname);
+#endif
+
+#ifdef JEP0085
+  /* JEP-0085 5.1
+   * "Until receiving a reply to the initial content message (or a standalone
+   * notification) from the Contact, the User MUST NOT send subsequent chat
+   * state notifications to the Contact."
+   * In our implementation support is initially "unknown", then it's "probed"
+   * and can become "ok".
+   */
+  if (jep85 && (jep85->support == CHATSTATES_SUPPORT_OK ||
+                jep85->support == CHATSTATES_SUPPORT_UNKNOWN)) {
+    event = lm_message_node_add_child(x->node, "active", NULL);
+    lm_message_node_set_attribute(event, "xmlns", NS_CHATSTATES);
+    if (jep85->support == CHATSTATES_SUPPORT_UNKNOWN)
+      jep85->support = CHATSTATES_SUPPORT_PROBED;
+    else
+      use_jep85 = 1;
+    jep85->last_state_sent = ROSTER_EVENT_ACTIVE;
+  }
+#endif
+#ifdef JEP0022
+  /* JEP-22
+   * If the Contact supports JEP-0085, we do not use JEP-0022.
+   * If not, we try to fall back to JEP-0022.
+   */
+  if (!use_jep85) {
+    struct jep0022 *jep22 = NULL;
+    event = lm_message_node_add_child(x->node, "x", NULL);
+    lm_message_node_set_attribute(event, "xmlns", NS_EVENT);
+    lm_message_node_add_child(event, "composing", NULL);
+
+    if (sl_buddy)
+      jep22 = buddy_resource_jep22(sl_buddy->data, rname);
+    if (jep22)
+      jep22->last_state_sent = ROSTER_EVENT_ACTIVE;
+
+    // An id is mandatory when using JEP-0022.
+    if (text || subject) {
+      const gchar *msgid = lm_message_get_id(x);
+      // Let's update last_msgid_sent
+      if (jep22) {
+        g_free(jep22->last_msgid_sent);
+        jep22->last_msgid_sent = g_strdup(msgid);
+      }
+    }
+  }
+#endif
+
+xmpp_send_msg_no_chatstates:
+  if (mystatus != invisible)
+    update_last_use();
+  lm_connection_send(lconnection, x, NULL);
+  lm_message_unref(x);
+}
+
+#ifdef JEP0085
+//  xmpp_send_jep85_chatstate()
+// Send a JEP-85 chatstate.
+static void xmpp_send_jep85_chatstate(const char *bjid, const char *resname,
+                                      guint state)
+{
+  LmMessage *m;
+  LmMessageNode *event;
+  GSList *sl_buddy;
+  const char *chattag;
+  char *rjid, *fjid = NULL;
+  struct jep0085 *jep85 = NULL;
+
+  if (!lm_connection_is_authenticated(lconnection)) return;
+
+  sl_buddy = roster_find(bjid, jidsearch, ROSTER_TYPE_USER);
+
+  // If we have a resource name, we use it.  Else we use NULL,
+  // which hopefully will give us the most likely resource.
+  if (sl_buddy)
+    jep85 = buddy_resource_jep85(sl_buddy->data, resname);
+
+  if (!jep85 || (jep85->support != CHATSTATES_SUPPORT_OK))
+    return;
+
+  if (state == jep85->last_state_sent)
+    return;
+
+  if (state == ROSTER_EVENT_ACTIVE)
+    chattag = "active";
+  else if (state == ROSTER_EVENT_COMPOSING)
+    chattag = "composing";
+  else if (state == ROSTER_EVENT_PAUSED)
+    chattag = "paused";
+  else {
+    scr_LogPrint(LPRINT_LOGNORM, "Error: unsupported JEP-85 state (%d)", state);
+    return;
+  }
+
+  jep85->last_state_sent = state;
+
+  if (resname)
+    fjid = g_strdup_printf("%s/%s", bjid, resname);
+
+  rjid = resname ? fjid : (char*)bjid;
+  m = lm_message_new_with_sub_type(rjid, LM_MESSAGE_TYPE_MESSAGE,
+                                   LM_MESSAGE_SUB_TYPE_CHAT);
+
+  event = lm_message_node_add_child(m->node, chattag, NULL);
+  lm_message_node_set_attribute(event, "xmlns", NS_CHATSTATES);
+
+  lm_connection_send(lconnection, m, NULL);
+  lm_message_unref(m);
+
+  g_free(fjid);
+}
+#endif
+
+#ifdef JEP0022
+//  xmpp_send_jep22_event()
+// Send a JEP-22 message event (delivered, composing...).
+static void xmpp_send_jep22_event(const char *fjid, guint type)
+{
+  LmMessage *x;
+  LmMessageNode *event;
+  const char *msgid;
+  char *rname, *barejid;
+  GSList *sl_buddy;
+  struct jep0022 *jep22 = NULL;
+  guint jep22_state;
+
+  if (!lm_connection_is_authenticated(lconnection)) return;
+
+  rname = strchr(fjid, JID_RESOURCE_SEPARATOR);
+  barejid = jidtodisp(fjid);
+  sl_buddy = roster_find(barejid, jidsearch, ROSTER_TYPE_USER);
+  g_free(barejid);
+
+  // If we can get a resource name, we use it.  Else we use NULL,
+  // which hopefully will give us the most likely resource.
+  if (rname)
+    rname++;
+  if (sl_buddy)
+    jep22 = buddy_resource_jep22(sl_buddy->data, rname);
+
+  if (!jep22)
+    return; // XXX Maybe we could try harder (other resources?)
+
+  msgid = jep22->last_msgid_rcvd;
+
+  // For composing events (composing, active, inactive, paused...),
+  // JEP22 only has 2 states; we'll use composing and active.
+  if (type == ROSTER_EVENT_COMPOSING)
+    jep22_state = ROSTER_EVENT_COMPOSING;
+  else if (type == ROSTER_EVENT_ACTIVE ||
+           type == ROSTER_EVENT_PAUSED)
+    jep22_state = ROSTER_EVENT_ACTIVE;
+  else
+    jep22_state = 0; // ROSTER_EVENT_NONE
+
+  if (jep22_state) {
+    // Do not re-send a same event
+    if (jep22_state == jep22->last_state_sent)
+      return;
+    jep22->last_state_sent = jep22_state;
+  }
+
+  x = lm_message_new_with_sub_type(fjid, LM_MESSAGE_TYPE_MESSAGE,
+                                   LM_MESSAGE_SUB_TYPE_CHAT);
+
+  event = lm_message_node_add_child(x->node, "x", NULL);
+  lm_message_node_set_attribute(event, "xmlns", NS_EVENT);
+  if (type == ROSTER_EVENT_DELIVERED)
+    lm_message_node_add_child(event, "delivered", NULL);
+  else if (type == ROSTER_EVENT_COMPOSING)
+    lm_message_node_add_child(event, "composing", NULL);
+  lm_message_node_add_child(event, "id", msgid);
+
+  lm_connection_send(lconnection, x, NULL);
+  lm_message_unref(x);
+}
+#endif
+
+//  xmpp_send_chatstate(buddy, state)
+// Send a chatstate or event (JEP-22/85) according to the buddy's capabilities.
+// The message is sent to one of the resources with the highest priority.
+#if defined JEP0022 || defined JEP0085
+void xmpp_send_chatstate(gpointer buddy, guint chatstate)
+{
+  const char *bjid;
+#ifdef JEP0085
+  GSList *resources, *p_res, *p_next;
+  struct jep0085 *jep85 = NULL;
+#endif
+#ifdef JEP0022
+  struct jep0022 *jep22;
+#endif
+
+  bjid = buddy_getjid(buddy);
+  if (!bjid) return;
+
+#ifdef JEP0085
+  /* Send the chatstate to the last resource (which should have the highest
+     priority).
+     If chatstate is "active", send an "active" state to all resources
+     which do not curently have this state.
+   */
+  resources = buddy_getresources(buddy);
+  for (p_res = resources ; p_res ; p_res = p_next) {
+    p_next = g_slist_next(p_res);
+    jep85 = buddy_resource_jep85(buddy, p_res->data);
+    if (jep85 && jep85->support == CHATSTATES_SUPPORT_OK) {
+      // If p_next is NULL, this is the highest (prio) resource, i.e.
+      // the one we are probably writing to.
+      if (!p_next || (jep85->last_state_sent != ROSTER_EVENT_ACTIVE &&
+                      chatstate == ROSTER_EVENT_ACTIVE))
+        xmpp_send_jep85_chatstate(bjid, p_res->data, chatstate);
+    }
+    g_free(p_res->data);
+  }
+  g_slist_free(resources);
+  // If the last resource had chatstates support when can return now,
+  // we don't want to send a JEP22 event.
+  if (jep85 && jep85->support == CHATSTATES_SUPPORT_OK)
+    return;
+#endif
+#ifdef JEP0022
+  jep22 = buddy_resource_jep22(buddy, NULL);
+  if (jep22 && jep22->support == CHATSTATES_SUPPORT_OK) {
+    xmpp_send_jep22_event(bjid, chatstate);
+  }
+#endif
+}
+#endif
+
+
+//  chatstates_reset_probed(fulljid)
+// If the JEP has been probed for this contact, set it back to unknown so
+// that we probe it again.  The parameter must be a full jid (w/ resource).
+#if defined JEP0022 || defined JEP0085
+static void chatstates_reset_probed(const char *fulljid)
+{
+  char *rname, *barejid;
+  GSList *sl_buddy;
+  struct jep0085 *jep85;
+  struct jep0022 *jep22;
+
+  rname = strchr(fulljid, JID_RESOURCE_SEPARATOR);
+  if (!rname++)
+    return;
+
+  barejid = jidtodisp(fulljid);
+  sl_buddy = roster_find(barejid, jidsearch, ROSTER_TYPE_USER);
+  g_free(barejid);
+
+  if (!sl_buddy)
+    return;
+
+  jep85 = buddy_resource_jep85(sl_buddy->data, rname);
+  jep22 = buddy_resource_jep22(sl_buddy->data, rname);
+
+  if (jep85 && jep85->support == CHATSTATES_SUPPORT_PROBED)
+    jep85->support = CHATSTATES_SUPPORT_UNKNOWN;
+  if (jep22 && jep22->support == CHATSTATES_SUPPORT_PROBED)
+    jep22->support = CHATSTATES_SUPPORT_UNKNOWN;
+}
+#endif
+
+#ifdef HAVE_GPGME
+//  keys_mismatch(key, expectedkey)
+// Return TRUE if both keys are non-null and "expectedkey" doesn't match
+// the end of "key".
+// If one of the keys is null, return FALSE.
+// If expectedkey is less than 8 bytes long, return TRUE.
+//
+// Example: keys_mismatch("C9940A9BB0B92210", "B0B92210") will return FALSE.
+static bool keys_mismatch(const char *key, const char *expectedkey)
+{
+  int lk, lek;
+
+  if (!expectedkey || !key)
+    return FALSE;
+
+  lk = strlen(key);
+  lek = strlen(expectedkey);
+
+  // If the expectedkey is less than 8 bytes long, this is probably a
+  // user mistake so we consider it's a mismatch.
+  if (lek < 8)
+    return TRUE;
+
+  if (lek < lk)
+    key += lk - lek;
+
+  return strcasecmp(key, expectedkey);
+}
+#endif
+
+//  check_signature(barejid, resourcename, xmldata, text)
+// Verify the signature (in xmldata) of "text" for the contact
+// barejid/resourcename.
+// xmldata is the 'jabber:x:signed' stanza.
+// If the key id is found, the contact's PGP data are updated.
+static void check_signature(const char *barejid, const char *rname,
+                            LmMessageNode *node, const char *text)
+{
+#ifdef HAVE_GPGME
+  const char *p, *key;
+  GSList *sl_buddy;
+  struct pgp_data *res_pgpdata;
+  gpgme_sigsum_t sigsum;
+
+  // All parameters must be valid
+  if (!(node && barejid && rname && text))
+    return;
+
+  if (!gpg_enabled())
+    return;
+
+  // Get the resource PGP data structure
+  sl_buddy = roster_find(barejid, jidsearch, ROSTER_TYPE_USER);
+  if (!sl_buddy)
+    return;
+  res_pgpdata = buddy_resource_pgp(sl_buddy->data, rname);
+  if (!res_pgpdata)
+    return;
+
+  if (!node->name || strcmp(node->name, "x")) //XXX: probably useless
+    return; // We expect "<x xmlns='jabber:x:signed'>"
+
+  // Get signature
+  p = lm_message_node_get_value(node);
+  if (!p)
+    return;
+
+  key = gpg_verify(p, text, &sigsum);
+  if (key) {
+    const char *expectedkey;
+    char *buf;
+    g_free(res_pgpdata->sign_keyid);
+    res_pgpdata->sign_keyid = (char *)key;
+    res_pgpdata->last_sigsum = sigsum;
+    if (sigsum & GPGME_SIGSUM_RED) {
+      buf = g_strdup_printf("Bad signature from <%s/%s>", barejid, rname);
+      scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_INFO, 0);
+      scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
+      g_free(buf);
+    }
+    // Verify that the key id is the one we expect.
+    expectedkey = settings_pgp_getkeyid(barejid);
+    if (keys_mismatch(key, expectedkey)) {
+      buf = g_strdup_printf("Warning: The KeyId from <%s/%s> doesn't match "
+                            "the key you set up", barejid, rname);
+      scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_INFO, 0);
+      scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
+      g_free(buf);
+    }
+  }
+#endif
+}
+
+static LmSSLResponse ssl_cb(LmSSL *ssl, LmSSLStatus status, gpointer ud)
+{
+  scr_LogPrint(LPRINT_LOGNORM, "SSL status:%d", status);
+
+  switch (status) {
+  case LM_SSL_STATUS_NO_CERT_FOUND:
+    scr_LogPrint(LPRINT_LOGNORM, "No certificate found!");
+    break;
+  case LM_SSL_STATUS_UNTRUSTED_CERT:
+    scr_LogPrint(LPRINT_LOGNORM, "Certificate is not trusted!");
+    break;
+  case LM_SSL_STATUS_CERT_EXPIRED:
+    scr_LogPrint(LPRINT_LOGNORM, "Certificate has expired!");
+    break;
+  case LM_SSL_STATUS_CERT_NOT_ACTIVATED:
+    scr_LogPrint(LPRINT_LOGNORM, "Certificate has not been activated!");
+    break;
+  case LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH:
+    scr_LogPrint(LPRINT_LOGNORM,
+                 "Certificate hostname does not match expected hostname!");
+    break;
+  case LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH: {
+    char fpr[49];
+    fingerprint_to_hex((const unsigned char*)lm_ssl_get_fingerprint(ssl),
+                       fpr);
+    scr_LogPrint(LPRINT_LOGNORM,
+              "Certificate fingerprint does not match expected fingerprint!");
+    scr_LogPrint(LPRINT_LOGNORM, "Remote fingerprint: %s", fpr);
+
+    scr_LogPrint(LPRINT_LOGNORM, "Expected fingerprint: %s",
+                 settings_opt_get("ssl_fingerprint"));
+
+    return LM_SSL_RESPONSE_STOP;
+    break;
+  }
+  case LM_SSL_STATUS_GENERIC_ERROR:
+    scr_LogPrint(LPRINT_LOGNORM, "Generic SSL error!");
+    break;
+  }
+
+  if (!settings_opt_get_int("ssl_ignore_checks"))
+    return LM_SSL_RESPONSE_CONTINUE;
+  return LM_SSL_RESPONSE_STOP;
+}
+
+static void connection_auth_cb(LmConnection *connection, gboolean success,
+                               gpointer user_data)
+{
+  if (success) {
+    LmMessage *m;
+
+    m = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_PRESENCE,
+                                     LM_MESSAGE_SUB_TYPE_AVAILABLE);
+    lm_connection_send(connection, m, NULL);
+
+    lm_message_unref(m);
+    xmpp_setprevstatus();
+    xmpp_iq_request(NULL, NS_ROSTER);
+    xmpp_request_storage("storage:bookmarks");
+    xmpp_request_storage("storage:rosternotes");
+
+    AutoConnection = TRUE;
+  } else
+    scr_LogPrint(LPRINT_LOGNORM, "Authentication failed");
+}
+
+gboolean xmpp_reconnect()
+{
+  if (!lm_connection_is_authenticated(lconnection))
+    xmpp_connect();
+  return FALSE;
+}
+
+static void _try_to_reconnect(void)
+{
+  if (AutoConnection)
+    g_timeout_add_seconds(RECONNECTION_TIMEOUT, xmpp_reconnect, NULL);
+}
+
+static void connection_open_cb(LmConnection *connection, gboolean success,
+                               gpointer user_data)
+{
+  const char *username, *password, *resource, *servername;
+  GError *error;
+
+  if (success) {
+    servername = settings_opt_get("server");
+    username   = settings_opt_get("username");
+    password   = settings_opt_get("password");
+    resource   = strchr(lm_connection_get_jid(connection),
+                        JID_RESOURCE_SEPARATOR);
+    if (resource)
+      resource++;
+
+    if (!lm_connection_authenticate(lconnection, username, password, resource,
+                                    connection_auth_cb, NULL, FALSE, &error)) {
+      scr_LogPrint(LPRINT_LOGNORM, "Failed to authenticate: %s\n",
+                   error->message);
+      _try_to_reconnect();
+    }
+  } else {
+    scr_LogPrint(LPRINT_LOGNORM, "There was an error while connecting.");
+    _try_to_reconnect();
+  }
+}
+
+static void connection_close_cb(LmConnection *connection,
+                                LmDisconnectReason reason,
+                                gpointer user_data)
+{
+  const char *str;
+
+  switch (reason) {
+  case LM_DISCONNECT_REASON_OK:
+          str = "LM_DISCONNECT_REASON_OK";
+          break;
+  case LM_DISCONNECT_REASON_PING_TIME_OUT:
+          str = "LM_DISCONNECT_REASON_PING_TIME_OUT";
+          break;
+  case LM_DISCONNECT_REASON_HUP:
+          str = "LM_DISCONNECT_REASON_HUP";
+          break;
+  case LM_DISCONNECT_REASON_ERROR:
+          str = "LM_DISCONNECT_REASON_ERROR";
+          break;
+  case LM_DISCONNECT_REASON_UNKNOWN:
+  default:
+          str = "LM_DISCONNECT_REASON_UNKNOWN";
+          break;
+  }
+
+  if (reason != LM_DISCONNECT_REASON_OK)
+    _try_to_reconnect();
+
+  // Free bookmarks
+  if (bookmarks)
+    lm_message_node_unref(bookmarks);
+  bookmarks = NULL;
+  // Free roster
+  roster_free();
+  if (rosternotes)
+    lm_message_node_unref(rosternotes);
+  rosternotes = NULL;
+  // Update display
+  update_roster = TRUE;
+  scr_UpdateBuddyWindow();
+
+  scr_LogPrint(LPRINT_NORMAL, "Disconnected, reason:%d->'%s'\n", reason, str);
+}
+
+static void handle_state_events(const char *from, LmMessageNode *node)
+{
+#if defined JEP0022 || defined JEP0085
+  LmMessageNode *state_ns = NULL;
+  const char *body;
+  char *rname, *bjid;
+  GSList *sl_buddy;
+  guint events;
+  struct jep0022 *jep22 = NULL;
+  struct jep0085 *jep85 = NULL;
+  enum {
+    JEP_none,
+    JEP_85,
+    JEP_22
+  } which_jep = JEP_none;
+
+  rname = strchr(from, JID_RESOURCE_SEPARATOR);
+  if (rname)
+    ++rname;
+  else
+    rname = (char *)from + strlen(from);
+  bjid  = jidtodisp(from);
+  sl_buddy = roster_find(bjid, jidsearch, ROSTER_TYPE_USER);
+  g_free(bjid);
+
+  /* XXX Actually that's wrong, since it filters out server "offline"
+     messages (for JEP-0022).  This JEP is (almost) deprecated so
+     we don't really care. */
+  if (!sl_buddy) {
+    return;
+  }
+
+  /* Let's see chich JEP the contact uses.  If possible, we'll use
+     JEP-85, if not we'll look for JEP-22 support. */
+  events = buddy_resource_getevents(sl_buddy->data, rname);
+
+  jep85 = buddy_resource_jep85(sl_buddy->data, rname);
+  if (jep85) {
+    state_ns = lm_message_node_find_xmlns(node, NS_CHATSTATES);
+    if (state_ns)
+      which_jep = JEP_85;
+  }
+
+  if (which_jep != JEP_85) { /* Fall back to JEP-0022 */
+    jep22 = buddy_resource_jep22(sl_buddy->data, rname);
+    if (jep22) {
+      state_ns = lm_message_node_find_xmlns(node, NS_EVENT);
+      if (state_ns)
+        which_jep = JEP_22;
+    }
+  }
+
+  if (!which_jep) { /* Sender does not use chat states */
+    return;
+  }
+
+  body = lm_message_node_get_child_value(node, "body");
+
+  if (which_jep == JEP_85) { /* JEP-0085 */
+    jep85->support = CHATSTATES_SUPPORT_OK;
+
+    if (!strcmp(state_ns->name, "composing")) {
+      jep85->last_state_rcvd = ROSTER_EVENT_COMPOSING;
+    } else if (!strcmp(state_ns->name, "active")) {
+      jep85->last_state_rcvd = ROSTER_EVENT_ACTIVE;
+    } else if (!strcmp(state_ns->name, "paused")) {
+      jep85->last_state_rcvd = ROSTER_EVENT_PAUSED;
+    } else if (!strcmp(state_ns->name, "inactive")) {
+      jep85->last_state_rcvd = ROSTER_EVENT_INACTIVE;
+    } else if (!strcmp(state_ns->name, "gone")) {
+      jep85->last_state_rcvd = ROSTER_EVENT_GONE;
+    }
+    events = jep85->last_state_rcvd;
+  } else {              /* JEP-0022 */
+#ifdef JEP0022
+    const char *msgid;
+    jep22->support = CHATSTATES_SUPPORT_OK;
+    jep22->last_state_rcvd = ROSTER_EVENT_NONE;
+
+    msgid = lm_message_node_get_attribute(node, "id");
+
+    if (lm_message_node_get_child(state_ns, "composing")) {
+      // Clear composing if the message contains a body
+      if (body)
+        events &= ~ROSTER_EVENT_COMPOSING;
+      else
+        events |= ROSTER_EVENT_COMPOSING;
+      jep22->last_state_rcvd |= ROSTER_EVENT_COMPOSING;
+
+    } else {
+      events &= ~ROSTER_EVENT_COMPOSING;
+    }
+
+    // Cache the message id
+    g_free(jep22->last_msgid_rcvd);
+    if (msgid)
+      jep22->last_msgid_rcvd = g_strdup(msgid);
+    else
+      jep22->last_msgid_rcvd = NULL;
+
+    if (lm_message_node_get_child(state_ns, "delivered")) {
+      jep22->last_state_rcvd |= ROSTER_EVENT_DELIVERED;
+
+      // Do we have to send back an ACK?
+      if (body)
+        xmpp_send_jep22_event(from, ROSTER_EVENT_DELIVERED);
+    }
+#endif
+  }
+
+  buddy_resource_setevents(sl_buddy->data, rname, events);
+
+  update_roster = TRUE;
+#endif
+}
+
+static void gotmessage(LmMessageSubType type, const char *from,
+                       const char *body, const char *enc, const char *subject,
+                       time_t timestamp, LmMessageNode *node_signed)
+{
+  char *bjid;
+  const char *rname, *s;
+  char *decrypted_pgp = NULL;
+  char *decrypted_otr = NULL;
+  int otr_msg = 0, free_msg = 0;
+
+  bjid = jidtodisp(from);
+
+  rname = strchr(from, JID_RESOURCE_SEPARATOR);
+  if (rname) rname++;
+
+#ifdef HAVE_GPGME
+  if (enc && gpg_enabled()) {
+    decrypted_pgp = gpg_decrypt(enc);
+    if (decrypted_pgp) {
+      body = decrypted_pgp;
+    }
+  }
+  // Check signature of an unencrypted message
+  if (node_signed && gpg_enabled())
+    check_signature(bjid, rname, node_signed, decrypted_pgp);
+#endif
+
+#ifdef HAVE_LIBOTR
+  if (otr_enabled()) {
+    decrypted_otr = (char*)body;
+    otr_msg = otr_receive(&decrypted_otr, bjid, &free_msg);
+    if (!decrypted_otr) {
+      goto gotmessage_return;
+    }
+    body = decrypted_otr;
+  }
+#endif
+
+  // Check for unexpected groupchat messages
+  // If we receive a groupchat message from a room we're not a member of,
+  // this is probably a server issue and the best we can do is to send
+  // a type unavailable.
+  if (type == LM_MESSAGE_SUB_TYPE_GROUPCHAT && !roster_getnickname(bjid)) {
+    // It shouldn't happen, probably a server issue
+    GSList *room_elt;
+    char *mbuf;
+
+    mbuf = g_strdup_printf("Unexpected groupchat packet!");
+    scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf);
+    scr_WriteIncomingMessage(bjid, mbuf, 0, HBB_PREFIX_INFO, 0);
+    g_free(mbuf);
+
+    // Send back an unavailable packet
+    xmpp_setstatus(offline, bjid, "", TRUE);
+
+    // MUC
+    // Make sure this is a room (it can be a conversion user->room)
+    room_elt = roster_find(bjid, jidsearch, 0);
+    if (!room_elt) {
+      room_elt = roster_add_user(bjid, NULL, NULL, ROSTER_TYPE_ROOM,
+                                 sub_none, -1);
+    } else {
+      buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
+    }
+
+    buddylist_build();
+    scr_DrawRoster();
+    goto gotmessage_return;
+  }
+
+  // We don't call the message_in hook if 'block_unsubscribed' is true and
+  // this is a regular message from an unsubscribed user.
+  // System messages (from our server) are allowed.
+  if ((!settings_opt_get_int("block_unsubscribed") ||
+       (roster_getsubscription(bjid) & sub_from) ||
+       (type == LM_MESSAGE_SUB_TYPE_CHAT)) ||
+      ((s = settings_opt_get("server")) != NULL && !strcasecmp(bjid, s))) {
+    gchar *fullbody = NULL;
+    guint encrypted;
+
+    if (decrypted_pgp)
+      encrypted = ENCRYPTED_PGP;
+    else if (otr_msg)
+      encrypted = ENCRYPTED_OTR;
+    else
+      encrypted = 0;
+
+    if (subject) {
+      if (body)
+        fullbody = g_strdup_printf("[%s]\n%s", subject, body);
+      else
+        fullbody = g_strdup_printf("[%s]\n", subject);
+      body = fullbody;
+    }
+    hk_message_in(bjid, rname, timestamp, body, type, encrypted);
+    g_free(fullbody);
+  } else {
+    scr_LogPrint(LPRINT_LOGNORM, "Blocked a message from <%s>", bjid);
+  }
+
+gotmessage_return:
+  // Clean up and exit
+  g_free(bjid);
+  g_free(decrypted_pgp);
+  if (free_msg)
+    g_free(decrypted_otr);
+}
+
+
+static LmHandlerResult handle_messages(LmMessageHandler *handler,
+                                       LmConnection *connection,
+                                       LmMessage *m, gpointer user_data)
+{
+  const char *p, *from=lm_message_get_from(m);
+  char *r, *s;
+  LmMessageNode *x;
+  const char *body = NULL;
+  const char *enc = NULL;
+  const char *subject = NULL;
+  time_t timestamp = 0L;
+
+  body = lm_message_node_get_child_value(m->node, "body");
+
+  x = lm_message_node_find_xmlns(m->node, NS_ENCRYPTED);
+  if (x && (p = lm_message_node_get_value(x)) != NULL)
+    enc = p;
+
+  p = lm_message_node_get_child_value(m->node, "subject");
+  if (p != NULL) {
+    if (lm_message_get_sub_type(m) != LM_MESSAGE_SUB_TYPE_GROUPCHAT) {
+      // Chat message
+      subject = p;
+    } else {                                      // Room topic
+      GSList *roombuddy;
+      gchar *mbuf;
+      const gchar *subj = p;
+      // Get the room (s) and the nickname (r)
+      s = g_strdup(lm_message_get_from(m));
+      r = strchr(s, JID_RESOURCE_SEPARATOR);
+      if (r) *r++ = 0;
+      else   r = s;
+      // Set the new topic
+      roombuddy = roster_find(s, jidsearch, 0);
+      if (roombuddy)
+        buddy_settopic(roombuddy->data, subj);
+      // Display inside the room window
+      if (r == s) {
+        // No specific resource (this is certainly history)
+        mbuf = g_strdup_printf("The topic has been set to: %s", subj);
+      } else {
+        mbuf = g_strdup_printf("%s has set the topic to: %s", r, subj);
+      }
+      scr_WriteIncomingMessage(s, mbuf, 0,
+                               HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
+      if (settings_opt_get_int("log_muc_conf"))
+        hlog_write_message(s, 0, -1, mbuf);
+      g_free(s);
+      g_free(mbuf);
+      // The topic is displayed in the chat status line, so refresh now.
+      scr_UpdateChatStatus(TRUE);
+    }
+  }
+
+  // Timestamp?
+  timestamp = lm_message_node_get_timestamp(m->node);
+
+  if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) {
+    x = lm_message_node_get_child(m->node, "error");
+    display_server_error(x);
+#if defined JEP0022 || defined JEP0085
+    // If the JEP85/22 support is probed, set it back to unknown so that
+    // we probe it again.
+    chatstates_reset_probed(from);
+#endif
+  } else {
+    handle_state_events(from, m->node);
+  }
+  if (from && (body || subject))
+    gotmessage(lm_message_get_sub_type(m), from, body, enc, subject, timestamp,
+               lm_message_node_find_xmlns(m->node, NS_SIGNED));
+
+  if (from) {
+    x = lm_message_node_find_xmlns(m->node,
+                                   "http://jabber.org/protocol/muc#user");
+    if (x && !strcmp(x->name, "x"))
+      got_muc_message(from, x);
+  }
+
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+static LmHandlerResult handle_presence(LmMessageHandler *handler,
+                                       LmConnection *connection,
+                                       LmMessage *m, gpointer user_data)
+{
+  char *r;
+  const char *from, *rname, *p=NULL, *ustmsg=NULL;
+  enum imstatus ust;
+  char bpprio;
+  time_t timestamp = 0L;
+  LmMessageNode *muc_packet;
+
+  //Check for MUC presence packet
+  muc_packet = lm_message_node_find_xmlns
+          (m->node, "http://jabber.org/protocol/muc#user");
+
+  from = lm_message_get_from(m);
+
+  rname = strchr(from, JID_RESOURCE_SEPARATOR);
+  if (rname) rname++;
+
+  if (settings_opt_get_int("ignore_self_presence")) {
+    const char *self_fjid = lm_connection_get_jid(connection);
+    if (self_fjid && !strcasecmp(self_fjid, from)) {
+      return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; // Ignoring self presence
+    }
+  }
+
+  r = jidtodisp(from);
+
+  if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) {
+    LmMessageNode *x;
+    scr_LogPrint(LPRINT_LOGNORM, "Error presence packet from <%s>", r);
+    x = lm_message_node_find_child(m->node, "error");
+    display_server_error(x);
+    // Let's check it isn't a nickname conflict.
+    // XXX Note: We should handle the <conflict/> string condition.
+    if ((p = lm_message_node_get_attribute(x, "code")) != NULL) {
+      if (atoi(p) == 409) {
+        // 409 = conflict (nickname is in use or registered by another user)
+        // If we are not inside this room, we should reset the nickname
+        GSList *room_elt = roster_find(r, jidsearch, 0);
+        if (room_elt && !buddy_getinsideroom(room_elt->data))
+          buddy_setnickname(room_elt->data, NULL);
+      }
+    }
+
+    g_free(r);
+    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+  }
+
+  p = lm_message_node_get_child_value(m->node, "priority");
+  if (p && *p) bpprio = (gchar)atoi(p);
+  else         bpprio = 0;
+
+  ust = available;
+
+  p = lm_message_node_get_child_value(m->node, "show");
+  if (p) {
+    if (!strcmp(p, "away"))      ust = away;
+    else if (!strcmp(p, "dnd"))  ust = dontdisturb;
+    else if (!strcmp(p, "xa"))   ust = notavail;
+    else if (!strcmp(p, "chat")) ust = freeforchat;
+  }
+
+  if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_UNAVAILABLE)
+    ust = offline;
+
+  ustmsg = lm_message_node_get_child_value(m->node, "status");
+
+  // Timestamp?
+  timestamp = lm_message_node_get_timestamp(m->node);
+
+  if (muc_packet) {
+    // This is a MUC presence message
+    handle_muc_presence(from, muc_packet, r, rname,
+                        ust, ustmsg, timestamp, bpprio);
+  } else {
+    // Not a MUC message, so this is a regular buddy...
+    // Call hk_statuschange() if status has changed or if the
+    // status message is different
+    const char *msg;
+    msg = roster_getstatusmsg(r, rname);
+    if ((ust != roster_getstatus(r, rname)) ||
+        (!ustmsg && msg && msg[0]) || (ustmsg && (!msg || strcmp(ustmsg, msg))))
+      hk_statuschange(r, rname, bpprio, timestamp, ust, ustmsg);
+    // Presence signature processing
+    if (!ustmsg)
+      ustmsg = ""; // Some clients omit the <status/> element :-(
+    check_signature(r, rname, lm_message_node_find_xmlns(m->node, NS_SIGNED),
+                    ustmsg);
+  }
+
+  g_free(r);
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+
+static LmHandlerResult handle_iq(LmMessageHandler *handler,
+                                 LmConnection *connection,
+                                 LmMessage *m, gpointer user_data)
+{
+  int i;
+  const char *xmlns = NULL;
+  LmMessageNode *x;
+
+  for (x = m->node->children; x; x=x->next) {
+    xmlns = lm_message_node_get_attribute(x, "xmlns");
+    if (xmlns)
+      for (i=0; iq_handlers[i].xmlns; ++i)
+        if (!strcmp(iq_handlers[i].xmlns, xmlns))
+          return iq_handlers[i].handler(NULL, connection, m, user_data);
+    xmlns = NULL;
+  }
+
+  if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) {
+    display_server_error(lm_message_node_get_child(m->node, "error"));
+    return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+  }
+
+  if ((lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_SET) ||
+      (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_GET))
+    send_iq_error(connection, m, XMPP_ERROR_NOT_IMPLEMENTED);
+
+  scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, "Unhandled IQ: %s",
+               lm_message_node_to_string(m->node));
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+static LmHandlerResult handle_s10n(LmMessageHandler *handler,
+                                   LmConnection *connection,
+                                   LmMessage *m, gpointer user_data)
+{
+  char *r;
+  char *buf;
+  int newbuddy;
+  const char *from = lm_message_get_from(m);
+
+  r = jidtodisp(from);
+
+  newbuddy = !roster_find(r, jidsearch, 0);
+
+  if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_SUBSCRIBE) {
+    /* The sender wishes to subscribe to our presence */
+    const char *msg;
+    int isagent;
+    eviqs *evn;
+
+    isagent = (roster_gettype(r) & ROSTER_TYPE_AGENT) != 0;
+    msg = lm_message_node_get_child_value(m->node, "status");
+
+    buf = g_strdup_printf("<%s> wants to subscribe to your presence updates",
+                          from);
+    scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0);
+    scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
+    g_free(buf);
+
+    if (msg) {
+      buf = g_strdup_printf("<%s> said: %s", from, msg);
+      scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0);
+      replace_nl_with_dots(buf);
+      scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
+      g_free(buf);
+    }
+
+    // Create a new event item
+    evn = evs_new(EVS_TYPE_SUBSCRIPTION, EVS_MAX_TIMEOUT);
+    if (evn) {
+      evn->callback = &evscallback_subscription;
+      evn->data = g_strdup(r);
+      evn->desc = g_strdup_printf("<%s> wants to subscribe to your "
+                                  "presence updates", r);
+      buf = g_strdup_printf("Please use /event %s accept|reject", evn->id);
+    } else {
+      buf = g_strdup_printf("Unable to create a new event!");
+    }
+    scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0);
+    scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
+    g_free(buf);
+  } else if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_UNSUBSCRIBE) {
+    /* The sender is unsubscribing from our presence */
+    xmpp_send_s10n(from, LM_MESSAGE_SUB_TYPE_UNSUBSCRIBED);
+    buf = g_strdup_printf("<%s> is unsubscribing from your "
+                          "presence updates", from);
+    scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0);
+    scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
+    g_free(buf);
+  } else if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_SUBSCRIBED) {
+    /* The sender has allowed us to receive their presence */
+    buf = g_strdup_printf("<%s> has allowed you to receive their "
+                          "presence updates", from);
+    scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0);
+    scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
+    g_free(buf);
+  } else if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_UNSUBSCRIBED) {
+    /* The subscription request has been denied or a previously-granted
+       subscription has been cancelled */
+    roster_unsubscribed(from);
+    update_roster = TRUE;
+    buf = g_strdup_printf("<%s> has cancelled your subscription to "
+                          "their presence updates", from);
+    scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0);
+    scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
+    g_free(buf);
+  } else {
+    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+  }
+
+  if (newbuddy)
+    update_roster = TRUE;
+  g_free(r);
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+//TODO: Use the enum of loudmouth, when it's included in the header...
+typedef enum {
+  LM_LOG_LEVEL_VERBOSE = 1 << (G_LOG_LEVEL_USER_SHIFT),
+  LM_LOG_LEVEL_NET     = 1 << (G_LOG_LEVEL_USER_SHIFT + 1),
+  LM_LOG_LEVEL_PARSER  = 1 << (G_LOG_LEVEL_USER_SHIFT + 2),
+  LM_LOG_LEVEL_SSL     = 1 << (G_LOG_LEVEL_USER_SHIFT + 3),
+  LM_LOG_LEVEL_SASL    = 1 << (G_LOG_LEVEL_USER_SHIFT + 4),
+  LM_LOG_LEVEL_ALL     = (LM_LOG_LEVEL_NET |
+        LM_LOG_LEVEL_VERBOSE |
+        LM_LOG_LEVEL_PARSER |
+        LM_LOG_LEVEL_SSL |
+        LM_LOG_LEVEL_SASL)
+} LmLogLevelFlags;
+
+static void lm_debug_handler (const gchar    *log_domain,
+                              GLogLevelFlags  log_level,
+                              const gchar    *message,
+                              gpointer        user_data)
+{
+  if (settings_opt_get_int("tracelog_level") != 2)
+    return;
+  if (message) {
+    char *msg;
+    if (message[0] == '\n')
+      msg = g_strdup(&message[1]);
+    else
+      msg = g_strdup(message);
+    if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = '\0';
+
+    if (log_level & LM_LOG_LEVEL_VERBOSE) {
+      scr_LogPrint(LPRINT_DEBUG, "LM-VERBOSE: %s", msg);
+    }
+    if ((LmLogLevelFlags)log_level & LM_LOG_LEVEL_NET) {
+      scr_LogPrint(LPRINT_DEBUG, "LM-NET: %s", msg);
+    }
+    else if (log_level & LM_LOG_LEVEL_PARSER) {
+      scr_LogPrint(LPRINT_DEBUG, "LM-PARSER: %s", msg);
+    }
+    else if (log_level & LM_LOG_LEVEL_SASL) {
+      scr_LogPrint(LPRINT_DEBUG, "LM-SASL: %s", msg);
+    }
+    else if (log_level & LM_LOG_LEVEL_SSL) {
+      scr_LogPrint(LPRINT_DEBUG, "LM-SSL: %s", msg);
+    }
+    g_free(msg);
+  }
+}
+
+
+void xmpp_connect(void)
+{
+  const char *username, *password, *resource, *servername, *ssl_fpr;
+  char *dynresource = NULL;
+  char fpr[16];
+  const char *proxy_host;
+  const char *resource_prefix = PACKAGE_NAME;
+  char *fjid;
+  int ssl, tls;
+  LmSSL *lssl;
+  unsigned int port;
+  unsigned int ping;
+  LmMessageHandler *handler;
+  GError *error = NULL;
+
+  if (lconnection && lm_connection_is_open(lconnection))
+    xmpp_disconnect();
+
+  servername = settings_opt_get("server");
+  username   = settings_opt_get("username");
+  password   = settings_opt_get("password");
+  resource   = settings_opt_get("resource");
+  proxy_host = settings_opt_get("proxy_host");
+  ssl_fpr    = settings_opt_get("ssl_fingerprint");
+
+  if (!servername) {
+    scr_LogPrint(LPRINT_LOGNORM, "Server name has not been specified!");
+    return;
+  }
+
+  if (!username) {
+    scr_LogPrint(LPRINT_LOGNORM, "User name has not been specified!");
+    return;
+  }
+  if (!password) {
+    scr_LogPrint(LPRINT_LOGNORM, "Password has not been specified!");
+    return;
+  }
+
+  lconnection = lm_connection_new_with_context
+          (NULL, g_main_loop_get_context(main_loop));
+
+  g_log_set_handler("LM", LM_LOG_LEVEL_ALL, lm_debug_handler, NULL);
+
+  ping = 40;
+  if (settings_opt_get("pinginterval"))
+    ping = (unsigned int) settings_opt_get_int("pinginterval");
+  lm_connection_set_keep_alive_rate(lconnection, ping);
+  scr_LogPrint(LPRINT_DEBUG, "Ping interval established: %d secs", ping);
+
+  lm_connection_set_disconnect_function(lconnection, connection_close_cb,
+                                        NULL, NULL);
+
+  handler = lm_message_handler_new(handle_messages, NULL, NULL);
+  lm_connection_register_message_handler(lconnection, handler,
+                                         LM_MESSAGE_TYPE_MESSAGE,
+                                         LM_HANDLER_PRIORITY_NORMAL);
+  lm_message_handler_unref(handler);
+
+  handler = lm_message_handler_new(handle_iq, NULL, NULL);
+  lm_connection_register_message_handler(lconnection, handler,
+                                         LM_MESSAGE_TYPE_IQ,
+                                         LM_HANDLER_PRIORITY_NORMAL);
+  lm_message_handler_unref(handler);
+
+  handler = lm_message_handler_new(handle_presence, NULL, NULL);
+  lm_connection_register_message_handler(lconnection, handler,
+                                         LM_MESSAGE_TYPE_PRESENCE,
+                                         LM_HANDLER_PRIORITY_LAST);
+  lm_message_handler_unref(handler);
+
+  handler = lm_message_handler_new(handle_s10n, NULL, NULL);
+  lm_connection_register_message_handler(lconnection, handler,
+                                         LM_MESSAGE_TYPE_PRESENCE,
+                                         LM_HANDLER_PRIORITY_NORMAL);
+  lm_message_handler_unref(handler);
+
+  /* Connect to server */
+  scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, "Connecting to server: %s",
+               servername);
+  if (!resource)
+    resource = resource_prefix;
+
+  if (!settings_opt_get("disable_random_resource")) {
+#if HAVE_ARC4RANDOM
+    dynresource = g_strdup_printf("%s.%08x", resource, arc4random());
+#else
+    unsigned int tab[2];
+    srand(time(NULL));
+    tab[0] = (unsigned int) (0xffff * (rand() / (RAND_MAX + 1.0)));
+    tab[1] = (unsigned int) (0xffff * (rand() / (RAND_MAX + 1.0)));
+    dynresource = g_strdup_printf("%s.%04x%04x", resource, tab[0], tab[1]);
+#endif
+    resource = dynresource;
+  }
+
+  port = (unsigned int) settings_opt_get_int("port");
+
+  if (port)
+    scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, " using port %d", port);
+  scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, " resource %s", resource);
+
+  if (proxy_host) {
+    int proxy_port = settings_opt_get_int("proxy_port");
+    if (proxy_port <= 0 || proxy_port > 65535) {
+      scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, "Invalid proxy port: %d",
+                   proxy_port);
+    } else {
+      const char *proxy_user, *proxy_pass;
+      LmProxy *lproxy;
+      proxy_user = settings_opt_get("proxy_user");
+      proxy_pass = settings_opt_get("proxy_pass");
+      // Proxy initialization
+      lproxy = lm_proxy_new_with_server(LM_PROXY_TYPE_HTTP,
+                                        proxy_host, proxy_port);
+      lm_proxy_set_username(lproxy, proxy_user);
+      lm_proxy_set_password(lproxy, proxy_pass);
+      lm_connection_set_proxy(lconnection, lproxy);
+      lm_proxy_unref(lproxy);
+      scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, " using proxy %s:%d",
+                   proxy_host, proxy_port);
+    }
+  }
+
+  fjid = compose_jid(username, servername, resource);
+  lm_connection_set_jid(lconnection, fjid);
+#if defined(HAVE_LIBOTR)
+  otr_init(fjid);
+#endif
+  g_free(fjid);
+  g_free(dynresource);
+
+  ssl = settings_opt_get_int("ssl");
+  tls = settings_opt_get_int("tls");
+
+  if (!lm_ssl_is_supported()) {
+    if (ssl || tls) {
+      scr_LogPrint(LPRINT_LOGNORM, "** Error: SSL is NOT available, "
+                   "please recompile loudmouth with SSL enabled.");
+      return;
+    }
+  }
+
+  if (ssl && tls) {
+    scr_LogPrint(LPRINT_LOGNORM, "You can only set ssl or tls, not both.");
+    return;
+  }
+
+  if (!port)
+    port = (ssl ? LM_CONNECTION_DEFAULT_PORT_SSL : LM_CONNECTION_DEFAULT_PORT);
+  lm_connection_set_port(lconnection, port);
+  scr_LogPrint(LPRINT_LOGNORM, "Port: %i\n", port);
+
+  if (ssl_fpr && (!hex_to_fingerprint(ssl_fpr, fpr))) {
+    scr_LogPrint(LPRINT_LOGNORM, "** Plese set the fingerprint in the format "
+                 "97:5C:00:3F:1D:77:45:25:E2:C5:70:EC:83:C8:87:EE");
+    return;
+  }
+
+  lssl = lm_ssl_new((ssl_fpr ? fpr : NULL), ssl_cb, NULL, NULL);
+  if (lssl) {
+    lm_ssl_use_starttls(lssl, !ssl, tls);
+    lm_connection_set_ssl(lconnection, lssl);
+    lm_ssl_unref(lssl);
+  } else if (ssl || tls) {
+    scr_LogPrint(LPRINT_LOGNORM, "** Error: Couldn't create SSL struct.");
+    return;
+  }
+
+  if (!lm_connection_open(lconnection, connection_open_cb,
+                          NULL, FALSE, &error)) {
+    _try_to_reconnect();
+    scr_LogPrint(LPRINT_LOGNORM, "Failed to open: %s\n", error->message);
+  }
+}
+
+//  insert_entity_capabilities(presence_stanza)
+// Entity Capabilities (XEP-0115)
+static void insert_entity_capabilities(LmMessageNode * x)
+{
+  LmMessageNode *y;
+  const char *ver = entity_version();
+  char *exts, *exts2;
+
+  exts = NULL;
+
+  y = lm_message_node_add_child(x, "c", NULL);
+  lm_message_node_set_attribute(y, "xmlns", NS_CAPS);
+  lm_message_node_set_attribute(y, "node", MCABBER_CAPS_NODE);
+  lm_message_node_set_attribute(y, "ver", ver);
+#ifdef JEP0085
+  if (!chatstates_disabled) {
+    exts2 = g_strjoin(" ", "csn", exts, NULL);
+    g_free(exts);
+    exts = exts2;
+  }
+#endif
+  if (!settings_opt_get_int("iq_last_disable")) {
+    exts2 = g_strjoin(" ", "iql", exts, NULL);
+    g_free(exts);
+    exts = exts2;
+  }
+  if (exts) {
+    lm_message_node_set_attribute(y, "ext", exts);
+    g_free(exts);
+  }
+}
+
+void xmpp_disconnect(void)
+{
+  if (!lconnection || !lm_connection_is_authenticated(lconnection))
+    return;
+
+  // Launch pre-disconnect internal hook
+  hook_execute_internal("hook-pre-disconnect");
+  // Announce it to  everyone else
+  xmpp_setstatus(offline, NULL, "", FALSE);
+  lm_connection_close(lconnection, NULL);
+}
+
+void xmpp_setstatus(enum imstatus st, const char *recipient, const char *msg,
+                  int do_not_sign)
+{
+  LmMessage *m;
+
+  if (msg) {
+    // The status message has been specified.  We'll use it, unless it is
+    // "-" which is a special case (option meaning "no status message").
+    if (!strcmp(msg, "-"))
+      msg = "";
+  } else {
+    // No status message specified; we'll use:
+    // a) the default status message (if provided by the user);
+    // b) the current status message;
+    // c) no status message (i.e. an empty one).
+    msg = settings_get_status_msg(st);
+    if (!msg) {
+      if (mystatusmsg)
+        msg = mystatusmsg;
+      else
+        msg = "";
+    }
+  }
+
+  // Only send the packet if we're online.
+  // (But we want to update internal status even when disconnected,
+  // in order to avoid some problems during network failures)
+  if (lm_connection_is_authenticated(lconnection)) {
+    const char *s_msg = (st != invisible ? msg : NULL);
+    m = lm_message_new_presence(st, recipient, s_msg);
+    insert_entity_capabilities(m->node); // Entity Capabilities (XEP-0115)
+#ifdef HAVE_GPGME
+    if (!do_not_sign && gpg_enabled()) {
+      char *signature;
+      signature = gpg_sign(s_msg ? s_msg : "");
+      if (signature) {
+        LmMessageNode *y;
+        y = lm_message_node_add_child(m->node, "x", signature);
+        lm_message_node_set_attribute(y, "xmlns", NS_SIGNED);
+        g_free(signature);
+      }
+    }
+#endif
+    lm_connection_send(lconnection, m, NULL);
+    lm_message_unref(m);
+  }
+
+  // If we didn't change our _global_ status, we are done
+  if (recipient) return;
+
+  if (lm_connection_is_authenticated(lconnection)) {
+    // Send presence to chatrooms
+    if (st != invisible) {
+      struct T_presence room_presence;
+      room_presence.st = st;
+      room_presence.msg = msg;
+      foreach_buddy(ROSTER_TYPE_ROOM, &roompresence, &room_presence);
+    }
+
+    // We'll have to update the roster if we switch to/from offline because
+    // we don't know the presences of buddies when offline...
+    if (mystatus == offline || st == offline)
+      update_roster = TRUE;
+
+    hk_mystatuschange(0, mystatus, st, (st != invisible ? msg : ""));
+    mystatus = st;
+  }
+
+  if (st)
+    mywantedstatus = st;
+
+  if (msg != mystatusmsg) {
+    g_free(mystatusmsg);
+    if (*msg)
+      mystatusmsg = g_strdup(msg);
+    else
+      mystatusmsg = NULL;
+  }
+
+  if (!Autoaway)
+    update_last_use();
+
+  // Update status line
+  scr_UpdateMainStatus(TRUE);
+}
+
+
+enum imstatus xmpp_getstatus(void)
+{
+  return mystatus;
+}
+
+const char *xmpp_getstatusmsg(void)
+{
+  return mystatusmsg;
+}
+
+//  xmpp_setprevstatus()
+// Set previous status.  This wrapper function is used after a disconnection.
+void xmpp_setprevstatus(void)
+{
+  xmpp_setstatus(mywantedstatus, NULL, mystatusmsg, FALSE);
+}
+
+//  send_storage(store)
+// Send the node "store" to update the server.
+// Note: the sender should check we're online.
+void send_storage(LmMessageNode *store)
+{
+  LmMessage *iq;
+  LmMessageNode *query;
+
+  if (!rosternotes) return;
+
+  iq = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_IQ,
+                                    LM_MESSAGE_SUB_TYPE_SET);
+  query = lm_message_node_add_child(iq->node, "query", NULL);
+  lm_message_node_set_attribute(query, "xmlns", NS_PRIVATE);
+  lm_message_node_insert_childnode(query, store);
+
+  lm_connection_send(lconnection, iq, NULL);
+  lm_message_unref(iq);
+}
+
+
+//  xmpp_is_bookmarked(roomjid)
+// Return TRUE if there's a bookmark for the given jid.
+guint xmpp_is_bookmarked(const char *bjid)
+{
+  LmMessageNode *x;
+
+  if (!bookmarks)
+    return FALSE;
+
+  // Walk through the storage bookmark tags
+  for (x = bookmarks->children ; x; x = x->next) {
+    // If the node is a conference item, check the jid.
+    if (x->name && !strcmp(x->name, "conference")) {
+      const char *fjid = lm_message_node_get_attribute(x, "jid");
+      if (fjid && !strcasecmp(bjid, fjid))
+        return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+//  xmpp_get_bookmark_nick(roomjid)
+// Return the room nickname if it is present in a bookmark.
+const char *xmpp_get_bookmark_nick(const char *bjid)
+{
+  LmMessageNode *x;
+
+  if (!bookmarks || !bjid)
+    return NULL;
+
+  // Walk through the storage bookmark tags
+  for (x = bookmarks->children ; x; x = x->next) {
+    // If the node is a conference item, check the jid.
+    if (x->name && !strcmp(x->name, "conference")) {
+      const char *fjid = lm_message_node_get_attribute(x, "jid");
+      if (fjid && !strcasecmp(bjid, fjid))
+        return lm_message_node_get_child_value(x, "nick");
+    }
+  }
+  return NULL;
+}
+
+
+//  xmpp_get_all_storage_bookmarks()
+// Return a GSList with all storage bookmarks.
+// The caller should g_free the list (not the MUC jids).
+GSList *xmpp_get_all_storage_bookmarks(void)
+{
+  LmMessageNode *x;
+  GSList *sl_bookmarks = NULL;
+
+  // If we have no bookmarks, probably the server doesn't support them.
+  if (!bookmarks)
+    return NULL;
+
+  // Walk through the storage bookmark tags
+  for (x = bookmarks->children ; x; x = x->next) {
+    // If the node is a conference item, let's add the note to our list.
+    if (x->name && !strcmp(x->name, "conference")) {
+      struct bookmark *bm_elt;
+      const char *autojoin, *name, *nick;
+      const char *fjid = lm_message_node_get_attribute(x, "jid");
+      if (!fjid)
+        continue;
+      bm_elt = g_new0(struct bookmark, 1);
+      bm_elt->roomjid = g_strdup(fjid);
+      autojoin = lm_message_node_get_attribute(x, "autojoin");
+      nick = lm_message_node_get_attribute(x, "nick");
+      name = lm_message_node_get_attribute(x, "name");
+      if (autojoin && !strcmp(autojoin, "1"))
+        bm_elt->autojoin = 1;
+      if (nick)
+        bm_elt->nick = g_strdup(nick);
+      if (name)
+        bm_elt->name = g_strdup(name);
+      sl_bookmarks = g_slist_append(sl_bookmarks, bm_elt);
+    }
+  }
+  return sl_bookmarks;
+}
+
+//  xmpp_set_storage_bookmark(roomid, name, nick, passwd, autojoin,
+//                          printstatus, autowhois)
+// Update the private storage bookmarks: add a conference room.
+// If name is nil, we remove the bookmark.
+void xmpp_set_storage_bookmark(const char *roomid, const char *name,
+                               const char *nick, const char *passwd,
+                               int autojoin, enum room_printstatus pstatus,
+                               enum room_autowhois awhois)
+{
+  LmMessageNode *x;
+  bool changed = FALSE;
+
+  if (!roomid)
+    return;
+
+  // If we have no bookmarks, probably the server doesn't support them.
+  if (!bookmarks) {
+    scr_LogPrint(LPRINT_NORMAL,
+                 "Sorry, your server doesn't seem to support private storage.");
+    return;
+  }
+
+  // Walk through the storage tags
+  for (x = bookmarks->children ; x; x = x->next) {
+    // If the current node is a conference item, see if we have to replace it.
+    if (x->name && !strcmp(x->name, "conference")) {
+      const char *fjid = lm_message_node_get_attribute(x, "jid");
+      if (!fjid)
+        continue;
+      if (!strcmp(fjid, roomid)) {
+        // We've found a bookmark for this room.  Let's hide it and we'll
+        // create a new one.
+        lm_message_node_hide(x);
+        changed = TRUE;
+        if (!name)
+          scr_LogPrint(LPRINT_LOGNORM, "Deleting bookmark...");
+      }
+    }
+  }
+
+  // Let's create a node/bookmark for this roomid, if the name is not NULL.
+  if (name) {
+    x = lm_message_node_add_child(bookmarks, "conference", NULL);
+    lm_message_node_set_attributes(x,
+                                   "jid", roomid,
+                                   "name", name,
+                                   "autojoin", autojoin ? "1" : "0",
+                                   NULL);
+    if (nick)
+      lm_message_node_add_child(x, "nick", nick);
+    if (passwd)
+      lm_message_node_add_child(x, "password", passwd);
+    if (pstatus)
+      lm_message_node_add_child(x, "print_status", strprintstatus[pstatus]);
+    if (awhois)
+      lm_message_node_add_child(x, "autowhois",
+                                (awhois == autowhois_on) ? "1" : "0");
+    changed = TRUE;
+    scr_LogPrint(LPRINT_LOGNORM, "Updating bookmarks...");
+  }
+
+  if (!changed)
+    return;
+
+  if (lm_connection_is_authenticated(lconnection))
+    send_storage(bookmarks);
+  else
+    scr_LogPrint(LPRINT_LOGNORM,
+                 "Warning: you're not connected to the server.");
+}
+
+static struct annotation *parse_storage_rosternote(LmMessageNode *notenode)
+{
+  const char *p;
+  struct annotation *note = g_new0(struct annotation, 1);
+  p = lm_message_node_get_attribute(notenode, "cdate");
+  if (p)
+    note->cdate = from_iso8601(p, 1);
+  p = lm_message_node_get_attribute(notenode, "mdate");
+  if (p)
+    note->mdate = from_iso8601(p, 1);
+  note->text = g_strdup(lm_message_node_get_value(notenode));
+  note->jid = g_strdup(lm_message_node_get_attribute(notenode, "jid"));
+  return note;
+}
+
+//  xmpp_get_all_storage_rosternotes()
+// Return a GSList with all storage annotations.
+// The caller should g_free the list and its contents.
+GSList *xmpp_get_all_storage_rosternotes(void)
+{
+  LmMessageNode *x;
+  GSList *sl_notes = NULL;
+
+  // If we have no rosternotes, probably the server doesn't support them.
+  if (!rosternotes)
+    return NULL;
+
+  // Walk through the storage rosternotes tags
+  for (x = rosternotes->children ; x; x = x->next) {
+    struct annotation *note;
+
+    // We want a note item
+    if (!x->name || strcmp(x->name, "note"))
+      continue;
+    // Just in case, check the jid...
+    if (!lm_message_node_get_attribute(x, "jid"))
+      continue;
+    // Ok, let's add the note to our list
+    note = parse_storage_rosternote(x);
+    sl_notes = g_slist_append(sl_notes, note);
+  }
+  return sl_notes;
+}
+
+//  xmpp_get_storage_rosternotes(barejid, silent)
+// Return the annotation associated with this jid.
+// If silent is TRUE, no warning is displayed when rosternotes is disabled
+// The caller should g_free the string and structure after use.
+struct annotation *xmpp_get_storage_rosternotes(const char *barejid, int silent)
+{
+  LmMessageNode *x;
+
+  if (!barejid)
+    return NULL;
+
+  // If we have no rosternotes, probably the server doesn't support them.
+  if (!rosternotes) {
+    if (!silent)
+      scr_LogPrint(LPRINT_NORMAL, "Sorry, "
+                   "your server doesn't seem to support private storage.");
+    return NULL;
+  }
+
+  // Walk through the storage rosternotes tags
+  for (x = rosternotes->children ; x; x = x->next) {
+    const char *fjid;
+    // We want a note item
+    if (!x->name || strcmp(x->name, "note"))
+      continue;
+    // Just in case, check the jid...
+    fjid = lm_message_node_get_attribute(x, "jid");
+    if (fjid && !strcmp(fjid, barejid)) // We've found a note for this contact.
+      return parse_storage_rosternote(x);
+  }
+  return NULL;  // No note found
+}
+
+//  xmpp_set_storage_rosternotes(barejid, note)
+// Update the private storage rosternotes: add/delete a note.
+// If note is nil, we remove the existing note.
+void xmpp_set_storage_rosternotes(const char *barejid, const char *note)
+{
+  LmMessageNode *x;
+  bool changed = FALSE;
+  const char *cdate = NULL;
+
+  if (!barejid)
+    return;
+
+  // If we have no rosternotes, probably the server doesn't support them.
+  if (!rosternotes) {
+    scr_LogPrint(LPRINT_NORMAL,
+                 "Sorry, your server doesn't seem to support private storage.");
+    return;
+  }
+
+  // Walk through the storage tags
+  for (x = rosternotes->children ; x; x = x->next) {
+    // If the current node is a conference item, see if we have to replace it.
+    if (x->name && !strcmp(x->name, "note")) {
+      const char *fjid = lm_message_node_get_attribute(x, "jid");
+      if (!fjid)
+        continue;
+      if (!strcmp(fjid, barejid)) {
+        // We've found a note for this jid.  Let's hide it and we'll
+        // create a new one.
+        cdate = lm_message_node_get_attribute(x, "cdate");
+        lm_message_node_hide(x);
+        changed = TRUE;
+        break;
+      }
+    }
+  }
+
+  // Let's create a node for this jid, if the note is not NULL.
+  if (note) {
+    char mdate[20];
+    time_t now;
+    time(&now);
+    to_iso8601(mdate, now);
+    if (!cdate)
+      cdate = mdate;
+    x = lm_message_node_add_child(rosternotes, "note", note);
+    lm_message_node_set_attributes(x,
+                                   "jid", barejid,
+                                   "cdate", cdate,
+                                   "mdate", mdate,
+                                   NULL);
+    changed = TRUE;
+  }
+
+  if (!changed)
+    return;
+
+  if (lm_connection_is_authenticated(lconnection))
+    send_storage(rosternotes);
+  else
+    scr_LogPrint(LPRINT_LOGNORM,
+                 "Warning: you're not connected to the server.");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/xmpp.h	Sun Oct 11 15:38:32 2009 +0200
@@ -0,0 +1,80 @@
+#ifndef __XMPP_H__
+#define __XMPP_H__ 1
+
+#include <loudmouth/loudmouth.h>
+#include "roster.h"
+
+enum iqreq_type {
+  iqreq_none,
+  iqreq_version,
+  iqreq_time,
+  iqreq_last,
+  iqreq_vcard
+};
+
+struct annotation {
+  time_t cdate;
+  time_t mdate;
+  gchar *jid;
+  gchar *text;
+};
+
+struct bookmark {
+  gchar *roomjid;
+  gchar *name;
+  gchar *nick;
+  guint autojoin;
+  /* enum room_printstatus pstatus; */
+  /* enum room_autowhois awhois; */
+};
+
+extern LmConnection* lconnection;
+extern LmSSL* lssl;
+extern GMainLoop *main_loop;
+
+void xmpp_connect(void);
+void xmpp_disconnect(void);
+
+void xmpp_room_join(const char *room, const char *nickname, const char *passwd);
+int xmpp_room_setattrib(const char *roomid, const char *fjid,
+                        const char *nick, struct role_affil ra,
+                        const char *reason);
+void xmpp_room_invite(const char *room, const char *fjid, const char *reason);
+void xmpp_room_unlock(const char *room);
+void xmpp_room_destroy(const char *room, const char *venue, const char *reason);
+
+void xmpp_addbuddy(const char *bjid, const char *name, const char *group);
+void xmpp_updatebuddy(const char *bjid, const char *name, const char *group);
+void xmpp_delbuddy(const char *bjid);
+
+void xmpp_send_msg(const char *fjid, const char *text, int type,
+                   const char *subject, gboolean otrinject, gint *encrypted,
+                   LmMessageSubType type_overwrite);
+
+void xmpp_send_s10n(const char *bjid, LmMessageSubType type);
+
+enum imstatus xmpp_getstatus(void);
+const char *xmpp_getstatusmsg(void);
+void xmpp_setprevstatus(void);
+
+void xmpp_setstatus(enum imstatus st, const char *recipient,
+                    const char *msg, int do_not_sign);
+
+void xmpp_send_chatstate(gpointer buddy, guint chatstate);
+
+GSList *xmpp_get_all_storage_bookmarks(void);
+GSList *xmpp_get_all_storage_rosternotes(void);
+void xmpp_set_storage_bookmark(const char *roomid, const char *name,
+                               const char *nick, const char *passwd,
+                               int autojoin, enum room_printstatus pstatus,
+                               enum room_autowhois awhois);
+struct annotation *xmpp_get_storage_rosternotes(const char *barejid,
+                                                int silent);
+void xmpp_set_storage_rosternotes(const char *barejid, const char *note);
+guint xmpp_is_bookmarked(const char *bjid);
+const char *xmpp_get_bookmark_nick(const char *bjid);
+
+void xmpp_request(const char *fjid, enum iqreq_type reqtype);
+void request_vcard(const char *bjid);
+void xmpp_request_storage(const gchar *storage);
+#endif /* __XMPP_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/xmpp_defines.h	Sun Oct 11 15:38:32 2009 +0200
@@ -0,0 +1,77 @@
+#ifndef __XMPP_DEFINES_H__
+#define __XMPP_DEFINES_H__ 1
+
+#define NS_CLIENT    "jabber:client"
+#define NS_SERVER    "jabber:server"
+#define NS_DIALBACK  "jabber:server:dialback"
+#define NS_AUTH      "jabber:iq:auth"
+#define NS_AUTH_CRYPT "jabber:iq:auth:crypt"
+#define NS_REGISTER  "jabber:iq:register"
+#define NS_ROSTER    "jabber:iq:roster"
+#define NS_OFFLINE   "jabber:x:offline"
+#define NS_AGENT     "jabber:iq:agent"
+#define NS_AGENTS    "jabber:iq:agents"
+#define NS_DELAY     "jabber:x:delay"
+#define NS_VERSION   "jabber:iq:version"
+#define NS_TIME      "jabber:iq:time"
+#define NS_VCARD     "vcard-temp"
+#define NS_PRIVATE   "jabber:iq:private"
+#define NS_SEARCH    "jabber:iq:search"
+#define NS_OOB       "jabber:iq:oob"
+#define NS_XOOB      "jabber:x:oob"
+#define NS_ADMIN     "jabber:iq:admin"
+#define NS_FILTER    "jabber:iq:filter"
+#define NS_AUTH_0K   "jabber:iq:auth:0k"
+#define NS_BROWSE    "jabber:iq:browse"
+#define NS_EVENT     "jabber:x:event"
+#define NS_CONFERENCE "jabber:iq:conference"
+#define NS_SIGNED    "jabber:x:signed"
+#define NS_ENCRYPTED "jabber:x:encrypted"
+#define NS_GATEWAY   "jabber:iq:gateway"
+#define NS_LAST      "jabber:iq:last"
+#define NS_ENVELOPE  "jabber:x:envelope"
+#define NS_EXPIRE    "jabber:x:expire"
+#define NS_XHTML     "http://www.w3.org/1999/xhtml"
+#define NS_DISCO_INFO "http://jabber.org/protocol/disco#info"
+#define NS_DISCO_ITEMS "http://jabber.org/protocol/disco#items"
+#define NS_IQ_AUTH    "http://jabber.org/features/iq-auth"
+#define NS_REGISTER_FEATURE "http://jabber.org/features/iq-register"
+
+#define NS_CAPS       "http://jabber.org/protocol/caps"
+#define NS_CHATSTATES "http://jabber.org/protocol/chatstates"
+#define NS_COMMANDS   "http://jabber.org/protocol/commands"
+#define NS_MUC        "http://jabber.org/protocol/muc"
+
+#define NS_XDBGINSERT "jabber:xdb:ginsert"
+#define NS_XDBNSLIST  "jabber:xdb:nslist"
+
+#define NS_XMPP_STANZAS "urn:ietf:params:xml:ns:xmpp-stanzas"
+#define NS_XMPP_TLS  "urn:ietf:params:xml:ns:xmpp-tls"
+#define NS_XMPP_STREAMS "urn:ietf:params:xml:ns:xmpp-streams"
+
+#define NS_XMPP_DELAY "urn:xmpp:delay"
+#define NS_XMPP_TIME  "urn:xmpp:time"
+#define NS_PING       "urn:xmpp:ping"
+
+#define NS_JABBERD_STOREDPRESENCE "http://jabberd.org/ns/storedpresence"
+#define NS_JABBERD_HISTORY "http://jabberd.org/ns/history"
+
+#define XMPP_ERROR_REDIRECT              302
+#define XMPP_ERROR_BAD_REQUEST           400
+#define XMPP_ERROR_NOT_AUTHORIZED        401
+#define XMPP_ERROR_PAYMENT_REQUIRED      402
+#define XMPP_ERROR_FORBIDDEN             403
+#define XMPP_ERROR_NOT_FOUND             404
+#define XMPP_ERROR_NOT_ALLOWED           405
+#define XMPP_ERROR_NOT_ACCEPTABLE        406
+#define XMPP_ERROR_REGISTRATION_REQUIRED 407
+#define XMPP_ERROR_REQUEST_TIMEOUT       408
+#define XMPP_ERROR_CONFLICT              409
+#define XMPP_ERROR_INTERNAL_SERVER_ERROR 500
+#define XMPP_ERROR_NOT_IMPLEMENTED       501
+#define XMPP_ERROR_REMOTE_SERVER_ERROR   502
+#define XMPP_ERROR_SERVICE_UNAVAILABLE   503
+#define XMPP_ERROR_REMOTE_SERVER_TIMEOUT 504
+#define XMPP_ERROR_DISCONNECTED          510
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/xmpp_helper.c	Sun Oct 11 15:38:32 2009 +0200
@@ -0,0 +1,290 @@
+/*
+ * xmpp_helper.c     -- Jabber protocol helper functions
+ *
+ * Copyright (C) 2008 Frank Zschockelt <mcabber@freakysoft.de>
+ * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
+ * Some parts initially came from the centericq project:
+ * Copyright (C) 2002-2005 by Konstantin Klyagin <konst@konst.org.ua>
+ * Some small parts come from the Pidgin project <http://pidgin.im/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include "xmpp_helper.h"
+
+time_t iqlast; // last message/status change time
+
+const gchar* lm_message_node_get_child_value(LmMessageNode *node,
+                                             const gchar *child)
+{
+  LmMessageNode *tmp;
+  tmp = lm_message_node_find_child(node, child);
+  if (tmp)
+    return lm_message_node_get_value(tmp);
+  else return NULL;
+}
+
+static LmMessageNode *hidden = NULL;
+
+void lm_message_node_hide(LmMessageNode *node)
+{
+  LmMessageNode *parent = node->parent, *prev_sibling = node->prev;
+
+  if (hidden) {
+    hidden->children = hidden->next = hidden->prev = hidden->parent = NULL;
+    lm_message_node_unref(hidden);
+  }
+
+  if (parent->children == node)
+    parent->children = node->next;
+  if (prev_sibling)
+    prev_sibling->next = node->next;
+  if (node->next)
+    node->next->prev = prev_sibling;
+}
+
+//maybe not a good idea, because it uses internals of loudmouth...
+//it's used for rosternotes/bookmarks
+LmMessageNode *lm_message_node_new(const gchar *name, const gchar *xmlns)
+{
+  LmMessageNode *node;
+
+  node = g_new0 (LmMessageNode, 1);
+  node->name       = g_strdup (name);
+  node->value      = NULL;
+  node->raw_mode   = FALSE;
+  node->attributes = NULL;
+  node->next       = NULL;
+  node->prev       = NULL;
+  node->parent     = NULL;
+  node->children   = NULL;
+
+  node->ref_count  = 1;
+  lm_message_node_set_attribute(node, "xmlns", xmlns);
+  return node;
+}
+
+void lm_message_node_insert_childnode(LmMessageNode *node,
+                                      LmMessageNode *child)
+{
+  LmMessageNode *x;
+  lm_message_node_deep_ref(child);
+
+  if (node->children == NULL)
+    node->children = child;
+  else {
+    for (x = node->children; x->next; x = x->next)
+      ;
+    x->next = child;
+  }
+}
+
+void lm_message_node_deep_ref(LmMessageNode *node)
+{
+  if (node == NULL)
+    return;
+  lm_message_node_ref(node);
+  lm_message_node_deep_ref(node->next);
+  lm_message_node_deep_ref(node->children);
+}
+
+const gchar* lm_message_get_from(LmMessage *m)
+{
+  return lm_message_node_get_attribute(m->node, "from");
+}
+
+const gchar* lm_message_get_id(LmMessage *m)
+{
+  return lm_message_node_get_attribute(m->node, "id");
+}
+
+static LmMessage *lm_message_new_iq_from_query(LmMessage *m,
+                                               LmMessageSubType type)
+{
+  LmMessage *new;
+  const char *from = lm_message_node_get_attribute(m->node, "from");
+  const char *id = lm_message_node_get_attribute(m->node, "id");
+
+  new = lm_message_new_with_sub_type(from, LM_MESSAGE_TYPE_IQ,
+                                     type);
+  if (id)
+    lm_message_node_set_attribute(new->node, "id", id);
+
+  return new;
+}
+
+//  entity_version()
+// Return a static version string for Entity Capabilities.
+// It should be specific to the client version, please change the id
+// if you alter mcabber's disco support (or add something to the version
+// number) so that it doesn't conflict with the official client.
+const char *entity_version(void)
+{
+  static char *ver;
+  const char *PVERSION = PACKAGE_VERSION; // "+xxx";
+
+  if (ver)
+    return ver;
+
+#ifdef HGCSET
+  ver = g_strdup_printf("%s-%s", PVERSION, HGCSET);
+#else
+  ver = g_strdup(PVERSION);
+#endif
+
+  return ver;
+}
+
+inline static LmMessageNode *lm_message_node_find_xmlns(LmMessageNode *node,
+                                                        const char *xmlns)
+{
+  LmMessageNode *x;
+  const char *p;
+
+  for (x = node->children ; x; x = x->next) {
+    if ((p = lm_message_node_get_attribute(x, "xmlns")) && !strcmp(p, xmlns))
+      break;
+  }
+  return x;
+}
+
+static time_t lm_message_node_get_timestamp(LmMessageNode *node)
+{
+  LmMessageNode *x;
+  const char *p;
+
+  x = lm_message_node_find_xmlns(node, NS_XMPP_DELAY);
+  if (x && (!strcmp(x->name, "delay")) &&
+      (p = lm_message_node_get_attribute(x, "stamp")) != NULL)
+    return from_iso8601(p, 1);
+  x = lm_message_node_find_xmlns(node, NS_DELAY);
+  if (x && (p = lm_message_node_get_attribute(x, "stamp")) != NULL)
+    return from_iso8601(p, 1);
+  return 0;
+}
+
+//  lm_message_new_presence(status, recipient, message)
+// Create an xmlnode with default presence attributes
+// Note: the caller must free the node after use
+static LmMessage *lm_message_new_presence(enum imstatus st,
+                                           const char *recipient,
+                                           const char *msg)
+{
+  unsigned int prio;
+  LmMessage *x = lm_message_new(recipient, LM_MESSAGE_TYPE_PRESENCE);
+
+  switch(st) {
+    case away:
+    case notavail:
+    case dontdisturb:
+    case freeforchat:
+        lm_message_node_add_child(x->node, "show", imstatus_showmap[st]);
+        break;
+
+    case invisible:
+        lm_message_node_set_attribute(x->node, "type", "invisible");
+        break;
+
+    case offline:
+        lm_message_node_set_attribute(x->node, "type", "unavailable");
+        break;
+
+    default:
+        break;
+  }
+
+  if (st == away || st == notavail)
+    prio = settings_opt_get_int("priority_away");
+  else
+    prio = settings_opt_get_int("priority");
+
+  if (prio) {
+    char strprio[8];
+    snprintf(strprio, 8, "%d", (int)prio);
+    lm_message_node_add_child(x->node, "priority", strprio);
+  }
+
+  if (msg)
+    lm_message_node_add_child(x->node, "status", msg);
+
+  return x;
+}
+
+static const char *defaulterrormsg(guint code)
+{
+  int i = 0;
+
+  for (i = 0; xmpp_errors[i].code; ++i) {
+    if (xmpp_errors[i].code == code)
+      return xmpp_errors[i].meaning;
+  }
+  return NULL;
+}
+
+//  display_server_error(x)
+// Display the error to the user
+// x: error tag xmlnode pointer
+void display_server_error(LmMessageNode *x)
+{
+  const char *desc = NULL, *p=NULL, *s;
+  char *sdesc, *tmp;
+  int code = 0;
+
+  if (!x) return;
+
+  /* RFC3920:
+   *    The <error/> element:
+   *       o  MUST contain a child element corresponding to one of the defined
+   *          stanza error conditions specified below; this element MUST be
+   *          qualified by the 'urn:ietf:params:xml:ns:xmpp-stanzas' namespace.
+   */
+  if (x->children)
+    p = x->children->name;
+  if (p)
+    scr_LogPrint(LPRINT_LOGNORM, "Received error packet [%s]", p);
+
+  // For backward compatibility
+  if ((s = lm_message_node_get_attribute(x, "code")) != NULL) {
+    code = atoi(s);
+    // Default message
+    desc = defaulterrormsg(code);
+  }
+
+  // Error tag data is better, if available
+  s = lm_message_node_get_value(x);
+  if (s && *s) desc = s;
+
+  // And sometimes there is a text message
+  s = lm_message_node_get_child_value(x, "text");
+
+  if (s && *s) desc = s;
+
+  // If we still have no description, let's give up
+  if (!desc)
+    return;
+
+  // Strip trailing newlines
+  sdesc = g_strdup(desc);
+  for (tmp = sdesc; *tmp; tmp++) ;
+  if (tmp > sdesc)
+    tmp--;
+  while (tmp >= sdesc && (*tmp == '\n' || *tmp == '\r'))
+    *tmp-- = '\0';
+
+  scr_LogPrint(LPRINT_LOGNORM, "Error code from server: %d %s", code, sdesc);
+  g_free(sdesc);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/xmpp_helper.h	Sun Oct 11 15:38:32 2009 +0200
@@ -0,0 +1,23 @@
+#ifndef __XMPPHELPER_H__
+#define __XMPPHELPER_H__ 1
+
+extern time_t iqlast;           /* last message/status change time */
+
+struct T_presence {
+  enum imstatus st;
+  const char *msg;
+};
+
+LmMessageNode * lm_message_node_new(const gchar *name, const gchar *xmlns);
+const gchar* lm_message_node_get_child_value(LmMessageNode * node,
+                                             const gchar *child);
+void lm_message_node_hide(LmMessageNode * node);
+void lm_message_node_insert_childnode(LmMessageNode * node,
+                                      LmMessageNode *child);
+void lm_message_node_deep_ref(LmMessageNode * node);
+
+/* XEP-0115 (Entity Capabilities) node */
+#define MCABBER_CAPS_NODE "http://mcabber.com/caps"
+const char *entity_version(void);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/xmpp_iq.c	Sun Oct 11 15:38:32 2009 +0200
@@ -0,0 +1,820 @@
+/* See xmpp.c file for copyright and license details. */
+
+static LmHandlerResult handle_iq_command_set_status(LmMessageHandler *h,
+                                                    LmConnection *c,
+                                                    LmMessage *m,
+                                                    gpointer ud);
+
+static LmHandlerResult handle_iq_command_leave_groupchats(LmMessageHandler *h,
+                                                          LmConnection *c,
+                                                          LmMessage *m,
+                                                          gpointer ud);
+
+inline double seconds_since_last_use(void);
+
+struct adhoc_command {
+  char *name;
+  char *description;
+  bool only_for_self;
+  LmHandleMessageFunction callback;
+};
+
+const struct adhoc_command adhoc_command_list[] = {
+  { "http://jabber.org/protocol/rc#set-status",
+    "Change client status",
+    1,
+    &handle_iq_command_set_status },
+  { "http://jabber.org/protocol/rc#leave-groupchats",
+    "Leave groupchat(s)",
+    1,
+    &handle_iq_command_leave_groupchats },
+  { NULL, NULL, 0, NULL },
+};
+
+struct adhoc_status {
+  char *name;   // the name used by adhoc
+  char *description;
+  char *status; // the string, used by setstus
+};
+// It has to match imstatus of roster.h!
+const struct adhoc_status adhoc_status_list[] = {
+  {"offline", "Offline", "offline"},
+  {"online", "Online", "avail"},
+  {"chat", "Chat", "free"},
+  {"dnd", "Do not disturb", "dnd"},
+  {"xd", "Extended away", "notavail"},
+  {"away", "Away", "away"},
+  {"invisible", "Invisible", "invisible"},
+  {NULL, NULL, NULL},
+};
+
+static char *generate_session_id(char *prefix)
+{
+  char *result;
+  static int counter = 0;
+  counter++;
+  // TODO better use timestamp?
+  result = g_strdup_printf("%s-%i", prefix, counter);
+  return result;
+}
+
+static LmMessage *lm_message_new_iq_error(LmMessage *m, guint error)
+{
+  LmMessage *r;
+  LmMessageNode *err;
+  int i;
+
+  for (i = 0; xmpp_errors[i].code; ++i)
+    if (xmpp_errors[i].code == error)
+      break;
+  g_return_val_if_fail(xmpp_errors[i].code > 0, NULL);
+
+  r = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_ERROR);
+  err = lm_message_node_add_child(r->node, "error", NULL);
+  lm_message_node_set_attribute(err, "code", xmpp_errors[i].code_str);
+  lm_message_node_set_attribute(err, "type", xmpp_errors[i].type);
+  lm_message_node_set_attribute
+          (lm_message_node_add_child(err,
+                                     xmpp_errors[i].condition, NULL),
+           "xmlns", NS_XMPP_STANZAS);
+
+  return r;
+}
+
+static void send_iq_error(LmConnection *c, LmMessage *m, guint error)
+{
+  LmMessage *r;
+  r = lm_message_new_iq_error(m, error);
+  lm_connection_send(c, r, NULL);
+  lm_message_unref(r);
+}
+
+static void lm_message_node_add_dataform_result(LmMessageNode *node,
+                                                const char *message)
+{
+  LmMessageNode *x, *field;
+
+  x = lm_message_node_add_child(node, "x", NULL);
+  lm_message_node_set_attributes(x,
+                                 "type", "result",
+                                 "xmlns", "jabber:x:data",
+                                 NULL);
+  field = lm_message_node_add_child(x, "field", NULL);
+  lm_message_node_set_attributes(field,
+                                 "type", "text-single",
+                                 "var", "message",
+                                 NULL);
+  lm_message_node_add_child(field, "value", message);
+}
+
+static LmHandlerResult handle_iq_commands_list(LmMessageHandler *h,
+                                               LmConnection *c,
+                                               LmMessage *m, gpointer ud)
+{
+  LmMessage *iq;
+  LmMessageNode *query;
+  const char *requester_jid;
+  const struct adhoc_command *command;
+  const char *node;
+  gboolean from_self;
+
+  iq = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT);
+  query = lm_message_node_add_child(iq->node, "query", NULL);
+  node = lm_message_node_get_attribute
+          (lm_message_node_get_child(m->node, "query"),
+           "node");
+  if (node)
+    lm_message_node_set_attribute(query, "node", node);
+
+  requester_jid = lm_message_get_from(m);
+  from_self = jid_equal(lm_connection_get_jid(c), requester_jid);
+
+  for (command = adhoc_command_list ; command->name ; command++) {
+    if (!command->only_for_self || from_self) {
+      lm_message_node_set_attributes
+              (lm_message_node_add_child(query, "item", NULL),
+               "node", command->name,
+               "name", command->description,
+               "jid", lm_connection_get_jid(c),
+               NULL);
+    }
+  }
+
+  lm_connection_send(c, iq, NULL);
+  lm_message_unref(iq);
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+static LmHandlerResult handle_iq_command_set_status(LmMessageHandler *h,
+                                                    LmConnection *c,
+                                                    LmMessage *m, gpointer ud)
+{
+  const char *action, *node;
+  char *sessionid;
+  LmMessage *iq;
+  LmMessageNode *command, *x, *y;
+  const struct adhoc_status *s;
+
+  x = lm_message_node_get_child(m->node, "command");
+  action = lm_message_node_get_attribute(x, "action");
+  node = lm_message_node_get_attribute(x, "node");
+  sessionid = (char *)lm_message_node_get_attribute(x, "sessionid");
+
+  iq = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT);
+  command = lm_message_node_add_child(iq->node, "command", NULL);
+  lm_message_node_set_attribute(command, "node", node);
+  lm_message_node_set_attribute(command, "xmlns", NS_COMMANDS);
+
+  if (!sessionid) {
+    sessionid = generate_session_id("set-status");
+    lm_message_node_set_attribute(command, "sessionid", sessionid);
+    g_free(sessionid);
+    sessionid = NULL;
+    lm_message_node_set_attribute(command, "status", "executing");
+
+    x = lm_message_node_add_child(command, "x", NULL);
+    lm_message_node_set_attribute(x, "type", "form");
+    lm_message_node_set_attribute(x, "xmlns", "jabber:x:data");
+
+    lm_message_node_add_child(x, "title", "Change Status");
+
+    lm_message_node_add_child(x, "instructions",
+                              "Choose the status and status message");
+
+    // TODO see if factorisation is possible
+    y = lm_message_node_add_child(x, "field", NULL);
+    lm_message_node_set_attribute(y, "type", "hidden");
+    lm_message_node_set_attribute(y, "var", "FORM_TYPE");
+
+    lm_message_node_add_child(y, "value", "http://jabber.org/protocol/rc");
+
+    y = lm_message_node_add_child(x, "field", NULL);
+    lm_message_node_set_attributes(y,
+                                   "type", "list-single",
+                                   "var", "status",
+                                   "label", "Status",
+                                   NULL);
+    lm_message_node_add_child(y, "required", NULL);
+
+    // XXX: ugly
+    lm_message_node_add_child(y, "value",
+                              adhoc_status_list[xmpp_getstatus()].name);
+    for (s = adhoc_status_list; s->name; s++) {
+        LmMessageNode *option = lm_message_node_add_child(y, "option", NULL);
+        lm_message_node_add_child(option, "value", s->name);
+        lm_message_node_set_attribute(option, "label", s->description);
+    }
+    // TODO add priority ?
+    // I do not think this is useful, user should not have to care of the
+    // priority like gossip and gajim do (misc)
+    lm_message_node_set_attributes
+            (lm_message_node_add_child(x, "field", NULL),
+             "type", "text-multi",
+             "var", "status-message",
+             "label", "Message",
+             NULL);
+  } else if (action && !strcmp(action, "cancel")) {
+    lm_message_node_set_attribute(command, "status", "canceled");
+  } else  { // (if sessionid and not canceled)
+    y = lm_message_node_find_xmlns(x, "jabber:x:data"); //x?xmlns=jabber:x:data
+    if (y) {
+      const char *value=NULL, *message=NULL;
+      LmMessageNode *fields, *field;
+      field = fields = lm_message_node_get_child(y, "field"); //field?var=status
+      while (field && strcmp("status",
+                             lm_message_node_get_attribute(field, "var")))
+        field = field->next;
+      field = lm_message_node_get_child(field, "value");
+      if (field)
+        value = lm_message_node_get_value(field);
+      field = fields; //field?var=status-message
+      while (field && strcmp("status-message",
+                             lm_message_node_get_attribute(field, "var")))
+        field = field->next;
+      field = lm_message_node_get_child(field, "value");
+      if (field)
+        message = lm_message_node_get_value(field);
+      if (value) {
+        for (s = adhoc_status_list; !s->name || strcmp(s->name, value); s++);
+        if (s->name) {
+          char *status = g_strdup_printf("%s %s", s->status,
+                                         message ? message : "");
+          cmd_setstatus(NULL, status);
+          g_free(status);
+          lm_message_node_set_attribute(command, "status", "completed");
+          lm_message_node_add_dataform_result(command,
+                                              "Status has been changed");
+        }
+      }
+    }
+  }
+  if (sessionid)
+    lm_message_node_set_attribute(command, "sessionid", sessionid);
+  lm_connection_send(c, iq, NULL);
+  lm_message_unref(iq);
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+static void _callback_foreach_buddy_groupchat(gpointer rosterdata, void *param)
+{
+  LmMessageNode *field, *value, *option;
+  const char *room_jid, *nickname;
+  char *desc;
+
+  room_jid = buddy_getjid(rosterdata);
+  if (!room_jid) return;
+  nickname = buddy_getnickname(rosterdata);
+  if (!nickname) return;
+  field = param;
+
+  option = lm_message_node_add_child(field, "option", NULL);
+  value = lm_message_node_add_child(option, "value", room_jid);
+  desc = g_strdup_printf("%s on %s", nickname, room_jid);
+  lm_message_node_set_attribute(option, "label", desc);
+  g_free(desc);
+}
+
+static LmHandlerResult handle_iq_command_leave_groupchats(LmMessageHandler *h,
+                                                          LmConnection *c,
+                                                          LmMessage *m,
+                                                          gpointer ud)
+{
+  const char *action, *node;
+  char *sessionid;
+  LmMessage *iq;
+  LmMessageNode *command, *x;
+
+  x = lm_message_node_get_child(m->node, "command");
+  action = lm_message_node_get_attribute(x, "action");
+  node = lm_message_node_get_attribute(x, "node");
+  sessionid = (char*)lm_message_node_get_attribute(x, "sessionid");
+
+  iq = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT);
+  command = lm_message_node_add_child(iq->node, "command", NULL);
+  lm_message_node_set_attributes(command,
+                                 "node", node,
+                                 "xmlns", NS_COMMANDS,
+                                 NULL);
+
+  if (!sessionid) {
+    LmMessageNode *field;
+
+    sessionid = generate_session_id("leave-groupchats");
+    lm_message_node_set_attribute(command, "sessionid", sessionid);
+    g_free(sessionid);
+    sessionid = NULL;
+    lm_message_node_set_attribute(command, "status", "executing");
+
+    x = lm_message_node_add_child(command, "x", NULL);
+    lm_message_node_set_attributes(x,
+                                   "type", "form",
+                                   "xmlns", "jabber:x:data",
+                                   NULL);
+
+    lm_message_node_add_child(x, "title", "Leave groupchat(s)");
+
+    lm_message_node_add_child(x, "instructions",
+                              "What groupchats do you want to leave?");
+
+    field = lm_message_node_add_child(x, "field", NULL);
+    lm_message_node_set_attributes(field,
+                                   "type", "hidden",
+                                   "var", "FORM_TYPE",
+                                   NULL);
+
+    lm_message_node_add_child(field, "value",
+                              "http://jabber.org/protocol/rc");
+
+    field = lm_message_node_add_child(x, "field", NULL);
+    lm_message_node_set_attributes(field,
+                                   "type", "list-multi",
+                                   "var", "groupchats",
+                                   "label", "Groupchats: ",
+                                   NULL);
+    lm_message_node_add_child(field, "required", NULL);
+
+    foreach_buddy(ROSTER_TYPE_ROOM, &_callback_foreach_buddy_groupchat, field);
+    //TODO: return an error if we are not connected to groupchats
+  } else if (action && !strcmp(action, "cancel")) {
+    lm_message_node_set_attribute(command, "status", "canceled");
+  } else  { // (if sessionid and not canceled)
+    LmMessageNode *form = lm_message_node_find_xmlns(x, "jabber:x:data");//TODO
+    if (form) {
+      LmMessageNode *field;
+
+      lm_message_node_set_attribute(command, "status", "completed");
+      //TODO: implement sth. like "field?var=groupchats" in xmlnode...
+      field  = lm_message_node_get_child(form, "field");
+      while (field && strcmp("groupchats",
+                             lm_message_node_get_attribute(field, "var")))
+        field = field->next;
+
+      for (x = field->children ; x ; x = x->next)
+      {
+        LmMessageNode *to_leave = lm_message_node_get_child(x, "value");
+        if (to_leave) {
+          GList* b = buddy_search_jid(lm_message_node_get_value(to_leave));
+          if (b)
+            cmd_room_leave(b->data, "Requested by remote command");
+        }
+      }
+      lm_message_node_add_dataform_result(command,
+                                          "Groupchats have been left");
+    }
+  }
+  if (sessionid)
+    lm_message_node_set_attribute(command, "sessionid", sessionid);
+  lm_connection_send(c, iq, NULL);
+  lm_message_unref(iq);
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+static LmHandlerResult handle_iq_commands(LmMessageHandler *h,
+                                          LmConnection *c,
+                                          LmMessage *m, gpointer ud)
+{
+  const char *requester_jid = NULL;
+  LmMessageNode *cmd;
+  const struct adhoc_command *command;
+
+  // mcabber has only partial XEP-0146 support...
+  if (LM_MESSAGE_SUB_TYPE_SET != lm_message_get_sub_type(m))
+    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+
+  requester_jid = lm_message_get_from(m);
+
+  cmd = lm_message_node_get_child(m->node, "command");
+  if (jid_equal(lm_connection_get_jid(c), requester_jid)) {
+    const char *action, *node;
+    action = lm_message_node_get_attribute(cmd, "action");
+    node = lm_message_node_get_attribute(cmd, "node");
+    // action can be NULL, in which case it seems to take the default,
+    // ie execute
+    if (!action || !strcmp(action, "execute") || !strcmp(action, "cancel")
+        || !strcmp(action, "next") || !strcmp(action, "complete")) {
+      for (command = adhoc_command_list; command->name; command++) {
+        if (!strcmp(node, command->name))
+          command->callback(h, c, m, ud);
+      }
+      // "prev" action will get there, as we do not implement it,
+      // and do not authorize it
+    } else {
+      LmMessage *r;
+      LmMessageNode *err;
+      r = lm_message_new_iq_error(m, XMPP_ERROR_BAD_REQUEST);
+      err = lm_message_node_get_child(r->node, "error");
+      lm_message_node_set_attribute
+              (lm_message_node_add_child(err, "malformed-action", NULL),
+               "xmlns", NS_COMMANDS);
+      lm_connection_send(c, r, NULL);
+      lm_message_unref(r);
+    }
+  } else {
+    send_iq_error(c, m, XMPP_ERROR_FORBIDDEN);
+  }
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+
+static LmHandlerResult handle_iq_disco_items(LmMessageHandler *h,
+                                             LmConnection *c,
+                                             LmMessage *m, gpointer ud)
+{
+  LmMessageNode *query;
+  const char *node;
+  query = lm_message_node_get_child(m->node, "query");
+  node = lm_message_node_get_attribute(query, "node");
+  if (node) {
+    if (!strcmp(node, NS_COMMANDS)) {
+      return handle_iq_commands_list(NULL, c, m, ud);
+    } else {
+      send_iq_error(c, m, XMPP_ERROR_NOT_IMPLEMENTED);
+    }
+  } else {
+    // not sure about this one
+    send_iq_error(c, m, XMPP_ERROR_NOT_IMPLEMENTED);
+  }
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+
+//  disco_info_set_ext(ansquery, ext)
+// Add features attributes to ansquery for extension ext.
+static void disco_info_set_ext(LmMessageNode *ansquery, const char *ext)
+{
+  char *nodename = g_strdup_printf("%s#%s", MCABBER_CAPS_NODE, ext);
+  lm_message_node_set_attribute(ansquery, "node", nodename);
+  g_free(nodename);
+  if (!strcasecmp(ext, "csn")) {
+    // I guess it's ok to send this even if it's not compiled in.
+    lm_message_node_set_attribute(lm_message_node_add_child(ansquery,
+                                                            "feature", NULL),
+                                  "var", NS_CHATSTATES);
+  }
+  if (!strcasecmp(ext, "iql")) {
+    // I guess it's ok to send this even if it's not compiled in.
+    lm_message_node_set_attribute(lm_message_node_add_child(ansquery,
+                                                            "feature", NULL),
+                                  "var", NS_LAST);
+  }
+}
+
+//  disco_info_set_default(ansquery, entitycaps)
+// Add features attributes to ansquery.  If entitycaps is TRUE, assume
+// that we're answering an Entity Caps request (if not, the request was
+// a basic discovery query).
+// Please change the entity version string if you modify mcabber disco
+// source code, so that it doesn't conflict with the upstream client.
+static void disco_info_set_default(LmMessageNode *ansquery, guint entitycaps)
+{
+  LmMessageNode *y;
+  char *eversion;
+
+  eversion = g_strdup_printf("%s#%s", MCABBER_CAPS_NODE, entity_version());
+  lm_message_node_set_attribute(ansquery, "node", eversion);
+  g_free(eversion);
+
+  y = lm_message_node_add_child(ansquery, "identity", NULL);
+
+  lm_message_node_set_attributes(y,
+                                 "category", "client",
+                                 "type", "pc",
+                                 "name", PACKAGE_NAME,
+                                 NULL);
+
+  lm_message_node_set_attribute
+          (lm_message_node_add_child(ansquery, "feature", NULL),
+           "var", NS_DISCO_INFO);
+  lm_message_node_set_attribute
+          (lm_message_node_add_child(ansquery, "feature", NULL),
+           "var", NS_MUC);
+#ifdef JEP0085
+  // Advertise ChatStates only if we're not using Entity Capabilities
+  if (!entitycaps)
+    lm_message_node_set_attribute
+            (lm_message_node_add_child(ansquery, "feature", NULL),
+             "var", NS_CHATSTATES);
+#endif
+  lm_message_node_set_attribute
+          (lm_message_node_add_child(ansquery, "feature", NULL),
+           "var", NS_TIME);
+  lm_message_node_set_attribute
+          (lm_message_node_add_child(ansquery, "feature", NULL),
+           "var", NS_XMPP_TIME);
+  lm_message_node_set_attribute
+          (lm_message_node_add_child(ansquery, "feature", NULL),
+           "var", NS_VERSION);
+  lm_message_node_set_attribute
+          (lm_message_node_add_child(ansquery, "feature", NULL),
+           "var", NS_PING);
+  lm_message_node_set_attribute
+          (lm_message_node_add_child(ansquery, "feature", NULL),
+           "var", NS_COMMANDS);
+  if (!entitycaps)
+    lm_message_node_set_attribute
+            (lm_message_node_add_child(ansquery, "feature", NULL),
+             "var", NS_LAST);
+}
+
+static LmHandlerResult handle_iq_disco_info(LmMessageHandler *h,
+                                            LmConnection *c,
+                                            LmMessage *m, gpointer ud)
+{
+  LmMessage *r;
+  LmMessageNode *query, *tmp;
+  const char *node = NULL;
+
+  r = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT);
+  query = lm_message_node_add_child(r->node, "query", NULL);
+  lm_message_node_set_attribute(query, "xmlns", NS_DISCO_INFO);
+  tmp = lm_message_node_find_child(m->node, "query");
+  if (tmp)
+    node = lm_message_node_get_attribute(tmp, "node");
+  if (node && startswith(node, MCABBER_CAPS_NODE "#", FALSE)) {
+    const char *param = node+strlen(MCABBER_CAPS_NODE)+1;
+    if (!strcmp(param, entity_version()))
+      disco_info_set_default(query, TRUE);  // client#version
+    else
+      disco_info_set_ext(query, param);     // client#extension
+  } else {
+    // Basic discovery request
+    disco_info_set_default(query, FALSE);
+  }
+
+  lm_connection_send(c, r, NULL);
+  lm_message_unref(r);
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+static LmHandlerResult handle_iq_roster(LmMessageHandler *h, LmConnection *c,
+                                        LmMessage *m, gpointer ud)
+{
+  LmMessageNode *y;
+  const char *fjid, *name, *group, *sub, *ask;
+  char *cleanalias;
+  enum subscr esub;
+  int need_refresh = FALSE;
+  guint roster_type;
+
+  for (y = lm_message_node_find_child(lm_message_node_find_xmlns
+                                      (m->node, NS_ROSTER),
+                                      "item");
+       y;
+       y = y->next) {
+    char *name_tmp = NULL;
+
+    fjid = lm_message_node_get_attribute(y, "jid");
+    name = lm_message_node_get_attribute(y, "name");
+    sub = lm_message_node_get_attribute(y, "subscription");
+    ask = lm_message_node_get_attribute(y, "ask");
+
+    if (lm_message_node_find_child(y, "group"))
+      group = lm_message_node_get_value(lm_message_node_find_child(y, "group"));
+    else
+      group = NULL;
+
+    if (!fjid)
+      continue;
+
+    cleanalias = jidtodisp(fjid);
+
+    esub = sub_none;
+    if (sub) {
+      if (!strcmp(sub, "to"))          esub = sub_to;
+      else if (!strcmp(sub, "from"))   esub = sub_from;
+      else if (!strcmp(sub, "both"))   esub = sub_both;
+      else if (!strcmp(sub, "remove")) esub = sub_remove;
+    }
+
+    if (esub == sub_remove) {
+      roster_del_user(cleanalias);
+      scr_LogPrint(LPRINT_LOGNORM, "Buddy <%s> has been removed "
+                   "from the roster", cleanalias);
+      g_free(cleanalias);
+      need_refresh = TRUE;
+      continue;
+    }
+
+    if (ask && !strcmp(ask, "subscribe"))
+      esub |= sub_pending;
+
+    if (!name) {
+      if (!settings_opt_get_int("roster_hide_domain")) {
+        name = cleanalias;
+      } else {
+        char *p;
+        name = name_tmp = g_strdup(cleanalias);
+        p = strchr(name_tmp, JID_DOMAIN_SEPARATOR);
+        if (p)  *p = '\0';
+      }
+    }
+
+    // Tricky... :-\  My guess is that if there is no JID_DOMAIN_SEPARATOR,
+    // this is an agent.
+    if (strchr(cleanalias, JID_DOMAIN_SEPARATOR))
+      roster_type = ROSTER_TYPE_USER;
+    else
+      roster_type = ROSTER_TYPE_AGENT;
+
+    roster_add_user(cleanalias, name, group, roster_type, esub, 1);
+
+    g_free(name_tmp);
+    g_free(cleanalias);
+  }
+
+  buddylist_build();
+  update_roster = TRUE;
+  if (need_refresh)
+    scr_UpdateBuddyWindow();
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+static LmHandlerResult handle_iq_ping(LmMessageHandler *h, LmConnection *c,
+                                       LmMessage *m, gpointer ud)
+{
+  LmMessage *r;
+
+  r = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT);
+  lm_connection_send(c, r, NULL);
+  lm_message_unref(r);
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+double seconds_since_last_use(void)
+{
+  return difftime(time(NULL), iqlast);
+}
+
+static LmHandlerResult handle_iq_last(LmMessageHandler *h, LmConnection *c,
+                                      LmMessage *m, gpointer ud)
+{
+  LmMessage *r;
+  LmMessageNode *query;
+  char *seconds;
+
+  if (!settings_opt_get_int("iq_hide_requests")) {
+    scr_LogPrint(LPRINT_LOGNORM, "Received an IQ last time request from <%s>",
+                 lm_message_get_from(m));
+  }
+
+  if (settings_opt_get_int("iq_last_disable") ||
+      (settings_opt_get_int("iq_last_disable_when_notavail") &&
+       xmpp_getstatus() == notavail))
+  {
+    send_iq_error(c, m, XMPP_ERROR_SERVICE_UNAVAILABLE);
+    return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+  }
+
+  r = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT);
+  query = lm_message_node_add_child(r->node, "query", NULL);
+  seconds = g_strdup_printf("%.0f", seconds_since_last_use());
+  lm_message_node_set_attribute(query, "seconds", seconds);
+  g_free(seconds);
+
+  lm_connection_send(c, r, NULL);
+  lm_message_unref(r);
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+static LmHandlerResult handle_iq_version(LmMessageHandler *h, LmConnection *c,
+                                         LmMessage *m, gpointer ud)
+{
+  LmMessage *r;
+  LmMessageNode *query;
+  char *os = NULL;
+  char *ver = mcabber_version();
+
+  if (!settings_opt_get_int("iq_hide_requests")) {
+    scr_LogPrint(LPRINT_LOGNORM, "Received an IQ version request from <%s>",
+                 lm_message_get_from(m));
+  }
+  if (!settings_opt_get_int("iq_version_hide_os")) {
+    struct utsname osinfo;
+    uname(&osinfo);
+    os = g_strdup_printf("%s %s %s", osinfo.sysname, osinfo.release,
+                         osinfo.machine);
+  }
+
+  r = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT);
+
+  query = lm_message_node_add_child(r->node, "query", NULL);
+
+  lm_message_node_add_child(query, "name", PACKAGE_NAME);
+  lm_message_node_add_child(query, "version", ver);
+  if (os) {
+    lm_message_node_add_child(query, "os", os);
+    g_free(os);
+  }
+
+  g_free(ver);
+  lm_connection_send(c, r, NULL);
+  lm_message_unref(r);
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+// This function borrows some code from the Pidgin project
+static LmHandlerResult handle_iq_time(LmMessageHandler *h, LmConnection *c,
+                                      LmMessage *m, gpointer ud)
+{
+  LmMessage *r;
+  LmMessageNode *query;
+  char *buf, *utf8_buf;
+  time_t now_t;
+  struct tm *now;
+
+  time(&now_t);
+
+  if (!settings_opt_get_int("iq_hide_requests")) {
+    scr_LogPrint(LPRINT_LOGNORM, "Received an IQ time request from <%s>",
+                 lm_message_get_from(m));
+  }
+
+  buf = g_new0(char, 512);
+
+  r = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT);
+  query = lm_message_node_add_child(r->node, "query", NULL);
+
+  now = gmtime(&now_t);
+
+  strftime(buf, 512, "%Y%m%dT%T", now);
+  lm_message_node_add_child(query, "utc", buf);
+
+  now = localtime(&now_t);
+
+  strftime(buf, 512, "%Z", now);
+  if ((utf8_buf = to_utf8(buf))) {
+    lm_message_node_add_child(query, "tz", utf8_buf);
+    g_free(utf8_buf);
+  }
+
+  strftime(buf, 512, "%d %b %Y %T", now);
+  if ((utf8_buf = to_utf8(buf))) {
+    lm_message_node_add_child(query, "display", utf8_buf);
+    g_free(utf8_buf);
+  }
+
+  lm_connection_send(c, r, NULL);
+  lm_message_unref(r);
+  g_free(buf);
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+// This function borrows some code from the Pidgin project
+static LmHandlerResult handle_iq_time202(LmMessageHandler *h, LmConnection *c,
+                                         LmMessage *m, gpointer ud)
+{
+  LmMessage *r;
+  LmMessageNode *query;
+  char *buf, *utf8_buf;
+  time_t now_t;
+  struct tm *now;
+  char const *sign;
+  int diff = 0;
+
+  time(&now_t);
+
+  if (!settings_opt_get_int("iq_hide_requests")) {
+    scr_LogPrint(LPRINT_LOGNORM, "Received an IQ time request from <%s>",
+                 lm_message_get_from(m));
+  }
+
+  buf = g_new0(char, 512);
+
+  r = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT);
+  query = lm_message_node_add_child(r->node, "time", NULL);
+  lm_message_node_set_attribute(query, "xmlns", NS_XMPP_TIME);
+
+  now = localtime(&now_t);
+
+  if (now->tm_isdst >= 0) {
+#if defined HAVE_TM_GMTOFF
+    diff = now->tm_gmtoff;
+#elif defined HAVE_TIMEZONE
+    tzset();
+    diff = -timezone;
+#endif
+  }
+
+  if (diff < 0) {
+    sign = "-";
+    diff = -diff;
+  } else {
+    sign = "+";
+  }
+  diff /= 60;
+  snprintf(buf, 512, "%c%02d:%02d", *sign, diff / 60, diff % 60);
+  if ((utf8_buf = to_utf8(buf))) {
+    lm_message_node_add_child(query, "tzo", utf8_buf);
+    g_free(utf8_buf);
+  }
+
+  now = gmtime(&now_t);
+
+  strftime(buf, 512, "%Y-%m-%dT%TZ", now);
+  lm_message_node_add_child(query, "utc", buf);
+
+  lm_connection_send(c, r, NULL);
+  lm_message_unref(r);
+  g_free(buf);
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/xmpp_iqrequest.c	Sun Oct 11 15:38:32 2009 +0200
@@ -0,0 +1,600 @@
+/* See xmpp.c file for copyright and license details. */
+
+static LmHandlerResult cb_roster(LmMessageHandler *h, LmConnection *c,
+                                 LmMessage *m, gpointer user_data);
+static LmHandlerResult cb_version(LmMessageHandler *h, LmConnection *c,
+                                  LmMessage *m, gpointer user_data);
+static LmHandlerResult cb_time(LmMessageHandler *h, LmConnection *c,
+                               LmMessage *m, gpointer user_data);
+static LmHandlerResult cb_last(LmMessageHandler *h, LmConnection *c,
+                               LmMessage *m, gpointer user_data);
+static LmHandlerResult cb_vcard(LmMessageHandler *h, LmConnection *c,
+                               LmMessage *m, gpointer user_data);
+
+static struct IqRequestHandlers
+{
+  const gchar *xmlns;
+  const gchar *querytag;
+  LmHandleMessageFunction handler;
+} iq_request_handlers[] = {
+  {NS_ROSTER, "query", &cb_roster},
+  {NS_VERSION,"query", &cb_version},
+  {NS_TIME,   "query", &cb_time},
+  {NS_LAST,   "query", &cb_last},
+  {NS_VCARD,  "vCard", &cb_vcard},
+  {NULL, NULL, NULL}
+};
+
+// Enum for vCard attributes
+enum vcard_attr {
+  vcard_home    = 1<<0,
+  vcard_work    = 1<<1,
+  vcard_postal  = 1<<2,
+  vcard_voice   = 1<<3,
+  vcard_fax     = 1<<4,
+  vcard_cell    = 1<<5,
+  vcard_inet    = 1<<6,
+  vcard_pref    = 1<<7,
+};
+
+// xmlns has to be a namespace from iq_request_handlers[].xmlns
+void xmpp_iq_request(const char *fulljid, const char *xmlns)
+{
+  LmMessage *iq;
+  LmMessageNode *query;
+  LmMessageHandler *handler;
+  int i;
+
+  iq = lm_message_new_with_sub_type(fulljid, LM_MESSAGE_TYPE_IQ,
+                                    LM_MESSAGE_SUB_TYPE_GET);
+  for (i = 0; strcmp(iq_request_handlers[i].xmlns, xmlns) != 0 ; ++i)
+       ;
+  query = lm_message_node_add_child(iq->node,
+                                    iq_request_handlers[i].querytag,
+                                    NULL);
+  lm_message_node_set_attribute(query, "xmlns", xmlns);
+  handler = lm_message_handler_new(iq_request_handlers[i].handler,
+                                   NULL, FALSE);
+  lm_connection_send_with_reply(lconnection, iq, handler, NULL);
+  lm_message_handler_unref(handler);
+  lm_message_unref(iq);
+}
+
+//  This callback is reached when mcabber receives the first roster update
+// after the connection.
+static LmHandlerResult cb_roster(LmMessageHandler *h, LmConnection *c,
+                                 LmMessage *m, gpointer user_data)
+{
+  LmMessageNode *x;
+  const char *ns;
+
+  // Only execute the hook if the roster has been successfully retrieved
+  if (lm_message_get_sub_type(m) != LM_MESSAGE_SUB_TYPE_RESULT)
+    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+
+  x = lm_message_node_find_child(m->node, "query");
+  if (!x)
+    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+
+  ns = lm_message_node_get_attribute(x, "xmlns");
+  if (ns && !strcmp(ns, NS_ROSTER))
+    handle_iq_roster(NULL, c, m, user_data);
+
+  // Post-login stuff
+  hook_execute_internal("hook-post-connect");
+
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+static LmHandlerResult cb_version(LmMessageHandler *h, LmConnection *c,
+                                  LmMessage *m, gpointer user_data)
+{
+  LmMessageNode *ansqry;
+  const char *p, *bjid;
+  char *tmp;
+  char *buf;
+
+  ansqry = lm_message_node_get_child(m->node, "query");
+  if (!ansqry) {
+    scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:version result!");
+    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+  }
+
+  // Display IQ result sender...
+  p = lm_message_get_from(m);
+  if (!p) {
+    scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:version result (no sender name).");
+    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+  }
+  bjid = p;
+
+  buf = g_strdup_printf("Received IQ:version result from <%s>", bjid);
+  scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
+
+  // bjid should now really be the "bare JID", let's strip the resource
+  tmp = strchr(bjid, JID_RESOURCE_SEPARATOR);
+  if (tmp) *tmp = '\0';
+
+  scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0);
+  g_free(buf);
+
+  // Get result data...
+  p = lm_message_node_get_child_value(ansqry, "name");
+  if (p) {
+    buf = g_strdup_printf("Name:    %s", p);
+    scr_WriteIncomingMessage(bjid, buf,
+                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+    g_free(buf);
+  }
+  p = lm_message_node_get_child_value(ansqry, "version");
+  if (p) {
+    buf = g_strdup_printf("Version: %s", p);
+    scr_WriteIncomingMessage(bjid, buf,
+                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+    g_free(buf);
+  }
+  p = lm_message_node_get_child_value(ansqry, "os");
+  if (p) {
+    buf = g_strdup_printf("OS:      %s", p);
+    scr_WriteIncomingMessage(bjid, buf,
+                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+    g_free(buf);
+  }
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+static LmHandlerResult cb_time(LmMessageHandler *h, LmConnection *c,
+                               LmMessage *m, gpointer user_data)
+{
+  LmMessageNode *ansqry;
+  const char *p, *bjid;
+  char *tmp;
+  char *buf;
+
+  ansqry = lm_message_node_get_child(m->node, "query");
+  if (!ansqry) {
+    scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:time result!");
+    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+  }
+  // Display IQ result sender...
+  p = lm_message_get_from(m);
+  if (!p) {
+    scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:time result (no sender name).");
+    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+  }
+  bjid = p;
+
+  buf = g_strdup_printf("Received IQ:time result from <%s>", bjid);
+  scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
+
+  // bjid should now really be the "bare JID", let's strip the resource
+  tmp = strchr(bjid, JID_RESOURCE_SEPARATOR);
+  if (tmp) *tmp = '\0';
+
+  scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0);
+  g_free(buf);
+
+  // Get result data...
+  p = lm_message_node_get_child_value(ansqry, "utc");
+  if (p) {
+    buf = g_strdup_printf("UTC:  %s", p);
+    scr_WriteIncomingMessage(bjid, buf,
+                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+    g_free(buf);
+  }
+  p = lm_message_node_get_child_value(ansqry, "tz");
+  if (p) {
+    buf = g_strdup_printf("TZ:   %s", p);
+    scr_WriteIncomingMessage(bjid, buf,
+                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+    g_free(buf);
+  }
+  p = lm_message_node_get_child_value(ansqry, "display");
+  if (p) {
+    buf = g_strdup_printf("Time: %s", p);
+    scr_WriteIncomingMessage(bjid, buf,
+                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+    g_free(buf);
+  }
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+static LmHandlerResult cb_last(LmMessageHandler *h, LmConnection *c,
+                               LmMessage *m, gpointer user_data)
+{
+  LmMessageNode *ansqry;
+  const char *p, *bjid;
+  char *buf, *tmp;
+
+  ansqry = lm_message_node_get_child(m->node, "query");
+  if (!ansqry) {
+    scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:last result!");
+    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+  }
+  // Display IQ result sender...
+  p = lm_message_get_from(m);
+  if (!p) {
+    scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:last result (no sender name).");
+    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+  }
+  bjid = p;
+
+  buf = g_strdup_printf("Received IQ:last result from <%s>", bjid);
+  scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
+
+  // bjid should now really be the "bare JID", let's strip the resource
+  tmp = strchr(bjid, JID_RESOURCE_SEPARATOR);
+  if (tmp) *tmp = '\0';
+
+  scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0);
+  g_free(buf);
+
+  // Get result data...
+  p = lm_message_node_get_attribute(ansqry, "seconds");
+  if (p) {
+    long int s;
+    GString *sbuf;
+    sbuf = g_string_new("Idle time: ");
+    s = atol(p);
+    // Days
+    if (s > 86400L) {
+      g_string_append_printf(sbuf, "%ldd ", s/86400L);
+      s %= 86400L;
+    }
+    // hh:mm:ss
+    g_string_append_printf(sbuf, "%02ld:", s/3600L);
+    s %= 3600L;
+    g_string_append_printf(sbuf, "%02ld:%02ld", s/60L, s%60L);
+    scr_WriteIncomingMessage(bjid, sbuf->str,
+                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+    g_string_free(sbuf, TRUE);
+  } else {
+    scr_WriteIncomingMessage(bjid, "No idle time reported.",
+                             0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+  }
+  p = lm_message_node_get_value(ansqry);
+  if (p) {
+    buf = g_strdup_printf("Status message: %s", p);
+    scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0);
+    g_free(buf);
+  }
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+static void display_vcard_item(const char *bjid, const char *label,
+                               enum vcard_attr vcard_attrib, const char *text)
+{
+  char *buf;
+
+  if (!text || !bjid || !label)
+    return;
+
+  buf = g_strdup_printf("%s: %s%s%s%s%s%s%s%s%s%s", label,
+                        (vcard_attrib & vcard_home ? "[home]" : ""),
+                        (vcard_attrib & vcard_work ? "[work]" : ""),
+                        (vcard_attrib & vcard_postal ? "[postal]" : ""),
+                        (vcard_attrib & vcard_voice ? "[voice]" : ""),
+                        (vcard_attrib & vcard_fax  ? "[fax]"  : ""),
+                        (vcard_attrib & vcard_cell ? "[cell]" : ""),
+                        (vcard_attrib & vcard_inet ? "[inet]" : ""),
+                        (vcard_attrib & vcard_pref ? "[pref]" : ""),
+                        (vcard_attrib ? " " : ""),
+                        text);
+  scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+  g_free(buf);
+}
+
+static void handle_vcard_node(const char *barejid, LmMessageNode *vcardnode)
+{
+  LmMessageNode *x;
+  const char *p;
+
+  for (x = vcardnode->children ; x; x = x->next) {
+    const char *data;
+    enum vcard_attr vcard_attrib = 0;
+
+    p = x->name;
+    data = lm_message_node_get_value(x);
+    if (!p || !data)
+      continue;
+
+    if (!strcmp(p, "FN"))
+      display_vcard_item(barejid, "Name", vcard_attrib, data);
+    else if (!strcmp(p, "NICKNAME"))
+      display_vcard_item(barejid, "Nickname", vcard_attrib, data);
+    else if (!strcmp(p, "URL"))
+      display_vcard_item(barejid, "URL", vcard_attrib, data);
+    else if (!strcmp(p, "BDAY"))
+      display_vcard_item(barejid, "Birthday", vcard_attrib, data);
+    else if (!strcmp(p, "TZ"))
+      display_vcard_item(barejid, "Timezone", vcard_attrib, data);
+    else if (!strcmp(p, "TITLE"))
+      display_vcard_item(barejid, "Title", vcard_attrib, data);
+    else if (!strcmp(p, "ROLE"))
+      display_vcard_item(barejid, "Role", vcard_attrib, data);
+    else if (!strcmp(p, "DESC"))
+      display_vcard_item(barejid, "Comment", vcard_attrib, data);
+    else if (!strcmp(p, "N")) {
+      data = lm_message_node_get_child_value(x, "FAMILY");
+      display_vcard_item(barejid, "Family Name", vcard_attrib, data);
+      data = lm_message_node_get_child_value(x, "GIVEN");
+      display_vcard_item(barejid, "Given Name", vcard_attrib, data);
+      data = lm_message_node_get_child_value(x, "MIDDLE");
+      display_vcard_item(barejid, "Middle Name", vcard_attrib, data);
+    } else if (!strcmp(p, "ORG")) {
+      data = lm_message_node_get_child_value(x, "ORGNAME");
+      display_vcard_item(barejid, "Organisation name", vcard_attrib, data);
+      data = lm_message_node_get_child_value(x, "ORGUNIT");
+      display_vcard_item(barejid, "Organisation unit", vcard_attrib, data);
+    } else {
+      // The HOME, WORK and PREF attributes are common to the remaining fields
+      // (ADR, TEL & EMAIL)
+      if (lm_message_node_get_child(x, "HOME"))
+        vcard_attrib |= vcard_home;
+      if (lm_message_node_get_child(x, "WORK"))
+        vcard_attrib |= vcard_work;
+      if (lm_message_node_get_child(x, "PREF"))
+        vcard_attrib |= vcard_pref;
+      if (!strcmp(p, "ADR")) {          // Address
+        if (lm_message_node_get_child(x, "POSTAL"))
+          vcard_attrib |= vcard_postal;
+        data = lm_message_node_get_child_value(x, "EXTADD");
+        display_vcard_item(barejid, "Addr (ext)", vcard_attrib, data);
+        data = lm_message_node_get_child_value(x, "STREET");
+        display_vcard_item(barejid, "Street", vcard_attrib, data);
+        data = lm_message_node_get_child_value(x, "LOCALITY");
+        display_vcard_item(barejid, "Locality", vcard_attrib, data);
+        data = lm_message_node_get_child_value(x, "REGION");
+        display_vcard_item(barejid, "Region", vcard_attrib, data);
+        data = lm_message_node_get_child_value(x, "PCODE");
+        display_vcard_item(barejid, "Postal code", vcard_attrib, data);
+        data = lm_message_node_get_child_value(x, "CTRY");
+        display_vcard_item(barejid, "Country", vcard_attrib, data);
+      } else if (!strcmp(p, "TEL")) {   // Telephone
+        data = lm_message_node_get_child_value(x, "NUMBER");
+        if (data) {
+          if (lm_message_node_get_child(x, "VOICE"))
+            vcard_attrib |= vcard_voice;
+          if (lm_message_node_get_child(x, "FAX"))
+            vcard_attrib |= vcard_fax;
+          if (lm_message_node_get_child(x, "CELL"))
+            vcard_attrib |= vcard_cell;
+          display_vcard_item(barejid, "Phone", vcard_attrib, data);
+        }
+      } else if (!strcmp(p, "EMAIL")) { // Email
+        if (lm_message_node_get_child(x, "INTERNET"))
+          vcard_attrib |= vcard_inet;
+        data = lm_message_node_get_child_value(x, "USERID");
+        display_vcard_item(barejid, "Email", vcard_attrib, data);
+      }
+    }
+  }
+}
+
+static LmHandlerResult cb_vcard(LmMessageHandler *h, LmConnection *c,
+                               LmMessage *m, gpointer user_data)
+{
+  LmMessageNode *ansqry;
+  const char *p, *bjid;
+  char *buf, *tmp;
+
+  // Display IQ result sender...
+  p = lm_message_get_from(m);
+  if (!p) {
+    scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:vCard result (no sender name).");
+    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+  }
+  bjid = p;
+
+  buf = g_strdup_printf("Received IQ:vCard result from <%s>", bjid);
+  scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
+
+  // Get the vCard node
+  ansqry = lm_message_node_get_child(m->node, "vCard");
+  if (!ansqry) {
+    scr_LogPrint(LPRINT_LOGNORM, "Empty IQ:vCard result!");
+    g_free(buf);
+    return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+  }
+
+  // bjid should really be the "bare JID", let's strip the resource
+  tmp = strchr(bjid, JID_RESOURCE_SEPARATOR);
+  if (tmp) *tmp = '\0';
+
+  scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0);
+  g_free(buf);
+
+  // Get result data...
+  handle_vcard_node(bjid, ansqry);
+  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+}
+
+static void storage_bookmarks_parse_conference(LmMessageNode *node)
+{
+  const char *fjid, *name, *autojoin;
+  const char *pstatus, *awhois;
+  char *bjid;
+  GSList *room_elt;
+
+  fjid = lm_message_node_get_attribute(node, "jid");
+  if (!fjid)
+    return;
+  name = lm_message_node_get_attribute(node, "name");
+  autojoin = lm_message_node_get_attribute(node, "autojoin");
+  awhois = lm_message_node_get_attribute(node, "autowhois");
+  pstatus = lm_message_node_get_child_value(node, "print_status");
+
+  bjid = jidtodisp(fjid); // Bare jid
+
+  // Make sure this is a room (it can be a conversion user->room)
+  room_elt = roster_find(bjid, jidsearch, 0);
+  if (!room_elt) {
+    room_elt = roster_add_user(bjid, name, NULL, ROSTER_TYPE_ROOM,
+                               sub_none, -1);
+  } else {
+    buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
+    /*
+    // If the name is available, should we use it?
+    // I don't think so, it would be confusing because this item is already
+    // in the roster.
+    if (name)
+      buddy_setname(room_elt->data, name);
+    */
+  }
+
+  // Set the print_status and auto_whois values
+  if (pstatus) {
+    enum room_printstatus i;
+    for (i = status_none; i <= status_all; i++)
+      if (!strcasecmp(pstatus, strprintstatus[i]))
+        break;
+    if (i <= status_all)
+      buddy_setprintstatus(room_elt->data, i);
+  }
+  if (awhois) {
+    enum room_autowhois i = autowhois_default;
+    if (!strcmp(awhois, "1"))
+      i = autowhois_on;
+    else if (!strcmp(awhois, "0"))
+      i = autowhois_off;
+    if (i != autowhois_default)
+      buddy_setautowhois(room_elt->data, i);
+  }
+
+  // Is autojoin set?
+  // If it is, we'll look up for more information (nick? password?) and
+  // try to join the room.
+  if (autojoin && !strcmp(autojoin, "1")) {
+    const char *nick, *passwd;
+    char *tmpnick = NULL;
+    nick = lm_message_node_get_child_value(node, "nick");
+    passwd = lm_message_node_get_child_value(node, "password");
+    if (!nick || !*nick)
+      nick = tmpnick = default_muc_nickname(NULL);
+    // Let's join now
+    scr_LogPrint(LPRINT_LOGNORM, "Auto-join bookmark <%s>", bjid);
+    xmpp_room_join(bjid, nick, passwd);
+    g_free(tmpnick);
+  }
+  g_free(bjid);
+}
+
+static LmHandlerResult cb_storage_bookmarks(LmMessageHandler *h,
+                                            LmConnection *c,
+                                            LmMessage *m, gpointer user_data)
+{
+  LmMessageNode *x, *ansqry;
+  char *p;
+
+  if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) {
+    // No server support, or no bookmarks?
+    p = m->node->children->name;
+    if (p && !strcmp(p, "item-not-found")) {
+      // item-no-found means the server has Private Storage, but it's
+      // currently empty.
+      if (bookmarks)
+        lm_message_node_unref(bookmarks);
+      bookmarks = lm_message_node_new("storage", "storage:bookmarks");
+      // We return 0 so that the IQ error message be
+      // not displayed, as it isn't a real error.
+      return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+    }
+    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; // Unhandled error
+  }
+
+  ansqry = lm_message_node_get_child(m->node, "query");
+  ansqry = lm_message_node_get_child(ansqry, "storage");
+  if (!ansqry) {
+    scr_LogPrint(LPRINT_LOG, "Invalid IQ:private result! (storage:bookmarks)");
+    return 0;
+  }
+
+  // Walk through the storage tags
+  for (x = ansqry->children ; x; x = x->next) {
+    // If the current node is a conference item, parse it and update the roster
+    if (x->name && !strcmp(x->name, "conference"))
+      storage_bookmarks_parse_conference(x);
+  }
+  // "Copy" the bookmarks node
+  if (bookmarks)
+    lm_message_node_unref(bookmarks);
+  lm_message_node_deep_ref(ansqry);
+  bookmarks = ansqry;
+  return 0;
+}
+
+
+static LmHandlerResult cb_storage_rosternotes(LmMessageHandler *h,
+                                              LmConnection *c,
+                                              LmMessage *m, gpointer user_data)
+{
+  LmMessageNode *ansqry;
+
+  if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) {
+    const char *p;
+    // No server support, or no roster notes?
+    p = m->node->children->name;
+    if (p && !strcmp(p, "item-not-found")) {
+      // item-no-found means the server has Private Storage, but it's
+      // currently empty.
+      if (rosternotes)
+        lm_message_node_unref(rosternotes);
+      rosternotes = lm_message_node_new("storage", "storage:rosternotes");
+      // We return 0 so that the IQ error message be
+      // not displayed, as it isn't a real error.
+      return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+    }
+    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; // Unhandled error
+  }
+
+  ansqry = lm_message_node_get_child(m->node, "query");
+  ansqry = lm_message_node_get_child(ansqry, "storage");
+  if (!ansqry) {
+    scr_LogPrint(LPRINT_LOG, "Invalid IQ:private result! "
+                 "(storage:rosternotes)");
+    return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+  }
+  // Copy the rosternotes node
+  if (rosternotes)
+    lm_message_node_unref(rosternotes);
+  lm_message_node_deep_ref(ansqry);
+  rosternotes = ansqry;
+  return 0;
+}
+
+
+static struct IqRequestStorageHandlers
+{
+  const gchar *storagens;
+  LmHandleMessageFunction handler;
+} iq_request_storage_handlers[] = {
+  {"storage:rosternotes", &cb_storage_rosternotes},
+  {"storage:bookmarks", &cb_storage_bookmarks},
+  {NULL, NULL}
+};
+
+void xmpp_request_storage(const gchar *storage)
+{
+  LmMessage *iq;
+  LmMessageNode *query;
+  LmMessageHandler *handler;
+  int i;
+
+  iq = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_IQ,
+                                    LM_MESSAGE_SUB_TYPE_GET);
+  query = lm_message_node_add_child(iq->node, "query", NULL);
+  lm_message_node_set_attribute(query, "xmlns", NS_PRIVATE);
+  lm_message_node_set_attribute(lm_message_node_add_child
+                                (query, "storage", NULL),
+                                "xmlns", storage);
+
+  for (i = 0;
+       strcmp(iq_request_storage_handlers[i].storagens, storage) != 0;
+       ++i) ;
+
+  handler = lm_message_handler_new(iq_request_storage_handlers[i].handler,
+                                   NULL, FALSE);
+  lm_connection_send_with_reply(lconnection, iq, handler, NULL);
+  lm_message_handler_unref(handler);
+  lm_message_unref(iq);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/xmpp_muc.c	Sun Oct 11 15:38:32 2009 +0200
@@ -0,0 +1,678 @@
+/* See xmpp.c file for copyright and license details. */
+
+static void decline_invitation(event_muc_invitation *invitation, char *reason)
+{
+  // cut and paste from xmpp_room_invite
+  LmMessage *m;
+  LmMessageNode *x, *y;
+
+  if (!invitation) return;
+  if (!invitation->to || !invitation->from) return;
+
+  m = lm_message_new(invitation->to, LM_MESSAGE_TYPE_MESSAGE);
+
+  x = lm_message_node_add_child(m->node, "x", NULL);
+  lm_message_node_set_attribute(x, "xmlns",
+                                "http://jabber.org/protocol/muc#user");
+
+  y = lm_message_node_add_child(x, "decline", NULL);
+  lm_message_node_set_attribute(y, "to", invitation->from);
+
+  if (reason)
+    lm_message_node_add_child(y, "reason", reason);
+
+  lm_connection_send(lconnection, m, NULL);
+  lm_message_unref(m);
+}
+
+static int evscallback_invitation(eviqs *evp, guint evcontext)
+{
+  event_muc_invitation *invitation = evp->data;
+
+  // Sanity check
+  if (!invitation) {
+    // Shouldn't happen.
+    scr_LogPrint(LPRINT_LOGNORM, "Error in evs callback.");
+    return 0;
+  }
+
+  if (evcontext == EVS_CONTEXT_TIMEOUT) {
+    scr_LogPrint(LPRINT_LOGNORM, "Event %s timed out, cancelled.", evp->id);
+    goto evscallback_invitation_free;
+  }
+  if (evcontext == EVS_CONTEXT_CANCEL) {
+    scr_LogPrint(LPRINT_LOGNORM, "Event %s cancelled.", evp->id);
+    goto evscallback_invitation_free;
+  }
+  if (!(evcontext & EVS_CONTEXT_USER))
+    goto evscallback_invitation_free;
+  // Ok, let's work now.
+  // evcontext: 0, 1 == reject, accept
+
+  if (evcontext & ~EVS_CONTEXT_USER) {
+    char *nickname = default_muc_nickname(invitation->to);
+    xmpp_room_join(invitation->to, nickname, invitation->passwd);
+    g_free(nickname);
+  } else {
+    scr_LogPrint(LPRINT_LOGNORM, "Invitation to %s refused.", invitation->to);
+    decline_invitation(invitation, NULL);
+  }
+
+evscallback_invitation_free:
+  g_free(invitation->to);
+  g_free(invitation->from);
+  g_free(invitation->passwd);
+  g_free(invitation->reason);
+  g_free(invitation);
+  evp->data = NULL;
+  return 0;
+}
+
+// Join a MUC room
+void xmpp_room_join(const char *room, const char *nickname, const char *passwd)
+{
+  LmMessage *x;
+  LmMessageNode *y;
+  gchar *roomid;
+  GSList *room_elt;
+
+  if (!lm_connection_is_authenticated(lconnection) || !room) return;
+  if (!nickname)        return;
+
+  roomid = g_strdup_printf("%s/%s", room, nickname);
+  if (check_jid_syntax(roomid)) {
+    scr_LogPrint(LPRINT_NORMAL, "<%s/%s> is not a valid Jabber room", room,
+                 nickname);
+    g_free(roomid);
+    return;
+  }
+
+  room_elt = roster_find(room, jidsearch, ROSTER_TYPE_USER|ROSTER_TYPE_ROOM);
+  // Add room if it doesn't already exist
+  if (!room_elt) {
+    room_elt = roster_add_user(room, NULL, NULL, ROSTER_TYPE_ROOM,
+                               sub_none, -1);
+  } else {
+    // Make sure this is a room (it can be a conversion user->room)
+    buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
+  }
+  // If insideroom is TRUE, this is a nickname change and we don't care here
+  if (!buddy_getinsideroom(room_elt->data)) {
+    // We're trying to enter a room
+    buddy_setnickname(room_elt->data, nickname);
+  }
+
+  // Send the XML request
+  x = lm_message_new(roomid, LM_MESSAGE_TYPE_PRESENCE);
+
+  x = lm_message_new_presence(mystatus, roomid, mystatusmsg);
+  y = lm_message_node_add_child(x->node, "x", NULL);
+  lm_message_node_set_attribute(y, "xmlns", "http://jabber.org/protocol/muc");
+  if (passwd)
+    lm_message_node_add_child(y, "password", passwd);
+
+  lm_connection_send(lconnection, x, NULL);
+  lm_message_unref(x);
+  g_free(roomid);
+}
+
+// Invite a user to a MUC room
+// room syntax: "room@server"
+// reason can be null.
+void xmpp_room_invite(const char *room, const char *fjid, const char *reason)
+{
+  LmMessage *msg;
+  LmMessageNode *x, *y;
+
+  if (!lm_connection_is_authenticated(lconnection) || !room || !fjid) return;
+
+  msg = lm_message_new(room, LM_MESSAGE_TYPE_MESSAGE);
+
+  x = lm_message_node_add_child(msg->node, "x", NULL);
+  lm_message_node_set_attribute(x, "xmlns",
+                                "http://jabber.org/protocol/muc#user");
+
+  y = lm_message_node_add_child(x, "invite", NULL);
+  lm_message_node_set_attribute(y, "to", fjid);
+
+  if (reason)
+    lm_message_node_add_child(y, "reason", reason);
+
+  lm_connection_send(lconnection, msg, NULL);
+  lm_message_unref(msg);
+}
+
+int xmpp_room_setattrib(const char *roomid, const char *fjid,
+                        const char *nick, struct role_affil ra,
+                        const char *reason)
+{
+  LmMessage *iq;
+  LmMessageNode *query, *x;
+
+  if (!lm_connection_is_authenticated(lconnection) || !roomid) return 1;
+  if (!fjid && !nick) return 1;
+
+  if (check_jid_syntax((char*)roomid)) {
+    scr_LogPrint(LPRINT_NORMAL, "<%s> is not a valid Jabber id", roomid);
+    return 1;
+  }
+  if (fjid && check_jid_syntax((char*)fjid)) {
+    scr_LogPrint(LPRINT_NORMAL, "<%s> is not a valid Jabber id", fjid);
+    return 1;
+  }
+
+  if (ra.type == type_affil && ra.val.affil == affil_outcast && !fjid)
+    return 1; // Shouldn't happen (jid mandatory when banning)
+
+  iq = lm_message_new_with_sub_type(roomid, LM_MESSAGE_TYPE_IQ,
+                                    LM_MESSAGE_SUB_TYPE_SET);
+  query = lm_message_node_add_child(iq->node, "query", NULL);
+  lm_message_node_set_attribute(query, "xmlns",
+                                "http://jabber.org/protocol/muc#admin");
+  x = lm_message_node_add_child(query, "item", NULL);
+
+  if (fjid) {
+    lm_message_node_set_attribute(x, "jid", fjid);
+  } else { // nickname
+    lm_message_node_set_attribute(x, "nick", nick);
+  }
+
+  if (ra.type == type_affil)
+    lm_message_node_set_attribute(x, "affiliation", straffil[ra.val.affil]);
+  else if (ra.type == type_role)
+    lm_message_node_set_attribute(x, "role", strrole[ra.val.role]);
+
+  if (reason)
+    lm_message_node_add_child(x, "reason", reason);
+
+  lm_connection_send(lconnection, iq, NULL);
+  lm_message_unref(iq);
+
+  return 0;
+}
+
+// Unlock a MUC room
+// room syntax: "room@server"
+void xmpp_room_unlock(const char *room)
+{
+  LmMessageNode *y, *z;
+  LmMessage *iq;
+
+  if (!lm_connection_is_authenticated(lconnection) || !room) return;
+
+  iq = lm_message_new_with_sub_type(room, LM_MESSAGE_TYPE_IQ,
+                                    LM_MESSAGE_SUB_TYPE_SET);
+  lm_message_node_set_attribute(iq->node, "xmlns",
+                                "http://jabber.org/protocol/muc#owner");
+
+
+  y = lm_message_node_add_child(iq->node, "query", NULL);
+  z = lm_message_node_add_child(y, "x", NULL);
+  lm_message_node_set_attribute(z, "xmlns", "jabber:x:data");
+  lm_message_node_set_attribute(z, "type", "submit");
+
+  lm_connection_send(lconnection, iq, NULL);
+  lm_message_unref(iq);
+}
+
+// Destroy a MUC room
+// room syntax: "room@server"
+void xmpp_room_destroy(const char *room, const char *venue, const char *reason)
+{
+  LmMessage *iq;
+  LmMessageNode *query, *x;
+
+  if (!lm_connection_is_authenticated(lconnection) || !room) return;
+
+  iq = lm_message_new_with_sub_type(room, LM_MESSAGE_TYPE_IQ,
+                                    LM_MESSAGE_SUB_TYPE_SET);
+  query = lm_message_node_add_child(iq->node, "query", NULL);
+  lm_message_node_set_attribute(query, "xmlns",
+                                "http://jabber.org/protocol/muc#owner");
+  x = lm_message_node_add_child(query, "destroy", NULL);
+
+  if (venue && *venue)
+    lm_message_node_set_attribute(x, "jid", venue);
+
+  if (reason)
+    lm_message_node_add_child(x, "reason", reason);
+
+  lm_connection_send(lconnection, iq, NULL);
+  lm_message_unref(iq);
+}
+
+//  muc_get_item_info(...)
+// Get room member's information from xmlndata.
+// The variables must be initialized before calling this function,
+// because they are not touched if the relevant information is missing.
+static void muc_get_item_info(const char *from, LmMessageNode *xmldata,
+                              enum imrole *mbrole, enum imaffiliation *mbaffil,
+                              const char **mbjid, const char **mbnick,
+                              const char **actorjid, const char **reason)
+{
+  LmMessageNode *y, *z;
+  const char *p;
+
+  y = lm_message_node_find_child(xmldata, "item");
+  if (!y)
+    return;
+
+  p = lm_message_node_get_attribute(y, "affiliation");
+  if (p) {
+    if (!strcmp(p, "owner"))        *mbaffil = affil_owner;
+    else if (!strcmp(p, "admin"))   *mbaffil = affil_admin;
+    else if (!strcmp(p, "member"))  *mbaffil = affil_member;
+    else if (!strcmp(p, "outcast")) *mbaffil = affil_outcast;
+    else if (!strcmp(p, "none"))    *mbaffil = affil_none;
+    else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown affiliation \"%s\"",
+                      from, p);
+  }
+  p = lm_message_node_get_attribute(y, "role");
+  if (p) {
+    if (!strcmp(p, "moderator"))        *mbrole = role_moderator;
+    else if (!strcmp(p, "participant")) *mbrole = role_participant;
+    else if (!strcmp(p, "visitor"))     *mbrole = role_visitor;
+    else if (!strcmp(p, "none"))        *mbrole = role_none;
+    else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown role \"%s\"",
+                      from, p);
+  }
+  *mbjid = lm_message_node_get_attribute(y, "jid");
+  *mbnick = lm_message_node_get_attribute(y, "nick");
+  // For kick/ban, there can be actor and reason tags
+  *reason = lm_message_node_get_child_value(y, "reason");
+  z = lm_message_node_find_child(y, "actor");
+  if (z)
+    *actorjid = lm_message_node_get_attribute(z, "jid");
+}
+
+//  muc_handle_join(...)
+// Handle a join event in a MUC room.
+// This function will return the new_member value TRUE if somebody else joins
+// the room (and FALSE if _we_ are joining the room).
+static bool muc_handle_join(const GSList *room_elt, const char *rname,
+                            const char *roomjid, const char *ournick,
+                            enum room_printstatus printstatus,
+                            time_t usttime, int log_muc_conf)
+{
+  bool new_member = FALSE; // True if somebody else joins the room (not us)
+  gchar *mbuf;
+
+  if (!buddy_getinsideroom(room_elt->data)) {
+    // We weren't inside the room yet.  Now we are.
+    // However, this could be a presence packet from another room member
+
+    buddy_setinsideroom(room_elt->data, TRUE);
+    // Set the message flag unless we're already in the room buffer window
+    scr_setmsgflag_if_needed(roomjid, FALSE);
+    // Add a message to the tracelog file
+    mbuf = g_strdup_printf("You have joined %s as \"%s\"", roomjid, ournick);
+    scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf);
+    g_free(mbuf);
+    mbuf = g_strdup_printf("You have joined as \"%s\"", ournick);
+
+    // The 1st presence message could be for another room member
+    if (strcmp(ournick, rname)) {
+      // Display current mbuf and create a new message for the member
+      // Note: the usttime timestamp is related to the other member,
+      //       so we use 0 here.
+      scr_WriteIncomingMessage(roomjid, mbuf, 0,
+                               HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
+      if (log_muc_conf)
+        hlog_write_message(roomjid, 0, -1, mbuf);
+      g_free(mbuf);
+      if (printstatus != status_none)
+        mbuf = g_strdup_printf("%s has joined", rname);
+      else
+        mbuf = NULL;
+      new_member = TRUE;
+    }
+  } else {
+    mbuf = NULL;
+    if (strcmp(ournick, rname)) {
+      if (printstatus != status_none)
+        mbuf = g_strdup_printf("%s has joined", rname);
+      new_member = TRUE;
+    }
+  }
+
+  if (mbuf) {
+    guint msgflags = HBB_PREFIX_INFO;
+    if (!settings_opt_get_int("muc_flag_joins"))
+      msgflags |= HBB_PREFIX_NOFLAG;
+    scr_WriteIncomingMessage(roomjid, mbuf, usttime, msgflags, 0);
+    if (log_muc_conf)
+      hlog_write_message(roomjid, 0, -1, mbuf);
+    g_free(mbuf);
+  }
+
+  return new_member;
+}
+
+static void handle_muc_presence(const char *from, LmMessageNode *xmldata,
+                                const char *roomjid, const char *rname,
+                                enum imstatus ust, const char *ustmsg,
+                                time_t usttime, char bpprio)
+{
+  LmMessageNode *y;
+  const char *p;
+  char *mbuf;
+  const char *ournick;
+  enum imrole mbrole = role_none;
+  enum imaffiliation mbaffil = affil_none;
+  enum room_printstatus printstatus;
+  enum room_autowhois autowhois;
+  const char *mbjid = NULL, *mbnick = NULL;
+  const char *actorjid = NULL, *reason = NULL;
+  bool new_member = FALSE; // True if somebody else joins the room (not us)
+  guint statuscode = 0;
+  guint nickchange = 0;
+  GSList *room_elt;
+  int log_muc_conf;
+  guint msgflags;
+
+  log_muc_conf = settings_opt_get_int("log_muc_conf");
+
+  room_elt = roster_find(roomjid, jidsearch, 0);
+  if (!room_elt) {
+    // Add room if it doesn't already exist
+    // It shouldn't happen, there is probably something wrong (server or
+    // network issue?)
+    room_elt = roster_add_user(roomjid, NULL, NULL, ROSTER_TYPE_ROOM,
+                               sub_none, -1);
+    scr_LogPrint(LPRINT_LOGNORM, "Strange MUC presence message");
+  } else {
+    // Make sure this is a room (it can be a conversion user->room)
+    buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
+  }
+
+  // Get room member's information
+  muc_get_item_info(from, xmldata, &mbrole, &mbaffil, &mbjid, &mbnick,
+                    &actorjid, &reason);
+
+  // Get our room nickname
+  ournick = buddy_getnickname(room_elt->data);
+
+  if (!ournick) {
+    // It shouldn't happen, probably a server issue
+    mbuf = g_strdup_printf("Unexpected groupchat packet!");
+
+    scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf);
+    scr_WriteIncomingMessage(roomjid, mbuf, 0, HBB_PREFIX_INFO, 0);
+    g_free(mbuf);
+    // Send back an unavailable packet
+    xmpp_setstatus(offline, roomjid, "", TRUE);
+    scr_DrawRoster();
+    return;
+  }
+
+  // Get the status code
+  // 201: a room has been created
+  // 301: the user has been banned from the room
+  // 303: new room nickname
+  // 307: the user has been kicked from the room
+  // 321,322,332: the user has been removed from the room
+  y = lm_message_node_find_child(xmldata, "status");
+  if (y) {
+    p = lm_message_node_get_attribute(y, "code");
+    if (p)
+      statuscode = atoi(p);
+  }
+
+  // Get the room's "print_status" settings
+  printstatus = buddy_getprintstatus(room_elt->data);
+  if (printstatus == status_default) {
+    printstatus = (guint) settings_opt_get_int("muc_print_status");
+    if (printstatus > 3)
+      printstatus = status_default;
+  }
+
+  // A new room has been created; accept MUC default config
+  if (statuscode == 201)
+    xmpp_room_unlock(roomjid);
+
+  // Check for nickname change
+  if (statuscode == 303 && mbnick) {
+    mbuf = g_strdup_printf("%s is now known as %s", rname, mbnick);
+    scr_WriteIncomingMessage(roomjid, mbuf, usttime,
+                             HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
+    if (log_muc_conf)
+      hlog_write_message(roomjid, 0, -1, mbuf);
+    g_free(mbuf);
+    buddy_resource_setname(room_elt->data, rname, mbnick);
+    // Maybe it's _our_ nickname...
+    if (ournick && !strcmp(rname, ournick))
+      buddy_setnickname(room_elt->data, mbnick);
+    nickchange = TRUE;
+  }
+
+  // Check for departure/arrival
+  if (!mbnick && ust == offline) {
+    // Somebody is leaving
+    enum { leave=0, kick, ban } how = leave;
+    bool we_left = FALSE;
+
+    if (statuscode == 307)
+      how = kick;
+    else if (statuscode == 301)
+      how = ban;
+
+    // If this is a leave, check if it is ourself
+    if (ournick && !strcmp(rname, ournick)) {
+      we_left = TRUE; // _We_ have left! (kicked, banned, etc.)
+      buddy_setinsideroom(room_elt->data, FALSE);
+      buddy_setnickname(room_elt->data, NULL);
+      buddy_del_all_resources(room_elt->data);
+      buddy_settopic(room_elt->data, NULL);
+      scr_UpdateChatStatus(FALSE);
+      update_roster = TRUE;
+    }
+
+    // The message depends on _who_ left, and _how_
+    if (how) {
+      gchar *mbuf_end;
+      // Forced leave
+      if (actorjid) {
+        mbuf_end = g_strdup_printf("%s from %s by <%s>.\nReason: %s",
+                                   (how == ban ? "banned" : "kicked"),
+                                   roomjid, actorjid, reason);
+      } else {
+        mbuf_end = g_strdup_printf("%s from %s.",
+                                   (how == ban ? "banned" : "kicked"),
+                                   roomjid);
+      }
+      if (we_left)
+        mbuf = g_strdup_printf("You have been %s", mbuf_end);
+      else
+        mbuf = g_strdup_printf("%s has been %s", rname, mbuf_end);
+
+      g_free(mbuf_end);
+    } else {
+      // Natural leave
+      if (we_left) {
+        LmMessageNode *destroynode = lm_message_node_find_child(xmldata,
+                                                                "destroy");
+        if (destroynode) {
+          if ((reason = lm_message_node_get_child_value(destroynode,
+                                                       "reason"))) {
+            mbuf = g_strdup_printf("You have left %s, "
+                                   "the room has been destroyed: %s",
+                                   roomjid, reason);
+          } else {
+            mbuf = g_strdup_printf("You have left %s, "
+                                   "the room has been destroyed", roomjid);
+          }
+        } else {
+          mbuf = g_strdup_printf("You have left %s", roomjid);
+        }
+      } else {
+        if (ust != offline) {
+          // This can happen when a network failure occurs,
+          // this isn't an official leave but the user isn't there anymore.
+          mbuf = g_strdup_printf("%s has disappeared!", rname);
+          ust = offline;
+        } else {
+          if (ustmsg)
+            mbuf = g_strdup_printf("%s has left: %s", rname, ustmsg);
+          else
+            mbuf = g_strdup_printf("%s has left", rname);
+        }
+      }
+    }
+
+    // Display the mbuf message if we're concerned
+    // or if the print_status isn't set to none.
+    if (we_left || printstatus != status_none) {
+      msgflags = HBB_PREFIX_INFO;
+      if (!we_left && settings_opt_get_int("muc_flag_joins") != 2)
+        msgflags |= HBB_PREFIX_NOFLAG;
+      scr_WriteIncomingMessage(roomjid, mbuf, usttime, msgflags, 0);
+    }
+
+    if (log_muc_conf)
+      hlog_write_message(roomjid, 0, -1, mbuf);
+
+    if (we_left) {
+      scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf);
+      g_free(mbuf);
+      return;
+    }
+    g_free(mbuf);
+  } else if (buddy_getstatus(room_elt->data, rname) == offline &&
+             ust != offline) {
+    // Somebody is joining
+    new_member = muc_handle_join(room_elt, rname, roomjid, ournick,
+                                 printstatus, usttime, log_muc_conf);
+  } else {
+    // This is a simple member status change
+
+    if (printstatus == status_all && !nickchange) {
+      mbuf = g_strdup_printf("Member status has changed: %s [%c] %s", rname,
+                             imstatus2char[ust], ((ustmsg) ? ustmsg : ""));
+      scr_WriteIncomingMessage(roomjid, mbuf, usttime,
+                               HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
+      g_free(mbuf);
+    }
+  }
+
+  // Sanity check, shouldn't happen...
+  if (!rname)
+    return;
+
+  // Update room member status
+  roster_setstatus(roomjid, rname, bpprio, ust, ustmsg, usttime,
+                   mbrole, mbaffil, mbjid);
+
+  autowhois = buddy_getautowhois(room_elt->data);
+  if (autowhois == autowhois_default)
+    autowhois = (settings_opt_get_int("muc_auto_whois") ?
+                 autowhois_on : autowhois_off);
+
+  if (new_member && autowhois == autowhois_on) {
+    // FIXME: This will fail for some UTF-8 nicknames.
+    gchar *joiner_nick = from_utf8(rname);
+    cmd_room_whois(room_elt->data, joiner_nick, FALSE);
+    g_free(joiner_nick);
+  }
+
+  scr_DrawRoster();
+}
+
+static void roompresence(gpointer room, void *presencedata)
+{
+  const char *bjid;
+  const char *nickname;
+  char *to;
+  struct T_presence *pres = presencedata;
+
+  if (!buddy_getinsideroom(room))
+    return;
+
+  bjid = buddy_getjid(room);
+  if (!bjid) return;
+  nickname = buddy_getnickname(room);
+  if (!nickname) return;
+
+  to = g_strdup_printf("%s/%s", bjid, nickname);
+  xmpp_setstatus(pres->st, to, pres->msg, TRUE);
+  g_free(to);
+}
+
+//  got_invite(from, to, reason, passwd)
+// This function should be called when receiving an invitation from user
+// "from", to enter the room "to".  Optional reason and room password can
+// be provided.
+static void got_invite(const char* from, const char *to, const char* reason,
+                       const char* passwd)
+{
+  eviqs *evn;
+  event_muc_invitation *invitation;
+  GString *sbuf;
+  char *barejid;
+  GSList *room_elt;
+
+  sbuf = g_string_new("");
+  if (reason) {
+    g_string_printf(sbuf,
+                    "Received an invitation to <%s>, from <%s>, reason: %s",
+                    to, from, reason);
+  } else {
+    g_string_printf(sbuf, "Received an invitation to <%s>, from <%s>",
+                    to, from);
+  }
+
+  barejid = jidtodisp(from);
+  scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0);
+  scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str);
+
+  evn = evs_new(EVS_TYPE_INVITATION, EVS_MAX_TIMEOUT);
+  if (evn) {
+    evn->callback = &evscallback_invitation;
+    invitation = g_new(event_muc_invitation, 1);
+    invitation->to = g_strdup(to);
+    invitation->from = g_strdup(from);
+    invitation->passwd = g_strdup(passwd);
+    invitation->reason = g_strdup(reason);
+    evn->data = invitation;
+    evn->desc = g_strdup_printf("<%s> invites you to %s ", from, to);
+    g_string_printf(sbuf, "Please use /event %s accept|reject", evn->id);
+  } else {
+    g_string_printf(sbuf, "Unable to create a new event!");
+  }
+  scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0);
+  scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str);
+  g_string_free(sbuf, TRUE);
+  g_free(barejid);
+
+  // Make sure the MUC room barejid is a room in the roster
+  barejid = jidtodisp(to);
+  room_elt = roster_find(barejid, jidsearch, 0);
+  if (room_elt)
+    buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
+
+  g_free(barejid);
+}
+
+
+// Specific MUC message handling (for example invitation processing)
+static void got_muc_message(const char *from, LmMessageNode *x)
+{
+  LmMessageNode *invite = lm_message_node_get_child(x, "invite");
+  if (invite)
+  {
+    const char *invite_from;
+    const char *reason = NULL;
+    const char *password = NULL;
+
+    invite_from = lm_message_node_get_attribute(invite, "from");
+    reason = lm_message_node_get_child_value(invite, "reason");
+    password = lm_message_node_get_child_value(invite, "password");
+    if (invite_from)
+      got_invite(invite_from, from, reason, password);
+  }
+  // TODO
+  // handle status code = 100 ( not anonymous )
+  // handle status code = 170 ( changement de config )
+  // 10.2.1 Notification of Configuration Changes
+  // declined invitation
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/xmpp_s10n.c	Sun Oct 11 15:38:32 2009 +0200
@@ -0,0 +1,63 @@
+/* See xmpp.c file for copyright and license details. */
+
+//  xmpp_send_s10n(jid, subtype)
+// Send a s10n message with the passed subtype
+void xmpp_send_s10n(const char *bjid, LmMessageSubType type)
+{
+  LmMessage *x = lm_message_new_with_sub_type(bjid,
+                                              LM_MESSAGE_TYPE_PRESENCE,
+                                              type);
+  lm_connection_send(lconnection, x, NULL);
+  lm_message_unref(x);
+}
+
+static int evscallback_subscription(eviqs *evp, guint evcontext)
+{
+  char *barejid;
+  char *buf;
+
+  if (evcontext == EVS_CONTEXT_TIMEOUT) {
+    scr_LogPrint(LPRINT_LOGNORM, "Event %s timed out, cancelled.",
+                 evp->id);
+    return 0;
+  }
+  if (evcontext == EVS_CONTEXT_CANCEL) {
+    scr_LogPrint(LPRINT_LOGNORM, "Event %s cancelled.", evp->id);
+    return 0;
+  }
+  if (!(evcontext & EVS_CONTEXT_USER))
+    return 0;
+
+  // Sanity check
+  if (!evp->data) {
+    // Shouldn't happen, data should be set to the barejid.
+    scr_LogPrint(LPRINT_LOGNORM, "Error in evs callback.");
+    return 0;
+  }
+
+  // Ok, let's work now.
+  // evcontext: 0, 1 == reject, accept
+
+  barejid = evp->data;
+
+  if (evcontext & ~EVS_CONTEXT_USER) {
+    // Accept subscription request
+    xmpp_send_s10n(barejid, LM_MESSAGE_SUB_TYPE_SUBSCRIBED);
+    buf = g_strdup_printf("<%s> is allowed to receive your presence updates",
+                          barejid);
+  } else {
+    // Reject subscription request
+    xmpp_send_s10n(barejid, LM_MESSAGE_SUB_TYPE_UNSUBSCRIBED);
+    buf = g_strdup_printf("<%s> won't receive your presence updates", barejid);
+    if (settings_opt_get_int("delete_on_reject")) {
+      // Remove the buddy from the roster if there is no current subscription
+      if (roster_getsubscription(barejid) == sub_none)
+        xmpp_delbuddy(barejid);
+    }
+  }
+  scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_INFO, 0);
+  scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
+  g_free(buf);
+  return 0;
+}
+