aboutsummaryrefslogtreecommitdiff
path: root/net-im/centericq
diff options
context:
space:
mode:
Diffstat (limited to 'net-im/centericq')
-rw-r--r--net-im/centericq/Makefile26
-rw-r--r--net-im/centericq/distinfo2
-rw-r--r--net-im/centericq/files/msn-Makefile.in32
-rw-r--r--net-im/centericq/files/msn-abstracthook.cc20
-rw-r--r--net-im/centericq/files/msn-config.h.in12
-rw-r--r--net-im/centericq/files/msn-configure72
-rw-r--r--net-im/centericq/files/msn-imcontroller.cc10
-rw-r--r--net-im/centericq/files/msn-libmsn5986
-rw-r--r--net-im/centericq/files/msn-msnhook.cc804
-rw-r--r--net-im/centericq/files/msn-msnhook.h92
-rw-r--r--net-im/centericq/files/msn-src::Makefile.in17
-rw-r--r--net-im/centericq/files/msn-src::hooks::Makefile.in34
-rw-r--r--net-im/centericq/files/patch-icqconf.cc11
-rw-r--r--net-im/centericq/files/patch-msn_bittybits.C28
-rw-r--r--net-im/centericq/files/patch-msn_core.C923
-rw-r--r--net-im/centericq/files/patch-msn_core.h123
-rw-r--r--net-im/centericq/files/patch-msn_interface.h20
-rw-r--r--net-im/centericq/files/patch-msnhook.cc98
-rw-r--r--net-im/centericq/files/patch-src:Makefile.in7
-rw-r--r--net-im/centericq/files/patch-yahoohook.cc11
-rw-r--r--net-im/centericq/pkg-descr4
21 files changed, 7102 insertions, 1230 deletions
diff --git a/net-im/centericq/Makefile b/net-im/centericq/Makefile
index 88ac280ecc01..3feee484d97e 100644
--- a/net-im/centericq/Makefile
+++ b/net-im/centericq/Makefile
@@ -7,8 +7,8 @@
#
PORTNAME= centericq
-PORTVERSION= 4.9.7
-PORTREVISION= 3
+PORTVERSION= 4.9.8
+PORTREVISION= 0
CATEGORIES= net
MASTER_SITES= http://centericq.de/archive/source/releases/
@@ -18,8 +18,6 @@ COMMENT= A text mode menu- and window-driven IM interface
LIB_DEPENDS= intl.5:${PORTSDIR}/devel/gettext \
iconv.3:${PORTSDIR}/converters/libiconv
-BROKEN= Does not fetch, will be removed after Feb 2
-
USE_OPENSSL= yes
USE_GMAKE= yes
GNU_CONFIGURE= yes
@@ -33,8 +31,22 @@ LIB_DEPENDS+= fribidi.0:${PORTSDIR}/converters/fribidi
CONFIGURE_ARGS+= --with-fribidi
.endif
-.if !defined(WITH_MSN)
-CONFIGURE_ARGS+= --disable-msn
+.if defined(WITH_MSN)
+CONFIGURE_ARGS+= --enable-msn
+EXTRA_PATCHES= ${.CURDIR}/files/msn-*
+pre-patch:
+ @${ECHO_CMD} "========================================================="
+ @${ECHO_CMD} "=====================Important !!!======================="
+ @${ECHO_CMD} "========================================================="
+ @${ECHO_CMD} "There may be some sticky legal issues with the new"
+ @${ECHO_CMD} "version of this protocol. Users should be aware that they"
+ @${ECHO_CMD} "might be in violation of the DMCA or other laws. If this"
+ @${ECHO_CMD} "is unacceptable, hit Ctrl-C now and remove WITH_MSN from"
+ @${ECHO_CMD} "your make flags. The FreeBSD group assumes no"
+ @${ECHO_CMD} "responsibility or liability for any losses or damages"
+ @${ECHO_CMD} "sustained by use or disuse of software in the ports tree."
+ @${ECHO_CMD} "========================================================="
+ @sleep 5
.endif
.if !defined(WITH_YAHOO)
@@ -61,7 +73,7 @@ CONFIGURE_ARGS+= --disable-rss
CONFIGURE_ARGS+= --disable-lj
.endif
-MAN1= centericq.1 cicqconv.1 cicqsync.1
+MAN1= cicqconv.1 cicqsync.1
post-patch:
.for file in kkconsui-0.1/include/conf.h kkstrtext-0.1/conf.h kksystr-0.1/include/conf.h
diff --git a/net-im/centericq/distinfo b/net-im/centericq/distinfo
index 0bdd0aebb983..831d6da26c11 100644
--- a/net-im/centericq/distinfo
+++ b/net-im/centericq/distinfo
@@ -1 +1 @@
-MD5 (centericq-4.9.7.tar.gz) = 09c1672c0c2e5ef7e8a94052a71c58cc
+MD5 (centericq-4.9.8.tar.gz) = 94e605d33f0dec7619bdfe6dad7b7a33
diff --git a/net-im/centericq/files/msn-Makefile.in b/net-im/centericq/files/msn-Makefile.in
new file mode 100644
index 000000000000..b7808b00e830
--- /dev/null
+++ b/net-im/centericq/files/msn-Makefile.in
@@ -0,0 +1,32 @@
+--- Makefile.in.orig Sat Oct 25 15:53:45 2003
++++ Makefile.in Mon Nov 3 20:14:01 2003
+@@ -92,10 +92,10 @@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
+
+-SUBDIRS = firetalk-0.1 kkconsui-0.1 kkstrtext-0.1 libicq2000-0.1 libjabber-0.1 libyahoo2-0.1 kksystr-0.1 connwrap-0.1 intl po contrib misc share src
++SUBDIRS = blip-0.1 firetalk-0.1 kkconsui-0.1 kkstrtext-0.1 libicq2000-0.1 libjabber-0.1 libyahoo2-0.1 kksystr-0.1 connwrap-0.1 intl po contrib misc share src
+
+ # END OF MOTOR DIST TARGETS #
+-EXTRA_DIST = centericq.1 centericq.motor config.rpath FAQ NEWS TODO README THANKS AUTHORS INSTALL ABOUT-NLS ChangeLog COPYING centericq.spec firetalk-0.1/* kkconsui-0.1/* kkstrtext-0.1/* libicq2000-0.1/* libjabber-0.1/* libyahoo2-0.1/* kksystr-0.1/* connwrap-0.1/*
++EXTRA_DIST = centericq.1 centericq.motor config.rpath FAQ NEWS TODO README THANKS AUTHORS INSTALL ABOUT-NLS ChangeLog COPYING centericq.spec blip-0.1/* firetalk-0.1/* kkconsui-0.1/* kkstrtext-0.1/* libicq2000-0.1/* libjabber-0.1/* libyahoo2-0.1/* kksystr-0.1/* connwrap-0.1/*
+ AUTOMAKE_OPTIONS = foreign
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+@@ -289,6 +289,7 @@
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile
+ $(mkinstalldirs) $(distdir)/connwrap-0.1 $(distdir)/firetalk-0.1 \
++ $(distdir)/blip-0.1 \
+ $(distdir)/kkconsui-0.1 $(distdir)/kkstrtext-0.1 \
+ $(distdir)/kksystr-0.1 $(distdir)/libicq2000-0.1 \
+ $(distdir)/libjabber-0.1 $(distdir)/libyahoo2-0.1
+@@ -388,7 +389,7 @@
+
+ dist-hook:
+ cd $(top_distdir); subs=`egrep "^[:space:]*SUBDIRS" Makefile.am | sed 's/SUBDIRS[ =]\+//g'`; \
+- echo "SUBDIRS = firetalk-0.1 kkconsui-0.1 kkstrtext-0.1 libicq2000-0.1 libjabber-0.1 libyahoo2-0.1 kksystr-0.1 connwrap-0.1 $$subs" >>.makefile.am; \
++ echo "SUBDIRS = blip-0.1 firetalk-0.1 kkconsui-0.1 kkstrtext-0.1 libicq2000-0.1 libjabber-0.1 libyahoo2-0.1 kksystr-0.1 connwrap-0.1 $$subs" >>.makefile.am; \
+ egrep -v "^[:space:]*SUBDIRS" Makefile.am >>.makefile.am; \
+ mv .makefile.am Makefile.am; autoconf && automake
+
diff --git a/net-im/centericq/files/msn-abstracthook.cc b/net-im/centericq/files/msn-abstracthook.cc
new file mode 100644
index 000000000000..111e87201af4
--- /dev/null
+++ b/net-im/centericq/files/msn-abstracthook.cc
@@ -0,0 +1,20 @@
+--- src/hooks/abstracthook.cc.orig Sun Oct 19 06:57:26 2003
++++ src/hooks/abstracthook.cc Mon Nov 3 19:54:31 2003
+@@ -31,6 +31,7 @@
+ #include "jabberhook.h"
+ #include "rsshook.h"
+ #include "ljhook.h"
++#include "msnhook.h"
+
+ #include "md5.h"
+
+@@ -325,6 +326,9 @@
+ #endif
+ #ifdef BUILD_LJ
+ case livejournal: return lhook;
++#endif
++#ifdef BUILD_MSN
++ case msn: return mhook;
+ #endif
+ }
+
diff --git a/net-im/centericq/files/msn-config.h.in b/net-im/centericq/files/msn-config.h.in
new file mode 100644
index 000000000000..44e77b5a4eb4
--- /dev/null
+++ b/net-im/centericq/files/msn-config.h.in
@@ -0,0 +1,12 @@
+--- config.h.in.orig Thu Oct 16 06:07:45 2003
++++ config.h.in Mon Nov 3 21:31:23 2003
+@@ -220,6 +220,9 @@
+ /* use gnutls */
+ #undef HAVE_GNUTLS
+
++/* build with msn support */
++#undef BUILD_MSN
++
+ /* build with yahoo support */
+ #undef BUILD_YAHOO
+
diff --git a/net-im/centericq/files/msn-configure b/net-im/centericq/files/msn-configure
new file mode 100644
index 000000000000..5fb5aa045f30
--- /dev/null
+++ b/net-im/centericq/files/msn-configure
@@ -0,0 +1,72 @@
+--- configure.orig Sat Oct 25 15:53:45 2003
++++ configure Mon Nov 3 20:21:06 2003
+@@ -27,6 +27,8 @@
+ ac_help="$ac_help
+ --with-libgnutls-extra-prefix=PFX Prefix where libgnutls-extra is installed (optional)"
+ ac_help="$ac_help
++ --enable-msn Build with MSN!"
++ac_help="$ac_help
+ --disable-yahoo Build without Yahoo!"
+ ac_help="$ac_help
+ --disable-aim Build without AIM"
+@@ -2365,6 +2367,14 @@
+ ;;
+ esac
+
++# Check whether --enable-msn or --disable-msn was given.
++if test "${enable_msn+set}" = set; then
++ enableval="$enable_msn"
++ build_msn="$enableval"
++else
++ build_msn="yes"
++fi
++
+ # Check whether --enable-yahoo or --disable-yahoo was given.
+ if test "${enable_yahoo+set}" = set; then
+ enableval="$enable_yahoo"
+@@ -2424,6 +2434,13 @@
+
+
+
++if test "x$build_msn" = xyes; then
++ BUILD_MSN_TRUE=
++ BUILD_MSN_FALSE='#'
++else
++ BUILD_MSN_TRUE='#'
++ BUILD_MSN_FALSE=
++fi
+
+ if test "x$build_yahoo" = xyes; then
+ BUILD_YAHOO_TRUE=
+@@ -2478,6 +2495,13 @@
+ BUILD_LJ_FALSE=
+ fi
+
++if test "$build_msn" = "yes"; then
++ cat >> confdefs.h <<\EOF
++#define BUILD_MSN 1
++EOF
++
++fi
++
+ if test "$build_yahoo" = "yes"; then
+ cat >> confdefs.h <<\EOF
+ #define BUILD_YAHOO 1
+@@ -4994,7 +5018,7 @@
+
+
+
+-subdirs="firetalk-0.1 kkconsui-0.1 kkstrtext-0.1 libicq2000-0.1 libjabber-0.1 libyahoo2-0.1 kksystr-0.1 connwrap-0.1"
++subdirs="firetalk-0.1 kkconsui-0.1 kkstrtext-0.1 libicq2000-0.1 libjabber-0.1 libyahoo2-0.1 kksystr-0.1 connwrap-0.1 blip-0.1"
+
+ trap '' 1 2 15
+ cat > confcache <<\EOF
+@@ -5538,7 +5562,7 @@
+ esac
+ done
+
+- for ac_config_dir in firetalk-0.1 kkconsui-0.1 kkstrtext-0.1 libicq2000-0.1 libjabber-0.1 libyahoo2-0.1 kksystr-0.1 connwrap-0.1; do
++ for ac_config_dir in firetalk-0.1 kkconsui-0.1 kkstrtext-0.1 libicq2000-0.1 libjabber-0.1 libyahoo2-0.1 kksystr-0.1 connwrap-0.1 blip-0.1; do
+
+ # Do not complain, so a configure script can configure whichever
+ # parts of a large source tree are present.
diff --git a/net-im/centericq/files/msn-imcontroller.cc b/net-im/centericq/files/msn-imcontroller.cc
new file mode 100644
index 000000000000..079d202ccaeb
--- /dev/null
+++ b/net-im/centericq/files/msn-imcontroller.cc
@@ -0,0 +1,10 @@
+--- src/imcontroller.cc.orig Thu Oct 16 07:40:18 2003
++++ src/imcontroller.cc Mon Nov 3 20:03:55 2003
+@@ -31,6 +31,7 @@
+ #include "jabberhook.h"
+ #include "icqcontacts.h"
+ #include "eventmanager.h"
++#include "msnhook.h"
+
+ #define clr(c) conf.getcolor(c)
+
diff --git a/net-im/centericq/files/msn-libmsn b/net-im/centericq/files/msn-libmsn
new file mode 100644
index 000000000000..1a85fe8384eb
--- /dev/null
+++ b/net-im/centericq/files/msn-libmsn
@@ -0,0 +1,5986 @@
+diff -ruN blip-0.1.orig/Makefile.am blip-0.1/Makefile.am
+--- blip-0.1.orig/Makefile.am Thu Jan 1 08:00:00 1970
++++ blip-0.1/Makefile.am Mon Nov 3 20:09:02 2003
+@@ -0,0 +1,10 @@
++noinst_LIBRARIES = libblip.a
++libblip_a_SOURCES = md5.c msn_bittybits.C msn_core.C
++EXTRA_DIST = md5.c msn_bittybits.C msn_core.C md5.h msn_bittybits.h msn_core.h msn_interface.h
++AUTOMAKE_OPTIONS = foreign
++
++if BUILD_MSN
++
++
++endif
++
+diff -ruN blip-0.1.orig/Makefile.in blip-0.1/Makefile.in
+--- blip-0.1.orig/Makefile.in Thu Jan 1 08:00:00 1970
++++ blip-0.1/Makefile.in Mon Nov 3 20:09:02 2003
+@@ -0,0 +1,364 @@
++# Makefile.in generated automatically by automake 1.4-p5 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 = libblip.a
++libblip_a_SOURCES = md5.c msn_bittybits.C msn_core.C
++EXTRA_DIST = md5.c msn_bittybits.C msn_core.C md5.h msn_bittybits.h msn_core.h msn_interface.h
++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)
++CPPFLAGS = @CPPFLAGS@
++LDFLAGS = @LDFLAGS@
++LIBS = @LIBS@
++libblip_a_LIBADD =
++libblip_a_OBJECTS = md5.o msn_bittybits.o msn_core.o
++AR = ar
++CXXFLAGS = @CXXFLAGS@
++CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
++CXXLD = $(CXX)
++CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
++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 \
++install-sh missing mkinstalldirs
++
++
++DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
++
++TAR = gtar
++GZIP_ENV = --best
++DEP_FILES = .deps/md5.P .deps/msn_bittybits.P .deps/msn_core.P
++SOURCES = $(libblip_a_SOURCES)
++OBJECTS = $(libblip_a_OBJECTS)
++
++all: all-redirect
++.SUFFIXES:
++.SUFFIXES: .C .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:
++
++libblip.a: $(libblip_a_OBJECTS) $(libblip_a_DEPENDENCIES)
++ -rm -f libblip.a
++ $(AR) cru libblip.a $(libblip_a_OBJECTS) $(libblip_a_LIBADD)
++ $(RANLIB) libblip.a
++.C.o:
++ $(CXXCOMPILE) -c $<
++
++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: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
++ tags=; \
++ here=`pwd`; \
++ 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
++
++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
++
++%.o: %.C
++ @echo '$(CXXCOMPILE) -c $<'; \
++ $(CXXCOMPILE) -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 '$(LTCXXCOMPILE) -c $<'; \
++ $(LTCXXCOMPILE) -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-am
++dvi-am:
++dvi: dvi-am
++check-am: all-am
++check: check-am
++installcheck-am:
++installcheck: installcheck-am
++install-exec-am:
++install-exec: install-exec-am
++
++install-data-am:
++install-data: install-data-am
++
++install-am: all-am
++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
++install: install-am
++uninstall-am:
++uninstall: uninstall-am
++all-am: Makefile $(LIBRARIES)
++all-redirect: all-am
++install-strip:
++ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
++installdirs:
++
++
++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-am
++
++clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-depend \
++ clean-generic mostlyclean-am
++
++clean: clean-am
++
++distclean-am: distclean-noinstLIBRARIES distclean-compile \
++ distclean-tags distclean-depend distclean-generic \
++ clean-am
++
++distclean: distclean-am
++ -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-am
++ -rm -f config.status
++
++.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
++clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
++mostlyclean-compile distclean-compile clean-compile \
++maintainer-clean-compile tags 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 \
++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:
+diff -ruN blip-0.1.orig/aclocal.m4 blip-0.1/aclocal.m4
+--- blip-0.1.orig/aclocal.m4 Thu Jan 1 08:00:00 1970
++++ blip-0.1/aclocal.m4 Mon Nov 3 20:09:02 2003
+@@ -0,0 +1,117 @@
++dnl aclocal.m4 generated automatically by aclocal 1.4-p5
++
++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([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, $missing_dir)
++AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
++AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
++AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
++AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
++AC_REQUIRE([AC_PROG_MAKE_SET])])
++
++#
++# 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])
++
+diff -ruN blip-0.1.orig/configure blip-0.1/configure
+--- blip-0.1.orig/configure Thu Jan 1 08:00:00 1970
++++ blip-0.1/configure Mon Nov 3 20:09:02 2003
+@@ -0,0 +1,1519 @@
++#! /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-msn Build without MSN"
++
++# 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.
++
++# 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:558: 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:611: 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:668: 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=blip
++
++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""... $ac_c" 1>&6
++echo "configure:714: checking for working aclocal" >&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 --version) < /dev/null > /dev/null 2>&1; then
++ ACLOCAL=aclocal
++ echo "$ac_t""found" 1>&6
++else
++ ACLOCAL="$missing_dir/missing aclocal"
++ echo "$ac_t""missing" 1>&6
++fi
++
++echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
++echo "configure:727: 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""... $ac_c" 1>&6
++echo "configure:740: checking for working automake" >&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 --version) < /dev/null > /dev/null 2>&1; then
++ AUTOMAKE=automake
++ echo "$ac_t""found" 1>&6
++else
++ AUTOMAKE="$missing_dir/missing automake"
++ echo "$ac_t""missing" 1>&6
++fi
++
++echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
++echo "configure:753: 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:766: 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:783: 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
++
++
++# Check whether --enable-msn or --disable-msn was given.
++if test "${enable_msn+set}" = set; then
++ enableval="$enable_msn"
++ build_msn="$enableval"
++else
++ build_msn="yes"
++fi
++
++
++
++if test "x$build_msn" = xyes; then
++ BUILD_MSN_TRUE=
++ BUILD_MSN_FALSE='#'
++else
++ BUILD_MSN_TRUE='#'
++ BUILD_MSN_FALSE=
++fi
++
++if test "$build_msn" = "yes"; then
++ # 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:833: 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:863: 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:914: 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:946: 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 957 "configure"
++#include "confdefs.h"
++
++main(){return(0);}
++EOF
++if { (eval echo configure:962: \"$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:988: 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:993: 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:1002: \"$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:1021: 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:1057: 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:1089: 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 1100 "configure"
++#include "confdefs.h"
++
++int main(){return(0);}
++EOF
++if { (eval echo configure:1105: \"$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:1131: 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:1136: 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:1145: \"$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:1164: 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
++
++for ac_declaration in \
++ ''\
++ '#include <stdlib.h>' \
++ 'extern "C" void std::exit (int) throw (); using std::exit;' \
++ 'extern "C" void std::exit (int); using std::exit;' \
++ 'extern "C" void exit (int) throw ();' \
++ 'extern "C" void exit (int);' \
++ 'void exit (int);'
++do
++ cat > conftest.$ac_ext <<EOF
++#line 1205 "configure"
++#include "confdefs.h"
++#include <stdlib.h>
++$ac_declaration
++int main() {
++exit (42);
++; return 0; }
++EOF
++if { (eval echo configure:1213: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++ :
++else
++ echo "configure: failed program was:" >&5
++ cat conftest.$ac_ext >&5
++ rm -rf conftest*
++ continue
++fi
++rm -f conftest*
++ cat > conftest.$ac_ext <<EOF
++#line 1223 "configure"
++#include "confdefs.h"
++$ac_declaration
++int main() {
++exit (42);
++; return 0; }
++EOF
++if { (eval echo configure:1230: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++ rm -rf conftest*
++ break
++else
++ echo "configure: failed program was:" >&5
++ cat conftest.$ac_ext >&5
++fi
++rm -f conftest*
++done
++if test -n "$ac_declaration"; then
++ echo '#ifdef __cplusplus' >>confdefs.h
++ echo $ac_declaration >>confdefs.h
++ echo '#endif' >>confdefs.h
++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%@BUILD_MSN_TRUE@%$BUILD_MSN_TRUE%g
++s%@BUILD_MSN_FALSE@%$BUILD_MSN_FALSE%g
++s%@CC@%$CC%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
++
+diff -ruN blip-0.1.orig/configure.in blip-0.1/configure.in
+--- blip-0.1.orig/configure.in Thu Jan 1 08:00:00 1970
++++ blip-0.1/configure.in Mon Nov 3 20:09:02 2003
+@@ -0,0 +1,14 @@
++AC_INIT(aclocal.m4)
++AM_INIT_AUTOMAKE(blip, 0.1)
++
++AC_PROG_RANLIB
++
++AC_ARG_ENABLE(msn, [ --disable-msn Build without MSN], build_msn="$enableval", build_msn="yes")
++AM_CONDITIONAL(BUILD_MSN, test "x$build_msn" = xyes)
++
++if test "$build_msn" = "yes"; then
++ AC_PROG_CC
++ AC_PROG_CXX
++fi
++
++AC_OUTPUT(Makefile)
+diff -ruN blip-0.1.orig/install-sh blip-0.1/install-sh
+--- blip-0.1.orig/install-sh Thu Jan 1 08:00:00 1970
++++ blip-0.1/install-sh Mon Nov 3 20:09:02 2003
+@@ -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
+diff -ruN blip-0.1.orig/md5.c blip-0.1/md5.c
+--- blip-0.1.orig/md5.c Thu Jan 1 08:00:00 1970
++++ blip-0.1/md5.c Mon Nov 3 20:09:02 2003
+@@ -0,0 +1,392 @@
++/*
++ 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
++
++ */
++/*$Id: md5.c,v 1.1.1.1 2002/12/09 08:48:19 konst Exp $ */
++/*
++ 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.
++ */
++
++#include "md5.h"
++
++#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.
++ */
++#include <string.h>
++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));
++}
+diff -ruN blip-0.1.orig/md5.h blip-0.1/md5.h
+--- blip-0.1.orig/md5.h Thu Jan 1 08:00:00 1970
++++ blip-0.1/md5.h Mon Nov 3 20:09:02 2003
+@@ -0,0 +1,94 @@
++/*
++ 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
++
++ */
++/*$Id: md5.h,v 1.1.1.1 2002/12/09 08:48:22 konst Exp $ */
++/*
++ 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 */
+diff -ruN blip-0.1.orig/missing blip-0.1/missing
+--- blip-0.1.orig/missing Thu Jan 1 08:00:00 1970
++++ blip-0.1/missing Mon Nov 3 20:09:02 2003
+@@ -0,0 +1,198 @@
++#! /bin/sh
++# Common stub for a few missing GNU programs while installing.
++# Copyright (C) 1996, 1997, 2001 Free Software Foundation, Inc.
++# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
++
++# 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
++# 02111-1307, USA.
++
++if test $# -eq 0; then
++ echo 1>&2 "Try \`$0 --help' for more information"
++ exit 1
++fi
++
++# In the cases where this matters, `missing' is being run in the
++# srcdir already.
++if test -f configure.in; then
++ configure_ac=configure.ac
++else
++ configure_ac=configure.in
++fi
++
++case "$1" in
++
++ -h|--h|--he|--hel|--help)
++ echo "\
++$0 [OPTION]... PROGRAM [ARGUMENT]...
++
++Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
++error status if there is no known handling for PROGRAM.
++
++Options:
++ -h, --help display this help and exit
++ -v, --version output version information and exit
++
++Supported PROGRAM values:
++ aclocal touch file \`aclocal.m4'
++ autoconf touch file \`configure'
++ autoheader touch file \`config.h.in'
++ automake touch all \`Makefile.in' files
++ bison create \`y.tab.[ch]', if possible, from existing .[ch]
++ flex create \`lex.yy.c', if possible, from existing .c
++ lex create \`lex.yy.c', if possible, from existing .c
++ makeinfo touch the output file
++ yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
++ ;;
++
++ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
++ echo "missing - GNU libit 0.0"
++ ;;
++
++ -*)
++ echo 1>&2 "$0: Unknown \`$1' option"
++ echo 1>&2 "Try \`$0 --help' for more information"
++ exit 1
++ ;;
++
++ aclocal)
++ echo 1>&2 "\
++WARNING: \`$1' is missing on your system. You should only need it if
++ you modified \`acinclude.m4' or \`$configure_ac'. You might want
++ to install the \`Automake' and \`Perl' packages. Grab them from
++ any GNU archive site."
++ touch aclocal.m4
++ ;;
++
++ autoconf)
++ echo 1>&2 "\
++WARNING: \`$1' is missing on your system. You should only need it if
++ you modified \`$configure_ac'. You might want to install the
++ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
++ archive site."
++ touch configure
++ ;;
++
++ autoheader)
++ echo 1>&2 "\
++WARNING: \`$1' is missing on your system. You should only need it if
++ you modified \`acconfig.h' or \`$configure_ac'. You might want
++ to install the \`Autoconf' and \`GNU m4' packages. Grab them
++ from any GNU archive site."
++ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' $configure_ac`
++ test -z "$files" && files="config.h"
++ touch_files=
++ for f in $files; do
++ case "$f" in
++ *:*) touch_files="$touch_files "`echo "$f" |
++ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
++ *) touch_files="$touch_files $f.in";;
++ esac
++ done
++ touch $touch_files
++ ;;
++
++ automake)
++ echo 1>&2 "\
++WARNING: \`$1' is missing on your system. You should only need it if
++ you modified \`Makefile.am', \`acinclude.m4' or \`$configure_ac'.
++ You might want to install the \`Automake' and \`Perl' packages.
++ Grab them from any GNU archive site."
++ find . -type f -name Makefile.am -print |
++ sed 's/\.am$/.in/' |
++ while read f; do touch "$f"; done
++ ;;
++
++ bison|yacc)
++ echo 1>&2 "\
++WARNING: \`$1' is missing on your system. You should only need it if
++ you modified a \`.y' file. You may need the \`Bison' package
++ in order for those modifications to take effect. You can get
++ \`Bison' from any GNU archive site."
++ rm -f y.tab.c y.tab.h
++ if [ $# -ne 1 ]; then
++ eval LASTARG="\${$#}"
++ case "$LASTARG" in
++ *.y)
++ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
++ if [ -f "$SRCFILE" ]; then
++ cp "$SRCFILE" y.tab.c
++ fi
++ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
++ if [ -f "$SRCFILE" ]; then
++ cp "$SRCFILE" y.tab.h
++ fi
++ ;;
++ esac
++ fi
++ if [ ! -f y.tab.h ]; then
++ echo >y.tab.h
++ fi
++ if [ ! -f y.tab.c ]; then
++ echo 'main() { return 0; }' >y.tab.c
++ fi
++ ;;
++
++ lex|flex)
++ echo 1>&2 "\
++WARNING: \`$1' is missing on your system. You should only need it if
++ you modified a \`.l' file. You may need the \`Flex' package
++ in order for those modifications to take effect. You can get
++ \`Flex' from any GNU archive site."
++ rm -f lex.yy.c
++ if [ $# -ne 1 ]; then
++ eval LASTARG="\${$#}"
++ case "$LASTARG" in
++ *.l)
++ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
++ if [ -f "$SRCFILE" ]; then
++ cp "$SRCFILE" lex.yy.c
++ fi
++ ;;
++ esac
++ fi
++ if [ ! -f lex.yy.c ]; then
++ echo 'main() { return 0; }' >lex.yy.c
++ fi
++ ;;
++
++ makeinfo)
++ echo 1>&2 "\
++WARNING: \`$1' is missing on your system. You should only need it if
++ you modified a \`.texi' or \`.texinfo' file, or any other file
++ indirectly affecting the aspect of the manual. The spurious
++ call might also be the consequence of using a buggy \`make' (AIX,
++ DU, IRIX). You might want to install the \`Texinfo' package or
++ the \`GNU make' package. Grab either from any GNU archive site."
++ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
++ if test -z "$file"; then
++ file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
++ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
++ fi
++ touch $file
++ ;;
++
++ *)
++ echo 1>&2 "\
++WARNING: \`$1' is needed, and you do not seem to have it handy on your
++ system. You might have modified some files without having the
++ proper tools for further handling them. Check the \`README' file,
++ it often tells you about the needed prerequirements for installing
++ this package. You may also peek at any GNU archive site, in case
++ some other package would contain this missing \`$1' program."
++ exit 1
++ ;;
++esac
++
++exit 0
+diff -ruN blip-0.1.orig/mkinstalldirs blip-0.1/mkinstalldirs
+--- blip-0.1.orig/mkinstalldirs Thu Jan 1 08:00:00 1970
++++ blip-0.1/mkinstalldirs Mon Nov 3 20:09:02 2003
+@@ -0,0 +1,40 @@
++#! /bin/sh
++# mkinstalldirs --- make directory hierarchy
++# Author: Noah Friedman <friedman@prep.ai.mit.edu>
++# Created: 1993-05-16
++# Public domain
++
++# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $
++
++errstatus=0
++
++for file
++do
++ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
++ shift
++
++ pathcomp=
++ for d
++ do
++ pathcomp="$pathcomp$d"
++ case "$pathcomp" in
++ -* ) pathcomp=./$pathcomp ;;
++ esac
++
++ if test ! -d "$pathcomp"; then
++ echo "mkdir $pathcomp"
++
++ mkdir "$pathcomp" || lasterr=$?
++
++ if test ! -d "$pathcomp"; then
++ errstatus=$lasterr
++ fi
++ fi
++
++ pathcomp="$pathcomp/"
++ done
++done
++
++exit $errstatus
++
++# mkinstalldirs ends here
+diff -ruN blip-0.1.orig/msn_bittybits.C blip-0.1/msn_bittybits.C
+--- blip-0.1.orig/msn_bittybits.C Thu Jan 1 08:00:00 1970
++++ blip-0.1/msn_bittybits.C Mon Nov 3 20:09:02 2003
+@@ -0,0 +1,283 @@
++/* msn_bittybits.c - all the little string- and list-bashing functions */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <ctype.h>
++#include <sys/errno.h>
++
++#include "msn_core.h"
++#include "msn_interface.h"
++#include "msn_bittybits.h"
++
++char ** msn_read_line(int sock, int * numargs)
++{
++ // Right, this is quite a task. Step One is to read the thing in.
++ char ** retval;
++ char c;
++ int pos=0, numspaces=0;
++
++ *numargs = 0;
++
++ while(1)
++ {
++ if(read(sock, &c, 1)<1)
++ {
++ #ifdef MSNDEBUG
++ perror("Stream closed\n"); //DEBUG
++ #endif
++ return NULL;
++ }
++ if(c=='\314') { return NULL; } // just drop it
++ if(c=='\r') { continue; }
++ if(c=='\n') { numspaces++; buf[pos]='\0'; break; }
++ if(c==' ') { numspaces++; }
++ buf[pos]=c;
++ pos++;
++ if(pos>=BUF_SIZE)
++ {
++ #ifdef MSNDEBUG
++ printf("Severe warning - overflow, dropping/splitting a line!");
++ #endif
++ return NULL;
++ }
++ }
++
++ if(numspaces==0) {
++ #ifdef MSNDEBUG
++ printf("What the..?\n");
++ #endif
++ return NULL; }
++
++ ext_protocol_log(buf, 1, 0);
++
++ retval=new char * [numspaces];
++ retval[0]=new char[strlen(buf)+1];
++ strcpy(retval[0], buf);
++ *numargs=numspaces;
++
++ // OK, take it as read (boom, boom!)
++ // Now we cruise through the string, changing all spaces to null 0's and setting
++ // a pointer at the beginning of each substring
++
++ pos=0;
++ numspaces=1; // pointer #0 is already set at the beginning
++ while(1)
++ {
++ if(retval[0][pos]==' ')
++ {
++ retval[0][pos]='\0';
++ retval[numspaces]=retval[0]+pos+1;
++ numspaces++;
++ pos++;
++ continue;
++ }
++ if(retval[0][pos]=='\0') { break; }
++
++ pos++;
++ }
++
++ return retval;
++}
++
++void msn_clean_up(msnconn * conn)
++{
++ llist * connlist;
++ connlist=connections;
++
++ if(conn->type!=CONN_FTP)
++ { ext_closing_connection(conn); }
++
++ while(1)
++ {
++ if(connlist==NULL) { return; }
++ if(connlist->data==conn) { break; }
++ connlist=connlist->next;
++ }
++
++ close(conn->sock);
++ ext_unregister_sock(conn->sock);
++// delete conn;
++
++ if(connlist->next!=NULL)
++ { connlist->next->prev=connlist->prev; }
++ if(connlist->prev!=NULL)
++ { connlist->prev->next=connlist->next; } else { connections=connlist->next; }
++ connlist->prev=NULL; // no recursive destructors, please...
++ connlist->next=NULL;
++ connlist->data=NULL; // already deleted the conn object
++ delete connlist;
++}
++
++void msn_add_callback(msnconn * conn, void (*func)(msnconn * conn, int trid, char ** args, int numargs, callback_data * data), int trid, callback_data * data)
++{
++ callback * call;
++
++ call=new callback;
++ call->trid=trid;
++ call->data=data;
++ call->func=func;
++
++ msn_add_to_llist(conn->callbacks, call);
++}
++
++void msn_del_callback(msnconn * conn, int trid)
++{
++ llist * list;
++ callback * call;
++
++ list=conn->callbacks;
++
++ if(list==NULL) { return; }
++
++ do
++ {
++ call=(callback *)list->data;
++ if(call->trid==trid)
++ {
++ if(list->next!=NULL)
++ { list->next->prev=list->prev; }
++ if(list->prev!=NULL)
++ { list->prev->next=list->next; } else { conn->callbacks=NULL; }
++ list->prev=NULL; // no recursive destructors
++ list->next=NULL;
++ delete list;
++ break;
++ }
++ list=list->next;
++ } while(list!=NULL);
++}
++
++void msn_add_to_llist(llist *& listp, llist_data * data)
++{
++ llist * tlist;
++ llist * newlist;
++
++ if(listp==NULL) { listp=new llist; listp->data=data; return; }
++
++ tlist=listp;
++
++ while(tlist->next!=NULL) { tlist=tlist->next; }
++
++ newlist=new llist;
++ newlist->prev=tlist;
++ newlist->next=NULL;
++ newlist->data=data;
++ tlist->next=newlist;
++}
++
++void msn_del_from_llist(llist *& listp, llist_data * data)
++{
++ // Note: this function does NOT delete the data, only the list object
++ llist * tlist;
++
++ tlist=listp;
++
++ while(tlist!=NULL)
++ {
++ if(tlist->data==data)
++ {
++ if(tlist->next!=NULL)
++ { tlist->next->prev=tlist->prev; }
++ if(tlist->prev!=NULL)
++ { tlist->prev->next=tlist->next; } else { listp=tlist->next; }
++ tlist->next=NULL; // otherwise the whole list is clobbered by the destructor
++ tlist->prev=NULL;
++ tlist->data=NULL;
++ delete tlist;
++ return;
++ }
++ tlist=tlist->next;
++ }
++}
++
++int msn_count_llist(llist * list)
++{
++ llist * l=list;
++ int retval=0;
++
++ while(l!=NULL) { l=l->next; retval++; }
++
++ return retval;
++}
++
++char * msn_permstring(const char * s)
++{
++ char * retval;
++
++ if(s==NULL) { return NULL; }
++
++ retval=new char [strlen(s)+1];
++
++ strcpy(retval, s);
++
++ return retval;
++}
++
++char * msn_decode_URL(char * s)
++{
++ char * rpos; // read
++ char * wpos; // write
++
++ wpos=rpos=s;
++
++ while(1)
++ {
++ if(*rpos=='\0') { *wpos='\0'; break; }
++
++ if(*rpos=='%')
++ {
++ char buf[3];
++ int c;
++ rpos++;
++ buf[0]=*rpos;
++ rpos++;
++ buf[1]=*rpos;
++ rpos++;
++ buf[2]='\0';
++ sscanf(buf, "%x", &c);
++ *wpos=c;
++ wpos++;
++ continue;
++ }
++
++ *wpos=*rpos;
++ rpos++;
++ wpos++;
++ }
++ return s;
++}
++
++char * msn_encode_URL(const char * s)
++{
++ const char * rptr = s;
++ char * wptr;
++ char * retval;
++
++ wptr=retval=new char[strlen(s)*3];
++
++ while(1)
++ {
++ if(*rptr=='\0')
++ { *wptr='\0'; break; }
++
++ if(!(isalpha(*rptr) || isdigit(*rptr)))
++ {
++ if ( *rptr != '\xc2' && *rptr != '\xb0' ) {
++ sprintf(wptr, "%%%2x", (int)(*rptr));
++
++ rptr++;
++ wptr+=3;
++ continue;
++ }
++ }
++
++ *wptr=*rptr;
++ wptr++;
++ rptr++;
++ }
++
++ return retval;
++}
++
+diff -ruN blip-0.1.orig/msn_bittybits.h blip-0.1/msn_bittybits.h
+--- blip-0.1.orig/msn_bittybits.h Thu Jan 1 08:00:00 1970
++++ blip-0.1/msn_bittybits.h Mon Nov 3 20:09:02 2003
+@@ -0,0 +1,35 @@
++#ifndef __MSN_BITTYBITS_H__
++#define __MSN_BITTYBITS_H__
++
++/* msn_bittybits.h - all the little string-bashing functions */
++
++/*
++ char ** msn_read_line(int sock, int * numargs);
++
++ Purpose: Read a line from the MSN server, then break it up into
++ space-separated strings
++ Arguments:
++ sock The socket to use
++ numargs Gets set to the number of arguments
++ Returns: A NULL-terminated array of strings, or NULL on error
++*/
++char ** msn_read_line(int sock, int * numargs);
++
++void msn_clean_up(msnconn * conn);
++
++void msn_add_callback(msnconn * conn, void (*func)(msnconn * conn, int trid, char ** args, int numargs, callback_data * data), int trid, callback_data * data);
++
++void msn_del_callback(msnconn * conn, int trid);
++
++void msn_add_to_llist(llist *& listp, llist_data * data);
++
++void msn_del_from_llist(llist *& listp, llist_data * data);
++
++int msn_count_llist(llist * list);
++
++char * msn_permstring(const char * s);
++
++char * msn_decode_URL(char * s);
++char * msn_encode_URL(const char * s);
++
++#endif
+diff -ruN blip-0.1.orig/msn_core.C blip-0.1/msn_core.C
+--- blip-0.1.orig/msn_core.C Thu Jan 1 08:00:00 1970
++++ blip-0.1/msn_core.C Mon Nov 3 20:09:02 2003
+@@ -0,0 +1,2162 @@
++/* msn_core.c - this contains all the functions used to do anything with MSN */
++
++#include <stdio.h>
++#include <unistd.h>
++#include <ctype.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include <errno.h>
++#include <sys/time.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <time.h>
++
++#include <sys/types.h>
++#include <sys/socket.h> // for the accept() in filetrans code
++#include <sys/stat.h>
++
++#include "md5.h"
++#include "msn_core.h"
++#include "msn_bittybits.h"
++#include "msn_interface.h"
++#include "../connwrap-0.1/connwrap.h"
++
++#define DEBUG 1
++#define MSN_VERSION_ID 0 // ID that is sent after commands like CHG, NLN, etc.
++
++// Define all those extern'ed variables in msn_core.h:
++llist * connections=NULL;
++int next_trid=10;
++char buf[BUF_SIZE]; // used for anything temporary
++char * errors[1000];
++char default_error_msg[]="Unknown error code";
++
++void msn_init(msnconn * conn, const char * username, const char * password)
++{
++ srand(time(NULL));
++
++ conn->auth=new authdata_NS;
++ conn->type=CONN_NS;
++ conn->ready=0;
++ ((authdata_NS *)conn->auth)->username=msn_permstring(username);
++ ((authdata_NS *)conn->auth)->password=msn_permstring(password);
++
++ for(int a=0; a<1000; a++)
++ {
++ errors[a]=default_error_msg;
++ }
++
++ errors[200]=msn_permstring("Syntax error");
++ errors[201]=msn_permstring("Invalid parameter");
++ errors[205]=msn_permstring("Invalid user");
++ errors[206]=msn_permstring("Domain name missing from username");
++ errors[207]=msn_permstring("Already logged in");
++ errors[208]=msn_permstring("Invalid username");
++ errors[209]=msn_permstring("Invalid friendly name");
++ errors[210]=msn_permstring("List full");
++ errors[215]=msn_permstring("This user is already on this list or in this session");
++ errors[216]=msn_permstring("Not on list");
++ errors[218]=msn_permstring("Already in this mode");
++ errors[219]=msn_permstring("This user is already in the opposite list");
++ errors[280]=msn_permstring("Switchboard server failed");
++ errors[281]=msn_permstring("Transfer notification failed");
++ errors[300]=msn_permstring("Required fields missing");
++ errors[302]=msn_permstring("Not logged in");
++ errors[500]=msn_permstring("Internal server error");
++ errors[501]=msn_permstring("Database server error");
++ errors[510]=msn_permstring("File operation failed at server");
++ errors[520]=msn_permstring("Memory allocation failed on server");
++ errors[600]=msn_permstring("The server is too busy");
++ errors[601]=msn_permstring("The server is unavailable");
++ errors[602]=msn_permstring("A Peer Notification Server is down");
++ errors[603]=msn_permstring("Database connection failed");
++ errors[604]=msn_permstring("Server going down for maintenance");
++ errors[707]=msn_permstring("Server failed to create connection");
++ errors[711]=msn_permstring("Blocking write failed on server");
++ errors[712]=msn_permstring("Session overload on server");
++ errors[713]=msn_permstring("You have been too active recently. Slow down!");
++ errors[714]=msn_permstring("Too many sessions open");
++ errors[715]=msn_permstring("Not expected");
++ errors[717]=msn_permstring("Bad friend file on server");
++ errors[911]=msn_permstring("Authentication failed. Check that you typed your username and password correctly.");
++ errors[913]=msn_permstring("This action is not allowed while you are offline");
++ errors[920]=msn_permstring("This server is not accepting new users");
++
++ msn_add_to_llist(connections, conn);
++}
++
++void msn_show_verbose_error(msnconn * conn, int errcode)
++{
++ snprintf(buf, 1024, "An error has occurred while communicating with the MSN Messenger server: %s (code %d)", errors[errcode], errcode);
++ ext_show_error(conn, buf);
++}
++
++void msn_invite_user(msnconn * conn, char * rcpt)
++{
++ sprintf(buf, "CAL %d %s\r\n", next_trid++, rcpt);
++ write(conn->sock, buf, strlen(buf));
++}
++
++void msn_send_IM(msnconn * conn, const char * rcpt, const char * s)
++{
++ static char header[]="MIME-Version: 1.0\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n";
++ message * msg=new message;
++ msg->body=s;
++ msg->header=msn_permstring(header);
++ msg->font=NULL;
++ msg->colour=NULL;
++ msn_send_IM(conn, rcpt, msg);
++
++ msg->body=NULL; // don't delete s
++ delete msg;
++}
++
++void msn_send_IM(msnconn * conn, const char * rcpt, message * msg)
++{
++ char header[1024];
++
++ if(conn->type==CONN_NS)
++ {
++ llist * list;
++
++ list=connections;
++ while(1)
++ {
++ msnconn * c;
++ llist * users;
++
++ if(list==NULL) { break ; }
++ c=(msnconn *)list->data;
++ if(c->type==CONN_NS) { list=list->next; continue; }
++ users=c->users;
++ // the below sends a message into this session if the only other participant is
++ // the user we want to talk to
++ if(users!=NULL && users->next==NULL && !strcmp(((char_data *)users->data)->c, rcpt))
++ {
++ msn_send_IM(c, rcpt, msg);
++ return;
++ }
++
++ list=list->next;
++ }
++ // otherwise, just connect
++ msn_request_SB(conn, rcpt, msg, NULL);
++ return;
++ }
++
++ if(msg->header==NULL)
++ {
++ if(msg->font==NULL)
++ {
++ sprintf(header, "MIME-Version: 1.0\r\nContent-Type: %s\r\n\r\n", (msg->content==NULL)?("text/plain; charset=UTF-8"):(msg->content));
++ } else {
++ char * fontname=msn_encode_URL(msg->font);
++ char ef[2] = {'\0', '\0'};
++ if(msg->bold) { ef[0]='B'; }
++ if(msg->underline) { ef[0]='U'; }
++
++ sprintf(header, "MIME-Version: 1.0\r\nContent-Type: %s\r\nX-MMS-IM-Format: FN=%s; EF=%s; CO=%s; CS=0; PF=%d\r\n\r\n",
++ (msg->content==NULL)?("text/plain"):(msg->content), fontname, ef, msg->colour, msg->fontsize);
++
++ delete fontname;
++ }
++ } else {
++ strcpy(header, msg->header);
++ }
++
++
++ sprintf(buf, "MSG %d N %d\r\n%s", next_trid, strlen(header)+strlen(msg->body), header);
++ write(conn->sock, buf, strlen(buf));
++ write(conn->sock, msg->body, strlen(msg->body));
++ next_trid++;
++}
++
++void msn_send_typing(msnconn * conn)
++{
++ char header[]="MIME-Version: 1.0\r\nContent-Type: text/x-msmsgscontrol\r\nTypingUser: ";
++ char * username=((authdata_SB *)conn->auth)->username;
++
++ sprintf(buf, "MSG %d U %d\r\n%s%s\r\n\r\n\r\n",
++ next_trid++, strlen(header)+strlen(username)+6, header, username);
++
++ write(conn->sock, buf, strlen(buf));
++}
++
++void msn_add_to_list(msnconn * conn, const char * lst, const char * username)
++{
++ sprintf(buf, "ADD %d %s %s %s\r\n", next_trid++, lst, username, username);
++ write(conn->sock, buf, strlen(buf));
++}
++
++void msn_del_from_list(msnconn * conn, const char * lst, const char * username)
++{
++ sprintf(buf, "REM %d %s %s\r\n", next_trid++, lst, username);
++ write(conn->sock, buf, strlen(buf));
++}
++
++void msn_set_GTC(msnconn * conn, char c)
++{
++ sprintf(buf, "GTC %d %c\r\n", next_trid++, c);
++ write(conn->sock, buf, strlen(buf));
++}
++
++void msn_set_BLP(msnconn * conn, char c)
++{
++ sprintf(buf, "BLP %d %cL\r\n", next_trid++, c);
++ write(conn->sock, buf, strlen(buf));
++}
++
++void msn_set_friendlyname(msnconn * conn, const char * friendlyname)
++{
++ char * username;
++
++ username=((authdata_NS *)conn->auth)->username;
++ sprintf(buf, "REA %d %s %s\r\n", next_trid++, username, msn_encode_URL(friendlyname));
++ write(conn->sock, buf, strlen(buf));
++}
++
++void msn_get_list_info( msnconn *conn, int nargs, char **args )
++{
++ char buf[ 1000 ];
++ syncinfo *info;
++
++ info = conn->sync_info;
++
++ if ( NULL == info )
++ {
++ ext_debug("error! : conn->sync_info == NULL in msn_get_list_info");
++ return ;
++ }
++
++ if ( !nargs )
++ return ;
++
++ if ( !strcmp( args[ 0 ], "SYN" ) )
++ {
++ if ( info->serial == atoi( args[ 2 ] ) )
++ {
++ delete info;
++ info = NULL;
++ ext_got_info(conn, NULL);
++ return;
++ }
++
++ info->serial = atoi( args[ 2 ] );
++ ext_latest_serial( conn, info->serial );
++ info->nContacts = atoi( args[ 3 ] );
++ info->nGroups = atoi( args[ 4 ] );
++ return ;
++ }
++
++ if ( !strcmp( args[ 0 ], "GTC" ) )
++ {
++ info->gtc = args[ 1 ][ 0 ];
++ info->complete |= COMPLETE_GTC;
++ ext_got_GTC( conn, args[ 1 ][ 0 ] );
++ }
++
++ if ( !strcmp( args[ 0 ], "BLP" ) )
++ {
++ info->blp = args[ 1 ][0];
++ info->complete |= COMPLETE_BLP;
++ ext_got_BLP( conn, args[ 1 ][ 0 ] );
++ }
++
++ if ( !strcmp( args[ 0 ], "PRP" ) )
++ {
++ // We just eat PRP-codes.
++ return ;
++ }
++
++ if ( !strcmp( args[ 0 ], "LSG" ) )
++ {
++ if ( !info->nContacts )
++ {
++ msn_check_rl(conn, info);
++ ext_got_info(conn, info);
++ delete info;
++ conn->sync = 0;
++ }
++
++ // Just eat 'm.
++ return ;
++ }
++
++ if ( !strcmp( args[ 0 ], "BPR" ) )
++ {
++ if ( !info->nFound ) {
++ ext_debug("MSNp8: error: got BPR without contact");
++ } else {
++ llist *ll = info->fl;
++
++ while( ll ) {
++ userdata * ud = (userdata *) ll->data;
++
++ if( !strcmp( ud->username, info->last_user_handled ) )
++ {
++ phonedata * newphone=new phonedata();
++ newphone->title=msn_permstring(args[1]);
++ newphone->number=msn_decode_URL(msn_permstring(args[2]));
++ msn_add_to_llist( ud->phone, newphone );
++ break;
++ }
++
++ ll = ll->next;
++ }
++ }
++
++ return ;
++ }
++
++ // 0 1 2
++ // LST email@address.com Friendly%20Nickname w x,y,z
++ if ( !strcmp( args[ 0 ], "LST" ) )
++ {
++ // XXX - Todo: see if the user is really on our FL
++ // list and handle the BL list.
++
++ userdata *newuser_fl = new userdata();
++ newuser_fl->username = msn_permstring( args[ 1 ] );
++ newuser_fl->friendlyname = msn_decode_URL( msn_permstring( args[ 1 ] ) );
++
++ info->last_user_handled = newuser_fl->username;
++
++ msn_add_to_llist( info->fl, newuser_fl );
++
++ userdata *newuser_rl = new userdata();
++ newuser_rl->username = msn_permstring( args[ 1 ] );
++ newuser_rl->friendlyname = msn_decode_URL( msn_permstring( args[ 1 ] ) );
++
++ msn_add_to_llist( info->rl, newuser_rl );
++
++ userdata *newuser_al = new userdata();
++ newuser_al->username = msn_permstring( args[ 1 ] );
++ newuser_al->friendlyname = msn_decode_URL( msn_permstring( args[ 1 ] ) );
++
++ msn_add_to_llist( info->al, newuser_al );
++
++ info->nFound++;
++
++ if ( info->nFound == info->nContacts )
++ {
++ msn_check_rl(conn, info);
++ ext_got_info(conn, info);
++ delete info;
++ conn->sync = 0;
++ }
++ }
++}
++
++void msn_sync_lists(msnconn * conn, int version)
++{
++ syncinfo * info=new syncinfo;
++
++ info->serial=version;
++
++ sprintf(buf, "SYN %d %d\r\n", next_trid, version);
++ write(conn->sock, buf, strlen(buf));
++
++ conn->sync = 1;
++ conn->sync_info = info;
++
++ next_trid++;
++}
++
++void msn_check_rl(msnconn * conn, syncinfo * info)
++{
++ llist * flist; // FL
++ llist * olist; // other list
++ userdata * fcontact;
++ userdata * ocontact;
++
++ int is_on_list;
++ int a=0;
++
++ flist=info->rl;
++
++ while(flist!=NULL)
++ {
++ is_on_list=0;
++
++ fcontact=(userdata *)flist->data;
++
++ a=0;
++ for(olist=info->al; a<2; olist=info->bl, a++)
++ {
++ while(olist!=NULL)
++ {
++ ocontact=(userdata *)olist->data;
++ if(!strcmp(ocontact->username, fcontact->username))
++ {
++ is_on_list=1;
++ break;
++ }
++ olist=olist->next;
++ }
++ if(is_on_list) { break; } // avoid a second loop if unnecessary
++ }
++
++ if(!is_on_list)
++ {
++ ext_new_RL_entry(conn, fcontact->username, fcontact->friendlyname);
++ }
++
++ flist=flist->next;
++ }
++}
++
++void msn_new_SB(msnconn * nsconn, void * tag)
++{
++ msn_request_SB(nsconn, NULL, NULL, tag);
++}
++
++void msn_request_SB(msnconn * nsconn, const char * rcpt, message * msg, void * tag)
++{
++ conninfo_SB * info=new conninfo_SB;
++
++ info->auth=new authdata_SB;
++ info->auth->username=msn_permstring(((authdata_NS *)nsconn->auth)->username);
++ info->auth->rcpt=msn_permstring(rcpt);
++ if(msg==NULL)
++ {
++ info->auth->msg=NULL;
++ } else {
++ info->auth->msg=new message;
++ info->auth->msg->header=msn_permstring(msg->header);
++ info->auth->msg->body=msn_permstring(msg->body);
++ info->auth->msg->font=msn_permstring(msg->font);
++ info->auth->msg->colour=msn_permstring(msg->colour);
++ info->auth->msg->content=msn_permstring(msg->content);
++ info->auth->msg->bold=msg->bold;
++ info->auth->msg->italic=msg->italic;
++ info->auth->msg->underline=msg->underline;
++ }
++
++ info->auth->tag=tag;
++
++ sprintf(buf, "XFR %d SB\r\n", next_trid);
++ write(nsconn->sock, buf, strlen(buf));
++
++ msn_add_callback(nsconn, msn_SBconn_2, next_trid, info);
++ next_trid++;
++}
++
++void msn_SBconn_2(msnconn * conn, int trid, char ** args, int numargs, callback_data * data)
++{
++ conninfo_SB * info=(conninfo_SB *)data;
++
++ msn_del_callback(conn, trid);
++
++ if(strcmp(args[0], "XFR"))
++ {
++ msn_show_verbose_error(conn, atoi(args[0]));
++ delete info;
++ return;
++ }
++
++ info->auth->cookie=msn_permstring(args[5]);
++ info->auth->sessionID=NULL;
++
++ msnconn * newconn=new msnconn;
++
++ newconn->auth=info->auth;
++ newconn->type=CONN_SB;
++ newconn->ready=0;
++
++ msn_add_to_llist(connections, newconn);
++
++ int port=1863;
++ char * c;
++
++ if((c=strstr(args[3], ":"))!=NULL)
++ {
++ *c='\0';
++ c++;
++ port=atoi(c);
++ }
++
++ delete info;
++
++ msn_connect(newconn, args[3], port);
++}
++
++void msn_SBconn_3(msnconn * conn, int trid, char ** args, int numargs, callback_data * data)
++{
++ authdata_SB * auth=(authdata_SB *)conn->auth;
++
++ msn_del_callback(conn, trid);
++
++ if(strcmp(args[2], "OK"))
++ {
++ msn_show_verbose_error(conn, atoi(args[0]));
++ msn_clean_up(conn);
++ return;
++ }
++
++ if(auth->rcpt==NULL) // they're requesting the SB session the proper way
++ {
++ ext_got_SB(conn, auth->tag);
++ } else {
++ sprintf(buf, "CAL %d %s\r\n", next_trid, auth->rcpt);
++ write(conn->sock, buf, strlen(buf));
++
++ delete auth->rcpt;
++ auth->rcpt=NULL;
++
++ next_trid++;
++ }
++ conn->ready=1;
++ ext_new_connection(conn);
++}
++
++void msn_handle_incoming(int sock, int readable, int writable)
++{
++ // First, we find which msnconn this socket belongs to
++
++ llist * list;
++ msnconn * conn;
++ callback * call;
++
++ char ** args;
++ int numargs;
++ int trid;
++
++ list=connections;
++
++ if(list==NULL) { return; }
++
++ while(1)
++ {
++ conn=(msnconn *)list->data;
++ if(conn->sock==sock)
++ { break; }
++ list=list->next;
++ if(list==NULL)
++ {
++ #ifdef MSNDEBUG
++ printf("Network traffic not for us\n");
++ #endif
++ return;
++ } // not for us
++ }
++
++ // first, siphon off any file transfer traffic to the special handler
++ if(conn->type==CONN_FTP)
++ { msn_handle_filetrans_incoming(conn, readable, writable); return; }
++
++ // OK, it's for us. If it's readable, parse it, then deliver it to the appropriate handler
++
++ if(!readable) { return; }
++
++ args=msn_read_line(sock, &numargs);
++ if ( !numargs )
++ {
++ ext_debug("msn: error: no arguments for this data");
++ return ;
++ }
++
++ if(args==NULL)
++ {
++ if(errno!=0)
++ { msn_clean_up(conn); }
++ return;
++ }
++
++ if(!strcmp(args[0], "XFR") && !strcmp(args[2], "NS"))
++ {
++ delete conn->callbacks; // delete the callback data
++ conn->callbacks=NULL;
++
++ ext_unregister_sock(conn->sock);
++ close(conn->sock);
++
++ char * c;
++ int port=1863;
++
++ if((c=strstr(args[3], ":"))!=NULL)
++ {
++ *c='\0';
++ c++;
++ port=atoi(c);
++ }
++
++ msn_connect(conn, args[3], port);
++ return;
++ }
++
++ if(!strcmp(args[0], "RNG"))
++ {
++ msn_handle_RNG(conn, args, numargs);
++ return;
++ }
++
++ trid=atoi(args[1]);
++
++ if ( conn->sync )
++ {
++ // connection is synching. is this a SYNC-relation instruction?
++ if ( !strcmp( args[ 0 ], "SYN" ) || !strcmp( args[ 0 ], "GTC") || !strcmp( args[ 0 ], "BLP" ) ||
++ !strcmp( args[ 0 ], "PRP" ) || !strcmp( args[ 0 ], "LSG") || !strcmp( args[ 0 ], "BPR" ) ||
++ !strcmp( args[ 0 ], "LST" ) )
++ {
++ msn_get_list_info( conn, numargs, args );
++ delete args[0];
++ delete args;
++ return ;
++ }
++
++ // else: it's a normal message
++ }
++
++ list=conn->callbacks;
++
++ if(list!=NULL && trid>0)
++ {
++ while(1)
++ {
++ call=(callback *)list->data;
++ if(call->trid==trid)
++ {
++ (call->func)(conn, trid, args, numargs, call->data);
++ delete args[0];
++ delete args;
++ return;
++ }
++ list=list->next;
++ if(list==NULL) { break; } // defaults
++ }
++ }
++
++ msn_handle_default(conn, args, numargs);
++
++ delete args[0];
++ delete args;
++}
++
++void msn_handle_close(int sock)
++{
++ // First, we find which msnconn this socket belongs to
++
++ llist * list;
++ msnconn * conn;
++
++ list=connections;
++
++ if(list==NULL) { return; }
++
++ while(1)
++ {
++ conn=(msnconn *)list->data;
++ if(conn->sock==sock)
++ { break; }
++ list=list->next;
++ if(list==NULL)
++ {
++ #ifdef MSNDEBUG
++ printf("Socket close not for us\n");
++ #endif
++ return; } // not for us
++ }
++
++ msn_clean_up(conn);
++}
++
++void msn_handle_default(msnconn * conn, char ** args, int numargs)
++{
++
++ // Switchboard messages
++
++ if(!strcmp(args[0], "MSG"))
++ {
++ msn_handle_MSG(conn, args, numargs);
++ return;
++ }
++
++ if(!strcmp(args[0], "NAK"))
++ {
++ msn_handle_NAK(conn, args, numargs);
++ return;
++ }
++
++ if(!strcmp(args[0], "JOI"))
++ {
++ msn_handle_JOI(conn, args, numargs);
++ return;
++ }
++
++ if(!strcmp(args[0], "BYE"))
++ {
++ msn_handle_BYE(conn, args, numargs);
++ return;
++ }
++
++ // Notification server messages
++
++ if(!strcmp(args[0], "NLN") || !strcmp(args[0], "ILN") || !strcmp(args[0], "FLN"))
++ {
++ msn_handle_statechange(conn, args, numargs);
++ return;
++ }
++
++ if(!strcmp(args[0], "CHG"))
++ {
++ ext_changed_state(conn, args[2]);
++ return;
++ }
++
++ if(!strcmp(args[0], "ADD"))
++ {
++ msn_handle_ADD(conn, args, numargs);
++ return;
++ }
++
++ if(!strcmp(args[0], "REM"))
++ {
++ msn_handle_REM(conn, args, numargs);
++ return;
++ }
++
++ if(!strcmp(args[0], "BLP"))
++ {
++ msn_handle_BLP(conn, args, numargs);
++ return;
++ }
++
++ if(!strcmp(args[0], "GTC"))
++ {
++ msn_handle_GTC(conn, args, numargs);
++ return;
++ }
++
++ if(!strcmp(args[0], "REA"))
++ {
++ msn_handle_REA(conn, args, numargs);
++ return;
++ }
++
++ if(!strcmp(args[0], "CHL"))
++ {
++ msn_handle_CHL(conn, args, numargs);
++ return;
++ }
++
++ if(!strcmp(args[0], "OUT"))
++ {
++ msn_handle_OUT(conn, args, numargs);
++ return;
++ }
++
++ if(isdigit(args[0][0]))
++ {
++ msn_show_verbose_error(conn, atoi(args[0]));
++ return;
++ }
++
++ #ifdef MSNDEBUG
++ printf("Don't know what to do with this one, ignoring it:\n"); // DEBUG
++ for(int a=0; a<numargs; a++)
++ {
++ printf("%s ", args[a]);
++ }
++ printf("\n");
++ #endif
++}
++
++void msn_handle_MSG(msnconn * conn, char ** args, int numargs)
++{
++ int msglen;
++ char * msg;
++ char * mime;
++ char * body;
++ char * tmp;
++
++ msglen=atoi(args[3]);
++
++ msg=new char[msglen+1];
++ read(conn->sock, msg, msglen);
++ msg[msglen]='\0';
++
++ mime=msg;
++ body=strstr(msg, "\r\n\r\n");
++ if(body!=NULL) { body[2]='\0'; /* finish the MIME string */ body+=4; }
++
++ // the below is a kludge until I remember the header name for TypingUser
++ if((strstr(mime, "TypingUser")!=NULL) || (strstr(mime, "TypeingUser")!=NULL))
++ { // the second of the above two is a workaround for a spelling bug in the Jabber MSN transport
++ ext_typing_user(conn, args[1], msn_decode_URL(args[2]));
++ delete msg;
++ return;
++ }
++
++ /* Warning - the code below was written at what my body clock insisted was past midnight,
++ jetlagged, on a foreign road, because I had nothing better to do. I would like to please
++ call to your attention the no-warranty clause in the GPL.... :^) */
++
++ char * content; // content-type
++
++ content=msn_find_in_mime(mime, "Content-Type");
++ if(content==NULL) { ext_show_error(conn, "MSG with no Content-type set"); delete msg; return; }
++ #ifdef MSNDEBUG
++ printf("Content type: \"%s\"\n", content);
++ #endif
++ if((tmp=strstr(content, "; charset"))!=NULL) { *tmp='\0'; }
++
++ if(!strcmp(content, "text/x-msmsgsprofile"))
++ {
++ ext_debug("MSNp8: got x-msmsgsprofile");
++ } else
++ if(!strcmp(content, "text/plain"))
++ {
++ message * msg=new message;
++ msg->header=mime;
++ msg->body=body;
++ msg->font=NULL;
++ msg->content=msn_find_in_mime(mime, "Content-Type"); // include any "charset=" I've chopped off
++
++ ext_got_IM(conn, args[1], msn_decode_URL(args[2]), msg);
++ } else if(!strcmp(content, "text/x-msmsgsinitialemailnotification")) {
++ char * unread_ibc;
++ char * unread_folc;
++ int unread_ib=0, unread_fol=0;
++
++ unread_ibc=msn_find_in_mime(body, "Inbox-Unread");
++ unread_folc=msn_find_in_mime(body, "Folders-Unread");
++ if(unread_ibc!=NULL) { unread_ib=atoi(unread_ibc); delete unread_ibc; }
++ if(unread_folc!=NULL) { unread_fol=atoi(unread_folc); delete unread_folc; }
++
++ ext_initial_email(conn, unread_ib, unread_fol);
++ } else if(!strcmp(content, "text/x-msmsgsemailnotification")) {
++ char * from=msn_find_in_mime(body, "From-Addr");
++ char * subject=msn_find_in_mime(body, "Subject");
++
++ ext_new_mail_arrived(conn, from, subject);
++
++ delete from;
++ delete subject;
++ } else if(!strcmp(content, "text/x-msmsgsinvite")) {
++ msn_handle_invite(conn, args[1], msn_decode_URL(args[2]), mime, body);
++ } else {
++ #ifdef MSNDEBUG
++ printf("Unknown content-type: \"%s\"\n", content);
++ #endif
++ }
++ delete content;
++ delete msg;
++}
++
++char * msn_find_in_mime(char * mime, char * header)
++{
++ char * retval;
++ int pos;
++
++ if(!strncmp(mime, header, strlen(header)))
++ {
++ retval=mime;
++ } else {
++ char * tmp=new char[strlen(header)+3];
++ strcpy(tmp, "\r\n");
++ strcat(tmp, header);
++ retval=strstr(mime, header);
++ if(retval==NULL) { return NULL; }
++ retval+=2;
++ delete tmp;
++ }
++
++ while(*retval!=':') { retval++; }
++ retval++; // pass the colon
++ while(isspace(*retval)) { retval++; } // position at start of value
++
++ pos=0;
++ while(retval[pos]!='\0')
++ {
++ if(retval[pos]=='\r')
++ {
++ char * tmp;
++ retval[pos]='\0';
++ tmp=msn_permstring(retval);
++ retval[pos]='\r';
++ return tmp;
++ }
++ pos++;
++ }
++ #ifdef MSNDEBUG
++ printf("Invalid MIME header - WTF?!\n");
++ #endif
++ return NULL;
++}
++
++void msn_handle_invite(msnconn * conn, char * from, char * friendly, char * mime, char * body)
++{
++ char * command=msn_find_in_mime(body, "Invitation-Command");
++ char * cookie=msn_find_in_mime(body, "Invitation-Cookie");
++ int inv_is_out=0;
++ invitation * inv=NULL;
++ llist * l;
++
++ l=conn->invitations_in;
++ while(1)
++ {
++ if(l==NULL)
++ { if(!inv_is_out) { l=conn->invitations_out; inv_is_out=1; continue; } else { break; } }
++ inv=(invitation *)l->data;
++ #ifdef MSNDEBUG
++ printf("invitation: checking %s against %s\n", inv->cookie, cookie);
++ #endif
++ if(!strcmp(inv->cookie, cookie))
++ { break ; }
++ inv=NULL;
++ l=l->next;
++ }
++
++
++ if(!strcmp(command, "INVITE"))
++ {
++ msn_handle_new_invite(conn, from, friendly, mime, body);
++ } else if(!strcmp(command, "ACCEPT")) {
++ if(inv==NULL)
++ {
++ #ifdef MSNDEBUG
++ printf("Very odd - just got an ACCEPT out of mid-air...\n");
++ #endif
++ delete command; return; }
++
++ if(!inv_is_out && inv->app==APP_FTP)
++ {
++ #ifdef MSNDEBUG
++ printf("Downloading file from remote host..\n");
++ #endif
++ msn_recv_file((invitation_ftp *)inv, body);
++ } else if(inv_is_out && inv->app==APP_FTP) {
++ msn_send_file((invitation_ftp *)inv, body);
++ }
++ } else if(!strcmp(command, "CANCEL") || !strcmp(command, "REJECT")) {
++ if(inv==NULL)
++ {
++ #ifdef MSNDEBUG
++ printf("Very odd - just got a CANCEL/REJECT out of mid-air...\n");
++ #endif
++ delete command;
++ return;
++ }
++ if(inv->app==APP_FTP)
++ {
++ ext_filetrans_failed((invitation_ftp *)inv, 0, "Cancelled by remote user");
++ if(inv_is_out)
++ {
++ msn_del_from_llist(conn->invitations_out, inv);
++ } else {
++ msn_del_from_llist(conn->invitations_in, inv);
++ }
++ delete inv;
++ }
++ } else {
++ #ifdef MSNDEBUG
++ printf("Argh, don't support %s yet!\n", command);
++ #endif
++ }
++
++ delete command;
++}
++
++void msn_handle_new_invite(msnconn * conn, char * from, char * friendlyname, char * mime, char * body)
++{
++
++ char * appname;
++
++ char * tmp1=NULL;
++ char * tmp2=NULL;
++
++ appname=msn_find_in_mime(body, "Application-Name");
++ invitation * invg=NULL;
++
++ if((tmp1=msn_find_in_mime (body, "Application-File")) != NULL
++ && (tmp2=msn_find_in_mime (body, "Application-FileSize")) != NULL)
++ {
++ invitation_ftp * inv=new invitation_ftp;
++ invg=inv;
++ invg->app=APP_FTP;
++ invg->other_user=msn_permstring(from);
++ invg->cookie=msn_find_in_mime(body, "Invitation-Cookie");
++ invg->conn=conn;
++ inv->filename=tmp1;
++ tmp1=NULL;
++ inv->filesize=atol(tmp2);
++
++ ext_filetrans_invite(conn, from, friendlyname, inv);
++ }
++ if(tmp1!=NULL) { delete tmp1; }
++ if(tmp2!=NULL) { delete tmp2; }
++
++ delete appname;
++
++ if(invg==NULL)
++ {
++ ext_show_error(conn, "Unknown invitation type!");
++ return;
++ }
++
++ msn_add_to_llist(conn->invitations_in, invg);
++}
++
++void msn_recv_file(invitation_ftp * inv, char * msg_body)
++{
++ char * cookie=msn_find_in_mime(msg_body, "AuthCookie");
++ char * remote=msn_find_in_mime(msg_body, "IP-Address");
++ char * port_c=msn_find_in_mime(msg_body, "Port");
++ int port;
++
++ if(cookie==NULL || remote==NULL || port_c==NULL)
++ {
++ ext_filetrans_failed(inv, 0, "Missing parameters");
++ msn_del_from_llist(inv->conn->invitations_in, inv);
++ if(cookie!=NULL) { delete cookie; }
++ if(remote!=NULL) { delete remote; }
++ if(port_c!=NULL) { delete port_c; }
++ delete inv;
++ }
++
++ port=atoi(port_c);
++ delete port_c;
++
++ msnconn * conn=new msnconn;
++ conn->type=CONN_FTP;
++
++ sprintf(buf, "Connecting to %s:%d\n", remote, port);
++ ext_filetrans_progress(inv, buf, 0, 0);
++
++ conn->sock=ext_connect_socket(remote, port);
++ delete remote;
++
++ if(conn->sock<0)
++ {
++ ext_filetrans_failed(inv, errno, strerror(errno));
++ msn_del_from_llist(inv->conn->invitations_in, inv);
++ delete cookie;
++ delete inv;
++ return;
++ }
++
++ ext_register_sock(conn->sock, 1, 0);
++
++ ext_filetrans_progress(inv, "Connected", 0, 0);
++
++ authdata_FTP * auth=new authdata_FTP;
++ auth->cookie=msn_permstring(cookie);
++ delete cookie;
++ auth->inv=inv;
++ auth->username=msn_permstring(((authdata_SB *)inv->conn->auth)->username);
++ auth->direction=MSNFTP_RECV;
++
++ conn->auth=auth;
++
++ msn_add_to_llist(connections, conn);
++
++ write(conn->sock, "VER MSNFTP\r\n", strlen("VER MSNFTP\r\n"));
++}
++
++void msn_handle_filetrans_incoming(msnconn * conn, int readable, int writable)
++{
++ authdata_FTP * auth=(authdata_FTP *)conn->auth;
++
++ #ifdef MSNDEBUG
++ printf("Incoming from file sender\n");
++ #endif
++
++ if(auth->direction==MSNFTP_RECV)
++ {
++ if(!readable) { return; } // not interested...
++
++ if(auth->fd==-1)
++ {
++ char ** args;
++ int numargs;
++
++ args=msn_read_line(conn->sock, &numargs);
++
++ if(args==NULL) { msn_clean_up(conn); return; }
++
++ if(!strcmp(args[0], "VER"))
++ {
++ sprintf(buf, "USR %s %s\r\n", auth->username, auth->cookie);
++ write(conn->sock, buf, strlen(buf));
++ ext_filetrans_progress(auth->inv, "Negotiating", 0, 0);
++ } else if (!strcmp(args[0], "FIL")) {
++ auth->fd=open(auth->inv->filename, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU);
++ if(auth->fd<0)
++ {
++ ext_filetrans_failed(auth->inv, errno, strerror(errno));
++ msn_del_from_llist(conn->invitations_in, auth->inv);
++ msn_clean_up(conn);
++ delete args[0];
++ delete args;
++ return;
++ }
++
++ write(conn->sock, "TFR\r\n", strlen("TFR\r\n"));
++ }
++ delete args[0];
++ delete args;
++ auth->num_ignore=3;
++ }
++
++ fd_set readfd;
++ struct timeval timeout={0, 0};
++ FD_ZERO(&readfd);
++ FD_SET(conn->sock, &readfd);
++ char c;
++
++ while(select(conn->sock+1, &readfd, NULL, NULL, &timeout)==1)
++ {
++ if(read(conn->sock, &c, 1)<1)
++ {
++ msn_clean_up(conn);
++ return;
++ }
++ if(auth->num_ignore>0)
++ {
++ auth->num_ignore--;
++ continue;
++ }
++ auth->bytes_done++;
++ write(auth->fd, &c, 1);
++ if(auth->bytes_done==auth->inv->filesize)
++ {
++ write(conn->sock, "BYE 16777989\r\n", strlen("BYE 16777989"));
++ ext_filetrans_success(auth->inv);
++
++ msn_del_from_llist(auth->inv->conn->invitations_in, auth->inv);
++ msn_clean_up(conn);
++ return;
++ }
++ if(auth->bytes_done%2045==0) { auth->num_ignore=3; }
++ }
++
++ ext_filetrans_progress(auth->inv, "Receiving file", auth->bytes_done, auth->inv->filesize);
++ } else {
++ // We are sending
++
++ if(!auth->connected) // we have not accept()ed yet, but the read/writability means there's one waiting
++ {
++ int s;
++
++ if((s=accept(conn->sock, NULL, NULL))<0)
++ {
++ #ifdef MSNDEBUG
++ perror("Could not accept()\n");
++ #endif
++ ext_filetrans_failed(auth->inv, errno, strerror(errno));
++ msn_del_from_llist(auth->inv->conn->invitations_out, auth->inv);
++ msn_clean_up(conn); // that will nuke both auth and inv
++ return;
++ }
++
++ ext_unregister_sock(conn->sock);
++ close(conn->sock);
++
++ conn->sock=s;
++ ext_register_sock(conn->sock, 1, 1);
++
++ ext_filetrans_progress(auth->inv, "Connected", 0, 0);
++
++ auth->connected=1;
++ } else {
++ // we know it's connected already
++
++ if(auth->fd==-1)
++ {
++ char ** args;
++ int numargs;
++
++ if(!readable) { return; } // not interested...
++
++ if((args=msn_read_line(conn->sock, &numargs))==NULL)
++ {
++ #ifdef MSNDEBUG
++ perror("read() failed");
++ #endif
++ ext_filetrans_failed(auth->inv, errno, strerror(errno));
++ msn_del_from_llist(auth->inv->conn->invitations_out, auth->inv);
++ msn_clean_up(conn);
++ return;
++ }
++
++ if(!strcmp(args[0], "VER"))
++ {
++ sprintf(buf, "VER MSNFTP\r\n");
++ write(conn->sock, buf, strlen(buf));
++ ext_filetrans_progress(auth->inv, "Negotiating", 0, 0);
++ }
++
++ if(!strcmp(args[0], "USR"))
++ {
++ if(strcmp(args[2], auth->cookie)) // if they DIFFER
++ {
++ ext_filetrans_failed(auth->inv, errno, strerror(errno));
++ msn_del_from_llist(auth->inv->conn->invitations_out, auth->inv);
++ msn_clean_up(conn);
++ return;
++ }
++
++ sprintf(buf, "FIL %lu\r\n", auth->inv->filesize);
++ write(conn->sock, buf, strlen(buf));
++ }
++
++ if(!strcmp(args[0], "TFR"))
++ {
++ // you asked for it, go to data-dump mode
++ auth->fd=open(auth->inv->filename, O_RDONLY);
++ if(auth->fd<0)
++ {
++ ext_filetrans_failed(auth->inv, errno, "Could not open file for reading");
++ msn_del_from_llist(auth->inv->conn->invitations_out, auth->inv);
++ msn_clean_up(conn);
++ return;
++ }
++
++ // OK, now we lose control, but the next round of the polling loop will
++ // say that the socket is writable, and then the fun starts...
++ ext_filetrans_progress(auth->inv, "Sending data", 0, 0);
++ }
++ } else {
++ // just pumping data now
++
++ fd_set writefd;
++ FD_ZERO(&writefd);
++ FD_SET(conn->sock, &writefd);
++ struct timeval tout={0, 0};
++ char c;
++
++ while(select(conn->sock+1, NULL, &writefd, NULL, &tout)==1)
++ {
++ if(auth->bytes_done%2045==0)
++ {
++ unsigned char check[3];
++ int to_go=(auth->inv->filesize-auth->bytes_done>2045)?(2045):(auth->inv->filesize-auth->bytes_done);
++
++
++ check[0]='\0';
++ check[1]=to_go%256;
++ check[2]=to_go/256;
++ write(conn->sock, check, 3);
++ }
++
++ if(read(auth->fd, &c, 1)<1)
++ {
++ ext_filetrans_failed(auth->inv, errno, strerror(errno));
++ msn_del_from_llist(auth->inv->conn->invitations_out, auth->inv);
++ msn_clean_up(conn);
++ return;
++ }
++
++ auth->bytes_done++;
++ write(conn->sock, &c, 1);
++
++ if(auth->bytes_done==auth->inv->filesize)
++ {
++ ext_filetrans_success(auth->inv);
++
++ msn_del_from_llist(auth->inv->conn->invitations_in, auth->inv);
++ msn_clean_up(conn);
++ return;
++ }
++ }
++
++ ext_filetrans_progress(auth->inv, "Sending file", auth->bytes_done, auth->inv->filesize);
++ }
++ }
++ }
++}
++
++void msn_send_file(invitation_ftp * inv, char * msg_body)
++{
++ int port=6891;
++ msnconn * conn=new msnconn;
++
++ ext_filetrans_progress(inv, "Sending IP address", 0, 0);
++
++ conn->type=CONN_FTP;
++
++ while((conn->sock=ext_server_socket(port))<0)
++ {
++ port++;
++ if(port>6911)
++ {
++ ext_filetrans_failed(inv, errno, strerror(errno));
++ msn_del_from_llist(inv->conn->invitations_out, inv);
++ delete inv;
++ delete conn;
++ return;
++ }
++ }
++
++ ext_register_sock(conn->sock, 1, 0);
++
++ msn_add_to_llist(connections, conn);
++
++ authdata_FTP * auth=new authdata_FTP;
++
++ conn->auth=auth;
++
++ auth->cookie=new char[64];
++ sprintf(auth->cookie, "%d", rand());
++
++ auth->inv=inv;
++ auth->direction=MSNFTP_SEND;
++
++ auth->connected=0;
++
++ message * msg=new message;
++ msg->content=msn_permstring("text/x-msmsgsinvite; charset=UTF-8");
++
++
++ sprintf(buf, "Invitation-Command: ACCEPT\r\nInvitation-Cookie: %s\r\nIP-Address: %s\r\nPort: %d\r\nAuthCookie: %s\r\nLaunch-Application: FALSE\r\nRequest-Data: IP-Address:\r\n\r\n",
++ inv->cookie, ext_get_IP(), port, auth->cookie);
++
++ msg->body=msn_permstring(buf);
++
++ msn_send_IM(inv->conn, NULL, msg);
++
++ delete msg;
++}
++
++void msn_handle_NAK(msnconn * conn, char ** args, int numargs)
++{
++ ext_IM_failed(conn);
++}
++
++void msn_handle_JOI(msnconn * conn, char ** args, int numargs)
++{
++ authdata_SB * auth;
++
++ auth=(authdata_SB *)conn->auth;
++
++ if(!strcmp(args[1], auth->username)) { return; }
++
++ msn_add_to_llist(conn->users, new char_data(msn_permstring(args[1])));
++ ext_user_joined(conn, args[1], msn_decode_URL(args[2]), 0);
++
++ if(auth->msg!=NULL)
++ {
++ msn_send_IM(conn, NULL, auth->msg);
++ delete auth->msg;
++ auth->msg=NULL;
++ }
++}
++
++void msn_handle_RNG(msnconn * conn, char ** args, int numargs)
++{
++ msnconn * newSBconn=new msnconn;
++ authdata_SB * auth=new authdata_SB;
++
++ newSBconn->type=CONN_SB;
++ newSBconn->auth=auth;
++
++ auth->username=msn_permstring(((authdata_NS *)(conn->auth))->username);
++ auth->sessionID=msn_permstring(args[1]);
++ auth->cookie=msn_permstring(args[4]);
++ auth->msg=NULL;
++
++ msn_add_to_llist(connections, newSBconn);
++
++ char * c;
++ int port=1863;
++ if((c=strstr(args[2], ":"))!=NULL)
++ {
++ *c='\0';
++ c++;
++ port=atoi(c);
++ }
++
++ msn_connect(newSBconn, args[2], port);
++}
++
++void msn_handle_BYE(msnconn * conn, char ** args, int numargs)
++{
++ llist * list;
++ char_data * c;
++
++ list=conn->users;
++
++ ext_user_left(conn, args[1]);
++
++ while(list!=NULL)
++ {
++ c=(char_data *)list->data;
++ if(!strcmp(c->c, args[1])) // if the departing user matches this item on the list
++ {
++ if(list->next!=NULL)
++ { list->next->prev=list->prev; }
++ if(list->prev!=NULL)
++ { list->prev->next=list->next; }
++ if(list->prev==NULL) { conn->users=list->next; }
++ list->next=NULL; // otherwise the delete will go through the entire llist!
++ list->prev=NULL;
++ delete list; // will delete the char_data for us too
++ break;
++ }
++ list=list->next;
++ }
++
++ if(conn->users==NULL)
++ {
++ msn_clean_up(conn);
++ }
++}
++
++void msn_handle_statechange(msnconn * conn, char ** args, int numargs)
++{
++ char * buddy;
++ char * state;
++ char * friendlyname;
++
++ if(!strcmp(args[0], "ILN"))
++ {
++ friendlyname=args[4];
++ buddy=args[3];
++ state=args[2];
++ } else if(!strcmp(args[0], "FLN")) {
++ buddy=args[1];
++ ext_buddy_offline(conn, buddy);
++ return;
++ } else {
++ friendlyname=args[3];
++ buddy=args[2];
++ state=args[1];
++ }
++
++ ext_buddy_set(conn, buddy, msn_decode_URL(friendlyname), state);
++}
++
++void msn_handle_ADD(msnconn * conn, char ** args, int numargs)
++{
++ if(!strcmp(args[2], "RL"))
++ {
++ #ifdef MSNDEBUG
++ printf("Via ADD:\n");
++ #endif
++ ext_new_RL_entry(conn, args[4], msn_decode_URL(args[5]));
++ }
++
++ ext_new_list_entry(conn, args[2], args[4]);
++ ext_latest_serial(conn, atoi(args[3]));
++}
++
++void msn_handle_REM(msnconn * conn, char ** args, int numargs)
++{
++ ext_del_list_entry(conn, args[2], args[4]);
++ ext_latest_serial(conn, atoi(args[3]));
++}
++
++
++void msn_handle_BLP(msnconn * conn, char ** args, int numargs)
++{
++ ext_got_BLP(conn, args[3][0]);
++ ext_latest_serial(conn, atoi(args[3]));
++}
++
++void msn_handle_GTC(msnconn * conn, char ** args, int numargs)
++{
++ ext_got_GTC(conn, args[3][0]);
++ ext_latest_serial(conn, atoi(args[3]));
++}
++
++void msn_handle_REA(msnconn * conn, char ** args, int numargs)
++{
++ ext_latest_serial(conn, atoi(args[2]));
++ ext_got_friendlyname(conn, msn_decode_URL(args[4]));
++}
++
++void msn_handle_CHL(msnconn * conn, char ** args, int numargs)
++{
++ md5_state_t state;
++ md5_byte_t digest[16];
++ int a;
++
++ md5_init(&state);
++ md5_append(&state, (md5_byte_t *)(args[2]), strlen(args[2]));
++ md5_append(&state, (md5_byte_t *)"VT6PX?UQTM4WM%YR", 16);
++
++ md5_finish(&state, digest);
++
++ sprintf(buf, "QRY %d PROD0038W!61ZTF9 32\r\n", next_trid++ );
++
++ write(conn->sock, buf, strlen(buf));
++
++ for(a=0; a<16; a++)
++ {
++ sprintf(buf, "%02x", digest[a]);
++ write(conn->sock, buf, strlen(buf));
++ }
++}
++
++void msn_handle_OUT(msnconn * conn, char ** args, int numargs)
++{
++ if(numargs>1)
++ {
++ if(!strcmp(args[1], "OTH"))
++ {
++ ext_show_error(conn, "You have logged onto MSN twice at once. Your MSN session will now terminate.");
++ } else if(!strcmp(args[1], "SSD")) {
++ ext_show_error(conn, "This MSN server is going down for maintenance. Your MSN session will now terminate.");
++ } else {
++ sprintf(buf, "The MSN server has terminated the connection with an unknown reason code. Please report this code: %s", args[1]);
++ ext_show_error(conn, buf);
++ }
++ }
++ msn_clean_up(conn);
++}
++
++void msn_filetrans_reject(invitation_ftp * inv)
++{
++ message * msg=new message;
++
++ sprintf(buf, "Invitation-Command: CANCEL\r\nInvitation-Cookie: %s\r\nCancel-Code: REJECT\r\n",
++ inv->cookie);
++ msg->body=msn_permstring(buf);
++ msg->content=msn_permstring("text/x-msmsgsinvite; charset=UTF-8");
++ msn_send_IM(inv->conn, NULL, msg);
++ delete msg;
++
++ #ifdef MSNDEBUG
++ printf("Rejecting file transfer\n");
++ #endif
++
++ msn_del_from_llist(inv->conn->invitations_in, inv);
++}
++
++void msn_filetrans_accept(invitation_ftp * inv, const char * dest)
++{
++ message * msg=new message;
++
++ delete inv->filename;
++ inv->filename=msn_permstring(dest);
++ sprintf(buf, "Invitation-Command: ACCEPT\r\nInvitation-Cookie: %s\r\nLaunch-Application: FALSE\r\nRequest-Data: IP-Address\r\n\r\n",
++ inv->cookie);
++ msg->body=msn_permstring(buf);
++ msg->content=msn_permstring("text/x-msmsgsinvite; charset=UTF-8");
++ msn_send_IM(inv->conn, NULL, msg);
++ delete msg;
++
++ #ifdef MSNDEBUG
++ printf("Accepting file transfer\n");
++ #endif
++}
++
++void msn_filetrans_cancel(invitation_ftp * inv)
++{
++ llist * l;
++ msnconn * conn;
++
++ // one of the two below will fail, but it will do so safely and quietly
++ msn_del_from_llist(inv->conn->invitations_in, inv);
++ msn_del_from_llist(inv->conn->invitations_out, inv);
++
++ l=connections;
++
++ while(1)
++ {
++ if(l==NULL) { delete inv; return; } // Hmm, couldn't find it...
++
++ conn=(msnconn *)l->data;
++
++ if(conn->type==CONN_FTP && ((authdata_FTP *)(conn->auth))->inv==inv)
++ { break; }
++
++ l=l->next;
++ }
++
++ authdata_FTP * auth=(authdata_FTP *)conn->auth;
++ delete auth->inv;
++ auth->inv=NULL;
++ delete auth;
++ conn->auth=NULL;
++
++ msn_clean_up(conn);
++}
++
++invitation_ftp * msn_filetrans_send(msnconn * conn, const char * path)
++{
++ struct stat st_info;
++
++ if(stat(path, &st_info)<0)
++ { ext_show_error(conn, "Could not open file"); return NULL; }
++
++ invitation_ftp * inv=new invitation_ftp;
++
++ inv->app=APP_FTP;
++ inv->cookie=new char[64];
++ sprintf(inv->cookie, "%d", rand());
++ inv->other_user=NULL;
++ inv->conn=conn;
++
++ inv->filename=msn_permstring(path);
++ inv->filesize=st_info.st_size;
++
++ message * msg=new message;
++ char * basename;
++
++ basename=inv->filename+strlen(inv->filename);
++
++ while(basename>=inv->filename && *basename!='/' && *basename!='\\')
++ {
++ basename--;
++ }
++
++ basename++; // it will always be 1 char before the start of the string
++
++ msg->content=msn_permstring("text/x-msmsgsinvite; charset=UTF-8");
++
++ sprintf(buf, "Application-Name: File transfer\r\nApplication-GUID: {5D3E02AB-6190-11d3-BBBB-00C04F795683}\r\nInvitation-Command: INVITE\r\nInvitation-Cookie: %s\r\nApplication-File: %s\r\nApplication-FileSize: %lu\r\n\r\n",
++ inv->cookie, basename, inv->filesize);
++
++ msg->body=msn_permstring(buf);
++
++ msn_send_IM(conn, NULL, msg);
++
++ msn_add_to_llist(conn->invitations_out, inv);
++
++ delete msg;
++
++ ext_filetrans_progress(inv, "Negotiating connection", 0, 0);
++
++ return inv;
++}
++
++#define szUser info->username
++#define szPassword info->password
++
++int msn_login_read( int nSock, char *buf, int nMax )
++{
++ return cw_read( nSock, buf, nMax, 0 );
++}
++
++int msn_login_wait( int nSocket, char *szCommand )
++{
++ int nRet = 0;
++
++ while ( !nRet )
++ nRet = read( nSocket, szCommand, 1000 );
++
++ #ifdef MSNDEBUG
++ printf("<< %s", szCommand );
++ #endif
++
++ return 1;
++}
++
++void msn_login_write1( int nSocket, char *szString, char *szArg )
++{
++ char szWrite[ 1000 ];
++
++ // ext_debug( szString );
++ // ext_debug( szArg );
++
++ memset( szWrite, 0, 999 );
++ sprintf( szWrite, "%s %s\r\n", szString, szArg );
++
++ // ext_debug( szWrite );
++
++ cw_write( nSocket, szWrite, strlen( szWrite ), 0 );
++}
++
++void msn_login_write( int nSocket, char *szString )
++{
++ char szWrite[ 1000 ];
++
++ memset( szWrite, 0, 1000 );
++ sprintf( szWrite, "%s\r\n", szString );
++
++ cw_write( nSocket, szWrite, strlen( szWrite ), 0 );
++}
++
++int msn_login_connect( int nPort, char *szAddress )
++{
++ return ext_connect_socket( szAddress, nPort );
++}
++
++int msn_login_ssl_write( int nSock, char *str )
++{
++ return cw_write( nSock, str, strlen( str ), 1 );
++}
++
++int msn_login_ssl_read( int nSock, char *buf, int nMax )
++{
++ return cw_read( nSock, buf, nMax, 1 );
++}
++
++int msn_login_close( int nSock )
++{
++ return cw_close( nSock );
++}
++
++int msn_login_ssl_connect( int nPort, char *szAddr )
++{
++ return ext_connect_socket_ssl( szAddr, nPort );
++}
++
++int msn_login_get_server( char *str, char *filter, char *Server, char *Site )
++{
++ char *c, *c1, *c2;
++
++ c = strstr( str, filter );
++ if ( NULL == c )
++ return 0;
++ // Skip the "Filter="-part.
++ c++;
++ c += strlen( filter );
++ c1 = strchr( c, '/' );
++ if ( NULL == c1 )
++ return 0;
++ c2 = strchr( c1, ',' );
++ if ( NULL == c2 )
++ return 0;
++
++ strncpy( Server, c, (unsigned long)c1 - (unsigned long)c );
++ strncpy( Site, c1, (unsigned long)c2 - (unsigned long)c1 );
++
++ return 1;
++}
++
++int msnAuth( char *lc, char *ticket, char *user, char *password )
++{
++ int nexus; // Passport Login Nexus
++ int logins; // Login Server
++ char result[ 5000 ];
++ char result2[ 1000 ];
++ char Server[ 100 ]; // e.g. www.server.com
++ char Site[ 100 ]; // e.g. /site.html
++ char String[ 800 ];
++ int i;
++ char mail[ 255 ];
++ char name[ 255 ];
++
++ memset( mail, 0, 255 );
++ memset( name, 0, 255 );
++
++ for ( i = 0; i < strlen( user ); i++ )
++ {
++ if ( user[i] == '@' )
++ {
++ strncpy( name, user, i );
++ strcpy( mail, (char*)( (unsigned long)user + i + 1 ) );
++ break;
++ }
++ }
++
++ memset( Server, 0, 100 );
++ memset( Site, 0, 100 );
++
++ nexus = msn_login_ssl_connect( 443, "nexus.passport.com" );
++ msn_login_ssl_write( nexus, "GET /rdr/pprdr.asp HTTP/1.0\r\n\r\n" );
++ msn_login_ssl_read( nexus, result, 800 );
++ msn_login_close( nexus );
++ msn_login_get_server( result, "DALogin", Server, Site );
++
++ #ifdef MSNDEBUG
++ printf("Connecting to server '%s' .. site '%s'\n", Server, Site );
++ #endif
++
++ for ( ; ; )
++ {
++ // Connect to Login Server
++ logins = msn_login_ssl_connect( 443, Server );
++ memset( String, 0, 800 );
++ sprintf( String, "GET %s HTTP/1.1\r\n"
++ "Authorization: Passport1.4 OrgVerb=GET,OrgURL=http%%3A%%2F%%2Fmessenger%%2Emsn%%2Ecom,sign-in=%s%%40%s,pwd=%s,%s\r\n"
++ "Host: %s\r\n\r\n",
++ Site, name, mail, password, lc, Server );
++
++ #ifdef MSNDEBUG
++ printf("Writing: \n%s\n", String );
++ #endif
++
++ msn_login_ssl_write( logins, String );
++
++ memset( result, 0, 5000 );
++ memset( result2, 0, 1000 );
++
++ msn_login_ssl_read( logins, result, 5000 );
++ msn_login_ssl_read( logins, result2, 1000 );
++
++ strcat( result, result2 );
++
++ if ( strstr( result, "200 OK" ) )
++ {
++ char *tick;
++ char *c3, *c4;
++ // Okay.
++
++ tick = strstr( result, "t=" );
++ if ( NULL == tick )
++ {
++ #ifdef MSNDEBUG
++ printf("No t= found in response.\n");
++ #endif
++ return 0;
++ }
++
++ tick += 2;
++
++ c4 = strstr( tick, "," );
++
++ strncpy( ticket, tick, (unsigned long)c4 - (unsigned long)tick - 1 );
++
++ //msn_login_close( logins );
++ return 1;
++ }
++
++ if ( strstr( result, "302 Found") && strstr( result, "redir" ) && strstr( result, "Location: " ) )
++ {
++ // Redirection.
++ char *c3, *c4;
++
++ c3 = strstr( result, "Location: " );
++ c3 += 10;
++
++ c3 = strstr( c3, "https://" );
++ c3 += 8;
++
++ c4 = strstr( c3, "/" );
++ strncpy( Server, c3, (unsigned long)c4 - (unsigned long)c3 );
++ strncpy( Site, c4, (unsigned long)strchr( c4, '\r' ) - (unsigned long)c4 );
++
++ // printf("Redirection to server [%s] - Site [%s]\n", Server, Site );
++ msn_login_close( logins );
++ continue;
++ }
++
++ break;
++ }
++
++ // printf("Error\n");
++ return 0;
++}
++
++int msn_connect_v8_error( connectinfo *info, msnconn *conn, char *szErr )
++{
++ ext_show_error( NULL, szErr );
++ delete info;
++
++ if ( conn->sock != -1 )
++ {
++ ext_unregister_sock( conn->sock );
++ close( conn->sock );
++ conn->sock = -1;
++ }
++
++ return -1;
++}
++
++int msn_connect_v8( connectinfo *info, msnconn *conn, int *nNextTrid )
++{
++ int ds; // Dispatch Server
++ char result[ 1000 ];
++ char *c;
++ char szIp[ 20 ];
++ char szPort[ 20 ];
++ int nPort;
++ char lc[ 400 ];
++ char ticket[ 2000 ];
++
++ memset( result, 0, 500 );
++
++ ext_debug("MSNp8: finding login server");
++
++ // ds = msn_login_connect( 1863, "messenger.hotmail.com" );
++ ds = conn->sock;
++
++ // >> VER 1 MSNP8 CVR0\r\n
++ msn_login_write( ds, "VER 1 MSNP8 CVR0" );
++ msn_login_wait( ds, result );
++
++ if ( !strstr( result, "VER 1" ) )
++ return msn_connect_v8_error( info, conn, "Protocol error (didn't receive VER 1)" );
++
++ // >> CVR 2 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS something@something.com\r\n
++ // ext_debug( szUser );
++
++ msn_login_write1( ds, "CVR 2 0x0409 winnt 5.1 i386 MSNMSGR 5.0.0540 MSMSGS", szUser );
++
++ msn_login_wait( ds, result );
++
++ if ( !strstr( result, "CVR 2" ) )
++ return msn_connect_v8_error( info, conn, "Protocol error (didn't receive CVR 2)" );
++
++ // >> USR 3 TWN I something@something.com\r\n
++ msn_login_write1( ds, "USR 3 TWN I", szUser );
++ msn_login_wait( ds, result );
++ if ( !strstr( result, "XFR 3 NS " ) )
++ return msn_connect_v8_error( info, conn, "Protocol error (didn't receive XFR 3)" );
++
++ // Read MSN Server IP from message.
++ c = strstr( result, "NS ");
++ c += 3;
++ memset( szIp, 0, 20 );
++ memset( szPort, 0, 20 );
++ strncpy( szIp, c, (unsigned long)strchr( c, ':' ) - (unsigned long)c );
++ c = strchr( c, ':' ); c++;
++ strncpy( szPort, c, (unsigned long)strchr( c, ' ' ) - (unsigned long)c );
++ nPort = atoi( szPort );
++
++ // Close current socket.
++ msn_login_close( ds );
++ ext_unregister_sock( ds );
++ conn->sock = -1;
++
++ #ifdef MSNDEBUG
++ printf("* Connecting to IP `%s' port %d *\n", szIp, nPort );
++ #endif
++
++ ext_debug("MSNp8: found.. connecting");
++
++ // Try to connect to other server.
++ ds = msn_login_connect( nPort, szIp );
++ if ( ds <= 0 )
++ return msn_connect_v8_error( info, conn, "Error connecting to specified MSN Server" );
++
++ // OK. Register the socket.
++ conn->sock = ds;
++ ext_register_sock( ds, 1, 0 );
++
++ // >> VER 4 MSNP8 CVR0\r\n
++ msn_login_write( ds, "VER 4 MSNP8 CVR0" );
++ msn_login_wait( ds, result );
++
++ if ( !strstr( result, "VER 4" ) )
++ return msn_connect_v8_error( info, conn, "Protocol error (didn't receive VER 4)" );
++
++ // >> CVR 5 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS something@something.com\r\n
++ msn_login_write1( ds, "CVR 5 0x0409 winnt 5.1 i386 MSNMSGR 5.0.0540 MSMSGS", szUser );
++ msn_login_wait( ds, result );
++
++ if ( !strstr( result, "CVR 5" ) )
++ return msn_connect_v8_error( info, conn, "Protocol error (didn't receive CVR 5)" );
++
++ // >> USR 6 TWN I something@something.com\r\n
++ msn_login_write1( ds, "USR 6 TWN I", szUser );
++ msn_login_wait( ds, result );
++
++ // << USR 6 TWN S something@something.com lc=....,....=...\r\n
++ if ( !strstr( result, "TWN S" ) )
++ return msn_connect_v8_error( info, conn, "Protocol error (didn't receive TWS S)" );
++
++ memset( lc, 0, 400 );
++ c = strstr( result, "TWN S " );
++ c+=6;
++
++ strncpy( lc, c, (unsigned long)strchr(c, '\r') - (unsigned long)c );
++
++ #ifdef MSNDEBUG
++ printf("LC-etc string = `%s'\n", lc );
++ #endif
++
++ memset( ticket, 0, 2000 );
++
++ ext_debug("MSNp8: doing SSL auth");
++
++ if ( ! msnAuth( lc, ticket, szUser, szPassword ) )
++ {
++ // printf("Error #6\n");
++ return 0;
++ }
++
++ ext_debug("MSNp8: OK.. logging in");
++
++ #ifdef MSNDEBUG
++ printf("Ticket = `%s'\n", ticket );
++ #endif
++
++ memset( result, 0, 500 );
++ sprintf( result, "USR 7 TWN S t=%s", ticket );
++
++ // >> USR 7 TWN S t=<ticket>
++ msn_login_write( ds, result );
++ memset( result, 0, 500 );
++ msn_login_wait( ds, result );
++
++ if ( !strstr( result, "USR 7 OK") )
++ {
++ if ( result[ 0 ] >= '0' && result[ 0 ] <= '9' )
++ {
++ char *err;
++ int nCode = 0;
++ // We received an error code.
++
++ err = strchr( result, ' ' );
++ if ( NULL == err )
++ nCode = atoi( result );
++ else {
++ *err = '\0';
++ nCode = atoi( result );
++ }
++ if ( nCode <= 0 )
++ return msn_connect_v8_error( info, conn, "Protocol error (Invalid response after USR 7)" );
++ return nCode;
++ }
++
++ // Invalid response.
++ return msn_connect_v8_error( info, conn, "Protocol error (Invalid response after USR 7)" );
++ }
++
++ // We are now connected to the MSN Server
++
++ // msn_login_write( ds, "OUT" );
++ // msn_login_close( ds );
++
++ // << USR 7 OK something@something.com Something%20Friendly%Nick 1 0
++ {
++ char *szFriendly;
++ char *cEnd;
++ int i;
++
++ szFriendly = result;
++
++ for ( i = 0; i < 4; i++ )
++ {
++ szFriendly = strchr( szFriendly, ' ' );
++
++ if ( NULL == szFriendly )
++ {
++ ext_got_friendlyname( conn, "Unknown nickname" );
++ return 0;
++ }
++
++ szFriendly++;
++ }
++
++ cEnd = strchr( szFriendly, ' ');
++ if ( NULL != cEnd )
++ *cEnd = '\0';
++
++ // ext_debug( msn_decode_URL( szFriendly ) );
++ ext_got_friendlyname( conn, msn_decode_URL( szFriendly ) );
++ }
++
++ *nNextTrid = 8;
++
++ // No error.
++ return 0;
++}
++
++void msn_connect(msnconn * conn, const char * server, int port)
++{
++ int result;
++
++ conn->ready=0;
++
++ if(conn->type==CONN_SB)
++ {
++ authdata_SB * auth=(authdata_SB *)conn->auth;
++
++ if((conn->sock=ext_connect_socket(server, port))==-1)
++ {
++ ext_show_error(conn, "Could not connect to switchboard server");
++ return;
++ }
++
++ ext_register_sock(conn->sock, 1, 0);
++
++ if(auth->sessionID==NULL)
++ {
++ sprintf(buf, "USR %d %s %s\r\n", next_trid, auth->username, auth->cookie);
++ write(conn->sock, buf, strlen(buf));
++
++ msn_add_callback(conn, msn_SBconn_3, next_trid, NULL);
++ } else {
++ sprintf(buf, "ANS %d %s %s %s\r\n", next_trid, auth->username, auth->cookie, auth->sessionID);
++ write(conn->sock, buf, strlen(buf));
++
++ ext_new_connection(conn);
++ conn->ready=1;
++ msn_add_callback(conn, msn_SB_ans, next_trid, NULL);
++ }
++
++ next_trid++;
++
++ return;
++ } // Otherwise, it's a Notification Server (NS)
++
++ connectinfo * info;
++
++ info=new connectinfo;
++
++ // The following is necessary as username and password may be temp variables
++ // that will no longer exist when the next function is called
++ info->username=msn_permstring( ((authdata_NS *)conn->auth)->username);
++ info->password=msn_permstring( ((authdata_NS *)conn->auth)->password);
++
++ conn->ready=0;
++ if((conn->sock=ext_connect_socket(server, port))==-1)
++ {
++ ext_show_error(conn, "Could not connect to MSN server");
++ return;
++ }
++
++ ext_register_sock(conn->sock, 1, 0);
++
++ // Okay, now try to connect.
++
++ ext_debug("MSNp8: connecting to MSN.. this could take a few seconds");
++
++ result = msn_connect_v8( info, conn, &next_trid );
++
++ if ( 0 != result )
++ {
++ // Error code.
++
++ if ( result > 0 )
++ {
++ msn_show_verbose_error( conn, result );
++ delete info;
++ msn_clean_up( conn );
++ conn->sock = -1;
++
++ } // else: connection failed completely. msn_connect_v8 already took care of destroying the connection
++
++ }
++ else
++ {
++
++ // We received no error code. Everything went ok!
++ delete info;
++
++ ext_debug("MSNp8: OK");
++
++ conn->ready = 1;
++ ext_new_connection( conn );
++ }
++}
++
++void msn_SB_ans(msnconn * conn, int trid, char ** args, int numargs, callback_data * data)
++{
++ if(!strcmp(args[0], "ANS") && !strcmp(args[2], "OK"))
++ { return; }
++
++ if(isdigit(args[0][0]))
++ {
++ msn_del_callback(conn, trid);
++ msn_show_verbose_error(conn, atoi(args[0]));
++ msn_clean_up(conn);
++ return;
++ }
++
++ if(!strcmp(args[0], "IRO"))
++ {
++ if(!strcmp(args[4], ((authdata_SB *)conn->auth)->username)) { return; }
++ msn_add_to_llist(conn->users, new char_data(msn_permstring(args[4])));
++ ext_user_joined(conn, args[4], msn_decode_URL(args[5]), 1);
++ if(!strcmp(args[2], args[3]))
++ {
++ msn_del_callback(conn, trid);
++ }
++ }
++}
++
++void msn_set_state(msnconn * conn, const char * state)
++{
++ sprintf(buf, "CHG %d %s %d\r\n", next_trid, state, MSN_VERSION_ID );
++ write(conn->sock, buf, strlen(buf));
++ next_trid++;
++}
+diff -ruN blip-0.1.orig/msn_core.h blip-0.1/msn_core.h
+--- blip-0.1.orig/msn_core.h Thu Jan 1 08:00:00 1970
++++ blip-0.1/msn_core.h Mon Nov 3 20:09:02 2003
+@@ -0,0 +1,355 @@
++/* msn_core.h - prototypes for msn_core.C */
++#ifndef MSN_CORE_H
++#define MSN_CORE_H
++
++class llist_data // inherit it
++{};
++
++class llist
++{
++ public:
++ llist_data * data;
++ llist * next;
++ llist * prev;
++
++ llist() { data=NULL; next=NULL; prev=NULL; }
++ ~llist() { if(data!=NULL) { delete data; } if(next!=NULL) { delete next; } }
++};
++
++class char_data : public llist_data
++{
++ public:
++ char * c;
++ char_data(char * tc) { c=tc; }
++ ~char_data() { if(c!=NULL) { delete c; } }
++};
++
++class callback_data
++{};
++
++class callback : public llist_data
++{
++ public:
++ int trid;
++ void (*func)(struct msnconn * conn, int trid, char ** args, int numargs, callback_data * data);
++ callback_data * data; // just gets passed
++};
++
++// Intermediate steps in synchronisation
++class syncinfo : public callback_data
++{
++ public:
++
++ llist * fl;
++ llist * rl;
++ llist * al;
++ llist * bl;
++
++ unsigned int complete;
++
++ int serial;
++ int nContacts;
++ int nGroups;
++ int nFound;
++
++ char *last_user_handled;
++
++ char blp;
++ char gtc;
++
++ syncinfo() { nFound = 0; nContacts = 0; blp='A'; gtc='A'; fl=rl=al=bl=NULL; complete=0; serial=0; }
++ ~syncinfo()
++ {
++ if(fl!=NULL) { delete fl; }
++ if(rl!=NULL) { delete rl; }
++ if(al!=NULL) { delete al; }
++ if(bl!=NULL) { delete bl; }
++ }
++};
++
++class message : public llist_data // This class encapsulates all that you need to know (tm) about a MSG
++{
++ public:
++
++ // Raw stuff
++ char * header; // MIME
++ const char * body;
++
++ // Parsed stuff
++ char * font;
++ char * colour;
++ int bold;
++ int italic;
++ int underline;
++ int fontsize;
++
++ char * content; // Content-type
++
++ message() { header=NULL; font=NULL; content=NULL; colour=NULL; }
++};
++
++class phonedata : public llist_data
++{
++ public:
++ char * title;
++ char * number;
++
++ phonedata() { title=number=NULL; }
++ ~phonedata() { if(title!=NULL) { delete title; } if(number!=NULL) { delete number; } }
++};
++
++class userdata : public llist_data
++{
++ public:
++ char * username;
++ char * friendlyname;
++
++ llist * phone;
++
++ userdata() { username=friendlyname=NULL; phone=NULL; }
++ ~userdata()
++ {
++ if(username!=NULL) { delete username; }
++ if(friendlyname!=NULL) { delete friendlyname; }
++ if(phone!=NULL) { delete phone; }
++ }
++};
++
++class authdata
++{};
++
++
++class msnconn : public llist_data
++{
++ public:
++ int sock; // Socket (durr...)
++ int type; // one of the #defines below
++ int sync; // syncing
++ int ready;
++
++ syncinfo *sync_info;
++ llist * users; // Users in this session - only for SB connections
++ llist * invitations_out; // invitations extended but not responded to
++ llist * invitations_in; // invitations received but not responded to
++ llist * callbacks;
++ authdata * auth;
++
++ msnconn() { sync = 0; users=NULL; callbacks=NULL; invitations_out=NULL; invitations_in=NULL; }
++ ~msnconn()
++ {
++ if(users!=NULL) { delete users; }
++ if(invitations_in!=NULL) { delete invitations_in; }
++ if(invitations_out!=NULL) { delete invitations_out; }
++ if(callbacks!=NULL) { delete callbacks; }
++ }
++};
++
++#define CONN_NS 1 // Notification Server (also Dispatch, as it does exactly the same thing)
++#define CONN_SB 2 // Switchboard Server
++#define CONN_FTP 3 // MSN file transfer
++
++class authdata_NS : public authdata
++{
++ public:
++ char * username;
++ char * password;
++
++ authdata_NS() { username=password=NULL; }
++ ~authdata_NS() { if(username!=NULL) { delete username; delete password; } }
++};
++
++class authdata_SB : public authdata
++{
++ public:
++ char * username;
++ char * sessionID;
++ char * cookie;
++ char * rcpt; // recipient of the below
++ message * msg; // to be sent as soon as connection is complete and someone joins
++ void * tag; // for SB connections without an initial message
++
++ authdata_SB() { username=sessionID=cookie=NULL; }
++ ~authdata_SB()
++ { if(username!=NULL) { delete username; delete sessionID; delete cookie; } }
++};
++
++class invitation : public llist_data
++{
++ public:
++ int app;
++ char * cookie;
++ char * other_user;
++ msnconn * conn;
++
++ invitation() { cookie=other_user=NULL; }
++ ~invitation() { if(cookie!=NULL) { delete cookie; } if(other_user!=NULL) { delete other_user; } }
++};
++
++#define APP_FTP 1 // NOTE: this is MSN file transfer, which is NOTHING to do with ordinary FTP!
++
++class invitation_ftp : public invitation
++{
++ public:
++ char * filename;
++ long unsigned filesize;
++
++ invitation_ftp() { filename=NULL; }
++ ~invitation_ftp()
++ { if(filename!=NULL) { delete filename; } }
++};
++
++
++class authdata_FTP : public authdata
++{
++ public:
++ char * cookie;
++ char * username;
++ invitation_ftp * inv;
++ int fd;
++ unsigned long bytes_done;
++ int num_ignore;
++ int direction;
++ int connected;
++
++ authdata_FTP() { cookie=username=NULL; inv=NULL; fd=-1; bytes_done=num_ignore=connected=0; }
++ ~authdata_FTP()
++ {
++ if(cookie!=NULL) { delete cookie; }
++ if(username!=NULL) { delete username; }
++ if(inv!=NULL) { delete inv; }
++ }
++};
++
++#define MSNFTP_SEND 1
++#define MSNFTP_RECV 2
++
++
++extern llist * connections;
++extern int next_trid;
++
++#define BUF_SIZE 1024
++extern char buf[]; // Used for anything temporary
++
++void msn_init(msnconn * conn, const char * username, const char * password);
++
++void msn_show_verbose_error(msnconn * conn, int errcode);
++
++void msn_connect(msnconn * conn, const char * server, int port);
++
++void msn_invite_user(msnconn * conn, char * rcpt);
++
++void msn_send_IM(msnconn * conn, const char * rcpt, const char * msg);
++
++void msn_send_IM(msnconn * conn, const char * rcpt, message * msg);
++
++void msn_send_typing(msnconn * conn);
++
++void msn_filetrans_accept(invitation_ftp * inv, const char * dest);
++
++void msn_filetrans_reject(invitation_ftp * inv);
++
++invitation_ftp * msn_filetrans_send(msnconn * conn, const char * path);
++
++void msn_sync_lists(msnconn * conn, int version);
++
++#define LST_FL 1
++#define LST_RL 2
++#define LST_AL 4
++#define LST_BL 8
++
++#define COMPLETE_BLP 16
++#define COMPLETE_GTC 32
++
++void msn_set_friendlyname(msnconn * conn, const char * friendlyname);
++
++void msn_sync_lists(msnconn * conn, int version);
++void msn_add_to_list(msnconn * conn, const char * lst, const char * user);
++void msn_del_from_list(msnconn * conn, const char * lst, const char * user);
++void msn_set_GTC(msnconn * conn, char c);
++void msn_set_BLP(msnconn * conn, char c);
++void msn_syncdata(msnconn * conn, int trid, char ** args, int numargs, callback_data * data);
++void msn_phonedata(msnconn * conn, int trid, char ** args, int numargs, callback_data * data);
++void msn_check_rl(msnconn * conn, syncinfo * info);
++
++void msn_connect_and_send(msnconn * nsconn, char * dest, char * msg);
++
++void msn_set_state(msnconn * conn, const char * state);
++
++// Intermediate steps in switchboard connection:
++class conninfo_SB : public callback_data
++{
++ public:
++ authdata_SB * auth;
++};
++
++void msn_new_SB(msnconn * nsconn, void * tag);
++void msn_request_SB(msnconn * nsconn, const char * rcpt, message * msg, void * tag);
++
++void msn_SBconn_2(msnconn * conn, int trid, char ** args, int numargs, callback_data * data);
++void msn_SBconn_3(msnconn * conn, int trid, char ** args, int numargs, callback_data * data);
++
++void msn_handle_incoming(int sock, int readable, int writable);
++
++void msn_handle_filetrans_incoming(msnconn * conn, int readable, int writable);
++
++void msn_handle_close(int sock);
++
++void msn_handle_default(msnconn * conn, char ** args, int numargs);
++
++void msn_handle_MSG(msnconn * conn, char ** args, int numargs);
++
++void msn_handle_invite(msnconn * conn, char * from, char * friendly, char * mime, char * body);
++
++void msn_handle_new_invite(msnconn * conn, char * from, char * friendly, char * mime, char * body);
++
++void msn_recv_file(invitation_ftp * inv, char * dest);
++
++char * msn_find_in_mime(char * mime, char * header);
++
++void msn_send_file(invitation_ftp * inv, char * msg_body);
++
++void msn_handle_NAK(msnconn * conn, char ** args, int numargs);
++
++void msn_handle_JOI(msnconn * conn, char ** args, int numargs);
++
++void msn_handle_BYE(msnconn * conn, char ** args, int numargs);
++
++void msn_handle_RNG(msnconn * conn, char ** args, int numargs);
++
++void msn_handle_statechange(msnconn * conn, char ** args, int numargs);
++
++void msn_handle_ADD(msnconn * conn, char ** args, int numargs);
++
++void msn_handle_REM(msnconn * conn, char ** args, int numargs);
++
++void msn_handle_BLP(msnconn * conn, char ** args, int numargs);
++
++void msn_handle_GTC(msnconn * conn, char ** args, int numargs);
++
++void msn_handle_REA(msnconn * conn, char ** args, int numargs);
++
++void msn_handle_CHL(msnconn * conn, char ** args, int numargs);
++
++void msn_handle_OUT(msnconn * conn, char ** args, int numargs);
++
++
++
++// Intermediate steps in connection:
++class connectinfo : public callback_data
++{
++ public:
++ char * username;
++ char * password;
++ connectinfo() { username=password=NULL; }
++ ~connectinfo()
++ { if(username!=NULL) { delete username; } if(password!=NULL) { delete password; } }
++};
++
++void msn_connect_2(msnconn * conn, int trid, char ** args, int numargs, callback_data * data);
++void msn_connect_3(msnconn * conn, int trid, char ** args, int numargs, callback_data * data);
++void msn_connect_4(msnconn * conn, int trid, char ** args, int numargs, callback_data * data);
++
++// Connecting to switchboards:
++void msn_SB_ans(msnconn * conn, int trid, char ** args, int numargs, callback_data * data);
++
++#endif // MSN_CORE_H
+diff -ruN blip-0.1.orig/msn_interface.h blip-0.1/msn_interface.h
+--- blip-0.1.orig/msn_interface.h Thu Jan 1 08:00:00 1970
++++ blip-0.1/msn_interface.h Mon Nov 3 20:09:02 2003
+@@ -0,0 +1,92 @@
++#ifndef __MSN_INTERFACE_H__
++#define __MSN_INTERFACE_H__
++
++/* msn_interface.h - functions that talk to the outside world */
++
++/*
++ void ext_show_error(char * msg);
++
++ Purpose: Displays an error
++ Arguments:
++ msg The error message
++ Return: Nothing
++*/
++
++void ext_register_sock(int s, int read, int write);
++void ext_unregister_sock(int s);
++
++void ext_show_error(msnconn * conn, const char * msg);
++
++void ext_buddy_set(msnconn * conn, const char * buddy, const char * friendlyname, const char * state);
++
++void ext_buddy_offline(msnconn * conn, const char * buddy);
++
++void ext_got_friendlyname(msnconn * conn, const char * friendlyname);
++
++void ext_got_info(msnconn * conn, syncinfo * data);
++
++void ext_debug( char *msg );
++
++void ext_latest_serial(msnconn * conn, int serial);
++
++void ext_got_GTC(msnconn * conn, char c);
++
++void ext_got_BLP(msnconn * conn, char c);
++
++void ext_new_RL_entry(msnconn * conn, const char * username, const char * friendlyname);
++
++void ext_new_list_entry(msnconn * conn, const char * lst, const char * username);
++
++void ext_del_list_entry(msnconn * conn, const char * lst, const char * username);
++
++void ext_got_SB(msnconn * conn, void * tag);
++
++void ext_user_joined(msnconn * conn, const char * username, const char * friendlyname, int is_initial);
++
++void ext_user_left(msnconn * conn, const char * username);
++
++void ext_got_IM(msnconn * conn, const char * username, const char * friendlyname, message * msg);
++
++void ext_IM_failed(msnconn * conn);
++
++void ext_typing_user(msnconn * conn, const char * username, const char * friendlyname);
++
++void ext_initial_email(msnconn * conn, int unread_inbox, int unread_folders);
++
++void ext_new_mail_arrived(msnconn * conn, const char * from, const char * subject);
++
++void ext_filetrans_invite(msnconn * conn, const char * username, const char * friendlyname, invitation_ftp * inv);
++
++void ext_filetrans_progress(invitation_ftp * inv, const char * status, unsigned long recv, unsigned long total);
++
++void ext_filetrans_failed(invitation_ftp * inv, int error, const char * message);
++
++void ext_filetrans_success(invitation_ftp * inv);
++
++void ext_new_connection(msnconn * conn);
++
++void ext_closing_connection(msnconn * conn);
++
++void ext_changed_state(msnconn * conn, const char * state);
++
++/*
++ int connect_socket(char * server, int port);
++
++ Purpose: Makes a TCP socket, connects it to the specified server and port,
++ and then registers it for
++ Arguments:
++ server The server name
++ port The TCP port to connect to
++ Return: Nothing
++*/
++int ext_connect_socket(const char * server, int port);
++
++int ext_connect_socket_ssl(const char * server, int port);
++
++int ext_server_socket(int port);
++
++char * ext_get_IP(void);
++
++void ext_protocol_log(const char *buf, int readev, int writeev);
++
++#endif
diff --git a/net-im/centericq/files/msn-msnhook.cc b/net-im/centericq/files/msn-msnhook.cc
new file mode 100644
index 000000000000..3e00cd68d492
--- /dev/null
+++ b/net-im/centericq/files/msn-msnhook.cc
@@ -0,0 +1,804 @@
+--- src/hooks/msnhook.cc.orig Mon Nov 3 20:25:37 2003
++++ src/hooks/msnhook.cc Mon Nov 3 20:24:20 2003
+@@ -0,0 +1,801 @@
++/*
++*
++* centericq MSN protocol handling class
++* $Id: msnhook.cc,v 1.67 2003/09/30 11:38:43 konst Exp $
++*
++* Copyright (C) 2001 by Konstantin Klyagin <konst@konst.org.ua>
++*
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by
++* the Free Software Foundation; either version 2 of the License, or (at
++* your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but
++* WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++* General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++* USA
++*
++*/
++
++#include "icqcommon.h"
++
++#ifdef BUILD_MSN
++
++#include "msnhook.h"
++#include "icqconf.h"
++#include "icqface.h"
++#include "icqcontacts.h"
++#include "accountmanager.h"
++#include "eventmanager.h"
++#include "imlogger.h"
++#include "connwrap.h"
++
++#include "msn_bittybits.h"
++
++#include <unistd.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++#include <netinet/in.h>
++#include <netdb.h>
++#include <arpa/inet.h>
++
++msnhook mhook;
++
++static string nicknormalize(const string &nick) {
++ if(nick.find("@") == -1) return nick + "@hotmail.com";
++ return nick;
++}
++
++static string nicktodisp(const string &nick) {
++ int pos;
++ string r = nick;
++
++ if((pos = r.find("@")) != -1)
++ if(r.substr(pos+1) == "hotmail.com")
++ r.erase(pos);
++
++ return r;
++}
++
++struct st2imr {
++ char *name;
++ imstatus st;
++};
++
++const st2imr st2im[] = {
++ { "FLN", offline },
++ { "NLN", available },
++ { "HDN", invisible },
++ { "BSY", dontdisturb },
++ { "PHN", occupied },
++ { "AWY", away },
++ { "BRB", away },
++ { "LUN", notavail },
++ { "IDL", away },
++ { 0, offline }
++};
++
++static imstatus msn2imstatus(const string &sname) {
++ for(const st2imr *sa = st2im; sa->name; sa++)
++ if(sname == sa->name)
++ return sa->st;
++
++ return offline;
++}
++
++static const char *stat2name(imstatus st) {
++ for(const st2imr *sa = st2im; sa->name; sa++)
++ if(st == sa->st)
++ return sa->name;
++
++ return "NLN";
++}
++
++// ----------------------------------------------------------------------------
++
++msnhook::msnhook(): abstracthook(msn) {
++ ourstatus = offline;
++ fonline = false;
++
++ fcapabs.insert(hookcapab::synclist);
++ fcapabs.insert(hookcapab::changedetails);
++ fcapabs.insert(hookcapab::directadd);
++// fcapabs.insert(hookcapab::files);
++}
++
++msnhook::~msnhook() {
++}
++
++void msnhook::init() {
++ manualstatus = conf.getstatus(msn);
++}
++
++void msnhook::connect() {
++ icqconf::imaccount account = conf.getourid(msn);
++
++ face.log(_("+ [msn] connecting to the server"));
++
++ flogged = false;
++ fonline = true;
++
++ msn_init(&conn, nicknormalize(account.nickname).c_str(), account.password.c_str());
++ msn_connect(&conn, account.server.c_str(), account.port);
++
++ fonline = true;
++ flogged = true;
++}
++
++void msnhook::disconnect() {
++ msn_clean_up(&conn);
++}
++
++void msnhook::exectimers() {
++}
++
++void msnhook::main() {
++ vector<int>::const_iterator i;
++ fd_set rs, ws;
++ struct timeval tv;
++ int hsock;
++
++ FD_ZERO(&rs);
++ FD_ZERO(&ws);
++
++ tv.tv_sec = tv.tv_usec = 0;
++ hsock = 0;
++
++ for(i = rfds.begin(); i != rfds.end(); ++i) {
++ FD_SET(*i, &rs);
++ hsock = max(hsock, *i);
++ }
++
++ for(i = wfds.begin(); i != wfds.end(); ++i) {
++ FD_SET(*i, &ws);
++ hsock = max(hsock, *i);
++ }
++
++ if(select(hsock+1, &rs, &ws, 0, &tv) > 0) {
++ for(i = rfds.begin(); i != rfds.end(); ++i)
++ if(FD_ISSET(*i, &rs)) {
++ msn_handle_incoming(*i, 1, 0);
++ return;
++ }
++
++ for(i = wfds.begin(); i != wfds.end(); ++i)
++ if(FD_ISSET(*i, &ws)) {
++ msn_handle_incoming(*i, 0, 1);
++ return;
++ }
++ }
++}
++
++void msnhook::getsockets(fd_set &rf, fd_set &wf, fd_set &efds, int &hsocket) const {
++ vector<int>::const_iterator i;
++
++ for(i = rfds.begin(); i != rfds.end(); ++i) {
++ hsocket = max(hsocket, *i);
++ FD_SET(*i, &rf);
++ }
++
++ for(i = wfds.begin(); i != wfds.end(); ++i) {
++ hsocket = max(hsocket, *i);
++ FD_SET(*i, &wf);
++ }
++}
++
++bool msnhook::isoursocket(fd_set &rf, fd_set &wf, fd_set &efds) const {
++ vector<int>::const_iterator i;
++
++ for(i = rfds.begin(); i != rfds.end(); ++i)
++ if(FD_ISSET(*i, &rf))
++ return true;
++
++ for(i = wfds.begin(); i != wfds.end(); ++i)
++ if(FD_ISSET(*i, &wf))
++ return true;
++
++ return false;
++}
++
++bool msnhook::online() const {
++ return fonline;
++}
++
++bool msnhook::logged() const {
++ return fonline && flogged;
++}
++
++bool msnhook::isconnecting() const {
++ return fonline && !flogged;
++}
++
++bool msnhook::enabled() const {
++ return true;
++}
++
++bool msnhook::send(const imevent &ev) {
++ string text;
++
++ if(ev.gettype() == imevent::message) {
++ const immessage *m = static_cast<const immessage *>(&ev);
++ if(m) text = m->gettext();
++
++ } else if(ev.gettype() == imevent::url) {
++ const imurl *m = static_cast<const imurl *>(&ev);
++ if(m) text = m->geturl() + "\n\n" + m->getdescription();
++
++ } else if(ev.gettype() == imevent::file) {
++ const imfile *m = static_cast<const imfile *>(&ev);
++ vector<imfile::record> files = m->getfiles();
++ vector<imfile::record>::const_iterator ir;
++
++ for(ir = files.begin(); ir != files.end(); ++ir) {
++ imfile::record r;
++ invitation_ftp *p;
++
++ r.fname = ir->fname;
++ r.size = ir->size;
++
++ imfile fr(ev.getcontact(), imevent::outgoing, "", vector<imfile::record>(1, r));
++
++ if(p = msn_filetrans_send(&conn, ir->fname.c_str()))
++ transferinfo[fr].first = p;
++ }
++
++ return true;
++ }
++
++ icqcontact *c = clist.get(ev.getcontact());
++ text = siconv(text, conf.getrussian(msn) ? "koi8-u" : conf.getdefcharset(), "utf-8");
++
++ if(c)
++ if(c->getstatus() != offline || !c->inlist()) {
++ msn_send_IM(&conn, nicknormalize(ev.getcontact().nickname).c_str(), text.c_str());
++ return true;
++ }
++
++ return false;
++}
++
++void msnhook::sendnewuser(const imcontact &ic) {
++ if(logged()) {
++ icqcontact *c;
++ imcontact icc(nicktodisp(ic.nickname), msn);
++
++ if(icc.nickname != ic.nickname)
++ if(c = clist.get(ic)) {
++ c->setdesc(icc);
++ c->setnick(icc.nickname);
++ c->setdispnick(icc.nickname);
++ }
++
++ msn_add_to_list(&conn, "FL", nicknormalize(ic.nickname).c_str());
++ }
++
++ requestinfo(ic);
++}
++
++void msnhook::setautostatus(imstatus st) {
++ if(st != offline) {
++ if(getstatus() == offline) {
++ connect();
++ } else {
++ logger.putourstatus(msn, ourstatus, st);
++ msn_set_state(&conn, stat2name(ourstatus = st));
++ }
++ } else {
++ if(getstatus() != offline) {
++ disconnect();
++ }
++ }
++}
++
++imstatus msnhook::getstatus() const {
++ return online() ? ourstatus : offline;
++}
++
++void msnhook::removeuser(const imcontact &ic) {
++ removeuser(ic, true);
++}
++
++void msnhook::removeuser(const imcontact &ic, bool report) {
++ if(online()) {
++ if(report)
++ face.log(_("+ [msn] removing %s from the contacts"), ic.nickname.c_str());
++
++ msn_del_from_list(&conn, "FL", nicknormalize(ic.nickname).c_str());
++ }
++}
++
++void msnhook::requestinfo(const imcontact &ic) {
++ icqcontact *c = clist.get(ic);
++
++ if(!c) {
++ c = clist.get(contactroot);
++ c->clear();
++ }
++
++ icqcontact::moreinfo m = c->getmoreinfo();
++ icqcontact::basicinfo b = c->getbasicinfo();
++
++ b.email = nicknormalize(ic.nickname);
++ m.homepage = "http://members.msn.com/" + b.email;
++
++ if(ic.nickname == conf.getourid(msn).nickname)
++ c->setnick(friendlynicks[ic.nickname]);
++
++ c->setmoreinfo(m);
++ c->setbasicinfo(b);
++}
++
++void msnhook::lookup(const imsearchparams &params, verticalmenu &dest) {
++ if(params.reverse) {
++ vector<pair<string, string> >::const_iterator i = slst["RL"].begin();
++
++ while(i != slst["RL"].end()) {
++ icqcontact *c = new icqcontact(imcontact(nicktodisp(i->first), msn));
++ c->setnick(i->second);
++
++ dest.additem(conf.getcolor(cp_clist_msn), c, (string) " " + i->first);
++ ++i;
++ }
++ face.findready();
++
++ face.log(_("+ [msn] reverse users listing finished, %d found"),
++ slst["RL"].size());
++
++ dest.redraw();
++ }
++}
++
++vector<icqcontact *> msnhook::getneedsync() {
++ int i;
++ vector<icqcontact *> r;
++ bool found;
++
++ for(i = 0; i < clist.count; i++) {
++ icqcontact *c = (icqcontact *) clist.at(i);
++
++ if(c->getdesc().pname == msn) {
++ vector<pair<string, string> >::const_iterator fi = slst["FL"].begin();
++
++ for(found = false; fi != slst["FL"].end() && !found; ++fi)
++ found = c->getdesc().nickname == fi->first;
++
++ if(!found)
++ r.push_back(c);
++ }
++ }
++
++ return r;
++}
++
++void msnhook::sendupdateuserinfo(const icqcontact &c) {
++ msn_set_friendlyname(&conn, c.getnick().c_str());
++}
++
++void msnhook::checkfriendly(icqcontact *c, const string friendlynick, bool forcefetch) {
++ string oldnick = c->getnick();
++ string newnick = siconv(unmime(friendlynick), "utf-8", conf.getrussian(msn) ? "koi8-u" : conf.getdefcharset());
++
++ c->setnick(newnick);
++
++ if(forcefetch || (oldnick != newnick && c->getdispnick() != oldnick) || oldnick.empty()) {
++ c->setdispnick(newnick);
++ face.relaxedupdate();
++ }
++}
++
++void msnhook::checkinlist(imcontact ic) {
++ icqcontact *c = clist.get(ic);
++ vector<icqcontact *> notremote = getneedsync();
++
++ if(c)
++ if(c->inlist())
++ if(find(notremote.begin(), notremote.end(), c) != notremote.end())
++ mhook.sendnewuser(ic);
++}
++
++bool msnhook::knowntransfer(const imfile &fr) const {
++ return transferinfo.find(fr) != transferinfo.end();
++}
++
++void msnhook::replytransfer(const imfile &fr, bool accept, const string &localpath) {
++ if(accept) {
++ transferinfo[fr].second = localpath;
++
++ if(transferinfo[fr].second.substr(transferinfo[fr].second.size()-1) != "/")
++ transferinfo[fr].second += "/";
++
++ transferinfo[fr].second += justfname(fr.getfiles().begin()->fname);
++ msn_filetrans_accept(transferinfo[fr].first, transferinfo[fr].second.c_str());
++
++ } else {
++ msn_filetrans_reject(transferinfo[fr].first);
++ transferinfo.erase(fr);
++
++ }
++}
++
++void msnhook::aborttransfer(const imfile &fr) {
++ msn_filetrans_reject(transferinfo[fr].first);
++
++ face.transferupdate(fr.getfiles().begin()->fname, fr,
++ icqface::tsCancel, 0, 0);
++
++ transferinfo.erase(fr);
++}
++
++bool msnhook::getfevent(invitation_ftp *fhandle, imfile &fr) {
++ map<imfile, pair<invitation_ftp *, string> >::const_iterator i = transferinfo.begin();
++
++ while(i != transferinfo.end()) {
++ if(i->second.first == fhandle) {
++ fr = i->first;
++ return true;
++ }
++ ++i;
++ }
++
++ return false;
++}
++
++// ----------------------------------------------------------------------------
++
++static void log(const string &s) {
++#ifdef DEBUG
++ face.log(s);
++#endif
++}
++
++int ext_debug( char *str )
++{
++ log( str );
++ return 0;
++}
++
++void ext_register_sock(int s, int reading, int writing) {
++ log("ext_register_sock");
++ if(reading) mhook.rfds.push_back(s);
++ if(writing) mhook.wfds.push_back(s);
++}
++
++void ext_unregister_sock(int s) {
++ log("ext_unregister_sock");
++ vector<int>::iterator i;
++
++ i = find(mhook.rfds.begin(), mhook.rfds.end(), s);
++ if(i != mhook.rfds.end()) mhook.rfds.erase(i);
++
++ i = find(mhook.wfds.begin(), mhook.wfds.end(), s);
++ if(i != mhook.wfds.end()) mhook.wfds.erase(i);
++}
++
++void ext_got_friendlyname(msnconn * conn, const char * friendlyname) {
++ log("ext_got_friendlyname");
++
++ if(friendlyname)
++ if(strlen(friendlyname))
++ mhook.friendlynicks[conf.getourid(msn).nickname] = friendlyname;
++}
++
++void ext_got_info(msnconn *conn, syncinfo *info) {
++ log("ext_got_info");
++
++ userdata *ud;
++ llist *lst, *pl;
++ imcontact ic;
++
++ for(lst = info->fl; lst; lst = lst->next) {
++ ud = (userdata *) lst->data;
++
++ mhook.slst["FL"].push_back(make_pair(ud->username, ud->friendlyname));
++
++ ic = imcontact(nicktodisp(ud->username), msn);
++ icqcontact *c = clist.get(ic);
++ if(!c) c = clist.addnew(ic, false);
++
++ icqcontact::basicinfo bi = c->getbasicinfo();
++ icqcontact::workinfo wi = c->getworkinfo();
++
++ for(pl = ud->phone; pl; pl = pl->next) {
++ phonedata *pd = (phonedata *) pl->data;
++ string title = pd->title ? pd->title : "";
++
++ if(pd->number)
++ if(strlen(pd->number)) {
++ if(title == "PHH") bi.phone = pd->number; else
++ if(title == "PHW") wi.phone = pd->number; else
++ if(title == "PHM") bi.cellular = pd->number;
++ }
++ }
++
++ c->setbasicinfo(bi);
++ c->setworkinfo(wi);
++ }
++
++ for(lst = info->rl; lst; lst = lst->next) {
++ ud = (userdata *) lst->data;
++ mhook.slst["RL"].push_back(make_pair(ud->username, ud->friendlyname));
++ }
++
++ mhook.setautostatus(mhook.ourstatus);
++}
++
++void ext_latest_serial(msnconn * conn, int serial) {
++ log("ext_latest_serial");
++}
++
++void ext_got_GTC(msnconn * conn, char c) {
++ log("ext_got_GTC");
++}
++
++void ext_got_BLP(msnconn * conn, char c) {
++ log("ext_got_BLP");
++}
++
++void ext_new_RL_entry(msnconn *conn, const char *username, const char *friendlyname) {
++ log("ext_new_RL_entry");
++ msn_add_to_list(&mhook.conn, "AL", username);
++
++ imcontact ic(nicktodisp(username), msn);
++ mhook.checkinlist(ic);
++ em.store(imnotification(ic, _("The user has added you to his/her contact list")));
++}
++
++void ext_new_list_entry(msnconn *conn, const char *lst, const char *username) {
++ log("ext_new_list_entry");
++ mhook.slst[lst].push_back(make_pair(username, string()));
++}
++
++void ext_del_list_entry(msnconn *conn, const char *lst, const char *username) {
++ log("ext_del_list_entry");
++
++ vector<pair<string, string> >::iterator i = mhook.slst[lst].begin();
++ while(i != mhook.slst[lst].end()) {
++ if(i->first == username) {
++ mhook.slst[lst].erase(i);
++ i = mhook.slst[lst].begin();
++ } else {
++ ++i;
++ }
++ }
++}
++
++void ext_show_error(msnconn * conn, const char * msg) {
++ log("ext_show_error");
++ log(msg);
++}
++
++void ext_buddy_set(msnconn * conn, const char * buddy, const char * friendlyname, const char * status) {
++ log("ext_buddy_set");
++ imcontact ic(nicktodisp(buddy), msn);
++ icqcontact *c = clist.get(ic);
++ bool forcefetch;
++
++ if(forcefetch = !c)
++ c = clist.addnew(ic, false);
++
++ if(friendlyname)
++ mhook.checkfriendly(c, friendlyname, forcefetch);
++
++ logger.putonline(ic, c->getstatus(), msn2imstatus(status));
++ c->setstatus(msn2imstatus(status));
++}
++
++void ext_buddy_offline(msnconn * conn, const char * buddy) {
++ log("ext_buddy_offline");
++ ext_buddy_set(conn, buddy, 0, "FLN");
++}
++
++void ext_got_SB(msnconn * conn, void * tag) {
++ log("ext_got_SB");
++}
++
++void ext_user_joined(msnconn *conn, const char *username, const char *friendlyname, int is_initial) {
++ log("ext_user_joined");
++}
++
++void ext_user_left(msnconn *conn, const char *username) {
++ log("ext_user_left");
++}
++
++void ext_got_IM(msnconn *conn, const char *username, const char *friendlyname, message *msg) {
++ log("ext_got_IM");
++ imcontact ic(nicktodisp(username), msn);
++
++ mhook.checkinlist(ic);
++
++ string text = siconv(msg->body, "utf-8", conf.getrussian(msn) ? "koi8-u" : conf.getdefcharset());
++ em.store(immessage(ic, imevent::incoming, text));
++}
++
++void ext_IM_failed(msnconn *conn) {
++ log("ext_IM_failed");
++}
++
++void ext_typing_user(msnconn *conn, const char *username, const char *friendlyname) {
++ log("ext_typing_user");
++ icqcontact *c = clist.get(imcontact(nicktodisp(username), msn));
++ if(c) c->setlasttyping(timer_current);
++}
++
++void ext_initial_email(msnconn *conn, int unread_inbox, int unread_folders) {
++ log("ext_initial_email");
++
++ face.log(_("+ [msn] unread e-mail: %d in inbox, %d in folders"),
++ unread_inbox, unread_folders);
++}
++
++void ext_new_mail_arrived(msnconn *conn, const char *from, const char *subject) {
++ log("ext_new_mail_arrived");
++
++ face.log(_("+ [msn] e-mail from %s, %s"), from, subject);
++ clist.get(contactroot)->playsound(imevent::email);
++}
++
++void ext_filetrans_invite(msnconn *conn, const char *username, const char *friendlyname, invitation_ftp *inv) {
++ log("ext_filetrans_invite");
++
++ if(!mhook.fcapabs.count(hookcapab::files))
++ return;
++
++ imfile::record r;
++ r.fname = inv->filename;
++ r.size = inv->filesize;
++
++ imcontact ic(nicktodisp(username), msn);
++ mhook.checkinlist(ic);
++
++ imfile fr(ic, imevent::incoming, "", vector<imfile::record>(1, r));
++
++ mhook.transferinfo[fr].first = inv;
++ em.store(fr);
++
++ face.transferupdate(inv->filename, fr, icqface::tsInit, inv->filesize, 0);
++}
++
++void ext_filetrans_progress(invitation_ftp *inv, const char *status, unsigned long sent, unsigned long total) {
++ log("ext_filetrans_progress");
++ imfile fr;
++
++ if(mhook.getfevent(inv, fr)) {
++ face.transferupdate(fr.getfiles().begin()->fname, fr,
++ icqface::tsProgress, total, sent);
++ }
++}
++
++void ext_filetrans_failed(invitation_ftp *inv, int error, const char *message) {
++ log("ext_filetrans_failed");
++ imfile fr;
++
++ if(mhook.getfevent(inv, fr)) {
++ face.transferupdate(fr.getfiles().begin()->fname, fr, icqface::tsError, 0, 0);
++ mhook.transferinfo.erase(fr);
++ }
++}
++
++void ext_filetrans_success(invitation_ftp *inv) {
++ log("ext_filetrans_success");
++ imfile fr;
++
++ if(mhook.getfevent(inv, fr)) {
++ face.transferupdate(fr.getfiles().begin()->fname, fr, icqface::tsFinish, 0, 0);
++ mhook.transferinfo.erase(fr);
++ }
++}
++
++void ext_new_connection(msnconn *conn) {
++ log("ext_new_connection");
++ if(conn->type == CONN_NS) {
++ msn_sync_lists(conn, 0);
++ logger.putourstatus(msn, offline, mhook.ourstatus = mhook.manualstatus);
++ mhook.flogged = true;
++ face.log(_("+ [msn] logged in"));
++ face.update();
++ }
++}
++
++void ext_closing_connection(msnconn *conn) {
++ log("ext_closing_connection");
++ if(conn->type == CONN_NS) {
++ mhook.rfds.clear();
++ mhook.wfds.clear();
++ logger.putourstatus(msn, mhook.getstatus(), mhook.ourstatus = offline);
++ clist.setoffline(msn);
++ mhook.fonline = false;
++ mhook.slst.clear();
++ face.log(_("+ [msn] disconnected"));
++ face.update();
++ }
++}
++
++void ext_changed_state(msnconn *conn, const char *state) {
++ log("ext_changed_state");
++}
++
++int ext_do_connect_socket(const char *hostname, int port, int ssl) {
++ struct sockaddr_in sa;
++ struct hostent *hp;
++ int a, s;
++ string msgerr = _("+ [msn] cannot connect: ");
++
++ hp = gethostbyname(hostname);
++ if(!hp) {
++ face.log(msgerr + _("could not resolve hostname"));
++ errno = ECONNREFUSED;
++ return -1;
++ }
++
++ memset(&sa, 0, sizeof(sa));
++ memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length);
++ sa.sin_family = hp->h_addrtype;
++ sa.sin_port = htons((u_short) port);
++
++ if((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0)
++ return -1;
++
++ if(cw_connect(s, (struct sockaddr *) &sa, sizeof(sa), ssl) < 0) {
++ face.log(msgerr + _("verify the hostname and port"));
++ close(s);
++ return -1;
++ }
++
++ return s;
++}
++
++int ext_connect_socket_ssl(const char *hostname, int port) {
++ log("ext_connect_socket_ssl");
++ return ext_do_connect_socket(hostname, port, 1);
++}
++
++int ext_connect_socket(const char *hostname, int port) {
++ log("ext_connect_socket");
++ return ext_do_connect_socket(hostname, port, 0);
++}
++
++int ext_server_socket(int port) {
++ log("ext_server_socket");
++ int s;
++ struct sockaddr_in addr;
++
++ if((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
++ return -1;
++
++ memset(&addr, 0, sizeof(addr));
++ addr.sin_family = AF_INET;
++ addr.sin_port = htons(port);
++
++ if(bind(s, (sockaddr *) &addr, sizeof(addr)) < 0 || listen(s, 1) < 0) {
++ close(s);
++ return -1;
++ }
++
++ return s;
++}
++
++char *ext_get_IP() {
++ log("ext_get_IP");
++ struct hostent *hn;
++ char buf2[1024];
++
++ gethostname(buf2, 1024);
++ hn = gethostbyname(buf2);
++
++ return inet_ntoa(*((struct in_addr*) hn->h_addr));
++}
++
++void ext_protocol_log(const char *buf, int readev, int writeev) {
++ if(readev) {
++ log(string("[IN] ") + buf);
++ } else if(writeev) {
++ log(string("[OUT] ") + buf);
++ }
++}
++
++#endif
diff --git a/net-im/centericq/files/msn-msnhook.h b/net-im/centericq/files/msn-msnhook.h
new file mode 100644
index 000000000000..e2e8ac8fe36b
--- /dev/null
+++ b/net-im/centericq/files/msn-msnhook.h
@@ -0,0 +1,92 @@
+--- src/hooks/msnhook.h.orig Mon Nov 3 20:25:39 2003
++++ src/hooks/msnhook.h Mon Nov 3 20:24:23 2003
+@@ -0,0 +1,89 @@
++#ifndef __MSNHOOK_H__
++#define __MSNHOOK_H__
++
++#include "abstracthook.h"
++
++#ifdef BUILD_MSN
++
++#include "msn_core.h"
++
++class msnhook : public abstracthook {
++
++ friend void ext_register_sock(int s, int reading, int writing);
++ friend void ext_unregister_sock(int s);
++ friend void ext_new_connection(msnconn *conn);
++ friend void ext_closing_connection(msnconn * conn);
++ friend void ext_buddy_set(msnconn *conn, const char *buddy, const char *friendlyname, const char *status);
++ friend void ext_got_info(msnconn *conn, syncinfo *info);
++ friend void ext_got_friendlyname(msnconn *conn, const char *friendlyname);
++ friend void ext_new_RL_entry(msnconn *conn, const char *username, const char *friendlyname);
++ friend void ext_new_list_entry(msnconn *conn, const char *lst, const char *username);
++ friend void ext_del_list_entry(msnconn *conn, const char *lst, const char *username);
++ friend void ext_got_IM(msnconn *conn, const char *username, const char *friendlyname, message *msg);
++ friend void ext_filetrans_invite(msnconn *conn, const char *username, const char *friendlyname, invitation_ftp *inv);
++ friend void ext_typing_user(msnconn *conn, const char *username, const char *friendlyname);
++ friend void ext_filetrans_progress(invitation_ftp *inv, const char *status, unsigned long sent, unsigned long total);
++ friend void ext_filetrans_failed(invitation_ftp *inv, int error, const char *message);
++ friend void ext_filetrans_success(invitation_ftp *inv);
++
++ protected:
++ imstatus ourstatus;
++ bool fonline, flogged;
++ msnconn conn;
++
++ vector<int> rfds, wfds;
++ map<string, string> friendlynicks;
++ map<string, vector<pair<string, string> > > slst;
++ map<imfile, pair<invitation_ftp *, string> > transferinfo;
++
++ void checkfriendly(icqcontact *c, const string friendlynick,
++ bool forcefetch = false);
++
++ void checkinlist(imcontact ic);
++
++ void removeuser(const imcontact &ic, bool report);
++ bool getfevent(invitation_ftp *fhandle, imfile &fr);
++
++ public:
++ msnhook();
++ ~msnhook();
++
++ void init();
++
++ void connect();
++ void disconnect();
++ void exectimers();
++ void main();
++
++ void getsockets(fd_set &rf, fd_set &wf, fd_set &ef, int &hsocket) const;
++ bool isoursocket(fd_set &rf, fd_set &wf, fd_set &ef) const;
++
++ bool online() const;
++ bool logged() const;
++ bool isconnecting() const;
++ bool enabled() const;
++
++ bool send(const imevent &ev);
++
++ void sendnewuser(const imcontact &c);
++ void removeuser(const imcontact &ic);
++ void requestinfo(const imcontact &ic);
++
++ void sendupdateuserinfo(const icqcontact &c);
++
++ void setautostatus(imstatus st);
++ imstatus getstatus() const;
++
++ void lookup(const imsearchparams &params, verticalmenu &dest);
++ vector<icqcontact *> getneedsync();
++
++ bool knowntransfer(const imfile &fr) const;
++ void replytransfer(const imfile &fr, bool accept, const string &localpath = string());
++ void aborttransfer(const imfile &fr);
++};
++
++extern msnhook mhook;
++
++#endif
++
++#endif
diff --git a/net-im/centericq/files/msn-src::Makefile.in b/net-im/centericq/files/msn-src::Makefile.in
new file mode 100644
index 000000000000..90333d9ab2fe
--- /dev/null
+++ b/net-im/centericq/files/msn-src::Makefile.in
@@ -0,0 +1,17 @@
+--- src/Makefile.in.orig Sat Oct 25 15:53:46 2003
++++ src/Makefile.in Mon Nov 3 20:16:35 2003
+@@ -92,11 +92,11 @@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
+
+-INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/hooks -I$(top_srcdir)/firetalk-0.1 -I$(top_srcdir)/kkconsui-0.1/include -I$(top_srcdir)/kkstrtext-0.1 -I$(top_srcdir)/libicq2000-0.1 -I$(top_srcdir)/libjabber-0.1 -I$(top_srcdir)/libyahoo2-0.1 -I$(top_srcdir)/kksystr-0.1/include -I$(top_srcdir)/connwrap-0.1 -I$(top_srcdir)/intl
++INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/hooks -I$(top_srcdir)/firetalk-0.1 -I$(top_srcdir)/kkconsui-0.1/include -I$(top_srcdir)/kkstrtext-0.1 -I$(top_srcdir)/libicq2000-0.1 -I$(top_srcdir)/libjabber-0.1 -I$(top_srcdir)/libyahoo2-0.1 -I$(top_srcdir)/kksystr-0.1/include -I$(top_srcdir)/connwrap-0.1 -I$(top_srcdir)/intl -I$(top_srcdir)/blip-0.1
+ bin_PROGRAMS = centericq
+ centericq_SOURCES = centericq.cc icqcontact.cc icqgroups.cc eventmanager.cc icqdialogs.cc icqhist.cc imexternal.cc imcontact.cc imlogger.cc accountmanager.cc icqcontacts.cc icqmlist.cc imcontroller.cc icqconf.cc imevents.cc icqface.cc centermain.cc icqgroup.cc
+-centericq_LDFLAGS = -L$(top_srcdir)/firetalk-0.1 -L$(top_srcdir)/kkconsui-0.1 -L$(top_srcdir)/kkstrtext-0.1 -L$(top_srcdir)/libicq2000-0.1 -L$(top_srcdir)/libjabber-0.1 -L$(top_srcdir)/libyahoo2-0.1 -L$(top_srcdir)/kksystr-0.1 -L$(top_srcdir)/connwrap-0.1
+-centericq_LDADD = $(top_srcdir)/src/hooks/libhooks.a -lfiretalk -lkkconsui -lkkstrtext -llibicq2000 -llibjabber -llibyahoo2 -lkksystr -lconnwrap @INTLLIBS@
++centericq_LDFLAGS = -L$(top_srcdir)/firetalk-0.1 -L$(top_srcdir)/kkconsui-0.1 -L$(top_srcdir)/kkstrtext-0.1 -L$(top_srcdir)/libicq2000-0.1 -L$(top_srcdir)/libjabber-0.1 -L$(top_srcdir)/libyahoo2-0.1 -L$(top_srcdir)/kksystr-0.1 -L$(top_srcdir)/connwrap-0.1 -L$(top_srcdir)/blip-0.1
++centericq_LDADD = $(top_srcdir)/src/hooks/libhooks.a -lfiretalk -lkkconsui -lkkstrtext -llibicq2000 -llibjabber -llibyahoo2 -lkksystr -lconnwrap @INTLLIBS@ -intl -lblip
+ SUBDIRS = hooks
+ EXTRA_DIST = centericq.cc icqcontact.cc icqgroups.cc eventmanager.cc icqdialogs.cc icqhist.cc imexternal.cc imcontact.cc imlogger.cc accountmanager.cc icqcontacts.cc icqmlist.cc imcontroller.cc icqconf.cc imevents.cc icqface.cc centermain.cc icqgroup.cc icqmlist.h imcontroller.h icqcommon.h icqcontacts.h centericq.h icqgroup.h imcontact.h accountmanager.h eventmanager.h imevents.h icqcontact.h imlogger.h icqconf.h icqface.h icqgroups.h icqhist.h imexternal.h
+ AUTOMAKE_OPTIONS = foreign
diff --git a/net-im/centericq/files/msn-src::hooks::Makefile.in b/net-im/centericq/files/msn-src::hooks::Makefile.in
new file mode 100644
index 000000000000..a8b2da15177b
--- /dev/null
+++ b/net-im/centericq/files/msn-src::hooks::Makefile.in
@@ -0,0 +1,34 @@
+--- src/hooks/Makefile.in.orig Sat Oct 25 15:53:46 2003
++++ src/hooks/Makefile.in Mon Nov 3 21:35:39 2003
+@@ -92,10 +92,10 @@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
+
+-INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/hooks -I$(top_srcdir)/firetalk-0.1 -I$(top_srcdir)/kkconsui-0.1/include -I$(top_srcdir)/kkstrtext-0.1 -I$(top_srcdir)/libicq2000-0.1 -I$(top_srcdir)/libjabber-0.1 -I$(top_srcdir)/libyahoo2-0.1 -I$(top_srcdir)/kksystr-0.1/include -I$(top_srcdir)/connwrap-0.1 -I$(top_srcdir)/intl
++INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/hooks -I$(top_srcdir)/firetalk-0.1 -I$(top_srcdir)/kkconsui-0.1/include -I$(top_srcdir)/kkstrtext-0.1 -I$(top_srcdir)/libicq2000-0.1 -I$(top_srcdir)/libjabber-0.1 -I$(top_srcdir)/libyahoo2-0.1 -I$(top_srcdir)/kksystr-0.1/include -I$(top_srcdir)/connwrap-0.1 -I$(top_srcdir)/intl -I$(top_srcdir)/blip-0.1
+ noinst_LIBRARIES = libhooks.a
+-libhooks_a_SOURCES = yahoohook.cc jabberhook.cc aimhook.cc icqhook.cc irchook.cc abstracthook.cc rsshook.cc HTTPClient.cc ljhook.cc
+-EXTRA_DIST = yahoohook.cc jabberhook.cc aimhook.cc icqhook.cc irchook.cc abstracthook.cc rsshook.cc HTTPClient.cc ljhook.cc yahoohook.h aimhook.h jabberhook.h icqhook.h irchook.h abstracthook.h rsshook.h HTTPClient.h ljhook.h
++libhooks_a_SOURCES = yahoohook.cc jabberhook.cc aimhook.cc icqhook.cc irchook.cc abstracthook.cc rsshook.cc HTTPClient.cc ljhook.cc msnhook.cc
++EXTRA_DIST = yahoohook.cc jabberhook.cc aimhook.cc icqhook.cc irchook.cc abstracthook.cc rsshook.cc HTTPClient.cc ljhook.cc msnhook.cc yahoohook.h aimhook.h jabberhook.h icqhook.h irchook.h abstracthook.h rsshook.h HTTPClient.h ljhook.h msnhook.h
+ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+ CONFIG_HEADER = ../../config.h
+ CONFIG_CLEAN_FILES =
+@@ -108,7 +108,7 @@
+ LIBS = @LIBS@
+ libhooks_a_LIBADD =
+ libhooks_a_OBJECTS = yahoohook.o jabberhook.o aimhook.o icqhook.o \
+-irchook.o abstracthook.o rsshook.o HTTPClient.o ljhook.o
++irchook.o abstracthook.o rsshook.o HTTPClient.o ljhook.o msnhook.o
+ AR = ar
+ CXXFLAGS = @CXXFLAGS@
+ CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+@@ -123,7 +123,7 @@
+ GZIP_ENV = --best
+ DEP_FILES = .deps/HTTPClient.P .deps/abstracthook.P .deps/aimhook.P \
+ .deps/icqhook.P .deps/irchook.P .deps/jabberhook.P .deps/ljhook.P \
+-.deps/rsshook.P .deps/yahoohook.P
++.deps/rsshook.P .deps/yahoohook.P .deps/msnhook.P
+ SOURCES = $(libhooks_a_SOURCES)
+ OBJECTS = $(libhooks_a_OBJECTS)
+
diff --git a/net-im/centericq/files/patch-icqconf.cc b/net-im/centericq/files/patch-icqconf.cc
deleted file mode 100644
index 21c75b162f44..000000000000
--- a/net-im/centericq/files/patch-icqconf.cc
+++ /dev/null
@@ -1,11 +0,0 @@
---- src/icqconf.cc.orig Wed Oct 1 08:27:45 2003
-+++ src/icqconf.cc Wed Oct 8 17:28:21 2003
-@@ -270,7 +270,7 @@
- if(getantispam()) f << "antispam" << endl;
- if(getmailcheck()) f << "mailcheck" << endl;
- if(getaskaway()) f << "askaway" << endl;
-- f << "defcharset" << getdefcharset() << endl;
-+ f << "defcharset\t" << getdefcharset() << endl;
-
- param = "";
- for(protocolname pname = icq; pname != protocolname_size; (int) pname += 1)
diff --git a/net-im/centericq/files/patch-msn_bittybits.C b/net-im/centericq/files/patch-msn_bittybits.C
deleted file mode 100644
index aa1a54f11a79..000000000000
--- a/net-im/centericq/files/patch-msn_bittybits.C
+++ /dev/null
@@ -1,28 +0,0 @@
---- blip-0.1/msn_bittybits.C.orig Mon Dec 9 20:31:41 2002
-+++ blip-0.1/msn_bittybits.C Thu Oct 23 20:02:19 2003
-@@ -18,6 +18,8 @@
- char c;
- int pos=0, numspaces=0;
-
-+ *numargs = 0;
-+
- while(1)
- {
- if(read(sock, &c, 1)<1)
-@@ -259,13 +261,16 @@
- {
- if(*rptr=='\0')
- { *wptr='\0'; break; }
-+
- if(!(isalpha(*rptr) || isdigit(*rptr)))
- {
-+ if ( *rptr != '\xc2' && *rptr != '\xb0' ) {
- sprintf(wptr, "%%%2x", (int)(*rptr));
-
- rptr++;
- wptr+=3;
- continue;
-+ }
- }
-
- *wptr=*rptr;
diff --git a/net-im/centericq/files/patch-msn_core.C b/net-im/centericq/files/patch-msn_core.C
deleted file mode 100644
index 767c3156c0a0..000000000000
--- a/net-im/centericq/files/patch-msn_core.C
+++ /dev/null
@@ -1,923 +0,0 @@
---- blip-0.1/msn_core.C.orig Sat Dec 14 07:58:01 2002
-+++ blip-0.1/msn_core.C Thu Oct 23 20:02:19 2003
-@@ -18,19 +18,18 @@
- #include <sys/stat.h>
-
- #include "md5.h"
--
- #include "msn_core.h"
- #include "msn_bittybits.h"
- #include "msn_interface.h"
-+#include "../connwrap-0.1/connwrap.h"
-
- #define DEBUG 1
-+#define MSN_VERSION_ID 0 // ID that is sent after commands like CHG, NLN, etc.
-
- // Define all those extern'ed variables in msn_core.h:
- llist * connections=NULL;
--
- int next_trid=10;
- char buf[BUF_SIZE]; // used for anything temporary
--
- char * errors[1000];
- char default_error_msg[]="Unknown error code";
-
-@@ -218,143 +217,151 @@
- write(conn->sock, buf, strlen(buf));
- }
-
--void msn_sync_lists(msnconn * conn, int version)
-+void msn_get_list_info( msnconn *conn, int nargs, char **args )
- {
-- syncinfo * info=new syncinfo;
-+ char buf[ 1000 ];
-+ syncinfo *info;
-
-- info->serial=version;
-+ info = conn->sync_info;
-
-- sprintf(buf, "SYN %d %d\r\n", next_trid, version);
-- write(conn->sock, buf, strlen(buf));
-+ if ( NULL == info )
-+ {
-+ ext_debug("error! : conn->sync_info == NULL in msn_get_list_info");
-+ return ;
-+ }
-
-- msn_add_callback(conn, msn_syncdata, next_trid, info);
-- next_trid++;
--}
-+ if ( !nargs )
-+ return ;
-
--void msn_syncdata(msnconn * conn, int trid, char ** args, int numargs, callback_data * data)
--{
-- syncinfo * info=(syncinfo *)data;
--
-- if(!strcmp(args[0], "SYN"))
-+ if ( !strcmp( args[ 0 ], "SYN" ) )
- {
-- if(info->serial==atoi(args[2]))
-+ if ( info->serial == atoi( args[ 2 ] ) )
- {
- delete info;
-- info=NULL;
-- msn_del_callback(conn, trid);
-+ info = NULL;
- ext_got_info(conn, NULL);
- return;
-- } else {
-- info->serial=atoi(args[2]);
-- ext_latest_serial(conn, info->serial);
-- msn_add_callback(conn, msn_phonedata, info->serial, info);
- }
-+
-+ info->serial = atoi( args[ 2 ] );
-+ ext_latest_serial( conn, info->serial );
-+ info->nContacts = atoi( args[ 3 ] );
-+ info->nGroups = atoi( args[ 4 ] );
-+ return ;
- }
-
-- if(!strcmp(args[0], "LST"))
-- {
-- if(!strcmp(args[2], "FL"))
-- {
-- if(!strcmp(args[5], "0"))
-+ if ( !strcmp( args[ 0 ], "GTC" ) )
- {
-- info->fl=NULL; info->complete|=LST_FL;
-- } else {
-- userdata * newuser=new userdata();
-- newuser->username=msn_permstring(args[6]);
-- newuser->friendlyname=msn_decode_URL(msn_permstring(args[6]));
-- msn_add_to_llist(info->fl, newuser);
-- if(atoi(args[4])==atoi(args[5]))
-- { info->complete|=LST_FL; }
-- }
-+ info->gtc = args[ 1 ][ 0 ];
-+ info->complete |= COMPLETE_GTC;
-+ ext_got_GTC( conn, args[ 1 ][ 0 ] );
- }
-- if(!strcmp(args[2], "RL"))
-- {
-- if(!strcmp(args[5], "0"))
-+
-+ if ( !strcmp( args[ 0 ], "BLP" ) )
- {
-- info->rl=NULL; info->complete|=LST_RL; // no mates! :-)
-- } else {
-- userdata * newuser=new userdata();
-- newuser->username=msn_permstring(args[6]);
-- newuser->friendlyname=msn_decode_URL(msn_permstring(args[6]));
-- msn_add_to_llist(info->rl, newuser);
-- if(atoi(args[4])==atoi(args[5]))
-- { info->complete|=LST_RL; }
-+ info->blp = args[ 1 ][0];
-+ info->complete |= COMPLETE_BLP;
-+ ext_got_BLP( conn, args[ 1 ][ 0 ] );
- }
-+
-+ if ( !strcmp( args[ 0 ], "PRP" ) )
-+ {
-+ // We just eat PRP-codes.
-+ return ;
- }
-- if(!strcmp(args[2], "AL"))
-+
-+ if ( !strcmp( args[ 0 ], "LSG" ) )
- {
-- if(!strcmp(args[5], "0"))
-+ if ( !info->nContacts )
- {
-- info->al=NULL; info->complete|=LST_AL;
-- } else {
-- userdata * newuser=new userdata();
-- newuser->username=msn_permstring(args[6]);
-- newuser->friendlyname=msn_decode_URL(msn_permstring(args[6]));
-- msn_add_to_llist(info->al, newuser);
-- if(atoi(args[4])==atoi(args[5]))
-- { info->complete|=LST_AL; }
-+ msn_check_rl(conn, info);
-+ ext_got_info(conn, info);
-+ delete info;
-+ conn->sync = 0;
- }
-+
-+ // Just eat 'm.
-+ return ;
- }
-- if(!strcmp(args[2], "BL"))
-- {
-- if(!strcmp(args[5], "0"))
-+
-+ if ( !strcmp( args[ 0 ], "BPR" ) )
- {
-- info->bl=NULL; info->complete|=LST_BL;
-+ if ( !info->nFound ) {
-+ ext_debug("MSNp8: error: got BPR without contact");
- } else {
-- userdata * newuser=new userdata();
-- newuser->username=msn_permstring(args[6]);
-- newuser->friendlyname=msn_decode_URL(msn_permstring(args[6]));
-- msn_add_to_llist(info->bl, newuser);
-- if(atoi(args[4])==atoi(args[5]))
-- { info->complete|=LST_BL; }
-+ llist *ll = info->fl;
-+
-+ while( ll ) {
-+ userdata * ud = (userdata *) ll->data;
-+
-+ if( !strcmp( ud->username, info->last_user_handled ) )
-+ {
-+ phonedata * newphone=new phonedata();
-+ newphone->title=msn_permstring(args[1]);
-+ newphone->number=msn_decode_URL(msn_permstring(args[2]));
-+ msn_add_to_llist( ud->phone, newphone );
-+ break;
- }
-+
-+ ll = ll->next;
- }
- }
-
-- if(!strcmp(args[0], "GTC"))
-- {
-- info->gtc=args[3][0];
-- info->complete|=COMPLETE_GTC;
-- ext_got_GTC(conn, args[3][0]);
-+ return ;
- }
-
-- if(!strcmp(args[0], "BLP"))
-+ // 0 1 2
-+ // LST email@address.com Friendly%20Nickname w x,y,z
-+ if ( !strcmp( args[ 0 ], "LST" ) )
- {
-- info->blp=args[3][0];
-- info->complete|=COMPLETE_BLP;
-- ext_got_BLP(conn, args[3][0]);
-- }
-+ // XXX - Todo: see if the user is really on our FL
-+ // list and handle the BL list.
-+
-+ userdata *newuser_fl = new userdata();
-+ newuser_fl->username = msn_permstring( args[ 1 ] );
-+ newuser_fl->friendlyname = msn_decode_URL( msn_permstring( args[ 1 ] ) );
-+
-+ info->last_user_handled = newuser_fl->username;
-+
-+ msn_add_to_llist( info->fl, newuser_fl );
-+
-+ userdata *newuser_rl = new userdata();
-+ newuser_rl->username = msn_permstring( args[ 1 ] );
-+ newuser_rl->friendlyname = msn_decode_URL( msn_permstring( args[ 1 ] ) );
-+
-+ msn_add_to_llist( info->rl, newuser_rl );
-
-- if(info->complete == (LST_FL|LST_RL|LST_AL|LST_BL|COMPLETE_BLP|COMPLETE_GTC))
-+ userdata *newuser_al = new userdata();
-+ newuser_al->username = msn_permstring( args[ 1 ] );
-+ newuser_al->friendlyname = msn_decode_URL( msn_permstring( args[ 1 ] ) );
-+
-+ msn_add_to_llist( info->al, newuser_al );
-+
-+ info->nFound++;
-+
-+ if ( info->nFound == info->nContacts )
- {
-- msn_del_callback(conn, trid);
-- msn_del_callback(conn, info->serial);
- msn_check_rl(conn, info);
- ext_got_info(conn, info);
- delete info;
-+ conn->sync = 0;
-+ }
- }
- }
-
--void msn_phonedata(msnconn * conn, int trid, char ** args, int numargs, callback_data * data)
-+void msn_sync_lists(msnconn * conn, int version)
- {
-- syncinfo * info=(syncinfo *)data;
-+ syncinfo * info=new syncinfo;
-
-- if(!strcmp(args[0], "BPR"))
-- {
-- llist * ll = info->fl;
-- while(ll) {
-- userdata * ud = (userdata *) ll->data;
-- if(!strcmp(ud->username, args[2]))
-- {
-- phonedata * newphone=new phonedata();
-- newphone->title=msn_permstring(args[3]);
-- newphone->number=msn_decode_URL(msn_permstring(args[4]));
-- msn_add_to_llist(ud->phone, newphone);
-- break;
-- }
-- ll = ll->next;
-- }
-- }
-+ info->serial=version;
-+
-+ sprintf(buf, "SYN %d %d\r\n", next_trid, version);
-+ write(conn->sock, buf, strlen(buf));
-+
-+ conn->sync = 1;
-+ conn->sync_info = info;
-+
-+ next_trid++;
- }
-
- void msn_check_rl(msnconn * conn, syncinfo * info)
-@@ -544,6 +551,11 @@
- if(!readable) { return; }
-
- args=msn_read_line(sock, &numargs);
-+ if ( !numargs )
-+ {
-+ ext_debug("msn: error: no arguments for this data");
-+ return ;
-+ }
-
- if(args==NULL)
- {
-@@ -582,6 +594,22 @@
-
- trid=atoi(args[1]);
-
-+ if ( conn->sync )
-+ {
-+ // connection is synching. is this a SYNC-relation instruction?
-+ if ( !strcmp( args[ 0 ], "SYN" ) || !strcmp( args[ 0 ], "GTC") || !strcmp( args[ 0 ], "BLP" ) ||
-+ !strcmp( args[ 0 ], "PRP" ) || !strcmp( args[ 0 ], "LSG") || !strcmp( args[ 0 ], "BPR" ) ||
-+ !strcmp( args[ 0 ], "LST" ) )
-+ {
-+ msn_get_list_info( conn, numargs, args );
-+ delete args[0];
-+ delete args;
-+ return ;
-+ }
-+
-+ // else: it's a normal message
-+ }
-+
- list=conn->callbacks;
-
- if(list!=NULL && trid>0)
-@@ -775,6 +803,10 @@
- #endif
- if((tmp=strstr(content, "; charset"))!=NULL) { *tmp='\0'; }
-
-+ if(!strcmp(content, "text/x-msmsgsprofile"))
-+ {
-+ ext_debug("MSNp8: got x-msmsgsprofile");
-+ } else
- if(!strcmp(content, "text/plain"))
- {
- message * msg=new message;
-@@ -1024,7 +1056,6 @@
- write(conn->sock, "VER MSNFTP\r\n", strlen("VER MSNFTP\r\n"));
- }
-
--
- void msn_handle_filetrans_incoming(msnconn * conn, int readable, int writable)
- {
- authdata_FTP * auth=(authdata_FTP *)conn->auth;
-@@ -1445,10 +1476,12 @@
-
- md5_init(&state);
- md5_append(&state, (md5_byte_t *)(args[2]), strlen(args[2]));
-- md5_append(&state, (md5_byte_t *)"Q1P7W2E4J9R8U3S5", 16);
-+ md5_append(&state, (md5_byte_t *)"VT6PX?UQTM4WM%YR", 16);
-+
- md5_finish(&state, digest);
-
-- sprintf(buf, "QRY %d msmsgs@msnmsgr.com 32\r\n", next_trid++);
-+ sprintf(buf, "QRY %d PROD0038W!61ZTF9 32\r\n", next_trid++ );
-+
- write(conn->sock, buf, strlen(buf));
-
- for(a=0; a<16; a++)
-@@ -1591,8 +1624,426 @@
- return inv;
- }
-
-+#define szUser info->username
-+#define szPassword info->password
-+
-+int msn_login_read( int nSock, char *buf, int nMax )
-+{
-+ return cw_read( nSock, buf, nMax, 0 );
-+}
-+
-+int msn_login_wait( int nSocket, char *szCommand )
-+{
-+ int nRet = 0;
-+
-+ while ( !nRet )
-+ nRet = read( nSocket, szCommand, 1000 );
-+
-+ #ifdef MSNDEBUG
-+ printf("<< %s", szCommand );
-+ #endif
-+
-+ return 1;
-+}
-+
-+void msn_login_write1( int nSocket, char *szString, char *szArg )
-+{
-+ char szWrite[ 1000 ];
-+
-+ // ext_debug( szString );
-+ // ext_debug( szArg );
-+
-+ memset( szWrite, 0, 999 );
-+ sprintf( szWrite, "%s %s\r\n", szString, szArg );
-+
-+ // ext_debug( szWrite );
-+
-+ cw_write( nSocket, szWrite, strlen( szWrite ), 0 );
-+}
-+
-+void msn_login_write( int nSocket, char *szString )
-+{
-+ char szWrite[ 1000 ];
-+
-+ memset( szWrite, 0, 1000 );
-+ sprintf( szWrite, "%s\r\n", szString );
-+
-+ cw_write( nSocket, szWrite, strlen( szWrite ), 0 );
-+}
-+
-+int msn_login_connect( int nPort, char *szAddress )
-+{
-+ return ext_connect_socket( szAddress, nPort );
-+}
-+
-+int msn_login_ssl_write( int nSock, char *str )
-+{
-+ return cw_write( nSock, str, strlen( str ), 1 );
-+}
-+
-+int msn_login_ssl_read( int nSock, char *buf, int nMax )
-+{
-+ return cw_read( nSock, buf, nMax, 1 );
-+}
-+
-+int msn_login_close( int nSock )
-+{
-+ return cw_close( nSock );
-+}
-+
-+int msn_login_ssl_connect( int nPort, char *szAddr )
-+{
-+ return ext_connect_socket_ssl( szAddr, nPort );
-+}
-+
-+int msn_login_get_server( char *str, char *filter, char *Server, char *Site )
-+{
-+ char *c, *c1, *c2;
-+
-+ c = strstr( str, filter );
-+ if ( NULL == c )
-+ return 0;
-+ // Skip the "Filter="-part.
-+ c++;
-+ c += strlen( filter );
-+ c1 = strchr( c, '/' );
-+ if ( NULL == c1 )
-+ return 0;
-+ c2 = strchr( c1, ',' );
-+ if ( NULL == c2 )
-+ return 0;
-+
-+ strncpy( Server, c, (unsigned long)c1 - (unsigned long)c );
-+ strncpy( Site, c1, (unsigned long)c2 - (unsigned long)c1 );
-+
-+ return 1;
-+}
-+
-+int msnAuth( char *lc, char *ticket, char *user, char *password )
-+{
-+ int nexus; // Passport Login Nexus
-+ int logins; // Login Server
-+ char result[ 5000 ];
-+ char result2[ 1000 ];
-+ char Server[ 100 ]; // e.g. www.server.com
-+ char Site[ 100 ]; // e.g. /site.html
-+ char String[ 800 ];
-+ int i;
-+ char mail[ 255 ];
-+ char name[ 255 ];
-+
-+ memset( mail, 0, 255 );
-+ memset( name, 0, 255 );
-+
-+ for ( i = 0; i < strlen( user ); i++ )
-+ {
-+ if ( user[i] == '@' )
-+ {
-+ strncpy( name, user, i );
-+ strcpy( mail, (char*)( (unsigned long)user + i + 1 ) );
-+ break;
-+ }
-+ }
-+
-+ memset( Server, 0, 100 );
-+ memset( Site, 0, 100 );
-+
-+ nexus = msn_login_ssl_connect( 443, "nexus.passport.com" );
-+ msn_login_ssl_write( nexus, "GET /rdr/pprdr.asp HTTP/1.0\r\n\r\n" );
-+ msn_login_ssl_read( nexus, result, 800 );
-+ msn_login_close( nexus );
-+ msn_login_get_server( result, "DALogin", Server, Site );
-+
-+ #ifdef MSNDEBUG
-+ printf("Connecting to server '%s' .. site '%s'\n", Server, Site );
-+ #endif
-+
-+ for ( ; ; )
-+ {
-+ // Connect to Login Server
-+ logins = msn_login_ssl_connect( 443, Server );
-+ memset( String, 0, 800 );
-+ sprintf( String, "GET %s HTTP/1.1\r\n"
-+ "Authorization: Passport1.4 OrgVerb=GET,OrgURL=http%%3A%%2F%%2Fmessenger%%2Emsn%%2Ecom,sign-in=%s%%40%s,pwd=%s,%s\r\n"
-+ "Host: %s\r\n\r\n",
-+ Site, name, mail, password, lc, Server );
-+
-+ #ifdef MSNDEBUG
-+ printf("Writing: \n%s\n", String );
-+ #endif
-+
-+ msn_login_ssl_write( logins, String );
-+
-+ memset( result, 0, 5000 );
-+ memset( result2, 0, 1000 );
-+
-+ msn_login_ssl_read( logins, result, 5000 );
-+ msn_login_ssl_read( logins, result2, 1000 );
-+
-+ strcat( result, result2 );
-+
-+ if ( strstr( result, "200 OK" ) )
-+ {
-+ char *tick;
-+ char *c3, *c4;
-+ // Okay.
-+
-+ tick = strstr( result, "t=" );
-+ if ( NULL == tick )
-+ {
-+ #ifdef MSNDEBUG
-+ printf("No t= found in response.\n");
-+ #endif
-+ return 0;
-+ }
-+
-+ tick += 2;
-+
-+ c4 = strstr( tick, "," );
-+
-+ strncpy( ticket, tick, (unsigned long)c4 - (unsigned long)tick - 1 );
-+
-+ //msn_login_close( logins );
-+ return 1;
-+ }
-+
-+ if ( strstr( result, "302 Found") && strstr( result, "redir" ) && strstr( result, "Location: " ) )
-+ {
-+ // Redirection.
-+ char *c3, *c4;
-+
-+ c3 = strstr( result, "Location: " );
-+ c3 += 10;
-+
-+ c3 = strstr( c3, "https://" );
-+ c3 += 8;
-+
-+ c4 = strstr( c3, "/" );
-+ strncpy( Server, c3, (unsigned long)c4 - (unsigned long)c3 );
-+ strncpy( Site, c4, (unsigned long)strchr( c4, '\r' ) - (unsigned long)c4 );
-+
-+ // printf("Redirection to server [%s] - Site [%s]\n", Server, Site );
-+ msn_login_close( logins );
-+ continue;
-+ }
-+
-+ break;
-+ }
-+
-+ // printf("Error\n");
-+ return 0;
-+}
-+
-+int msn_connect_v8_error( connectinfo *info, msnconn *conn, char *szErr )
-+{
-+ ext_show_error( NULL, szErr );
-+ delete info;
-+
-+ if ( conn->sock != -1 )
-+ {
-+ ext_unregister_sock( conn->sock );
-+ close( conn->sock );
-+ conn->sock = -1;
-+ }
-+
-+ return -1;
-+}
-+
-+int msn_connect_v8( connectinfo *info, msnconn *conn, int *nNextTrid )
-+{
-+ int ds; // Dispatch Server
-+ char result[ 1000 ];
-+ char *c;
-+ char szIp[ 20 ];
-+ char szPort[ 20 ];
-+ int nPort;
-+ char lc[ 400 ];
-+ char ticket[ 2000 ];
-+
-+ memset( result, 0, 500 );
-+
-+ ext_debug("MSNp8: finding login server");
-+
-+ // ds = msn_login_connect( 1863, "messenger.hotmail.com" );
-+ ds = conn->sock;
-+
-+ // >> VER 1 MSNP8 CVR0\r\n
-+ msn_login_write( ds, "VER 1 MSNP8 CVR0" );
-+ msn_login_wait( ds, result );
-+
-+ if ( !strstr( result, "VER 1" ) )
-+ return msn_connect_v8_error( info, conn, "Protocol error (didn't receive VER 1)" );
-+
-+ // >> CVR 2 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS something@something.com\r\n
-+ // ext_debug( szUser );
-+
-+ msn_login_write1( ds, "CVR 2 0x0409 winnt 5.1 i386 MSNMSGR 5.0.0540 MSMSGS", szUser );
-+
-+ msn_login_wait( ds, result );
-+
-+ if ( !strstr( result, "CVR 2" ) )
-+ return msn_connect_v8_error( info, conn, "Protocol error (didn't receive CVR 2)" );
-+
-+ // >> USR 3 TWN I something@something.com\r\n
-+ msn_login_write1( ds, "USR 3 TWN I", szUser );
-+ msn_login_wait( ds, result );
-+ if ( !strstr( result, "XFR 3 NS " ) )
-+ return msn_connect_v8_error( info, conn, "Protocol error (didn't receive XFR 3)" );
-+
-+ // Read MSN Server IP from message.
-+ c = strstr( result, "NS ");
-+ c += 3;
-+ memset( szIp, 0, 20 );
-+ memset( szPort, 0, 20 );
-+ strncpy( szIp, c, (unsigned long)strchr( c, ':' ) - (unsigned long)c );
-+ c = strchr( c, ':' ); c++;
-+ strncpy( szPort, c, (unsigned long)strchr( c, ' ' ) - (unsigned long)c );
-+ nPort = atoi( szPort );
-+
-+ // Close current socket.
-+ msn_login_close( ds );
-+ ext_unregister_sock( ds );
-+ conn->sock = -1;
-+
-+ #ifdef MSNDEBUG
-+ printf("* Connecting to IP `%s' port %d *\n", szIp, nPort );
-+ #endif
-+
-+ ext_debug("MSNp8: found.. connecting");
-+
-+ // Try to connect to other server.
-+ ds = msn_login_connect( nPort, szIp );
-+ if ( ds <= 0 )
-+ return msn_connect_v8_error( info, conn, "Error connecting to specified MSN Server" );
-+
-+ // OK. Register the socket.
-+ conn->sock = ds;
-+ ext_register_sock( ds, 1, 0 );
-+
-+ // >> VER 4 MSNP8 CVR0\r\n
-+ msn_login_write( ds, "VER 4 MSNP8 CVR0" );
-+ msn_login_wait( ds, result );
-+
-+ if ( !strstr( result, "VER 4" ) )
-+ return msn_connect_v8_error( info, conn, "Protocol error (didn't receive VER 4)" );
-+
-+ // >> CVR 5 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS something@something.com\r\n
-+ msn_login_write1( ds, "CVR 5 0x0409 winnt 5.1 i386 MSNMSGR 5.0.0540 MSMSGS", szUser );
-+ msn_login_wait( ds, result );
-+
-+ if ( !strstr( result, "CVR 5" ) )
-+ return msn_connect_v8_error( info, conn, "Protocol error (didn't receive CVR 5)" );
-+
-+ // >> USR 6 TWN I something@something.com\r\n
-+ msn_login_write1( ds, "USR 6 TWN I", szUser );
-+ msn_login_wait( ds, result );
-+
-+ // << USR 6 TWN S something@something.com lc=....,....=...\r\n
-+ if ( !strstr( result, "TWN S" ) )
-+ return msn_connect_v8_error( info, conn, "Protocol error (didn't receive TWS S)" );
-+
-+ memset( lc, 0, 400 );
-+ c = strstr( result, "TWN S " );
-+ c+=6;
-+
-+ strncpy( lc, c, (unsigned long)strchr(c, '\r') - (unsigned long)c );
-+
-+ #ifdef MSNDEBUG
-+ printf("LC-etc string = `%s'\n", lc );
-+ #endif
-+
-+ memset( ticket, 0, 2000 );
-+
-+ ext_debug("MSNp8: doing SSL auth");
-+
-+ if ( ! msnAuth( lc, ticket, szUser, szPassword ) )
-+ {
-+ // printf("Error #6\n");
-+ return 0;
-+ }
-+
-+ ext_debug("MSNp8: OK.. logging in");
-+
-+ #ifdef MSNDEBUG
-+ printf("Ticket = `%s'\n", ticket );
-+ #endif
-+
-+ memset( result, 0, 500 );
-+ sprintf( result, "USR 7 TWN S t=%s", ticket );
-+
-+ // >> USR 7 TWN S t=<ticket>
-+ msn_login_write( ds, result );
-+ memset( result, 0, 500 );
-+ msn_login_wait( ds, result );
-+
-+ if ( !strstr( result, "USR 7 OK") )
-+ {
-+ if ( result[ 0 ] >= '0' && result[ 0 ] <= '9' )
-+ {
-+ char *err;
-+ int nCode = 0;
-+ // We received an error code.
-+
-+ err = strchr( result, ' ' );
-+ if ( NULL == err )
-+ nCode = atoi( result );
-+ else {
-+ *err = '\0';
-+ nCode = atoi( result );
-+ }
-+ if ( nCode <= 0 )
-+ return msn_connect_v8_error( info, conn, "Protocol error (Invalid response after USR 7)" );
-+ return nCode;
-+ }
-+
-+ // Invalid response.
-+ return msn_connect_v8_error( info, conn, "Protocol error (Invalid response after USR 7)" );
-+ }
-+
-+ // We are now connected to the MSN Server
-+
-+ // msn_login_write( ds, "OUT" );
-+ // msn_login_close( ds );
-+
-+ // << USR 7 OK something@something.com Something%20Friendly%Nick 1 0
-+ {
-+ char *szFriendly;
-+ char *cEnd;
-+ int i;
-+
-+ szFriendly = result;
-+
-+ for ( i = 0; i < 4; i++ )
-+ {
-+ szFriendly = strchr( szFriendly, ' ' );
-+
-+ if ( NULL == szFriendly )
-+ {
-+ ext_got_friendlyname( conn, "Unknown nickname" );
-+ return 0;
-+ }
-+
-+ szFriendly++;
-+ }
-+
-+ cEnd = strchr( szFriendly, ' ');
-+ if ( NULL != cEnd )
-+ *cEnd = '\0';
-+
-+ // ext_debug( msn_decode_URL( szFriendly ) );
-+ ext_got_friendlyname( conn, msn_decode_URL( szFriendly ) );
-+ }
-+
-+ *nNextTrid = 8;
-+
-+ // No error.
-+ return 0;
-+}
-+
- void msn_connect(msnconn * conn, const char * server, int port)
- {
-+ int result;
-+
- conn->ready=0;
-
- if(conn->type==CONN_SB)
-@@ -1645,106 +2096,37 @@
-
- ext_register_sock(conn->sock, 1, 0);
-
-- #ifdef MSNDEBUG
-- printf("Connected\n"); // DEBUG
-- #endif
--
-- sprintf(buf, "VER %d MSNP7\r\n", next_trid);
-- write(conn->sock, buf, strlen(buf));
-- msn_add_callback(conn, msn_connect_2, next_trid, (callback_data *)info);
-- next_trid++;
--}
--
--// Further connection functions:
-+ // Okay, now try to connect.
-
--void msn_connect_2(msnconn * conn, int trid, char ** args, int numargs, callback_data * data)
--{
-- connectinfo * info;
-+ ext_debug("MSNp8: connecting to MSN.. this could take a few seconds");
-
-- info=(connectinfo *)data;
-- msn_del_callback(conn, trid);
-+ result = msn_connect_v8( info, conn, &next_trid );
-
-- if(strcmp(args[0], "VER") || strcmp(args[2], "MSNP7")) // if either *differs*...
-+ if ( 0 != result )
- {
-- ext_show_error(NULL, "Protocol negotiation failed");
-- delete info;
-- ext_unregister_sock(conn->sock);
-- close(conn->sock);
-- conn->sock=-1;
-- return;
-- }
--
-- sprintf(buf, "USR %d MD5 I %s\r\n", next_trid, info->username);
-- write(conn->sock, buf, strlen(buf));
--
-- msn_add_callback(conn, msn_connect_3, next_trid, data);
-- next_trid++;
--}
--
--void msn_connect_3(msnconn * conn, int trid, char ** args, int numargs, callback_data * data)
--{
-- connectinfo * info;
--
-- md5_state_t state;
-- md5_byte_t digest[16];
-- int a;
--
-- info=(connectinfo *)data;
-- msn_del_callback(conn, trid);
-+ // Error code.
-
-- if(isdigit(args[0][0]))
-+ if ( result > 0 )
- {
-- msn_show_verbose_error(conn, atoi(args[0]));
-- msn_clean_up(conn);
-+ msn_show_verbose_error( conn, result );
- delete info;
-- return;
-- }
-+ msn_clean_up( conn );
-+ conn->sock = -1;
-
-- // OK, the challenge just arrived as args[4]
-+ } // else: connection failed completely. msn_connect_v8 already took care of destroying the connection
-
-- md5_init(&state);
-- md5_append(&state, (md5_byte_t *)(args[4]), strlen(args[4]));
-- md5_append(&state, (md5_byte_t *)(info->password), strlen(info->password));
-- md5_finish(&state, digest);
--
-- sprintf(buf, "USR %d MD5 S ", next_trid);
-- write(conn->sock, buf, strlen(buf));
--
-- for(a=0; a<16; a++)
-- {
-- sprintf(buf, "%02x", digest[a]);
-- write(conn->sock, buf, 2);
- }
--
-- write(conn->sock, "\r\n", 2);
--
-- msn_add_callback(conn, msn_connect_4, next_trid, data);
-- next_trid++;
--}
--
--void msn_connect_4(msnconn * conn, int trid, char ** args, int numargs, callback_data * data)
--{
-- connectinfo * info;
--
-- info=(connectinfo *)data;
-- msn_del_callback(conn, trid);
--
-- if(isdigit(args[0][0]))
-+ else
- {
-- msn_show_verbose_error(conn, atoi(args[0]));
-- delete info;
-- msn_clean_up(conn);
-- return;
-- }
--
-- ext_got_friendlyname(conn, msn_decode_URL(args[4]));
-
-+ // We received no error code. Everything went ok!
- delete info;
-
-- next_trid++;
-+ ext_debug("MSNp8: OK");
-
-- conn->ready=1;
-- ext_new_connection(conn);
-+ conn->ready = 1;
-+ ext_new_connection( conn );
-+ }
- }
-
- void msn_SB_ans(msnconn * conn, int trid, char ** args, int numargs, callback_data * data)
-@@ -1774,30 +2156,7 @@
-
- void msn_set_state(msnconn * conn, const char * state)
- {
-- sprintf(buf, "CHG %d %s\r\n", next_trid, state);
-+ sprintf(buf, "CHG %d %s %d\r\n", next_trid, state, MSN_VERSION_ID );
- write(conn->sock, buf, strlen(buf));
- next_trid++;
- }
--
--/*
--void msn_connect_3(msnconn * conn, char ** args, int numargs, callback_data * data)
--{
-- connectinfo * info;
--
-- info=(connectinfo *)data;
-- msn_del_callback(conn, trid);
-- trid++;
--
-- if(isdigit(args[0][0]))
-- {
-- msn_print_verbose_error(conn, atoi(args[0]));
-- delete info;
-- return;
-- }
--
-- sprintf(buf, "INF %d\r\n", trid, info->username);
-- write(conn.sock, buf, strlen(buf));
--
-- msn_add_callback(conn, msn_connect_4, trid, data);
--}
--*/
diff --git a/net-im/centericq/files/patch-msn_core.h b/net-im/centericq/files/patch-msn_core.h
deleted file mode 100644
index 587455cdf636..000000000000
--- a/net-im/centericq/files/patch-msn_core.h
+++ /dev/null
@@ -1,123 +0,0 @@
---- blip-0.1/msn_core.h.orig Sat Dec 14 07:58:06 2002
-+++ blip-0.1/msn_core.h Thu Oct 23 20:02:19 2003
-@@ -24,6 +24,49 @@
- ~char_data() { if(c!=NULL) { delete c; } }
- };
-
-+class callback_data
-+{};
-+
-+class callback : public llist_data
-+{
-+ public:
-+ int trid;
-+ void (*func)(struct msnconn * conn, int trid, char ** args, int numargs, callback_data * data);
-+ callback_data * data; // just gets passed
-+};
-+
-+// Intermediate steps in synchronisation
-+class syncinfo : public callback_data
-+{
-+ public:
-+
-+ llist * fl;
-+ llist * rl;
-+ llist * al;
-+ llist * bl;
-+
-+ unsigned int complete;
-+
-+ int serial;
-+ int nContacts;
-+ int nGroups;
-+ int nFound;
-+
-+ char *last_user_handled;
-+
-+ char blp;
-+ char gtc;
-+
-+ syncinfo() { nFound = 0; nContacts = 0; blp='A'; gtc='A'; fl=rl=al=bl=NULL; complete=0; serial=0; }
-+ ~syncinfo()
-+ {
-+ if(fl!=NULL) { delete fl; }
-+ if(rl!=NULL) { delete rl; }
-+ if(al!=NULL) { delete al; }
-+ if(bl!=NULL) { delete bl; }
-+ }
-+};
-+
- class message : public llist_data // This class encapsulates all that you need to know (tm) about a MSG
- {
- public:
-@@ -81,14 +124,17 @@
- public:
- int sock; // Socket (durr...)
- int type; // one of the #defines below
-+ int sync; // syncing
- int ready;
-+
-+ syncinfo *sync_info;
- llist * users; // Users in this session - only for SB connections
- llist * invitations_out; // invitations extended but not responded to
- llist * invitations_in; // invitations received but not responded to
- llist * callbacks;
- authdata * auth;
-
-- msnconn() { users=NULL; callbacks=NULL; invitations_out=NULL; invitations_in=NULL; }
-+ msnconn() { sync = 0; users=NULL; callbacks=NULL; invitations_out=NULL; invitations_in=NULL; }
- ~msnconn()
- {
- if(users!=NULL) { delete users; }
-@@ -177,17 +223,6 @@
- #define MSNFTP_SEND 1
- #define MSNFTP_RECV 2
-
--class callback_data
--{};
--
--class callback : public llist_data
--{
-- public:
-- int trid;
-- void (*func)(struct msnconn * conn, int trid, char ** args, int numargs, callback_data * data);
-- callback_data * data; // just gets passed
--};
--
-
- extern llist * connections;
- extern int next_trid;
-@@ -224,33 +259,6 @@
-
- #define COMPLETE_BLP 16
- #define COMPLETE_GTC 32
--
--// Intermediate steps in synchronisation
--class syncinfo : public callback_data
--{
-- public:
--
-- llist * fl;
-- llist * rl;
-- llist * al;
-- llist * bl;
--
-- unsigned int complete;
--
-- int serial;
--
-- char blp;
-- char gtc;
--
-- syncinfo() { blp='A'; gtc='A'; fl=rl=al=bl=NULL; complete=0; serial=0; }
-- ~syncinfo()
-- {
-- if(fl!=NULL) { delete fl; }
-- if(rl!=NULL) { delete rl; }
-- if(al!=NULL) { delete al; }
-- if(bl!=NULL) { delete bl; }
-- }
--};
-
- void msn_set_friendlyname(msnconn * conn, const char * friendlyname);
-
diff --git a/net-im/centericq/files/patch-msn_interface.h b/net-im/centericq/files/patch-msn_interface.h
deleted file mode 100644
index b83df2514f90..000000000000
--- a/net-im/centericq/files/patch-msn_interface.h
+++ /dev/null
@@ -1,20 +0,0 @@
---- blip-0.1/msn_interface.h.orig Mon Dec 9 20:31:41 2002
-+++ blip-0.1/msn_interface.h Thu Oct 23 20:02:19 2003
-@@ -25,6 +25,8 @@
-
- void ext_got_info(msnconn * conn, syncinfo * data);
-
-+void ext_debug( char *msg );
-+
- void ext_latest_serial(msnconn * conn, int serial);
-
- void ext_got_GTC(msnconn * conn, char c);
-@@ -78,6 +80,8 @@
- Return: Nothing
- */
- int ext_connect_socket(const char * server, int port);
-+
-+int ext_connect_socket_ssl(const char * server, int port);
-
- int ext_server_socket(int port);
-
diff --git a/net-im/centericq/files/patch-msnhook.cc b/net-im/centericq/files/patch-msnhook.cc
deleted file mode 100644
index 4f01d4541799..000000000000
--- a/net-im/centericq/files/patch-msnhook.cc
+++ /dev/null
@@ -1,98 +0,0 @@
---- src/hooks/msnhook.cc.orig Tue Sep 30 19:38:43 2003
-+++ src/hooks/msnhook.cc Thu Oct 23 20:12:58 2003
-@@ -120,11 +120,14 @@
-
- face.log(_("+ [msn] connecting to the server"));
-
-+ flogged = false;
-+ fonline = true;
-+
- msn_init(&conn, nicknormalize(account.nickname).c_str(), account.password.c_str());
- msn_connect(&conn, account.server.c_str(), account.port);
-
- fonline = true;
-- flogged = false;
-+ flogged = true;
- }
-
- void msnhook::disconnect() {
-@@ -248,7 +251,7 @@
- }
-
- icqcontact *c = clist.get(ev.getcontact());
-- text = siconv(text, conf.getrussian(msn) ? "koi8-u" : conf.getdefcharset(), "utf8");
-+ text = siconv(text, conf.getrussian(msn) ? "koi8-u" : conf.getdefcharset(), "utf-8");
-
- if(c)
- if(c->getstatus() != offline || !c->inlist()) {
-@@ -378,11 +381,11 @@
-
- void msnhook::checkfriendly(icqcontact *c, const string friendlynick, bool forcefetch) {
- string oldnick = c->getnick();
-- string newnick = unmime(friendlynick);
-+ string newnick = siconv(unmime(friendlynick), "utf-8", conf.getrussian(msn) ? "koi8-u" : conf.getdefcharset());
-
- c->setnick(newnick);
-
-- if(forcefetch || (oldnick != newnick && c->getdispnick() == oldnick) || oldnick.empty()) {
-+ if(forcefetch || (oldnick != newnick && c->getdispnick() != oldnick) || oldnick.empty()) {
- c->setdispnick(newnick);
- face.relaxedupdate();
- }
-@@ -450,6 +453,12 @@
- #endif
- }
-
-+int ext_debug( char *str )
-+{
-+ log( str );
-+ return 0;
-+}
-+
- void ext_register_sock(int s, int reading, int writing) {
- log("ext_register_sock");
- if(reading) mhook.rfds.push_back(s);
-@@ -602,7 +611,7 @@
-
- mhook.checkinlist(ic);
-
-- string text = siconv(msg->body, "utf8", conf.getrussian(msn) ? "koi8-u" : conf.getdefcharset());
-+ string text = siconv(msg->body, "utf-8", conf.getrussian(msn) ? "koi8-u" : conf.getdefcharset());
- em.store(immessage(ic, imevent::incoming, text));
- }
-
-@@ -710,8 +719,7 @@
- log("ext_changed_state");
- }
-
--int ext_connect_socket(const char *hostname, int port) {
-- log("ext_connect_socket");
-+int ext_do_connect_socket(const char *hostname, int port, int ssl) {
- struct sockaddr_in sa;
- struct hostent *hp;
- int a, s;
-@@ -732,13 +740,23 @@
- if((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0)
- return -1;
-
-- if(cw_connect(s, (struct sockaddr *) &sa, sizeof(sa), 0) < 0) {
-+ if(cw_connect(s, (struct sockaddr *) &sa, sizeof(sa), ssl) < 0) {
- face.log(msgerr + _("verify the hostname and port"));
- close(s);
- return -1;
- }
-
- return s;
-+}
-+
-+int ext_connect_socket_ssl(const char *hostname, int port) {
-+ log("ext_connect_socket_ssl");
-+ return ext_do_connect_socket(hostname, port, 1);
-+}
-+
-+int ext_connect_socket(const char *hostname, int port) {
-+ log("ext_connect_socket");
-+ return ext_do_connect_socket(hostname, port, 0);
- }
-
- int ext_server_socket(int port) {
diff --git a/net-im/centericq/files/patch-src:Makefile.in b/net-im/centericq/files/patch-src:Makefile.in
deleted file mode 100644
index 413071b5991d..000000000000
--- a/net-im/centericq/files/patch-src:Makefile.in
+++ /dev/null
@@ -1,7 +0,0 @@
---- src/Makefile.in.orig Thu May 8 14:58:44 2003
-+++ src/Makefile.in Thu May 8 14:58:57 2003
-@@ -98,3 +98,3 @@
- centericq_LDFLAGS = -L$(top_srcdir)/blip-0.1 -L$(top_srcdir)/firetalk-0.1 -L$(top_srcdir)/kkconsui-0.1 -L$(top_srcdir)/kkstrtext-0.1 -L$(top_srcdir)/libicq2000-0.1 -L$(top_srcdir)/libjabber-0.1 -L$(top_srcdir)/libyahoo2-0.1 -L$(top_srcdir)/kksystr-0.1 -L$(top_srcdir)/connwrap-0.1
--centericq_LDADD = $(top_srcdir)/src/hooks/libhooks.a -lblip -lfiretalk -lkkconsui -lkkstrtext -llibicq2000 -llibjabber -llibyahoo2 -lkksystr -lconnwrap @INTLLIBS@
-+centericq_LDADD = $(top_srcdir)/src/hooks/libhooks.a -lblip -lfiretalk -lkkconsui -lkkstrtext -llibicq2000 -llibjabber -llibyahoo2 -lkksystr -lconnwrap @INTLLIBS@ -lintl
- SUBDIRS = hooks
diff --git a/net-im/centericq/files/patch-yahoohook.cc b/net-im/centericq/files/patch-yahoohook.cc
deleted file mode 100644
index 11f5885fd615..000000000000
--- a/net-im/centericq/files/patch-yahoohook.cc
+++ /dev/null
@@ -1,11 +0,0 @@
---- src/hooks/yahoohook.cc.orig Fri Oct 3 03:55:06 2003
-+++ src/hooks/yahoohook.cc Wed Oct 8 17:29:21 2003
-@@ -556,7 +556,7 @@
-
- string yahoohook::decode(const string &text, bool utf) {
- if(utf)
-- return siconv(text, "utf8",
-+ return siconv(text, "utf-8",
- conf.getrussian(proto) ? "koi8-u" : conf.getdefcharset());
-
- return rushtmlconv("wk", text);
diff --git a/net-im/centericq/pkg-descr b/net-im/centericq/pkg-descr
index e8792d82f13d..54d14c937062 100644
--- a/net-im/centericq/pkg-descr
+++ b/net-im/centericq/pkg-descr
@@ -1,5 +1,5 @@
Centericq is a text mode menu- and window-driven IM interface that
-supports the ICQ2000, Yahoo!, AIM, MSN and IRC protocols. It allows you
+supports the ICQ2000, Yahoo!, AIM, and IRC protocols. It allows you
to send, receive, and forward messages, URLs, SMSes, contacts, and email
express messages. It also lets you set your own and fetch others' away
messages, and define external handlers for incoming events. You can
@@ -11,4 +11,6 @@ inactivity, and have your own ignore, visible, and invisible lists.
It can also associate events with sounds, make log of events, and
allows arrangement of contacts into groups.
+Note: MSN protocol is not supported offcially.
+
WWW: http://konst.org.ua/centericq/