changeset 25:bf3d6e241714

[/trunk] Changeset 41 by mikael * Add libjabber to trunk. Let the game begin! :-)
author mikael
date Sun, 27 Mar 2005 20:18:21 +0000
parents e88b15cbf2de
children 8588f5a4b638
files mcabber/connwrap/Makefile.am mcabber/connwrap/Makefile.in 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/install-sh mcabber/libjabber/Makefile.am mcabber/libjabber/Makefile.in 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
diffstat 53 files changed, 21517 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/connwrap/Makefile.am	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,7 @@
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/connwrap/Makefile.in	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,420 @@
+# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+CC = @CC@
+CXX = @CXX@
+LIBGNUTLS_EXTRA_CFLAGS = @LIBGNUTLS_EXTRA_CFLAGS@
+LIBGNUTLS_EXTRA_CONFIG = @LIBGNUTLS_EXTRA_CONFIG@
+LIBGNUTLS_EXTRA_LIBS = @LIBGNUTLS_EXTRA_LIBS@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+
+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
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs
+CONFIG_CLEAN_FILES = 
+LIBRARIES =  $(noinst_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) 
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libconnwrap_a_LIBADD = 
+libconnwrap_a_OBJECTS =  connwrap.o md5.o
+AR = ar
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  Makefile.am Makefile.in aclocal.m4 configure configure.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gnutar
+GZIP_ENV = --best
+DEP_FILES =  .deps/connwrap.P .deps/md5.P
+SOURCES = $(libconnwrap_a_SOURCES)
+OBJECTS = $(libconnwrap_a_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+	cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+	cd $(top_builddir) \
+	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4):  configure.in 
+	cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+	cd $(srcdir) && $(AUTOCONF)
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+.s.o:
+	$(COMPILE) -c $<
+
+.S.o:
+	$(COMPILE) -c $<
+
+mostlyclean-compile:
+	-rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+	-rm -f *.tab.c
+
+maintainer-clean-compile:
+
+libconnwrap.a: $(libconnwrap_a_OBJECTS) $(libconnwrap_a_DEPENDENCIES)
+	-rm -f libconnwrap.a
+	$(AR) cru libconnwrap.a $(libconnwrap_a_OBJECTS) $(libconnwrap_a_LIBADD)
+	$(RANLIB) libconnwrap.a
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive  \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+	@set fnord $(MAKEFLAGS); amf=$$2; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	   || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+	@set fnord $(MAKEFLAGS); amf=$$2; \
+	dot_seen=no; \
+	rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+	  rev="$$subdir $$rev"; \
+	  test "$$subdir" != "." || dot_seen=yes; \
+	done; \
+	test "$$dot_seen" = "no" && rev=". $$rev"; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	   || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+	list='$(SOURCES) $(HEADERS)'; \
+	unique=`for i in $$list; do echo $$i; done | \
+	  awk '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	here=`pwd` && cd $(srcdir) \
+	  && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+   if test "$$subdir" = .; then :; else \
+	    test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+   fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS)'; \
+	unique=`for i in $$list; do echo $$i; done | \
+	  awk '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+	  || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+	-rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	-rm -rf $(distdir)
+	GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+	mkdir $(distdir)/=build
+	mkdir $(distdir)/=inst
+	dc_install_base=`cd $(distdir)/=inst && pwd`; \
+	cd $(distdir)/=build \
+	  && ../configure --srcdir=.. --prefix=$$dc_install_base \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist
+	-rm -rf $(distdir)
+	@banner="$(distdir).tar.gz is ready for distribution"; \
+	dashes=`echo "$$banner" | sed s/./=/g`; \
+	echo "$$dashes"; \
+	echo "$$banner"; \
+	echo "$$dashes"
+dist: distdir
+	-chmod -R a+r $(distdir)
+	GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+	-rm -rf $(distdir)
+dist-all: distdir
+	-chmod -R a+r $(distdir)
+	GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+	-rm -rf $(distdir)
+distdir: $(DISTFILES)
+	-rm -rf $(distdir)
+	mkdir $(distdir)
+	-chmod 777 $(distdir)
+	here=`cd $(top_builddir) && pwd`; \
+	top_distdir=`cd $(distdir) && pwd`; \
+	distdir=`cd $(distdir) && pwd`; \
+	cd $(top_srcdir) \
+	  && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile
+	@for file in $(DISTFILES); do \
+	  d=$(srcdir); \
+	  if test -d $$d/$$file; then \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+	    || cp -p $$d/$$file $(distdir)/$$file || :; \
+	  fi; \
+	done
+	for subdir in $(SUBDIRS); do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d $(distdir)/$$subdir \
+	    || mkdir $(distdir)/$$subdir \
+	    || exit 1; \
+	    chmod 777 $(distdir)/$$subdir; \
+	    (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+	-rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+	@echo '$(COMPILE) -c $<'; \
+	$(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+	@-cp .deps/$(*F).pp .deps/$(*F).P; \
+	tr ' ' '\012' < .deps/$(*F).pp \
+	  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+	    >> .deps/$(*F).P; \
+	rm .deps/$(*F).pp
+
+%.lo: %.c
+	@echo '$(LTCOMPILE) -c $<'; \
+	$(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+	@-sed -e 's/^\([^:]*\)\.o[ 	]*:/\1.lo \1.o :/' \
+	  < .deps/$(*F).pp > .deps/$(*F).P; \
+	tr ' ' '\012' < .deps/$(*F).pp \
+	  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+	    >> .deps/$(*F).P; \
+	rm -f .deps/$(*F).pp
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-exec-am:
+install-exec: install-exec-recursive
+
+install-data-am:
+install-data: install-data-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am:
+uninstall: uninstall-recursive
+all-am: Makefile $(LIBRARIES)
+all-redirect: all-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-rm -f Makefile $(CONFIG_CLEAN_FILES)
+	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
+		mostlyclean-tags mostlyclean-depend mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am:  clean-noinstLIBRARIES clean-compile clean-tags clean-depend \
+		clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am:  distclean-noinstLIBRARIES distclean-compile \
+		distclean-tags distclean-depend distclean-generic \
+		clean-am
+
+distclean: distclean-recursive
+	-rm -f config.status
+
+maintainer-clean-am:  maintainer-clean-noinstLIBRARIES \
+		maintainer-clean-compile maintainer-clean-tags \
+		maintainer-clean-depend maintainer-clean-generic \
+		distclean-am
+	@echo "This command is intended for maintainers to use;"
+	@echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f config.status
+
+.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile install-data-recursive \
+uninstall-data-recursive install-exec-recursive \
+uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
+all-recursive check-recursive installcheck-recursive info-recursive \
+dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/connwrap/aclocal.m4	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,297 @@
+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.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/connwrap/configure	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,1893 @@
+#! /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
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/connwrap/configure.in	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,79 @@
+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)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/connwrap/connwrap.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,436 @@
+#include "connwrap.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>
+
+#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>
+
+#elif HAVE_GNUTLS
+
+#include <gnutls/openssl.h>
+#define HAVE_OPENSSL
+
+#endif
+
+static int in_http_connect = 0;
+
+#ifdef HAVE_OPENSSL
+
+static SSL_CTX *ctx = 0;
+
+typedef struct { int fd; SSL *ssl; } sslsock;
+
+static sslsock *socks = 0;
+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 0;
+}
+
+static sslsock *addsock(int fd) {
+    sslsock *p;
+    socks = (sslsock *) realloc(socks, sizeof(sslsock)*++sockcount);
+
+    p = &socks[sockcount-1];
+
+    if(!ctx) {
+	SSL_library_init();
+	SSL_load_error_strings();
+
+#ifdef HAVE_SSLEAY
+	SSLeay_add_all_algorithms();
+#else
+	OpenSSL_add_all_algorithms();
+#endif
+
+	ctx = SSL_CTX_new(SSLv23_method());
+    }
+
+    p->ssl = SSL_new(ctx);
+    SSL_set_fd(p->ssl, p->fd = fd);
+
+    return p;
+}
+
+static void delsock(int fd) {
+    int i, nsockcount;
+    sslsock *nsocks;
+
+    nsockcount = 0;
+    nsocks = (sslsock *) malloc(sizeof(sslsock)*(sockcount-1));
+
+    for(i = 0; i < sockcount; i++) {
+	if(socks[i].fd != fd) {
+	    nsocks[nsockcount++] = socks[i];
+	} else {
+	    SSL_free(socks[i].ssl);
+	}
+    }
+
+    free(socks);
+
+    socks = nsocks;
+    sockcount = nsockcount;
+}
+
+#endif
+
+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;
+
+    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;
+
+	sprintf(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 ");
+
+	    sprintf(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;
+    }
+#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_OPENSSL
+    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, &optlen) || optval)
+	    return -1;
+	}
+
+	if(!rc) {
+	    sslsock *p;
+	    if (*state & CW_CONNECT_SSL)
+		p = getsock(sockfd);
+	    else
+		p = addsock(sockfd);
+	    
+	    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;
+		}
+	    }
+	}
+	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 = connect(sockfd, serv_addr, addrlen);
+    else{ /* check if the socket is connected correctly */
+	int optlen = sizeof(int), optval;
+	if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &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, addrlen);
+
+	if(!rc) {
+	    sslsock *p = addsock(s);
+	    if(SSL_accept(p->ssl) != 1)
+		return -1;
+
+	}
+
+	return rc;
+    }
+#endif
+    return accept(s, addr, addrlen);
+}
+
+int cw_write(int fd, const void *buf, int count, int ssl) {
+#ifdef HAVE_OPENSSL
+    sslsock *p;
+
+    if(ssl)
+    if(p = getsock(fd))
+	return SSL_write(p->ssl, buf, count);
+#endif
+    return write(fd, buf, count);
+}
+
+int cw_read(int fd, void *buf, int count, int ssl) {
+#ifdef HAVE_OPENSSL
+    sslsock *p;
+
+    if(ssl)
+    if(p = getsock(fd))
+	return SSL_read(p->ssl, buf, count);
+#endif
+    return read(fd, buf, count);
+}
+
+int cw_close(int fd) {
+#ifdef HAVE_OPENSSL
+    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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/connwrap/connwrap.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,42 @@
+#ifndef __CONNWRAP_H__
+#define __CONNWRAP_H__
+
+#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);
+
+int cw_close(int fd);
+
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/connwrap/connwrap.spec	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,43 @@
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/connwrap/md5.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,408 @@
+/*
+  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));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/connwrap/md5.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,93 @@
+/*
+  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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/install-sh	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+		chmodcmd=""
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/Makefile.am	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,20 @@
+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
+
+if BUILD_JABBER
+
+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
+
+else
+
+liblibjabber_a_LIBADD = dummy.o
+
+dummy.c:
+	touch dummy.c
+
+endif
+
+SUBDIRS = 
+INCLUDES = -I$(top_srcdir)/../connwrap -I$(top_srcdir)/../connwrap-0.1
+CPPFLAGS = 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/Makefile.in	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,431 @@
+# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+CC = @CC@
+CXX = @CXX@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+
+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
+
+@BUILD_JABBER_TRUE@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
+
+@BUILD_JABBER_FALSE@liblibjabber_a_LIBADD = dummy.o
+
+SUBDIRS = 
+INCLUDES = -I$(top_srcdir)/../connwrap -I$(top_srcdir)/../connwrap-0.1
+CPPFLAGS = 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs
+CONFIG_CLEAN_FILES = 
+LIBRARIES =  $(noinst_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) 
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+@BUILD_JABBER_FALSE@liblibjabber_a_DEPENDENCIES =  dummy.o
+@BUILD_JABBER_TRUE@liblibjabber_a_OBJECTS =  jid.o log.o jutil.o str.o \
+@BUILD_JABBER_TRUE@expat.o hashtable.o genhash.o pproxy.o pool.o rate.o \
+@BUILD_JABBER_TRUE@xmlparse.o xstream.o xmltok.o xmlnode.o jconn.o \
+@BUILD_JABBER_TRUE@xmlrole.o jpacket.o snprintf.o socket.o sha.o
+AR = ar
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  Makefile.am Makefile.in aclocal.m4 configure configure.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gnutar
+GZIP_ENV = --best
+DEP_FILES =  .deps/expat.P .deps/genhash.P .deps/hashtable.P \
+.deps/jconn.P .deps/jid.P .deps/jpacket.P .deps/jutil.P .deps/log.P \
+.deps/pool.P .deps/pproxy.P .deps/rate.P .deps/sha.P .deps/snprintf.P \
+.deps/socket.P .deps/str.P .deps/xmlnode.P .deps/xmlparse.P \
+.deps/xmlrole.P .deps/xmltok.P .deps/xstream.P
+SOURCES = $(liblibjabber_a_SOURCES)
+OBJECTS = $(liblibjabber_a_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+	cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+	cd $(top_builddir) \
+	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4):  configure.in 
+	cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+	cd $(srcdir) && $(AUTOCONF)
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+.s.o:
+	$(COMPILE) -c $<
+
+.S.o:
+	$(COMPILE) -c $<
+
+mostlyclean-compile:
+	-rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+	-rm -f *.tab.c
+
+maintainer-clean-compile:
+
+liblibjabber.a: $(liblibjabber_a_OBJECTS) $(liblibjabber_a_DEPENDENCIES)
+	-rm -f liblibjabber.a
+	$(AR) cru liblibjabber.a $(liblibjabber_a_OBJECTS) $(liblibjabber_a_LIBADD)
+	$(RANLIB) liblibjabber.a
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive  \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+	@set fnord $(MAKEFLAGS); amf=$$2; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	   || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+	@set fnord $(MAKEFLAGS); amf=$$2; \
+	dot_seen=no; \
+	rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+	  rev="$$subdir $$rev"; \
+	  test "$$subdir" != "." || dot_seen=yes; \
+	done; \
+	test "$$dot_seen" = "no" && rev=". $$rev"; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	   || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+	list='$(SOURCES) $(HEADERS)'; \
+	unique=`for i in $$list; do echo $$i; done | \
+	  awk '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	here=`pwd` && cd $(srcdir) \
+	  && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+   if test "$$subdir" = .; then :; else \
+	    test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+   fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS)'; \
+	unique=`for i in $$list; do echo $$i; done | \
+	  awk '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+	  || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+	-rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	-rm -rf $(distdir)
+	GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+	mkdir $(distdir)/=build
+	mkdir $(distdir)/=inst
+	dc_install_base=`cd $(distdir)/=inst && pwd`; \
+	cd $(distdir)/=build \
+	  && ../configure --srcdir=.. --prefix=$$dc_install_base \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist
+	-rm -rf $(distdir)
+	@banner="$(distdir).tar.gz is ready for distribution"; \
+	dashes=`echo "$$banner" | sed s/./=/g`; \
+	echo "$$dashes"; \
+	echo "$$banner"; \
+	echo "$$dashes"
+dist: distdir
+	-chmod -R a+r $(distdir)
+	GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+	-rm -rf $(distdir)
+dist-all: distdir
+	-chmod -R a+r $(distdir)
+	GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+	-rm -rf $(distdir)
+distdir: $(DISTFILES)
+	-rm -rf $(distdir)
+	mkdir $(distdir)
+	-chmod 777 $(distdir)
+	here=`cd $(top_builddir) && pwd`; \
+	top_distdir=`cd $(distdir) && pwd`; \
+	distdir=`cd $(distdir) && pwd`; \
+	cd $(top_srcdir) \
+	  && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile
+	@for file in $(DISTFILES); do \
+	  d=$(srcdir); \
+	  if test -d $$d/$$file; then \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+	    || cp -p $$d/$$file $(distdir)/$$file || :; \
+	  fi; \
+	done
+	for subdir in $(SUBDIRS); do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d $(distdir)/$$subdir \
+	    || mkdir $(distdir)/$$subdir \
+	    || exit 1; \
+	    chmod 777 $(distdir)/$$subdir; \
+	    (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+	-rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+	@echo '$(COMPILE) -c $<'; \
+	$(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+	@-cp .deps/$(*F).pp .deps/$(*F).P; \
+	tr ' ' '\012' < .deps/$(*F).pp \
+	  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+	    >> .deps/$(*F).P; \
+	rm .deps/$(*F).pp
+
+%.lo: %.c
+	@echo '$(LTCOMPILE) -c $<'; \
+	$(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+	@-sed -e 's/^\([^:]*\)\.o[ 	]*:/\1.lo \1.o :/' \
+	  < .deps/$(*F).pp > .deps/$(*F).P; \
+	tr ' ' '\012' < .deps/$(*F).pp \
+	  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+	    >> .deps/$(*F).P; \
+	rm -f .deps/$(*F).pp
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-exec-am:
+install-exec: install-exec-recursive
+
+install-data-am:
+install-data: install-data-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am:
+uninstall: uninstall-recursive
+all-am: Makefile $(LIBRARIES)
+all-redirect: all-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-rm -f Makefile $(CONFIG_CLEAN_FILES)
+	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
+		mostlyclean-tags mostlyclean-depend mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am:  clean-noinstLIBRARIES clean-compile clean-tags clean-depend \
+		clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am:  distclean-noinstLIBRARIES distclean-compile \
+		distclean-tags distclean-depend distclean-generic \
+		clean-am
+
+distclean: distclean-recursive
+	-rm -f config.status
+
+maintainer-clean-am:  maintainer-clean-noinstLIBRARIES \
+		maintainer-clean-compile maintainer-clean-tags \
+		maintainer-clean-depend maintainer-clean-generic \
+		distclean-am
+	@echo "This command is intended for maintainers to use;"
+	@echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f config.status
+
+.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile install-data-recursive \
+uninstall-data-recursive install-exec-recursive \
+uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
+all-recursive check-recursive installcheck-recursive info-recursive \
+dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+@BUILD_JABBER_FALSE@dummy.c:
+@BUILD_JABBER_FALSE@	touch dummy.c
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/aclocal.m4	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,147 @@
+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])
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/asciitab.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,62 @@
+/*
+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,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/config.h.in	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,28 @@
+/* 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
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/configure	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,1469 @@
+#! /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
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/configure.in	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,14 @@
+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)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/expat.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,161 @@
+/*
+ *  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>
+
+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);
+    }
+}
+
+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;
+}
+
+void expat_charData(void* userdata, const char* s, int len)
+{
+    xmlnode *x = userdata;
+    xmlnode current = *x;
+
+    xmlnode_insert_cdata(current, s, len);
+}
+
+
+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 */
+}
+
+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 */
+}
+
+int xmlnode2file(char *file, xmlnode node)
+{
+    char *doc;
+    int fd, i;
+
+    if(file == NULL || node == NULL)
+        return -1;
+
+    fd = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0600);
+    if(fd < 0)
+        return -1;
+
+    doc = xmlnode2str(node);
+    i = write(fd,doc,strlen(doc));
+    if(i < 0)
+        return -1;
+
+    close(fd);
+    return 1;
+}
+
+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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/genhash.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,490 @@
+/*
+ *  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>
+
+/*****************************************************************************
+ * 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;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/hashtable.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,151 @@
+/*
+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;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/hashtable.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,69 @@
+/*
+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 *);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/iasciitab.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,63 @@
+/*
+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,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/jabber.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,322 @@
+/*
+ *  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.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 */
+
+
+/* --------------------------------------------------------- */
+/*                                                           */
+/* 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
+
+typedef struct jpacket_struct
+{
+    unsigned char type;
+    int           subtype;
+    int           flag;
+    void*         aux1;
+    xmlnode       x;
+    jid           to;
+    jid           from;
+    char*         iqns;
+    xmlnode       iq;
+    pool          p;
+} *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"}
+
+/* --------------------------------------------------------- */
+/*                                                           */
+/* 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_AUTH      "jabber:iq:auth"
+#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"
+
+
+/* --------------------------------------------------------- */
+/*                                                           */
+/* 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 */
+    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, 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);
+char *jab_reg(jconn j);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* INCL_JABBER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/jconn.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,536 @@
+/*
+ *  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"
+
+/* 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, 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->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->user->server, NETSOCKET_CLIENT, j->ssl);
+	else
+	    j->fd = make_nb_netsocket(j->port, j->user->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)) {
+	    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 || j->state == JCONN_STATE_OFF) return;
+
+    j->state = JCONN_STATE_OFF;
+    cw_close(j->fd);
+    j->fd = -1;
+    XML_ParserFree(j->parser);
+}
+
+/*
+ *  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;
+
+    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) {
+	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_reg -- register user
+ *
+ *  parameters
+ *      j -- connection
+ *
+ *  returns
+ *      id of the iq packet
+ */
+char *jab_reg(jconn j)
+{
+    xmlnode x,y,z;
+    char *hash, *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);
+	else
+	    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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/jid.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,287 @@
+/*
+ *  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"
+
+jid jid_safe(jid id)
+{
+    char *str;
+
+    if(strlen(id->server) == 0 || strlen(id->server) > 255)
+	return NULL;
+
+    /* 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 NULL;
+    }
+
+    /* cut off the user */
+    if(id->user != NULL && strlen(id->user) > 64)
+	id->user[64] = '\0';
+
+    /* 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 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 = pmalloc(p,sizeof(struct jid_struct));
+    id->full = id->server = id->user = id->resource = NULL;
+    id->p = p;
+    id->next = NULL;
+
+    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:
+	if(str != NULL && strlen(str) != 0)
+	    id->resource = pstrdup(id->p, str);
+	else
+	    id->resource = NULL;
+	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(id) == NULL)
+	    id->user = old; /* revert if invalid */
+	break;
+    case JID_SERVER:
+	old = id->server;
+	id->server = pstrdup(id->p, str);
+	if(jid_safe(id) == NULL)
+	    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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/jpacket.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,132 @@
+/*
+ *  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"
+
+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);
+}
+
+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(*val == 's' || *val == 'u')
+	    p->type = JPACKET_S10N;
+	else if(strcmp(val,"available") == 0)
+	{ /* someone is using type='available' which is frowned upon */
+	    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;
+}
+
+
+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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/jutil.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,247 @@
+#include "jabber.h"
+
+/* util for making presence packets */
+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;
+    }
+    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;
+}
+
+/* util for making IQ packets */
+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;
+}
+
+/* util for making message packets */
+xmlnode jutil_msgnew(char *type, char *to, char *subj, char *body)
+{
+    xmlnode msg;
+
+    msg = xmlnode_new_tag("message");
+    xmlnode_put_attrib (msg, "type", type);
+    xmlnode_put_attrib (msg, "to", to);
+
+    if (subj)
+    {
+	xmlnode_insert_cdata (xmlnode_insert_tag (msg, "subject"), subj, strlen (subj));
+    }
+
+    xmlnode_insert_cdata (xmlnode_insert_tag (msg, "body"), body, strlen (body));
+
+    return msg;
+}
+
+/* util for making stream packets */
+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 a presence packet */
+int jutil_priority(xmlnode x)
+{
+    char *str;
+    int p;
+
+    if(x == NULL)
+	return -1;
+
+    if(xmlnode_get_attrib(x,"type") != NULL)
+	return -1;
+
+    x = xmlnode_get_tag(x,"priority");
+    if(x == NULL)
+	return 0;
+
+    str = xmlnode_get_data((x));
+    if(str == NULL)
+	return 0;
+
+    p = atoi(str);
+    if(p >= 0)
+	return p;
+    else
+	return 0;
+}
+
+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);
+}
+
+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;
+}
+
+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;
+}
+
+void jutil_error(xmlnode x, terror E)
+{
+    xmlnode err;
+    char code[4];
+
+    xmlnode_put_attrib(x,"type","error");
+    err = xmlnode_insert_tag(x,"error");
+
+    snprintf(code,4,"%d",E.code);
+    xmlnode_put_attrib(err,"code",code);
+    if(E.msg != NULL)
+	xmlnode_insert_cdata(err,E.msg,strlen(E.msg));
+
+    jutil_tofrom(x);
+}
+
+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));
+}
+
+#define KEYBUF 100
+
+char *jutil_regkey(char *key, char *seed)
+{
+    static char keydb[KEYBUF][41];
+    static char seeddb[KEYBUF][41];
+    static int last = -1;
+    char *str, strint[32];
+    int i;
+
+    /* blanket the keydb first time */
+    if(last == -1)
+    {
+	last = 0;
+	memset(&keydb,0,KEYBUF*41);
+	memset(&seeddb,0,KEYBUF*41);
+	srand(time(NULL));
+    }
+
+    /* creation phase */
+    if(key == NULL && seed != NULL)
+    {
+	/* create a random key hash and store it */
+	sprintf(strint,"%d",rand());
+	strcpy(keydb[last],shahash(strint));
+
+	/* store a hash for the seed associated w/ this key */
+	strcpy(seeddb[last],shahash(seed));
+
+	/* return it all */
+	str = keydb[last];
+	last++;
+	if(last == KEYBUF) last = 0;
+	return str;
+    }
+
+    /* validation phase */
+    str = shahash(seed);
+    for(i=0;i<KEYBUF;i++)
+	if(j_strcmp(keydb[i],key) == 0 && j_strcmp(seeddb[i],str) == 0)
+	{
+	    seeddb[i][0] = '\0'; /* invalidate this key */
+	    return keydb[i];
+	}
+
+    return NULL;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/latin1tab.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,62 @@
+/*
+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,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/libxode.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,446 @@
+#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 <syslog.h>
+#include <strings.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+
+#include "xmlparse.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_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(ZONE) 
+#define pool_heap(i) _pool_new_heap(i,ZONE) 
+#else
+} _pool, *pool;
+#define pool_heap(i) _pool_new_heap(i,NULL) 
+#define pool_new() _pool_new(NULL)
+#endif
+
+pool _pool_new(char *zone); /* new pool :) */
+pool _pool_new_heap(int size, char *zone); /* 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 char 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 */
+
+/* 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 {
+  unsigned long H[5];
+  unsigned long W[80];
+  int lenW;
+  unsigned long 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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/log.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,44 @@
+/*
+ *  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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/log.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,36 @@
+/*
+ *  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 */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/nametab.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,150 @@
+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,
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/pool.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,292 @@
+/*
+ *  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/
+ *  
+ *  2/27/00:3am, random plans by jer
+ *  
+ *  ok based on gprof, we really need some innovation here... my thoughs are this:
+ *  
+ *  most things are strings, so have a string-based true-blue garbage collector
+ *  one big global hash containing all the strings created by any pstrdup, returning const char *
+ *  a refcount on each string block
+ *  when a pool is freed, it moves down the refcount
+ *  garbage collector collects pools on the free stack, and runs through the hash for unused strings
+ *  j_strcmp can check for == (if they are both from a pstrdup)
+ *  
+ *  let's see... this would change:
+ *  pstrdup: do a hash lookup, success=return, fail=pmalloc & hash put
+ *  pool_free: 
+ *  
+ *  
+ *  
+ *  
+ *  
+ */
+
+#include "libxode.h"
+
+#ifdef POOL_DEBUG
+int pool__total = 0;
+int pool__ltotal = 0;
+HASHTABLE pool__disturbed = NULL;
+void *_pool__malloc(size_t size)
+{
+    pool__total++;
+    return malloc(size);
+}
+void _pool__free(void *block)
+{
+    pool__total--;
+    free(block);
+}
+#else
+#define _pool__malloc malloc
+#define _pool__free free
+#endif
+
+
+/* make an empty pool */
+pool _pool_new(char *zone)
+{
+    pool p;
+    while((p = _pool__malloc(sizeof(_pool))) == NULL) sleep(1);
+    p->cleanup = NULL;
+    p->heap = NULL;
+    p->size = 0;
+
+#ifdef POOL_DEBUG
+    p->lsize = -1;
+    p->zone[0] = '\0';
+    strcat(p->zone,zone);
+    sprintf(p->name,"%X",p);
+
+    if(pool__disturbed == NULL)
+	pool__disturbed = ghash_create(POOL_DEBUG,(KEYHASHFUNC)str_hash_code,(KEYCOMPAREFUNC)j_strcmp);
+    ghash_put(pool__disturbed,p->name,p);
+#endif
+
+    return p;
+}
+
+/* free a heap */
+void _pool_heap_free(void *arg)
+{
+    struct pheap *h = (struct pheap *)arg;
+
+    _pool__free(h->block);
+    _pool__free(h);
+}
+
+/* mem should always be freed last */
+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 */
+struct pfree *_pool_free(pool p, pool_cleaner f, void *arg)
+{
+    struct pfree *ret;
+
+    /* make the storage for the tracker */
+    while((ret = _pool__malloc(sizeof(struct pfree))) == NULL) sleep(1);
+    ret->f = f;
+    ret->arg = arg;
+    ret->next = NULL;
+
+    return ret;
+}
+
+/* create a heap and make sure it get's cleaned up */
+struct pheap *_pool_heap(pool p, int size)
+{
+    struct pheap *ret;
+    struct pfree *clean;
+
+    /* make the return heap */
+    while((ret = _pool__malloc(sizeof(struct pheap))) == NULL) sleep(1);
+    while((ret->block = _pool__malloc(size)) == NULL) sleep(1);
+    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;
+}
+
+pool _pool_new_heap(int size, char *zone)
+{
+    pool p;
+    p = _pool_new(zone);
+    p->heap = _pool_heap(p,size);
+    return p;
+}
+
+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))
+    {
+	while((block = _pool__malloc(size)) == NULL) sleep(1);
+	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;
+}
+
+void *pmalloc_x(pool p, int size, char c)
+{
+   void* result = pmalloc(p, size);
+   if (result != NULL)
+	   memset(result, c, size);
+   return result;
+}  
+
+/* easy safety utility (for creating blank mem for structs, etc) */
+void *pmalloco(pool p, int size)
+{
+    void *block = pmalloc(p, size);
+    memset(block, 0, size);
+    return block;
+}  
+
+/* XXX efficient: move this to const char * and then loop throug the existing heaps to see if src is within a block in this pool */
+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 move above, this one would actually return a new block */
+char *pstrdupx(pool p, const char *src)
+{
+    return pstrdup(p, src);
+}
+
+int pool_size(pool p)
+{
+    if(p == NULL) return 0;
+
+    return p->size;
+}
+
+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, ...);
+int _pool_stat(void *arg, const void *key, void *data)
+{
+    pool p = (pool)data;
+
+    if(p->lsize == -1)
+	debug_log("leak","%s: %X is a new pool",p->zone,p->name);
+    else if(p->size > p->lsize)
+	debug_log("leak","%s: %X grew %d",p->zone,p->name, p->size - p->lsize);
+    else if((int)arg)
+	debug_log("leak","%s: %X exists %d",p->zone,p->name, p->size);
+    p->lsize = p->size;
+    return 1;
+}
+
+void pool_stat(int full)
+{
+    ghash_walk(pool__disturbed,_pool_stat,(void *)full);
+    if(pool__total != pool__ltotal)
+	debug_log("leak","%d\ttotal missed mallocs",pool__total);
+    pool__ltotal = pool__total;
+    return;
+}
+#else
+void pool_stat(int full)
+{
+    return;
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/pproxy.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,198 @@
+/*
+ *  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"
+
+/* 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)
+{
+    char *res;
+    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,id);
+    }
+
+    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;
+
+    /* this is a presence from a resource, make an entry for just the user */
+    if(id->user != NULL && id->resource != NULL)
+    {
+	/* modify the id to just user@host */
+	res = id->resource;
+	jid_set(id,NULL,JID_RESOURCE);
+	curu = _ppdb_get(db,id);
+
+	/* no user entry, make one */
+	if(curu == NULL)
+	{
+	    curu = _ppdb_new(db->p,id);
+	    curu->next = db->next;
+	    db->next = curu;
+	}
+
+	/* restore the id */
+	jid_set(id,res,JID_RESOURCE);
+
+	/* 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);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/rate.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,76 @@
+/*
+ *  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"
+
+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;
+}
+
+void jlimit_free(jlimit r)
+{
+    if(r != NULL)
+    {
+	if(r->key != NULL) free(r->key);
+	pool_free(r->p);
+    }
+}
+
+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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/sha.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,206 @@
+/* 
+ * 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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/snprintf.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,932 @@
+/* ====================================================================
+ * 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.
+ */
+
+#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;
+
+#define FALSE           0
+#define TRUE            1
+#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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/socket.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,237 @@
+/*
+ *  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"
+#include "connwrap.h"
+
+/* socket.c
+ *
+ * Simple wrapper to make socket creation easy.
+ * type = NETSOCKET_SERVER is local listening socket
+ * type = NETSOCKET_CLIENT is connection socket
+ * type = NETSOCKET_UDP
+ */
+
+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 != -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.  "flag" is 1 to close on exec, 0 to
+ * leave open across exec.
+ * -- EJB 7/31/2000
+ */
+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);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/str.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,378 @@
+/*
+ *  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"
+
+char *j_strdup(const char *str)
+{
+    if(str == NULL)
+        return NULL;
+    else
+        return strdup(str);
+}
+
+char *j_strcat(char *dest, char *txt)
+{
+    if(!txt) return(dest);
+
+    while(*txt)
+        *dest++ = *txt++;
+    *dest = '\0';
+
+    return(dest);
+}
+
+int j_strcmp(const char *a, const char *b)
+{
+    if(a == NULL || b == NULL)
+        return -1;
+    else
+        return strcmp(a, b);
+}
+
+int j_strcasecmp(const char *a, const char *b)
+{
+    if(a == NULL || b == NULL)
+        return -1;
+    else
+        return strcasecmp(a, b);
+}
+
+int j_strncmp(const char *a, const char *b, int i)
+{
+    if(a == NULL || b == NULL)
+        return -1;
+    else
+        return strncmp(a, b, i);
+}
+
+int j_strncasecmp(const char *a, const char *b, int i)
+{
+    if(a == NULL || b == NULL)
+        return -1;
+    else
+        return strncasecmp(a, b, i);
+}
+
+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((int)arg == (int)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((int)arg == (int)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<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;
+}
+
+void str_b64decode(char* str)
+{
+    char *cur;
+    int d, dlast, phase;
+    unsigned char c;
+    static int table[256] = {
+        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 00-0F */
+        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 10-1F */
+        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,  /* 20-2F */
+        52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,  /* 30-3F */
+        -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,  /* 40-4F */
+        15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,  /* 50-5F */
+        -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,  /* 60-6F */
+        41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,  /* 70-7F */
+        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 80-8F */
+        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 90-9F */
+        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* A0-AF */
+        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* B0-BF */
+        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* C0-CF */
+        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* D0-DF */
+        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* E0-EF */
+        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1   /* F0-FF */
+    };
+
+    phase = 0;
+    for (cur = str; *cur != '\0'; ++cur )
+    {
+        d = table[(int)*cur];
+        if(d != -1)
+        {
+            switch(phase)
+            {
+            case 0:
+                ++phase;
+                break;
+            case 1:
+                c = ((dlast << 2) | ((d & 0x30) >> 4));
+                *str++ = c;
+                ++phase;
+                break;
+            case 2:
+                c = (((dlast & 0xf) << 4) | ((d & 0x3c) >> 2));
+                *str++ = c;
+                ++phase;
+                break;
+            case 3:
+                c = (((dlast & 0x03 ) << 6) | d);
+                *str++ = c;
+                phase = 0;
+                break;
+            }
+            dlast = d;
+        }
+    }
+    *str = '\0';
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/utf8tab.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,63 @@
+/*
+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,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/xmldef.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,63 @@
+/*
+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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/xmlnode.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,795 @@
+/*
+ *  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"
+
+/* 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)pmalloc(p, sizeof(_xmlnode));
+    memset(result, '\0', 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 || 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;
+}
+
+static char* _xmlnode_merge(pool p, char* dest, unsigned int destsize, const char* src, unsigned int srcsize)
+{
+    char* result;
+    result = (char*)pmalloc(p, destsize + srcsize + 1);
+    memcpy(result, dest, destsize);
+    memcpy(result+destsize, src, srcsize);
+    result[destsize + srcsize] = '\0';
+
+    /* WARNING: major ugly hack: since we're throwing the old data away, let's jump in the pool and subtract it from the size, this is for xmlstream's big-node checking */
+    p->size -= destsize;
+
+    return result;
+}
+
+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
+ *  If last child of the parent is CDATA, merges CDATA nodes. Otherwise
+ *  creates a CDATA node, and appends it to the parent's child list.
+ *
+ *  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 == -1)
+        size = strlen(CDATA);
+
+    if ((parent->lastchild != NULL) && (parent->lastchild->type == NTYPE_CDATA))
+    {
+        result = parent->lastchild;
+        result->data = _xmlnode_merge(result->p, result->data, result->data_sz, CDATA, size);
+        result->data_sz = result->data_sz + size;
+    }
+    else
+    {
+        result = _xmlnode_insert(parent, "", 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
+ *              or any combination: "name/name/?attrib", 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)
+        return _xmlnode_search(parent->firstchild, name, NTYPE_TAG);
+
+    /* jer's note: why can't I modify the name directly, why do I have to strdup it?  damn c grrr! */
+    str = strdup(name);
+    slash = strstr(str, "/");
+    qmark = strstr(str, "?");
+    equals = strstr(str, "=");
+
+    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)
+{
+    xmlnode cur;
+
+    if(node == NULL) return NULL;
+
+    if(xmlnode_get_type(node) == NTYPE_TAG) /* loop till we find a CDATA */
+    {
+        for(cur = xmlnode_get_firstchild(node); cur != NULL; cur = xmlnode_get_nextsibling(cur))
+            if(xmlnode_get_type(cur) == NTYPE_CDATA)
+                return cur->data;
+    }else{
+        return node->data;
+    }
+    return NULL;
+}
+
+int xmlnode_get_datasz(xmlnode node)
+{
+    if (node != NULL)
+        return node->data_sz;
+    return (int)NULL;
+}
+
+int xmlnode_get_type(xmlnode node)
+{
+    if (node != NULL)
+        return node->type;
+    return (int)NULL;
+}
+
+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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/xmlparse.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,3250 @@
+/*
+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 < 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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/xmlparse.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,482 @@
+/*
+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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/xmlrole.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,1113 @@
+/*
+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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/xmlrole.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,111 @@
+/*
+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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/xmltok.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,1527 @@
+/*
+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 < 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 < 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[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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/xmltok.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,307 @@
+/*
+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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/xmltok_impl.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,71 @@
+/*
+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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/xmltok_impl_c.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,1746 @@
+/*
+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;
+
+    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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/xmltok_ns_c.h	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,115 @@
+/*
+ *  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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/libjabber/xstream.c	Sun Mar 27 20:18:21 2005 +0000
@@ -0,0 +1,219 @@
+/*
+ *  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>
+
+/* 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 do that */
+
+/******* internal expat callbacks *********/
+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;
+}
+
+
+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--;
+}
+
+
+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);
+}
+
+
+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 */
+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, (void *)_xstream_startElement, (void *)_xstream_endElement);
+    XML_SetCharacterDataHandler(newx->parser, (void *)_xstream_charData);
+    pool_cleanup(p, _xstream_cleanup, (void *)newx);
+
+    return newx;
+}
+
+/* attempts to parse the buff onto this stream firing events to the handler, returns the last known 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 */
+xmlnode xstream_header(char *namespace, char *to, char *from)
+{
+    xmlnode x;
+    char id[10];
+
+    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 :) [NO CHILDREN ALLOWED] */
+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;
+}
+