<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/">
  <channel rdf:about="http://blog.gmane.org/gmane.network.irc.bot.wraith.scm">
    <title>gmane.network.irc.bot.wraith.scm</title>
    <link>http://blog.gmane.org/gmane.network.irc.bot.wraith.scm</link>
    <description/>
    <syn:updatePeriod>hourly</syn:updatePeriod>
    <syn:updateFrequency>1</syn:updateFrequency>
    <syn:updateBase>1901-01-01T00:00+00:00</syn:updateBase>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/770"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/769"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/768"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/767"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/766"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/765"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/764"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/763"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/762"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/761"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/760"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/759"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/758"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/757"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/756"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/755"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/754"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/753"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/752"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/751"/>
      </rdf:Seq>
    </items>
    <image rdf:resource="http://gmane.org/img/gmane-25t.png"/>
    <textinput rdf:resource=""/>
  </channel>
  <image rdf:about="http://gmane.org/img/gmane-25t.png">
    <title>Gmane</title>
    <url>http://gmane.org/img/gmane-25t.png</url>
    <link>http://gmane.org</link>
  </image>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/770">
    <title>branch 'maint' updated. v1.3.4-506-g3aba8b0</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/770</link>
    <description>&lt;pre&gt;The branch 'maint' has been updated

Summary of changes:
 .gitignore                                         |   20 +-
 Makefile.in                                        |   58 +-
 README                                             |   24 +-
 autotools/Makefile                                 |   35 -
 autotools/depcomp                                  |  105 -
 {autotools =&amp;gt; build/autotools}/.gitignore          |    0
 build/autotools/Makefile                           |   40 +
 {autotools =&amp;gt; build/autotools}/README              |    0
 {autotools =&amp;gt; build/autotools}/configure.ac        |  108 +-
 build/autotools/depcomp                            |  630 ++++++
 .../autotools}/includes/acinclude.m4               |   94 +-
 {autotools =&amp;gt; build/autotools}/includes/depend.m4  |    1 -
 build/autotools/includes/libtcl.m4                 |  593 ++++++
 {autotools =&amp;gt; build/autotools}/includes/stat.m4    |    0
 {autotools =&amp;gt; build/autotools}/includes/wrap.m4    |    0
 build/cc1plus                                      |   58 +
 configure                                          | 2229 +++++++++++++-------
 doc/UPDATES                                        |   55 +
 doc/help.txt                                       |  185 ++-
 doc/responses.txt                                  |    2 +-
 doc/settings.txt                                   |   22 +-
 lib/bdlib                                          |    2 +-
 src/.gitignore                                     |    2 +
 src/Makefile.in                                    |   43 +-
 src/binary.c                                       |   37 +-
 src/binary.h                                       |    1 +
 src/botcmd.c                                       |   22 +
 src/botmsg.c                                       |    2 +-
 src/botmsg.h                                       |    2 +-
 src/botnet.c                                       |  130 +-
 src/chan.h                                         |   81 +-
 src/chanprog.c                                     |  291 ++--
 src/chanprog.h                                     |   13 +-
 src/cmds.c                                         |  247 ++-
 src/compat/Makefile.in                             |   23 +-
 src/conf.c                                         |   84 +-
 src/conf.h                                         |    7 +-
 config.h.in =&amp;gt; src/config.h.in                     |  100 +-
 src/crypt.c                                        |    2 +-
 src/crypt.h                                        |    2 +-
 src/crypto/Makefile.in                             |   26 +-
 src/crypto/aes_util.c                              |    2 +-
 src/crypto/bf_util.c                               |   26 +-
 src/crypto/crypto.h                                |   12 -
 src/crypto/dh_util.c                               |  154 ++
 src/crypto/dh_util.h                               |   22 +
 src/dcc.c                                          |   12 +-
 src/dcc.h                                          |    6 +-
 src/dccutil.c                                      |   84 +-
 src/dccutil.h                                      |    9 +-
 src/debug.c                                        |   82 +-
 src/dhparam.c                                      |  108 +
 src/{mod/compress.mod/compress.h =&amp;gt; dl.c}          |   40 +-
 src/dl.h                                           |   35 +
 src/eggdrop.h                                      |   36 +-
 src/enclink.c                                      |   20 +-
 src/flags.c                                        |   72 +-
 src/flags.h                                        |   41 +-
 src/garble.h                                       |    2 +
 src/generate_defs.sh                               |   65 +
 src/generate_symbol.sh                             |   56 +
 src/libcrypto.c                                    |  133 ++
 src/libcrypto.h                                    |   33 +
 src/libssl.c                                       |  106 +
 src/libssl.h                                       |   30 +
 src/libtcl.c                                       |  152 ++
 src/libtcl.h                                       |   26 +
 src/log.c                                          |    2 +-
 src/main.c                                         |   34 +-
 src/main.h                                         |    2 +-
 src/misc.c                                         |   79 +-
 src/mod/Makefile.in                                |    2 +-
 src/mod/channels.mod/Makefile                      |   11 +-
 src/mod/channels.mod/{tclchan.c =&amp;gt; chanmisc.c}     |  206 ++-
 src/mod/channels.mod/channels.c                    |   43 +-
 src/mod/channels.mod/channels.h                    |    2 +-
 src/mod/channels.mod/cmdschan.c                    |   85 +-
 src/mod/channels.mod/userchan.c                    |   47 +-
 src/mod/compress.mod/Makefile                      |   10 +-
 src/mod/console.mod/Makefile                       |   10 +-
 src/mod/ctcp.mod/Makefile                          |   10 +-
 src/mod/ctcp.mod/ctcp.c                            |   30 +-
 src/mod/irc.mod/Makefile                           |   11 +-
 src/mod/irc.mod/chan.c                             |  461 +++--
 src/mod/irc.mod/cmdsirc.c                          |   73 +-
 src/mod/irc.mod/irc.c                              |  578 +++---
 src/mod/irc.mod/irc.h                              |   40 +-
 src/mod/irc.mod/mode.c                             |  174 ++-
 src/mod/irc.mod/msgcmds.c                          |   28 +-
 src/mod/mod.mk.in                                  |   14 +
 src/mod/server.mod/Makefile                        |   10 +-
 src/mod/server.mod/cmdsserv.c                      |   63 +-
 src/mod/server.mod/server.c                        |   82 +-
 src/mod/server.mod/server.h                        |   16 +-
 src/mod/server.mod/servmsg.c                       |  151 ++-
 src/mod/share.mod/Makefile                         |   10 +-
 src/mod/share.mod/share.c                          |    8 +
 src/mod/transfer.mod/Makefile                      |   10 +-
 src/mod/transfer.mod/transfer.c                    |   14 +-
 src/mod/transfer.mod/transfer.h                    |    6 +-
 src/mod/update.mod/Makefile                        |   10 +-
 src/net.c                                          |  199 ++-
 src/net.h                                          |   26 +-
 src/openssl.c                                      |  162 ++
 src/openssl.h                                      |   22 +
 src/set.c                                          |  144 +-
 src/set.h                                          |    6 +-
 src/settings.h                                     |   12 +-
 src/shell.c                                        |   47 +-
 src/socket.h                                       |    2 +-
 src/stringfix.c                                    |   54 +-
 src/tandem.h                                       |    1 -
 src/types.h                                        |   21 +-
 src/userent.c                                      |   41 +-
 src/userrec.c                                      |   38 +-
 src/userrec.h                                      |    3 +-
 src/users.h                                        |    6 +-
 117 files changed, 7187 insertions(+), 2669 deletions(-)
 delete mode 100755 autotools/Makefile
 delete mode 100755 autotools/depcomp
 rename {autotools =&amp;gt; build/autotools}/.gitignore (100%)
 create mode 100755 build/autotools/Makefile
 rename {autotools =&amp;gt; build/autotools}/README (100%)
 rename {autotools =&amp;gt; build/autotools}/configure.ac (63%)
 create mode 100755 build/autotools/depcomp
 rename {autotools =&amp;gt; build/autotools}/includes/acinclude.m4 (86%)
 rename {autotools =&amp;gt; build/autotools}/includes/depend.m4 (97%)
 create mode 100644 build/autotools/includes/libtcl.m4
 rename {autotools =&amp;gt; build/autotools}/includes/stat.m4 (100%)
 rename {autotools =&amp;gt; build/autotools}/includes/wrap.m4 (100%)
 create mode 100755 build/cc1plus
 rename config.h.in =&amp;gt; src/config.h.in (79%)
 delete mode 100755 src/crypto/crypto.h
 create mode 100644 src/crypto/dh_util.c
 create mode 100644 src/crypto/dh_util.h
 create mode 100644 src/dhparam.c
 copy src/{mod/compress.mod/compress.h =&amp;gt; dl.c} (50%)
 mode change 100755 =&amp;gt; 100644
 create mode 100644 src/dl.h
 create mode 100755 src/generate_defs.sh
 create mode 100755 src/generate_symbol.sh
 create mode 100644 src/libcrypto.c
 create mode 100644 src/libcrypto.h
 create mode 100644 src/libssl.c
 create mode 100644 src/libssl.h
 create mode 100644 src/libtcl.c
 create mode 100644 src/libtcl.h
 rename src/mod/channels.mod/{tclchan.c =&amp;gt; chanmisc.c} (83%)
 create mode 100644 src/mod/mod.mk.in
 create mode 100644 src/openssl.c
 create mode 100644 src/openssl.h

...from  1b15e9a4113b761557522b1b0043df5ab1687802 (commit) to (3aba8b0c8143d232a6a6dd648432e1f5c2ece405)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
-----------------------------------------------------------------------

Complete Diff

diff --git a/.gitignore b/.gitignore
index 9a9342c..992037f 100644
--- a/.gitignore
+++ b/.gitignore
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,11 +1,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 /Makefile
-/confcache
-/config.cache
-/confdefs.h
-/config.h
-/config.log
-/config.status
-/stamp.*
+/build/confcache
+/build/config.cache
+/build/confdefs.h
+/src/config.h
+/build/config.log
+/build/config.status
+/build/stamp.*
+/build/autotools/src
+/src/mod/mod.mk
 /*.tgz
 /leaf
 /hub
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -16,5 +18,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 /ts
 /...
 /.l-*
-.*.swp
+.*.sw*
+.hosts
+.resolv.conf
 .buildbot
diff --git a/Makefile.in b/Makefile.in
index d1dad17..736a7cb 100755
--- a/Makefile.in
+++ b/Makefile.in
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -12,10 +12,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; VPATH = &amp;lt; at &amp;gt;srcdir&amp;lt; at &amp;gt;
 CCDEPMODE = &amp;lt; at &amp;gt;CCDEPMODE&amp;lt; at &amp;gt;
 BINEXEC = wraith&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt;
 
-STATICMAKEFILES = lib/Makefile src/mod/Makefile src/crypto/Makefile src/compat/Makefile src/Makefile Makefile
-CONFIGFILES = config.cache config.log config.status config.h src/buildinfo.h
+STATICMAKEFILES = lib/Makefile src/mod/Makefile src/crypto/Makefile src/compat/Makefile src/Makefile Makefile src/mod/mod.mk
+CONFIGFILES = build/config.cache build/config.log build/config.status src/config.h src/buildinfo.h
 
-DISTROFILES = README LICENSE config.h.in autotools doc scripts lib Makefile.in build.sh configure src BSDmakefile
+DISTROFILES = README LICENSE build doc scripts lib Makefile.in build.sh configure src BSDmakefile
 EXCLUDES = $(CONFIGFILES) $(STATICMAKEFILES)
 
 COMMIT_FULL := $(shell git log -1 --pretty=format:%H HEAD)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -30,7 +30,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; SETTINGSFILE = doc/settings.txt
 RESPONSESFILE = doc/responses.txt
 
 # defaults
-CXX = &amp;lt; at &amp;gt;CCACHE&amp;lt; at &amp;gt; &amp;lt; at &amp;gt;DISTCC&amp;lt; at &amp;gt; &amp;lt; at &amp;gt;CXX&amp;lt; at &amp;gt; &amp;lt; at &amp;gt;STATIC&amp;lt; at &amp;gt;
+CXX = &amp;lt; at &amp;gt;CCACHE&amp;lt; at &amp;gt; &amp;lt; at &amp;gt;DISTCC&amp;lt; at &amp;gt; &amp;lt; at &amp;gt;CXX&amp;lt; at &amp;gt; &amp;lt; at &amp;gt;STATIC&amp;lt; at &amp;gt; -no-integrated-cpp
 LD_DYNAMIC = &amp;lt; at &amp;gt;CXX&amp;lt; at &amp;gt;
 LD_STATIC = &amp;lt; at &amp;gt;CXX&amp;lt; at &amp;gt; &amp;lt; at &amp;gt;STATIC&amp;lt; at &amp;gt;
 CCDEBUG = &amp;lt; at &amp;gt;CCACHE&amp;lt; at &amp;gt; &amp;lt; at &amp;gt;DISTCC&amp;lt; at &amp;gt; &amp;lt; at &amp;gt;CXX&amp;lt; at &amp;gt;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -39,7 +39,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; STRIP = &amp;lt; at &amp;gt;STRIP&amp;lt; at &amp;gt;
 DIFF = &amp;lt; at &amp;gt;DIFF&amp;lt; at &amp;gt;
 
 #LIBS = &amp;lt; at &amp;gt;LIBS&amp;lt; at &amp;gt; &amp;lt; at &amp;gt;ZLIB&amp;lt; at &amp;gt;
-LIBS = &amp;lt; at &amp;gt;LIBS&amp;lt; at &amp;gt; &amp;lt; at &amp;gt;SSL_LIBS&amp;lt; at &amp;gt;
+LIBS = &amp;lt; at &amp;gt;LIBS&amp;lt; at &amp;gt;
+INCLUDES = &amp;lt; at &amp;gt;TCL_INCLUDES&amp;lt; at &amp;gt;
 
 DEBCXXFLAGS = -DDEBUG -fno-inline -g3 -ggdb3 -O0 -Wshadow -Wpointer-arith -Wcast-align &amp;lt; at &amp;gt;GCC3DEB&amp;lt; at &amp;gt; &amp;lt; at &amp;gt;GCC4DEB&amp;lt; at &amp;gt;
 CFLGS = &amp;lt; at &amp;gt;GCC3&amp;lt; at &amp;gt; -fno-rtti &amp;lt; at &amp;gt;SSL_INCLUDES&amp;lt; at &amp;gt;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -57,26 +58,28 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; _CFLGS = -fno-strict-aliasing -W -Wformat \
 
 MAKEFLAGS = -s &amp;lt; at &amp;gt;MAKEJOBS&amp;lt; at &amp;gt;
 
-MAKE_STATIC = $(MAKE) 'MAKE=$(MAKE)' 'CXX=$(CXX)' 'LD=$(LD_STATIC)' \
+STRINGFIX = src/stringfix
+
+MAKE_STATIC = $(MAKE) 'MAKE=$(MAKE)' 'CXX=$(CXX)' 'LD=$(LD_STATIC)' 'INCLUDES=$(INCLUDES)' \
 'CCDEPMODE=$(CCDEPMODE)' 'BRANCH=$(BRANCH)' 'COMMIT=$(COMMIT_SHORT)' 'BUILDTS=$(BUILDTS)' 'VERSION=$(VERSION)' \
-'STRIP=$(STRIP)' 'CFLGS=$(CFLGS) -DBIN_TYPE_STATIC' \
+'STRIP=$(STRIP)' 'CFLGS=$(CFLGS) -DBIN_TYPE_STATIC' 'STRINGFIX=$(STRINGFIX)' \
 'LIBS=$(LIBS)' 'EGGEXEC=$(BINEXEC)' 'EGGBUILD=(wraith)'
 
-MAKE_DYNAMIC = $(MAKE) 'MAKE=$(MAKE)' 'CXX=$(CXX)' 'LD=$(LD_DYNAMIC)' \
+MAKE_DYNAMIC = $(MAKE) 'MAKE=$(MAKE)' 'CXX=$(CXX)' 'LD=$(LD_DYNAMIC)' 'INCLUDES=$(INCLUDES)' \
 'CCDEPMODE=$(CCDEPMODE)' 'BRANCH=$(BRANCH)' 'COMMIT=$(COMMIT_SHORT)' 'BUILDTS=$(BUILDTS)' 'VERSION=$(VERSION)' \
-'STRIP=$(STRIP)' 'CFLGS=$(CFLGS) -DBIN_TYPE_DYNAMIC' \
+'STRIP=$(STRIP)' 'CFLGS=$(CFLGS) -DBIN_TYPE_DYNAMIC' 'STRINGFIX=$(STRINGFIX)' \
 'LIBS=$(LIBS)' 'EGGEXEC=$(BINEXEC)' 'EGGBUILD=(wraith)'
 
-MAKE_DEBUG = $(MAKE) 'MAKE=$(MAKE)' 'CXX=$(CCDEBUG)' 'LD=$(LD_DEBUG) -g' \
+MAKE_DEBUG = $(MAKE) 'MAKE=$(MAKE)' 'CXX=$(CCDEBUG)' 'LD=$(LD_DEBUG) -g' 'INCLUDES=$(INCLUDES)' \
 'CCDEPMODE=$(CCDEPMODE)' 'BRANCH=$(BRANCH)' 'COMMIT=$(COMMIT_SHORT)' 'BUILDTS=$(BUILDTS)' 'VERSION=$(VERSION)' \
-'STRIP=touch' 'CFLGS=$(CFLGS) $(DEBCXXFLAGS) -DBIN_TYPE_DYNAMIC' \
+'STRIP=touch' 'CFLGS=$(CFLGS) $(DEBCXXFLAGS) -DBIN_TYPE_DYNAMIC' 'STRINGFIX=' \
 'LIBS=$(LIBS)' 'EGGEXEC=$(BINEXEC)' 'EGGBUILD=(debug)'
 
-MAKE_UTILS = $(MAKE) 'MAKE=$(MAKE)' 'CXX=$(CCDEBUG)' 'STRIP=touch' \
+MAKE_UTILS = $(MAKE) 'MAKE=$(MAKE)' 'CXX=$(CCDEBUG)' 'STRIP=touch' 'INCLUDES=$(INCLUDES)' \
 'CCDEPMODE=$(CCDEPMODE)' \
 'CFLGS=$(CFLGS) $(DEBCXXFLAGS)' 'LIBS=$(LIBS)' 'LD=$(LD_DEBUG) -g'
 
-MAKE_UTILS_NR = $(MAKE) 'CXX=$(CXX)' 'STRIP=touch' \
+MAKE_UTILS_NR = $(MAKE) 'CXX=$(CXX)' 'STRIP=touch' 'INCLUDES=$(INCLUDES)' \
 'CCDEPMODE=$(CCDEPMODE)' \
 'CFLGS=$(CFLGS) $(DEBCXXFLAGS)' 'LIBS=$(LIBS)' 'LD=$(LD) -g'
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -89,7 +92,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; all: dynamic
 test:
 
 cleanutils:
-&amp;lt; at &amp;gt;rm -f src/stringfix&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt; src/sorthelp&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt; src/makehelp&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt; src/makeres&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt; src/makeset&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt;
+&amp;lt; at &amp;gt;rm -f $(STRINGFIX) src/sorthelp&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt; src/makehelp&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt; src/makeres&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt; src/makeset&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt;
 
 clean:  cleanutils
 +&amp;lt; at &amp;gt;cd src &amp;amp;&amp;amp; $(MAKE) clean
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -97,14 +100,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; clean:  cleanutils
 +&amp;lt; at &amp;gt;cd src/crypto &amp;amp;&amp;amp; $(MAKE) clean
 +&amp;lt; at &amp;gt;cd src/mod &amp;amp;&amp;amp; $(MAKE) distclean
 -+&amp;lt; at &amp;gt;cd lib &amp;amp;&amp;amp; $(MAKE) clean
-&amp;lt; at &amp;gt;rm -f $(BINEXEC) stamp.* *~ src/*~ configure.temp .mangled
+&amp;lt; at &amp;gt;rm -f $(BINEXEC) build/stamp.* *~ src/*~ configure.temp .mangled stamp.*
 &amp;lt; at &amp;gt;rm -f src/help.h src/response.h src/responses.h utctime&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt; ts&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt;
 
 distclean: clean
 &amp;lt; at &amp;gt;rm -rf *-$(VERSION)/ autom4te.cache/ autoscan.log configure.scan
-&amp;lt; at &amp;gt;rm -rf src/.deps/ src/compat/.deps/ src/strucutres/.deps/ src/mod/*.mod/.deps/ src/crypto/.deps
+&amp;lt; at &amp;gt;rm -rf src/.deps/ src/compat/.deps/ src/strucutres/.deps/ src/mod/*.mod/.deps/ src/crypto/.deps src/.defs/
 -+&amp;lt; at &amp;gt;cd lib &amp;amp;&amp;amp; $(MAKE) distclean
-&amp;lt; at &amp;gt;rm -f $(STATICMAKEFILES) $(CONFIGFILES)
+&amp;lt; at &amp;gt;rm -f $(STATICMAKEFILES) $(CONFIGFILES) config.h config.log config.status config.cache
 
 
 distrib: clean
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -149,12 +152,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; sort: sorthelp
 &amp;lt; at &amp;gt;(src/sorthelp&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt; $(HELPFILE) $(HELPFILE) || (cp -f help.txt~ $(HELPFILE); echo "Sort failed, restoring backup."))
 &amp;lt; at &amp;gt;rm -f help.txt~
 
-help: makehelp stringfix
-&amp;lt; at &amp;gt;src/makehelp&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt; $(HELPFILE) src/help.h.tmp~
+help: makehelp
+&amp;lt; at &amp;gt;src/makehelp&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt; $(HELPFILE) src/help.h~
 &amp;lt; at &amp;gt;(if [ ! -f src/help.h ]; then \
 touch src/help.h; \
 fi)
-&amp;lt; at &amp;gt;src/stringfix&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt; src/help.h.tmp~ src/help.h~ 1
 &amp;lt; at &amp;gt;(if test "x`$(DIFF) -qurN src/help.h~ src/help.h`" != "x"; then \
 cp -f src/help.h~ src/help.h; \
 fi)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -184,7 +186,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; res: makeres
 cp -f src/responses.h~ src/responses.h; \
 fi)
 
-stringfix: src/stringfix.c config.h
+stringfix: src/stringfix.c src/config.h
 +&amp;lt; at &amp;gt;cd src &amp;amp;&amp;amp; ${MAKE_UTILS} stringfix
 
 makeres: src/makeres.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -204,30 +206,30 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; utils: stringfix makehelp
 crypto:
 +&amp;lt; at &amp;gt;cd src/crypto &amp;amp;&amp;amp; ${MAKE_UTILS} crypto
 
-general: help res set
+general: help res set stringfix
 
 .NOTPARALLEL: checkclean.static checkclean.dynamic checkclean.debug
 
 checkclean.static:
-&amp;lt; at &amp;gt;(if test -f stamp.dynamic -o -f stamp.debug; then \
+&amp;lt; at &amp;gt;(if test -f build/stamp.dynamic -o -f build/stamp.debug; then \
 echo "[*] Cleaning up alternate build"; \
 $(MAKE) MAKEFLAGS=-s clean; \
 fi)
-&amp;lt; at &amp;gt;touch stamp.static
+&amp;lt; at &amp;gt;touch build/stamp.static
 
 checkclean.dynamic:
-&amp;lt; at &amp;gt;(if test -f stamp.static -o -f stamp.debug; then \
+&amp;lt; at &amp;gt;(if test -f build/stamp.static -o -f build/stamp.debug; then \
 echo "[*] Cleaning up alternate build"; \
 $(MAKE) MAKEFLAGS=-s clean; \
 fi)
-&amp;lt; at &amp;gt;touch stamp.dynamic
+&amp;lt; at &amp;gt;touch build/stamp.dynamic
 
 checkclean.debug:
-&amp;lt; at &amp;gt;(if test -f stamp.static -o -f stamp.dynamic; then \
+&amp;lt; at &amp;gt;(if test -f build/stamp.static -o -f build/stamp.dynamic; then \
 echo "[*] Cleaning up alternate build"; \
 $(MAKE) MAKEFLAGS=-s clean; \
 fi)
-&amp;lt; at &amp;gt;touch stamp.debug
+&amp;lt; at &amp;gt;touch build/stamp.debug
 
 lib:
 +&amp;lt; at &amp;gt;cd lib &amp;amp;&amp;amp; $(MAKE)
diff --git a/README b/README
index e08fdeb..2b0a67c 100644
--- a/README
+++ b/README
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5,10 +5,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; __  _  ______________  |__|/  |_|  |__
   \/\_/   |__|  (____  /__||__| |___|  /
                      \/              \/
        http://wraith.botpack.net
+            &amp;lt; at &amp;gt;wraithbotpack
 
-Wraith is an IRC bot written purely in C/C++. It has been in development since late 2003.
-It is based on Eggdrop 1.6.12 but has since evolved into something much different at its
-core. TCL and loadable modules are currently not supported.
+Wraith is an IRC channel management bot written purely in C/C++.
+It has been in development since late 2003. It is based on
+Eggdrop 1.6.12 but has since evolved into something much
+different at its core. TCL and loadable modules are currently
+not supported.
 
 Wraith aims to be a secure and easy to setup and manage botnet.
 A botnet can be setup in a matter of minutes and updated later with 1 command.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -24,16 +27,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; Git: git://github.com/wraith/wraith.git
 
 See git for a list of Contributors: git shortlog -sen master
 
-You can also follow us on twitter: http://twitter.com/wraithbotpack
-
 Support:
-  How To Contribute: http://wraith.botpack.net/wiki/Contributing
-  Getting Started: http://wraith.botpack.net/wiki/GettingStarted
-  FAQ: http://wraith.botpack.net/wiki/FrequentlyAskedQuestions
-  Documentation Index: http://wraith.botpack.net/wiki/Documentation
-  Bugs can be reported at: http://wraith.botpack.net/newticket
-  Bugs can be looked up by #, i.e., '#24' in url: http://wraith.botpack.net/ticket/24
-  #wraith &amp;lt; at &amp;gt; EFnet
+* How To Contribute: http://wraith.botpack.net/wiki/Contributing
+* Getting Started: http://wraith.botpack.net/wiki/GettingStarted
+* FAQ: http://wraith.botpack.net/wiki/FrequentlyAskedQuestions
+* Documentation Index: http://wraith.botpack.net/wiki/Documentation
+* Issues can be reported at: https://github.com/wraith/wraith/issues
+* #wraith &amp;lt; at &amp;gt; EFnet
 
 Please support wraith by signing up for a shell at http://www.xzibition.com (coupon 'wraith' for 30% off)
 
diff --git a/autotools/Makefile b/autotools/Makefile
deleted file mode 100755
index 7c78797..0000000
--- a/autotools/Makefile
+++ /dev/null
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,35 +0,0 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
-
-all: clean aclocal autoheader autoconf clean_again
-
-
-aclocal:
-&amp;lt; at &amp;gt;rm -rf aclocal.m4
-aclocal -I includes/
-
-autoheader:
-&amp;lt; at &amp;gt;rm -rf ../config.h.in
-&amp;lt; at &amp;gt;echo "Autoheader..."
-&amp;lt; at &amp;gt;autoheader
-&amp;lt; at &amp;gt;mv -f config.h.in ../config.h.in
-&amp;lt; at &amp;gt;ls -al ../config.h.in
-
-autoconf: 
-&amp;lt; at &amp;gt;rm -rf ../configure
-&amp;lt; at &amp;gt;echo "Autoconf...."
-&amp;lt; at &amp;gt;autoconf
-&amp;lt; at &amp;gt;echo "Fixing configure for cache_file"
-&amp;lt; at &amp;gt;(if ! sed configure -e "s/^cache_file=\/dev\/null/cache_file=\.\/config.cache/" \
--e "s/&amp;amp;&amp;amp; echo \"updating cache .cache_file\"//" &amp;gt; ../configure; then \
-cp configure ../configure; \
-rm configure; \
-fi)
-&amp;lt; at &amp;gt;chmod 700 ../configure
-&amp;lt; at &amp;gt;ls -al ../configure
-
-clean:
-&amp;lt; at &amp;gt;echo "Cleaning..."
-&amp;lt; at &amp;gt;rm -rf autom4te.cache/ configure config.h.in aclocal.m4
-
-clean_again:
-&amp;lt; at &amp;gt;echo "Cleaning..."
-&amp;lt; at &amp;gt;rm -rf autom4te.cache/ configure config.h.in aclocal.m4
diff --git a/autotools/depcomp b/autotools/depcomp
deleted file mode 100755
index 55d653b..0000000
--- a/autotools/depcomp
+++ /dev/null
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,105 +0,0 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
-#! /bin/sh
-
-# depcomp - compile a program generating dependencies as side-effects
-# Copyright 1999, 2000 Free Software Foundation, Inc.
-
-if test -z "$depmode" || test -z "$source" || test -z "$object"; then
-  echo "depcomp: Variables source, object and depmode must be set" 1&amp;gt;&amp;amp;2
-  exit 1
-fi
-
-if test -z "$depfile"; then
-   base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
-   dir=`echo "$object" | sed 's,/.*$,/,'`
-   if test "$dir" = "$object"; then
-      dir=
-   fi
-   depfile="$dir.deps/$base"
-fi
-
-tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
-
-rm -f "$tmpdepfile"
-
-# Some modes work just like other modes, but use different flags.  We
-# parameterize here, but still list the modes in the big case below,
-# to make depend.m4 easier to write.  Note that we *cannot* use a case
-# here, because this file can only contain one case statement.
-
-case "$depmode" in
-gcc3)
-## gcc 3 implements dependency tracking that does exactly what
-## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
-## it if -MD -MP comes after the -MF stuff.  Hmm.
-  if test -z "$MM"; then
-   "$&amp;lt; at &amp;gt;" -MT "$object" -MD -MP -MF "$tmpdepfile"
-  else
-   "$&amp;lt; at &amp;gt;" -MM "$object" -MD -MP -MF "$tmpdepfile"
-  fi
-  stat=$?
-  if test $stat -eq 0; then :
-  else
-    rm -f "$tmpdepfile"
-    exit $stat
-  fi
-  mv "$tmpdepfile" "$depfile"
-  ;;
-
-gcc)
-## There are various ways to get dependency output from gcc.  Here's
-## why we pick this rather obscure method:
-## - Don't want to use -MD because we'd like the dependencies to end
-##   up in a subdir.  Having to rename by hand is ugly.
-##   (We might end up doing this anyway to support other compilers.)
-## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
-##   -MM, not -M (despite what the docs say).
-## - Using -M directly means running the compiler twice (even worse
-##   than renaming).
-  if test -z "$gccflag"; then
-    gccflag=-MD,
-  fi
-  "$&amp;lt; at &amp;gt;" -Wp,"$gccflag$tmpdepfile"
-  stat=$?
-  if test $stat -eq 0; then :
-  else
-    rm -f "$tmpdepfile"
-    exit $stat
-  fi
-  rm -f "$depfile"
-  echo "$object : \\" &amp;gt; "$depfile"
-  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
-## The second -e expression handles DOS-style file names with drive letters.
-  sed -e 's/^[^:]*: / /' \
-      -e 's/^['$alpha']:\/[^:]*: / /' &amp;lt; "$tmpdepfile" &amp;gt;&amp;gt; "$depfile"
-## This next piece of magic avoids the `deleted header file' problem.
-## The problem is that when a header file which appears in a .P file
-## is deleted, the dependency causes make to die (because there is
-## typically no way to rebuild the header).  We avoid this by adding
-## dummy dependencies for each header file.  Too bad gcc doesn't do
-## this for us directly.
-  tr ' ' '
-' &amp;lt; "$tmpdepfile" |
-## Some versions of gcc put a space before the `:'.  On the theory
-## that the space means something, we add a space to the output as
-## well.
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly.  Breaking it into two sed invocations is a workaround.
-    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' &amp;gt;&amp;gt; "$depfile"
-  rm -f "$tmpdepfile"
-  ;;
-
-#nosideeffect)
-  # This comment above is used by automake to tell side-effect
-  # dependency tracking mechanisms from slower ones.
-
-none)
-  exec "$&amp;lt; at &amp;gt;"
-  ;;
-
-*)
-  echo "Unknown depmode $depmode" 1&amp;gt;&amp;amp;2
-  exit 1
-  ;;
-esac
-
-exit 0
diff --git a/autotools/.gitignore b/build/autotools/.gitignore
similarity index 100%
rename from autotools/.gitignore
rename to build/autotools/.gitignore
diff --git a/build/autotools/Makefile b/build/autotools/Makefile
new file mode 100755
index 0000000..23a86ea
--- /dev/null
+++ b/build/autotools/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,40 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+
+all: clean aclocal autoheader autoconf clean_again
+
+
+aclocal:
+&amp;lt; at &amp;gt;rm -rf aclocal.m4
+&amp;lt; at &amp;gt;mkdir src
+aclocal -I includes/
+
+autoheader:
+&amp;lt; at &amp;gt;rm -f ../../src/config.h.in
+&amp;lt; at &amp;gt;echo "Autoheader..."
+&amp;lt; at &amp;gt;autoheader
+&amp;lt; at &amp;gt;mv -f src/config.h.in ../../src/config.h.in
+&amp;lt; at &amp;gt;ls -al ../../src/config.h.in
+
+autoconf: 
+&amp;lt; at &amp;gt;rm -rf ../../configure
+&amp;lt; at &amp;gt;echo "Autoconf...."
+&amp;lt; at &amp;gt;autoconf
+&amp;lt; at &amp;gt;echo "Fixing configure temp paths"
+&amp;lt; at &amp;gt;(if ! sed configure \
+  -e 's:config\.log:build/config.log:g' \
+  -e 's:config\.status:build/config.status:g' \
+  -e 's:confdefs\.h:build/confdefs.h:g' \
+  &amp;gt; ../../configure; then \
+  echo "FAILED TO FIX configure" &amp;gt;&amp;amp;2; \
+          cp configure ../../configure; \
+          rm configure; \
+fi)
+&amp;lt; at &amp;gt;chmod 700 ../../configure
+&amp;lt; at &amp;gt;ls -al ../../configure
+
+clean:
+&amp;lt; at &amp;gt;echo "Cleaning..."
+&amp;lt; at &amp;gt;rm -rf autom4te.cache/ configure aclocal.m4 src/
+
+clean_again:
+&amp;lt; at &amp;gt;echo "Cleaning..."
+&amp;lt; at &amp;gt;rm -rf autom4te.cache/ configure aclocal.m4 src/
diff --git a/autotools/README b/build/autotools/README
similarity index 100%
rename from autotools/README
rename to build/autotools/README
diff --git a/autotools/configure.ac b/build/autotools/configure.ac
similarity index 63%
rename from autotools/configure.ac
rename to build/autotools/configure.ac
index 85bc837..d0ef1db 100755
--- a/autotools/configure.ac
+++ b/build/autotools/configure.ac
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5,8 +5,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; dnl
 AC_PREREQ(2.59)
 AC_INIT([wraith],[],[wraith&amp;lt; at &amp;gt;botpack.net])
 AC_CONFIG_SRCDIR(src/eggdrop.h)
-AC_CONFIG_HEADER(config.h)
-AC_COPYRIGHT([Copyright (c) 2003 - 2010 Bryan Drewery])
+AC_CONFIG_HEADER(src/config.h)
+AC_COPYRIGHT([Copyright (c) Bryan Drewery])
 AC_REVISION($Revision$)
 
 EGG_SAVE_PARAMETERS
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -15,7 +15,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; EGG_SAVE_PARAMETERS
 dnl Search for newer gcc versions before older
 #AC_REQUIRE_CPP
 AC_LANG(C++)
-AC_PROG_CXX([g++45 g++-4.5 g++-4.4 g++-4.4.1 g++-4.4.2 g++-4.4.0 g++44 g++4 g++-3.3 g++33 g++-3 g++3 g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC])
+AC_PROG_CXX([g++47 g++-4.7 g++46 g++-4.6 g++45 g++-4.5 g++-4.4 g++-4.4.1 g++-4.4.2 g++-4.4.0 g++44 g++4 eg++ g++-3.3 g++33 g++-3 g++3 g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC])
 dnl AC_PROG_CC([gcc34 gcc-3.4 gcc33 gcc3 gcc-3.3 gcc cc c1])
 EGG_CHECK_CC
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -38,6 +38,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; AC_CACHE_SAVE
 
 # Checks for programs
 AC_PROG_MAKE_SET
+AC_PROG_SED
 EGG_PROG_HEAD_1
 EGG_PROG_AWK
 EGG_PROG_BASENAME
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -79,7 +80,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; AC_HEADER_STAT
 #checkpoint
 AC_CACHE_SAVE 
 AC_CHECK_HEADERS([stdarg.h std_arg.h arpa/inet.h fcntl.h limits.h locale.h netdb.h netinet/in.h])
-AC_CHECK_HEADERS([sys/file.h sys/ioctl.h sys/param.h sys/socket.h wchar.h sys/ptrace.h paths.h])
+AC_CHECK_HEADERS([sys/file.h sys/ioctl.h sys/param.h sys/socket.h wchar.h sys/ptrace.h paths.h sys/prctl.h])
 
 #checkpoint
 AC_CACHE_SAVE
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -88,6 +89,60 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; AC_CACHE_SAVE
 #EGG_CHECK_ZLIB
 CHECK_SSL
 
+# TCL checks
+
+# Tcl version to recommend if no Tcl is found, and the site where it can be
+# found for download.
+tclrecommendver="8.5.X"
+tclrecommendsite="ftp://tcl.activestate.com/pub/tcl/tcl8_5/"
+
+# Tcl library filename prefixes, suffixes, and search paths.
+tcllibnames="tcl8.5 tcl85 tcl8.4 tcl84 tcl8.3 tcl83 tcl8.2 tcl82 \
+             tcl8.1 tcl81 tcl8.0 tcl80 tcl tcl7.6 tcl76 tcl7.5 tcl75 \
+             tcl7.4 tcl74 tcl7.3 tcl73 tcl7.2 tcl72 tcl7.1 tcl71 \
+             tcl7.0 tcl70"
+
+tcllibextensions=".so .so.1 .so.1.0 .so.1.1 .so.1.2 .dll .dylib .sl .a"
+
+tcllibpaths="$HOME/lib $HOME/tcl/lib \
+             /usr/local/lib /usr/lib /lib /lib64 /usr/lib64 \
+             /usr/local/lib/tcl8.5 /usr/lib/tcl8.5 \
+             /usr/local/lib/tcl8.4 /usr/lib/tcl8.4 \
+             /usr/local/lib/tcl8.3 /usr/lib/tcl8.3 \
+             /usr/local/pkgs/tcl/lib /sys/lib /usr/pkg/lib \
+             /usr/i486-linuxaout/lib /beos/system/lib $HOME"
+
+# Tcl header filenames and search paths.
+tclheadernames="tcl.h"
+tclheaderpaths="$HOME/include $HOME/tcl/include \
+                /usr/local/include /usr/include \
+                /usr/local/include/tcl8.5 /usr/include/tcl8.5 \
+                /usr/local/include/tcl8.4 /usr/include/tcl8.4 \
+                /usr/local/include/tcl8.3 /usr/include/tcl8.3 \
+                /usr/local/pkgs/tcl/include /sys/include \
+                /usr/pkg/lib /beos/system/include /beos/devel/include $HOME"
+
+
+# Misc Tcl checks.
+EGG_TCL_OPTIONS
+EGG_TCL_ENV
+EGG_TCL_WITH_TCLLIB
+EGG_TCL_WITH_TCLINC
+EGG_TCL_FIND_LIBRARY
+EGG_TCL_FIND_HEADER
+EGG_TCL_CHECK_LIBRARY
+EGG_TCL_CHECK_HEADER
+EGG_TCL_DETECT_CHANGE
+EGG_TCL_CHECK_VERSION
+EGG_TCL_CHECK_PRE70
+EGG_TCL_TESTLIBS
+EGG_TCL_CHECK_FREE
+#EGG_TCL_CHECK_GETCURRENTTHREAD
+#EGG_TCL_CHECK_GETTHREADDATA
+EGG_TCL_CHECK_SETNOTIFIER
+EGG_TCL_LIB_REQS
+
+AC_CACHE_SAVE
 
 #AC_SUBST(ZLIB)dnl
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -108,13 +163,19 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; AC_C_CHAR_UNSIGNED
 #checkpoint
 AC_CACHE_SAVE 
 
-AC_CHECK_SIZEOF(short, 0)
-AC_CHECK_SIZEOF(int, 0)
-AC_CHECK_SIZEOF(long, 0)
-AC_CHECK_SIZEOF(long long,0)
-AC_CHECK_SIZEOF(size_t, 0)
-AC_CHECK_SIZEOF(ptrdiff_t, 0)
-AC_CHECK_SIZEOF(time_t, 0)
+# Checks for typedefs, structures, and compiler characteristics
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_TYPE_UID_T
+AC_TYPE_LONG_LONG_INT
+AC_TYPE_INT8_T
+AC_TYPE_UINT8_T
+AC_TYPE_INT16_T
+AC_TYPE_UINT16_T
+AC_TYPE_INT32_T
+AC_TYPE_UINT32_T
+AC_TYPE_INT64_T
+AC_TYPE_UINT64_T
 
 
 AC_STRUCT_TIMEZONE
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -159,7 +220,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; EGG_SUBST_VERSION
 EGG_SUBST_MOD_UPDIR
 DO_DEPS
 
-AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile src/compat/Makefile src/crypto/Makefile src/mod/Makefile src/buildinfo.h])
+AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile src/compat/Makefile src/crypto/Makefile src/mod/Makefile src/buildinfo.h src/mod/mod.mk])
 AC_OUTPUT
 
 AH_TEMPLATE(HAVE_ST_MTIM, [Define to 1 if your struct stat has an st_mtim member])
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -199,6 +260,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; AH_BOTTOM([/*
 #    endif
 #  endif
 #endif
+
+/* TCL sanity check */
+#ifdef USE_SCRIPT_TCL
+#  ifndef HAVE_LIBTCL
+#    undef USE_SCRIPT_TCL
+#  endif
+#endif
 ])
 
 [
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -217,13 +285,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if [ "$GIT_REQUIRED" = "1" ]; then
 fi
 ]
 
-echo ""
-echo ""
-echo "------------ Configuring BDLIB ------------"
 [
 if test -d .git; then
   git submodule init
   git submodule update
 fi
 ]
-test -f lib/bdlib/configure &amp;amp;&amp;amp; cd lib/bdlib &amp;amp;&amp;amp; MAKEJOBS="$MAKEJOBS" ./configure
+
+CXX="$CXX" TCL_INCLUDES="$TCL_INCLUDES" SSL_INCLUDES="$SSL_INCLUDES" SED="$SED" src/generate_defs.sh
+[
+if [ $? -ne 0 ]; then
+  exit 1
+fi
+]
+
+echo ""
+echo ""
+echo "------------ Configuring BDLIB ------------"
+test -f lib/bdlib/configure &amp;amp;&amp;amp; cd lib/bdlib &amp;amp;&amp;amp; CXX="$CXX" MAKEJOBS="$MAKEJOBS" ./configure
diff --git a/build/autotools/depcomp b/build/autotools/depcomp
new file mode 100755
index 0000000..df8eea7
--- /dev/null
+++ b/build/autotools/depcomp
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,630 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
+# Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva &amp;lt;oliva&amp;lt; at &amp;gt;dcc.unicamp.br&amp;gt;.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1&amp;gt;&amp;amp;2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat &amp;lt;&amp;lt;\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to &amp;lt;bug-automake&amp;lt; at &amp;gt;gnu.org&amp;gt;.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1&amp;gt;&amp;amp;2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&amp;amp;|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+   # This is just like msvisualcpp but w/o cygpath translation.
+   # Just convert the backslash-escaped backslashes to single forward
+   # slashes to satisfy depend.m4
+   cygpath_u="sed s,\\\\\\\\,/,g"
+   depmode=msvisualcpp
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$&amp;lt; at &amp;gt;" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$&amp;lt; at &amp;gt;" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$&amp;lt; at &amp;gt;"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$&amp;lt; at &amp;gt;" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" &amp;gt; "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' &amp;lt; "$tmpdepfile" &amp;gt;&amp;gt; "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' &amp;lt; "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' &amp;gt;&amp;gt; "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$&amp;lt; at &amp;gt;" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$&amp;lt; at &amp;gt;" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" &amp;gt; "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' &amp;lt; "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' &amp;gt;&amp;gt; "$depfile"
+    echo &amp;gt;&amp;gt; "$depfile"
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' &amp;lt; "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   &amp;gt;&amp;gt; "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" &amp;gt; "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" &amp;amp;&amp;amp; dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
+    "$&amp;lt; at &amp;gt;" -Wc,-M
+  else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
+    "$&amp;lt; at &amp;gt;" -M
+  fi
+  stat=$?
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" &amp;amp;&amp;amp; break
+  done
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^.*\.[a-z]*:,$object:," &amp;lt; "$tmpdepfile" &amp;gt; "$depfile"
+    # That's a tab and a space in the [].
+    sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' &amp;lt; "$tmpdepfile" &amp;gt;&amp;gt; "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" &amp;gt; "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$&amp;lt; at &amp;gt;" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," &amp;lt; "$tmpdepfile" &amp;gt; "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' &amp;lt; "$tmpdepfile" |
+    sed -e 's/$/ :/' &amp;gt;&amp;gt; "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" &amp;amp;&amp;amp; dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$&amp;lt; at &amp;gt;" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$&amp;lt; at &amp;gt;" +Maked
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" &amp;amp;&amp;amp; break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" &amp;gt; "$depfile"
+    # Add `dependent.h:' lines.
+    sed -ne '2,${
+       s/^ *//
+       s/ \\*$//
+       s/$/:/
+       p
+     }' "$tmpdepfile" &amp;gt;&amp;gt; "$depfile"
+  else
+    echo "#dummy" &amp;gt; "$depfile"
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" &amp;amp;&amp;amp; dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mechanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
+      "$&amp;lt; at &amp;gt;" -Wc,-MD
+   else
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
+      "$&amp;lt; at &amp;gt;" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+      exit $stat
+   fi
+
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" &amp;amp;&amp;amp; break
+   done
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," &amp;lt; "$tmpdepfile" &amp;gt; "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' &amp;lt; "$tmpdepfile" &amp;gt;&amp;gt; "$depfile"
+   else
+      echo "#dummy" &amp;gt; "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$&amp;lt; at &amp;gt;" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$&amp;lt; at &amp;gt;" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" &amp;amp;&amp;amp; dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$&amp;lt; at &amp;gt;" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' &amp;gt; "$tmpdepfile"
+  rm -f "$depfile"
+  cat &amp;lt; "$tmpdepfile" &amp;gt; "$depfile"
+  tr ' ' '
+' &amp;lt; "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' &amp;gt;&amp;gt; "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$&amp;lt; at &amp;gt;" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no eat=no
+  for arg
+  do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    if test $eat = yes; then
+      eat=no
+      continue
+    fi
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$&amp;lt; at &amp;gt;" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -arch)
+      eat=yes ;;
+    -*|$object)
+      ;;
+    *)
+      set fnord "$&amp;lt; at &amp;gt;" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix=`echo "$object" | sed 's/^.*\././'`
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$&amp;lt; at &amp;gt;"
+  rm -f "$depfile"
+  cat &amp;lt; "$tmpdepfile" &amp;gt; "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' &amp;gt;&amp;gt; "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$&amp;lt; at &amp;gt;" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$&amp;lt; at &amp;gt;" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$&amp;lt; at &amp;gt;" -E |
+    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' &amp;gt; "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" &amp;gt; "$depfile"
+  cat &amp;lt; "$tmpdepfile" &amp;gt;&amp;gt; "$depfile"
+  sed &amp;lt; "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' &amp;gt;&amp;gt; "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$&amp;lt; at &amp;gt;" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+set fnord "$&amp;lt; at &amp;gt;"
+shift
+shift
+;;
+    *)
+set fnord "$&amp;lt; at &amp;gt;" "$arg"
+shift
+shift
+;;
+    esac
+  done
+  "$&amp;lt; at &amp;gt;" -E 2&amp;gt;/dev/null |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u &amp;gt; "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" &amp;gt; "$depfile"
+  sed &amp;lt; "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1 \\:p' &amp;gt;&amp;gt; "$depfile"
+  echo "" &amp;gt;&amp;gt; "$depfile"
+  sed &amp;lt; "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' &amp;gt;&amp;gt; "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvcmsys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+none)
+  exec "$&amp;lt; at &amp;gt;"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1&amp;gt;&amp;amp;2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/autotools/includes/acinclude.m4 b/build/autotools/includes/acinclude.m4
similarity index 86%
rename from autotools/includes/acinclude.m4
rename to build/autotools/includes/acinclude.m4
index 709d258..1856708 100755
--- a/autotools/includes/acinclude.m4
+++ b/build/autotools/includes/acinclude.m4
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3,6 +3,65 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; dnl   macros autoconf uses when building configure from configure.in
 dnl
 dnl
 
+AC_DEFUN([MY_ARG_WITH], [
+  AC_ARG_WITH(m4_translit([[$1]], [_], [-]),
+     [AS_HELP_STRING([--with-m4_translit([$1], [_], [-])],
+                     [use $1 (default is $2)])],
+     [with_[]$1=$withval],
+     [with_[]$1=$2])
+])
+
+AC_DEFUN([MY_ARG_WITH_PATH], [
+  AC_ARG_WITH(m4_translit([[$1]], [_], [-]),
+     [AS_HELP_STRING([--with-m4_translit([$1], [_], [-])=PATH],
+                     [$2])],
+     [with_[]$1_path=$withval],
+     [with_[]$1_path=$3])
+])
+
+AC_DEFUN([MY_ARG_ENABLE], [
+  AC_MSG_CHECKING([whether $2 is enabled])
+  AC_ARG_ENABLE(m4_translit([[$1]], [_], [-]),
+     [AS_HELP_STRING([--enable-m4_translit([$1], [_], [-])],
+                     [enable $2 support])],
+     [
+       enable_[]$1=$enableval
+       AC_MSG_RESULT([$enableval])
+       AC_DEFINE(m4_translit([[USE_$1]], [a-z], [A-Z]), 1, [Define if you want $2 support])
+     ],
+     [
+       # default if not given is DISABLED
+       if test "x$enableval" = "x"; then
+         enableval="no"
+       fi
+       enable_[]$1=$enableval
+       AC_MSG_RESULT([$enableval])
+     ]
+  )
+])
+
+AC_DEFUN([MY_ARG_DISABLE], [
+  AC_MSG_CHECKING([whether $2 is enabled])
+  AC_ARG_ENABLE(m4_translit([[$1]], [_], [-]),
+     [AS_HELP_STRING([--disable-m4_translit([$1], [_], [-])],
+                     [disable $2 support])],
+     [
+       enable_[]$1=$enableval
+       AC_MSG_RESULT([$enableval])
+     ],
+     [
+       # default if not given is ENABLED
+       if test "x$enableval" = "x"; then
+         enableval="yes"
+       fi
+       enable_[]$1=$enableval
+       AC_MSG_RESULT([$enableval])
+       AC_DEFINE(m4_translit([[USE_$1]], [a-z], [A-Z]), 1, [Define if you want $2 support])
+     ]
+  )
+])
+
+
 dnl  EGG_CHECK_CC()
 dnl
 AC_DEFUN([EGG_CHECK_CC], 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -13,7 +72,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; then
 configure: error:
 
   This system does not appear to have a working C compiler.
-  A working C compiler is required to compile Eggdrop.
+  A working C compiler is required to compile Wraith.
 
 EOF
   exit 1
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -29,21 +88,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; dnl  EGG_IPV6_OPTIONS()
 dnl
 AC_DEFUN([EGG_IPV6_OPTIONS], 
 [
-AC_MSG_CHECKING(whether or not you disabled IPv6 support)
-AC_ARG_ENABLE(ipv6, [AS_HELP_STRING([--disable-ipv6], [disable IPv6 support])],
-[ ac_cv_dipv6="yes"
-  AC_MSG_RESULT(yes)
-],
-[ ac_cv_dipv6="no"
-  if test "$egg_cv_ipv6_supported" = "no"; then
-    ac_cv_dipv6="no"
-  fi
-  AC_MSG_RESULT($ac_cv_dipv6)
-])
-
-if test "$ac_cv_dipv6" = "no"; then
-  AC_DEFINE(USE_IPV6, 1, [Define if you want ipv6 support])
-fi
+MY_ARG_DISABLE(ipv6, [IPv6])
 ])
 
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -203,7 +248,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; then
 configure: error:
 
   This system seems to lack a working 'head -1' or 'head -n 1' command.
-  A working 'head -1' (or equivalent) command is required to compile Eggdrop.
+  A working 'head -1' (or equivalent) command is required to compile Wraith.
 
 EOF
   exit 1
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -226,7 +271,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; then
 configure: error:
 
   This system seems to lack a working 'awk' command.
-  A working 'awk' command is required to compile Eggdrop.
+  A working 'awk' command is required to compile Wraith.
 
 EOF
   exit 1
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -246,7 +291,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; then
 configure: error:
 
   This system seems to lack a working 'basename' command.
-  A working 'basename' command is required to compile Eggdrop.
+  A working 'basename' command is required to compile Wraith.
 
 EOF
   exit 1
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -460,16 +505,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; AC_DEFUN([CHECK_SSL],
 dnl Adapted from Ratbox configure.ac
 dnl OpenSSL support
 AC_MSG_CHECKING(for path to OpenSSL)
-AC_ARG_WITH(openssl,
-[AS_HELP_STRING([--with-openssl=DIR],[Path to OpenSSL])],
-[cf_with_openssl=$withval],
-[cf_with_openssl="auto"]
-)
+MY_ARG_WITH_PATH(openssl, [Path to OpenSSL], [auto])
 
 cf_openssl_basedir=""
-if test "$cf_with_openssl" != "auto"; then
+if test "$with_openssl_path" != "auto"; then
   dnl Support for --with-openssl=/some/place
-  cf_openssl_basedir="`echo ${cf_with_openssl} | sed 's/\/$//'`"
+  cf_openssl_basedir="`echo ${with_openssl_path} | sed 's/\/$//'`"
 else
   dnl Do the auto-probe here.  Check some common directory paths.
   for dirs in /usr/local/ssl /usr/pkg /usr/local /usr/local/openssl; do
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -547,6 +588,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; LIBS="$save_LIBS"
 
 AC_SUBST(SSL_INCLUDES)
 AC_SUBST(SSL_LIBS)
+AC_DEFINE_UNQUOTED(EGG_SSL_EXT, 1, [Defines whether or not SSL is supported])dnl
 ])
 
 dnl  EGG_HEADER_STDC()
diff --git a/autotools/includes/depend.m4 b/build/autotools/includes/depend.m4
similarity index 97%
rename from autotools/includes/depend.m4
rename to build/autotools/includes/depend.m4
index b6f52d1..f9762db 100755
--- a/autotools/includes/depend.m4
+++ b/build/autotools/includes/depend.m4
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -57,7 +57,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; for mf in $files; do
       fi
     fi
     echo "include .deps/$base.Po" &amp;gt;&amp;gt; "$dirpart/.deps/includes"
-    echo "_$base.c:" &amp;gt;&amp;gt; "$dirpart/.deps/includes"
   done
 done
 ])
diff --git a/build/autotools/includes/libtcl.m4 b/build/autotools/includes/libtcl.m4
new file mode 100644
index 0000000..12cdbc8
--- /dev/null
+++ b/build/autotools/includes/libtcl.m4
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,593 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+dnl libtcl.m4
+dnl   macros autoconf uses when building configure from configure.in
+dnl   These are taken from Eggdrop
+dnl
+
+dnl EGG_TCL_OPTIONS()
+dnl
+AC_DEFUN([EGG_TCL_OPTIONS],
+[
+  AC_ARG_WITH(tcllib, [AS_HELP_STRING([--with-tcllib=PATH],[full path to Tcl library])], [tcllibname="$withval"])
+  AC_ARG_WITH(tclinc, [AS_HELP_STRING([--with-tclinc=PATH],[full path to Tcl header])],  [tclincname="$withval"])
+
+  MY_ARG_DISABLE([script_tcl], [TCL Script])
+
+  WARN=0
+  # Make sure either both or neither $tcllibname and $tclincname are set
+  if test "x$tcllibname" != x; then
+    if test "x$tclincname" = x; then
+      WARN=1
+      tcllibname=""
+      TCLLIB=""
+      TCLINC=""
+    fi
+  else
+    if test "x$tclincname" != x; then
+      WARN=1
+      tclincname=""
+      TCLLIB=""
+      TCLINC=""
+    fi
+  fi
+
+  if test "$WARN" = 1; then
+    cat &amp;lt;&amp;lt; 'EOF' &amp;gt;&amp;amp;2
+configure: WARNING:
+
+  You must specify both --with-tcllib and --with-tclinc for either to work.
+
+  configure will now attempt to autodetect both the Tcl library and header.
+
+EOF
+  fi
+])
+
+
+dnl EGG_TCL_ENV()
+dnl
+AC_DEFUN([EGG_TCL_ENV],
+[
+  WARN=0
+  # Make sure either both or neither $TCLLIB and $TCLINC are set
+  if test "x$TCLLIB" != x; then
+    if test "x$TCLINC" = x; then
+      WARN=1
+      WVAR1=TCLLIB
+      WVAR2=TCLINC
+      TCLLIB=""
+    fi
+  else
+    if test "x$TCLINC" != x; then
+      WARN=1
+      WVAR1=TCLINC
+      WVAR2=TCLLIB
+      TCLINC=""
+    fi
+  fi
+
+  if test "$WARN" = 1; then
+    cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;amp;2
+configure: WARNING:
+
+  Environment variable $WVAR1 was set, but I did not detect ${WVAR2}.
+  Please set both TCLLIB and TCLINC correctly if you wish to use them.
+
+  configure will now attempt to autodetect both the Tcl library and header.
+
+EOF
+  fi
+])
+
+
+dnl EGG_TCL_WITH_TCLLIB()
+dnl
+AC_DEFUN([EGG_TCL_WITH_TCLLIB],
+[
+  # Look for Tcl library: if $tcllibname is set, check there first
+  if test "x$tcllibname" != x; then
+    if test -f "$tcllibname" &amp;amp;&amp;amp; test -r "$tcllibname"; then
+      TCLLIB=`echo $tcllibname | sed 's%/[[^/]][[^/]]*$%%'`
+      TCLLIBFN=`$BASENAME $tcllibname | cut -c4-`
+      TCLLIBEXT=".`echo $TCLLIBFN | $AWK '{j=split([$]1, i, "."); print i[[j]]}'`"
+      TCLLIBFNS=`$BASENAME $tcllibname $TCLLIBEXT | cut -c4-`
+    else
+      cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;amp;2
+configure: WARNING:
+
+  The file '$tcllibname' given to option --with-tcllib is not valid.
+
+  configure will now attempt to autodetect both the Tcl library and header.
+
+EOF
+      tcllibname=""
+      tclincname=""
+      TCLLIB=""
+      TCLLIBFN=""
+      TCLINC=""
+      TCLINCFN=""
+    fi
+  fi
+])
+
+
+dnl EGG_TCL_WITH_TCLINC()
+dnl
+AC_DEFUN([EGG_TCL_WITH_TCLINC],
+[
+  # Look for Tcl header: if $tclincname is set, check there first
+  if test "x$tclincname" != x; then
+    if test -f "$tclincname" &amp;amp;&amp;amp; test -r "$tclincname"; then
+      TCLINC=`echo $tclincname | sed 's%/[[^/]][[^/]]*$%%'`
+      TCLINCFN=`$BASENAME $tclincname`
+    else
+      cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;amp;2
+configure: WARNING:
+
+  The file '$tclincname' given to option --with-tclinc is not valid.
+
+  configure will now attempt to autodetect both the Tcl library and header.
+
+EOF
+      tcllibname=""
+      tclincname=""
+      TCLLIB=""
+      TCLLIBFN=""
+      TCLINC=""
+      TCLINCFN=""
+    fi
+  fi
+])
+
+
+dnl EGG_TCL_FIND_LIBRARY()
+dnl
+AC_DEFUN([EGG_TCL_FIND_LIBRARY],
+[
+  # Look for Tcl library: if $TCLLIB is set, check there first
+  if test "x$TCLLIBFN" = x &amp;amp;&amp;amp; test "x$TCLLIB" != x; then
+    if test -d "$TCLLIB"; then
+      for tcllibfns in $tcllibnames; do
+        for tcllibext in $tcllibextensions; do
+          if test -r "${TCLLIB}/lib${tcllibfns}${tcllibext}"; then
+            TCLLIBFN="${tcllibfns}${tcllibext}"
+            TCLLIBEXT="$tcllibext"
+            TCLLIBFNS="$tcllibfns"
+            break 2
+          fi
+        done
+      done
+    fi
+
+    if test "x$TCLLIBFN" = x; then
+      cat &amp;lt;&amp;lt; 'EOF' &amp;gt;&amp;amp;2
+configure: WARNING:
+
+  Environment variable TCLLIB was set, but incorrectly.
+  Please set both TCLLIB and TCLINC correctly if you wish to use them.
+
+  configure will now attempt to autodetect both the Tcl library and header.
+
+EOF
+      TCLLIB=""
+      TCLLIBFN=""
+      TCLINC=""
+      TCLINCFN=""
+    fi
+  fi
+])
+
+
+dnl EGG_TCL_FIND_HEADER()
+dnl
+AC_DEFUN([EGG_TCL_FIND_HEADER],
+[
+  # Look for Tcl header: if $TCLINC is set, check there first
+  if test "x$TCLINCFN" = x &amp;amp;&amp;amp; test "x$TCLINC" != x; then
+    if test -d "$TCLINC"; then
+      for tclheaderfn in $tclheadernames; do
+        if test -r "${TCLINC}/${tclheaderfn}"; then
+          TCLINCFN="$tclheaderfn"
+          break
+        fi
+      done
+    fi
+
+    if test "x$TCLINCFN" = x; then
+      cat &amp;lt;&amp;lt; 'EOF' &amp;gt;&amp;amp;2
+configure: WARNING:
+
+  Environment variable TCLINC was set, but incorrectly.
+  Please set both TCLLIB and TCLINC correctly if you wish to use them.
+
+  configure will now attempt to autodetect both the Tcl library and header.
+
+EOF
+      TCLLIB=""
+      TCLLIBFN=""
+      TCLINC=""
+      TCLINCFN=""
+    fi
+  fi
+])
+
+
+dnl EGG_TCL_CHECK_LIBRARY()
+dnl
+AC_DEFUN([EGG_TCL_CHECK_LIBRARY],
+[
+  if test "$enable_script_tcl" = "yes"; then
+    AC_MSG_CHECKING([for Tcl library])
+
+    # Attempt autodetect for $TCLLIBFN if it's not set
+    if test "x$TCLLIBFN" != x; then
+      AC_MSG_RESULT([using ${TCLLIB}/lib${TCLLIBFN}])
+    else
+      for tcllibfns in $tcllibnames; do
+        for tcllibext in $tcllibextensions; do
+          for tcllibpath in $tcllibpaths; do
+            if test -r "${tcllibpath}/lib${tcllibfns}${tcllibext}"; then
+              AC_MSG_RESULT([found ${tcllibpath}/lib${tcllibfns}${tcllibext}])
+              TCLLIB="$tcllibpath"
+              TCLLIBFN="${tcllibfns}${tcllibext}"
+              TCLLIBEXT="$tcllibext"
+              TCLLIBFNS="$tcllibfns"
+              break 3
+            fi
+          done
+        done
+      done
+    fi
+
+    # Show if $TCLLIBFN wasn't found
+    if test "x$TCLLIBFN" = x; then
+      AC_MSG_RESULT([not found])
+    fi
+  fi
+
+  AC_SUBST(TCLLIB)
+  AC_SUBST(TCLLIBFN)
+])
+
+
+dnl EGG_TCL_CHECK_HEADER()
+dnl
+AC_DEFUN([EGG_TCL_CHECK_HEADER],
+[
+  if test "$enable_script_tcl" = "yes"; then
+    AC_MSG_CHECKING([for Tcl header])
+
+    # Attempt autodetect for $TCLINCFN if it's not set
+    if test "x$TCLINCFN" != x; then
+      AC_MSG_RESULT([using ${TCLINC}/${TCLINCFN}])
+    else
+      for tclheaderpath in $tclheaderpaths; do
+        for tclheaderfn in $tclheadernames; do
+          if test -r "${tclheaderpath}/${tclheaderfn}"; then
+            AC_MSG_RESULT([found ${tclheaderpath}/${tclheaderfn}])
+            TCLINC="$tclheaderpath"
+            TCLINCFN="$tclheaderfn"
+            break 2
+          fi
+        done
+      done
+
+      # FreeBSD hack ...
+      if test "x$TCLINCFN" = x; then
+        for tcllibfns in $tcllibnames; do
+          for tclheaderpath in $tclheaderpaths; do
+            for tclheaderfn in $tclheadernames; do
+              if test -r "${tclheaderpath}/${tcllibfns}/${tclheaderfn}"; then
+                AC_MSG_RESULT([found ${tclheaderpath}/${tcllibfns}/${tclheaderfn}])
+                TCLINC="${tclheaderpath}/${tcllibfns}"
+                TCLINCFN="$tclheaderfn"
+                break 3
+              fi
+            done
+          done
+        done
+      fi
+    fi
+
+    TCL_INCLUDES=""
+    if ! test "x$TCLINC" = x; then
+      TCL_INCLUDES="-I$TCLINC"
+    fi
+
+    if test "x$TCLINCFN" = x; then
+      AC_MSG_RESULT([not found])
+    fi
+  fi
+
+  AC_SUBST(TCL_INCLUDES)
+  AC_SUBST(TCLINCFN)
+])
+
+
+dnl EGG_CACHE_UNSET(CACHE-ID)
+dnl
+dnl Unsets a certain cache item. Typically called before using the AC_CACHE_*()
+dnl macros.
+dnl
+AC_DEFUN([EGG_CACHE_UNSET], [unset $1])
+
+
+dnl EGG_TCL_DETECT_CHANGE()
+dnl
+dnl Detect whether the Tcl system has changed since our last configure run.
+dnl Set egg_tcl_changed accordingly.
+dnl
+dnl Tcl related feature and version checks should re-run their checks as soon
+dnl as egg_tcl_changed is set to "yes".
+dnl
+AC_DEFUN([EGG_TCL_DETECT_CHANGE],
+[
+  if test "$enable_script_tcl" = "yes"; then
+    dnl NOTE: autoconf 2.50+ disables config.cache by default.
+    dnl       These checks don't do us much good if cache is disabled.
+    AC_MSG_CHECKING([whether the Tcl system has changed])
+    egg_tcl_changed="yes"
+    egg_tcl_id="${TCLLIB}:${TCLLIBFN}:${TCLINC}:${TCLINCFN}"
+    if test "$egg_tcl_id" != ":::"; then
+      egg_tcl_cached="yes"
+      AC_CACHE_VAL(egg_cv_var_tcl_id, [
+        egg_cv_var_tcl_id="$egg_tcl_id"
+        egg_tcl_cached="no"
+      ])
+      if test "$egg_tcl_cached" = yes; then
+        if test "x$egg_cv_var_tcl_id" = "x$egg_tcl_id"; then
+          egg_tcl_changed="no"
+        else
+          egg_cv_var_tcl_id="$egg_tcl_id"
+        fi
+      fi
+    fi
+
+    if test "$egg_tcl_changed" = yes; then
+      AC_MSG_RESULT([yes])
+    else
+      AC_MSG_RESULT([no])
+    fi
+  fi
+])
+
+
+dnl EGG_TCL_CHECK_VERSION()
+dnl
+AC_DEFUN([EGG_TCL_CHECK_VERSION],
+[
+  if test "$enable_script_tcl" = "yes"; then
+    # Both TCLLIBFN &amp;amp; TCLINCFN must be set, or we bail
+    TCL_FOUND=0
+    if test "x$TCLLIBFN" != x &amp;amp;&amp;amp; test "x$TCLINCFN" != x; then
+      TCL_FOUND=1
+
+      # Check Tcl's version
+      if test "$egg_tcl_changed" = yes; then
+        EGG_CACHE_UNSET(egg_cv_var_tcl_version)
+      fi
+
+      AC_MSG_CHECKING([for Tcl version])
+      AC_CACHE_VAL(egg_cv_var_tcl_version, [
+        egg_cv_var_tcl_version=`grep TCL_VERSION $TCLINC/$TCLINCFN | $HEAD_1 | $AWK '{gsub(/\"/, "", [$]3); print [$]3}'`
+      ])
+
+      if test "x$egg_cv_var_tcl_version" != x; then
+        AC_MSG_RESULT([$egg_cv_var_tcl_version])
+      else
+        AC_MSG_RESULT([not found])
+        TCL_FOUND=0
+      fi
+
+      # Check Tcl's patch level (if available)
+      if test "$egg_tcl_changed" = yes; then
+        EGG_CACHE_UNSET(egg_cv_var_tcl_patch_level)
+      fi
+      AC_MSG_CHECKING([for Tcl patch level])
+      AC_CACHE_VAL(egg_cv_var_tcl_patch_level, [
+        eval "egg_cv_var_tcl_patch_level=`grep TCL_PATCH_LEVEL $TCLINC/$TCLINCFN | $HEAD_1 | $AWK '{gsub(/\"/, "", [$]3); print [$]3}'`"
+      ])
+
+      if test "x$egg_cv_var_tcl_patch_level" != x; then
+        AC_MSG_RESULT([$egg_cv_var_tcl_patch_level])
+      else
+        egg_cv_var_tcl_patch_level="unknown"
+        AC_MSG_RESULT([unknown])
+      fi
+    fi
+
+    # Check if we found Tcl's version
+    if test "$TCL_FOUND" = 0; then
+      cat &amp;lt;&amp;lt; 'EOF' &amp;gt;&amp;amp;2
+configure: error:
+
+  Tcl cannot be found on this system.
+
+  Tcl is not required. Wraith will be compiled without TCL support. If you
+  already have Tcl installed on this system, please specify the path by
+  rerunning ./configure using the --with-tcllib='/path/to/libtcl.so' and
+  --with-tclinc='/path/to/tcl.h' options.
+
+EOF
+    enable_script_tcl="no"
+    else
+      AC_DEFINE(HAVE_LIBTCL, 1, [Define if you have support for libtcl])
+    fi
+  fi
+])
+
+
+dnl EGG_TCL_CHECK_PRE70()
+dnl
+AC_DEFUN([EGG_TCL_CHECK_PRE70],
+[
+  if test "$enable_script_tcl" = "yes"; then
+    # Is this version of Tcl too old for us to use ?
+    TCL_VER_PRE70=`echo $egg_cv_var_tcl_version | $AWK '{split([$]1, i, "."); if (i[[1]] &amp;lt; 7) print "yes"; else print "no"}'`
+    if test "$TCL_VER_PRE70" = yes; then
+      cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;amp;2
+configure: error:
+
+  Your Tcl version is much too old for Wraith to use. You should
+  download and compile a more recent version. The most reliable
+  current version is $tclrecommendver and can be downloaded from
+  ${tclrecommendsite}.
+
+  See doc/COMPILE-GUIDE's 'Tcl Detection and Installation' section
+  for more information.
+
+EOF
+      exit 1
+    fi
+  fi
+])
+
+
+dnl EGG_TCL_TESTLIBS()
+dnl
+AC_DEFUN([EGG_TCL_TESTLIBS],
+[
+  # Set variables for Tcl library tests
+  TCL_TEST_LIB="$TCLLIBFNS"
+  TCL_TEST_OTHERLIBS="-L$TCLLIB $EGG_MATH_LIB"
+  if test "x$ac_cv_lib_pthread" != x; then
+    TCL_TEST_OTHERLIBS="$TCL_TEST_OTHERLIBS $ac_cv_lib_pthread"
+  fi
+])
+
+
+dnl EGG_TCL_CHECK_FREE()
+dnl
+AC_DEFUN([EGG_TCL_CHECK_FREE],
+[
+  if test "$enable_script_tcl" = "yes"; then
+    if test "$egg_tcl_changed" = yes; then
+      EGG_CACHE_UNSET(egg_cv_var_tcl_free)
+    fi
+
+    # Check for Tcl_Free()
+    AC_CHECK_LIB($TCL_TEST_LIB, Tcl_Free, [egg_cv_var_tcl_free="yes"], [egg_cv_var_tcl_free="no"], $TCL_TEST_OTHERLIBS)
+
+    if test "$egg_cv_var_tcl_free" = yes; then
+      AC_DEFINE(HAVE_TCL_FREE, 1, [Define for Tcl that has Tcl_Free() (7.5p1 and later).])
+    fi
+  fi
+])
+
+
+dnl EGG_TCL_CHECK_GETCURRENTTHREAD
+dnl
+AC_DEFUN([EGG_TCL_CHECK_GETCURRENTTHREAD],
+[
+  if test "$enable_script_tcl" = "yes"; then
+    if test "$egg_tcl_changed" = yes; then
+      EGG_CACHE_UNSET(egg_cv_var_tcl_getcurrentthread)
+    fi
+
+    # Check for Tcl_GetCurrentThread()
+    AC_CHECK_LIB($TCL_TEST_LIB, Tcl_GetCurrentThread, [egg_cv_var_tcl_getcurrentthread="yes"], [egg_cv_var_tcl_getcurrentthread="no"], $TCL_TEST_OTHERLIBS)
+    if test "$egg_cv_var_tcl_getcurrentthread" = yes; then
+      AC_DEFINE(HAVE_TCL_GETCURRENTTHREAD, 1, [Define for Tcl that has Tcl_GetCurrentThread() (8.1a2 and later).])
+
+      # Add pthread library to $LIBS if we need it for threaded Tcl
+      if test "x$ac_cv_lib_pthread" != x; then
+        EGG_APPEND_VAR(LIBS, $ac_cv_lib_pthread)
+      fi
+    fi
+  fi
+])
+
+
+dnl EGG_TCL_CHECK_GETTHREADDATA
+dnl
+AC_DEFUN([EGG_TCL_CHECK_GETTHREADDATA],
+[
+  if test "$enable_script_tcl" = "yes"; then
+    if test "$egg_tcl_changed" = yes; then
+      EGG_CACHE_UNSET(egg_cv_var_tcl_getthreaddata)
+    fi
+
+    # Check for Tcl_GetThreadData()
+    AC_CHECK_LIB($TCL_TEST_LIB, Tcl_GetThreadData, [egg_cv_var_tcl_getthreaddata="yes"], [egg_cv_var_tcl_getthreaddata="no"], $TCL_TEST_OTHERLIBS)
+    if test "$egg_cv_var_tcl_getthreaddata" = yes; then
+      AC_DEFINE(HAVE_TCL_GETTHREADDATA, 1, [Define for Tcl that has Tcl_GetThreadData() (8.1a2 and later).])
+    fi
+  fi
+])
+
+
+dnl EGG_TCL_CHECK_SETNOTIFIER
+dnl
+AC_DEFUN([EGG_TCL_CHECK_SETNOTIFIER],
+[
+  if test "$enable_script_tcl" = "yes"; then
+    if test "$egg_tcl_changed" = yes; then
+      EGG_CACHE_UNSET(egg_cv_var_tcl_setnotifier)
+    fi
+
+    # Check for Tcl_SetNotifier()
+    AC_CHECK_LIB($TCL_TEST_LIB, Tcl_SetNotifier, [egg_cv_var_tcl_setnotifier="yes"], [egg_cv_var_tcl_setnotifier="no"], $TCL_TEST_OTHERLIBS)
+    if test "$egg_cv_var_tcl_setnotifier" = yes; then
+      AC_DEFINE(HAVE_TCL_SETNOTIFIER, 1, [Define for Tcl that has Tcl_SetNotifier() (8.2b1 and later).])
+    fi
+  fi
+])
+
+
+dnl EGG_TCL_LIB_REQS()
+dnl
+AC_DEFUN([EGG_TCL_LIB_REQS],
+[
+  if test "$enable_script_tcl" = "yes"; then
+    if test "$EGG_CYGWIN" = yes; then
+      TCL_REQS="${TCLLIB}/lib${TCLLIBFN}"
+      TCL_LIBS="-L$TCLLIB -l$TCLLIBFNS $EGG_MATH_LIB"
+    else
+      if test "$TCLLIBEXT" != ".a"; then
+        TCL_REQS="${TCLLIB}/lib${TCLLIBFN}"
+        TCL_LIBS="-L$TCLLIB -l$TCLLIBFNS $EGG_MATH_LIB"
+      else
+        # Set default make as static for unshared Tcl library
+        if test "$DEFAULT_MAKE" != static; then
+          cat &amp;lt;&amp;lt; 'EOF' &amp;gt;&amp;amp;2
+configure: WARNING:
+
+  Your Tcl library is not a shared lib.
+  configure will now set default make type to static.
+
+EOF
+          DEFAULT_MAKE="static"
+          AC_SUBST(DEFAULT_MAKE)
+        fi
+
+        # Are we using a pre 7.4 Tcl version ?
+        TCL_VER_PRE74=`echo $egg_cv_var_tcl_version | $AWK '{split([$]1, i, "."); if (((i[[1]] == 7) &amp;amp;&amp;amp; (i[[2]] &amp;lt; 4)) || (i[[1]] &amp;lt; 7)) print "yes"; else print "no"}'`
+        if test "$TCL_VER_PRE74" = no; then
+
+          # Was the --with-tcllib option given ?
+          if test "x$tcllibname" != x; then
+            TCL_REQS="${TCLLIB}/lib${TCLLIBFN}"
+            TCL_LIBS="${TCLLIB}/lib${TCLLIBFN} $EGG_MATH_LIB"
+          else
+            TCL_REQS="${TCLLIB}/lib${TCLLIBFN}"
+            TCL_LIBS="-L$TCLLIB -l$TCLLIBFNS $EGG_MATH_LIB"
+          fi
+        else
+          cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;amp;2
+configure: WARNING:
+
+  Your Tcl version ($egg_cv_var_tcl_version) is older than 7.4.
+  There are known problems, but we will attempt to work around them.
+
+EOF
+          TCL_REQS="libtcle.a"
+          TCL_LIBS="-L`pwd` -ltcle $EGG_MATH_LIB"
+        fi
+      fi
+    fi
+  fi
+
+  AC_SUBST(TCL_REQS)
+  AC_SUBST(TCL_LIBS)
+])
+
+
diff --git a/autotools/includes/stat.m4 b/build/autotools/includes/stat.m4
similarity index 100%
rename from autotools/includes/stat.m4
rename to build/autotools/includes/stat.m4
diff --git a/autotools/includes/wrap.m4 b/build/autotools/includes/wrap.m4
similarity index 100%
rename from autotools/includes/wrap.m4
rename to build/autotools/includes/wrap.m4
diff --git a/build/cc1plus b/build/cc1plus
new file mode 100755
index 0000000..1f27a11
--- /dev/null
+++ b/build/cc1plus
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,58 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+#! /bin/sh
+
+# This file intercepts the pre-processor and runs 'stringfix' on the source file before it is processed.
+# This avoids the need for the old _*.c temp files.
+
+# Only capture pre-processing
+if [ $1 != "-E" -o -z "$STRINGFIX" -o ! -f "$STRINGFIX" ]; then
+  exec $(${COLLECT_GCC} --print-prog-name=cc1plus) "$&amp;lt; at &amp;gt;"
+fi
+
+
+# Check for '-MD' as this may be the 'depcomp' call
+depcomp=0
+for arg; do
+  case "$arg" in
+    -MD)
+      depcomp=1
+      ;;
+    *)
+      ;;
+  esac
+done
+
+# Only continue if running in depcomp (avoiding a 2nd pass for -dD/-g3)
+if [ $depcomp -eq 0 ]; then
+  exec $(${COLLECT_GCC} --print-prog-name=cc1plus) "$&amp;lt; at &amp;gt;"
+fi
+
+### Is this a pipe or not? ###
+
+# Determine the last argument
+for i
+do
+  third_last="$third_last $second_last"
+  second_last=$last
+  last=$i
+done
+
+# If the last param is *.ii, there's no pipe
+case $last in
+  *.ii)
+    piping=0
+    ;;
+  *)
+    piping=1
+    ;;
+esac
+
+if [ $piping -eq 1 ]; then
+  exec $(${COLLECT_GCC} --print-prog-name=cc1plus) "$&amp;lt; at &amp;gt;" | $STRINGFIX
+else
+  gcc_status=$($(${COLLECT_GCC} --print-prog-name=cc1plus) "$&amp;lt; at &amp;gt;")
+
+  TEMPFILE=`(umask 077 &amp;amp;&amp;amp; mktemp -t "ccXXXXXX") 2&amp;gt;/dev/null`
+  $STRINGFIX &amp;lt; $last &amp;gt; $TEMPFILE
+  mv -f $TEMPFILE $last
+  exit $gcc_status
+fi
diff --git a/configure b/configure
index e87bfb7..aa76aac 100755
--- a/configure
+++ b/configure
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -12,7 +12,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 # This configure script is free software; the Free Software Foundation
 # gives unlimited permission to copy, distribute and modify it.
 #
-# Copyright (c) 2003 - 2010 Bryan Drewery
+# Copyright (c) Bryan Drewery
 ## -------------------- ##
 ## M4sh Initialization. ##
 ## -------------------- ##
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -610,6 +610,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; MOD_UPDIR
 NUMVER
 VERSION
 LIBOBJS
+TCL_LIBS
+TCL_REQS
+DEFAULT_MAKE
+TCLINCFN
+TCL_INCLUDES
+TCLLIBFN
+TCLLIB
 SSL_LIBS
 SSL_INCLUDES
 MAKEJOBS
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -626,6 +633,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; OBJCOPY
 BASENAME
 AWK
 HEAD_1
+SED
 SET_MAKE
 GCC4DEB
 GCC3DEB
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -685,6 +693,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; ac_user_opts='
 enable_option_checking
 enable_ipv6
 with_openssl
+with_tcllib
+with_tclinc
+enable_script_tcl
 '
       ac_precious_vars='build_alias
 host_alias
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -705,7 +716,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; ac_unrecognized_opts=
 ac_unrecognized_sep=
 # The variables have the same names as the options, with
 # dashes changed to underlines.
-cache_file=./config.cache
+cache_file=/dev/null
 exec_prefix=NONE
 no_create=
 no_recursion=
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1306,11 +1317,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; Optional Features:
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   --disable-ipv6          disable IPv6 support
+  --disable-script-tcl    disable TCL Script support
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
-  --with-openssl=DIR      Path to OpenSSL
+  --with-openssl=PATH     Path to OpenSSL
+  --with-tcllib=PATH      full path to Tcl library
+  --with-tclinc=PATH      full path to Tcl header
 
 Some influential environment variables:
   CXX         C++ compiler command
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1395,7 +1409,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; Copyright (C) 2010 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 
-Copyright (c) 2003 - 2010 Bryan Drewery
+Copyright (c) Bryan Drewery
 _ACEOF
   exit
 fi
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1500,8 +1514,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
   # Is the header compilable?
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" &amp;gt;&amp;amp;5
 $as_echo_n "checking $2 usability... " &amp;gt;&amp;amp;6; }
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 $4
 #include &amp;lt;$2&amp;gt;
 _ACEOF
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1517,8 +1531,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo "$ac_header_compiler" &amp;gt;&amp;amp;6; }
 # Is the header present?
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" &amp;gt;&amp;amp;5
 $as_echo_n "checking $2 presence... " &amp;gt;&amp;amp;6; }
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;$2&amp;gt;
 _ACEOF
 if ac_fn_cxx_try_cpp "$LINENO"; then :
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1620,8 +1634,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking for $2... " &amp;gt;&amp;amp;6; }
 if eval \${$3+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 $4
 #include &amp;lt;$2&amp;gt;
 _ACEOF
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1698,8 +1712,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if eval \${$3+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
   eval "$3=no"
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 $4
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1711,8 +1725,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if (sizeof ($2))
 }
 _ACEOF
 if ac_fn_cxx_try_compile "$LINENO"; then :
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 $4
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1739,23 +1753,31 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo "$ac_res" &amp;gt;&amp;amp;6; }
 
 } # ac_fn_cxx_check_type
 
-# ac_fn_cxx_compute_int LINENO EXPR VAR INCLUDES
-# ----------------------------------------------
-# Tries to find the compile-time value of EXPR in a program that includes
-# INCLUDES, setting VAR accordingly. Returns whether the value could be
-# computed
-ac_fn_cxx_compute_int ()
+# ac_fn_c_find_intX_t LINENO BITS VAR
+# -----------------------------------
+# Finds a signed integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_intX_t ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if test "$cross_compiling" = yes; then
-    # Depending upon the size, compute the lo and hi bounds.
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
-$4
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" &amp;gt;&amp;amp;5
+$as_echo_n "checking for int$2_t... " &amp;gt;&amp;amp;6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
+else
+  eval "$3=no"
+     # Order is important - never check a type that is potentially smaller
+     # than half of the expected target width.
+     for ac_type in int$2_t 'int' 'long int' \
+ 'long long int' 'short int' 'signed char'; do
+       cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
+$ac_includes_default
+     enum { N = $2 / 2 - 1 };
 int
 main ()
 {
-static int test_array [1 - 2 * !(($2) &amp;gt;= 0)];
+static int test_array [1 - 2 * !(0 &amp;lt; ($ac_type) ((((($ac_type) 1 &amp;lt;&amp;lt; N) &amp;lt;&amp;lt; N) - 1) * 2 + 1))];
 test_array [0] = 0
 
   ;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1763,15 +1785,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; test_array [0] = 0
 }
 _ACEOF
 if ac_fn_cxx_try_compile "$LINENO"; then :
-  ac_lo=0 ac_mid=0
-  while :; do
-    cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
-$4
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
+$ac_includes_default
+        enum { N = $2 / 2 - 1 };
 int
 main ()
 {
-static int test_array [1 - 2 * !(($2) &amp;lt;= $ac_mid)];
+static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 &amp;lt;&amp;lt; N) &amp;lt;&amp;lt; N) - 1) * 2 + 1)
+ &amp;lt; ($ac_type) ((((($ac_type) 1 &amp;lt;&amp;lt; N) &amp;lt;&amp;lt; N) - 1) * 2 + 2))];
 test_array [0] = 0
 
   ;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1779,75 +1801,56 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; test_array [0] = 0
 }
 _ACEOF
 if ac_fn_cxx_try_compile "$LINENO"; then :
-  ac_hi=$ac_mid; break
+
 else
-  as_fn_arith $ac_mid + 1 &amp;amp;&amp;amp; ac_lo=$as_val
-if test $ac_lo -le $ac_mid; then
-  ac_lo= ac_hi=
-  break
+  case $ac_type in #(
+  int$2_t) :
+    eval "$3=yes" ;; #(
+  *) :
+    eval "$3=\$ac_type" ;;
+esac
 fi
-as_fn_arith 2 '*' $ac_mid + 1 &amp;amp;&amp;amp; ac_mid=$as_val
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  done
-else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) &amp;lt; 0)];
-test_array [0] = 0
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-  ac_hi=-1 ac_mid=-1
-  while :; do
-    cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) &amp;gt;= $ac_mid)];
-test_array [0] = 0
+       if eval test \"x\$"$3"\" = x"no"; then :
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-  ac_lo=$ac_mid; break
 else
-  as_fn_arith '(' $ac_mid ')' - 1 &amp;amp;&amp;amp; ac_hi=$as_val
-if test $ac_mid -le $ac_hi; then
-  ac_lo= ac_hi=
   break
 fi
-as_fn_arith 2 '*' $ac_mid &amp;amp;&amp;amp; ac_mid=$as_val
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
   done
-else
-  ac_lo= ac_hi=
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-# Binary search between lo and hi bounds.
-while test "x$ac_lo" != "x$ac_hi"; do
-  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo &amp;amp;&amp;amp; ac_mid=$as_val
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
-$4
+eval ac_res=\$$3
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" &amp;gt;&amp;amp;5
+$as_echo "$ac_res" &amp;gt;&amp;amp;6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_find_intX_t
+
+# ac_fn_c_find_uintX_t LINENO BITS VAR
+# ------------------------------------
+# Finds an unsigned integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_uintX_t ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" &amp;gt;&amp;amp;5
+$as_echo_n "checking for uint$2_t... " &amp;gt;&amp;amp;6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
+else
+  eval "$3=no"
+     # Order is important - never check a type that is potentially smaller
+     # than half of the expected target width.
+     for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \
+ 'unsigned long long int' 'unsigned short int' 'unsigned char'; do
+       cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
+$ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(($2) &amp;lt;= $ac_mid)];
+static int test_array [1 - 2 * !((($ac_type) -1 &amp;gt;&amp;gt; ($2 / 2 - 1)) &amp;gt;&amp;gt; ($2 / 2 - 1) == 3)];
 test_array [0] = 0
 
   ;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1855,67 +1858,27 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; test_array [0] = 0
 }
 _ACEOF
 if ac_fn_cxx_try_compile "$LINENO"; then :
-  ac_hi=$ac_mid
-else
-  as_fn_arith '(' $ac_mid ')' + 1 &amp;amp;&amp;amp; ac_lo=$as_val
+  case $ac_type in #(
+  uint$2_t) :
+    eval "$3=yes" ;; #(
+  *) :
+    eval "$3=\$ac_type" ;;
+esac
 fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-case $ac_lo in #((
-?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
-'') ac_retval=1 ;;
-esac
-  else
-    cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-static long int longval () { return $2; }
-static unsigned long int ulongval () { return $2; }
-#include &amp;lt;stdio.h&amp;gt;
-#include &amp;lt;stdlib.h&amp;gt;
-int
-main ()
-{
-
-  FILE *f = fopen ("conftest.val", "w");
-  if (! f)
-    return 1;
-  if (($2) &amp;lt; 0)
-    {
-      long int i = longval ();
-      if (i != ($2))
-return 1;
-      fprintf (f, "%ld", i);
-    }
-  else
-    {
-      unsigned long int i = ulongval ();
-      if (i != ($2))
-return 1;
-      fprintf (f, "%lu", i);
-    }
-  /* Do not output a trailing newline, as this causes \r\n confusion
-     on some platforms.  */
-  return ferror (f) || fclose (f) != 0;
+       if eval test \"x\$"$3"\" = x"no"; then :
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_run "$LINENO"; then :
-  echo &amp;gt;&amp;gt;conftest.val; read $3 &amp;lt;conftest.val; ac_retval=0
 else
-  ac_retval=1
+  break
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-rm -f conftest.val
-
+     done
   fi
+eval ac_res=\$$3
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" &amp;gt;&amp;amp;5
+$as_echo "$ac_res" &amp;gt;&amp;amp;6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
 
-} # ac_fn_cxx_compute_int
+} # ac_fn_c_find_uintX_t
 
 # ac_fn_cxx_check_member LINENO AGGR MEMBER VAR INCLUDES
 # ------------------------------------------------------
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1929,8 +1892,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking for $2.$3... " &amp;gt;&amp;amp;6; }
 if eval \${$4+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 $5
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1945,8 +1908,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; _ACEOF
 if ac_fn_cxx_try_compile "$LINENO"; then :
   eval "$4=yes"
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 $5
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1988,8 +1951,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking whether $as_decl_name is declared... " &amp;gt;&amp;amp;6; }
 if eval \${$3+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 $4
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2031,8 +1994,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking for $2... " &amp;gt;&amp;amp;6; }
 if eval \${$3+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 /* Define $2 to an innocuous variant, in case &amp;lt;limits.h&amp;gt; declares $2.
    For example, HP-UX 11i &amp;lt;limits.h&amp;gt; declares gettimeofday.  */
 #define $2 innocuous_$2
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2086,7 +2049,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo "$ac_res" &amp;gt;&amp;amp;6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_cxx_check_func
-cat &amp;gt;config.log &amp;lt;&amp;lt;_ACEOF
+cat &amp;gt;build/config.log &amp;lt;&amp;lt;_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2096,7 +2059,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; generated by GNU Autoconf 2.68.  Invocation command line was
   $ $0 $&amp;lt; at &amp;gt;
 
 _ACEOF
-exec 5&amp;gt;&amp;gt;config.log
+exec 5&amp;gt;&amp;gt;build/config.log
 {
 cat &amp;lt;&amp;lt;_ASUNAME
 ## --------- ##
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2192,12 +2155,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; done
 { ac_configure_args1=; unset ac_configure_args1;}
 
 # When interrupted or exit'd, cleanup temporary files, and complete
-# config.log.  We remove comments because anyway the quotes in there
+# build/config.log.  We remove comments because anyway the quotes in there
 # would cause problems or look ugly.
 # WARNING: Use '\'' to represent an apostrophe within the trap.
 # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
 trap 'exit_status=$?
-  # Save into config.log some information that might help in debugging.
+  # Save into build/config.log some information that might help in debugging.
   {
     echo
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2267,12 +2230,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" &amp;gt;&amp;amp;2;} ;;
       echo
     fi
 
-    if test -s confdefs.h; then
+    if test -s build/confdefs.h; then
       $as_echo "## ----------- ##
-## confdefs.h. ##
+## build/confdefs.h. ##
 ## ----------- ##"
       echo
-      cat confdefs.h
+      cat build/confdefs.h
       echo
     fi
     test "$ac_signal" != 0 &amp;amp;&amp;amp;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2288,34 +2251,34 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; for ac_signal in 1 2 13 15; do
 done
 ac_signal=0
 
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -f -r conftest* confdefs.h
+# build/confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* build/confdefs.h
 
-$as_echo "/* confdefs.h */" &amp;gt; confdefs.h
+$as_echo "/* build/confdefs.h */" &amp;gt; build/confdefs.h
 
 # Predefined preprocessor variables.
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define PACKAGE_NAME "$PACKAGE_NAME"
 _ACEOF
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define PACKAGE_TARNAME "$PACKAGE_TARNAME"
 _ACEOF
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define PACKAGE_VERSION "$PACKAGE_VERSION"
 _ACEOF
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define PACKAGE_STRING "$PACKAGE_STRING"
 _ACEOF
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
 _ACEOF
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define PACKAGE_URL "$PACKAGE_URL"
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2349,7 +2312,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo "$as_me: loading site script $ac_site_file" &amp;gt;&amp;amp;6;}
       || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" &amp;gt;&amp;amp;5
 $as_echo "$as_me: error: in \`$ac_pwd':" &amp;gt;&amp;amp;2;}
 as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5; }
+See \`build/config.log' for more details" "$LINENO" 5; }
   fi
 done
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2413,7 +2376,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo "$as_me:   former value:  \`$ac_old_val'" &amp;gt;&amp;amp;2;}
 $as_echo "$as_me:   current value: \`$ac_new_val'" &amp;gt;&amp;amp;2;}
       fi;;
   esac
-  # Pass precious variables to config.status.
+  # Pass precious variables to build/config.status.
   if test "$ac_new_set" = set; then
     case $ac_new_val in
     *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2444,7 +2407,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
-ac_config_headers="$ac_config_headers config.h"
+ac_config_headers="$ac_config_headers src/config.h"
 
 
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2496,7 +2459,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if test -z "$CXX"; then
     CXX=$CCC
   else
     if test -n "$ac_tool_prefix"; then
-  for ac_prog in g++45 g++-4.5 g++-4.4 g++-4.4.1 g++-4.4.2 g++-4.4.0 g++44 g++4 g++-3.3 g++33 g++-3 g++3 g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+  for ac_prog in g++47 g++-4.7 g++46 g++-4.6 g++45 g++-4.5 g++-4.4 g++-4.4.1 g++-4.4.2 g++-4.4.0 g++44 g++4 eg++ g++-3.3 g++33 g++-3 g++3 g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2540,7 +2503,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 fi
 if test -z "$CXX"; then
   ac_ct_CXX=$CXX
-  for ac_prog in g++45 g++-4.5 g++-4.4 g++-4.4.1 g++-4.4.2 g++-4.4.0 g++44 g++4 g++-3.3 g++33 g++-3 g++3 g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+  for ac_prog in g++47 g++-4.7 g++46 g++-4.6 g++45 g++-4.5 g++-4.4 g++-4.4.1 g++-4.4.2 g++-4.4.0 g++44 g++4 eg++ g++-3.3 g++33 g++-3 g++3 g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2622,8 +2585,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo "$ac_try_echo"; } &amp;gt;&amp;amp;5
   test $ac_status = 0; }
 done
 
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2710,7 +2673,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; sed 's/^/| /' conftest.$ac_ext &amp;gt;&amp;amp;5
 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" &amp;gt;&amp;amp;5
 $as_echo "$as_me: error: in \`$ac_pwd':" &amp;gt;&amp;amp;2;}
 as_fn_error 77 "C++ compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5; }
+See \`build/config.log' for more details" "$LINENO" 5; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" &amp;gt;&amp;amp;5
 $as_echo "yes" &amp;gt;&amp;amp;6; }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2753,7 +2716,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" &amp;gt;&amp;amp;5
 $as_echo "$as_me: error: in \`$ac_pwd':" &amp;gt;&amp;amp;2;}
 as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5; }
+See \`build/config.log' for more details" "$LINENO" 5; }
 fi
 rm -f conftest conftest$ac_cv_exeext
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" &amp;gt;&amp;amp;5
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2762,8 +2725,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo "$ac_cv_exeext" &amp;gt;&amp;amp;6; }
 rm -f conftest.$ac_ext
 EXEEXT=$ac_cv_exeext
 ac_exeext=$EXEEXT
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;stdio.h&amp;gt;
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2812,7 +2775,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo "$ac_try_echo"; } &amp;gt;&amp;amp;5
 $as_echo "$as_me: error: in \`$ac_pwd':" &amp;gt;&amp;amp;2;}
 as_fn_error $? "cannot run C++ compiled programs.
 If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5; }
+See \`build/config.log' for more details" "$LINENO" 5; }
     fi
   fi
 fi
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2826,8 +2789,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking for suffix of object files... " &amp;gt;&amp;amp;6; }
 if ${ac_cv_objext+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2864,7 +2827,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; sed 's/^/| /' conftest.$ac_ext &amp;gt;&amp;amp;5
 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" &amp;gt;&amp;amp;5
 $as_echo "$as_me: error: in \`$ac_pwd':" &amp;gt;&amp;amp;2;}
 as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5; }
+See \`build/config.log' for more details" "$LINENO" 5; }
 fi
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2877,8 +2840,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking whether we are using the GNU C++ compiler... " &amp;gt;&amp;amp;6; }
 if ${ac_cv_cxx_compiler_gnu+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2918,8 +2881,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
    ac_cxx_werror_flag=yes
    ac_cv_prog_cxx_g=no
    CXXFLAGS="-g"
-   cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+   cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2933,8 +2896,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if ac_fn_cxx_try_compile "$LINENO"; then :
   ac_cv_prog_cxx_g=yes
 else
   CXXFLAGS=""
-      cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+      cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2949,8 +2912,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if ac_fn_cxx_try_compile "$LINENO"; then :
 else
   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
  CXXFLAGS="-g"
- cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+ cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3000,7 +2963,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; then
 configure: error:
 
   This system does not appear to have a working C compiler.
-  A working C compiler is required to compile Eggdrop.
+  A working C compiler is required to compile Wraith.
 
 EOF
   exit 1
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3037,8 +3000,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do
   # &amp;lt;limits.h&amp;gt; exists even on freestanding compilers.
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #ifdef __STDC__
 # include &amp;lt;limits.h&amp;gt;
 #else
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3056,8 +3019,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; rm -f conftest.err conftest.i conftest.$ac_ext
 
   # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;ac_nonexistent.h&amp;gt;
 _ACEOF
 if ac_fn_cxx_try_cpp "$LINENO"; then :
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3096,8 +3059,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do
   # &amp;lt;limits.h&amp;gt; exists even on freestanding compilers.
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #ifdef __STDC__
 # include &amp;lt;limits.h&amp;gt;
 #else
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3115,8 +3078,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; rm -f conftest.err conftest.i conftest.$ac_ext
 
   # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;ac_nonexistent.h&amp;gt;
 _ACEOF
 if ac_fn_cxx_try_cpp "$LINENO"; then :
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3138,7 +3101,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" &amp;gt;&amp;amp;5
 $as_echo "$as_me: error: in \`$ac_pwd':" &amp;gt;&amp;amp;2;}
 as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
+See \`build/config.log' for more details" "$LINENO" 5; }
 fi
 
 ac_ext=cpp
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3283,8 +3246,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking for ANSI C header files... " &amp;gt;&amp;amp;6; }
 if ${ac_cv_header_stdc+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;stdlib.h&amp;gt;
 #include &amp;lt;stdarg.h&amp;gt;
 #include &amp;lt;string.h&amp;gt;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3307,8 +3270,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;string.h&amp;gt;
 
 _ACEOF
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3324,8 +3287,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;stdlib.h&amp;gt;
 
 _ACEOF
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3344,8 +3307,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if test $ac_cv_header_stdc = yes; then
   if test "$cross_compiling" = yes; then :
   :
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;ctype.h&amp;gt;
 #include &amp;lt;stdlib.h&amp;gt;
 #if ((' ' &amp;amp; 0x0FF) == 0x020)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3386,7 +3349,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 $as_echo "$ac_cv_header_stdc" &amp;gt;&amp;amp;6; }
 if test $ac_cv_header_stdc = yes; then
 
-$as_echo "#define STDC_HEADERS 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define STDC_HEADERS 1" &amp;gt;&amp;gt;build/confdefs.h
 
 fi
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3398,7 +3361,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do :
 ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
 "
 if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3418,13 +3381,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 
   if test "$MINIX" = yes; then
 
-$as_echo "#define _POSIX_SOURCE 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define _POSIX_SOURCE 1" &amp;gt;&amp;gt;build/confdefs.h
 
 
-$as_echo "#define _POSIX_1_SOURCE 2" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define _POSIX_1_SOURCE 2" &amp;gt;&amp;gt;build/confdefs.h
 
 
-$as_echo "#define _MINIX 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define _MINIX 1" &amp;gt;&amp;gt;build/confdefs.h
 
   fi
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3434,8 +3397,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking whether it is safe to define __EXTENSIONS__... " &amp;gt;&amp;amp;6; }
 if ${ac_cv_safe_to_define___extensions__+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 #  define __EXTENSIONS__ 1
   $ac_includes_default
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3457,15 +3420,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" &amp;gt;&amp;amp;5
 $as_echo "$ac_cv_safe_to_define___extensions__" &amp;gt;&amp;amp;6; }
   test $ac_cv_safe_to_define___extensions__ = yes &amp;amp;&amp;amp;
-    $as_echo "#define __EXTENSIONS__ 1" &amp;gt;&amp;gt;confdefs.h
+    $as_echo "#define __EXTENSIONS__ 1" &amp;gt;&amp;gt;build/confdefs.h
 
-  $as_echo "#define _ALL_SOURCE 1" &amp;gt;&amp;gt;confdefs.h
+  $as_echo "#define _ALL_SOURCE 1" &amp;gt;&amp;gt;build/confdefs.h
 
-  $as_echo "#define _GNU_SOURCE 1" &amp;gt;&amp;gt;confdefs.h
+  $as_echo "#define _GNU_SOURCE 1" &amp;gt;&amp;gt;build/confdefs.h
 
-  $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" &amp;gt;&amp;gt;confdefs.h
+  $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" &amp;gt;&amp;gt;build/confdefs.h
 
-  $as_echo "#define _TANDEM_SOURCE 1" &amp;gt;&amp;gt;confdefs.h
+  $as_echo "#define _TANDEM_SOURCE 1" &amp;gt;&amp;gt;build/confdefs.h
 
 
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3475,8 +3438,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if ${ac_cv_search_strerror+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
   ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3535,7 +3498,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; cat &amp;gt;confcache &amp;lt;&amp;lt;\_ACEOF
 # It is not useful on other systems.  If it contains results you don't
 # want to keep, you may remove or edit it.
 #
-# config.status only pays attention to the cache file if you give it
+# build/config.status only pays attention to the cache file if you give it
 # the --recheck option to rerun configure.
 #
 # `ac_cv_env_foo' variables (set or unset) will be overridden when
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3625,8 +3588,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
 
       ac_old_CXXFLAGS="$CXXFLAGS"
       CXXFLAGS="$CXXFLAGS -Wall"
-       cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+       cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
          int main ()
          {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3665,8 +3628,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
 
         ac_old_CXX="$CXX"
         CXX="$CXX -pipe"
-        cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+        cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
           int main ()
           {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3718,7 +3681,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; cat &amp;gt;confcache &amp;lt;&amp;lt;\_ACEOF
 # It is not useful on other systems.  If it contains results you don't
 # want to keep, you may remove or edit it.
 #
-# config.status only pays attention to the cache file if you give it
+# build/config.status only pays attention to the cache file if you give it
 # the --recheck option to rerun configure.
 #
 # `ac_cv_env_foo' variables (set or unset) will be overridden when
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3829,6 +3792,75 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo "no" &amp;gt;&amp;amp;6; }
   SET_MAKE="MAKE=${MAKE-make}"
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" &amp;gt;&amp;amp;5
+$as_echo_n "checking for a sed that does not truncate output... " &amp;gt;&amp;amp;6; }
+if ${ac_cv_path_SED+:} false; then :
+  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
+else
+            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+     for ac_i in 1 2 3 4 5 6 7; do
+       ac_script="$ac_script$as_nl$ac_script"
+     done
+     echo "$ac_script" 2&amp;gt;/dev/null | sed 99q &amp;gt;conftest.sed
+     { ac_script=; unset ac_script;}
+     if test -z "$SED"; then
+  ac_path_SED_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" &amp;amp;&amp;amp; as_dir=.
+    for ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_SED" &amp;amp;&amp;amp; $as_test_x "$ac_path_SED"; } || continue
+# Check for GNU ac_path_SED and select it if it is found.
+  # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2&amp;gt;&amp;amp;1` in
+*GNU*)
+  ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 &amp;gt;"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" &amp;gt;"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo '' &amp;gt;&amp;gt; "conftest.nl"
+    "$ac_path_SED" -f conftest.sed &amp;lt; "conftest.nl" &amp;gt;"conftest.out" 2&amp;gt;/dev/null || break
+    diff "conftest.out" "conftest.nl" &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || break
+    as_fn_arith $ac_count + 1 &amp;amp;&amp;amp; ac_count=$as_val
+    if test $ac_count -gt ${ac_path_SED_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_SED="$ac_path_SED"
+      ac_path_SED_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 &amp;amp;&amp;amp; break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_SED_found &amp;amp;&amp;amp; break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_SED"; then
+    as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+  fi
+else
+  ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" &amp;gt;&amp;amp;5
+$as_echo "$ac_cv_path_SED" &amp;gt;&amp;amp;6; }
+ SED="$ac_cv_path_SED"
+  rm -f conftest.sed
+
 
 cat &amp;lt;&amp;lt; 'EOF' &amp;gt; conftest.head
 a
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3867,7 +3899,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; then
 configure: error:
 
   This system seems to lack a working 'head -1' or 'head -n 1' command.
-  A working 'head -1' (or equivalent) command is required to compile Eggdrop.
+  A working 'head -1' (or equivalent) command is required to compile Wraith.
 
 EOF
   exit 1
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3926,7 +3958,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; then
 configure: error:
 
   This system seems to lack a working 'awk' command.
-  A working 'awk' command is required to compile Eggdrop.
+  A working 'awk' command is required to compile Wraith.
 
 EOF
   exit 1
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3977,7 +4009,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; then
 configure: error:
 
   This system seems to lack a working 'basename' command.
-  A working 'basename' command is required to compile Eggdrop.
+  A working 'basename' command is required to compile Wraith.
 
 EOF
   exit 1
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4251,7 +4283,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; case "$egg_cv_var_system_type" in
   ;;
   HP-UX)
 
-$as_echo "#define MD32_XARRAY 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define MD32_XARRAY 1" &amp;gt;&amp;gt;build/confdefs.h
 
   ;;
   Ultrix)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4277,19 +4309,19 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo "#define MD32_XARRAY 1" &amp;gt;&amp;gt;confdefs.h
       ;;
       1.0|1.1|1.2)
 
-$as_echo "#define OSF1_HACKS 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define OSF1_HACKS 1" &amp;gt;&amp;gt;build/confdefs.h
       ;;
       1.*)
 
-$as_echo "#define OSF1_HACKS 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define OSF1_HACKS 1" &amp;gt;&amp;gt;build/confdefs.h
       ;;
       *)
       ;;
     esac
 
-$as_echo "#define STOP_UAC 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define STOP_UAC 1" &amp;gt;&amp;gt;build/confdefs.h
 
-$as_echo "#define BROKEN_SNPRINTF 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define BROKEN_SNPRINTF 1" &amp;gt;&amp;gt;build/confdefs.h
   ;;
   SunOS)
     SUNOS="yes"
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4310,7 +4342,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking if system is Mach based... " &amp;gt;&amp;amp;6; }
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" &amp;gt;&amp;amp;5
 $as_echo "yes" &amp;gt;&amp;amp;6; }
 
-$as_echo "#define BORGCUBES 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define BORGCUBES 1" &amp;gt;&amp;gt;build/confdefs.h
     else
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" &amp;gt;&amp;amp;5
 $as_echo "no" &amp;gt;&amp;amp;6; }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4346,32 +4378,35 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; esac
 # Check for IPv6 support
 #EGG_IPV6_SUPPORTED
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether or not you disabled IPv6 support" &amp;gt;&amp;amp;5
-$as_echo_n "checking whether or not you disabled IPv6 support... " &amp;gt;&amp;amp;6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether IPv6 is enabled" &amp;gt;&amp;amp;5
+$as_echo_n "checking whether IPv6 is enabled... " &amp;gt;&amp;amp;6; }
 # Check whether --enable-ipv6 was given.
 if test "${enable_ipv6+set}" = set; then :
-  enableval=$enable_ipv6;  ac_cv_dipv6="yes"
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" &amp;gt;&amp;amp;5
-$as_echo "yes" &amp;gt;&amp;amp;6; }
+  enableval=$enable_ipv6;
+       enable_ipv6=$enableval
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" &amp;gt;&amp;amp;5
+$as_echo "$enableval" &amp;gt;&amp;amp;6; }
 
 else
-   ac_cv_dipv6="no"
-  if test "$egg_cv_ipv6_supported" = "no"; then
-    ac_cv_dipv6="no"
-  fi
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_dipv6" &amp;gt;&amp;amp;5
-$as_echo "$ac_cv_dipv6" &amp;gt;&amp;amp;6; }
 
+       # default if not given is ENABLED
+       if test "x$enableval" = "x"; then
+         enableval="yes"
 fi
+       enable_ipv6=$enableval
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" &amp;gt;&amp;amp;5
+$as_echo "$enableval" &amp;gt;&amp;amp;6; }
 
+$as_echo "#define USE_IPV6 1" &amp;gt;&amp;gt;build/confdefs.h
 
-if test "$ac_cv_dipv6" = "no"; then
 
-$as_echo "#define USE_IPV6 1" &amp;gt;&amp;gt;confdefs.h
 
 fi
 
 
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t" &amp;gt;&amp;amp;5
 $as_echo_n "checking for socklen_t... " &amp;gt;&amp;amp;6; }
 if ${egg_cv_socklen_t+:} false; then :
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4381,8 +4416,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
   if test "$cross_compiling" = yes; then :
   egg_cv_socklen_t=no
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 #include &amp;lt;unistd.h&amp;gt;
 #include &amp;lt;sys/types.h&amp;gt;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4411,7 +4446,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 
 if test "$egg_cv_socklen_t" = "yes"; then
 
-$as_echo "#define HAVE_SOCKLEN_T 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define HAVE_SOCKLEN_T 1" &amp;gt;&amp;gt;build/confdefs.h
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" &amp;gt;&amp;amp;5
 $as_echo "yes" &amp;gt;&amp;amp;6; }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4437,7 +4472,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking for random limit... " &amp;gt;&amp;amp;6; }
 $as_echo "$RMAX" &amp;gt;&amp;amp;6; }
 
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define RANDOM_MAX $RMAX
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4454,8 +4489,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking whether the compiler understands -static... " &amp;gt;&amp;amp;6; }
 if ${egg_cv_var_ccstatic+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-        cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+        cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4503,7 +4538,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; cat &amp;gt;confcache &amp;lt;&amp;lt;\_ACEOF
 # It is not useful on other systems.  If it contains results you don't
 # want to keep, you may remove or edit it.
 #
-# config.status only pays attention to the cache file if you give it
+# build/config.status only pays attention to the cache file if you give it
 # the --recheck option to rerun configure.
 #
 # `ac_cv_env_foo' variables (set or unset) will be overridden when
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4591,8 +4626,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if ${ac_cv_lib_socket_socket+:} false; then :
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lsocket  $LIBS"
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4621,7 +4656,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" &amp;gt;&amp;amp;5
 $as_echo "$ac_cv_lib_socket_socket" &amp;gt;&amp;amp;6; }
 if test "x$ac_cv_lib_socket_socket" = xyes; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_LIBSOCKET 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4637,8 +4672,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if ${ac_cv_lib_dl_dlopen+:} false; then :
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-ldl  $LIBS"
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4667,7 +4702,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" &amp;gt;&amp;amp;5
 $as_echo "$ac_cv_lib_dl_dlopen" &amp;gt;&amp;amp;6; }
 if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_LIBDL 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4702,8 +4737,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if ${ac_cv_lib_dl_main+:} false; then :
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-ldl  $LIBS"
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 
 int
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4726,7 +4761,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_main" &amp;gt;&amp;amp;5
 $as_echo "$ac_cv_lib_dl_main" &amp;gt;&amp;amp;6; }
 if test "x$ac_cv_lib_dl_main" = xyes; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_LIBDL 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4741,8 +4776,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if ${ac_cv_lib_socket_main+:} false; then :
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lsocket  $LIBS"
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 
 int
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4765,7 +4800,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_main" &amp;gt;&amp;amp;5
 $as_echo "$ac_cv_lib_socket_main" &amp;gt;&amp;amp;6; }
 if test "x$ac_cv_lib_socket_main" = xyes; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_LIBSOCKET 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4780,8 +4815,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if ${ac_cv_lib_nsl_main+:} false; then :
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lnsl  $LIBS"
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 
 int
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4804,7 +4839,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_main" &amp;gt;&amp;amp;5
 $as_echo "$ac_cv_lib_nsl_main" &amp;gt;&amp;amp;6; }
 if test "x$ac_cv_lib_nsl_main" = xyes; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_LIBNSL 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4825,8 +4860,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking for $ac_hdr that defines DIR... " &amp;gt;&amp;amp;6; }
 if eval \${$as_ac_Header+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;sys/types.h&amp;gt;
 #include &amp;lt;$ac_hdr&amp;gt;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4850,7 +4885,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; eval ac_res=\$$as_ac_Header
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" &amp;gt;&amp;amp;5
 $as_echo "$ac_res" &amp;gt;&amp;amp;6; }
 if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4866,8 +4901,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if ${ac_cv_search_opendir+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
   ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4923,8 +4958,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if ${ac_cv_search_opendir+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
   ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4980,8 +5015,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " &amp;gt;&amp;amp;6; }
 if ${ac_cv_header_sys_wait_h+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;sys/types.h&amp;gt;
 #include &amp;lt;sys/wait.h&amp;gt;
 #ifndef WEXITSTATUS
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5012,7 +5047,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 $as_echo "$ac_cv_header_sys_wait_h" &amp;gt;&amp;amp;6; }
 if test $ac_cv_header_sys_wait_h = yes; then
 
-$as_echo "#define HAVE_SYS_WAIT_H 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define HAVE_SYS_WAIT_H 1" &amp;gt;&amp;gt;build/confdefs.h
 
 fi
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5021,8 +5056,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking whether time.h and sys/time.h may both be included... " &amp;gt;&amp;amp;6
 if ${ac_cv_header_time+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;sys/types.h&amp;gt;
 #include &amp;lt;sys/time.h&amp;gt;
 #include &amp;lt;time.h&amp;gt;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5047,7 +5082,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 $as_echo "$ac_cv_header_time" &amp;gt;&amp;amp;6; }
 if test $ac_cv_header_time = yes; then
 
-$as_echo "#define TIME_WITH_SYS_TIME 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define TIME_WITH_SYS_TIME 1" &amp;gt;&amp;gt;build/confdefs.h
 
 fi
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5056,8 +5091,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking whether stat file-mode macros are broken... " &amp;gt;&amp;amp;6; }
 if ${ac_cv_header_stat_broken+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;sys/types.h&amp;gt;
 #include &amp;lt;sys/stat.h&amp;gt;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5089,7 +5124,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 $as_echo "$ac_cv_header_stat_broken" &amp;gt;&amp;amp;6; }
 if test $ac_cv_header_stat_broken = yes; then
 
-$as_echo "#define STAT_MACROS_BROKEN 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define STAT_MACROS_BROKEN 1" &amp;gt;&amp;gt;build/confdefs.h
 
 fi
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5101,7 +5136,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; cat &amp;gt;confcache &amp;lt;&amp;lt;\_ACEOF
 # It is not useful on other systems.  If it contains results you don't
 # want to keep, you may remove or edit it.
 #
-# config.status only pays attention to the cache file if you give it
+# build/config.status only pays attention to the cache file if you give it
 # the --recheck option to rerun configure.
 #
 # `ac_cv_env_foo' variables (set or unset) will be overridden when
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5184,7 +5219,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
 if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5192,12 +5227,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 
 done
 
-for ac_header in sys/file.h sys/ioctl.h sys/param.h sys/socket.h wchar.h sys/ptrace.h paths.h
+for ac_header in sys/file.h sys/ioctl.h sys/param.h sys/socket.h wchar.h sys/ptrace.h paths.h sys/prctl.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
 if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5214,7 +5249,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; cat &amp;gt;confcache &amp;lt;&amp;lt;\_ACEOF
 # It is not useful on other systems.  If it contains results you don't
 # want to keep, you may remove or edit it.
 #
-# config.status only pays attention to the cache file if you give it
+# build/config.status only pays attention to the cache file if you give it
 # the --recheck option to rerun configure.
 #
 # `ac_cv_env_foo' variables (set or unset) will be overridden when
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5299,18 +5334,19 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; rm -f confcache
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for path to OpenSSL" &amp;gt;&amp;amp;5
 $as_echo_n "checking for path to OpenSSL... " &amp;gt;&amp;amp;6; }
 
+
 # Check whether --with-openssl was given.
 if test "${with_openssl+set}" = set; then :
-  withval=$with_openssl; cf_with_openssl=$withval
+  withval=$with_openssl; with_openssl_path=$withval
 else
-  cf_with_openssl="auto"
-
+  with_openssl_path=auto
 fi
 
 
+
 cf_openssl_basedir=""
-if test "$cf_with_openssl" != "auto"; then
-    cf_openssl_basedir="`echo ${cf_with_openssl} | sed 's/\/$//'`"
+if test "$with_openssl_path" != "auto"; then
+    cf_openssl_basedir="`echo ${with_openssl_path} | sed 's/\/$//'`"
 else
     for dirs in /usr/local/ssl /usr/pkg /usr/local /usr/local/openssl; do
     if test -f "${dirs}/include/openssl/opensslv.h" ; then
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5351,8 +5387,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; LIBS="$LIBS $SSL_LIBS"
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL version" &amp;gt;&amp;amp;5
 $as_echo_n "checking for OpenSSL version... " &amp;gt;&amp;amp;6; }
 
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;openssl/opensslv.h&amp;gt;
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5389,8 +5425,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if ${ac_cv_lib_crypto_AES_encrypt+:} false; then :
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lcrypto  $LIBS"
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5442,144 +5478,888 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; LIBS="$save_LIBS"
 
 
 
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
+#define EGG_SSL_EXT 1
+_ACEOF
 
 
-#AC_SUBST(ZLIB)dnl
+# TCL checks
 
-# Checks for typedefs, structures, and compiler characteristics
-ac_fn_cxx_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
-if test "x$ac_cv_type_pid_t" = xyes; then :
+# Tcl version to recommend if no Tcl is found, and the site where it can be
+# found for download.
+tclrecommendver="8.5.X"
+tclrecommendsite="ftp://tcl.activestate.com/pub/tcl/tcl8_5/"
 
-else
+# Tcl library filename prefixes, suffixes, and search paths.
+tcllibnames="tcl8.5 tcl85 tcl8.4 tcl84 tcl8.3 tcl83 tcl8.2 tcl82 \
+             tcl8.1 tcl81 tcl8.0 tcl80 tcl tcl7.6 tcl76 tcl7.5 tcl75 \
+             tcl7.4 tcl74 tcl7.3 tcl73 tcl7.2 tcl72 tcl7.1 tcl71 \
+             tcl7.0 tcl70"
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
-#define pid_t int
-_ACEOF
+tcllibextensions=".so .so.1 .so.1.0 .so.1.1 .so.1.2 .dll .dylib .sl .a"
 
-fi
+tcllibpaths="$HOME/lib $HOME/tcl/lib \
+             /usr/local/lib /usr/lib /lib /lib64 /usr/lib64 \
+             /usr/local/lib/tcl8.5 /usr/lib/tcl8.5 \
+             /usr/local/lib/tcl8.4 /usr/lib/tcl8.4 \
+             /usr/local/lib/tcl8.3 /usr/lib/tcl8.3 \
+             /usr/local/pkgs/tcl/lib /sys/lib /usr/pkg/lib \
+             /usr/i486-linuxaout/lib /beos/system/lib $HOME"
 
-ac_fn_cxx_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
-if test "x$ac_cv_type_size_t" = xyes; then :
+# Tcl header filenames and search paths.
+tclheadernames="tcl.h"
+tclheaderpaths="$HOME/include $HOME/tcl/include \
+                /usr/local/include /usr/include \
+                /usr/local/include/tcl8.5 /usr/include/tcl8.5 \
+                /usr/local/include/tcl8.4 /usr/include/tcl8.4 \
+                /usr/local/include/tcl8.3 /usr/include/tcl8.3 \
+                /usr/local/pkgs/tcl/include /sys/include \
+                /usr/pkg/lib /beos/system/include /beos/devel/include $HOME"
 
-else
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
-#define size_t unsigned int
-_ACEOF
+# Misc Tcl checks.
 
+
+# Check whether --with-tcllib was given.
+if test "${with_tcllib+set}" = set; then :
+  withval=$with_tcllib; tcllibname="$withval"
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" &amp;gt;&amp;amp;5
-$as_echo_n "checking for uid_t in sys/types.h... " &amp;gt;&amp;amp;6; }
-if ${ac_cv_type_uid_t+:} false; then :
-  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
-else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
-#include &amp;lt;sys/types.h&amp;gt;
 
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2&amp;gt;&amp;amp;5 |
-  $EGREP "uid_t" &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then :
-  ac_cv_type_uid_t=yes
-else
-  ac_cv_type_uid_t=no
+# Check whether --with-tclinc was given.
+if test "${with_tclinc+set}" = set; then :
+  withval=$with_tclinc; tclincname="$withval"
 fi
-rm -f conftest*
 
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether TCL Script is enabled" &amp;gt;&amp;amp;5
+$as_echo_n "checking whether TCL Script is enabled... " &amp;gt;&amp;amp;6; }
+  # Check whether --enable-script-tcl was given.
+if test "${enable_script_tcl+set}" = set; then :
+  enableval=$enable_script_tcl;
+       enable_script_tcl=$enableval
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" &amp;gt;&amp;amp;5
+$as_echo "$enableval" &amp;gt;&amp;amp;6; }
+
+else
+
+       # default if not given is ENABLED
+       if test "x$enableval" = "x"; then
+         enableval="yes"
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" &amp;gt;&amp;amp;5
-$as_echo "$ac_cv_type_uid_t" &amp;gt;&amp;amp;6; }
-if test $ac_cv_type_uid_t = no; then
+       enable_script_tcl=$enableval
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" &amp;gt;&amp;amp;5
+$as_echo "$enableval" &amp;gt;&amp;amp;6; }
 
-$as_echo "#define uid_t int" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define USE_SCRIPT_TCL 1" &amp;gt;&amp;gt;build/confdefs.h
 
 
-$as_echo "#define gid_t int" &amp;gt;&amp;gt;confdefs.h
 
 fi
 
 
 
-#AC_C_CONST
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working volatile" &amp;gt;&amp;amp;5
-$as_echo_n "checking for working volatile... " &amp;gt;&amp;amp;6; }
-if ${ac_cv_c_volatile+:} false; then :
-  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
+  WARN=0
+  # Make sure either both or neither $tcllibname and $tclincname are set
+  if test "x$tcllibname" != x; then
+    if test "x$tclincname" = x; then
+      WARN=1
+      tcllibname=""
+      TCLLIB=""
+      TCLINC=""
+    fi
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+    if test "x$tclincname" != x; then
+      WARN=1
+      tclincname=""
+      TCLLIB=""
+      TCLINC=""
+    fi
+  fi
 
-int
-main ()
-{
+  if test "$WARN" = 1; then
+    cat &amp;lt;&amp;lt; 'EOF' &amp;gt;&amp;amp;2
+configure: WARNING:
 
-volatile int x;
-int * volatile y = (int *) 0;
-return !x &amp;amp;&amp;amp; !y;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-  ac_cv_c_volatile=yes
+  You must specify both --with-tcllib and --with-tclinc for either to work.
+
+  configure will now attempt to autodetect both the Tcl library and header.
+
+EOF
+  fi
+
+
+  WARN=0
+  # Make sure either both or neither $TCLLIB and $TCLINC are set
+  if test "x$TCLLIB" != x; then
+    if test "x$TCLINC" = x; then
+      WARN=1
+      WVAR1=TCLLIB
+      WVAR2=TCLINC
+      TCLLIB=""
+    fi
 else
-  ac_cv_c_volatile=no
+    if test "x$TCLINC" != x; then
+      WARN=1
+      WVAR1=TCLINC
+      WVAR2=TCLLIB
+      TCLINC=""
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" &amp;gt;&amp;amp;5
-$as_echo "$ac_cv_c_volatile" &amp;gt;&amp;amp;6; }
-if test $ac_cv_c_volatile = no; then
 
-$as_echo "#define volatile /**/" &amp;gt;&amp;gt;confdefs.h
+  if test "$WARN" = 1; then
+    cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;amp;2
+configure: WARNING:
+
+  Environment variable $WVAR1 was set, but I did not detect ${WVAR2}.
+  Please set both TCLLIB and TCLINC correctly if you wish to use them.
 
+  configure will now attempt to autodetect both the Tcl library and header.
+
+EOF
 fi
 
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" &amp;gt;&amp;amp;5
-$as_echo_n "checking whether byte ordering is bigendian... " &amp;gt;&amp;amp;6; }
-if ${ac_cv_c_bigendian+:} false; then :
-  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
+
+  # Look for Tcl library: if $tcllibname is set, check there first
+  if test "x$tcllibname" != x; then
+    if test -f "$tcllibname" &amp;amp;&amp;amp; test -r "$tcllibname"; then
+      TCLLIB=`echo $tcllibname | sed 's%/[^/][^/]*$%%'`
+      TCLLIBFN=`$BASENAME $tcllibname | cut -c4-`
+      TCLLIBEXT=".`echo $TCLLIBFN | $AWK '{j=split($1, i, "."); print i[j]}'`"
+      TCLLIBFNS=`$BASENAME $tcllibname $TCLLIBEXT | cut -c4-`
 else
-  ac_cv_c_bigendian=unknown
-    # See if we're dealing with a universal compiler.
-    cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
-#ifndef __APPLE_CC__
-       not a universal capable compiler
-     #endif
-     typedef int dummy;
+      cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;amp;2
+configure: WARNING:
 
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+  The file '$tcllibname' given to option --with-tcllib is not valid.
 
-# Check for potential -arch flags.  It is not universal unless
-# there are at least two -arch flags with different values.
-ac_arch=
-ac_prev=
-for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
- if test -n "$ac_prev"; then
-   case $ac_word in
-     i?86 | x86_64 | ppc | ppc64)
-       if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
- ac_arch=$ac_word
-       else
- ac_cv_c_bigendian=universal
- break
-       fi
-       ;;
-   esac
-   ac_prev=
- elif test "x$ac_word" = "x-arch"; then
-   ac_prev=arch
+  configure will now attempt to autodetect both the Tcl library and header.
+
+EOF
+      tcllibname=""
+      tclincname=""
+      TCLLIB=""
+      TCLLIBFN=""
+      TCLINC=""
+      TCLINCFN=""
  fi
-       done
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-    if test $ac_cv_c_bigendian = unknown; then
-      # See if sys/param.h defines the BYTE_ORDER macro.
-      cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+
+
+  # Look for Tcl header: if $tclincname is set, check there first
+  if test "x$tclincname" != x; then
+    if test -f "$tclincname" &amp;amp;&amp;amp; test -r "$tclincname"; then
+      TCLINC=`echo $tclincname | sed 's%/[^/][^/]*$%%'`
+      TCLINCFN=`$BASENAME $tclincname`
+    else
+      cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;amp;2
+configure: WARNING:
+
+  The file '$tclincname' given to option --with-tclinc is not valid.
+
+  configure will now attempt to autodetect both the Tcl library and header.
+
+EOF
+      tcllibname=""
+      tclincname=""
+      TCLLIB=""
+      TCLLIBFN=""
+      TCLINC=""
+      TCLINCFN=""
+    fi
+  fi
+
+
+  # Look for Tcl library: if $TCLLIB is set, check there first
+  if test "x$TCLLIBFN" = x &amp;amp;&amp;amp; test "x$TCLLIB" != x; then
+    if test -d "$TCLLIB"; then
+      for tcllibfns in $tcllibnames; do
+        for tcllibext in $tcllibextensions; do
+          if test -r "${TCLLIB}/lib${tcllibfns}${tcllibext}"; then
+            TCLLIBFN="${tcllibfns}${tcllibext}"
+            TCLLIBEXT="$tcllibext"
+            TCLLIBFNS="$tcllibfns"
+            break 2
+          fi
+        done
+      done
+    fi
+
+    if test "x$TCLLIBFN" = x; then
+      cat &amp;lt;&amp;lt; 'EOF' &amp;gt;&amp;amp;2
+configure: WARNING:
+
+  Environment variable TCLLIB was set, but incorrectly.
+  Please set both TCLLIB and TCLINC correctly if you wish to use them.
+
+  configure will now attempt to autodetect both the Tcl library and header.
+
+EOF
+      TCLLIB=""
+      TCLLIBFN=""
+      TCLINC=""
+      TCLINCFN=""
+    fi
+  fi
+
+
+  # Look for Tcl header: if $TCLINC is set, check there first
+  if test "x$TCLINCFN" = x &amp;amp;&amp;amp; test "x$TCLINC" != x; then
+    if test -d "$TCLINC"; then
+      for tclheaderfn in $tclheadernames; do
+        if test -r "${TCLINC}/${tclheaderfn}"; then
+          TCLINCFN="$tclheaderfn"
+          break
+        fi
+      done
+    fi
+
+    if test "x$TCLINCFN" = x; then
+      cat &amp;lt;&amp;lt; 'EOF' &amp;gt;&amp;amp;2
+configure: WARNING:
+
+  Environment variable TCLINC was set, but incorrectly.
+  Please set both TCLLIB and TCLINC correctly if you wish to use them.
+
+  configure will now attempt to autodetect both the Tcl library and header.
+
+EOF
+      TCLLIB=""
+      TCLLIBFN=""
+      TCLINC=""
+      TCLINCFN=""
+    fi
+  fi
+
+
+  if test "$enable_script_tcl" = "yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl library" &amp;gt;&amp;amp;5
+$as_echo_n "checking for Tcl library... " &amp;gt;&amp;amp;6; }
+
+    # Attempt autodetect for $TCLLIBFN if it's not set
+    if test "x$TCLLIBFN" != x; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: using ${TCLLIB}/lib${TCLLIBFN}" &amp;gt;&amp;amp;5
+$as_echo "using ${TCLLIB}/lib${TCLLIBFN}" &amp;gt;&amp;amp;6; }
+    else
+      for tcllibfns in $tcllibnames; do
+        for tcllibext in $tcllibextensions; do
+          for tcllibpath in $tcllibpaths; do
+            if test -r "${tcllibpath}/lib${tcllibfns}${tcllibext}"; then
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${tcllibpath}/lib${tcllibfns}${tcllibext}" &amp;gt;&amp;amp;5
+$as_echo "found ${tcllibpath}/lib${tcllibfns}${tcllibext}" &amp;gt;&amp;amp;6; }
+              TCLLIB="$tcllibpath"
+              TCLLIBFN="${tcllibfns}${tcllibext}"
+              TCLLIBEXT="$tcllibext"
+              TCLLIBFNS="$tcllibfns"
+              break 3
+            fi
+          done
+        done
+      done
+    fi
+
+    # Show if $TCLLIBFN wasn't found
+    if test "x$TCLLIBFN" = x; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" &amp;gt;&amp;amp;5
+$as_echo "not found" &amp;gt;&amp;amp;6; }
+    fi
+  fi
+
+
+
+
+
+  if test "$enable_script_tcl" = "yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl header" &amp;gt;&amp;amp;5
+$as_echo_n "checking for Tcl header... " &amp;gt;&amp;amp;6; }
+
+    # Attempt autodetect for $TCLINCFN if it's not set
+    if test "x$TCLINCFN" != x; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: using ${TCLINC}/${TCLINCFN}" &amp;gt;&amp;amp;5
+$as_echo "using ${TCLINC}/${TCLINCFN}" &amp;gt;&amp;amp;6; }
+    else
+      for tclheaderpath in $tclheaderpaths; do
+        for tclheaderfn in $tclheadernames; do
+          if test -r "${tclheaderpath}/${tclheaderfn}"; then
+            { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${tclheaderpath}/${tclheaderfn}" &amp;gt;&amp;amp;5
+$as_echo "found ${tclheaderpath}/${tclheaderfn}" &amp;gt;&amp;amp;6; }
+            TCLINC="$tclheaderpath"
+            TCLINCFN="$tclheaderfn"
+            break 2
+          fi
+        done
+      done
+
+      # FreeBSD hack ...
+      if test "x$TCLINCFN" = x; then
+        for tcllibfns in $tcllibnames; do
+          for tclheaderpath in $tclheaderpaths; do
+            for tclheaderfn in $tclheadernames; do
+              if test -r "${tclheaderpath}/${tcllibfns}/${tclheaderfn}"; then
+                { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${tclheaderpath}/${tcllibfns}/${tclheaderfn}" &amp;gt;&amp;amp;5
+$as_echo "found ${tclheaderpath}/${tcllibfns}/${tclheaderfn}" &amp;gt;&amp;amp;6; }
+                TCLINC="${tclheaderpath}/${tcllibfns}"
+                TCLINCFN="$tclheaderfn"
+                break 3
+              fi
+            done
+          done
+        done
+      fi
+    fi
+
+    TCL_INCLUDES=""
+    if ! test "x$TCLINC" = x; then
+      TCL_INCLUDES="-I$TCLINC"
+    fi
+
+    if test "x$TCLINCFN" = x; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" &amp;gt;&amp;amp;5
+$as_echo "not found" &amp;gt;&amp;amp;6; }
+    fi
+  fi
+
+
+
+
+
+  if test "$enable_script_tcl" = "yes"; then
+            { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the Tcl system has changed" &amp;gt;&amp;amp;5
+$as_echo_n "checking whether the Tcl system has changed... " &amp;gt;&amp;amp;6; }
+    egg_tcl_changed="yes"
+    egg_tcl_id="${TCLLIB}:${TCLLIBFN}:${TCLINC}:${TCLINCFN}"
+    if test "$egg_tcl_id" != ":::"; then
+      egg_tcl_cached="yes"
+      if ${egg_cv_var_tcl_id+:} false; then :
+  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
+else
+
+        egg_cv_var_tcl_id="$egg_tcl_id"
+        egg_tcl_cached="no"
+
+fi
+
+      if test "$egg_tcl_cached" = yes; then
+        if test "x$egg_cv_var_tcl_id" = "x$egg_tcl_id"; then
+          egg_tcl_changed="no"
+        else
+          egg_cv_var_tcl_id="$egg_tcl_id"
+        fi
+      fi
+    fi
+
+    if test "$egg_tcl_changed" = yes; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" &amp;gt;&amp;amp;5
+$as_echo "yes" &amp;gt;&amp;amp;6; }
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" &amp;gt;&amp;amp;5
+$as_echo "no" &amp;gt;&amp;amp;6; }
+    fi
+  fi
+
+
+  if test "$enable_script_tcl" = "yes"; then
+    # Both TCLLIBFN &amp;amp; TCLINCFN must be set, or we bail
+    TCL_FOUND=0
+    if test "x$TCLLIBFN" != x &amp;amp;&amp;amp; test "x$TCLINCFN" != x; then
+      TCL_FOUND=1
+
+      # Check Tcl's version
+      if test "$egg_tcl_changed" = yes; then
+        unset egg_cv_var_tcl_version
+      fi
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl version" &amp;gt;&amp;amp;5
+$as_echo_n "checking for Tcl version... " &amp;gt;&amp;amp;6; }
+      if ${egg_cv_var_tcl_version+:} false; then :
+  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
+else
+
+        egg_cv_var_tcl_version=`grep TCL_VERSION $TCLINC/$TCLINCFN | $HEAD_1 | $AWK '{gsub(/\"/, "", $3); print $3}'`
+
+fi
+
+
+      if test "x$egg_cv_var_tcl_version" != x; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $egg_cv_var_tcl_version" &amp;gt;&amp;amp;5
+$as_echo "$egg_cv_var_tcl_version" &amp;gt;&amp;amp;6; }
+      else
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" &amp;gt;&amp;amp;5
+$as_echo "not found" &amp;gt;&amp;amp;6; }
+        TCL_FOUND=0
+      fi
+
+      # Check Tcl's patch level (if available)
+      if test "$egg_tcl_changed" = yes; then
+        unset egg_cv_var_tcl_patch_level
+      fi
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl patch level" &amp;gt;&amp;amp;5
+$as_echo_n "checking for Tcl patch level... " &amp;gt;&amp;amp;6; }
+      if ${egg_cv_var_tcl_patch_level+:} false; then :
+  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
+else
+
+        eval "egg_cv_var_tcl_patch_level=`grep TCL_PATCH_LEVEL $TCLINC/$TCLINCFN | $HEAD_1 | $AWK '{gsub(/\"/, "", $3); print $3}'`"
+
+fi
+
+
+      if test "x$egg_cv_var_tcl_patch_level" != x; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $egg_cv_var_tcl_patch_level" &amp;gt;&amp;amp;5
+$as_echo "$egg_cv_var_tcl_patch_level" &amp;gt;&amp;amp;6; }
+      else
+        egg_cv_var_tcl_patch_level="unknown"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" &amp;gt;&amp;amp;5
+$as_echo "unknown" &amp;gt;&amp;amp;6; }
+      fi
+    fi
+
+    # Check if we found Tcl's version
+    if test "$TCL_FOUND" = 0; then
+      cat &amp;lt;&amp;lt; 'EOF' &amp;gt;&amp;amp;2
+configure: error:
+
+  Tcl cannot be found on this system.
+
+  Tcl is not required. Wraith will be compiled without TCL support. If you
+  already have Tcl installed on this system, please specify the path by
+  rerunning ./configure using the --with-tcllib='/path/to/libtcl.so' and
+  --with-tclinc='/path/to/tcl.h' options.
+
+EOF
+    enable_script_tcl="no"
+    else
+
+$as_echo "#define HAVE_LIBTCL 1" &amp;gt;&amp;gt;build/confdefs.h
+
+    fi
+  fi
+
+
+  if test "$enable_script_tcl" = "yes"; then
+    # Is this version of Tcl too old for us to use ?
+    TCL_VER_PRE70=`echo $egg_cv_var_tcl_version | $AWK '{split($1, i, "."); if (i[1] &amp;lt; 7) print "yes"; else print "no"}'`
+    if test "$TCL_VER_PRE70" = yes; then
+      cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;amp;2
+configure: error:
+
+  Your Tcl version is much too old for Wraith to use. You should
+  download and compile a more recent version. The most reliable
+  current version is $tclrecommendver and can be downloaded from
+  ${tclrecommendsite}.
+
+  See doc/COMPILE-GUIDE's 'Tcl Detection and Installation' section
+  for more information.
+
+EOF
+      exit 1
+    fi
+  fi
+
+
+  # Set variables for Tcl library tests
+  TCL_TEST_LIB="$TCLLIBFNS"
+  TCL_TEST_OTHERLIBS="-L$TCLLIB $EGG_MATH_LIB"
+  if test "x$ac_cv_lib_pthread" != x; then
+    TCL_TEST_OTHERLIBS="$TCL_TEST_OTHERLIBS $ac_cv_lib_pthread"
+  fi
+
+
+  if test "$enable_script_tcl" = "yes"; then
+    if test "$egg_tcl_changed" = yes; then
+      unset egg_cv_var_tcl_free
+    fi
+
+    # Check for Tcl_Free()
+    as_ac_Lib=`$as_echo "ac_cv_lib_$TCL_TEST_LIB''_Tcl_Free" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl_Free in -l$TCL_TEST_LIB" &amp;gt;&amp;amp;5
+$as_echo_n "checking for Tcl_Free in -l$TCL_TEST_LIB... " &amp;gt;&amp;amp;6; }
+if eval \${$as_ac_Lib+:} false; then :
+  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$TCL_TEST_LIB $TCL_TEST_OTHERLIBS $LIBS"
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char Tcl_Free ();
+int
+main ()
+{
+return Tcl_Free ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" &amp;gt;&amp;amp;5
+$as_echo "$ac_res" &amp;gt;&amp;amp;6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+  egg_cv_var_tcl_free="yes"
+else
+  egg_cv_var_tcl_free="no"
+fi
+
+
+    if test "$egg_cv_var_tcl_free" = yes; then
+
+$as_echo "#define HAVE_TCL_FREE 1" &amp;gt;&amp;gt;build/confdefs.h
+
+    fi
+  fi
+
+#EGG_TCL_CHECK_GETCURRENTTHREAD
+#EGG_TCL_CHECK_GETTHREADDATA
+
+  if test "$enable_script_tcl" = "yes"; then
+    if test "$egg_tcl_changed" = yes; then
+      unset egg_cv_var_tcl_setnotifier
+    fi
+
+    # Check for Tcl_SetNotifier()
+    as_ac_Lib=`$as_echo "ac_cv_lib_$TCL_TEST_LIB''_Tcl_SetNotifier" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl_SetNotifier in -l$TCL_TEST_LIB" &amp;gt;&amp;amp;5
+$as_echo_n "checking for Tcl_SetNotifier in -l$TCL_TEST_LIB... " &amp;gt;&amp;amp;6; }
+if eval \${$as_ac_Lib+:} false; then :
+  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$TCL_TEST_LIB $TCL_TEST_OTHERLIBS $LIBS"
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char Tcl_SetNotifier ();
+int
+main ()
+{
+return Tcl_SetNotifier ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" &amp;gt;&amp;amp;5
+$as_echo "$ac_res" &amp;gt;&amp;amp;6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+  egg_cv_var_tcl_setnotifier="yes"
+else
+  egg_cv_var_tcl_setnotifier="no"
+fi
+
+    if test "$egg_cv_var_tcl_setnotifier" = yes; then
+
+$as_echo "#define HAVE_TCL_SETNOTIFIER 1" &amp;gt;&amp;gt;build/confdefs.h
+
+    fi
+  fi
+
+
+  if test "$enable_script_tcl" = "yes"; then
+    if test "$EGG_CYGWIN" = yes; then
+      TCL_REQS="${TCLLIB}/lib${TCLLIBFN}"
+      TCL_LIBS="-L$TCLLIB -l$TCLLIBFNS $EGG_MATH_LIB"
+    else
+      if test "$TCLLIBEXT" != ".a"; then
+        TCL_REQS="${TCLLIB}/lib${TCLLIBFN}"
+        TCL_LIBS="-L$TCLLIB -l$TCLLIBFNS $EGG_MATH_LIB"
+      else
+        # Set default make as static for unshared Tcl library
+        if test "$DEFAULT_MAKE" != static; then
+          cat &amp;lt;&amp;lt; 'EOF' &amp;gt;&amp;amp;2
+configure: WARNING:
+
+  Your Tcl library is not a shared lib.
+  configure will now set default make type to static.
+
+EOF
+          DEFAULT_MAKE="static"
+
+        fi
+
+        # Are we using a pre 7.4 Tcl version ?
+        TCL_VER_PRE74=`echo $egg_cv_var_tcl_version | $AWK '{split($1, i, "."); if (((i[1] == 7) &amp;amp;&amp;amp; (i[2] &amp;lt; 4)) || (i[1] &amp;lt; 7)) print "yes"; else print "no"}'`
+        if test "$TCL_VER_PRE74" = no; then
+
+          # Was the --with-tcllib option given ?
+          if test "x$tcllibname" != x; then
+            TCL_REQS="${TCLLIB}/lib${TCLLIBFN}"
+            TCL_LIBS="${TCLLIB}/lib${TCLLIBFN} $EGG_MATH_LIB"
+          else
+            TCL_REQS="${TCLLIB}/lib${TCLLIBFN}"
+            TCL_LIBS="-L$TCLLIB -l$TCLLIBFNS $EGG_MATH_LIB"
+          fi
+        else
+          cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;amp;2
+configure: WARNING:
+
+  Your Tcl version ($egg_cv_var_tcl_version) is older than 7.4.
+  There are known problems, but we will attempt to work around them.
+
+EOF
+          TCL_REQS="libtcle.a"
+          TCL_LIBS="-L`pwd` -ltcle $EGG_MATH_LIB"
+        fi
+      fi
+    fi
+  fi
+
+
+
+
+
+cat &amp;gt;confcache &amp;lt;&amp;lt;\_ACEOF
+# 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, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# build/config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# 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.
+(
+  for ac_var in `(set) 2&amp;gt;&amp;amp;1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" &amp;gt;&amp;amp;5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" &amp;gt;&amp;amp;2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2&amp;gt;&amp;amp;1 |
+    case $as_nl`(ac_space=' '; set) 2&amp;gt;&amp;amp;1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+"s/'/'\\\\''/g;
+  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &amp;amp;/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' &amp;gt;&amp;gt;confcache
+if diff "$cache_file" confcache &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" &amp;gt;&amp;amp;5
+$as_echo "$as_me: updating cache $cache_file" &amp;gt;&amp;amp;6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+cat confcache &amp;gt;"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+  mv -f confcache "$cache_file"$$ &amp;amp;&amp;amp;
+  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+  mv -f confcache "$cache_file" ;;
+esac
+      fi
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" &amp;gt;&amp;amp;5
+$as_echo "$as_me: not updating unwritable cache $cache_file" &amp;gt;&amp;amp;6;}
+  fi
+fi
+rm -f confcache
+
+#AC_SUBST(ZLIB)dnl
+
+# Checks for typedefs, structures, and compiler characteristics
+ac_fn_cxx_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
+if test "x$ac_cv_type_pid_t" = xyes; then :
+
+else
+
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+ac_fn_cxx_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" &amp;gt;&amp;amp;5
+$as_echo_n "checking for uid_t in sys/types.h... " &amp;gt;&amp;amp;6; }
+if ${ac_cv_type_uid_t+:} false; then :
+  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
+else
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
+#include &amp;lt;sys/types.h&amp;gt;
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2&amp;gt;&amp;amp;5 |
+  $EGREP "uid_t" &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then :
+  ac_cv_type_uid_t=yes
+else
+  ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" &amp;gt;&amp;amp;5
+$as_echo "$ac_cv_type_uid_t" &amp;gt;&amp;amp;6; }
+if test $ac_cv_type_uid_t = no; then
+
+$as_echo "#define uid_t int" &amp;gt;&amp;gt;build/confdefs.h
+
+
+$as_echo "#define gid_t int" &amp;gt;&amp;gt;build/confdefs.h
+
+fi
+
+
+
+#AC_C_CONST
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working volatile" &amp;gt;&amp;amp;5
+$as_echo_n "checking for working volatile... " &amp;gt;&amp;amp;6; }
+if ${ac_cv_c_volatile+:} false; then :
+  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
+else
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
+
+int
+main ()
+{
+
+volatile int x;
+int * volatile y = (int *) 0;
+return !x &amp;amp;&amp;amp; !y;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_c_volatile=yes
+else
+  ac_cv_c_volatile=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" &amp;gt;&amp;amp;5
+$as_echo "$ac_cv_c_volatile" &amp;gt;&amp;amp;6; }
+if test $ac_cv_c_volatile = no; then
+
+$as_echo "#define volatile /**/" &amp;gt;&amp;gt;build/confdefs.h
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" &amp;gt;&amp;amp;5
+$as_echo_n "checking whether byte ordering is bigendian... " &amp;gt;&amp;amp;6; }
+if ${ac_cv_c_bigendian+:} false; then :
+  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
+else
+  ac_cv_c_bigendian=unknown
+    # See if we're dealing with a universal compiler.
+    cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
+#ifndef __APPLE_CC__
+       not a universal capable compiler
+     #endif
+     typedef int dummy;
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+# Check for potential -arch flags.  It is not universal unless
+# there are at least two -arch flags with different values.
+ac_arch=
+ac_prev=
+for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+   case $ac_word in
+     i?86 | x86_64 | ppc | ppc64)
+       if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+       else
+ ac_cv_c_bigendian=universal
+ break
+       fi
+       ;;
+   esac
+   ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+   ac_prev=arch
+ fi
+       done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if sys/param.h defines the BYTE_ORDER macro.
+      cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;sys/types.h&amp;gt;
      #include &amp;lt;sys/param.h&amp;gt;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5598,8 +6378,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; main ()
 _ACEOF
 if ac_fn_cxx_try_compile "$LINENO"; then :
   # It does; now see whether it defined to BIG_ENDIAN or not.
- cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+ cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;sys/types.h&amp;gt;
 #include &amp;lt;sys/param.h&amp;gt;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5625,8 +6405,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     fi
     if test $ac_cv_c_bigendian = unknown; then
       # See if &amp;lt;limits.h&amp;gt; defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
-      cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+      cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;limits.h&amp;gt;
 
 int
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5642,8 +6422,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; main ()
 _ACEOF
 if ac_fn_cxx_try_compile "$LINENO"; then :
   # It does; now see whether it defined to _BIG_ENDIAN or not.
- cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+ cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;limits.h&amp;gt;
 
 int
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5670,8 +6450,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
       # Compile a test program.
       if test "$cross_compiling" = yes; then :
   # Try to guess by grepping values from an object file.
- cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+ cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 short int ascii_mm[] =
   { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
 short int ascii_ii[] =
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5711,8 +6491,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if ac_fn_cxx_try_compile "$LINENO"; then :
 fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 $ac_includes_default
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5747,15 +6527,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo "$ac_cv_c_bigendian" &amp;gt;&amp;amp;6; }
  case $ac_cv_c_bigendian in #(
    yes)
 
-$as_echo "#define B_ENDIAN 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define B_ENDIAN 1" &amp;gt;&amp;gt;build/confdefs.h
 ;; #(
    no)
 
-$as_echo "#define L_ENDIAN 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define L_ENDIAN 1" &amp;gt;&amp;gt;build/confdefs.h
  ;; #(
    universal)
 
-$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" &amp;gt;&amp;gt;build/confdefs.h
 
      ;; #(
    *)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5769,8 +6549,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking whether char is unsigned... " &amp;gt;&amp;amp;6; }
 if ${ac_cv_c_char_unsigned+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 $ac_includes_default
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5792,7 +6572,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_char_unsigned" &amp;gt;&amp;amp;5
 $as_echo "$ac_cv_c_char_unsigned" &amp;gt;&amp;amp;6; }
 if test $ac_cv_c_char_unsigned = yes &amp;amp;&amp;amp; test "$GCC" != yes; then
-  $as_echo "#define __CHAR_UNSIGNED__ 1" &amp;gt;&amp;gt;confdefs.h
+  $as_echo "#define __CHAR_UNSIGNED__ 1" &amp;gt;&amp;gt;build/confdefs.h
 
 fi
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5807,7 +6587,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; cat &amp;gt;confcache &amp;lt;&amp;lt;\_ACEOF
 # It is not useful on other systems.  If it contains results you don't
 # want to keep, you may remove or edit it.
 #
-# config.status only pays attention to the cache file if you give it
+# build/config.status only pays attention to the cache file if you give it
 # the --recheck option to rerun configure.
 #
 # `ac_cv_env_foo' variables (set or unset) will be overridden when
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5886,236 +6666,247 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo "$as_me: not updating unwritable cache $cache_file" &amp;gt;&amp;amp;6;}
 fi
 rm -f confcache
 
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) &amp;gt;= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" &amp;gt;&amp;amp;5
-$as_echo_n "checking size of short... " &amp;gt;&amp;amp;6; }
-if ${ac_cv_sizeof_short+:} false; then :
-  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
-else
-  if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short"        "$ac_includes_default"; then :
+# Checks for typedefs, structures, and compiler characteristics
+ac_fn_cxx_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
+if test "x$ac_cv_type_pid_t" = xyes; then :
 
 else
-  if test "$ac_cv_type_short" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" &amp;gt;&amp;amp;5
-$as_echo "$as_me: error: in \`$ac_pwd':" &amp;gt;&amp;amp;2;}
-as_fn_error 77 "cannot compute sizeof (short)
-See \`config.log' for more details" "$LINENO" 5; }
-   else
-     ac_cv_sizeof_short=0
-   fi
-fi
+
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
+#define pid_t int
+_ACEOF
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" &amp;gt;&amp;amp;5
-$as_echo "$ac_cv_sizeof_short" &amp;gt;&amp;amp;6; }
 
+ac_fn_cxx_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
 
+else
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
-#define SIZEOF_SHORT $ac_cv_sizeof_short
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
+#define size_t unsigned int
 _ACEOF
 
+fi
 
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) &amp;gt;= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" &amp;gt;&amp;amp;5
-$as_echo_n "checking size of int... " &amp;gt;&amp;amp;6; }
-if ${ac_cv_sizeof_int+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" &amp;gt;&amp;amp;5
+$as_echo_n "checking for uid_t in sys/types.h... " &amp;gt;&amp;amp;6; }
+if ${ac_cv_type_uid_t+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int"        "$ac_includes_default"; then :
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
+#include &amp;lt;sys/types.h&amp;gt;
 
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2&amp;gt;&amp;amp;5 |
+  $EGREP "uid_t" &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then :
+  ac_cv_type_uid_t=yes
 else
-  if test "$ac_cv_type_int" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" &amp;gt;&amp;amp;5
-$as_echo "$as_me: error: in \`$ac_pwd':" &amp;gt;&amp;amp;2;}
-as_fn_error 77 "cannot compute sizeof (int)
-See \`config.log' for more details" "$LINENO" 5; }
-   else
-     ac_cv_sizeof_int=0
-   fi
+  ac_cv_type_uid_t=no
 fi
+rm -f conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" &amp;gt;&amp;amp;5
-$as_echo "$ac_cv_sizeof_int" &amp;gt;&amp;amp;6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" &amp;gt;&amp;amp;5
+$as_echo "$ac_cv_type_uid_t" &amp;gt;&amp;amp;6; }
+if test $ac_cv_type_uid_t = no; then
 
+$as_echo "#define uid_t int" &amp;gt;&amp;gt;build/confdefs.h
 
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
-#define SIZEOF_INT $ac_cv_sizeof_int
-_ACEOF
+$as_echo "#define gid_t int" &amp;gt;&amp;gt;build/confdefs.h
+
+fi
 
 
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) &amp;gt;= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" &amp;gt;&amp;amp;5
-$as_echo_n "checking size of long... " &amp;gt;&amp;amp;6; }
-if ${ac_cv_sizeof_long+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" &amp;gt;&amp;amp;5
+$as_echo_n "checking for long long int... " &amp;gt;&amp;amp;6; }
+if ${ac_cv_type_long_long_int+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
+
+  /* For now, do not test the preprocessor; as of 2007 there are too many
+         implementations with broken preprocessors.  Perhaps this can
+         be revisited in 2012.  In the meantime, code should not expect
+         #if to work with literals wider than 32 bits.  */
+      /* Test literals.  */
+      long long int ll = 9223372036854775807ll;
+      long long int nll = -9223372036854775807LL;
+      unsigned long long int ull = 18446744073709551615ULL;
+      /* Test constant expressions.   */
+      typedef int a[((-9223372036854775807LL &amp;lt; 0 &amp;amp;&amp;amp; 0 &amp;lt; 9223372036854775807ll)
+                     ? 1 : -1)];
+      typedef int b[(18446744073709551615ULL &amp;lt;= (unsigned long long int) -1
+                     ? 1 : -1)];
+      int i = 63;
+int
+main ()
+{
+/* Test availability of runtime routines for shift and division.  */
+      long long int llmax = 9223372036854775807ll;
+      unsigned long long int ullmax = 18446744073709551615ull;
+      return ((ll &amp;lt;&amp;lt; 63) | (ll &amp;gt;&amp;gt; 63) | (ll &amp;lt; i) | (ll &amp;gt; i)
+              | (llmax / ll) | (llmax % ll)
+              | (ull &amp;lt;&amp;lt; 63) | (ull &amp;gt;&amp;gt; 63) | (ull &amp;lt;&amp;lt; i) | (ull &amp;gt;&amp;gt; i)
+              | (ullmax / ull) | (ullmax % ull));
+  ;
+  return 0;
+}
 
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+                          if test "$cross_compiling" = yes; then :
+  ac_cv_type_long_long_int=yes
 else
-  if test "$ac_cv_type_long" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" &amp;gt;&amp;amp;5
-$as_echo "$as_me: error: in \`$ac_pwd':" &amp;gt;&amp;amp;2;}
-as_fn_error 77 "cannot compute sizeof (long)
-See \`config.log' for more details" "$LINENO" 5; }
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
+#include &amp;lt;limits.h&amp;gt;
+               #ifndef LLONG_MAX
+               # define HALF \
+                        (1LL &amp;lt;&amp;lt; (sizeof (long long int) * CHAR_BIT - 2))
+               # define LLONG_MAX (HALF - 1 + HALF)
+               #endif
+int
+main ()
+{
+long long int n = 1;
+               int i;
+               for (i = 0; ; i++)
+                 {
+                   long long int m = n &amp;lt;&amp;lt; i;
+                   if (m &amp;gt;&amp;gt; i != n)
+                     return 1;
+                   if (LLONG_MAX / 2 &amp;lt; m)
+                     break;
+                 }
+               return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+  ac_cv_type_long_long_int=yes
    else
-     ac_cv_sizeof_long=0
-   fi
+  ac_cv_type_long_long_int=no
 fi
-
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" &amp;gt;&amp;amp;5
-$as_echo "$ac_cv_sizeof_long" &amp;gt;&amp;amp;6; }
-
-
-
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
-#define SIZEOF_LONG $ac_cv_sizeof_long
-_ACEOF
-
-
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) &amp;gt;= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" &amp;gt;&amp;amp;5
-$as_echo_n "checking size of long long... " &amp;gt;&amp;amp;6; }
-if ${ac_cv_sizeof_long_long+:} false; then :
-  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
-else
-  if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long"        "$ac_includes_default"; then :
 
 else
-  if test "$ac_cv_type_long_long" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" &amp;gt;&amp;amp;5
-$as_echo "$as_me: error: in \`$ac_pwd':" &amp;gt;&amp;amp;2;}
-as_fn_error 77 "cannot compute sizeof (long long)
-See \`config.log' for more details" "$LINENO" 5; }
-   else
-     ac_cv_sizeof_long_long=0
+  ac_cv_type_long_long_int=no
    fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" &amp;gt;&amp;amp;5
+$as_echo "$ac_cv_type_long_long_int" &amp;gt;&amp;amp;6; }
+  if test $ac_cv_type_long_long_int = yes; then
 
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" &amp;gt;&amp;amp;5
-$as_echo "$ac_cv_sizeof_long_long" &amp;gt;&amp;amp;6; }
+$as_echo "#define HAVE_LONG_LONG_INT 1" &amp;gt;&amp;gt;build/confdefs.h
 
+  fi
 
+ac_fn_c_find_intX_t "$LINENO" "8" "ac_cv_c_int8_t"
+case $ac_cv_c_int8_t in #(
+  no|yes) ;; #(
+  *)
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
-#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
+#define int8_t $ac_cv_c_int8_t
 _ACEOF
+;;
+esac
 
+ac_fn_c_find_uintX_t "$LINENO" "8" "ac_cv_c_uint8_t"
+case $ac_cv_c_uint8_t in #(
+  no|yes) ;; #(
+  *)
 
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) &amp;gt;= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" &amp;gt;&amp;amp;5
-$as_echo_n "checking size of size_t... " &amp;gt;&amp;amp;6; }
-if ${ac_cv_sizeof_size_t+:} false; then :
-  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
-else
-  if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t"        "$ac_includes_default"; then :
-
-else
-  if test "$ac_cv_type_size_t" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" &amp;gt;&amp;amp;5
-$as_echo "$as_me: error: in \`$ac_pwd':" &amp;gt;&amp;amp;2;}
-as_fn_error 77 "cannot compute sizeof (size_t)
-See \`config.log' for more details" "$LINENO" 5; }
-   else
-     ac_cv_sizeof_size_t=0
-   fi
-fi
+$as_echo "#define _UINT8_T 1" &amp;gt;&amp;gt;build/confdefs.h
 
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" &amp;gt;&amp;amp;5
-$as_echo "$ac_cv_sizeof_size_t" &amp;gt;&amp;amp;6; }
 
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
+#define uint8_t $ac_cv_c_uint8_t
+_ACEOF
+;;
+  esac
 
+ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t"
+case $ac_cv_c_int16_t in #(
+  no|yes) ;; #(
+  *)
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
-#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
+#define int16_t $ac_cv_c_int16_t
 _ACEOF
+;;
+esac
 
+ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t"
+case $ac_cv_c_uint16_t in #(
+  no|yes) ;; #(
+  *)
 
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) &amp;gt;= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of ptrdiff_t" &amp;gt;&amp;amp;5
-$as_echo_n "checking size of ptrdiff_t... " &amp;gt;&amp;amp;6; }
-if ${ac_cv_sizeof_ptrdiff_t+:} false; then :
-  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
-else
-  if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (ptrdiff_t))" "ac_cv_sizeof_ptrdiff_t"        "$ac_includes_default"; then :
 
-else
-  if test "$ac_cv_type_ptrdiff_t" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" &amp;gt;&amp;amp;5
-$as_echo "$as_me: error: in \`$ac_pwd':" &amp;gt;&amp;amp;2;}
-as_fn_error 77 "cannot compute sizeof (ptrdiff_t)
-See \`config.log' for more details" "$LINENO" 5; }
-   else
-     ac_cv_sizeof_ptrdiff_t=0
-   fi
-fi
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
+#define uint16_t $ac_cv_c_uint16_t
+_ACEOF
+;;
+  esac
 
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_ptrdiff_t" &amp;gt;&amp;amp;5
-$as_echo "$ac_cv_sizeof_ptrdiff_t" &amp;gt;&amp;amp;6; }
+ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t"
+case $ac_cv_c_int32_t in #(
+  no|yes) ;; #(
+  *)
 
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
+#define int32_t $ac_cv_c_int32_t
+_ACEOF
+;;
+esac
 
+ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t"
+case $ac_cv_c_uint32_t in #(
+  no|yes) ;; #(
+  *)
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
-#define SIZEOF_PTRDIFF_T $ac_cv_sizeof_ptrdiff_t
-_ACEOF
+$as_echo "#define _UINT32_T 1" &amp;gt;&amp;gt;build/confdefs.h
 
 
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) &amp;gt;= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of time_t" &amp;gt;&amp;amp;5
-$as_echo_n "checking size of time_t... " &amp;gt;&amp;amp;6; }
-if ${ac_cv_sizeof_time_t+:} false; then :
-  $as_echo_n "(cached) " &amp;gt;&amp;amp;6
-else
-  if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_sizeof_time_t"        "$ac_includes_default"; then :
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
+#define uint32_t $ac_cv_c_uint32_t
+_ACEOF
+;;
+  esac
 
-else
-  if test "$ac_cv_type_time_t" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" &amp;gt;&amp;amp;5
-$as_echo "$as_me: error: in \`$ac_pwd':" &amp;gt;&amp;amp;2;}
-as_fn_error 77 "cannot compute sizeof (time_t)
-See \`config.log' for more details" "$LINENO" 5; }
-   else
-     ac_cv_sizeof_time_t=0
-   fi
-fi
+ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t"
+case $ac_cv_c_int64_t in #(
+  no|yes) ;; #(
+  *)
 
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" &amp;gt;&amp;amp;5
-$as_echo "$ac_cv_sizeof_time_t" &amp;gt;&amp;amp;6; }
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
+#define int64_t $ac_cv_c_int64_t
+_ACEOF
+;;
+esac
+
+ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t"
+case $ac_cv_c_uint64_t in #(
+  no|yes) ;; #(
+  *)
 
+$as_echo "#define _UINT64_T 1" &amp;gt;&amp;gt;build/confdefs.h
 
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
-#define SIZEOF_TIME_T $ac_cv_sizeof_time_t
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
+#define uint64_t $ac_cv_c_uint64_t
 _ACEOF
-
+;;
+  esac
 
 
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6124,8 +6915,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking whether struct tm is in sys/time.h or time.h... " &amp;gt;&amp;amp;6; }
 if ${ac_cv_struct_tm+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;sys/types.h&amp;gt;
 #include &amp;lt;time.h&amp;gt;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6150,7 +6941,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 $as_echo "$ac_cv_struct_tm" &amp;gt;&amp;amp;6; }
 if test $ac_cv_struct_tm = sys/time.h; then
 
-$as_echo "#define TM_IN_SYS_TIME 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define TM_IN_SYS_TIME 1" &amp;gt;&amp;gt;build/confdefs.h
 
 fi
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6160,7 +6951,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; ac_fn_cxx_check_member "$LINENO" "struct tm" "tm_zone" "ac_cv_member_struct_tm_t
 "
 if test "x$ac_cv_member_struct_tm_tm_zone" = xyes; then :
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_STRUCT_TM_TM_ZONE 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6169,7 +6960,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 
 if test "$ac_cv_member_struct_tm_tm_zone" = yes; then
 
-$as_echo "#define HAVE_TM_ZONE 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define HAVE_TM_ZONE 1" &amp;gt;&amp;gt;build/confdefs.h
 
 else
   ac_fn_cxx_check_decl "$LINENO" "tzname" "ac_cv_have_decl_tzname" "#include &amp;lt;time.h&amp;gt;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6180,7 +6971,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
   ac_have_decl=0
 fi
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_DECL_TZNAME $ac_have_decl
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6189,8 +6980,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking for tzname... " &amp;gt;&amp;amp;6; }
 if ${ac_cv_var_tzname+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;time.h&amp;gt;
 #if !HAVE_DECL_TZNAME
 extern char *tzname[];
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6216,7 +7007,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 $as_echo "$ac_cv_var_tzname" &amp;gt;&amp;amp;6; }
   if test $ac_cv_var_tzname = yes; then
 
-$as_echo "#define HAVE_TZNAME 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define HAVE_TZNAME 1" &amp;gt;&amp;gt;build/confdefs.h
 
   fi
 fi
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6226,8 +7017,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo_n "checking whether struct tm is in sys/time.h or time.h... " &amp;gt;&amp;amp;6; }
 if ${ac_cv_struct_tm+:} false; then :
   $as_echo_n "(cached) " &amp;gt;&amp;amp;6
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;sys/types.h&amp;gt;
 #include &amp;lt;time.h&amp;gt;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6252,7 +7043,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 $as_echo "$ac_cv_struct_tm" &amp;gt;&amp;amp;6; }
 if test $ac_cv_struct_tm = sys/time.h; then
 
-$as_echo "#define TM_IN_SYS_TIME 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define TM_IN_SYS_TIME 1" &amp;gt;&amp;gt;build/confdefs.h
 
 fi
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6262,7 +7053,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; for ac_header in vfork.h
 do :
   ac_fn_cxx_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default"
 if test "x$ac_cv_header_vfork_h" = xyes; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_VFORK_H 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6275,7 +7066,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
 if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6291,8 +7082,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
   if test "$cross_compiling" = yes; then :
   ac_cv_func_fork_works=cross
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 $ac_includes_default
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6344,8 +7135,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
   if test "$cross_compiling" = yes; then :
   ac_cv_func_vfork_works=cross
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 /* Thanks to Paul Eggert for this test.  */
 $ac_includes_default
 #include &amp;lt;sys/wait.h&amp;gt;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6458,16 +7249,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 
 if test "x$ac_cv_func_vfork_works" = xyes; then
 
-$as_echo "#define HAVE_WORKING_VFORK 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define HAVE_WORKING_VFORK 1" &amp;gt;&amp;gt;build/confdefs.h
 
 else
 
-$as_echo "#define vfork fork" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define vfork fork" &amp;gt;&amp;gt;build/confdefs.h
 
 fi
 if test "x$ac_cv_func_fork_works" = xyes; then
 
-$as_echo "#define HAVE_WORKING_FORK 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define HAVE_WORKING_FORK 1" &amp;gt;&amp;gt;build/confdefs.h
 
 fi
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6482,8 +7273,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if test "$as_ln_s" = "ln -s" &amp;amp;&amp;amp; ln -s conftest.file conftest.sym; then
   if test "$cross_compiling" = yes; then :
   ac_cv_func_lstat_dereferences_slashed_symlink=no
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 $ac_includes_default
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6519,7 +7310,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo "$ac_cv_func_lstat_dereferences_slashed_symlink" &amp;gt;&amp;amp;6; }
 
 test $ac_cv_func_lstat_dereferences_slashed_symlink = yes &amp;amp;&amp;amp;
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6541,8 +7332,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
   if test "$cross_compiling" = yes; then :
   ac_cv_func_lstat_empty_string_bug=yes
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 $ac_includes_default
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6573,7 +7364,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if test $ac_cv_func_lstat_empty_string_bug = yes; then
 esac
 
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_LSTAT_EMPTY_STRING_BUG 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6590,8 +7381,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if test "$as_ln_s" = "ln -s" &amp;amp;&amp;amp; ln -s conftest.file conftest.sym; then
   if test "$cross_compiling" = yes; then :
   ac_cv_func_lstat_dereferences_slashed_symlink=no
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 $ac_includes_default
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6627,7 +7418,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo "$ac_cv_func_lstat_dereferences_slashed_symlink" &amp;gt;&amp;amp;6; }
 
 test $ac_cv_func_lstat_dereferences_slashed_symlink = yes &amp;amp;&amp;amp;
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6645,7 +7436,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; for ac_header in stdlib.h
 do :
   ac_fn_cxx_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
 if test "x$ac_cv_header_stdlib_h" = xyes; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_STDLIB_H 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6661,8 +7452,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
   if test "$cross_compiling" = yes; then :
   ac_cv_func_malloc_0_nonnull=no
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #if defined STDC_HEADERS || defined HAVE_STDLIB_H
 # include &amp;lt;stdlib.h&amp;gt;
 #else
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6691,10 +7482,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 $as_echo "$ac_cv_func_malloc_0_nonnull" &amp;gt;&amp;amp;6; }
 if test $ac_cv_func_malloc_0_nonnull = yes; then :
 
-$as_echo "#define HAVE_MALLOC 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define HAVE_MALLOC 1" &amp;gt;&amp;gt;build/confdefs.h
 
 else
-  $as_echo "#define HAVE_MALLOC 0" &amp;gt;&amp;gt;confdefs.h
+  $as_echo "#define HAVE_MALLOC 0" &amp;gt;&amp;gt;build/confdefs.h
 
    case " $LIBOBJS " in
   *" malloc.$ac_objext "* ) ;;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6703,7 +7494,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
 esac
 
 
-$as_echo "#define malloc rpl_malloc" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define malloc rpl_malloc" &amp;gt;&amp;gt;build/confdefs.h
 
 fi
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6717,7 +7508,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do :
 ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
 "
 if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6737,7 +7528,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
 if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6756,8 +7547,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
   if test "$cross_compiling" = yes; then :
   ac_cv_func_working_mktime=no
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 /* Test program from Paul Eggert and Tony Leneis.  */
 #ifdef TIME_WITH_SYS_TIME
 # include &amp;lt;sys/time.h&amp;gt;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6980,7 +7771,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; for ac_func in getpagesize
 do :
   ac_fn_cxx_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize"
 if test "x$ac_cv_func_getpagesize" = xyes; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_GETPAGESIZE 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6995,8 +7786,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
   if test "$cross_compiling" = yes; then :
   ac_cv_func_mmap_fixed_mapped=no
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 $ac_includes_default
 /* malloc might have been renamed as rpl_malloc. */
 #undef malloc
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7148,7 +7939,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 $as_echo "$ac_cv_func_mmap_fixed_mapped" &amp;gt;&amp;amp;6; }
 if test $ac_cv_func_mmap_fixed_mapped = yes; then
 
-$as_echo "#define HAVE_MMAP 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define HAVE_MMAP 1" &amp;gt;&amp;gt;build/confdefs.h
 
 fi
 rm -f conftest.mmap conftest.txt
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7157,7 +7948,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; for ac_header in stdlib.h
 do :
   ac_fn_cxx_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
 if test "x$ac_cv_header_stdlib_h" = xyes; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_STDLIB_H 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7173,8 +7964,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
   if test "$cross_compiling" = yes; then :
   ac_cv_func_realloc_0_nonnull=no
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #if defined STDC_HEADERS || defined HAVE_STDLIB_H
 # include &amp;lt;stdlib.h&amp;gt;
 #else
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7203,10 +7994,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 $as_echo "$ac_cv_func_realloc_0_nonnull" &amp;gt;&amp;amp;6; }
 if test $ac_cv_func_realloc_0_nonnull = yes; then :
 
-$as_echo "#define HAVE_REALLOC 1" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define HAVE_REALLOC 1" &amp;gt;&amp;gt;build/confdefs.h
 
 else
-  $as_echo "#define HAVE_REALLOC 0" &amp;gt;&amp;gt;confdefs.h
+  $as_echo "#define HAVE_REALLOC 0" &amp;gt;&amp;gt;build/confdefs.h
 
    case " $LIBOBJS " in
   *" realloc.$ac_objext "* ) ;;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7215,7 +8006,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
 esac
 
 
-$as_echo "#define realloc rpl_realloc" &amp;gt;&amp;gt;confdefs.h
+$as_echo "#define realloc rpl_realloc" &amp;gt;&amp;gt;build/confdefs.h
 
 fi
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7228,8 +8019,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; else
   if test "$cross_compiling" = yes; then :
   ac_cv_func_stat_empty_string_bug=yes
 else
-  cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+  cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 $ac_includes_default
 int
 main ()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7260,7 +8051,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if test $ac_cv_func_stat_empty_string_bug = yes; then
 esac
 
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_STAT_EMPTY_STRING_BUG 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7272,7 +8063,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; ac_fn_cxx_check_type "$LINENO" "struct timespec" "ac_cv_type_struct_timespec" "#
 #include &amp;lt;time.h&amp;gt;
 "
 if test "x$ac_cv_type_struct_timespec" = xyes; then :
-  $as_echo "#define HAVE_TIMESPEC 1" &amp;gt;&amp;gt;confdefs.h
+  $as_echo "#define HAVE_TIMESPEC 1" &amp;gt;&amp;gt;build/confdefs.h
 
 fi
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7280,12 +8071,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 if test X"$ac_cv_type_struct_timespec" != X"no"; then
  ac_fn_cxx_check_member "$LINENO" "struct stat" "st_mtim" "ac_cv_member_struct_stat_st_mtim" "$ac_includes_default"
 if test "x$ac_cv_member_struct_stat_st_mtim" = xyes; then :
-  $as_echo "#define HAVE_ST_MTIM 1" &amp;gt;&amp;gt;confdefs.h
+  $as_echo "#define HAVE_ST_MTIM 1" &amp;gt;&amp;gt;build/confdefs.h
 
 else
   ac_fn_cxx_check_member "$LINENO" "struct stat" "st_mtimespec" "ac_cv_member_struct_stat_st_mtimespec" "$ac_includes_default"
 if test "x$ac_cv_member_struct_stat_st_mtimespec" = xyes; then :
-  $as_echo "#define HAVE_ST_MTIMESPEC 1" &amp;gt;&amp;gt;confdefs.h
+  $as_echo "#define HAVE_ST_MTIMESPEC 1" &amp;gt;&amp;gt;build/confdefs.h
 
 fi
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7293,8 +8084,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for two-parameter timespecsub" &amp;gt;&amp;amp;5
 $as_echo_n "checking for two-parameter timespecsub... " &amp;gt;&amp;amp;6; }
- cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+ cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 #include &amp;lt;sys/types.h&amp;gt;
 #include &amp;lt;sys/time.h&amp;gt;
 int
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7311,7 +8102,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; timespecsub(&amp;amp;ts1, &amp;amp;ts2);
 }
 _ACEOF
 if ac_fn_cxx_try_compile "$LINENO"; then :
-  $as_echo "#define HAVE_TIMESPECSUB2 1" &amp;gt;&amp;gt;confdefs.h
+  $as_echo "#define HAVE_TIMESPECSUB2 1" &amp;gt;&amp;gt;build/confdefs.h
 
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" &amp;gt;&amp;amp;5
 $as_echo "yes" &amp;gt;&amp;amp;6; }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7326,7 +8117,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; for ac_func in strftime
 do :
   ac_fn_cxx_check_func "$LINENO" "strftime" "ac_cv_func_strftime"
 if test "x$ac_cv_func_strftime" = xyes; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_STRFTIME 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7339,8 +8130,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if ${ac_cv_lib_intl_strftime+:} false; then :
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lintl  $LIBS"
-cat confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
-/* end confdefs.h.  */
+cat build/confdefs.h - &amp;lt;&amp;lt;_ACEOF &amp;gt;conftest.$ac_ext
+/* end build/confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7369,7 +8160,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_strftime" &amp;gt;&amp;amp;5
 $as_echo "$ac_cv_lib_intl_strftime" &amp;gt;&amp;amp;6; }
 if test "x$ac_cv_lib_intl_strftime" = xyes; then :
-  $as_echo "#define HAVE_STRFTIME 1" &amp;gt;&amp;gt;confdefs.h
+  $as_echo "#define HAVE_STRFTIME 1" &amp;gt;&amp;gt;build/confdefs.h
 
 LIBS="-lintl $LIBS"
 fi
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7386,7 +8177,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; cat &amp;gt;confcache &amp;lt;&amp;lt;\_ACEOF
 # It is not useful on other systems.  If it contains results you don't
 # want to keep, you may remove or edit it.
 #
-# config.status only pays attention to the cache file if you give it
+# build/config.status only pays attention to the cache file if you give it
 # the --recheck option to rerun configure.
 #
 # `ac_cv_env_foo' variables (set or unset) will be overridden when
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7469,7 +8260,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
 if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7481,7 +8272,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
 if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7496,7 +8287,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; cat &amp;gt;confcache &amp;lt;&amp;lt;\_ACEOF
 # It is not useful on other systems.  If it contains results you don't
 # want to keep, you may remove or edit it.
 #
-# config.status only pays attention to the cache file if you give it
+# build/config.status only pays attention to the cache file if you give it
 # the --recheck option to rerun configure.
 #
 # `ac_cv_env_foo' variables (set or unset) will be overridden when
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7579,7 +8370,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
 if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7597,7 +8388,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; for ac_func in vsprintf
 do :
   ac_fn_cxx_check_func "$LINENO" "vsprintf" "ac_cv_func_vsprintf"
 if test "x$ac_cv_func_vsprintf" = xyes; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_VSPRINTF 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7621,7 +8412,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; for ac_func in uname
 do :
   ac_fn_cxx_check_func "$LINENO" "uname" "ac_cv_func_uname"
 if test "x$ac_cv_func_uname" = xyes; then :
-  cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+  cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define HAVE_UNAME 1
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7664,7 +8455,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; cat &amp;gt;confcache &amp;lt;&amp;lt;\_ACEOF
 # It is not useful on other systems.  If it contains results you don't
 # want to keep, you may remove or edit it.
 #
-# config.status only pays attention to the cache file if you give it
+# build/config.status only pays attention to the cache file if you give it
 # the --recheck option to rerun configure.
 #
 # `ac_cv_env_foo' variables (set or unset) will be overridden when
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7747,7 +8538,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; rm -f confcache
 VERSION=`grep "char" $srcdir/src/main.c | $AWK '/egg_version/ {print $5}' | sed -e 's/\"//g' | sed -e 's/\;//g'`
 version_num=`echo $VERSION | $AWK 'BEGIN {FS = "."} {printf("%d%02d%02d", $1, $2, $3)}'`
 
-cat &amp;gt;&amp;gt;confdefs.h &amp;lt;&amp;lt;_ACEOF
+cat &amp;gt;&amp;gt;build/confdefs.h &amp;lt;&amp;lt;_ACEOF
 #define EGG_VERSION $version_num
 _ACEOF
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7817,12 +8608,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; $as_echo X"$mf" |
       fi
     fi
     echo "include .deps/$base.Po" &amp;gt;&amp;gt; "$dirpart/.deps/includes"
-    echo "_$base.c:" &amp;gt;&amp;gt; "$dirpart/.deps/includes"
   done
 done
 
 
-ac_config_files="$ac_config_files Makefile lib/Makefile src/Makefile src/compat/Makefile src/crypto/Makefile src/mod/Makefile src/buildinfo.h"
+ac_config_files="$ac_config_files Makefile lib/Makefile src/Makefile src/compat/Makefile src/crypto/Makefile src/mod/Makefile src/buildinfo.h src/mod/mod.mk"
 
 cat &amp;gt;confcache &amp;lt;&amp;lt;\_ACEOF
 # This file is a shell script that caches the results of configure
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7831,7 +8621,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; cat &amp;gt;confcache &amp;lt;&amp;lt;\_ACEOF
 # It is not useful on other systems.  If it contains results you don't
 # want to keep, you may remove or edit it.
 #
-# config.status only pays attention to the cache file if you give it
+# build/config.status only pays attention to the cache file if you give it
 # the --recheck option to rerun configure.
 #
 # `ac_cv_env_foo' variables (set or unset) will be overridden when
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7935,7 +8725,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; LTLIBOBJS=$ac_ltlibobjs
 
 
 
-: "${CONFIG_STATUS=./config.status}"
+: "${CONFIG_STATUS=./build/config.status}"
 ac_write_fail=0
 ac_clean_files_save=$ac_clean_files
 ac_clean_files="$ac_clean_files $CONFIG_STATUS"
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7947,7 +8737,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; cat &amp;gt;$CONFIG_STATUS &amp;lt;&amp;lt;_ASEOF || as_write_fail=1
 # Generated by $as_me.
 # Run this file to recreate the current configuration.
 # Compiler output produced by configure, useful for debugging
-# configure, is in config.log if it exists.
+# configure, is in build/config.log if it exists.
 
 debug=false
 ac_cs_recheck=false
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -8367,7 +9157,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; esac
 
 
 cat &amp;gt;&amp;gt;$CONFIG_STATUS &amp;lt;&amp;lt;_ACEOF || ac_write_fail=1
-# Files that config.status was made for.
+# Files that build/config.status was made for.
 config_files="$ac_config_files"
 config_headers="$ac_config_headers"
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -8405,12 +9195,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; _ACEOF
 cat &amp;gt;&amp;gt;$CONFIG_STATUS &amp;lt;&amp;lt;_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&amp;amp;/g'`"
 ac_cs_version="\\
-config.status
+build/config.status
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
 Copyright (C) 2010 Free Software Foundation, Inc.
-This config.status script is free software; the Free Software Foundation
+This build/config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
 ac_pwd='$ac_pwd'
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -8508,7 +9298,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi
 
 _ACEOF
 cat &amp;gt;&amp;gt;$CONFIG_STATUS &amp;lt;&amp;lt;\_ACEOF || ac_write_fail=1
-exec 5&amp;gt;&amp;gt;config.log
+exec 5&amp;gt;&amp;gt;build/config.log
 {
   echo
   sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' &amp;lt;&amp;lt;_ASBOX
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -8527,7 +9317,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; cat &amp;gt;&amp;gt;$CONFIG_STATUS &amp;lt;&amp;lt;\_ACEOF || ac_write_fail=1
 for ac_config_target in $ac_config_targets
 do
   case $ac_config_target in
-    "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+    "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;;
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
     "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;;
     "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -8535,6 +9325,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do
     "src/crypto/Makefile") CONFIG_FILES="$CONFIG_FILES src/crypto/Makefile" ;;
     "src/mod/Makefile") CONFIG_FILES="$CONFIG_FILES src/mod/Makefile" ;;
     "src/buildinfo.h") CONFIG_FILES="$CONFIG_FILES src/buildinfo.h" ;;
+    "src/mod/mod.mk") CONFIG_FILES="$CONFIG_FILES src/mod/mod.mk" ;;
 
   *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -8579,7 +9370,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; ac_tmp=$tmp
 
 # Set up the scripts for CONFIG_FILES section.
 # No need to generate them if there are no CONFIG_FILES.
-# This happens for instance with `./config.status config.h'.
+# This happens for instance with `./build/config.status config.h'.
 if test -n "$CONFIG_FILES"; then
 
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -8737,21 +9528,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; fi # test -n "$CONFIG_FILES"
 
 # Set up the scripts for CONFIG_HEADERS section.
 # No need to generate them if there are no CONFIG_HEADERS.
-# This happens for instance with `./config.status Makefile'.
+# This happens for instance with `./build/config.status Makefile'.
 if test -n "$CONFIG_HEADERS"; then
 cat &amp;gt;"$ac_tmp/defines.awk" &amp;lt;&amp;lt;\_ACAWK ||
 BEGIN {
 _ACEOF
 
-# Transform confdefs.h into an awk script `defines.awk', embedded as
-# here-document in config.status, that substitutes the proper values into
+# Transform build/confdefs.h into an awk script `defines.awk', embedded as
+# here-document in build/config.status, that substitutes the proper values into
 # config.h.in to produce config.h.
 
-# Create a delimiter string that does not exist in confdefs.h, to ease
+# Create a delimiter string that does not exist in build/confdefs.h, to ease
 # handling of long lines.
 ac_delim='%!_!# '
 for ac_last_try in false false :; do
-  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  ac_tt=`sed -n "/$ac_delim/p" build/confdefs.h`
   if test -z "$ac_tt"; then
     break
   elif $ac_last_try; then
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -8801,7 +9592,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; d
 :bsnlc
 s/["\\]/\\&amp;amp;/g; s/^/"/; s/$/\\\\\\n"\\/p
 b cont
-' &amp;lt;confdefs.h | sed '
+' &amp;lt;build/confdefs.h | sed '
 s/'"$ac_delim"'/"\\\
 "/g' &amp;gt;&amp;gt;$CONFIG_STATUS || ac_write_fail=1
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -8889,7 +9680,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do
 
     # Let's still pretend it is `configure' which instantiates (i.e., don't
     # use $as_me), people would be surprised to read:
-    #    /* config.h.  Generated by config.status.  */
+    #    /* config.h.  Generated by build/config.status.  */
     configure_input='Generated from '`
   $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
 `' by configure.'
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -9091,13 +9882,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; test $ac_write_fail = 0 ||
   as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
 
 
-# configure is writing to config.log, and then calls config.status.
-# config.status does its own redirection, appending to config.log.
-# Unfortunately, on DOS this fails, as config.log is still kept open
-# by configure, so config.status won't be able to write to it; its
+# configure is writing to build/config.log, and then calls build/config.status.
+# build/config.status does its own redirection, appending to build/config.log.
+# Unfortunately, on DOS this fails, as build/config.log is still kept open
+# by configure, so build/config.status won't be able to write to it; its
 # output is simply discarded.  So we exec the FD to /dev/null,
-# effectively closing config.log, so it can be properly (re)opened and
-# appended to by config.status.  When coming back to configure, we
+# effectively closing build/config.log, so it can be properly (re)opened and
+# appended to by build/config.status.  When coming back to configure, we
 # need to make the FD available again.
 if test "$no_create" != yes; then
   ac_cs_success=:
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -9106,7 +9897,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if test "$no_create" != yes; then
     ac_config_status_args="$ac_config_status_args --quiet"
   exec 5&amp;gt;/dev/null
   $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
-  exec 5&amp;gt;&amp;gt;config.log
+  exec 5&amp;gt;&amp;gt;build/config.log
   # Use ||, not &amp;amp;&amp;amp;, to avoid exiting from the if with $? = 1, which
   # would make configure fail if this is the last instruction.
   $ac_cs_success || as_fn_exit 1
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -9139,13 +9930,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; if [ "$GIT_REQUIRED" = "1" ]; then
 fi
 
 
-echo ""
-echo ""
-echo "------------ Configuring BDLIB ------------"
 
 if test -d .git; then
   git submodule init
   git submodule update
 fi
 
-test -f lib/bdlib/configure &amp;amp;&amp;amp; cd lib/bdlib &amp;amp;&amp;amp; MAKEJOBS="$MAKEJOBS" ./configure
+
+CXX="$CXX" TCL_INCLUDES="$TCL_INCLUDES" SSL_INCLUDES="$SSL_INCLUDES" SED="$SED" src/generate_defs.sh
+
+if [ $? -ne 0 ]; then
+  exit 1
+fi
+
+
+echo ""
+echo ""
+echo "------------ Configuring BDLIB ------------"
+test -f lib/bdlib/configure &amp;amp;&amp;amp; cd lib/bdlib &amp;amp;&amp;amp; CXX="$CXX" MAKEJOBS="$MAKEJOBS" ./configure
diff --git a/doc/UPDATES b/doc/UPDATES
index 9fb1ff5..2177230 100755
--- a/doc/UPDATES
+++ b/doc/UPDATES
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,3 +1,58 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+1.4.0 - http://wraith.botpack.net/milestone/1.4.0
+  * Updated server list, 'set -yes servers -' and 'set -yes servers6 -' to get new list.
+  * Change +bitch reaction to use normal queue for deopping opper/opped clients
+  * Fix +take clearing -fastop (fixes #371)
+  * Added botbitch to mmode (fixes #139)
+  * Added SSL support
+    This includes new set options: 'servers-ssl', 'servers6-ssl', 'server-port-ssl', 'server-use-ssl'
+  * libcrypto (openssl) is now loaded at startup and is required.
+  * Added TCL support. This is *only* a .tcl command currently, no scripts are loadable yet.
+  * Fix blowfish not working correctly on 64bit
+  * Suicide will now remove all bots related to the binary being removed (fixes #435)
+  * FiSH message support added.
+    * FiSH support for DH1080 key-exchange. 'keyx' command added to start from bot, and responds to key-exchanges.
+    * Auto FiSH key-exchange when accepting users via callerid (controllable with set 'fish-auto-keyx')
+    * Automatic re-key exchange after every message to avoid replay attacks (controllable with set 'fish-paranoid')
+    * Set FiSH key via cmd_setkey and 'chanset fish-key'
+    * Bot expires key exchange if there's no response in 7 seconds.
+    * Bot expires key-exchanged keys after 60 minutes.
+  * When 'mdop' protection is on, re-op all previously opped clients automatically.
+  * When 'mop' protection is on, deop all previously regular clients automatically.
+  * Add './wraith -V' which will display the packconfig that the bot is using.
+  * Add cmd_newhub for adding a new hub. All bots will add this to their config.
+  * Hubs can now be overridden inside the botconfig (-C)
+  * Optimize userfile writing by doing it asynchronously
+  * Groups support added. See: http://wraith.botpack.net/wiki/Groups
+    * Add [bot]set var 'groups' to configure what groups bots are in
+    * Add chanset 'groups' to take a list of groups that should join. 'chanset #chan groups { main backup }'
+    * Added group support to 'botcmd': 'botcmd [*|&amp;amp;|?] %group cmd'
+    * 'botjoin' and 'botpart' have been removed. Just use .+chan, .chanset, .botset to control groups.
+    * Add command 'groups' to list all groups and which bots are in them.
+    * Command 'channels' now accepts a '%group' param to show which channels a group are in.
+    * Add '%group' support to 'bots' command.
+  * Improve output of 'bots' command by displaying and sorting nodename
+  * Minus chrec if .chattr set no flags
+  * Added 'chanset +floodban' to ban clients that violate 'flood-chan' and 'flood-ctcp'
+  * Bots now auto-reop other bots that get deopped
+  * Bots now ask for ops quicker if another bot is opped
+  * Bots now request/join +ilk channels much quicker
+  * Add 'chanset revenge' which will react/kick/ban/remove users who kick/ban/deop bots.
+  * Fix flood kicking not properly tracking multiple clients at once (#43)
+  * Add chanset 'flood-bytes' to count how many bytes:second a user sends before getting kicked for flood. (#42)
+  * Bot will now lockdown channel (+im) if banlist becomes full (#37)
+  * Bot will now lockdown channel (+im) if a drone flood is detected (#37)
+    * Add chansets 'flood-mchan', 'flood-mbytes', 'flood-mctcp' to control reactions to mass floods (#37)
+  * Remove unneeded chanset 'nomassjoin'
+  * Add chanset 'caps-limit' to handle % of message that can be in caps before kick (#8)
+  * Add chanset 'color-limit' to handle how many color codes are allowed in a message before kick (#8)
+  * Add chanset 'closed-exempt' which will allow exempting non-users (who are opped or voice) from being kicked. (fixes #171)
+  * Tweak limit range checking such that bot will set limit less often
+  * Bots now again respect devoices made by other bots and will not revoice those users.
+  * Add chanset 'voice-moderate' which will auto set +m in '+voice' channel and devoice flooding clients instead of kick. (#48)
+  * Bots now will enforce devoices made by ops (user +o) and allow any op (user +o) to revoice to disable that enforcement.
+    This used to use +m to enforce/allowed revoicing.
+  * Bots will now remember a client's flood/devoice settings if they cycle (#49)
+
 1.3.4 - http://wraith.botpack.net/milestone/1.3.4
   * Fix various compile warnings with newer GCC
   * Fix bot getting confused when changing to long nicks
diff --git a/doc/help.txt b/doc/help.txt
index 304bdfc..efb82b2 100644
--- a/doc/help.txt
+++ b/doc/help.txt
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -56,7 +56,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: invites, -invite, stick, unstick
    have no flags, an optional hostmask, and a random pass/secpass.
    List as many hosts as needed.
  
-See also: -user, +host, -host, clearhosts%{+ni}, newleaf%{-}
+See also: -user, +host, -host, clearhosts%{+ni}, newleaf%{-}%{+a}, newhub%{-}
 ::-ban
 ###  $b-ban$b &amp;lt;banmask or number&amp;gt; [channel]
    Removes the specified ban from the list of bans stored on the bot. You may
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -68,7 +68,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: bans, +ban, stick, unstick
    This is exactly the same as $b'%d-user'$b (it removes a user record). It is
    included for convenience.
  
-See also: +user, -user%{+n}, newleaf%{-}
+See also: +user, -user%{+ni}, newleaf%{-}%{+a}, newhub%{-}
 ::-chan
 ### $b-chan$b &amp;lt;channel&amp;gt;
    This removes ALL information about a channel from the bot. 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -121,7 +121,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: invites, +invite, stick, unstick
 ###  $b-user$b &amp;lt;handle&amp;gt; [anotherhandle] ...
    Removes the specified handles user records.
  
-See also: +user%{+ai}, -bot%{-}%{+nai}, newleaf%{-}
+See also: +user%{+ai}, -bot%{-}%{+ni}, newleaf%{-}%{+a}, newhub%{-}
 ::about:
 ###  $babout$b
    If you feel you are missing from the list feel free to contact bryan.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -235,7 +235,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: -ban, +ban, console%{+m|m}, chanset, chaninfo%{-}, stick, unstick
    one. You can also specify a bot, and attempt to boot someone from another
    bot on the botnet. You cannot boot a bot owner.
 :hub:botcmd:
-###  $bbotcmd$b &amp;lt;bot&amp;gt; &amp;lt;cmd&amp;gt; [params]
+###  $bbotcmd$b &amp;lt;bot|*|?|&amp;amp;&amp;gt; [%%group] &amp;lt;cmd&amp;gt; [params]
    The specified cmd and optional parameters are executed on the specified bot, 
    all results are displayed back on DCC. For example:
      [19:29] #bryan# botcmd wtest whom ...
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -253,6 +253,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: -ban, +ban, console%{+m|m}, chanset, chaninfo%{-}, stick, unstick
  
    Just using '?' for 'bot' will choose a random leaf bot.
    Just using '&amp;amp;' for 'bot' will do the cmd on all localhub bots. (first bot in config).
+   Use '%%group' to match a specific group. (see also: '%dhelp set')
  
    This cmd cannot be chained over the botnet, ie, no: '%dbotcmd [bot] botcmd [bot2] ...'
  
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -261,15 +262,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: -ban, +ban, console%{+m|m}, chanset, chaninfo%{-}, stick, unstick
      bl -&amp;gt; botcmd ?
  
 See also: cmdpass
-::botjoin
-###  $bbotjoin$b &amp;lt;bot&amp;gt; &amp;lt;channel&amp;gt; [options]
-   Adds a channel to the bot's channel list. If options are specified, the 
-   channel will be configured with the options.
- 
-   $bTHIS CMD IS CURRENTLY EXPERIMENTAL AND WILL NOT ACTUALLY SAVE STATE$b
-   $bMEANING, ALL BOTS WILL JOIN EVENTUALLY AFTER DOING BOTJOIN$b
- 
-See also: botpart, +chan, -chan, chanset, chaninfo
 :hub:botjump:
 ###  $bbotjump$b &amp;lt;bot&amp;gt; [server [port [pass]]]
    Makes the bot jump to another server. If you don't specify a
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -291,13 +283,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: msg%{+n}
    The specified bot will display its current nick over DCC.
  
 See also: netnick, nick
-::botpart
-###  $bbotpart$b &amp;lt;bot&amp;gt; &amp;lt;channel&amp;gt;
-   Removes bot from the specified channel
- 
-See also: botjoin, +chan, -chan, chanset, chaninfo
 :hub:bots
-###  $bbots$b [nodename]
+###  $bbots$b [nodename|%group]
    Shows the list of bots currently on the botnet.
    Example:
       Bots: cEvin, ruthie, Killa1
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -305,9 +292,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: botjoin, +chan, -chan, chanset, chaninfo
    bot. %{+n}Use $b'%dwho'$b or $b'%dbottree'$b for that information.%{-}
  
    Specifying a nodename will display all bots up/down on that nodename.
-   Bots with a * preceding its name ares down.
+   Bots with a * preceding its name are down.
+   Specifying a %%group will only show bots in that group.
  
-See also: downbots%{+n}, bottree%{-}
+See also: groups, downbots%{+n}, bottree%{-}
 :hub:botserver:
 ###  $bbotserver$b &amp;lt;bot&amp;gt;
    The bot will display its current server and lag over DCC.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -338,7 +326,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: set
    Red: localhubs (first bot in binary, see '%dhelp conf')
    Other: normal leaf bots
  
-See also: bots, downbots
+See also: bots, downbots, groups
 ::botversion:
 ###  $bbotversion$b &amp;lt;bot&amp;gt;
    The bot will display its pack version and uname.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -354,13 +342,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: version, netversion, about%{+m|m}, status%{-}
    and update all bots instead.
 %{-}
  
-See also: link
+See also: link%{+a}, newhub%{-}
 ::chaninfo
 ###  $bchaninfo$b &amp;lt;channel&amp;gt;
    This lists all the settings for the bot on the given channel.
    It shows any of the following:
-        $bchanmode$b   These modes are enforced on the channel. Both + and -
-                   modes can be enforced.
+        $bchanmode$b         These modes are enforced on the channel.
+                          Both + and - modes can be enforced. Use {} to
+                          add a key. '%dchanset #chan chanmode { +nt key }'
+        $bgroups$b            List of groups that should join the channel.
+                          Use {} to add multiple groups. See also '%dhelp set'
+                          '%dchanset #chan groups { main alt }'
 %{+m|m}
         $bauto-delay$b        Amount of seconds to wait before auto opping,
                               or auto voicing a client based on flags or
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -377,6 +369,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: link
                           enforce +p as well. The point is to notice the chan
                           and bots when an /invite is done. This is useful in 
                           seeing when a shell is hijacked ;)
+        $bcaps-limit$b        If this is set, any +f bots will kick a client for using
+                          too many caps. This is a percentage (0-100) of how much of
+                          their message can be caps before being kicked.
+        $bcolor-limit$b       If this is set, any +f bot will kick the client for
+                          excess color codes. The setting is how many color/bold
+                          character codes the message may contain before being kicked.
         $bban-time$b          Set here how long temporary bans will last (in
                           minutes). If you set this setting to 0, the bot will
                           never remove them. (This also requires +dynamicbans)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -416,9 +414,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: link
                               None/0         Stick to regular checking (+x)
                               Op/1           Ops are exempt from flood checks
                               Voice/2        Voices are exempt from flood checks
+        $bclosed-exempt$b     Should clients be exempt from +closed kicks based
+                              on their channel status?
+                              Valid values are:
+                              None/0         Stick to regular user checking (+o)
+                              Op/1           Ops are exempt from +closed kicks
+                              Voice/2        Voices are exempt from +closed kicks
  
         $bflood-lock-time$b   How long in seconds to keep the channel locked
                          during drone floods.
+        $bfish-key$b          The key to use for FiSH encryption. Use '{ key }'
+                          to set and '{}' to unset.
  
         $binvite-time$b       Set here how long temporary invites will last (in
                           minutes). If you set this setting to 0, the bot will
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -431,18 +437,23 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: link
                           channel is +protect.
         $bvoice-non-ident$b   If channel is +voice, clients without an ident will 
                           be voiced. Set to 0 to not voice clients without ident.
+        $bvoice-moderate$b    If channel is +voice, auto set +m and devoice flooders
+                          instead of kicking them. Set to 0 to disable.
  
    The following options choose how to respond to specific events.
         Each can be set as any of the specified options.
         ignore/0           Ignore
-        deop/1             Deop (chattr +d)
-        kick/2             Kick (chattr +k)
+        deop/1             Chattr user +d (deop)
+        kick/2             Chattr user +k (auto kickban)
         delete/remove/3    Remove user
-      
+        react/4            React and punish the client, but don't add or modify
+                             their user flags.
+   These events trigger the bot to react with the above option.
       $bbad-cookie$b             Missing or invalid cookie in bot op line.
-      $bmanop$b                  Users who op manually.
-      $bmdop$b                   Users who mass deop.
-      $bmop$b                    Users who mass op in a -mop chan.
+      $bmanop$b                  Manual op.
+      $bmdop$b                   Mass deop.
+      $bmop$b                    Mass op.
+      $brevenge$b                Client kicking/banning/deopping another bot.
  
    The following can be set + or - (e.g. '%dchanset #channel -enforcebans')
         $bautoop$b         Bots that are +y will auto-op all users with 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -465,7 +476,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: link
                        more secure and the chances of someone hijacking the bot
                        for ops in your channel are much less. This is
                        highly recommeneded to always be set.
-                       
+        $bfloodban$b   If a channel flood (public, notice or ctcp) is detected, the
+                       flooder will also be banned, in accordance with ban-type.
         $binactive$b       This prevents the bot from joining the channel (or
                        makes it leave the channel if it is already there). It
                        can be useful to make the bot leave a channel without
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -476,9 +488,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: link
                        the bot from fighting with services such as ChanServ, or
                        from kicking IRCops when setting channel modes without
                        having ops.
-        $bnomassjoin$b     If more than 6 clients join in 1 second, set +im
-                           for 2 minutes. (Could be triggered from net-split
-                           rejoin if clients hop servers and change nicks)
         $bprivate$b        This by far is probably the single most unique and
                        important feature of this pack. With this set, users with
                        global +o will not implicitly have access to the channel.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -499,11 +508,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: link
         $btake$b           Once a bot is opped, it will mass op all other bots
                        in the channel. After that, they will all attempt to 
                        mass deop in hopes 'taking' the channel. :)
-        $bvoice$b          This feature is somewhat experimental. With it set
-                       the +y bot will voice ALL people who join the channel
-                       unless they are +q globally or +q for the channel.
-                       If a botnet master devoices them, they will remain 
-                       devoiced no matter who voices them.
+        $bvoice$b          With this set, the +y bot will voice ALL clients
+                       that join the channel, whether they are a user or not.
+                       It will still keep +q|q users devoiced. Any client
+                       devoiced by a user op (+o) will remain devoiced even
+                       if they cycle. See also: 'voice-non-ident' and
+                       'voice-moderate'
         $bvoicebitch$b     Enforce voices in a +bitch style. Only +v users
                        will be allowed to be voiced. This does take +private
                        into mind as well.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -543,6 +553,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: link
         $bflood-chan$b  Set here how many channel messages in how many seconds
                     from one host constitutes a flood. Setting this to 0 or 0:0
                     disables text flood protection for the channel.
+        $bflood-bytes$b  Set here how many bytes in how many seconds from one
+                    host constitutes a flood. Setting this to 0 or 0:0
+                    disables text flood protection for the channel.
         $bflood-ctcp$b  Set here how many channel ctcps in how many seconds from
                     one host constitutes a flood. Setting this to 0 or 0:0
                     disables ctcp flood protection for the channel.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -558,8 +571,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: link
         $bflood-nick$b   Set here how many nick changes in how many seconds from
                     one host constitutes a flood. Setting this to 0 or 0:0
                     disables nick flood protection for the channel.
+   The following settings will trigger a lockdown (chanmode +mi) for 'flood-lock-time'
+   seconds. Unlike the other flood-* settings, these will trigger on $bmultiple$b clients.
+   They are for catching mass floods.
         $bflood-mjoin$b  Set how many joins in how many seconds before triggering
-                    a lockdown for mass join. ($bnomassjoin$b must be set).
+                    a lockdown for mass join. Setting this to 0 or 0:0 disables mass
+                    join protection for the channel.
+        $bflood-mchan$b  Set here how many channel messages in how many seconds
+                    from any host constitutes a flood. Setting this to 0 or 0:0
+                    disables text flood protection for the channel.
+        $bflood-mbytes$b  Set here how many bytes in how many seconds from any
+                    host constitutes a flood. Setting this to 0 or 0:0
+                    disables text flood protection for the channel.
+        $bflood-mctcp$b  Set here how many channel ctcps in how many seconds from
+                    any host constitutes a flood. Setting this to 0 or 0:0
+                    disables ctcp flood protection for the channel.
    These can all be changed simultaneously with $bflood-*$b
  
 See also: %{-}%{+n}+chan, -chan%{-}%{+m|m}, chanset%{-}
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -592,13 +618,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: %{-}%{+n}+chan, -chan%{-}%{+m|m}, chanset%{-}
  
 See also: status, whois
 ::channels:
-###  $bchannels$b %{+m}[user]%{-}
+###  $bchannels$b %{+m}[user|%group]%{-}
    Displays channels that you have access to, and any important 
    flags that are set on them.
 %{+m}
    Masters: You can specify other users to see what channels their 
             flags grant them access to.%{-}
-See also: whois%{+m}, chattr, chaninfo%{-}
+   Special %%group to see what channels a particular group is in.
+See also: whois%{+m}, chattr, chaninfo, groups%{-}
 ::chanset
 ###  $bchanset$b [#&amp;amp;!+channel|*|default] &amp;lt;settings&amp;gt;
    Allows you to change the channel settings (see $b'chaninfo'$b for the
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -649,8 +676,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: whois
 :hub:checkchannels
 ###  $bcheckchannels$b
    This will make all leaf bots display which channels they are currently
-   not in but *should* be in.  This command will not show channels which
-   the bot is not active in due to '$bbotpart$b'.
+   not in but *should* be in.  This will only shows channels that contain
+   the groups the bot are in.
  
 See also: botcmd, channels, channel, status
 :hub:chhandle
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -775,7 +802,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: console, echo, login, page, strip
                if you change any of the following: 
     $bhomedir$b, $bbinpath$b, $bbinname$b, $bportmin$b, $bportmax$b
  
-See also: newleaf
+See also: newleaf, newhub
 ::console:
 ###  $bconsole$b [channel] [modes]
    Changes your console level so that you will see only the types of console
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -964,7 +991,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: cycle
    Example:
       Down bots: cEvin, ruthie, Killa1
  
-See also: bots
+See also: bots, groups
 :leaf:dump
 ###  $bdump$b &amp;lt;text&amp;gt;
    dumps the text to the server.  keep in mind that this bot doesn't
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1061,6 +1088,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: -exempt, +exempt, console%{+m|m}, chanset, chaninfo%{-}, stick, unstic
    specified, your console channel is used.
  
 See also: console, channels%{+m}, status%{-}
+:hub:groups
+###  $bgroups$b [bot]
+   Shows the list of groups and which bots are in them.
+
+   Specify a bot to only show which groups it is in.
+ 
+See also: bots, downbots%{+n}, bottree%{-}
 ::handle
 ###  $bhandle$b &amp;lt;new-handle&amp;gt;
    Changes your handle on the bot. This is the handle (nickname) that the
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1191,6 +1225,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: console, invite
    Jumping servers ALWAYS makes the bot lose ops! be careful!
  
 See also: botjump, servers, botserver
+:leaf:keyx
+### $bkeyx$b &amp;lt;nick&amp;gt;
+    Initiaite DH1080 key-exchange with nick for FiSH protocol.
+ 
+%{+m}See also: setkey%{-}
 :leaf:kick
 ###  $bkick$b [channel|*] &amp;lt;nickname&amp;gt; [reason]
    Will kick a user off your current console channel (or specified
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1243,7 +1282,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: netlag
    Attempts to link to another hub.  This command is deprecated and not 
    recommended for use.
  
-See also: unlink, newleaf%{+a}, -bot%{-}
+See also: unlink%{+ni}, newleaf%{-}%{+a}, newhub, -bot%{-}
 ::login
 ###  $blogin$b &amp;lt;banner|bots|channels|whom&amp;gt; [on/off]
    Sets various login options.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1307,7 +1346,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: randstring, sha1, sha256, hash, encrypt, encrypt_fish, decrypt, decryp
    Performs an action on the party line. This appears as "* bryan is leaving",
    etc.
 :leaf:mmode:
-###  $bmmode$b &amp;lt;(+|-)MODE&amp;gt; &amp;lt;#channel&amp;gt; &amp;lt;a|o|v|d|r&amp;gt; [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [simul] [local]
+###  $bmmode$b &amp;lt;(+|-)MODE&amp;gt; &amp;lt;#channel&amp;gt; &amp;lt;a|o|v|d|r&amp;gt; [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [botbitch] [simul] [local]
    For those of us who do not wish to be rocket scientists in the mass mode department, 
    a simple '%dmmode -o #channel o' will suffice.
  
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1325,6 +1364,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: randstring, sha1, sha256, hash, encrypt, encrypt_fish, decrypt, decryp
      $br$b = $bregulars (-ov).$b
  
      $bbitch$b   - set +bitch after finished with mmode.
+     $bbotbitch$b - set +bitch after finished with mmode.
      $bsimul$b   - Simulates the mmode. IE: Gives you a practice run, will show who 
                    does what in the dcc chat window.
      $blocal$b   - Modes will not be distributed: Ran on local bot only.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1427,6 +1467,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: botversion, version, about%{+m|m}, status%{-}
    the results over DCC.
  
 See also: w
+:hub:newhub:
+###  $bnewhub$b &amp;lt;handle&amp;gt; &amp;lt;address&amp;gt; &amp;lt;port&amp;gt; [hublevel]
+    Add a new hub to the net.
+ 
+See also: chaddr, newleaf
 :hub:newleaf:
 ###  $bnewleaf$b &amp;lt;handle&amp;gt; [hostmask] [anotherhostmask] ...
    Adds a new leaf to the botnet with the specified handle and hostname.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1434,6 +1479,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: w
  
    The binary config botline will also be outputted, but should be
    checked for correctness.
+ 
+%{+a}See also: newhub%{-}
 ::newpass
 ###  $bnewpass$b &amp;lt;password|rand&amp;gt;
    Changes your password on the bot. This is similar to the '/msg &amp;lt;bot&amp;gt; pass'
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1514,7 +1561,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: restart
    The local bot must, however, have a bot record for the bot you wish to
    relay to. Typing '%dquit' or "*bye*" on a line by itself will end the relay.
  
-See also: bots%{+n}, newleaf%{-}%{+a}, -bot%{-}
+See also: bots%{+n}, newleaf%{-}%{+a}, newhub, -bot%{-}
 :leaf:release
 ###  $brelease$b
    Releases the bot's nick if it is on the jupenick. It gives an estimated
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1616,6 +1663,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: reload, backup
                           after the alias is expanded. 
                           $bAliases may not reference other aliases.$b
 [N]  $bserver-port$b     Default port to use for server connections.
+[N]  $bserver-port-ssl$b Default port to use for SSL server connections.
+[B]  $bserver-use-ssl$b  Use SSL for IRC server connections?
+ 
+ 
 [B]  $bauth-chan$b       If set, auth cmds will work in channels as well as in msg, otherwise 
                           only in msg.
 [S]  $bauth-key$b        The authkey used during authing. Give to users if they need to auth. 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1648,12 +1699,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: reload, backup
 [D]  $bhijack$b          How to handle when a commonly used hijack method attempt is detected. 
  
 [L]  $bservers$b         Comma-separated list of servers the bot will use.
+[L]  $bservers-ssl$b     Comma-separated list of SSL servers to use if server-use-ssl is true.
 [L]  $bservers6$b        Comma-separated list of servers the bot will use (FOR IPv6).
+[L]  $bservers6-ssl$b    Comma-separated list of IPv6 SSL servers to use if server-use-ssl is true.
  
 [N]  $bmsgburst$b        How many messages to burst at once to server. (Too high will excess flood)
 [N]  $bmsgrate$b         How often (msecs) to dequeue msgs to the server. Only used on
                            non-ratbox servers. Too small a value can result in Excess Flood.
-
+[L]  $bgroups$b          List of groups that the affected bots are a part of.
 [L]  $brbl-servers$b     Servers to use for RBL checking in channels that are +rbl.
  
 [S]  $brealname$b        The bot's "real name" when connecting. (supports '$n' expansion)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1665,6 +1718,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: reload, backup
 [B]  $bcallerid$b        Run bot in CALLERID mode. This is commonly known as +g on most
                            servers. +c bots will automatically accept messages from
                            known users. Note that this will break msg-ident.
+[B]  $bfish-auto-keyx$b  Whether to automatically do a DH1010 FiSH Key exchange when
+                           accepting users. This is only supported if using callerid.
+
+[B]  $bfish-paranoid$b   Whether to automatically re-keyexchange after every message. This
+                           mitigates replay attacks.
  
 [S]  $baltchars$b        Define string of characters to cycle when generating alternative
                           nicks when nick is taken. Ie: _-`[].
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1716,6 +1774,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: reload, backup
     '%dbotset wraith nick -'
  
 See also: botset
+:leaf:setkey
+### $bsetkey$b &amp;lt;nick&amp;gt; [key|rand]
+ 
+    Sets the FiSH key for the given target.
+    Use no key to clear the currently set key.
+    Use 'rand' to generate a random key.
+ 
+See also: keyx
 ::sha1
 ###  $bsha1$b &amp;lt;string&amp;gt;
    Returns the SHA1 hash of the specified string.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1838,6 +1904,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: die, conf, botcmd
     -Users will not see channels that are +s or +p unless they have op access there
  
 See also: find
+::tcl
+###  $btcl$b script
+   Executes the given string and returns the result.
 :leaf:topic
 ###  $btopic$b &amp;lt;text&amp;gt;
    Changes the channel's topic, assuming the bot is a chanop or the
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1874,7 +1943,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: dump
    to unlink them. If "*" is specified as the parameter, all bots will be
    unlinked.
  
-See also: %{+n}link, %{-}bots, downbots%{+n}, newleaf, bottree%{-}
+See also: %{+n}link, %{-}bots, downbots%{+n}, newleaf, bottree%{-}%{+a}, newhub%{-}
 ::unstick
 ###  $bunstick$b [ban/exempt/invite] &amp;lt;hostmask/number&amp;gt; [channel]
    Makes a "sticky" ban, exempt, or invite normal again.
diff --git a/doc/responses.txt b/doc/responses.txt
index b6a6f3a..52b295e 100755
--- a/doc/responses.txt
+++ b/doc/responses.txt
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -157,7 +157,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
  what's the rush?
  next time you do that, i'll kick you again
  and I thought you were a catcher
-:mean
+:revenge
  hey! that wasn't very nice!
  don't fuck with my pals
  don't touch my buddies like that queer
diff --git a/doc/settings.txt b/doc/settings.txt
index ae00e32..12787fd 100644
--- a/doc/settings.txt
+++ b/doc/settings.txt
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,6 +1,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 :alias
 bc botcmd
 bl botcmd ?
+gc botcmd *
 bm botmsg
 bs botset 
 op botcmd ? op
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -52,18 +53,25 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; irc.choopa.net
 irc.efnet.nl
 irc.inet.tele.dk
 irc.ipv6.homelien.no
-irc.paraphysics.net
+irc.ipv6.paraphysics.net
 irc.underworld.no
 
 :servers_ssl
 efnet.xs4all.nl
-irc.choopa.ca
-irc.choopa.net
-irc.eversible.com
+irc.choopa.ca:9999
+irc.choopa.net:9999
+irc.eversible.com:9999
 irc.paraphysics.net
-irc.servercentral.net
-irc.shoutcast.com
-irc.umich.edu
+irc.servercentral.net:9999
+irc.shoutcast.com:8000
+irc.umich.edu:9999
+irc.underworld.no
+
+:servers6_ssl
+efnet.ipv6.xs4all.nl
+irc.choopa.ca:9999
+irc.choopa.net:9999
+irc.ipv6.paraphysics.net
 irc.underworld.no
 
 :rbl
diff --git a/lib/bdlib b/lib/bdlib
index 8b67eea..dfc80a8 160000
--- a/lib/bdlib
+++ b/lib/bdlib
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1 +1 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
-Subproject commit 8b67eea164bf2869a393b1ec7aa78208c460799e
+Subproject commit dfc80a8a59cb7f903473a7008cc584ed6384befc
diff --git a/src/.gitignore b/src/.gitignore
index e7ec4c6..f93a970 100644
--- a/src/.gitignore
+++ b/src/.gitignore
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,11 +1,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 /Makefile
 /buildinfo.h
+/*.c.real
 /_*.c
 /*~
 /help.h
 /response.h
 /responses.h
 /.deps
+/.defs
 /stringfix
 /makehelp
 /sorthelp
diff --git a/src/Makefile.in b/src/Makefile.in
index c54508f..bdfc4f6 100755
--- a/src/Makefile.in
+++ b/src/Makefile.in
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4,13 +4,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; SHELL = &amp;lt; at &amp;gt;SHELL&amp;lt; at &amp;gt;
 top_srcdir = &amp;lt; at &amp;gt;top_srcdir&amp;lt; at &amp;gt;
 srcdir = &amp;lt; at &amp;gt;srcdir&amp;lt; at &amp;gt;
 VPATH = &amp;lt; at &amp;gt;srcdir&amp;lt; at &amp;gt;
-depcomp = /bin/sh $(top_srcdir)/autotools/depcomp
 
 &amp;lt; at &amp;gt;SET_MAKE&amp;lt; at &amp;gt;
 
-CXXFLAGS = &amp;lt; at &amp;gt;CXXFLAGS&amp;lt; at &amp;gt; -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_srcdir)/pack &amp;lt; at &amp;gt;DEFS&amp;lt; at &amp;gt; $(CFLGS) '-DCOMMIT="$(COMMIT)"' '-DBRANCH="$(BRANCH)"' -DBUILDTS=$(BUILDTS) '-DVERSION="$(VERSION)"'
+CXXFLAGS = &amp;lt; at &amp;gt;CXXFLAGS&amp;lt; at &amp;gt; -I. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_srcdir)/pack &amp;lt; at &amp;gt;DEFS&amp;lt; at &amp;gt; $(INCLUDES) $(CFLGS) '-DCOMMIT="$(COMMIT)"' '-DBRANCH="$(BRANCH)"' -DBUILDTS=$(BUILDTS) '-DVERSION="$(VERSION)"'
 CPPFLAGS = &amp;lt; at &amp;gt;CPPFLAGS&amp;lt; at &amp;gt;
 
+depcomp = /bin/sh $(top_srcdir)/build/autotools/depcomp
+
 OBJCOPY = &amp;lt; at &amp;gt;OBJCOPY&amp;lt; at &amp;gt;
 
 OBJS = auth.o \
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -29,17 +30,22 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; OBJS = auth.o \
 dcc.o \
 dccutil.o \
 debug.o \
+dl.o \
 egg_timer.o \
 enclink.o \
 EncryptedStream.o \
 flags.o \
 garble.o \
+libcrypto.o \
+libssl.o \
+libtcl.o \
 log.o \
 main.o \
 match.o \
 misc.o \
 misc_file.o \
 net.o \
+openssl.o \
 adns.o \
 response.o \
 rfc1459.o \
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -70,25 +76,25 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; blah:
 
 makeres: makeres.c ../lib/bdlib/src/libbdlib.a
 &amp;lt; at &amp;gt;echo -e "Compiling: \033[1mmakeres\033[0m"
-&amp;lt; at &amp;gt;$(CXX) $(CXXFLAGS) -I$(top_srcdir) -I$(top_srcdir)/pack $(CPPFLAGS) makeres.c ../lib/bdlib/src/libbdlib.a -o makeres
+&amp;lt; at &amp;gt;$(CXX) $(CXXFLAGS) -I$(top_srcdir)/src -I$(top_srcdir)/pack $(CPPFLAGS) makeres.c ../lib/bdlib/src/libbdlib.a -o makeres
 &amp;lt; at &amp;gt;$(STRIP) makeres&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt;
 
 makeset: makeset.c ../lib/bdlib/src/libbdlib.a
 &amp;lt; at &amp;gt;echo -e "Compiling: \033[1mmakeset\033[0m"
-&amp;lt; at &amp;gt;$(CXX) $(CXXFLAGS) -I$(top_srcdir) -I$(top_srcdir)/pack $(CPPFLAGS) makeset.c ../lib/bdlib/src/libbdlib.a -o makeset
+&amp;lt; at &amp;gt;$(CXX) $(CXXFLAGS) -I$(top_srcdir)/src -I$(top_srcdir)/pack $(CPPFLAGS) makeset.c ../lib/bdlib/src/libbdlib.a -o makeset
 &amp;lt; at &amp;gt;$(STRIP) makeset&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt;
 
 makehelp: makehelp.c ../lib/bdlib/src/libbdlib.a
 &amp;lt; at &amp;gt;echo -e "Compiling: \033[1mmakehelp\033[0m"
-&amp;lt; at &amp;gt;$(CXX) $(CXXFLAGS) -I$(top_srcdir) -I$(top_srcdir)/pack $(CPPFLAGS) makehelp.c ../lib/bdlib/src/libbdlib.a -o makehelp
+&amp;lt; at &amp;gt;$(CXX) $(CXXFLAGS) -I$(top_srcdir)/src -I$(top_srcdir)/pack $(CPPFLAGS) makehelp.c ../lib/bdlib/src/libbdlib.a -o makehelp
 &amp;lt; at &amp;gt;$(STRIP) makehelp&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt;
 
 sorthelp: sorthelp.c ../lib/bdlib/src/libbdlib.a
 &amp;lt; at &amp;gt;echo -e "Compiling: \033[1msorthelp\033[0m"
-&amp;lt; at &amp;gt;$(CXX) $(CXXFLAGS) -I$(top_srcdir) -I$(top_srcdir)/pack $(CPPFLAGS) sorthelp.c ../lib/bdlib/src/libbdlib.a -o sorthelp
+&amp;lt; at &amp;gt;$(CXX) $(CXXFLAGS) -I$(top_srcdir)/src -I$(top_srcdir)/pack $(CPPFLAGS) sorthelp.c ../lib/bdlib/src/libbdlib.a -o sorthelp
 &amp;lt; at &amp;gt;$(STRIP) sorthelp&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt;
 
-stringfix: stringfix.c common.h ../config.h eggdrop.h
+stringfix: stringfix.c common.h config.h eggdrop.h
 &amp;lt; at &amp;gt;echo -e "Compiling: \033[1mstringfix\033[0m"
 &amp;lt; at &amp;gt;$(CXX) $(CXXFLAGS) -I$(top_srcdir) -I$(top_srcdir)/pack $(CPPFLAGS) stringfix.c -o stringfix
 &amp;lt; at &amp;gt;$(STRIP) stringfix&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -124,14 +130,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; mycrypto:
 
 include ./.deps/includes
 
-.SUFFIXES:
-.SUFFIXES: .c .h .o
-
-.c.o: stringfix
-&amp;lt; at &amp;gt;echo -e "Compiling: \033[1m`basename $&amp;lt; .c`\033[0m"
-&amp;lt; at &amp;gt;./stringfix&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt; $&amp;lt; _$&amp;lt; || cp -f $&amp;lt; _$&amp;lt;
-source='$&amp;lt;' object='$&amp;lt; at &amp;gt;' depfile='.deps/$*.Po' tmpdepfile='.deps/$*.TPo' depmode=$(CCDEPMODE) $(depcomp) \
-$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c _$&amp;lt;  -o `basename $&amp;lt; .c`.o
-
-#safety hash
-
+%.o: %.c stringfix&amp;lt; at &amp;gt;EXEEXT&amp;lt; at &amp;gt; $(top_srcdir)/build/cc1plus
+&amp;lt; at &amp;gt;echo -e "Compiling: \033[1m$*\033[0m"
+ifeq ($(CCDEPMODE),gcc3)
+if STRINGFIX='$(top_srcdir)/$(STRINGFIX)' $(CXX) -MT '$&amp;lt; at &amp;gt;' -MD -MP -MF '.deps/$*.TPo' -DSTRINGFIX=$(STRINGFIX) -B$(top_srcdir)/build $(CXXFLAGS) $(CPPFLAGS) -c $&amp;lt; -o $&amp;lt; at &amp;gt;; then \
+mv '.deps/$*.TPo' '.deps/$*.Po'; \
+else rm -f '.deps/$*.Tpo'; exit 1; \
+fi
+else
+# STRINGFIX included after CXX for ccache to recognize
+STRINGFIX="$(top_srcdir)/$(STRINGFIX)" libtool=no source='$&amp;lt;' object='$&amp;lt; at &amp;gt;' depfile='.deps/$*.Po' tmpdepfile='.deps/$*.TPo' depmode=$(CCDEPMODE) $(depcomp) \
+$(CXX) -DSTRINGFIX=$(STRINGFIX) -B$(top_srcdir)/build $(CXXFLAGS) $(CPPFLAGS) -c $&amp;lt; -o $&amp;lt; at &amp;gt;
+endif
diff --git a/src/binary.c b/src/binary.c
index 67b3bfb..8c5de68 100755
--- a/src/binary.c
+++ b/src/binary.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -38,6 +38,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include "botnet.h"
 #include "net.h"
 #include "userrec.h"
+#include &amp;lt;bdlib/src/Array.h&amp;gt;
+#include &amp;lt;bdlib/src/String.h&amp;gt;
 
 #include &amp;lt;sys/wait.h&amp;gt;
 #include &amp;lt;sys/types.h&amp;gt;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -50,9 +52,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 settings_t settings = {
   SETTINGS_HEADER,
   /* -- STATIC -- */
-  "", "", "", "", "", "", "", "", "",
+  "", "", "", "", "", "", "", "", "", "",
   /* -- DYNAMIC -- */
-  "", "", "", "", "", "", "", "", "",
+  "", "", "", "", "", "", "", "", "", "",
   /* -- PADDING */
   ""
 };
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -431,6 +433,33 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; readcfg(const char *cfgfile, bool read_stdin)
   return 1;
 }
 
+void writecfg() {
+  const char salt1[] = SALT1;
+  const char salt2[] = SALT2;
+  bd::Array&amp;lt;bd::String&amp;gt; owners(bd::String(settings.owners).split(","));
+  bd::Array&amp;lt;bd::String&amp;gt; hubs(bd::String(settings.hubs).split(","));
+
+  printf("PACKNAME %s\n", settings.packname);
+  // Display the shellhash as salted-sha1 if it is not already
+  bd::String shellhash(settings.shellhash);
+  printf("BINARYPASS %s\n", (shellhash.length() == 40 || shellhash.length() == 47) ? shellhash.c_str() : salted_sha1(shellhash.c_str()));
+  printf("DCCPREFIX %s\n", settings.dcc_prefix);
+  for (size_t i = 0; i &amp;lt; owners.length(); ++i) {
+    bd::Array&amp;lt;bd::String&amp;gt; ownerInfo(static_cast&amp;lt;bd::String&amp;gt;(owners[i]).split(" "));
+    // Ensure the pass is salted-sha1
+    const size_t ownerPassLength = static_cast&amp;lt;bd::String&amp;gt;(ownerInfo[1]).length();
+    if (ownerPassLength != 40 &amp;amp;&amp;amp; ownerPassLength != 47) {
+      ownerInfo[1] = bd::String(salted_sha1(static_cast&amp;lt;bd::String&amp;gt;(ownerInfo[1]).c_str()));
+    }
+    printf("OWNER %s\n", ownerInfo.join(" ").c_str());
+  }
+  for (size_t i = 0; i &amp;lt; hubs.length(); ++i) {
+    printf("HUB %s\n", static_cast&amp;lt;bd::String&amp;gt;(hubs[i]).c_str());
+  }
+  printf("SALT1 %s\n", salt1);
+  printf("SALT2 %s\n", salt2);
+}
+
 static void edpack(settings_t *incfg, const char *in_hash, int what)
 {
   char *tmp = NULL, *hash = (char *) in_hash, nhash[51] = "";
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -490,6 +519,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void edpack(settings_t *incfg, const char *in_hash, int what)
 
   /* -- DYNAMIC -- */
   dofield(incfg-&amp;gt;dynamic_initialized);
+  dofield(incfg-&amp;gt;conf_hubs);
   dofield(incfg-&amp;gt;bots);
   dofield(incfg-&amp;gt;uid);
   dofield(incfg-&amp;gt;autocron);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -523,6 +553,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; tellconfig(settings_t *incfg)
 //  dofield(incfg-&amp;gt;salt2);
   // -- DYNAMIC --
   dofield(incfg-&amp;gt;dynamic_initialized);
+  dofield(incfg-&amp;gt;conf_hubs);
   dofield(incfg-&amp;gt;bots);
   dofield(incfg-&amp;gt;uid);
   dofield(incfg-&amp;gt;autocron);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -699,6 +730,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void conf_to_bin(conf_t *in, bool move, int die)
                            bot-&amp;gt;net.ip6 ? bot-&amp;gt;net.ip6 : "");
     }
 
+  simple_snprintf(settings.conf_hubs, sizeof(settings.conf_hubs), in-&amp;gt;hubs.join(',').c_str());
+
   newbin = binname;
 //  tellconfig(&amp;amp;settings); 
   write_settings(newbin, -1, 1);
diff --git a/src/binary.h b/src/binary.h
index 7c25d22..2baefef 100755
--- a/src/binary.h
+++ b/src/binary.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -17,4 +17,5 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int check_bin_initialized(const char *fname);
 bool check_bin_compat(const char *fname);
 void conf_to_bin(conf_t *, bool, int);
 void reload_bin_data();
+void writecfg();
 #endif /* !_BINARY_H */
diff --git a/src/botcmd.c b/src/botcmd.c
index 4773fbc..a52c97e 100755
--- a/src/botcmd.c
+++ b/src/botcmd.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -47,6 +47,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include "chan.h"
 #include "core_binds.h"
 #include "egg_timer.h"
+#include "shell.h"
 
 static char TBUF[1024] = "";/* Static buffer for goofy bot stuff */
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1367,11 +1368,32 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void bot_rd(char* botnick, char* code, char* msg)
   }
 }
 
+static void bot_suicide(char* botnick, char* code, char* msg)
+{
+  conf_bot *bot = NULL;
+  bool valid_source = 0;
+
+  for (bot = conf.bots; bot &amp;amp;&amp;amp; bot-&amp;gt;nick; bot = bot-&amp;gt;next) {
+    if (!strcmp(botnick, bot-&amp;gt;nick)) {
+      valid_source = 1;
+      break;
+    }
+  }
+
+  if (!valid_source) {
+    putlog(LOG_WARN, "*", STR("AN INVALID BOT (%s) JUST SENT ME A SUICIDE REQUEST!"), botnick);
+    return;
+  }
+
+  suicide(msg);
+}
+
 static cmd_t my_bot[] = 
 {
   {"rd","",(Function) bot_rd,NULL, 0},
   {"r-sr","",(Function) bot_rsimr,NULL, HUB},
   {"r-s","",(Function) bot_rsim,NULL, 0},
+  {"suicide","",(Function) bot_suicide,NULL, 0},
   {NULL, NULL, NULL, NULL, 0}
 };
 
diff --git a/src/botmsg.c b/src/botmsg.c
index 59d4326..cbb20b6 100755
--- a/src/botmsg.c
+++ b/src/botmsg.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -299,7 +299,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void putallbots(const char *par)
   return;
 }
 
-void putbot(const char *bot, char *par)
+void putbot(const char *bot, const char *par)
 {
   if (!bot || !par || !bot[0] || !par[0])
     return;
diff --git a/src/botmsg.h b/src/botmsg.h
index 8fb7912..19513c5 100755
--- a/src/botmsg.h
+++ b/src/botmsg.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -10,7 +10,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 void botnet_send_var(int idx, variable_t *);
 void botnet_send_var_broad(int idx, variable_t *);
-void putbot(const char *, char *);
+void putbot(const char *, const char *);
 void putallbots(const char *);
 int add_note(char *, char *, char *, int, int);
 
diff --git a/src/botnet.c b/src/botnet.c
index 0d59728..b837b7b 100755
--- a/src/botnet.c
+++ b/src/botnet.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -49,6 +49,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include "core_binds.h"
 #include &amp;lt;bdlib/src/String.h&amp;gt;
 #include &amp;lt;bdlib/src/Array.h&amp;gt;
+#include &amp;lt;algorithm&amp;gt;
 
 tand_t*tandbot = NULL;/* Keep track of tandem bots on the
    botnet */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -522,65 +523,100 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void answer_local_whom(int idx, int chan)
   dprintf(idx, "Total users: %d\n", total);
 }
 
+bool sortNodes(const bd::String nodeA, const bd::String nodeB) {
+  const bd::String unknown("(unknown)");
+  if (nodeA == unknown) {
+    return true;
+  } else if (nodeB == unknown) {
+    return false;
+  }
+  // Reverse the domains
+  const bd::Array&amp;lt;bd::String&amp;gt; partsA(nodeA.split("."));
+  const bd::Array&amp;lt;bd::String&amp;gt; partsB(nodeB.split("."));
+  bd::Array&amp;lt;bd::String&amp;gt; reversedPartsA, reversedPartsB;
+  bd::String reversedNodeA, reversedNodeB;
+
+  if (partsA.length()) {
+    for (size_t i = partsA.length() - 1; i &amp;gt; 0; --i) {
+      reversedPartsA &amp;lt;&amp;lt; partsA[i - 1];
+    }
+  }
+  if (partsB.length()) {
+    for (size_t i = partsB.length() - 1; i &amp;gt; 0; --i) {
+      reversedPartsB &amp;lt;&amp;lt; partsB[i - 1];
+    }
+  }
+  reversedNodeA = reversedPartsA.join(".");
+  reversedNodeB = reversedPartsB.join(".");
+  return reversedNodeA &amp;lt; reversedNodeB;
+}
+
 /* Show z a list of all bots connected
  */
 void
 tell_bots(int idx, int up, const char *nodename)
 {
-  struct userrec *u = NULL;
-  int cnt = 0, tot = 0, total = 1, mtot = 0;
-  char work[151] = "", *node = NULL;
-
-  if (up) {
-    if (nodename)
-      node = (char *) get_user(&amp;amp;USERENTRY_NODENAME, conf.bot-&amp;gt;u);    
-    if (!nodename || wild_match(nodename, node)) {
-      strlcat(work, conf.bot-&amp;gt;nick, sizeof(work));
-      strlcat(work, " ", sizeof(work));
-      cnt++;
-      tot++;
-      if (nodename)
-        mtot++;
-    }
+  size_t total = 0, maxNodeNameLength = 0;;
+  bd::Array&amp;lt;bd::String&amp;gt; nodes;
+  bd::HashTable&amp;lt;bd::String, bd::Array&amp;lt;bd::String&amp;gt; &amp;gt; nodeBots;
+  bd::Array&amp;lt;bd::String&amp;gt; bots;
+  bd::String group;
+
+  if (nodename &amp;amp;&amp;amp; nodename[0] == '%') {
+    group = nodename + 1;
   }
 
-  for (u = userlist; u; u = u-&amp;gt;next) {
+  // Gather a list of nodes and bots per node, as well as per domain
+  for (struct userrec* u = userlist; u; u = u-&amp;gt;next) {
     if (u-&amp;gt;bot) {
-      if (strcasecmp(u-&amp;gt;handle, conf.bot-&amp;gt;nick)) {
-        bool found = 0;
+      // If looking for groups, exclude hubs
+      if (group.length() &amp;amp;&amp;amp; bot_hublevel(u) != 999) {
+        continue;
+      }
+      ++total;
+      bd::String botnick(u-&amp;gt;handle);
+      const bd::Array&amp;lt;bd::String&amp;gt; botgroups((bd::String(var_get_bot_data(u, "groups", true))).split(","));
         
-        if (findbot(u-&amp;gt;handle))
-          found = 1;
-        total++;
-        if (nodename || (!nodename &amp;amp;&amp;amp; ((!up &amp;amp;&amp;amp; !found) || (up &amp;amp;&amp;amp; found)))) {
-          if (nodename)
-            node = (char *) get_user(&amp;amp;USERENTRY_NODENAME, u);
-          if (!nodename || wild_match(nodename, node)) {
-            if (nodename &amp;amp;&amp;amp; !found)
-              strlcat(work, "*", sizeof(work));
-            strlcat(work, u-&amp;gt;handle, sizeof(work));
-            cnt++;
-            if (nodename)
-              mtot++;
-            if (!nodename || (nodename &amp;amp;&amp;amp; found))
-              tot++;
-            if (cnt == 11) {
-              dprintf(idx, "%s bots: %s\n", nodename ? "Matching" : up ? "Up" : "Down", work);
-              work[0] = 0;
-              cnt = 0;
-            } else {
-              strlcat(work, " ", sizeof(work));
+      // Include this bot?
+      const bool group_match = group.length() &amp;amp;&amp;amp; botgroups.find(group) != botgroups.npos;
+      const char *userNode = (const char*) get_user(&amp;amp;USERENTRY_NODENAME, u);
+      const bd::String node(userNode ? userNode : "(unknown)");
+      const bool node_match = ((nodename &amp;amp;&amp;amp; node.length() &amp;amp;&amp;amp; wild_match(nodename, node.c_str())) || !nodename);
+      const bool bot_found = u == conf.bot-&amp;gt;u || findbot(u-&amp;gt;handle);
+      const bool up_down_match = (nodename || (!nodename &amp;amp;&amp;amp; ((up &amp;amp;&amp;amp; bot_found) || (!up &amp;amp;&amp;amp; !bot_found))));
+      if (group_match || (group.length() == 0 &amp;amp;&amp;amp; node_match &amp;amp;&amp;amp; up_down_match)) {
+        if (nodes.find(node) == nodes.npos) {
+          nodes &amp;lt;&amp;lt; node;
+          if (node.length() &amp;gt; maxNodeNameLength) {
+            maxNodeNameLength = node.length();
+          }
             }
+        if ((group.length() || nodename) &amp;amp;&amp;amp; !bot_found) {
+          botnick = '*' + botnick;
           }
+        nodeBots[node] &amp;lt;&amp;lt; botnick;
+        bots &amp;lt;&amp;lt; botnick;
         }
       }
     }
+
+  if (group.length() == 0 &amp;amp;&amp;amp; !nodename) {
+    dumplots(idx, nodename ? "Matching: " : (up ? "Up: " : "Down: "), static_cast&amp;lt;bd::String&amp;gt;(bots.join(" ")).c_str());
+  } else {
+    // Sort by nodes
+    std::sort(nodes.begin(), nodes.end(), sortNodes);
+    for (size_t i = 0; i &amp;lt; nodes.length(); ++i) {
+      const bd::String node(nodes[i]);
+      const bd::Array&amp;lt;bd::String&amp;gt; botsInNode(nodeBots[node]);
+      dumplots(idx, bd::String::printf("%*s: ", int(maxNodeNameLength), node.c_str()).c_str(), static_cast&amp;lt;bd::String&amp;gt;(botsInNode.join(" ")).c_str());
+    }
+  }
+
+  if (nodename || group.length()) {
+    dprintf(idx, "(Total Matching: %zu/%zu)\n", bots.length(), total);
+  } else {
+    dprintf(idx, "(Total %s: %zu/%zu)\n", up ? "up" : "down", bots.length(), total);
   }
-  if (work[0])
-    dprintf(idx, "%s bot%s: %s\n", nodename ? "Matching" : up ? "Up" : "Down", cnt &amp;gt; 1 ? "s" : "", work);
-  if (nodename)
-    dprintf(idx, "(Total Matching: %d/%d)\n", mtot, total);
-  dprintf(idx, "(Total %s: %d/%d)\n", nodename ? "up" : up ? "up" : "down", tot, nodename ? mtot : total);
 }
 
 /* Show a simpleton bot tree
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -985,7 +1021,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int botlink(char *linker, int idx, char *nick)
       correct_handle(nick);
 
       char *address = NULL;
-      port_t port = 0;
+      in_port_t port = 0;
 
       if (unix_domain) {
         address = conf.localhub_socket;
diff --git a/src/chan.h b/src/chan.h
index 6390aa0..19deb31 100755
--- a/src/chan.h
+++ b/src/chan.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -8,6 +8,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #ifndef _EGG_CHAN_H
 #define _EGG_CHAN_H
 
+#include &amp;lt;lib/bdlib/src/Array.h&amp;gt;
+#include &amp;lt;lib/bdlib/src/String.h&amp;gt;
+
 typedef struct memstruct {
   struct memstruct *next;
   struct userrec *user;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -21,9 +24,26 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct memstruct {
   char nick[NICKLEN];
   char userhost[UHOSTLEN];
   char userip[UHOSTLEN];
+  char from[NICKLEN + UHOSTLEN];   /* nick!user&amp;lt; at &amp;gt;host */
+  char fromip[NICKLEN + UHOSTLEN]; /* nick!user&amp;lt; at &amp;gt;ip */
   bool is_me;
+  bd::HashTable&amp;lt;flood_t, time_t&amp;gt;     *floodtime; // floodtime[FLOOD_PRIVMSG] = now;
+  bd::HashTable&amp;lt;flood_t, int&amp;gt;         *floodnum; // floodnum[FLOOD_PRIVMSG] = 1;
 } memberlist;
 
+#include &amp;lt;bdlib/src/bdlib.h&amp;gt;
+BDLIB_NS_BEGIN
+template&amp;lt;typename T&amp;gt;
+  struct Hash;
+
+template&amp;lt;&amp;gt;
+  struct Hash&amp;lt;memberlist*&amp;gt;
+  {
+    // Use memory address
+    inline size_t operator()(memberlist* m) const { return reinterpret_cast&amp;lt;size_t&amp;gt;(m); }
+  };
+BDLIB_NS_END
+
 #define CHAN_FLAG_OP1
 #define CHAN_FLAG_VOICE 2
 #define CHAN_FLAG_USER 3
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -58,10 +78,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct memstruct {
 #define chan_wasop(x) (x-&amp;gt;flags &amp;amp; WASOP)
 #define chan_stopcheck(x) (x-&amp;gt;flags &amp;amp; STOPCHECK)
 
-#define P_IGNORE0
-#define P_DEOP1
-#define P_KICK2
-#define P_DELETE3
+enum deflag_t {
+  DEFLAG_IGNORE = 0,
+  DEFLAG_DEOP = 1,
+  DEFLAG_KICK = 2,
+  DEFLAG_DELETE = 3,
+  DEFLAG_REACT = 4,
+};
 
 /* Why duplicate this struct for exempts and invites only under another
  * name? &amp;lt;cybah&amp;gt;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -114,6 +137,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct chan_t {
   char *topic;
   char *key;
   unsigned short int mode;
+
+  // Shared non-member counts (JOIN/PART)
+  bd::HashTable&amp;lt;bd::String, bd::HashTable&amp;lt;flood_t, time_t&amp;gt; &amp;gt;     *floodtime; // floodtime[uhost][FLOOD_PRIVMSG] = now;
+  bd::HashTable&amp;lt;bd::String, bd::HashTable&amp;lt;flood_t, int&amp;gt; &amp;gt;         *floodnum; //  floodnum[uhost][FLOOD_PRIVMSG] = 1;
+
+  // Member caching to cache cyclers
+  bd::HashTable&amp;lt;bd::String, memberlist*&amp;gt; *cached_members;
 };
 
 #define CHANINV    BIT0/* +i*/
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -150,11 +180,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct chanset_t {
     char *op;
   } ccmode[MODES_PER_LINE_MAX];                 /* parameter-type mode changes -        */
   /* detect floods */
-  time_t floodtime[FLOOD_CHAN_MAX];
   uint32_t status;
   uint32_t ircnet_status;
   int flood_pub_thr;
   interval_t flood_pub_time;
+  int flood_mpub_thr;
+  interval_t flood_mpub_time;
+  int flood_bytes_thr;
+  interval_t flood_bytes_time;
+  int flood_mbytes_thr;
+  interval_t flood_mbytes_time;
   int flood_join_thr;
   interval_t flood_join_time;
   int flood_deop_thr;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -163,20 +198,27 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct chanset_t {
   interval_t flood_kick_time;
   int flood_ctcp_thr;
   interval_t flood_ctcp_time;
+  int flood_mctcp_thr;
+  interval_t flood_mctcp_time;
   int flood_nick_thr;
   interval_t flood_nick_time;
   interval_t flood_lock_time;
   interval_t flood_mjoin_time;
   int flood_mjoin_thr;
   int limitraise;
+  int capslimit;
+  int colorlimit;
   int checklimit;
   int closed_ban;
   int closed_private;
   int closed_invite;
-  int bad_cookie;
-  int manop;
-  int mdop;
-  int mop;
+  int closed_exempt_mode;
+  int voice_moderate;
+  deflag_t bad_cookie;
+  deflag_t manop;
+  deflag_t mdop;
+  deflag_t mop;
+  deflag_t revenge;
   int voice_non_ident;
   int ban_type;
   interval_t auto_delay;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -186,9 +228,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct chanset_t {
  *int temp;
  */
   int flood_exempt_mode;
-#ifdef REVENGE
-  int revenge_mode;
-#endif
   interval_t ban_time;
   interval_t invite_time;
   interval_t exempt_time;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -202,7 +241,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct chanset_t {
   size_t bytes;/* total bytes so far*/
   size_t cbytes;
   int compat;/* to prevent mixing old/new modes*/
-  int floodnum[FLOOD_CHAN_MAX];
   int opreqtime[5];             /* remember when ops was requested */
 
   char *key;/* new key to set*/
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -210,13 +248,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct chanset_t {
   char pls[21];/* positive mode changes*/
   char mns[21];/* negative mode changes*/
   char key_prot[121];/* desired password*/
+  bd::Array&amp;lt;bd::String&amp;gt; *groups;/* groups that should join */
+  char fish_key[50];
 /* Chanchar template
  *char temp[121];
  */
   char topic[121];
   char added_by[HANDLEN + 1];/* who added the channel? */
-  char floodwho[FLOOD_CHAN_MAX][128];
-  char deopd[NICKLEN];/* last person deop'd (must change*/
   char dname[81];               /* what the users know the channel as like !eggdev */
   char name[81];                /* what the servers know the channel as, like !ABCDEeggdev */
 };
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -241,7 +279,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct chanset_t {
 #define CHAN_CYCLE          BIT11/* cycle the channel if possible      */
 #define CHAN_INACTIVE       BIT12/* no irc support for this channel */
 #define CHAN_VOICE          BIT13/* a bot +y|y will voice *, except +q */
-#define CHAN_NOMASSJOIN     BIT14       /* watch for mass join for flood nets and react */
+//#define CHAN_NOMASSJOIN     BIT14       /* watch for mass join for flood nets and react */
 #define CHAN_NODESYNCH      BIT15
 #define CHAN_FASTOP         BIT16/* Bots will not use +o-b to op (no cookies) */ 
 #define CHAN_PRIVATE        BIT17/* users need |o to access chan */ 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -253,6 +291,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct chanset_t {
 #define CHAN_AUTOOP         BIT23
 #define CHAN_MEANKICKS      BIT24/* use mean/offensive kicks/bans */
 #define CHAN_VOICEBITCH     BIT25
+#define CHAN_FLOODBAN       BIT26
 
 #define CHAN_ASKED_EXEMPTS  BIT0
 #define CHAN_ASKED_INVITES  BIT1
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -266,7 +305,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct chanset_t {
 #define CHAN_STOP_CYCLE     BIT9/* Some efnetservers have defined NO_CHANOPS_WHEN_SPLIT */
 
 /* prototypes */
-memberlist *ismember(struct chanset_t *, const char *);
+memberlist *ismember(const struct chanset_t *, const char *);
 struct chanset_t *findchan(const char *name);
 struct chanset_t *findchan_by_dname(const char *name);
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -288,6 +327,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct chanset_t *findchan_by_dname(const char *name);
 #define channel_backup(chan) (chan-&amp;gt;status &amp;amp; CHAN_BACKUP)
 #define channel_bitch(chan) (chan-&amp;gt;status &amp;amp; CHAN_BITCH)
 #define chan_bitch(chan) (chan-&amp;gt;status &amp;amp; (CHAN_BITCH|CHAN_BOTBITCH))
+#define channel_floodban(chan) (chan-&amp;gt;status &amp;amp; CHAN_FLOODBAN)
 #define channel_botbitch(chan) (chan-&amp;gt;status &amp;amp; CHAN_BOTBITCH)
 #define channel_nodesynch(chan) (chan-&amp;gt;status &amp;amp; CHAN_NODESYNCH)
 #define channel_enforcebans(chan) (chan-&amp;gt;status &amp;amp; CHAN_ENFORCEBANS)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -297,19 +337,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct chanset_t *findchan_by_dname(const char *name);
 #define channel_cycle(chan) (chan-&amp;gt;status &amp;amp; CHAN_CYCLE)
 #define channel_inactive(chan) (chan-&amp;gt;status &amp;amp; CHAN_INACTIVE)
 
-
-#ifdef REVENGE
-#define channel_revenge(chan) (chan-&amp;gt;status &amp;amp; CHAN_REVENGE)
-#define channel_revengebot(chan) (chan-&amp;gt;status &amp;amp; CHAN_REVENGEBOT)
-#endif 
-
 #define channel_closed(chan) (chan-&amp;gt;status &amp;amp; CHAN_CLOSED)
 #define channel_take(chan) (chan-&amp;gt;status &amp;amp; CHAN_TAKE)
 #define channel_voice(chan) (chan-&amp;gt;status &amp;amp; CHAN_VOICE)
 #define channel_fastop(chan) (chan-&amp;gt;status &amp;amp; CHAN_FASTOP)
 #define channel_privchan(chan) (chan-&amp;gt;status &amp;amp; CHAN_PRIVATE)
 #define channel_autoop(chan) (chan-&amp;gt;status &amp;amp; CHAN_AUTOOP)
-#define channel_nomassjoin(chan) (chan-&amp;gt;status &amp;amp; CHAN_NOMASSJOIN)
 #define channel_meankicks(chan) (chan-&amp;gt;status &amp;amp; CHAN_MEANKICKS)
 #define channel_rbl(chan) (chan-&amp;gt;status &amp;amp; CHAN_RBL)
 #define channel_voicebitch(chan) (chan-&amp;gt;status &amp;amp; CHAN_VOICEBITCH)
diff --git a/src/chanprog.c b/src/chanprog.c
index 6c28014..a311f7b 100755
--- a/src/chanprog.c
+++ b/src/chanprog.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -22,7 +22,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
  * chanprog.c -- handles:
  *   rmspace()
  *   maintaining the server list
- *   revenge punishment
  *   timers, utimers
  *   telling the current programmed settings
  *   initializing a lot of stuff and loading the tcl scripts
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -45,6 +44,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include "userrec.h"
 #include "main.h"
 #include "debug.h"
+#include "set.h"
 #include "dccutil.h"
 #include "botmsg.h"
 #if HAVE_GETRUSAGE
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -54,8 +54,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #endif
 #endif
 #include &amp;lt;sys/utsname.h&amp;gt;
+#include &amp;lt;bdlib/src/Array.h&amp;gt;
+#include &amp;lt;bdlib/src/String.h&amp;gt;
 
-char *def_chanset = "+enforcebans +dynamicbans +userbans -bitch +cycle -inactive +userexempts -dynamicexempts +userinvites -dynamicinvites -nodesynch -closed -take -voice -private -fastop +meankicks ban-type 3 protect-backup 1";
+char *def_chanset = "+enforcebans +dynamicbans +userbans -bitch +cycle -inactive +userexempts -dynamicexempts +userinvites -dynamicinvites -nodesynch -closed -take -voice -private -fastop +meankicks ban-type 3 protect-backup 1 groups { main } revenge react";
 struct chanset_t *chanset = NULL;/* Channel list*/
 struct chanset_t*chanset_default = NULL;/* Default channel list */
 char admin[121] = "";/* Admin info*/
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -63,7 +65,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; charorigbotnick[HANDLEN + 1] = "";/* from -B (placed into conf.bot-&amp;gt;nick ..
 char origbotname[NICKLEN] = "";/* Nick to regain */
 char                    jupenick[NICKLEN] = "";
 char botname[NICKLEN] = "";/* IRC nickname */
-port_t     my_port = 0;
+in_port_t     my_port = 0;
 intreset_chans = 0;
 bool                    cookies_disabled = 0;
 char s2_4[3] = "",s1_6[3] = "",s1_11[3] = "";
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -92,7 +94,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void rmspace(char *s)
 
 /* Returns memberfields if the nick is in the member list.
  */
-memberlist *ismember(struct chanset_t *chan, const char *nick)
+memberlist *ismember(const struct chanset_t *chan, const char *nick)
 {
   register memberlist*x = NULL;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -382,81 +384,48 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void reaffirm_owners()
 }
 
 bool is_hub(const char* nick) {
-  char *p = settings.hubs, *p2 = NULL, hubbuf[HANDLEN + 1] ="";
-  size_t len = 0;
-
-  while (p &amp;amp;&amp;amp; *p) {
-    if ((p2 = strchr(p, ' '))) {
-
-      len = p2 - p + 1;
-      if (len &amp;gt; sizeof(hubbuf))
-        len = sizeof(hubbuf);
-      strlcpy(hubbuf, p, len);
-      if (!strncasecmp(nick, hubbuf, HANDLEN))
-        return 1;
+  for (size_t idx = 0; idx &amp;lt; conf.hubs.length(); ++idx) {
+    bd::String hub(conf.hubs[idx]);
+    if (!strncasecmp(nick, newsplit(hub).c_str(), HANDLEN)) {
+      return true;
     }
-    if ((p = strchr(p, ',')))
-      p++;
   }
-  return 0;
+  return false;
 }
 
 void load_internal_users()
 {
-  char *p = NULL, *ln = NULL, *hand = NULL, *ip = NULL, *port = NULL, *pass = NULL, *q = NULL;
+  char *p = NULL, *ln = NULL, *hand = NULL, *pass = NULL, *q = NULL;
   char *hosts = NULL, buf[2048] = "", tmp[51] = "";
-  int i, hublevel = 0;
-  struct bot_addr *bi = NULL;
+  int i;
   struct userrec *u = NULL;
 
   /* hubs */
-  strlcpy(buf, settings.hubs, sizeof(buf));
-  p = buf;
-  while (p) {
-    ln = p;
-    p = strchr(p, ',');
-    if (p)
-      *p++ = 0;
-    hand = ln;
-    ip = NULL;
-    port = NULL;
-    u = NULL;
-    for (i = 0; ln; i++) {
-      switch (i) {
-        case 0:
-          hand = ln;
-          break;
-        case 1:
-          ip = ln;
-          break;
-        case 2:
-          port = ln;
-          hublevel++;/* We must increment this even if it is already added */
-          if (!get_user_by_handle(userlist, hand)) {
-            userlist = adduser(userlist, hand, "none", "-", USER_OP, 1);
-            u = get_user_by_handle(userlist, hand);
+  for (size_t idx = 0; idx &amp;lt; conf.hubs.length(); ++idx) {
+    bd::Array&amp;lt;bd::String&amp;gt; params(static_cast&amp;lt;bd::String&amp;gt;(conf.hubs[idx]).split(' '));
+    bd::String handle(params[0]);
+    if (!get_user_by_handle(userlist, const_cast&amp;lt;char*&amp;gt;(handle.c_str()))) {
+      bd::String address(params[1]);
+      in_port_t port = atoi(static_cast&amp;lt;bd::String&amp;gt;(params[2]).c_str());
+      unsigned short hublevel = params.length() == 4 ? atoi(static_cast&amp;lt;bd::String&amp;gt;(params[3]).c_str()) : (idx + 1);
+
+      userlist = adduser(userlist, handle.c_str(), "none", "-", USER_OP, 1);
+      u = get_user_by_handle(userlist, const_cast&amp;lt;char*&amp;gt;(handle.c_str()));
 
             simple_snprintf(tmp, sizeof(tmp), "%li [internal]", (long)now);
             set_user(&amp;amp;USERENTRY_ADDED, u, tmp);
 
-            bi = (struct bot_addr *) my_calloc(1, sizeof(struct bot_addr));
+      struct bot_addr *bi = (struct bot_addr *) my_calloc(1, sizeof(struct bot_addr));
 
-            bi-&amp;gt;address = strdup(ip);
-            bi-&amp;gt;telnet_port = atoi(port) ? atoi(port) : 0;
-            bi-&amp;gt;relay_port = bi-&amp;gt;telnet_port;
+      bi-&amp;gt;address = strdup(address.c_str());
+      bi-&amp;gt;telnet_port = bi-&amp;gt;relay_port = port;
             bi-&amp;gt;hublevel = hublevel;
-            if (conf.bot-&amp;gt;hub &amp;amp;&amp;amp; (!bi-&amp;gt;hublevel) &amp;amp;&amp;amp; (!strcasecmp(hand, conf.bot-&amp;gt;nick)))
+      if (conf.bot-&amp;gt;hub &amp;amp;&amp;amp; (!bi-&amp;gt;hublevel) &amp;amp;&amp;amp; (!strcasecmp(handle.c_str(), conf.bot-&amp;gt;nick))) {
               bi-&amp;gt;hublevel = 99;
+      }
             bi-&amp;gt;uplink = (char *) my_calloc(1, 1);
             set_user(&amp;amp;USERENTRY_BOTADDR, u, bi);
-            /* set_user(&amp;amp;USERENTRY_PASS, get_user_by_handle(userlist, hand), SALT2); */
-          }
-          break;
-        default:
-          break;
-      }
-      if (ln &amp;amp;&amp;amp; (ln = strchr(ln, ' ')))
-        *ln++ = 0;
+      /* set_user(&amp;amp;USERENTRY_PASS, get_user_by_handle(userlist, handle.c_str()), SALT2); */
     }
   }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -605,7 +574,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void rehash_ip() {
     }
     if (!listening) {
       // Listen on the unix domain socket
-      port_t port;
+      in_port_t port;
       int i = open_listen_addr_by_af(conf.localhub_socket, &amp;amp;port, AF_UNIX);
       if (i &amp;lt; 0) {
         putlog(LOG_ERRORS, "*", "Can't listen on %s - %s", conf.localhub_socket, i == -1 ? "it's taken." : "couldn't assign file.");
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -773,69 +742,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int isowner(char *name)
   }
 }
 
-/* this method is slow, but is only called when sharing and adding/removing chans */
-
-int 
-botshouldjoin(struct userrec *u, struct chanset_t *chan)
-{
-  /* just return 1 for now */
-  return 1;
-/*
-  char *chans = NULL;
-  struct userrec *u = NULL;
- 
-  u = get_user_by_handle(userlist, bot);
-  if (!u)
-    return;
-  chans = get_user(&amp;amp;USERENTRY_CHANS, u);
-*/
-}
-/* future use ?
-void
-chans_addbot(const char *bot, struct chanset_t *chan)
-{
-  char *chans = NULL;
-  struct userrec *u = NULL;
- 
-  u = get_user_by_handle(userlist, bot);
-  if (!u)
-    return;
-  chans = get_user(&amp;amp;USERENTRY_CHANS, u);
-  if (!botshouldjoin(u, chan)) {
-    size_t size;
-    char *buf = NULL;
-   
-    size = strlen(chans) + strlen(chan-&amp;gt;dname) + 2;
-    buf = (char *) my_calloc(1, size);
-    simple_snprintf(buf, size, "%s %s", chans, chan-&amp;gt;dname);
-    set_user(&amp;amp;USERENTRY_CHANS, u, buf);
-    free(buf);
-  }
-}
-
-void 
-chans_delbot(const char *bot, struct chanset_t *chan)
-{
-  char *chans = NULL;
-  struct userrec *u = NULL;
- 
-  u = get_user_by_handle(userlist, bot);
-  if (!u)
-    return;
- 
-  if (botshouldjoin(u, chan)) {
-    char *chans = NULL, *buf = NULL;
-    size_t size;
-
-    chans = get_user(&amp;amp;USERENTRY_CHANS, u);
-    size = strlen(chans) - strlen(chan-&amp;gt;dname) + 2;
-
-    
-  }
-}
-*/
-
-bool bot_shouldjoin(struct userrec* u, struct flag_record* fr, struct chanset_t* chan, bool ignore_inactive)
+bool bot_shouldjoin(struct userrec* u, struct flag_record* fr, const struct chanset_t* chan, bool ignore_inactive)
 {
   // If restarting, keep this channel.
   if (restarting &amp;amp;&amp;amp; (reset_chans == 2) &amp;amp;&amp;amp; (channel_active(chan) || channel_pending(chan))) return 1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -845,24 +752,29 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; bool bot_shouldjoin(struct userrec* u, struct flag_record* fr, struct chanset_t*
   // No user record, can't make any safe assumptions really
   if (!u) return 0;
 
-#ifdef DEBUG
-  /* Force debugging bots to only join 3 channels */
-  if (!strncmp(u-&amp;gt;handle, "wtest", 5)) {
-    if (!strcmp(chan-&amp;gt;dname, "#skynet") || 
-        !strcmp(chan-&amp;gt;dname, "#bryan") || 
-        !strcmp(chan-&amp;gt;dname, "#wraith"))
-      return 1;
-    else
-      return 0;
+  // Is this bot in the groups that this channel has?
+  const char *botgroups = u == conf.bot-&amp;gt;u ? groups : var_get_bot_data(u, "groups", true);
+  bd::Array&amp;lt;bd::String&amp;gt; my_groupsArray(bd::String(botgroups).split(','));
+  bool group_match = 0;
+
+  if (chan-&amp;gt;groups &amp;amp;&amp;amp; chan-&amp;gt;groups-&amp;gt;length()) {
+    for (size_t i = 0; i &amp;lt; my_groupsArray.length(); ++i) {
+      if (chan-&amp;gt;groups-&amp;gt;find(my_groupsArray[i]) != chan-&amp;gt;groups-&amp;gt;npos) {
+        group_match = 1;
+        break;
   }
-#endif
+    }
+  }
+
   // Ignore +inactive during cmd_slowjoin to ensure that +backup bots join
-  return (!glob_kick(*fr) &amp;amp;&amp;amp; !chan_kick(*fr) &amp;amp;&amp;amp;
-      ((ignore_inactive || !channel_inactive(chan)) &amp;amp;&amp;amp;
-       (channel_backup(chan) || (!glob_backup(*fr) &amp;amp;&amp;amp; !chan_backup(*fr)))));
+  return (!glob_kick(*fr) &amp;amp;&amp;amp; !chan_kick(*fr) &amp;amp;&amp;amp; // Not being kicked
+      ((ignore_inactive || !channel_inactive(chan)) &amp;amp;&amp;amp; // Not inactive
+      ((channel_backup(chan) &amp;amp;&amp;amp; (glob_backup(*fr) || chan_backup(*fr) || group_match)) || // Is +backup and I'm a backup bot or my group matches
+       (!channel_backup(chan) &amp;amp;&amp;amp; !glob_backup(*fr) &amp;amp;&amp;amp; !chan_backup(*fr) &amp;amp;&amp;amp; group_match))) // is -backup and I am not a backup bot and my group matches
+      );
 }
 
-bool shouldjoin(struct chanset_t *chan)
+bool shouldjoin(const struct chanset_t *chan)
 {
   struct flag_record fr = { FR_CHAN|FR_GLOBAL|FR_BOT, 0, 0, 0 };
   get_user_flagrec(conf.bot-&amp;gt;u, &amp;amp;fr, chan-&amp;gt;dname, chan);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -953,32 +865,99 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; samechans(const char *nick, const char *delim)
   return ret;
 }
 
-struct chanset_t* find_common_opped_chan(const char* nick) {
+struct chanset_t* find_common_opped_chan(bd::String nick) {
   for (struct chanset_t* chan = chanset; chan; chan = chan-&amp;gt;next) {
     if (channel_active(chan) &amp;amp;&amp;amp; (me_op(chan) || me_voice(chan))) {
-      if (ismember(chan, nick))
+      if (ismember(chan, nick.c_str()))
         return chan;
     }
   }
   return NULL;
 }
 
-void privmsg(const char* target, const char* msg, int idx) {
+void privmsg(bd::String target, bd::String msg, int idx) {
   struct chanset_t* chan = NULL;
-  if (have_cprivmsg &amp;amp;&amp;amp; !strchr(CHANMETA, target[0]))
+  bool talking_to_chan = strchr(CHANMETA, target[0]);
+  if (have_cprivmsg &amp;amp;&amp;amp; !talking_to_chan)
     chan = find_common_opped_chan(target);
+  bool cleartextPrefix = (msg(0, 3) == "+p ");
+
+  // Encrypt with FiSH?
+  if (!cleartextPrefix &amp;amp;&amp;amp; FishKeys.contains(target) &amp;amp;&amp;amp; FishKeys[target]-&amp;gt;sharedKey.length()) {
+    msg = "+OK " + egg_bf_encrypt(msg, FishKeys[target]-&amp;gt;sharedKey);
+  }
+
+  if (cleartextPrefix) {
+    msg += static_cast&amp;lt;size_t&amp;gt;(3);
+  }
+
   if (chan)
-    dprintf(idx, "CPRIVMSG %s %s :%s\n", target, chan-&amp;gt;name, msg);
+    dprintf(idx, "CPRIVMSG %s %s :%s\n", target.c_str(), chan-&amp;gt;name, msg.c_str());
   else
-    dprintf(idx, "PRIVMSG %s :%s\n", target, msg);
+    dprintf(idx, "PRIVMSG %s :%s\n", target.c_str(), msg.c_str());
 }
 
-void notice(const char* target, const char* msg, int idx) {
+void notice(bd::String target, bd::String msg, int idx) {
   struct chanset_t* chan = NULL;
-  if (have_cnotice &amp;amp;&amp;amp; !strchr(CHANMETA, target[0]))
+  bool talking_to_chan = strchr(CHANMETA, target[0]);
+  if (have_cnotice &amp;amp;&amp;amp; !talking_to_chan)
     chan = find_common_opped_chan(target);
+  bool cleartextPrefix = (msg(0, 3) == "+p ");
+
+  if (!cleartextPrefix &amp;amp;&amp;amp; FishKeys.contains(target) &amp;amp;&amp;amp; FishKeys[target]-&amp;gt;sharedKey.length()) {
+    msg = "+OK " + egg_bf_encrypt(msg, FishKeys[target]-&amp;gt;sharedKey);
+  }
+
+  if (cleartextPrefix) {
+    msg += static_cast&amp;lt;size_t&amp;gt;(3);
+  }
+
   if (chan)
-    dprintf(idx, "CNOTICE %s %s :%s\n", target, chan-&amp;gt;name, msg);
+    dprintf(idx, "CNOTICE %s %s :%s\n", target.c_str(), chan-&amp;gt;name, msg.c_str());
   else
-    dprintf(idx, "NOTICE %s :%s\n", target, msg);
+    dprintf(idx, "NOTICE %s :%s\n", target.c_str(), msg.c_str());
+}
+
+
+void keyx(const bd::String &amp;amp;target) {
+  bd::String myPublicKeyB64, myPrivateKey, sharedKey;
+
+  DH1080_gen(myPrivateKey, myPublicKeyB64);
+
+  fish_data_t* fishData = FishKeys.contains(target) ? FishKeys[target] : new fish_data_t;
+  fishData-&amp;gt;sharedKey.clear();
+  putlog(LOG_MSGS, "*", "[FiSH] Initiating DH1080 key-exchange with %s - sending my public key", target.c_str());
+  notice(target, "DH1080_INIT " + myPublicKeyB64, DP_HELP);
+  fishData-&amp;gt;myPublicKeyB64 = myPublicKeyB64;
+  fishData-&amp;gt;myPrivateKey = myPrivateKey;
+  fishData-&amp;gt;key_created_at = now;
+  FishKeys[target] = fishData;
+}
+
+void set_fish_key(char *target, bd::String key)
+{
+  fish_data_t* fishData = FishKeys.contains(target) ? FishKeys[target] : NULL;
+
+  if (!key.length()) { //remove key
+    if (fishData) {
+      FishKeys.remove(target);
+      delete fishData;
+    }
+  } else { //set key
+    fishData = new fish_data_t;
+
+    if (key == "rand") {
+      // Set a RANDOM key
+      const size_t randomKeyLength = 32;
+      char *rand_key = (char*)my_calloc(1, randomKeyLength+1);
+      make_rand_str(rand_key, randomKeyLength);
+      fishData-&amp;gt;sharedKey = rand_key;
+      free(rand_key);
+    } else {
+      fishData-&amp;gt;sharedKey = key;
+    }
+
+    // Set the key
+    FishKeys[target] = fishData;
+  }
 }
diff --git a/src/chanprog.h b/src/chanprog.h
index 913819d..d4831d3 100755
--- a/src/chanprog.h
+++ b/src/chanprog.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -23,21 +23,22 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void rmspace(char *s);
 void set_chanlist(const char *host, struct userrec *rec);
 void clear_chanlist(void);
 void clear_chanlist_member(const char *nick);
-int botshouldjoin(struct userrec *u, struct chanset_t *);
-bool bot_shouldjoin(struct userrec* , struct flag_record *, struct chanset_t *, bool = 0);
-bool shouldjoin(struct chanset_t *);
+bool bot_shouldjoin(struct userrec* , struct flag_record *, const struct chanset_t *, bool = 0);
+bool shouldjoin(const struct chanset_t *);
 char *samechans(const char *, const char *);
 void add_myself_to_userlist();
 void add_child_bots();
 bool is_hub(const char*);
 void load_internal_users();
 void setup_HQ(int);
-void privmsg(const char* target, const char* msg, int idx);
-void notice(const char* target, const char* msg, int idx);
+void privmsg(bd::String target, bd::String msg, int idx);
+void notice(bd::String target, bd::String msg, int idx);
+void keyx(const bd::String&amp;amp; target);
+void set_fish_key(char *, bd::String);
 
 extern struct chanset_t*chanset, *chanset_default;
 extern charadmin[], origbotnick[HANDLEN + 1], origbotname[NICKLEN], jupenick[NICKLEN], botname[NICKLEN], *def_chanset;
-extern port_tmy_port;
+extern in_port_tmy_port;
 extern intreset_chans;
 extern boolcookies_disabled;
 
diff --git a/src/cmds.c b/src/cmds.c
index 20aa60a..93b4e40 100755
--- a/src/cmds.c
+++ b/src/cmds.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -57,6 +57,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include "socket.h"
 #include "traffic.h" /* egg_traffic_t */
 #include "core_binds.h"
+#include "libtcl.h"
 #include "src/mod/console.mod/console.h"
 #include "src/mod/server.mod/server.h"
 #include "src/mod/irc.mod/irc.h"
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -900,23 +901,85 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_userlist(int idx, char *par)
   return;
 }
 
+static void cmd_groups(int idx, char *par)
+{
+  struct userrec *u = NULL;
+
+  putlog(LOG_CMDS, "*", "#%s# groups %s", dcc[idx].nick, par);
+  bd::String botnick(newsplit(&amp;amp;par));
+
+  if (botnick.length() &amp;amp;&amp;amp; !(u = get_user_by_handle(userlist, botnick.c_str()))) {
+    dprintf(idx, "No such bot.\n");
+    return;
+  }
+
+  if (u &amp;amp;&amp;amp; !u-&amp;gt;bot) {
+    dprintf(idx, "%s is not a bot.\n", botnick.c_str());
+    return;
+  }
+
+  bd::Array&amp;lt;bd::String&amp;gt; globalgroups = bd::String(var_get_gdata("groups")).split(",");
+  bd::Array&amp;lt;bd::String&amp;gt; allgroups;
+  bd::HashTable&amp;lt;bd::String, bd::Array&amp;lt;bd::String&amp;gt; &amp;gt; groupBots;
+  bd::HashTable&amp;lt;bd::String, bd::Array&amp;lt;bd::String&amp;gt; &amp;gt; botGroups;
+  size_t maxGroupLen = 0;
+
+  // Need to loop over every bot and make a list of all groups and bots which are in those groups
+  for (u = userlist; u; u = u-&amp;gt;next) {
+    if (u-&amp;gt;bot &amp;amp;&amp;amp; bot_hublevel(u) == 999) {
+      // Gather all the groups for this bot
+      botGroups[u-&amp;gt;handle] = bd::String(var_get_bot_data(u, "groups", true)).split(",");
+      for (size_t i = 0; i &amp;lt; botGroups[u-&amp;gt;handle].length(); ++i) {
+        const bd::String group(botGroups[u-&amp;gt;handle][i]);
+        if (group.length() &amp;gt; maxGroupLen) {
+          maxGroupLen = group.length();
+        }
+        // Add their groups into the master list
+        if (allgroups.find(group) == allgroups.npos) {
+          allgroups &amp;lt;&amp;lt; group;
+        }
+        // Add them to the list for this group
+        groupBots[group] &amp;lt;&amp;lt; u-&amp;gt;handle;
+
+      }
+    }
+  }
+
+  if (botnick.length()) {
+    dprintf(idx, "%s is in groups: %s\n", botnick.c_str(), static_cast&amp;lt;bd::String&amp;gt;(botGroups[botnick].join(" ")).c_str());
+    dprintf(idx, "Total groups: %zu/%zu\n", botGroups[botnick].length(), allgroups.length());
+  } else {
+    // Display all groups and which bots are in them
+    for (size_t i = 0; i &amp;lt; allgroups.length(); ++i) {
+      const bd::String group(allgroups[i]);
+      const bd::Array&amp;lt;bd::String&amp;gt; bots(groupBots[group]);
+      dumplots(idx, bd::String::printf("%-*s: ", int(maxGroupLen), group.c_str()).c_str(), static_cast&amp;lt;bd::String&amp;gt;(bots.join(" ")).c_str());
+    }
+    dprintf(idx, "Total groups: %zu\n", allgroups.length());
+  }
+
+  return;
+}
+
 static void cmd_channels(int idx, char *par) {
   putlog(LOG_CMDS, "*", "#%s# channels %s", dcc[idx].nick, par);
   if (par[0] &amp;amp;&amp;amp; (dcc[idx].user-&amp;gt;flags &amp;amp; USER_MASTER)) {
-    struct userrec *user = NULL;
-
-    user = get_user_by_handle(userlist, par);
+    if (par[0] == '%') {
+      show_channels(idx, par);
+    } else {
+      struct userrec *user = get_user_by_handle(userlist, par);
     if (user &amp;amp;&amp;amp; whois_access(dcc[idx].user, user)) {
       show_channels(idx, par);
     } else  {
       dprintf(idx, "No such user.\n");
     }
+    }
   } else {
       show_channels(idx, NULL);
   }
 
   if ((dcc[idx].user-&amp;gt;flags &amp;amp; USER_MASTER) &amp;amp;&amp;amp; !(par &amp;amp;&amp;amp; par[0]))
-    dprintf(idx, "You can also %schannels &amp;lt;user&amp;gt;\n", (dcc[idx].u.chat-&amp;gt;channel &amp;gt;= 0) ? settings.dcc_prefix : "");
+    dprintf(idx, "You can also %schannels &amp;lt;user|%%group&amp;gt;\n", (dcc[idx].u.chat-&amp;gt;channel &amp;gt;= 0) ? settings.dcc_prefix : "");
 }
 
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1327,18 +1390,27 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_botcmd(int idx, char *par)
     return;
   }
 
-  char *botm = newsplit(&amp;amp;par), *cmd = NULL;
+  char *botm = newsplit(&amp;amp;par), *group = NULL, *cmd = NULL;
   bool rand_leaf = 0, all_localhub = 0;
   
-  if (par[0])
+  if (par[0]) {
+    // Group specified
+    if (par[0] == '%') {
+      group = newsplit(&amp;amp;par);
+      ++group;
+    }
+  }
+  if (par[0]) {
     cmd = newsplit(&amp;amp;par);
+  }
 
   if (!botm[0] || !cmd || (cmd &amp;amp;&amp;amp; !cmd[0])) {
-    dprintf(idx, "Usage: botcmd &amp;lt;bot&amp;gt; &amp;lt;cmd&amp;gt; [params]\n");
+    dprintf(idx, "Usage: botcmd &amp;lt;bot|*|?|&amp;amp;&amp;gt; [%%group] &amp;lt;cmd&amp;gt; [params]\n");
     return;
   }
 
   int cnt = 0, rleaf = -1, tbots = 0, found = 0;
+  bool group_match = false;
   tand_t *tbot = NULL;
 
   /* the rest of the cmd will be logged remotely */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1346,9 +1418,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_botcmd(int idx, char *par)
     putlog(LOG_CMDS, "*", "#%s# botcmd %s %s ...", dcc[idx].nick, botm, cmd);
 
   // Restrict dangerous mass commands ('botcmd *' (any *) or 'botcmd &amp;amp;')
-  if ((strchr(botm, '*') &amp;amp;&amp;amp; !findbot(botm)) || !strcmp(botm, "&amp;amp;")) {
+  if ((strchr(botm, '*') &amp;amp;&amp;amp; !findbot(botm)) || !strcmp(botm, "&amp;amp;") || botm[0] == '%') {
     if (!strncasecmp(cmd, "di", 2) || (!strncasecmp(cmd, "res", 3) &amp;amp;&amp;amp; strncasecmp(cmd, "reset", 5)) || !strncasecmp(cmd, "sui", 3) || !strncasecmp(cmd, "pl", 2) || !strncasecmp(cmd, "ac", 2) ||
-        !strncasecmp(cmd, "j", 1) || (!strncasecmp(cmd, "dump", 4) &amp;amp;&amp;amp; (!strncasecmp(par, "privmsg", 7) || !strncasecmp(par, "notice", 6) || !strncasecmp(par, "quit", 4)))) {
+        !strncasecmp(cmd, "j", 1) || (!strncasecmp(cmd, "dump", 4) &amp;amp;&amp;amp; (!strncasecmp(par, "privmsg", 7) || !strncasecmp(par, "notice", 6) || !strncasecmp(par, "quit", 4))) ||
+        ((!strncasecmp(cmd, "tcl", 3) || !strncasecmp(cmd, "script", 6)) &amp;amp;&amp;amp; strstr(par, "privmsg"))) {
       dprintf(idx, "Not a good idea.\n");
       return;
     } else if (strchr(botm, '*') &amp;amp;&amp;amp; !(dcc[idx].user-&amp;gt;flags &amp;amp; USER_OWNER)) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1361,9 +1434,18 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_botcmd(int idx, char *par)
   if (!strcmp(botm, "?")) {
     rand_leaf = 1;
     for (tbot = tandbot; tbot; tbot = tbot-&amp;gt;next) {
-      if (bot_hublevel(get_user_by_handle(userlist, tbot-&amp;gt;bot)) == 999)
+      if (bot_hublevel(tbot-&amp;gt;u) == 999) {
+        group_match = false;
+        if (group) {
+          group_match = bd::String(var_get_bot_data(tbot-&amp;gt;u, "groups", true)).split(',').find(group) != bd::String::npos;
+        } else {
+          group_match = true;
+        }
+        if (group_match) {
         tbots++;
     }
+      }
+    }
     if (tbots)
       rleaf = 1 + randint(tbots);/* 1 &amp;lt;--&amp;gt; tbots */
   }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1376,15 +1458,31 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_botcmd(int idx, char *par)
     }
     all_localhub = 1;
     for (tbot = tandbot; tbot; tbot = tbot-&amp;gt;next) {
-      if (bot_hublevel(get_user_by_handle(userlist, tbot-&amp;gt;bot)) == 999 &amp;amp;&amp;amp; tbot-&amp;gt;localhub)
+      if (bot_hublevel(tbot-&amp;gt;u) == 999 &amp;amp;&amp;amp; tbot-&amp;gt;localhub) {
+        group_match = false;
+        if (group) {
+          group_match = bd::String(var_get_bot_data(tbot-&amp;gt;u, "groups", true)).split(',').find(group) != bd::String::npos;
+        } else {
+          group_match = true;
+        }
+        if (group_match) {
         tbots++;
     }
   }
+    }
+  }
   
   for (tbot = tandbot; tbot; tbot = tbot-&amp;gt;next) {
-    if ((rand_leaf &amp;amp;&amp;amp; bot_hublevel(get_user_by_handle(userlist, tbot-&amp;gt;bot)) != 999) ||
-        (all_localhub &amp;amp;&amp;amp; (bot_hublevel(get_user_by_handle(userlist, tbot-&amp;gt;bot)) != 999 || !tbot-&amp;gt;localhub)))
+    if ((rand_leaf &amp;amp;&amp;amp; bot_hublevel(tbot-&amp;gt;u) != 999) ||
+        (all_localhub &amp;amp;&amp;amp; (bot_hublevel(tbot-&amp;gt;u) != 999 || !tbot-&amp;gt;localhub)))
       continue;
+    group_match = false;
+    if (group &amp;amp;&amp;amp; bot_hublevel(tbot-&amp;gt;u) == 999) {
+      group_match = bd::String(var_get_bot_data(tbot-&amp;gt;u, "groups", true)).split(',').find(group) != bd::String::npos;
+    } else if (!group) {
+      group_match = true;
+    }
+    if (group_match) {
     cnt++;
     if ((rleaf != -1 &amp;amp;&amp;amp; cnt == rleaf) || (rleaf == -1 &amp;amp;&amp;amp; (all_localhub || wild_match(botm, tbot-&amp;gt;bot)))) {
       if (rleaf != -1)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1393,6 +1491,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_botcmd(int idx, char *par)
       found++;
     }
   }
+  }
 
   /* Only wild_match when not using botm=? and strlen(conf.bot-&amp;gt;nick) &amp;gt; 1, ie dont match on hubs with 1 letter nicks */
   if ((!(strlen(conf.bot-&amp;gt;nick) == 1 &amp;amp;&amp;amp; !strcmp(botm, "?")) &amp;amp;&amp;amp; wild_match(botm, conf.bot-&amp;gt;nick)) || !strcasecmp(botm, conf.bot-&amp;gt;nick)) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1507,7 +1606,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_chaddr(int idx, char *par)
   putlog(LOG_CMDS, "*", "#%s# chaddr %s %s", dcc[idx].nick, handle, addr);
   dprintf(idx, "Changed bot's address.\n");
 
-  port_t telnet_port = 3333, relay_port = 3333;
+  in_port_t telnet_port = 3333, relay_port = 3333;
   char *p = NULL, *q = NULL;
 #ifdef USE_IPV6
   char *r = NULL;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2594,8 +2693,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_chattr(int idx, char *par)
       build_flags(work, &amp;amp;user, NULL);
       if (work[0] != '-')
         dprintf(idx, "Channel flags for %s on %s are now +%s.\n", hand, chan-&amp;gt;dname, work);
-      else
+      else {
         dprintf(idx, "No flags for %s on %s.\n", hand, chan-&amp;gt;dname);
+        del_chanrec(u2, chan-&amp;gt;dname);
+      }
     }
   }
   if (chg &amp;amp;&amp;amp; !conf.bot-&amp;gt;hub)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3249,6 +3350,68 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_newleaf(int idx, char *par)
   }
 }
 
+static void cmd_newhub(int idx, char *par)
+{
+  bd::Array&amp;lt;bd::String&amp;gt; params(bd::String(par).split(' '));
+  if (!par[0] || params.length() &amp;lt; 3) {
+    dprintf(idx, "Usage: newhub &amp;lt;handle&amp;gt; &amp;lt;address&amp;gt; &amp;lt;port&amp;gt; [hublevel]\n");
+    return;
+  }
+
+  putlog(LOG_CMDS, "*", "#%s# newhub %s", dcc[idx].nick, par);
+
+  bd::String handle(params[0]);
+
+  if (handle.length() &amp;gt; HANDLEN) {
+    handle.resize(HANDLEN);
+  }
+  if (get_user_by_handle(userlist, const_cast&amp;lt;char*&amp;gt;(handle.c_str()))) {
+    dprintf(idx, "Already got a %s hub\n", handle.c_str());
+    return;
+  } else if (strchr(BADHANDCHARS, handle[0]) != NULL) {
+    dprintf(idx, "You can't start a botnick with '%c'.\n", static_cast&amp;lt;char&amp;gt;(handle[0]));
+    return;
+  }
+
+  bd::String address(params[1]);
+  in_port_t port = atoi(static_cast&amp;lt;bd::String&amp;gt;(params[2]).c_str());
+
+  unsigned short hublevel = 0;
+  // Was a hublevel passed in?
+  if (params.length() == 4) {
+    hublevel = atoi(static_cast&amp;lt;bd::String&amp;gt;(params[3]).c_str());
+  } else {
+    // Find next available hublevel
+    for (struct userrec *u = userlist; u; u = u-&amp;gt;next) {
+      unsigned short u_bot_hublevel = bot_hublevel(u);
+      if (u-&amp;gt;bot &amp;amp;&amp;amp; u_bot_hublevel &amp;lt; 999 &amp;amp;&amp;amp; u_bot_hublevel &amp;gt; hublevel) {
+        hublevel = u_bot_hublevel;
+      }
+    }
+    ++hublevel;
+  }
+
+  struct bot_addr *bi = NULL;
+  struct userrec *u1 = NULL;
+  char tmp[81] = "";
+
+  userlist = adduser(userlist, handle.c_str(), "none", "-", USER_OP, 1);
+  u1 = get_user_by_handle(userlist, const_cast&amp;lt;char*&amp;gt;(handle.c_str()));
+  bi = (struct bot_addr *) my_calloc(1, sizeof(struct bot_addr));
+  bi-&amp;gt;uplink = (char *) my_calloc(1, 1);
+  bi-&amp;gt;address = strdup(address.c_str());
+  bi-&amp;gt;telnet_port = port;
+  bi-&amp;gt;relay_port = port;
+  bi-&amp;gt;hublevel = hublevel;
+
+  set_user(&amp;amp;USERENTRY_BOTADDR, u1, bi);
+  simple_snprintf(tmp, sizeof(tmp), "%li %s", (long) now, dcc[idx].nick);
+  set_user(&amp;amp;USERENTRY_ADDED, u1, tmp);
+  dprintf(idx, "Added new hub: %s\n", handle.c_str());
+
+  write_userfile(idx);
+}
+
 static void cmd_nopass(int idx, char *par)
 {
   int cnt = 0;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3842,10 +4005,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void rcmd_cursrv(char * fbot, char * fhand, char * fidx) {
 
     if (server_online) {
       daysdur(now, server_online, tmp, sizeof(tmp));
-      if (floodless)
-        simple_snprintf(cursrv, sizeof(cursrv), "Currently: %-30s (connected %s) [floodless ;)]", cursrvname, tmp);
-      else
-        simple_snprintf(cursrv, sizeof(cursrv), "Currently: %-30s (connected %s)", cursrvname, tmp);
+      simple_snprintf(cursrv, sizeof(cursrv), "Currently: %-30s (connected %s)%s%s", cursrvname, tmp, socklist[findanysnum(serv)].ssl ? " [SSL]" : "", floodless ? " [floodless]" : "");
 
       if (server_lag &amp;gt; 0) {
         simple_snprintf(tmp, sizeof(tmp), " Lag:%ds", server_lag);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4302,7 +4462,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void rcmd_jump(char * frombot, char * fromhand, char * fromidx, char * pa
   if (!conf.bot-&amp;gt;hub) {
     if (par[0]) {
       char *other = newsplit(&amp;amp;par), *p = NULL;
-      port_t port = atoi(newsplit(&amp;amp;par));
+      in_port_t port = atoi(newsplit(&amp;amp;par));
 
       if ((p = strchr(other, ':'))) {
         *p = 0;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4312,7 +4472,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void rcmd_jump(char * frombot, char * fromhand, char * fromidx, char * pa
       }
 
       if (!port)
-        port = default_port;
+        port = (ssl_use ? default_port_ssl : default_port);
       strlcpy(newserver, other, 120); 
       newserverport = port; 
       strlcpy(newserverpass, par, 120); 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4526,6 +4686,24 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void cmd_test(int idx, char *par)
   putlog(LOG_CMDS, "*", "#%s# test", dcc[idx].nick);
 }
 
+#ifdef USE_SCRIPT_TCL
+void cmd_tcl(int idx, char *par)
+{
+  if (!isowner(dcc[idx].nick)) {
+    dprintf(idx, "tcl is only available to permanent owners.\n");
+    return;
+  }
+
+  putlog(LOG_CMDS, "*", "#%s# tcl", dcc[idx].nick);
+
+  bd::String result(tcl_eval(par));
+  if (dcc[idx].irc &amp;amp;&amp;amp; strcmp(dcc[idx].u.chat-&amp;gt;con_chan, "*")) {
+      privmsg(dcc[idx].u.chat-&amp;gt;con_chan, tcl_eval(par), DP_SERVER);
+  } else
+    dprintf(idx, result.c_str(), DP_SERVER);
+}
+#endif
+
 void cmd_botlink(int idx, char *par)
 {
   putlog(LOG_CMDS, "*", "#%s# botlink %s", dcc[idx].nick, par);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4599,6 +4777,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; cmd_t C_dcc[] =
   {"me","",(Function) cmd_me,NULL, 0},
   {"motd","",(Function) cmd_motd,NULL, 0},
   {"newleaf","n",(Function) cmd_newleaf,NULL, HUB},
+  {"newhub","a",(Function) cmd_newhub,NULL, HUB},
   {"nopass","m",(Function) cmd_nopass,NULL, HUB},
   {"newpass","",(Function) cmd_newpass,NULL, 0},
   {"secpass","",(Function) cmd_secpass,NULL, 0},
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4642,12 +4821,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; cmd_t C_dcc[] =
   {"version", "o", (Function) cmd_version, NULL, 0},
   {"netversion", "o", (Function) cmd_netversion, NULL, HUB},
   {"userlist", "m", (Function) cmd_userlist, NULL, 0},
+  {"groups", "m", (Function) cmd_groups, NULL, HUB},
   {"ps", "n", (Function) cmd_ps, NULL, 0},
   {"last", "n", (Function) cmd_last, NULL, 0},
   {"exec", "a", (Function) cmd_exec, NULL, 0},
   {"w", "n", (Function) cmd_w, NULL, 0},
   {"channels", "", (Function) cmd_channels, NULL, 0},
   {"test","",(Function) cmd_test,NULL, 0},
+#ifdef USE_SCRIPT_TCL
+  {"tcl","a",(Function) cmd_tcl,NULL, AUTH_ALL},
+#endif
   {"botlink","a",(Function) cmd_botlink,NULL, 0},
   {"randstring", "", (Function) cmd_randstring, NULL, AUTH_ALL},
   {"hash","",(Function) cmd_hash,NULL, AUTH_ALL},
diff --git a/src/compat/Makefile.in b/src/compat/Makefile.in
index 5181c6f..266fc71 100755
--- a/src/compat/Makefile.in
+++ b/src/compat/Makefile.in
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -4,7 +4,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; SHELL = &amp;lt; at &amp;gt;SHELL&amp;lt; at &amp;gt;
 top_srcdir = &amp;lt; at &amp;gt;top_srcdir&amp;lt; at &amp;gt;
 srcdir = &amp;lt; at &amp;gt;srcdir&amp;lt; at &amp;gt;
 VPATH = &amp;lt; at &amp;gt;srcdir&amp;lt; at &amp;gt;
-depcomp = /bin/sh $(top_srcdir)/autotools/depcomp
+depcomp = /bin/sh $(top_srcdir)/build/autotools/depcomp
 
 &amp;lt; at &amp;gt;SET_MAKE&amp;lt; at &amp;gt;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -37,13 +37,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; compat: $(OBJS)
 
 include ./.deps/includes
 
-.SUFFIXES:
-.SUFFIXES: .c .o .h
-
-.c.o:
-&amp;lt; at &amp;gt;echo -e "Compiling: \033[1m`basename $&amp;lt; .c`\033[0m"
-source='$&amp;lt;' object='$&amp;lt; at &amp;gt;' depfile='.deps/$*.Po' tmpdepfile='.deps/$*.TPo' depmode=$(CCDEPMODE) $(depcomp) \
-$(CXX) $(CXXFLAGS) -I../.. -I$(top_srcdir) -I$(top_srcdir)/src $(CPPFLAGS) -c $&amp;lt; 
-
-
-#safety hash
+%.o: %.c
+&amp;lt; at &amp;gt;echo -e "Compiling: \033[1m$*\033[0m"
+ifeq ($(CCDEPMODE),gcc3)
+if $(CXX) -MT '$&amp;lt; at &amp;gt;' -MD -MP -MF '.deps/$*.TPo' $(CXXFLAGS) $(CPPFLAGS) -c $&amp;lt; -o $&amp;lt; at &amp;gt;; then \
+mv '.deps/$*.TPo' '.deps/$*.Po'; \
+else rm -f '.deps/$*.Tpo'; exit 1; \
+fi
+else
+libtool=no source='$&amp;lt;' object='$&amp;lt; at &amp;gt;' depfile='.deps/$*.Po' tmpdepfile='.deps/$*.TPo' depmode=$(CCDEPMODE) $(depcomp) \
+$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $&amp;lt; -o $&amp;lt; at &amp;gt;
+endif
diff --git a/src/conf.c b/src/conf.c
index 1f362d6..b09d14f 100755
--- a/src/conf.c
+++ b/src/conf.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -322,6 +322,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; init_conf()
 //  conf.bots-&amp;gt;next = NULL;
   conf.bots = NULL;
   conf.bot = NULL;
+  // If conf_hubs is blank, revert to pack hubs
+  if (strlen(settings.conf_hubs)) {
+    conf.hubs = bd::String(settings.conf_hubs).split(',');
+  } else {
+    conf.hubs = bd::String(settings.hubs).split(',');
+  }
 
   conf.localhub = NULL;
   conf.autocron = 1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -465,7 +471,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; conf_addbot(const char *nick, const char *ip, const char *host, const char *ip6)
 
 //  bot-&amp;gt;pid = checkpid(nick, bot);
 
-  if (settings.hubs &amp;amp;&amp;amp; is_hub(bot-&amp;gt;nick))
+  if (is_hub(bot-&amp;gt;nick))
     bot-&amp;gt;hub = 1;
 
   /* not a hub 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -536,6 +542,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; free_conf()
     free(conf.datadir);
   if (conf.homedir)
     free(conf.homedir);
+  conf.hubs.clear();
   init_conf();
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -602,9 +609,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; readconf(const char *fname, int bits)
     fatal(STR("Cannot read config"), 0);
   }
 
+  conf.hubs.clear();
   free_conf_bots(conf.bots);
 
   bd::String line, option;
+  unsigned short hublevel = 0;
 
   while (stream-&amp;gt;tell() &amp;lt; stream-&amp;gt;length()) {
     line = stream-&amp;gt;getline().chomp().trim();
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -654,6 +663,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; readconf(const char *fname, int bits)
         if (str_isdigit(line.c_str()))
           conf.uid = atoi(line.c_str());
 
+      } else if (option == STR("hub")) {
+        if (line.split(' ').length() == 3) {
+          conf.hubs &amp;lt;&amp;lt; bd::String::printf("%s %d", line.c_str(), ++hublevel);
+        }
+
       } else {
         putlog(LOG_MISC, "*", STR("Unrecognized config option '%s'"), option.c_str());
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -687,6 +701,20 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; readconf(const char *fname, int bits)
 
 char s1_9[3] = "",s1_5[3] = "",s1_1[3] = "";
 
+bool hubSort (bd::String hub1, bd::String hub2) {
+  bd::Array&amp;lt;bd::String&amp;gt; hub1params(static_cast&amp;lt;bd::String&amp;gt;(hub1).split(' '));
+  bd::Array&amp;lt;bd::String&amp;gt; hub2params(static_cast&amp;lt;bd::String&amp;gt;(hub2).split(' '));
+
+  unsigned short hub1level = 99, hub2level = 99;
+  if (hub1params.length() == 4) {
+    hub1level = atoi(static_cast&amp;lt;bd::String&amp;gt;(hub1params[3]).c_str());
+  }
+  if (hub2params.length() == 4) {
+    hub2level = atoi(static_cast&amp;lt;bd::String&amp;gt;(hub2params[3]).c_str());
+  }
+  return hub1level &amp;lt; hub2level;
+}
+
 int
 writeconf(char *filename, int fd, int bits)
 {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -774,6 +802,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; writeconf(char *filename, int fd, int bits)
     comment("");
   }
 
+  if (conf.hubs.length()) {
+    comment("# Hubs this bot will connect to");
+    // Sort hub list by hublevel
+    bd::Array&amp;lt;bd::String&amp;gt; sortedhubs(conf.hubs);
+    std::sort(sortedhubs.begin(), sortedhubs.end(), hubSort);
+
+    for (size_t idx = 0; idx &amp;lt; sortedhubs.length(); ++idx) {
+      bd::Array&amp;lt;bd::String&amp;gt; hubparams(static_cast&amp;lt;bd::String&amp;gt;(sortedhubs[idx]).split(' '));
+      bd::String hubnick(hubparams[0]), address(hubparams[1]);
+      in_port_t port = atoi(static_cast&amp;lt;bd::String&amp;gt;(hubparams[2]).c_str());
+      *stream &amp;lt;&amp;lt; bd::String::printf(STR("! hub %s %s %d\n"), hubnick.c_str(), address.c_str(), port);
+    }
+    comment("");
+  }
+
   comment("# '|' means OR, [] means the enclosed is optional");
   comment("# A '+' in front of HOST means the HOST is ipv6");
   comment("# A '/' in front of BOT will disable that bot.");
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -980,6 +1023,45 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; bin_to_conf(bool error)
   tellconf();
 }
 
+void conf_update_hubs(struct userrec* list) {
+  if (!conf.bot-&amp;gt;hub &amp;amp;&amp;amp; !conf.bot-&amp;gt;localhub) {
+    return;
+  }
+
+  bd::Array&amp;lt;bd::String&amp;gt; hubUsers, oldhubs(conf.hubs);
+
+  // Count how many hubs there are
+  for (struct userrec *u = list; u; u = u-&amp;gt;next) {
+    if (bot_hublevel(u) &amp;lt; 999) {
+      hubUsers &amp;lt;&amp;lt; u-&amp;gt;handle;
+    }
+  }
+
+  conf.hubs.clear();
+  conf.hubs.Reserve(hubUsers.length());
+  for (size_t idx = 0; idx &amp;lt; hubUsers.length(); ++idx) {
+    struct userrec *u = get_user_by_handle(list, const_cast&amp;lt;char*&amp;gt;(static_cast&amp;lt;bd::String&amp;gt;(hubUsers[idx]).c_str()));
+    struct bot_addr *bi = (struct bot_addr *) get_user(&amp;amp;USERENTRY_BOTADDR, u);
+    conf.hubs &amp;lt;&amp;lt; bd::String::printf("%s %s %d %d", u-&amp;gt;handle, bi-&amp;gt;address, bi-&amp;gt;telnet_port, bi-&amp;gt;hublevel);
+  }
+
+  // Only rewrite binary / notify bots if the hubs changed
+  if (conf.hubs == oldhubs) {
+    return;
+  }
+
+  if (conf.bot-&amp;gt;hub || conf.bot-&amp;gt;localhub) {
+    /* rewrite our binary */
+    conf_to_bin(&amp;amp;conf, 0, -1);
+
+    /* Now signal all of the old bots with SIGUSR1
+     * They will auto die and determine new localhub, etc..
+     */
+    conf_checkpids(conf.bots);
+    conf_killbot(conf.bots, conf.bot-&amp;gt;nick, NULL, SIGUSR1, 1); /* Don't kill me. */
+  }
+}
+
 void conf_add_userlist_bots()
 {
   conf_bot *bot = NULL;
diff --git a/src/conf.h b/src/conf.h
index 1cbcaa4..ac4f040 100755
--- a/src/conf.h
+++ b/src/conf.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6,6 +6,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include "types.h"
 #include "eggdrop.h"
 #include "settings.h"
+#include &amp;lt;bdlib/src/Array.h&amp;gt;
 
 typedef struct conf_net_b {
   char *host;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -28,6 +29,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct conf_bot_b {
 } conf_bot;
 
 typedef struct conf_b {
+  bd::Array&amp;lt;bd::String&amp;gt; hubs;
   conf_bot *bots;       /* the list of bots */
   conf_bot *bot;        /* single bot (me) */
   int features;/* Pack features (take, mdop, beta... etc..) */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -38,8 +40,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct conf_b {
   char *datadir;
   char *username;       /* shell username */
   char *homedir;        /* homedir */
-  port_t portmin;       /* for hubs, the reserved port range for incoming connections */
-  port_t portmax;       /* for hubs, the reserved port range for incoming connections */
+  in_port_t portmin;       /* for hubs, the reserved port range for incoming connections */
+  in_port_t portmax;       /* for hubs, the reserved port range for incoming connections */
 } conf_t;
 
 extern conf_tconf;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -73,5 +75,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void deluser_removed_bots(conf_bot *, conf_bot *);
 conf_bot *conf_getlocalhub(conf_bot *);
 void conf_setmypid(pid_t);
 void conf_bot_dup(conf_bot *dest, conf_bot *src);
+void conf_update_hubs(struct userrec* list);
 
 #endif /* !_CONF_H */
diff --git a/config.h.in b/src/config.h.in
similarity index 79%
rename from config.h.in
rename to src/config.h.in
index b808554..3cf112f 100644
--- a/config.h.in
+++ b/src/config.h.in
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,4 +1,4 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
-/* config.h.in.  Generated from configure.ac by autoheader.  */
+/* src/config.h.in.  Generated from configure.ac by autoheader.  */
 
 /* Define if building universal (internal helper macro) */
 #undef AC_APPLE_UNIVERSAL_BUILD
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -13,6 +13,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 /* big endian */
 #undef B_ENDIAN
 
+/* Defines whether or not SSL is supported */
+#undef EGG_SSL_EXT
+
 /* Defines the current pack version */
 #undef EGG_VERSION
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -69,12 +72,18 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 /* Define to 1 if you have the `socket' library (-lsocket). */
 #undef HAVE_LIBSOCKET
 
+/* Define if you have support for libtcl */
+#undef HAVE_LIBTCL
+
 /* Define to 1 if you have the &amp;lt;limits.h&amp;gt; header file. */
 #undef HAVE_LIMITS_H
 
 /* Define to 1 if you have the &amp;lt;locale.h&amp;gt; header file. */
 #undef HAVE_LOCALE_H
 
+/* Define to 1 if the system has the type `long long int'. */
+#undef HAVE_LONG_LONG_INT
+
 /* Define to 1 if `lstat' has the bug that it succeeds when given the
    zero-length file name argument. */
 #undef HAVE_LSTAT_EMPTY_STRING_BUG
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -183,6 +192,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 /* Define to 1 if you have the &amp;lt;sys/param.h&amp;gt; header file. */
 #undef HAVE_SYS_PARAM_H
 
+/* Define to 1 if you have the &amp;lt;sys/prctl.h&amp;gt; header file. */
+#undef HAVE_SYS_PRCTL_H
+
 /* Define to 1 if you have the &amp;lt;sys/ptrace.h&amp;gt; header file. */
 #undef HAVE_SYS_PTRACE_H
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -201,6 +213,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 /* Define to 1 if you have &amp;lt;sys/wait.h&amp;gt; that is POSIX.1 compatible. */
 #undef HAVE_SYS_WAIT_H
 
+/* Define for Tcl that has Tcl_Free() (7.5p1 and later). */
+#undef HAVE_TCL_FREE
+
+/* Define for Tcl that has Tcl_SetNotifier() (8.2b1 and later). */
+#undef HAVE_TCL_SETNOTIFIER
+
 /* Define to 1 if you have struct timespec in sys/time.h */
 #undef HAVE_TIMESPEC
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -277,27 +295,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 /* Define limit of random() function. */
 #undef RANDOM_MAX
 
-/* The size of `int', as computed by sizeof. */
-#undef SIZEOF_INT
-
-/* The size of `long', as computed by sizeof. */
-#undef SIZEOF_LONG
-
-/* The size of `long long', as computed by sizeof. */
-#undef SIZEOF_LONG_LONG
-
-/* The size of `ptrdiff_t', as computed by sizeof. */
-#undef SIZEOF_PTRDIFF_T
-
-/* The size of `short', as computed by sizeof. */
-#undef SIZEOF_SHORT
-
-/* The size of `size_t', as computed by sizeof. */
-#undef SIZEOF_SIZE_T
-
-/* The size of `time_t', as computed by sizeof. */
-#undef SIZEOF_TIME_T
-
 /* Define to 1 if the `S_IS*' macros in &amp;lt;sys/stat.h&amp;gt; do not work properly. */
 #undef STAT_MACROS_BROKEN
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -313,9 +310,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 /* Define to 1 if your &amp;lt;sys/time.h&amp;gt; declares `struct tm'. */
 #undef TM_IN_SYS_TIME
 
-/* Define if you want ipv6 support */
+/* Define if you want IPv6 support */
 #undef USE_IPV6
 
+/* Define if you want TCL Script support */
+#undef USE_SCRIPT_TCL
+
 /* Enable extensions on AIX 3, Interix.  */
 #ifndef _ALL_SOURCE
 # undef _ALL_SOURCE
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -360,6 +360,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 /* Define to 1 if you need to in order for `stat' and other things to work. */
 #undef _POSIX_SOURCE
 
+/* Define for Solaris 2.5.1 so the uint32_t typedef from &amp;lt;sys/synch.h&amp;gt;,
+   &amp;lt;pthread.h&amp;gt;, or &amp;lt;semaphore.h&amp;gt; is not used. If the typedef were allowed, the
+   #define below would cause a syntax error. */
+#undef _UINT32_T
+
+/* Define for Solaris 2.5.1 so the uint64_t typedef from &amp;lt;sys/synch.h&amp;gt;,
+   &amp;lt;pthread.h&amp;gt;, or &amp;lt;semaphore.h&amp;gt; is not used. If the typedef were allowed, the
+   #define below would cause a syntax error. */
+#undef _UINT64_T
+
+/* Define for Solaris 2.5.1 so the uint8_t typedef from &amp;lt;sys/synch.h&amp;gt;,
+   &amp;lt;pthread.h&amp;gt;, or &amp;lt;semaphore.h&amp;gt; is not used. If the typedef were allowed, the
+   #define below would cause a syntax error. */
+#undef _UINT8_T
+
 /* Define to 1 if type `char' is unsigned and you are not using gcc.  */
 #ifndef __CHAR_UNSIGNED__
 # undef __CHAR_UNSIGNED__
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -368,6 +383,22 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 /* Define to `int' if &amp;lt;sys/types.h&amp;gt; doesn't define. */
 #undef gid_t
 
+/* Define to the type of a signed integer type of width exactly 16 bits if
+   such a type exists and the standard includes do not define it. */
+#undef int16_t
+
+/* Define to the type of a signed integer type of width exactly 32 bits if
+   such a type exists and the standard includes do not define it. */
+#undef int32_t
+
+/* Define to the type of a signed integer type of width exactly 64 bits if
+   such a type exists and the standard includes do not define it. */
+#undef int64_t
+
+/* Define to the type of a signed integer type of width exactly 8 bits if such
+   a type exists and the standard includes do not define it. */
+#undef int8_t
+
 /* Define to rpl_malloc if the replacement function should be used. */
 #undef malloc
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -383,6 +414,22 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 /* Define to `int' if &amp;lt;sys/types.h&amp;gt; doesn't define. */
 #undef uid_t
 
+/* Define to the type of an unsigned integer type of width exactly 16 bits if
+   such a type exists and the standard includes do not define it. */
+#undef uint16_t
+
+/* Define to the type of an unsigned integer type of width exactly 32 bits if
+   such a type exists and the standard includes do not define it. */
+#undef uint32_t
+
+/* Define to the type of an unsigned integer type of width exactly 64 bits if
+   such a type exists and the standard includes do not define it. */
+#undef uint64_t
+
+/* Define to the type of an unsigned integer type of width exactly 8 bits if
+   such a type exists and the standard includes do not define it. */
+#undef uint8_t
+
 /* Define as `fork' if `vfork' does not work. */
 #undef vfork
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -424,3 +471,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #  endif
 #endif
 
+/* TCL sanity check */
+#ifdef USE_SCRIPT_TCL
+#  ifndef HAVE_LIBTCL
+#    undef USE_SCRIPT_TCL
+#  endif
+#endif
+
diff --git a/src/crypt.c b/src/crypt.c
index cb2cf96..1ef3c01 100755
--- a/src/crypt.c
+++ b/src/crypt.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -11,7 +11,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include "settings.h"
 #include "misc.h"
 #include "base64.h"
-#include "src/crypto/crypto.h"
+#include "libcrypto.h"
 #include &amp;lt;stdarg.h&amp;gt;
 #include &amp;lt;bdlib/src/String.h&amp;gt;
 #include &amp;lt;bdlib/src/Stream.h&amp;gt;
diff --git a/src/crypt.h b/src/crypt.h
index 0faf3b9..db4b82a 100755
--- a/src/crypt.h
+++ b/src/crypt.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -8,7 +8,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #endif
 
 #include &amp;lt;sys/types.h&amp;gt;
-#include "src/crypto/crypto.h"
+#include "libcrypto.h"
 #include "users.h"
 
 #define SHA_HASH_LENGTH (SHA_DIGEST_LENGTH &amp;lt;&amp;lt; 1)
diff --git a/src/crypto/Makefile.in b/src/crypto/Makefile.in
index a015b51..37f9218 100755
--- a/src/crypto/Makefile.in
+++ b/src/crypto/Makefile.in
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -8,13 +8,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; CPPFLAGS = &amp;lt; at &amp;gt;CPPFLAGS&amp;lt; at &amp;gt;
 STRIP = &amp;lt; at &amp;gt;STRIP&amp;lt; at &amp;gt;
 
 VPATH = &amp;lt; at &amp;gt;srcdir&amp;lt; at &amp;gt;
-depcomp = /bin/sh $(top_srcdir)/autotools/depcomp
+depcomp = /bin/sh $(top_srcdir)/build/autotools/depcomp
 
 &amp;lt; at &amp;gt;SET_MAKE&amp;lt; at &amp;gt;
 
 OBJS = \
        aes_util.o \
-       bf_util.o
+       bf_util.o \
+       dh_util.o
 
 doofus:
 &amp;lt; at &amp;gt;echo ""
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -29,13 +30,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; crypto: $(OBJS)
 
 include ./.deps/includes
 
-.SUFFIXES:
-.SUFFIXES: .c .o .h
-
-.c.o:
-&amp;lt; at &amp;gt;echo -e "Compiling: \033[1m`basename $&amp;lt; .c`\033[0m"
-source='$&amp;lt;' object='$&amp;lt; at &amp;gt;' depfile='.deps/$*.Po' tmpdepfile='.deps/$*.TPo' depmode=$(CCDEPMODE) $(depcomp) \
-$(CXX) $(CXXFLAGS) -I../.. -I$(top_srcdir) -I$(top_srcdir)/src $(CPPFLAGS) -c $&amp;lt;
-
-
-
+%.o: %.c
+&amp;lt; at &amp;gt;echo -e "Compiling: \033[1m$*\033[0m"
+ifeq ($(CCDEPMODE),gcc3)
+if $(CXX) -MT '$&amp;lt; at &amp;gt;' -MD -MP -MF '.deps/$*.TPo' $(CXXFLAGS) $(CPPFLAGS) -c $&amp;lt; -o $&amp;lt; at &amp;gt;; then \
+mv '.deps/$*.TPo' '.deps/$*.Po'; \
+else rm -f '.deps/$*.Tpo'; exit 1; \
+fi
+else
+libtool=no source='$&amp;lt;' object='$&amp;lt; at &amp;gt;' depfile='.deps/$*.Po' tmpdepfile='.deps/$*.TPo' depmode=$(CCDEPMODE) $(depcomp) \
+$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $&amp;lt; -o $&amp;lt; at &amp;gt;
+endif
diff --git a/src/crypto/aes_util.c b/src/crypto/aes_util.c
index 126e9f5..691859d 100644
--- a/src/crypto/aes_util.c
+++ b/src/crypto/aes_util.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2,7 +2,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
  *
  */
 
-#include "crypto.h"
+#include "src/libcrypto.h"
 #include "src/compat/compat.h"
 #include &amp;lt;bdlib/src/String.h&amp;gt;
 
diff --git a/src/crypto/bf_util.c b/src/crypto/bf_util.c
index a8f25b2..525057b 100644
--- a/src/crypto/bf_util.c
+++ b/src/crypto/bf_util.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2,7 +2,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
  *
  */
 
-#include "crypto.h"
+#include "src/libcrypto.h"
 #include "src/compat/compat.h"
 #include &amp;lt;bdlib/src/String.h&amp;gt;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -32,8 +32,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static const char eggdrop_blowfish_base64_index[256] = {
 
 union bf_data {
   struct {
-    unsigned long left;
-    unsigned long right;
+    BF_LONG left;
+    BF_LONG right;
   } lr;
   BF_LONG bf_long;
 };
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -51,8 +51,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; bd::String egg_bf_encrypt(bd::String in, const bd::String&amp;amp; key)
   /* No key, no encryption */
   if (!key.length()) return in;
 
-  bd::String out(size_t(in.length() * 1.5));
   size_t datalen = in.length();
+  bd::String out(static_cast&amp;lt;size_t&amp;gt;(datalen * 1.5));
   if (datalen % 8 != 0) {
     datalen += 8 - (datalen % 8);
     in.resize(datalen, 0);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -94,7 +94,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; bd::String egg_bf_decrypt(bd::String in, const bd::String&amp;amp; key)
   // Skip over '+OK '
   if (in(0, 4) == "+OK ")
     in += static_cast&amp;lt;size_t&amp;gt;(4);
-  bd::String out(size_t(in.length() * .9));
+  bd::String out(static_cast&amp;lt;size_t&amp;gt;(in.length() * .9));
   // Too small to process
   if (in.size() &amp;lt; 12) return out;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -122,8 +122,20 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; bd::String egg_bf_decrypt(bd::String in, const bd::String&amp;amp; key)
       data.lr.left |= val &amp;lt;&amp;lt; part * 6;
     }
     BF_decrypt(&amp;amp;data.bf_long, &amp;amp;bf_d_key);
-    for (part = 0; part &amp;lt; 4; part++) out += char((data.lr.left &amp;amp; (0xff &amp;lt;&amp;lt; ((3 - part) * 8))) &amp;gt;&amp;gt; ((3 - part) * 8));
-    for (part = 0; part &amp;lt; 4; part++) out += char((data.lr.right &amp;amp; (0xff &amp;lt;&amp;lt; ((3 - part) * 8))) &amp;gt;&amp;gt; ((3 - part) * 8));
+    for (part = 0; part &amp;lt; 4; part++) {
+      const char decrypted_char = char((data.lr.left &amp;amp; (0xff &amp;lt;&amp;lt; ((3 - part) * 8))) &amp;gt;&amp;gt; ((3 - part) * 8));
+      // Don't write NULLs into the string
+      if (decrypted_char) {
+        out += decrypted_char;
+      }
+    }
+    for (part = 0; part &amp;lt; 4; part++) {
+      const char decrypted_char = char((data.lr.right &amp;amp; (0xff &amp;lt;&amp;lt; ((3 - part) * 8))) &amp;gt;&amp;gt; ((3 - part) * 8));
+      // Don't write NULLs into the string
+      if (decrypted_char) {
+        out += decrypted_char;
+      }
+    }
   }
 
   return out;
diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
deleted file mode 100755
index 834a068..0000000
--- a/src/crypto/crypto.h
+++ /dev/null
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,12 +0,0 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
-#ifndef _CRYPTO_H
-#define _CRYPTO_H
-
-#include "aes_util.h"
-#include "bf_util.h"
-#include &amp;lt;openssl/crypto.h&amp;gt;
-#include &amp;lt;openssl/aes.h&amp;gt;
-#include &amp;lt;openssl/blowfish.h&amp;gt;
-#include &amp;lt;openssl/md5.h&amp;gt;
-#include &amp;lt;openssl/sha.h&amp;gt;
-
-#endif /* !_CRYPTO_H */
diff --git a/src/crypto/dh_util.c b/src/crypto/dh_util.c
new file mode 100644
index 0000000..650c7ce
--- /dev/null
+++ b/src/crypto/dh_util.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,154 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/* dh_util.c
+ *
+ * Adapted from ZNC-fish
+ */
+
+#include "src/libcrypto.h"
+#include "src/compat/compat.h"
+#include &amp;lt;bdlib/src/String.h&amp;gt;
+#include &amp;lt;bdlib/src/base64.h&amp;gt;
+#include "dh_util.h"
+
+static BIGNUM* b_prime = NULL;
+static BIGNUM* b_generator = NULL;
+
+void DH1080_init() {
+  // ### new sophie-germain 1080bit prime number ###
+  //const char *prime1080 = "++ECLiPSE+is+proud+to+present+latest+FiSH+release+featuring+even+more+security+for+you+++shouts+go+out+to+TMG+for+helping+to+generate+this+cool+sophie+germain+prime+number++++/C32L";
+  // Base16: FBE1022E23D213E8ACFA9AE8B9DFADA3EA6B7AC7A7B7E95AB5EB2DF858921FEADE95E6AC7BE7DE6ADBAB8A783E7AF7A7FA6A2B7BEB1E72EAE2B72F9FA2BFB2A2EFBEFAC868BADB3E828FA8BADFADA3E4CC1BE7E8AFE85E9698A783EB68FA07A77AB6AD7BEB618ACF9CA2897EB28A6189EFA07AB99A8A7FA9AE299EFA7BA66DEAFEFBEFBF0B7D8B
+  // Base10: 12745216229761186769575009943944198619149164746831579719941140425076456621824834322853258804883232842877311723249782818608677050956745409379781245497526069657222703636504651898833151008222772087491045206203033063108075098874712912417029101508315117935752962862335062591404043092163187352352197487303798807791605274487594646923
+  const char *prime1080 = "FBE1022E23D213E8ACFA9AE8B9DFADA3EA6B7AC7A7B7E95AB5EB2DF858921FEADE95E6AC7BE7DE6ADBAB8A783E7AF7A7FA6A2B7BEB1E72EAE2B72F9FA2BFB2A2EFBEFAC868BADB3E828FA8BADFADA3E4CC1BE7E8AFE85E9698A783EB68FA07A77AB6AD7BEB618ACF9CA2897EB28A6189EFA07AB99A8A7FA9AE299EFA7BA66DEAFEFBEFBF0B7D8B";
+
+  if (!BN_hex2bn(&amp;amp;b_prime, prime1080)) {
+    sdprintf("BAD PRIME");
+    return;
+  }
+
+  if (!BN_dec2bn(&amp;amp;b_generator, "2")) {
+    sdprintf("BAD GENERATOR");
+    return;
+  }
+}
+
+void DH1080_uninit() {
+  BN_clear_free(b_prime);
+  BN_clear_free(b_generator);
+}
+
+/**
+ * &amp;lt; at &amp;gt;brief Encode a string using FiSH's base64 algorithm (from FiSH/mIRC)
+ * &amp;lt; at &amp;gt;note Any = padding is removed, and an 'A' is added if no padding was needed
+ * &amp;lt; at &amp;gt;param bd::String str The string to encode
+ * &amp;lt; at &amp;gt;returns Encoded string
+ * &amp;lt; at &amp;gt;note Adapated from FiSH code
+ */
+bd::String fishBase64Encode(const bd::String&amp;amp; str) {
+  bd::String result(bd::base64Encode(str));
+
+  // No padding, add an A on the end (base64-encoded NULL-terminator)
+  if (result.rfind('=') == result.npos) {
+    result += 'A';
+  } else {
+    // Remove padding
+    while (result.rfind('=') != result.npos) {
+      --result;
+    }
+  }
+  return result;
+}
+
+/**
+ * &amp;lt; at &amp;gt;brief Decode a string using FiSH's base64 algorithm (from FiSH/mIRC)
+ * &amp;lt; at &amp;gt;param bd::String str The string to decode
+ * &amp;lt; at &amp;gt;returns Decoded data
+ * &amp;lt; at &amp;gt;note Adapated from FiSH code
+ */
+bd::String fishBase64Decode(const bd::String&amp;amp; str) {
+  bd::String temp(str);
+
+  // Remove the 'A' NULL-terminator if present
+  if (temp.length() % 4 == 1 &amp;amp;&amp;amp; temp(-1, 1) == 'A') {
+    --temp;
+  }
+
+  while (temp.length() % 4) {
+    temp += '=';
+  }
+
+  return bd::base64Decode(temp);
+}
+
+
+void DH1080_gen(bd::String&amp;amp; privateKey, bd::String&amp;amp; publicKeyB64) {
+  DH *dh = NULL;
+
+  dh = DH_new();
+  dh-&amp;gt;p = BN_dup(b_prime);
+  dh-&amp;gt;g = BN_dup(b_generator);
+
+  if (!DH_generate_key(dh)) {
+    DH_free(dh);
+    return;
+  }
+
+  // Get private key
+  privateKey.resize(BN_num_bytes(dh-&amp;gt;priv_key), 0);
+  BN_bn2bin(dh-&amp;gt;priv_key, reinterpret_cast&amp;lt;unsigned char*&amp;gt;(privateKey.mdata()));
+
+  // Get public key
+  bd::String publicKey;
+  // Resize as the mdata() modification won't update the internal length, but resize() will
+  publicKey.resize(static_cast&amp;lt;size_t&amp;gt;(BN_num_bytes(dh-&amp;gt;pub_key)));
+  BN_bn2bin(dh-&amp;gt;pub_key, reinterpret_cast&amp;lt;unsigned char*&amp;gt;(publicKey.mdata()));;
+
+  // base64 encode
+  publicKeyB64 = fishBase64Encode(publicKey);
+
+  DH_free(dh);
+}
+
+bool DH1080_comp(const bd::String privateKey, const bd::String theirPublicKeyB64, bd::String&amp;amp; sharedKey) {
+  BIGNUM *b_myPrivkey = NULL, *b_HisPubkey = NULL;
+  DH *dh = NULL;
+
+
+  dh = DH_new();
+  dh-&amp;gt;p = BN_dup(b_prime);
+  dh-&amp;gt;g = BN_dup(b_generator);
+
+  // Setup my private key
+  b_myPrivkey = BN_bin2bn(reinterpret_cast&amp;lt;const unsigned char*&amp;gt;(privateKey.data()), privateKey.length(), NULL);
+  dh-&amp;gt;priv_key = b_myPrivkey;
+
+  // Prep their public key
+  bd::String theirPublicKey(fishBase64Decode(theirPublicKeyB64));
+  b_HisPubkey = BN_bin2bn(reinterpret_cast&amp;lt;const unsigned char*&amp;gt;(theirPublicKey.data()), theirPublicKey.length(), NULL);
+
+  // Compute the Shared key
+  char *key = (char *)my_calloc(1, DH_size(dh));
+  size_t len = DH_compute_key((unsigned char *)key, b_HisPubkey, dh);
+  DH_free(dh);
+  BN_clear_free(b_HisPubkey);
+  if (len == static_cast&amp;lt;size_t&amp;gt;(-1)) {
+    // Bad pub key
+    unsigned long err = ERR_get_error();
+    sdprintf("** DH Error: %s", ERR_error_string(err, NULL));
+    free(key);
+
+    sharedKey = ERR_error_string(err, NULL);
+    return false;
+  }
+
+  SHA256_CTX c;
+  bd::String SHA256Digest(static_cast&amp;lt;size_t&amp;gt;(SHA256_DIGEST_LENGTH));
+  SHA256Digest.resize(SHA256_DIGEST_LENGTH);
+
+  SHA256_Init(&amp;amp;c);
+  SHA256_Update(&amp;amp;c, key, len);
+  SHA256_Final(reinterpret_cast&amp;lt;unsigned char*&amp;gt;(SHA256Digest.mdata()), &amp;amp;c);
+  sharedKey = fishBase64Encode(SHA256Digest);
+
+  free(key);
+
+  return true;
+}
diff --git a/src/crypto/dh_util.h b/src/crypto/dh_util.h
new file mode 100644
index 0000000..0f9622e
--- /dev/null
+++ b/src/crypto/dh_util.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,22 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/* dh_util.h
+ *
+ */
+
+#ifndef _DH_UTIL_H
+#define _DH_UTIL_H 1
+
+#include &amp;lt;sys/types.h&amp;gt;
+#include &amp;lt;openssl/dh.h&amp;gt;
+
+namespace bd {
+  class String;
+}
+
+// Adapated from znc-fish
+bd::String fishBase64Encode(const bd::String&amp;amp; str);
+bd::String fishBase64Decode(const bd::String&amp;amp; str);
+void DH1080_gen(bd::String&amp;amp; privateKey, bd::String&amp;amp; publicKeyB64);
+bool DH1080_comp(const bd::String privateKey, const bd::String theirPublicKeyB64, bd::String&amp;amp; sharedKey);
+void DH1080_init();
+void DH1080_uninit();
+#endif
diff --git a/src/dcc.c b/src/dcc.c
index a86a4ed..61e040c 100755
--- a/src/dcc.c
+++ b/src/dcc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -613,7 +613,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void
 dcc_identd_connect(int idx, char *buf, int atr)
 {
   in_addr_t ip;
-  port_t port;
+  in_port_t port;
   int j, sock;
   char s[UHOSTLEN + 1] = "";
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1022,6 +1022,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; dcc_chat_pass(int idx, char *buf, int atr)
           return;
         }
 
+        sdprintf(STR("Using '%s' (%d/%d) for link with %s"), enclink[i].name, enclink[i].type, i, dcc[idx].nick);
+
         if (buf[0]) {
           const char *expected_nick = newsplit(&amp;amp;buf);
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1373,7 +1375,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void
 dcc_telnet(int idx, char *buf, int ii)
 {
   in_addr_t ip;
-  port_t port;
+  in_port_t port;
   char s[UHOSTLEN + 1] = "";
   int i;
   char x[1024] = "";
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1419,11 +1421,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; dcc_telnet(int idx, char *buf, int ii)
     return;
   }
 
-#if SIZEOF_SHORT == 2
-  if (port &amp;lt; 1024) {
-#else
-  if (port &amp;lt; 1024 || port &amp;gt; 65535) {
-#endif
+  if (port &amp;lt; 1024 || port &amp;gt; 65534) {
     putlog(LOG_BOTS, "*", "Refused %s/%d (bad src port)", s, port);
     killsock(sock);
     return;
diff --git a/src/dcc.h b/src/dcc.h
index 34a8677..a9026b4 100755
--- a/src/dcc.h
+++ b/src/dcc.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -61,7 +61,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct dcc_t {
 //  int auth;
   bool whowas;
   int dns_id;
-  port_t port;
+  in_port_t port;
   char simulbot[HANDLEN + 1];       /* used for hub-&amp;gt;leaf cmd simulation, holds bot that results should be sent to */
   char hash[MD5_HASH_LENGTH + 1];                /* used for dcc authing */
   char shahash[SHA_HASH_LENGTH + 1];
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -118,7 +118,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct xfer_info {
 struct bot_info {
   int  numver;
   int  uff_flags;               /* user file feature flags              */
-  port_t port;        /* base port                            */
+  in_port_t port;        /* base port                            */
   char linker[NOTENAMELEN + 1]; /* who requested this link              */
   char sysname[121];
   char version[121];            /* channel/version info                 */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -132,7 +132,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct relay_info {
 #ifdef USE_IPV6
   int af;
 #endif /* USE_IPV6 */
-  port_t port;
+  in_port_t port;
 };
 
 struct dupwait_info {
diff --git a/src/dccutil.c b/src/dccutil.c
index 25841be..c643d02 100755
--- a/src/dccutil.c
+++ b/src/dccutil.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -210,52 +210,47 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; colorbuf(char *buf, size_t len, int idx, size_t bufsiz)
 
 /* Dump a potentially super-long string of text.
  */
-void dumplots(int idx, const char *prefix, const char *data)
+void dumplots(int idx, const char *prefix, const bd::String data)
 {
   if (unlikely(!*data)) {
     dprintf(idx, "%s\n", prefix);
     return;
   }
 
-  char *p = (char*)data, *q = NULL, *n = NULL, c = 0;
   const size_t max_data_len = 120 - strlen(prefix);
+  bd::Array&amp;lt;bd::String&amp;gt; lines = data.split('\n');
+  size_t i = 0;
 
-  while ((strlen(p) - ansi_len(p)) &amp;gt; max_data_len) {
-    q = p + max_data_len;
-    /* Search for embedded linefeed first */
-    n = strchr(p, '\n');
-    if (n &amp;amp;&amp;amp; n &amp;lt; q) {
-      /* Great! dump that first line then start over */
-      *n = 0;
-      dprintf(idx, "%s%s\n", prefix, p);
-      *n = '\n';
-      p = n + 1;
-    } else {
-      /* Search backwards for the last space */
-      while (*q != ' ' &amp;amp;&amp;amp; q != p)
-        q--;
-      if (q == p)
-        q = p + max_data_len;
-      c = *q;
-      *q = 0;
-      dprintf(idx, "%s%s\n", prefix, p);
-      *q = c;
-      p = q;
-      if (c == ' ')
-        p++;
-    }
-  }
-  /* Last trailing bit: split by linefeeds if possible */
-  n = strchr(p, '\n');
-  while (n) {
-    *n = 0;
-    dprintf(idx, "%s%s\n", prefix, p);
-    *n = '\n';
-    p = n + 1;
-    n = strchr(p, '\n');
-  }
-  if (*p)
-    dprintf(idx, "%s%s\n", prefix, p);  /* Last trailing bit */
+  while (i &amp;lt; lines.length()) {
+    bd::String line(lines[i]);
+
+    if (line.length() &amp;gt; max_data_len) {
+      // Truncate at last space if possible
+      const size_t line_max = std::min(line.length() - 1, max_data_len);
+      size_t pos = line_max;
+
+      while (pos != bd::String::npos &amp;amp;&amp;amp; !strchr(",:; ", line[pos]))
+        --pos;
+      if (pos == bd::String::npos)
+        pos = line_max;
+
+      if (strchr(",:;", line[pos]))
+        ++pos;
+
+      if (bd::String(line(pos)).find("\n") != bd::String::npos) // Newline in remaining: dump it
+        dprintf(idx, "%s%s\n", prefix, bd::String(line(pos)).c_str());
+      else {
+        const size_t tpos = line[pos] == ' ' ? pos + 1 : pos; // Trim out the space
+        if (lines.length() - (i + 1) &amp;gt; 0) // Wrapped text: prepend to next line if possible
+          lines[i + 1] = line(tpos) + lines[i + 1];
+        else // Wrapped text (last line): Add onto list of lines
+          lines &amp;lt;&amp;lt; line(tpos);
+      }
+      line.resize(pos);
+    }
+    dprintf(idx, "%s%s\n", prefix, line.c_str());
+    ++i;
+  }
 }
 
 void
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -635,12 +630,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; tell_dcc(int idx)
   if (nicklen &amp;lt; 9)
     nicklen = 9;
 
-  simple_snprintf(format, sizeof format, "%%-4s %%-4s %%-8s %%-5s %%-%zus %%-40s %%s\n", nicklen);
-  dprintf(idx, format, "SOCK", "IDX", "ADDR", "PORT", "NICK", "HOST", "TYPE");
-  dprintf(idx, format, "----", "---", "--------", "-----", "---------",
+  simple_snprintf(format, sizeof format, "%%-4s %%-4s %%-4s %%-8s %%-5s %%-%zus %%-40s %%s\n", nicklen);
+  dprintf(idx, format, "SOCK", "IDX", "SSL", "ADDR", "PORT", "NICK", "HOST", "TYPE");
+  dprintf(idx, format, "----", "---", "---", "--------", "-----", "---------",
           "----------------------------------------", "----");
 
-  simple_snprintf(format, sizeof format, "%%-4d %%-4d %%08X %%5u %%-%zus %%-40s %%s\n", nicklen);
+  simple_snprintf(format, sizeof format, "%%-4d %%-4d %%-4s %%08X %%5u %%-%zus %%-40s %%s\n", nicklen);
 
   dprintf(idx, "dccn: %d, dcc_total: %d\n", dccn, dcc_total);
   dprintf(idx, "dns_idx: %d, servidx: %d\n", dns_idx, servidx);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -657,7 +652,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; tell_dcc(int idx)
         simple_snprintf(other, sizeof(other), "?:%lX  !! ERROR !!", (long) dcc[i].type);
         break;
       }
-      dprintf(idx, format, dcc[i].sock, i, dcc[i].addr, dcc[i].port, dcc[i].nick, dcc[i].host + j, other);
+      int snum = findanysnum(dcc[i].sock);
+      dprintf(idx, format, dcc[i].sock, i, (snum != -1 &amp;amp;&amp;amp; socklist[snum].ssl) ? "yes" : "no", dcc[i].addr, dcc[i].port, dcc[i].nick, dcc[i].host + j, other);
     }
   }
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -878,10 +874,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do_boot(int idx, const char *by, const char *reason)
 }
 
 int
-listen_all(port_t lport, bool off, bool should_v6)
+listen_all(in_port_t lport, bool off, bool should_v6)
 {
   int idx = -1;
-  port_t port, realport;
+  in_port_t port, realport;
 
 #ifdef USE_IPV6
   int i6 = -1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1008,7 +1004,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; identd_open(const char *sourceIp, const char *destIp, int identd)
   {
     int idx;
     int i = -1;
-    port_t port = 113;
+    in_port_t port = 113;
 
     for (idx = 0; idx &amp;lt; dcc_total; idx++)
       if (dcc[idx].type == &amp;amp;DCC_IDENTD_CONNECT)
diff --git a/src/dccutil.h b/src/dccutil.h
index c8b824d..67ae0a5 100755
--- a/src/dccutil.h
+++ b/src/dccutil.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7,13 +7,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 /* Public structure for the listening port map */
 struct portmap {
-  port_t realport;
-  port_t mappedto;
+  in_port_t realport;
+  in_port_t mappedto;
   struct portmap *next;
 };
 
 namespace bd {
   class Stream;
+  class String;
 }
 
 #define dprintf dprintf_eggdrop
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -37,7 +38,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; namespace bd {
 
 
 void init_dcc(void);
-void dumplots(int, const char *, const char *);
+void dumplots(int, const char *, bd::String);
 void rdprintf(const char*, int, const char *, ...) __attribute__((format(printf, 3, 4)));
 void dprintf(int, const char *, ...) __attribute__((format(printf, 2, 3)));
 void dprintf_real(int, char*, size_t, size_t, const char* = NULL);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -60,7 +61,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void do_boot(int, const char *, const char *);
 int detect_dcc_flood(time_t *, struct chat_info *, int);
 void identd_open(const char * = NULL, const char * = NULL, int identd = 1);
 void identd_close();
-int listen_all(port_t, bool, bool);
+int listen_all(in_port_t, bool, bool);
 bool valid_idx(int);
 int dcc_read(bd::Stream&amp;amp;);
 void dcc_write(bd::Stream&amp;amp;, int);
diff --git a/src/debug.c b/src/debug.c
index 7333d6a..b9bce7c 100755
--- a/src/debug.c
+++ b/src/debug.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -115,13 +115,48 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void sdprintf (const char *format, ...)
 #endif
 }
 
-static void write_debug()
+static void write_debug(bool fatal = 1)
 {
+  if (fatal) {
+    segfaulted = 1;
+    alarm(0);/* dont let anything jump out of this signal! */
+  }
+
   putlog(LOG_MISC, "*", "** Paste to bryan:");
   const size_t cur_buf = (current_get_buf == 0) ? GET_BUFS - 1 : current_get_buf - 1;
   for (size_t i = 0; i &amp;lt; GET_BUFS; i++)
     putlog(LOG_MISC, "*", "%c %02zu: %s", i == cur_buf ? '*' : '_', i, get_buf[i]);
   putlog(LOG_MISC, "*", "** end");
+
+#ifdef DEBUG
+  if (fatal) {
+    /* Write GDB backtrace */
+    char gdb[1024] = "", btfile[256] = "", std_in[101] = "", *out = NULL;
+
+    simple_snprintf(btfile, sizeof(btfile), ".gdb-backtrace-%d", (int)getpid());
+
+    FILE *f = fopen(btfile, "w");
+
+    if (f) {
+      strlcpy(std_in, "bt 100\nbt 100 full\ndetach\nquit\n", sizeof(std_in));
+      //simple_snprintf(stdin, sizeof(stdin), "detach\n");
+      //simple_snprintf(stdin, sizeof(stdin), "q\n");
+
+      simple_snprintf(gdb, sizeof(gdb), "gdb --pid=%d %s", (int)getpid(), binname);
+      shell_exec(gdb, std_in, &amp;amp;out, NULL);
+      fprintf(f, "%s\n", out);
+      fclose(f);
+      free(out);
+    }
+
+    //enabling core dumps
+    struct rlimit limit;
+    if (!getrlimit(RLIMIT_CORE, &amp;amp;limit)) {
+      limit.rlim_cur = limit.rlim_max;
+      setrlimit(RLIMIT_CORE, &amp;amp;limit);
+    }
+  }
+#endif
 }
 
 #ifndef DEBUG
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -146,57 +181,36 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void got_segv(int) __attribute__ ((noreturn));
 
 static void got_segv(int z)
 {
-  segfaulted = 1;
-  alarm(0);/* dont let anything jump out of this signal! */
   signal(SIGSEGV, SIG_DFL);
   write_debug();
   fatal("SEGMENT VIOLATION -- CRASHING!", 1);
 #ifdef DEBUG
-  char gdb[1024] = "", btfile[256] = "", std_in[101] = "", *out = NULL;
-
-  simple_snprintf(btfile, sizeof(btfile), ".gdb-backtrace-%d", getpid());
-
-  FILE *f = fopen(btfile, "w");
-
-  if (f) {
-    strlcpy(std_in, "bt 100\nbt 100 full\ndetach\nquit\n", sizeof(stdin));
-//    simple_snprintf(stdin, sizeof(stdin), "detach\n");
-//    simple_snprintf(stdin, sizeof(stdin), "q\n");
-
-    simple_snprintf(gdb, sizeof(gdb), "gdb %s %d", binname, getpid());
-    shell_exec(gdb, std_in, &amp;amp;out, NULL);
-    fprintf(f, "%s\n", out);
-    fclose(f);
-    free(out);
-  }
-
-  //enabling core dumps
-  struct rlimit limit;
-  if (!getrlimit(RLIMIT_CORE, &amp;amp;limit)) {
-    limit.rlim_cur = limit.rlim_max;
-    setrlimit(RLIMIT_CORE, &amp;amp;limit);
-  }
-
   raise(SIGSEGV);
 #else
   exit(1);
 #endif /* DEBUG */
 }
 
+#ifndef DEBUG
 static void got_fpe(int) __attribute__ ((noreturn));
+#endif /* DEBUG */
 
 static void got_fpe(int z)
 {
+  signal(SIGFPE, SIG_DFL);
   write_debug();
-  fatal("FLOATING POINT ERROR -- CRASHING!", 0);
-  exit(1);/* for GCC noreturn */
+  fatal("FLOATING POINT ERROR -- CRASHING!", 1);
+#ifdef DEBUG
+  raise(SIGFPE);
+#else
+  exit(1);
+#endif /* DEBUG */
 }
 
 static void got_term(int) __attribute__ ((noreturn));
 
 static void got_term(int z)
 {
-  if (conf.bot-&amp;gt;hub)
     write_userfile(-1);
   fatal("Received SIGTERM", 0);
   exit(1);/* for GCC noreturn */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -212,7 +226,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void got_abort(int z)
   write_debug();
   fatal("GOT SIGABRT -- CRASHING!", 1);
 #ifdef DEBUG
-  raise(SIGSEGV);
+  raise(SIGABRT);
 #else
   exit(1);
 #endif /* DEBUG */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -237,7 +251,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void got_alarm(int z)
  */
 static void got_ill(int z)
 {
-  write_debug();
+  write_debug(0);
 }
 
 static void
diff --git a/src/dhparam.c b/src/dhparam.c
new file mode 100644
index 0000000..b46b1fa
--- /dev/null
+++ b/src/dhparam.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,108 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+DH *get_dh2048() {
+  static unsigned char dh2048_p[]={
+    0xF1,0x9D,0x80,0xC5,0xC2,0x7F,0xE8,0xA5,0x37,0xDA,0x28,0x46,
+    0x6C,0x95,0x0A,0xC5,0x6C,0xE3,0x7E,0x1D,0x1F,0x4A,0x2E,0xD7,
+    0x6B,0xC1,0x80,0x4E,0xC9,0xC0,0x3F,0xB3,0x57,0x73,0x72,0xF2,
+    0xDA,0x30,0x15,0xB1,0xD3,0xD6,0x25,0x90,0xAF,0x8B,0x3F,0x81,
+    0x46,0x75,0xB1,0x1E,0x1B,0x85,0x5A,0x6C,0x13,0xA1,0x73,0x65,
+    0xFC,0x90,0xF3,0xBC,0xB9,0x9C,0xA0,0x62,0x74,0x7C,0x24,0x24,
+    0x27,0x80,0x12,0x3D,0x36,0xE9,0x62,0x78,0x31,0xE9,0x2F,0x96,
+    0xF4,0xD4,0xF2,0x04,0xEF,0x24,0x2C,0x60,0x04,0x41,0xF0,0x3E,
+    0xE9,0xF4,0xB4,0x5C,0x4F,0xFB,0xF3,0x64,0x91,0xB1,0x9F,0x5B,
+    0xBF,0xE5,0xBE,0x6F,0xD7,0x5B,0xED,0x34,0x94,0x51,0x58,0xDF,
+    0x00,0x5B,0x58,0xAE,0xBB,0x53,0x50,0xDE,0xFC,0x0A,0x91,0x6F,
+    0x3B,0xC7,0x7A,0x5E,0x7C,0xEE,0x5F,0x5E,0x3E,0x41,0x00,0x82,
+    0xD5,0x45,0x98,0xCC,0x01,0xFB,0x5C,0x64,0xBB,0xFB,0x06,0x55,
+    0xE5,0x19,0x6A,0x38,0x77,0x40,0x01,0xC6,0xCE,0xB5,0x52,0x82,
+    0xAA,0x7B,0x80,0xE6,0x37,0xB3,0x10,0x89,0x6E,0x42,0x63,0x33,
+    0xF8,0xCC,0xB6,0xC8,0xC6,0x9D,0xE2,0x98,0x3B,0xFC,0xFE,0xE4,
+    0xD2,0xB5,0xD3,0x19,0x6F,0xD7,0x62,0xBC,0xAA,0x16,0x92,0x14,
+    0xA0,0xD0,0xC1,0x7B,0xA9,0xE8,0x16,0xFC,0x6A,0x66,0x6F,0x29,
+    0xCA,0x18,0x28,0x4C,0x06,0xD8,0xAB,0x92,0x40,0xD5,0x83,0x9D,
+    0xEB,0x23,0x17,0x9E,0x06,0x20,0xF7,0xE8,0x8C,0xB9,0x0D,0xE7,
+    0x9D,0x40,0x50,0xA7,0xA1,0x74,0xD6,0xDF,0xF2,0x12,0x08,0xB3,
+    0x6B,0x4F,0x4A,0xAB,
+  };
+  static unsigned char dh2048_g[]={
+    0x02,
+  };
+  DH *dh;
+
+  if ((dh=DH_new()) == NULL) return(NULL);
+  dh-&amp;gt;p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
+  dh-&amp;gt;g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
+  if ((dh-&amp;gt;p == NULL) || (dh-&amp;gt;g == NULL))
+  { DH_free(dh); return(NULL); }
+  return(dh);
+}
+/*
+   -----BEGIN DH PARAMETERS-----
+   MIIBCAKCAQEA8Z2AxcJ/6KU32ihGbJUKxWzjfh0fSi7Xa8GATsnAP7NXc3Ly2jAV
+   sdPWJZCviz+BRnWxHhuFWmwToXNl/JDzvLmcoGJ0fCQkJ4ASPTbpYngx6S+W9NTy
+   BO8kLGAEQfA+6fS0XE/782SRsZ9bv+W+b9db7TSUUVjfAFtYrrtTUN78CpFvO8d6
+   XnzuX14+QQCC1UWYzAH7XGS7+wZV5RlqOHdAAcbOtVKCqnuA5jezEIluQmMz+My2
+   yMad4pg7/P7k0rXTGW/XYryqFpIUoNDBe6noFvxqZm8pyhgoTAbYq5JA1YOd6yMX
+   ngYg9+iMuQ3nnUBQp6F01t/yEgiza09KqwIBAg==
+   -----END DH PARAMETERS-----
+   */
+
+DH *get_dh1024() {
+  static unsigned char dh1024_p[]={
+    0xDA,0xF0,0x76,0xC8,0x15,0xC8,0xD2,0x62,0xED,0xBB,0x58,0x50,
+    0xB8,0x9A,0xF0,0x48,0xEF,0x09,0x6A,0x07,0xF5,0x42,0x34,0x92,
+    0xBA,0xC2,0x5E,0xA9,0x2D,0xC9,0xED,0xE7,0xF8,0x93,0x67,0x46,
+    0x47,0x42,0xD8,0xEB,0xA4,0x72,0xB4,0x51,0xF1,0xF2,0xCD,0xDC,
+    0x55,0x7D,0xD9,0x69,0x2B,0x91,0x57,0xA5,0xC3,0xDB,0x35,0x0C,
+    0xBE,0xAD,0x11,0xF2,0x26,0xB9,0x97,0x8E,0x71,0x80,0xEF,0x03,
+    0x01,0xEC,0x1B,0xE4,0xB3,0x6C,0xEB,0x52,0xF4,0x0E,0x15,0x50,
+    0xB5,0x5C,0x67,0xB8,0x57,0xAE,0xB9,0xC2,0xA9,0xD1,0x40,0x92,
+    0x9E,0xFC,0xAE,0x8E,0xCA,0xC6,0xA3,0xD5,0x02,0x41,0x80,0xD0,
+    0x06,0x16,0xB7,0xB4,0xD1,0xC5,0x10,0xA9,0x18,0xE6,0x13,0xD9,
+    0x07,0x40,0x15,0xBC,0xFF,0x15,0xA3,0x5B,
+  };
+  static unsigned char dh1024_g[]={
+    0x02,
+  };
+  DH *dh;
+
+  if ((dh=DH_new()) == NULL) return(NULL);
+  dh-&amp;gt;p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
+  dh-&amp;gt;g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
+  if ((dh-&amp;gt;p == NULL) || (dh-&amp;gt;g == NULL))
+  { DH_free(dh); return(NULL); }
+  return(dh);
+}
+/*
+   -----BEGIN DH PARAMETERS-----
+   MIGHAoGBANrwdsgVyNJi7btYULia8EjvCWoH9UI0krrCXqktye3n+JNnRkdC2Ouk
+   crRR8fLN3FV92WkrkVelw9s1DL6tEfImuZeOcYDvAwHsG+SzbOtS9A4VULVcZ7hX
+   rrnCqdFAkp78ro7KxqPVAkGA0AYWt7TRxRCpGOYT2QdAFbz/FaNbAgEC
+   -----END DH PARAMETERS-----
+   */
+DH *get_dh512() {
+  static unsigned char dh512_p[]={
+    0xC1,0x6E,0x10,0x0D,0x46,0x47,0xDA,0x08,0x42,0x54,0x02,0x23,
+    0x85,0xEE,0x07,0x3C,0x2E,0x7B,0xA9,0x3A,0xA8,0x88,0xDD,0x4E,
+    0x3F,0x71,0x8E,0xD3,0x52,0x3A,0xCA,0xC9,0xC3,0xF4,0xCD,0x65,
+    0x5E,0x05,0x25,0xA9,0xBA,0x10,0x8A,0x88,0x37,0xB3,0xCD,0x5D,
+    0x02,0x03,0x06,0x35,0x47,0x3C,0xD9,0x44,0x99,0xBB,0x9B,0x4C,
+    0x24,0xB2,0xC0,0x13,
+  };
+  static unsigned char dh512_g[]={
+    0x02,
+  };
+  DH *dh;
+
+  if ((dh=DH_new()) == NULL) return(NULL);
+  dh-&amp;gt;p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
+  dh-&amp;gt;g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
+  if ((dh-&amp;gt;p == NULL) || (dh-&amp;gt;g == NULL))
+  { DH_free(dh); return(NULL); }
+  return(dh);
+}
+/*
+   -----BEGIN DH PARAMETERS-----
+   MEYCQQDBbhANRkfaCEJUAiOF7gc8LnupOqiI3U4/cY7TUjrKycP0zWVeBSWpuhCK
+   iDezzV0CAwY1RzzZRJm7m0wkssATAgEC
+   -----END DH PARAMETERS-----
+   */
diff --git a/src/dl.c b/src/dl.c
new file mode 100644
index 0000000..931ad1c
--- /dev/null
+++ b/src/dl.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,35 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999 - 2002 Eggheads Development Team
+ * Copyright (C) 2002 - 2010 Bryan Drewery
+ *
+ * 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.
+ */
+
+/*
+ * dl.c -- handles:
+ *   dlopen/dlsym and symbol table handling
+ *
+ */
+
+
+#include "common.h"
+#include "main.h"
+#include "dl.h"
+#include &amp;lt;bdlib/src/String.h&amp;gt;
+#include &amp;lt;bdlib/src/Array.h&amp;gt;
+#include &amp;lt;bdlib/src/HashTable.h&amp;gt;
+
+bd::HashTable&amp;lt;bd::String, FunctionPtr&amp;gt; dl_symbol_table;
diff --git a/src/dl.h b/src/dl.h
new file mode 100644
index 0000000..ff79e79
--- /dev/null
+++ b/src/dl.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,35 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+#ifndef _DL_H
+#define _DL_H
+
+#include "common.h"
+#include &amp;lt;dlfcn.h&amp;gt;
+
+#include &amp;lt;bdlib/src/String.h&amp;gt;
+#include &amp;lt;bdlib/src/HashTable.h&amp;gt;
+
+#define DLSYM(_handle, x) \
+  dlerror(); \
+  x##_t x; \
+  *(void **) (&amp;amp;x) = dlsym(_handle, #x); \
+  dlsym_error = dlerror(); \
+  if (dlsym_error) { \
+    sdprintf("%s", dlsym_error); \
+    return(1); \
+  }
+
+#define DLSYM_GLOBAL(_handle, x) do { \
+  dlerror(); \
+  dl_symbol_table[#x] = (FunctionPtr) ((x##_t) dlsym(_handle, #x)); \
+  my_symbols &amp;lt;&amp;lt; #x; \
+  dlsym_error = dlerror(); \
+  if (dlsym_error) { \
+    sdprintf("%s", dlsym_error); \
+    return(1); \
+  } \
+} while (0)
+
+#define DLSYM_VAR(x) ((x##_t)dl_symbol_table[#x])
+
+extern bd::HashTable&amp;lt;bd::String, FunctionPtr&amp;gt; dl_symbol_table;
+
+#endif /* !_DL_H_ */
diff --git a/src/eggdrop.h b/src/eggdrop.h
index 005d88f..72ca339 100755
--- a/src/eggdrop.h
+++ b/src/eggdrop.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -127,16 +127,32 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum {/* TAKE A GUESS */
 
 
 /* chan &amp;amp; global */
-#define FLOOD_PRIVMSG    0
-#define FLOOD_NOTICE     1
-#define FLOOD_CTCP       2
-#define FLOOD_NICK       3
-#define FLOOD_JOIN       4
-#define FLOOD_KICK       5
-#define FLOOD_DEOP       6
-#define FLOOD_PART       7
-
-#define FLOOD_CHAN_MAX   8
+enum flood_t {
+  FLOOD_PRIVMSG  = 0,
+  FLOOD_NOTICE   = 1,
+  FLOOD_CTCP     = 2,
+  FLOOD_NICK     = 3,
+  FLOOD_JOIN     = 4,
+  FLOOD_KICK     = 5,
+  FLOOD_DEOP     = 6,
+  FLOOD_PART     = 7,
+  FLOOD_BYTES    = 8
+};
+
+
+#include &amp;lt;bdlib/src/bdlib.h&amp;gt;
+BDLIB_NS_BEGIN
+template&amp;lt;typename T&amp;gt;
+  struct Hash;
+
+template&amp;lt;&amp;gt;
+  struct Hash&amp;lt;flood_t&amp;gt;
+  {
+    inline size_t operator()(flood_t val) const { return static_cast&amp;lt;size_t&amp;gt;(val); }
+  };
+BDLIB_NS_END
+
+#define FLOOD_CHAN_MAX   9
 #define FLOOD_GLOBAL_MAX 3
 
 #define FEATURE_1BIT0
diff --git a/src/enclink.c b/src/enclink.c
index 7c868a0..3b90c19 100755
--- a/src/enclink.c
+++ b/src/enclink.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -38,7 +38,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ghost_link_case(int idx, direction_t direction)
   if (likely(snum &amp;gt;= 0)) {
     char initkey[33] = "", *tmp2 = NULL;
     char *keyp = NULL, *nick1 = NULL, *nick2 = NULL;
-    port_t port = 0;
+    in_port_t port = 0;
     const char salt1[] = SALT1;
     const char salt2[] = SALT2;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -124,10 +124,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void
 rotate_key(char* key, int&amp;amp; seed)
 {
   if (seed) {
-    *(dword *) &amp;amp; key[0] = prand(&amp;amp;seed, 0xFFFFFFFF);
-    *(dword *) &amp;amp; key[4] = prand(&amp;amp;seed, 0xFFFFFFFF);
-    *(dword *) &amp;amp; key[8] = prand(&amp;amp;seed, 0xFFFFFFFF);
-    *(dword *) &amp;amp; key[12] = prand(&amp;amp;seed, 0xFFFFFFFF);
+    *(uint32_t *) &amp;amp; key[0] = prand(&amp;amp;seed, 0xFFFFFFFF);
+    *(uint32_t *) &amp;amp; key[4] = prand(&amp;amp;seed, 0xFFFFFFFF);
+    *(uint32_t *) &amp;amp; key[8] = prand(&amp;amp;seed, 0xFFFFFFFF);
+    *(uint32_t *) &amp;amp; key[12] = prand(&amp;amp;seed, 0xFFFFFFFF);
 
     if (!seed)
       seed++;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -291,7 +291,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void link_challenge_to(int idx, char *buf) {
     }
     free(tmpp);
 
-    sdprintf(STR("Choosing '%s' (%d/%d) for link"), enclink[i].name, enclink[i].type, i);
+    // No shared type!
+    if (i == -1) {
+      sdprintf(STR("No shared cipher with %s"), dcc[idx].nick);
+      killsock(dcc[idx].sock);
+      lostdcc(idx);
+      return;
+    }
+
+    sdprintf(STR("Choosing '%s' (%d/%d) for link to %s"), enclink[i].name, enclink[i].type, i, dcc[idx].nick);
     link_hash(idx, rand);
     dprintf(-dcc[idx].sock, STR("neg %s %d %s\n"), dcc[idx].shahash, enclink[i].type, dcc[idx].nick);
     socklist[snum].enclink = i;
diff --git a/src/flags.c b/src/flags.c
index 12407d1..53580eb 100755
--- a/src/flags.c
+++ b/src/flags.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -380,7 +380,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; set_user_flagrec(struct userrec *u, struct flag_record *fr, const char *chname)
 /* Always pass the dname (display name) to this function for chname &amp;lt;cybah&amp;gt;
  */
 void
-get_user_flagrec(struct userrec *u, struct flag_record *fr, const char *chname, struct chanset_t* chan)
+get_user_flagrec(const struct userrec *u, struct flag_record *fr, const char *chname, const struct chanset_t* chan)
 {
   fr-&amp;gt;bot = 0;
   if (!u) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -427,7 +427,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; get_user_flagrec(struct userrec *u, struct flag_record *fr, const char *chname,
  * restricted by +private for the channel
  */
 int
-privchan(struct flag_record fr, struct chanset_t *chan, int type)
+privchan(const struct flag_record fr, const struct chanset_t *chan, int type)
 {
   if (!chan || !channel_privchan(chan) || glob_bot(fr) || glob_owner(fr))
     return 0;                   /* user is implicitly not restricted by +private, they may however be lacking other flags */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -444,7 +444,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; privchan(struct flag_record fr, struct chanset_t *chan, int type)
 }
 
 int
-real_chk_op(struct flag_record fr, struct chanset_t *chan, bool botbitch)
+real_chk_op(const struct flag_record fr, const struct chanset_t *chan, bool botbitch)
 {
   if (!chan &amp;amp;&amp;amp; glob_op(fr))
     return 1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -459,7 +459,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; real_chk_op(struct flag_record fr, struct chanset_t *chan, bool botbitch)
 }
 
 int
-chk_autoop(struct flag_record fr, struct chanset_t *chan)
+chk_autoop(const struct flag_record fr, const struct chanset_t *chan)
 {
   if (glob_bot(fr))
     return 0;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -471,7 +471,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; chk_autoop(struct flag_record fr, struct chanset_t *chan)
 }
 
 int
-real_chk_deop(struct flag_record fr, struct chanset_t *chan, bool botbitch)
+real_chk_deop(const struct flag_record fr, const struct chanset_t *chan, bool botbitch)
 {
   if (chan &amp;amp;&amp;amp; botbitch &amp;amp;&amp;amp; channel_botbitch(chan) &amp;amp;&amp;amp; !glob_bot(fr))
     return 1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -483,7 +483,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; real_chk_deop(struct flag_record fr, struct chanset_t *chan, bool botbitch)
 }
 
 int
-doresolv(struct chanset_t *chan)
+doresolv(const struct chanset_t *chan)
 {
   if (!chan)
     return 0;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -497,7 +497,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; doresolv(struct chanset_t *chan)
 }
 
 int
-dovoice(struct chanset_t *chan)
+dovoice(const struct chanset_t *chan)
 {
   if (!chan)
     return 0;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -511,7 +511,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; dovoice(struct chanset_t *chan)
 }
 
 int
-doflood(struct chanset_t *chan)
+doflood(const struct chanset_t *chan)
 {
   struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_BOT, 0, 0, 0 };
   if (!chan)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -524,7 +524,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; doflood(struct chanset_t *chan)
 }
 
 int
-dolimit(struct chanset_t *chan)
+dolimit(const struct chanset_t *chan)
 {
   if (!chan)
     return 0;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -564,64 +564,64 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; whois_access(struct userrec *user, struct userrec *whois_user)
   return 1;
 }
 
-int deflag_translate(const char *buf)
+deflag_t deflag_translate(const char *buf)
 {
   if (str_isdigit(buf))
-    return (atoi(buf));
+    return (static_cast&amp;lt;deflag_t&amp;gt;(atoi(buf)));
 
   if (!strcasecmp(buf, "ignore"))
-    return P_IGNORE;
+    return DEFLAG_IGNORE;
   else if (!strcasecmp(buf, "deop"))
-    return P_DEOP;
+    return DEFLAG_DEOP;
   else if (!strcasecmp(buf, "kick"))
-    return P_KICK;
+    return DEFLAG_KICK;
   else if (!strcasecmp(buf, "delete") || !strcasecmp(buf, "remove"))
-    return P_DELETE;
-  return P_IGNORE;
+    return DEFLAG_DELETE;
+  else if (!strcasecmp(buf, "react"))
+    return DEFLAG_REACT;
+  return DEFLAG_IGNORE;
 }
 
 
-void deflag_user(struct userrec *u, int why, char *msg, struct chanset_t *chan)
+void deflag_user(struct userrec *u, deflag_event_t why, const char *msg, const struct chanset_t *chan)
 {
-  char tmp[30] = "", tmp2[1024] = "";
+  char tmp[50] = "", tmp2[1024] = "";
   struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };
   int which = 0;
 
   switch (why) {
-  case DEFLAG_BADCOOKIE:
+  case DEFLAG_EVENT_BADCOOKIE:
     strlcpy(tmp, "Bad op cookie", sizeof(tmp));
     which = chan-&amp;gt;bad_cookie;
     break;
-  case DEFLAG_MANUALOP:
+  case DEFLAG_EVENT_MANUALOP:
     strlcpy(tmp, STR("Manual op in -manop channel"), sizeof(tmp));
     which = chan-&amp;gt;manop;
     break;
-#ifdef G_MEAN
-  case DEFLAG_MEAN_DEOP:
-    strlcpy(tmp, STR("Deopped bot in +mean channel"), sizeof(tmp));
-    ent = &amp;amp;CFG_MEANDEOP;
+  case DEFLAG_EVENT_REVENGE_DEOP:
+    strlcpy(tmp, STR("Deopped bot in +revenge channel"), sizeof(tmp));
+    which = chan-&amp;gt;revenge;
     break;
-  case DEFLAG_MEAN_KICK:
-    strlcpy(tmp, STR("Kicked bot in +mean channel"), sizeof(tmp));
-    ent = &amp;amp;CFG_MEANDEOP;
+  case DEFLAG_EVENT_REVENGE_KICK:
+    strlcpy(tmp, STR("Kicked bot in +revenge channel"), sizeof(tmp));
+    which = chan-&amp;gt;revenge;
     break;
-  case DEFLAG_MEAN_BAN:
-    strlcpy(tmp, STR("Banned bot in +mean channel"), sizeof(tmp));
-    ent = &amp;amp;CFG_MEANDEOP;
+  case DEFLAG_EVENT_REVENGE_BAN:
+    strlcpy(tmp, STR("Banned bot in +revenge channel"), sizeof(tmp));
+    which = chan-&amp;gt;revenge;
     break;
-#endif /* G_MEAN */
-  case DEFLAG_MDOP:
+  case DEFLAG_EVENT_MDOP:
     strlcpy(tmp, "Mass deop", sizeof(tmp));
     which = chan-&amp;gt;mdop;
     break;
-  case DEFLAG_MOP:
+  case DEFLAG_EVENT_MOP:
     strlcpy(tmp, "Mass op", sizeof(tmp));
     which = chan-&amp;gt;mop;
     break;
   default:
     simple_snprintf(tmp, sizeof(tmp), "Reason #%i", why);
   }
-  if (which == P_DEOP) {
+  if (which == DEFLAG_DEOP) {
     putlog(LOG_WARN, "*",  "Setting %s +d (%s): %s", u-&amp;gt;handle, tmp, msg);
     simple_snprintf(tmp2, sizeof(tmp2), "+d: %s (%s)", tmp, msg);
     set_user(&amp;amp;USERENTRY_COMMENT, u, tmp2);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -640,7 +640,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void deflag_user(struct userrec *u, int why, char *msg, struct chanset_t *chan)
     /* did anything change? */
     if (fr.match)
       set_user_flagrec(u, &amp;amp;fr, chan-&amp;gt;dname);
-  } else if (which == P_KICK) {
+  } else if (which == DEFLAG_KICK) {
     putlog(LOG_WARN, "*",  "Setting %s +dk (%s): %s", u-&amp;gt;handle, tmp, msg);
     simple_snprintf(tmp2, sizeof(tmp2), "+dk: %s (%s)", tmp, msg);
     set_user(&amp;amp;USERENTRY_COMMENT, u, tmp2);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -659,7 +659,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void deflag_user(struct userrec *u, int why, char *msg, struct chanset_t *chan)
     /* did anything change */
     if (fr.match)
       set_user_flagrec(u, &amp;amp;fr, chan-&amp;gt;dname);
-  } else if (which == P_DELETE) {
+  } else if (which == DEFLAG_DELETE) {
     putlog(LOG_WARN, "*",  "Deleting %s (%s): %s", u-&amp;gt;handle, tmp, msg);
     deluser(u-&amp;gt;handle);
   } else {
diff --git a/src/flags.h b/src/flags.h
index ac4ed92..5614012 100755
--- a/src/flags.h
+++ b/src/flags.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -48,16 +48,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct flag_record {
  *   unused letters: bchijpstw
  */
 
-#define DEFLAG_BADCOOKIE   1
-#define DEFLAG_MANUALOP    2
-#ifdef G_MEAN
-#  define DEFLAG_MEAN_DEOP   3
-#  define DEFLAG_MEAN_KICK   4
-#  define DEFLAG_MEAN_BAN    5
-#endif /* G_MEAN */
-#define DEFLAG_MDOP        6
-#define DEFLAG_MOP   7
-
+enum deflag_event_t {
+  DEFLAG_EVENT_BADCOOKIE = 1,
+  DEFLAG_EVENT_MANUALOP,
+  DEFLAG_EVENT_REVENGE_DEOP,
+  DEFLAG_EVENT_REVENGE_KICK,
+  DEFLAG_EVENT_REVENGE_BAN,
+  DEFLAG_EVENT_MDOP,
+  DEFLAG_EVENT_MOP,
+};
 
 #define USER_DEFAULT0
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -142,7 +141,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct flag_record {
 #define chan_doflood(x)((x).chan &amp;amp; BOT_FLOODBOT)
 
 void init_flags(void);
-void get_user_flagrec(struct userrec *, struct flag_record *, const char *, struct chanset_t* = NULL);
+void get_user_flagrec(const struct userrec *, struct flag_record *, const char *, const struct chanset_t* = NULL);
 void set_user_flagrec(struct userrec *, struct flag_record *, const char *);
 void break_down_flags(const char *, struct flag_record *, struct flag_record *);
 int build_flags(char *, struct flag_record *, struct flag_record *);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -151,12 +150,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int flagrec_ok(struct flag_record *, struct flag_record *);
 flag_t sanity_check(flag_t, int);
 flag_t chan_sanity_check(flag_t, int);
 char geticon(int);
-int privchan(struct flag_record, struct chanset_t *, int);
+int privchan(const struct flag_record, const struct chanset_t *, int);
 #define chk_op(fr, chan) real_chk_op(fr, chan, 1)
-int real_chk_op(struct flag_record, struct chanset_t *, bool);
-int chk_autoop(struct flag_record, struct chanset_t *);
+int real_chk_op(const struct flag_record, const struct chanset_t *, bool);
+int chk_autoop(const struct flag_record, const struct chanset_t *);
 #define chk_deop(fr, chan) real_chk_deop(fr, chan, 1)
-int real_chk_deop(struct flag_record, struct chanset_t *, bool);
+int real_chk_deop(const struct flag_record, const struct chanset_t *, bool);
 #define chk_voice(fr, chan) (\
     (\
      (!chan || (!privchan(fr, chan, PRIV_VOICE) &amp;amp;&amp;amp; !chk_devoice(fr))) \
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -166,13 +165,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int real_chk_deop(struct flag_record, struct chanset_t *, bool);
 #define chk_devoice(fr) ((chan_quiet(fr) || (glob_quiet(fr) &amp;amp;&amp;amp; !chan_voice(fr))) ? 1 : 0)
 #define isupdatehub() ((conf.bot-&amp;gt;hub &amp;amp;&amp;amp; conf.bot-&amp;gt;u &amp;amp;&amp;amp; (conf.bot-&amp;gt;u-&amp;gt;flags &amp;amp; BOT_UPDATEHUB)) ? 1 : 0)
 #define ischanhub() ((!conf.bot-&amp;gt;hub &amp;amp;&amp;amp; conf.bot-&amp;gt;u &amp;amp;&amp;amp; (conf.bot-&amp;gt;u-&amp;gt;flags &amp;amp; BOT_CHANHUB)) ? 1 : 0)
-int doresolv(struct chanset_t *);
-int dovoice(struct chanset_t *);
-int doflood(struct chanset_t *);
-int dolimit(struct chanset_t *);
+int doresolv(const struct chanset_t *);
+int dovoice(const struct chanset_t *);
+int doflood(const struct chanset_t *);
+int dolimit(const struct chanset_t *);
 int whois_access(struct userrec *, struct userrec *);
-void deflag_user(struct userrec *, int, char *, struct chanset_t *);
-int deflag_translate(const char *);
+void deflag_user(struct userrec *, deflag_event_t, const char *, const struct chanset_t *);
+deflag_t deflag_translate(const char *);
 
 
 #endif/* _EGG_FLAGS_H */
diff --git a/src/garble.h b/src/garble.h
index 422804c..c496402 100755
--- a/src/garble.h
+++ b/src/garble.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,7 +1,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #ifndef _GARBLE_H
 #define _GARBLE_H
 
+#ifdef DEBUG
 #define STR(x) x
+#endif
 
 const char *degarble(int, const char *);
 
diff --git a/src/generate_defs.sh b/src/generate_defs.sh
new file mode 100755
index 0000000..5369e69
--- /dev/null
+++ b/src/generate_defs.sh
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,65 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+#! /bin/sh
+
+### Export LC_ALL=C sort(1) stays consistent
+export LC_ALL=C
+
+if [ -z "$SED" -o -z "$CXX" ]; then
+  echo "This must be ran by configure" &amp;gt;&amp;amp;2
+  exit 1
+fi
+echo "Generating lib symbols"
+INCLUDES="${TCL_INCLUDES} ${SSL_INCLUDES}"
+
+mkdir -p src/.defs &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
+TMPFILE=$(mktemp "/tmp/pre.XXXXXX")
+for file in $(grep -l DLSYM_GLOBAL src/*.c|grep -v "src/_"); do
+  defsFile_wrappers="src/.defs/$(basename $file .c)_defs.c"
+  defsFile_pre="src/.defs/$(basename $file .c)_pre.h"
+  defsFile_post="src/.defs/$(basename $file .c)_post.h"
+
+  rm -f $defsFile_pre $defsFile_post $defsFile_wrappers &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
+  touch $defsFile_pre $defsFile_post $defsFile_wrappers
+done
+
+for file in $(grep -l DLSYM_GLOBAL src/*.c|grep -v "src/_"); do
+  defsFile_wrappers="src/.defs/$(basename $file .c)_defs.c"
+  defsFile_pre="src/.defs/$(basename $file .c)_pre.h"
+  defsFile_post="src/.defs/$(basename $file .c)_post.h"
+
+  echo "extern \"C\" {" &amp;gt; $defsFile_wrappers
+  echo "extern \"C\" {" &amp;gt; $defsFile_post
+
+  cd src &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
+  $CXX -E -I. -I.. -I../lib ${INCLUDES} -DHAVE_CONFIG_H ../${file} &amp;gt; $TMPFILE 2&amp;gt; /dev/null
+  # Fix wrapped prototypes
+  $SED -e :a -e N -e '$!ba' -e 's/,\n/,/g' $TMPFILE &amp;gt; $TMPFILE.sed
+  mv $TMPFILE.sed $TMPFILE
+
+  cd .. &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
+
+  for symbol in $($SED -n -e 's/.*DLSYM_GLOBAL(.*, \([^)]*\).*/\1/p' $file|sort -u); do
+    # Check if the typedef is already defined ...
+    typedef=$(grep "^typedef .*(\*${symbol}_t)" $(dirname $file)/$(basename $file .c).h)
+    # ... if not, generate it
+    if [ -z "$typedef" ]; then
+      # Trim off any extern "C", trim out the variable names, cleanup whitespace issues
+      typedef=$(grep -w "${symbol}" $TMPFILE | head -n 1 | $SED -e 's/extern "C" *//' -e "s/\(.*\) *${symbol} *(\(.*\)).*/typedef \1 (*${symbol}_t)(\2);/" -e 's/[_0-9A-Za-z]*\(,\)/\1/g' -e 's/[_0-9A-Za-z]*\();\)/\1/g' -e 's/  */ /g' -e 's/ \([,)]\)/\1/g' -e 's/ *()/(void)/g')
+      existing_typedef=0
+    else
+      existing_typedef=1
+    fi
+
+    if [ "${typedef%;}" = "${typedef}" ]; then
+      echo "Error: Unable to generate typedef for: ${symbol}" &amp;gt;&amp;amp;2
+      test -n "$typedef" &amp;amp;&amp;amp; echo "$typedef" &amp;gt;&amp;amp;2
+      continue
+    fi
+
+    #pipe typedef into generate_symbol.sh
+    test -n "$typedef" &amp;amp;&amp;amp; echo "${symbol} ${existing_typedef} ${typedef}"
+  done | src/generate_symbol.sh $defsFile_wrappers $defsFile_pre $defsFile_post
+
+  echo "}" &amp;gt;&amp;gt; $defsFile_wrappers
+  echo "}" &amp;gt;&amp;gt; $defsFile_post
+done
+rm -f $TMPFILE
diff --git a/src/generate_symbol.sh b/src/generate_symbol.sh
new file mode 100755
index 0000000..31991f1
--- /dev/null
+++ b/src/generate_symbol.sh
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,56 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+#! /bin/sh
+
+defsFile_wrappers="$1"
+defsFile_pre="$2"
+defsFile_post="$3"
+
+# X="typedef int (*Tcl_Eval_t)(Tcl_Interp*, const char*);"
+
+while read symbol existing_typedef typedef; do
+  echo "#define ${symbol} ORIGINAL_SYMBOL_${symbol}" &amp;gt;&amp;gt; $defsFile_pre
+  echo "#undef ${symbol}" &amp;gt;&amp;gt; $defsFile_post
+  test $existing_typedef -eq 0 &amp;amp;&amp;amp; echo "$typedef" &amp;gt;&amp;gt; $defsFile_post
+
+  returntype=$(echo "$typedef" | sed -e 's/typedef \([^(]*\) (\*\([^ ]*\)_t)(\(.*\));/\1/')
+  name=$(echo "$typedef" | sed -e 's/typedef \([^(]*\) (\*\([^ ]*\)_t)(\(.*\));/\2/')
+  params=$(echo "$typedef" | sed -e 's/typedef \([^(]*\) (\*\([^ ]*\)_t)(\(.*\));/\3/')
+
+  SAVE_IFS=$IFS
+  IFS=,
+
+  params_full=""
+  param_names=""
+
+  # Set params to $1,$2, etc
+  set $params
+  paramCount=$#
+  lastParam=$(expr $paramCount - 1)
+  i=0
+
+  while [ $i -lt $paramCount ]; do
+    x="x${i}"
+    if [ $1 = "void" ]; then
+      params_full="void"
+      param_names=""
+    else
+      params_full="${params_full}${1} ${x}"
+      param_names="${param_names}${x}"
+      if [ $i -ne $lastParam ]; then
+        params_full="${params_full},"
+        param_names="${param_names}, "
+      fi
+    fi
+    shift
+    i=$((i + 1))
+  done
+
+  cat &amp;gt;&amp;gt; $defsFile_wrappers &amp;lt;&amp;lt; EOF
+$returntype $name ($params_full) {
+  return DLSYM_VAR($name)($param_names);
+}
+EOF
+
+  echo "$returntype $name ($params_full);" &amp;gt;&amp;gt; $defsFile_post
+
+  IFS=$SAVE_IFS
+done
diff --git a/src/libcrypto.c b/src/libcrypto.c
new file mode 100644
index 0000000..f51fe4a
--- /dev/null
+++ b/src/libcrypto.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,133 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999 - 2002 Eggheads Development Team
+ * Copyright (C) 2002 - 2010 Bryan Drewery
+ *
+ * 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.
+ */
+
+/*
+ * libcrypto.c -- handles:
+ *   libcrypto handling
+ *
+ */
+
+
+#include "common.h"
+#include "main.h"
+#include "dl.h"
+#include &amp;lt;bdlib/src/String.h&amp;gt;
+#include &amp;lt;bdlib/src/Array.h&amp;gt;
+
+#include "libcrypto.h"
+#include ".defs/libcrypto_defs.c"
+
+void *libcrypto_handle = NULL;
+static bd::Array&amp;lt;bd::String&amp;gt; my_symbols;
+
+static int load_symbols(void *handle) {
+  const char *dlsym_error = NULL;
+
+  DLSYM_GLOBAL(handle, AES_cbc_encrypt);
+  DLSYM_GLOBAL(handle, AES_decrypt);
+  DLSYM_GLOBAL(handle, AES_encrypt);
+  DLSYM_GLOBAL(handle, AES_set_decrypt_key);
+  DLSYM_GLOBAL(handle, AES_set_encrypt_key);
+  DLSYM_GLOBAL(handle, BF_decrypt);
+  DLSYM_GLOBAL(handle, BF_encrypt);
+  DLSYM_GLOBAL(handle, BF_set_key);
+  DLSYM_GLOBAL(handle, ERR_error_string);
+  DLSYM_GLOBAL(handle, ERR_free_strings);
+  DLSYM_GLOBAL(handle, ERR_get_error);
+  DLSYM_GLOBAL(handle, OPENSSL_cleanse);
+  DLSYM_GLOBAL(handle, RAND_file_name);
+  DLSYM_GLOBAL(handle, RAND_load_file);
+  DLSYM_GLOBAL(handle, RAND_seed);
+  DLSYM_GLOBAL(handle, RAND_status);
+  DLSYM_GLOBAL(handle, RAND_write_file);
+  DLSYM_GLOBAL(handle, MD5_Final);
+  DLSYM_GLOBAL(handle, MD5_Init);
+  DLSYM_GLOBAL(handle, MD5_Update);
+  DLSYM_GLOBAL(handle, SHA1_Final);
+  DLSYM_GLOBAL(handle, SHA1_Init);
+  DLSYM_GLOBAL(handle, SHA1_Update);
+  DLSYM_GLOBAL(handle, SHA256_Final);
+  DLSYM_GLOBAL(handle, SHA256_Init);
+  DLSYM_GLOBAL(handle, SHA256_Update);
+
+  DLSYM_GLOBAL(handle, BN_bin2bn);
+  DLSYM_GLOBAL(handle, BN_bn2bin);
+  DLSYM_GLOBAL(handle, BN_clear_free);
+  DLSYM_GLOBAL(handle, BN_dec2bn);
+  DLSYM_GLOBAL(handle, BN_dup);
+  DLSYM_GLOBAL(handle, BN_hex2bn);
+  DLSYM_GLOBAL(handle, BN_num_bits);
+
+  DLSYM_GLOBAL(handle, DH_compute_key);
+  DLSYM_GLOBAL(handle, DH_free);
+  DLSYM_GLOBAL(handle, DH_generate_key);
+  DLSYM_GLOBAL(handle, DH_new);
+  DLSYM_GLOBAL(handle, DH_size);
+
+  DLSYM_GLOBAL(handle, EVP_cleanup);
+  DLSYM_GLOBAL(handle, CRYPTO_cleanup_all_ex_data);
+
+
+  return 0;
+}
+
+
+int load_libcrypto() {
+  if (libcrypto_handle) {
+    return 0;
+  }
+
+  sdprintf("Loading libcrypto");
+
+  bd::Array&amp;lt;bd::String&amp;gt; libs_list(bd::String("libcrypto.so." SHLIB_VERSION_NUMBER " libcrypto.so libcrypto.so.0.9.8 libcrypto.so.7 libcrypto.so.6").split(' '));
+
+  for (size_t i = 0; i &amp;lt; libs_list.length(); ++i) {
+    dlerror(); // Clear Errors
+    libcrypto_handle = dlopen(bd::String(libs_list[i]).c_str(), RTLD_LAZY|RTLD_GLOBAL);
+    if (libcrypto_handle) {
+      sdprintf("Found libcrypto: %s", bd::String(libs_list[i]).c_str());
+      break;
+    }
+  }
+  if (!libcrypto_handle) {
+    sdprintf("Unable to find libcrypto");
+    return(1);
+  }
+
+  load_symbols(libcrypto_handle);
+
+  return 0;
+}
+
+int unload_libcrypto() {
+  if (libcrypto_handle) {
+    // Cleanup symbol table
+    for (size_t i = 0; i &amp;lt; my_symbols.length(); ++i) {
+      dl_symbol_table.remove(my_symbols[i]);
+      static_cast&amp;lt;bd::String&amp;gt;(my_symbols[i]).clear();
+    }
+    my_symbols.clear();
+
+    dlclose(libcrypto_handle);
+    libcrypto_handle = NULL;
+    return 0;
+  }
+  return 1;
+}
diff --git a/src/libcrypto.h b/src/libcrypto.h
new file mode 100644
index 0000000..a60cd7b
--- /dev/null
+++ b/src/libcrypto.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,33 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+#ifndef _LIBCRYPTO_H
+#define _LIBCRYPTO_H
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include ".defs/libcrypto_pre.h"
+
+#include &amp;lt;openssl/crypto.h&amp;gt;
+#include &amp;lt;openssl/aes.h&amp;gt;
+#include &amp;lt;openssl/blowfish.h&amp;gt;
+#include &amp;lt;openssl/md5.h&amp;gt;
+#include &amp;lt;openssl/sha.h&amp;gt;
+#include &amp;lt;openssl/err.h&amp;gt;
+#include &amp;lt;openssl/rand.h&amp;gt;
+
+#include ".defs/libcrypto_post.h"
+
+#include "src/crypto/aes_util.h"
+#include "src/crypto/bf_util.h"
+#include "src/crypto/dh_util.h"
+
+#include "common.h"
+#include "dl.h"
+#include &amp;lt;bdlib/src/String.h&amp;gt;
+
+
+
+int load_libcrypto();
+int unload_libcrypto();
+
+#endif /* !_LIBCRYPTO_H */
diff --git a/src/libssl.c b/src/libssl.c
new file mode 100644
index 0000000..109a552
--- /dev/null
+++ b/src/libssl.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,106 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999 - 2002 Eggheads Development Team
+ * Copyright (C) 2002 - 2010 Bryan Drewery
+ *
+ * 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.
+ */
+
+/*
+ * libssl.c -- handles:
+ *   libssl handling
+ *
+ */
+
+
+#include "common.h"
+#include "main.h"
+#include "dl.h"
+#include &amp;lt;bdlib/src/String.h&amp;gt;
+#include &amp;lt;bdlib/src/Array.h&amp;gt;
+
+#include "libssl.h"
+#include ".defs/libssl_defs.c"
+
+void *libssl_handle = NULL;
+static bd::Array&amp;lt;bd::String&amp;gt; my_symbols;
+
+static int load_symbols(void *handle) {
+  const char *dlsym_error = NULL;
+
+  DLSYM_GLOBAL(handle, SSL_get_error);
+  DLSYM_GLOBAL(handle, SSL_connect);
+  DLSYM_GLOBAL(handle, SSL_CTX_free);
+  DLSYM_GLOBAL(handle, SSL_CTX_new);
+  DLSYM_GLOBAL(handle, SSL_free);
+  DLSYM_GLOBAL(handle, SSL_library_init);
+  DLSYM_GLOBAL(handle, SSL_load_error_strings);
+  DLSYM_GLOBAL(handle, SSL_new);
+  DLSYM_GLOBAL(handle, SSL_pending);
+  DLSYM_GLOBAL(handle, SSL_read);
+  DLSYM_GLOBAL(handle, SSL_set_fd);
+  DLSYM_GLOBAL(handle, SSL_shutdown);
+  DLSYM_GLOBAL(handle, SSLv23_client_method);
+  DLSYM_GLOBAL(handle, SSL_write);
+  DLSYM_GLOBAL(handle, SSL_CTX_ctrl);
+  DLSYM_GLOBAL(handle, SSL_CTX_set_cipher_list);
+  DLSYM_GLOBAL(handle, SSL_CTX_set_tmp_dh_callback);
+
+  return 0;
+}
+
+
+int load_libssl() {
+  if (ssl_ctx) {
+    return 0;
+  }
+
+  sdprintf("Loading libssl");
+
+  bd::Array&amp;lt;bd::String&amp;gt; libs_list(bd::String("libssl.so." SHLIB_VERSION_NUMBER " libssl.so libssl.so.0.9.8 libssl.so.7 libssl.so.6").split(' '));
+
+  for (size_t i = 0; i &amp;lt; libs_list.length(); ++i) {
+    dlerror(); // Clear Errors
+    libssl_handle = dlopen(bd::String(libs_list[i]).c_str(), RTLD_LAZY);
+    if (libssl_handle) {
+      sdprintf("Found libssl: %s", bd::String(libs_list[i]).c_str());
+      break;
+    }
+  }
+  if (!libssl_handle) {
+    sdprintf("Unable to find libssl");
+    return(1);
+  }
+
+  load_symbols(libssl_handle);
+
+  return 0;
+}
+
+int unload_libssl() {
+  if (libssl_handle) {
+    // Cleanup symbol table
+    for (size_t i = 0; i &amp;lt; my_symbols.length(); ++i) {
+      dl_symbol_table.remove(my_symbols[i]);
+      static_cast&amp;lt;bd::String&amp;gt;(my_symbols[i]).clear();
+    }
+    my_symbols.clear();
+
+    dlclose(libssl_handle);
+    libssl_handle = NULL;
+    return 0;
+  }
+  return 1;
+}
diff --git a/src/libssl.h b/src/libssl.h
new file mode 100644
index 0000000..ed3e641
--- /dev/null
+++ b/src/libssl.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,30 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+#ifndef _LIBSSL_H
+#define _LIBSSL_H
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "common.h"
+#include "dl.h"
+#include &amp;lt;bdlib/src/String.h&amp;gt;
+
+#include ".defs/libssl_pre.h"
+
+#ifdef EGG_SSL_EXT
+# ifndef EGG_SSL_INCS
+#  include &amp;lt;openssl/ssl.h&amp;gt;
+#  define EGG_SSL_INCS 1
+# endif
+#endif
+
+typedef DH* (*dh_callback_t)(SSL*, int, int);
+
+#include ".defs/libssl_post.h"
+
+typedef void (*SSL_CTX_set_tmp_dh_callback_t)(SSL_CTX*, dh_callback_t);
+
+int load_libssl();
+int unload_libssl();
+
+#endif /* !_LIBSSL_H */
diff --git a/src/libtcl.c b/src/libtcl.c
new file mode 100644
index 0000000..72bc995
--- /dev/null
+++ b/src/libtcl.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,152 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999 - 2002 Eggheads Development Team
+ * Copyright (C) 2002 - 2010 Bryan Drewery
+ *
+ * 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.
+ */
+
+/*
+ * tcl.c -- handles:
+ *   libtcl handling
+ *
+ */
+
+
+#include "common.h"
+#include "main.h"
+#include "dl.h"
+#include &amp;lt;bdlib/src/String.h&amp;gt;
+#include &amp;lt;bdlib/src/Array.h&amp;gt;
+
+#include "libtcl.h"
+#include ".defs/libtcl_defs.c"
+
+#ifdef USE_SCRIPT_TCL
+Tcl_Interp *global_interp = NULL;
+#endif
+
+void *libtcl_handle = NULL;
+static bd::Array&amp;lt;bd::String&amp;gt; my_symbols;
+
+void initialize_binds_tcl();
+
+static int load_symbols(void *handle) {
+#ifdef USE_SCRIPT_TCL
+  const char *dlsym_error = NULL;
+
+  DLSYM_GLOBAL(handle, Tcl_Eval);
+  DLSYM_GLOBAL(handle, Tcl_GetStringResult);
+  DLSYM_GLOBAL(handle, Tcl_DeleteInterp);
+  DLSYM_GLOBAL(handle, Tcl_CreateCommand);
+  DLSYM_GLOBAL(handle, Tcl_CreateInterp);
+  DLSYM_GLOBAL(handle, Tcl_FindExecutable);
+  DLSYM_GLOBAL(handle, Tcl_Init);
+#endif
+
+  return 0;
+}
+
+int load_libtcl() {
+#ifndef USE_SCRIPT_TCL
+  sdprintf("Not compiled with TCL support");
+  return 1;
+#else
+  if (global_interp) {
+    return 0;
+  }
+#endif
+
+  bd::Array&amp;lt;bd::String&amp;gt; libs_list(bd::String("libtcl.so libtcl83.so libtcl8.3.so libtcl84.so libtcl8.4.so libtcl85.so libtcl8.5.so").split(' '));
+
+  for (size_t i = 0; i &amp;lt; libs_list.length(); ++i) {
+    dlerror(); // Clear Errors
+    libtcl_handle = dlopen(bd::String(libs_list[i]).c_str(), RTLD_LAZY);
+    if (libtcl_handle) break;
+  }
+  if (!libtcl_handle) {
+    sdprintf("Unable to find libtcl");
+    return 1;
+  }
+
+  load_symbols(libtcl_handle);
+
+#ifdef USE_SCRIPT_TCL
+  // create interp
+  global_interp = Tcl_CreateInterp();
+  Tcl_FindExecutable(binname);
+
+  if (Tcl_Init(global_interp) != TCL_OK) {
+    sdprintf("Tcl_Init error: %s", Tcl_GetStringResult(global_interp));
+    return 1;
+  }
+
+  initialize_binds_tcl();
+#endif
+  return 0;
+}
+
+#ifdef USE_SCRIPT_TCL
+
+#include "chanprog.h"
+static int cmd_privmsg STDVAR {
+  bd::String str = argv[2];
+  for (int i = 3; i &amp;lt; argc; ++i)
+    str += " " + bd::String(argv[i]);
+  privmsg(argv[1], str, DP_SERVER);
+
+  return TCL_OK;
+}
+
+void initialize_binds_tcl() {
+  Tcl_CreateCommand(global_interp, "privmsg", (Tcl_CmdProc*) cmd_privmsg, NULL, NULL);
+}
+
+#endif
+
+int unload_libtcl() {
+  if (libtcl_handle) {
+#ifdef USE_SCRIPT_TCL
+    if (global_interp) {
+      Tcl_DeleteInterp(global_interp);
+      global_interp = NULL;
+    }
+#endif
+
+    // Cleanup symbol table
+    for (size_t i = 0; i &amp;lt; my_symbols.length(); ++i) {
+      dl_symbol_table.remove(my_symbols[i]);
+      static_cast&amp;lt;bd::String&amp;gt;(my_symbols[i]).clear();
+    }
+    my_symbols.clear();
+
+    dlclose(libtcl_handle);
+    libtcl_handle = NULL;
+    return 0;
+  }
+  return 1;
+}
+
+#ifdef USE_SCRIPT_TCL
+bd::String tcl_eval(const bd::String&amp;amp; str) {
+  load_libtcl();
+  if (!global_interp) return bd::String();
+  if (Tcl_Eval(global_interp, str.c_str()) == TCL_OK) {
+    return Tcl_GetStringResult(global_interp);
+  } else
+    return tcl_eval("set errorInfo");
+  return bd::String();
+}
+#endif
diff --git a/src/libtcl.h b/src/libtcl.h
new file mode 100644
index 0000000..7f5b0b3
--- /dev/null
+++ b/src/libtcl.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,26 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+#ifndef _LIBTCL_H
+#define _LIBTCL_H
+
+#include "common.h"
+#include "dl.h"
+#include &amp;lt;bdlib/src/String.h&amp;gt;
+#ifdef USE_SCRIPT_TCL
+
+#include ".defs/libtcl_pre.h"
+
+#include &amp;lt;tcl.h&amp;gt;
+
+#include ".defs/libtcl_post.h"
+
+
+#define STDVAR (ClientData cd, Tcl_Interp *interp, int argc, const char *argv[])
+
+extern Tcl_Interp *global_interp;
+bd::String tcl_eval(const bd::String&amp;amp;);
+#endif
+
+int load_libtcl();
+int unload_libtcl();
+
+
+#endif /* !_LIBTCL_H */
diff --git a/src/log.c b/src/log.c
index 0d3712b..f60fc6c 100755
--- a/src/log.c
+++ b/src/log.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -349,7 +349,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; irc_log(struct chanset_t *chan, const char *format, ...)
   if ((chan &amp;amp;&amp;amp; strcasecmp(chan-&amp;gt;dname, relay_chan)) || !chan) {
     bd::String msg;
     msg = bd::String::printf("[%s] %s", chan ? chan-&amp;gt;dname : "*" , va_out);
-    privmsg(relay_chan, msg.c_str(), DP_HELP);
+    privmsg(relay_chan, msg, DP_HELP);
   }
 /*
   chanout_but(-1, 1, "[%s] %s\n", chan-&amp;gt;dname, va_out);
diff --git a/src/main.c b/src/main.c
index 1a1b91b..c62983e 100755
--- a/src/main.c
+++ b/src/main.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -26,7 +26,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
  *
  */
 
-
 #include "common.h"
 #include "main.h"
 #include "userent.h"
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -99,6 +98,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; bool     have_linked_to_hub = 0;  /* Have we ever been linked to a hub? */
 intdefault_uflags = 0;/* Default userdefinied flags for people
    who say 'hello' or for .adduser */
 int     do_restart = 0;
+int     do_write_userfile = 0;
 boolbackgrd = 1;/* Run in the background? */
 uid_t   myuid;
 pid_t   mypid;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -198,6 +198,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void fatal(const char *s, int recoverable)
   }
 
   if (!recoverable) {
+//    uninit_openssl();
 //    if (conf.bot &amp;amp;&amp;amp; conf.bot-&amp;gt;pid_file)
 //      unlink(conf.bot-&amp;gt;pid_file);
     exit(1);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -320,12 +321,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void show_help()
   printf(format, STR("-u &amp;lt;binary&amp;gt;"), STR("Update binary, Automatically kill/respawn bots"));
   printf(format, STR("-U &amp;lt;binary&amp;gt;"), STR("Update binary"));
   printf(format, STR("-v"), STR("Displays bot version"));
+  printf(format, STR("-V"), STR("Displays the pack.cfg being used"));
   exit(0);
 }
 
 // leaf: BkLP
-#define PARSE_FLAGS STR("0234:aB:cCd:De:EH:k:hnr:tu:U:v")
-#define FLAGS_CHECKPASS STR("cCdDeEknrtuU")
+#define PARSE_FLAGS STR("0234:aB:cCd:De:EH:k:hnr:tu:U:vV")
+#define FLAGS_CHECKPASS STR("cCdDeEknrtuUV")
 static void dtx_arg(int&amp;amp; argc, char *argv[])
 {
   int i = 0, checked_pass = 0;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -429,13 +431,26 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void dtx_arg(int&amp;amp; argc, char *argv[])
         printf(STR("BuildOS: %s%s%s BuildArch: %s%s%s\n"), BOLD(-1), BUILD_OS, BOLD_END(-1), BOLD(-1), BUILD_ARCH, BOLD_END(-1));
         printf(STR("- http://wraith.botpack.net -\n"));
 #ifdef DEBUG
-printf(STR("pack: %zu conf: %zu settings_t: %zu prefix: %zu pad: %zu needed padding: %zu\n"), SIZE_PACK, SIZE_CONF, sizeof(settings_t), PREFIXLEN, SIZE_PAD, (16 - ((sizeof(settings_t) - sizeof(settings.padding)) % 16)) % 16);
+printf(STR("pack: %zu conf: %zu settings_t: %zu prefix: %zu pad: %zu/%zu needed padding: %zu/%zu\n"),
+            SIZE_PACK,
+            SIZE_CONF,
+            SIZE_SETTINGS,
+            PREFIXLEN,
+            SIZE_PAD_PACK,
+            SIZE_PAD,
+            (SIZE_PAD_ALIGN - ((SIZE_PACK - SIZE_PAD_PACK) % SIZE_PAD_ALIGN)) % SIZE_PAD_ALIGN,
+            (SIZE_PAD_ALIGN - ((SIZE_SETTINGS - SIZE_PAD) % SIZE_PAD_ALIGN)) % SIZE_PAD_ALIGN
+        );
 #endif
         if (settings.dynamic_initialized[0]) {
           bin_to_conf();
         }
 exit(0);
       }
+      case 'V':
+        writecfg();
+        exit(0);
+        break;
       case '?':
       default:
         break;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -520,6 +535,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void core_secondly()
     cnt = 0;
   }
 
+  if (unlikely(do_write_userfile) &amp;amp;&amp;amp; do_write_userfile-- == 1) {
+    real_write_userfile(-1);
+  }
+
   memcpy(&amp;amp;nowtm, gmtime(&amp;amp;now), sizeof(struct tm));
   if (nowtm.tm_min != lastmin) {
     int i = 0;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -686,6 +705,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int main(int argc, char **argv)
   check_trace(1);
 #endif
 
+  if (init_openssl()) {
+    fprintf(stderr, "Unable to initialize/find OpenSSL.\n");
+    return 1;
+  }
+
   /* Initialize variables and stuff */
   timer_update_now(&amp;amp;egg_timeval_now);
   now = egg_timeval_now.sec;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -812,7 +836,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int main(int argc, char **argv)
   if (!conf.bot-&amp;gt;hub &amp;amp;&amp;amp; conf.bot-&amp;gt;localhub)
     sdprintf(STR("I am localhub (%s)"), conf.bot-&amp;gt;nick);
 
-  if (conf.autocron &amp;amp;&amp;amp; (conf.bot-&amp;gt;hub || conf.bot-&amp;gt;localhub))
+  if (!sdebug &amp;amp;&amp;amp; (conf.autocron &amp;amp;&amp;amp; (conf.bot-&amp;gt;hub || conf.bot-&amp;gt;localhub)))
     check_crontab();
 
   /* Move into background? */
diff --git a/src/main.h b/src/main.h
index e051158..9b87c5a 100755
--- a/src/main.h
+++ b/src/main.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -15,7 +15,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum {
 };
 
 extern introle, default_flags, default_uflags, do_confedit,
-updating, do_restart;
+updating, do_restart, do_write_userfile;
 extern booluse_stderr, backgrd, used_B, term_z, loading, have_linked_to_hub, restart_was_update, restarting, safe_to_log;
 extern chartempdir[], *binname, owner[121], version[151], ver[101], quit_msg[], *socksfile;
 extern time_tonline_since, now, restart_time;
diff --git a/src/misc.c b/src/misc.c
index 967ab7b..ae58c7e 100755
--- a/src/misc.c
+++ b/src/misc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -436,46 +436,63 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void show_motd(int idx)
 
 void show_channels(int idx, char *handle)
 {
-  struct chanset_t *chan = NULL;
-  struct flag_record fr = { FR_CHAN | FR_GLOBAL, 0, 0, 0 };
   struct userrec *u = NULL;
-  int first = 0, total = 0;
-  size_t l = 0;
-  char format[120] = "";
+  size_t maxChannelLength = 0;
+  bd::Array&amp;lt;bd::String&amp;gt; channelNames;
+  bd::HashTable&amp;lt;bd::String, struct chanset_t*&amp;gt; channels;
+  bd::String group;
 
-  if (handle)
+  if (handle &amp;amp;&amp;amp; handle[0] != '%') {
     u = get_user_by_handle(userlist, handle);
-  else
+  } else {
     u = dcc[idx].user;
-
-  for (chan = chanset;chan ;chan = chan-&amp;gt;next) {
-    get_user_flagrec(u, &amp;amp;fr, chan-&amp;gt;dname);
-    if (l &amp;lt; strlen(chan-&amp;gt;dname)) {
-      l = strlen(chan-&amp;gt;dname);
+    if (handle &amp;amp;&amp;amp; handle[0] == '%') {
+      group = handle + 1;
     }
-    if (real_chk_op(fr, chan, 0))
-      total++;
   }
 
-  simple_snprintf(format, sizeof(format), "  %%c%%-%zus %%-s%%-s%%-s%%-s%%-s%%-s\n", (l+2));
-
-  for (chan = chanset;chan;chan = chan-&amp;gt;next) {
+  for (struct chanset_t* chan = chanset; chan; chan = chan-&amp;gt;next) {
+    struct flag_record fr = { FR_CHAN | FR_GLOBAL, 0, 0, 0 };
+    const bd::String chname(chan-&amp;gt;dname);
+    // If a group was passed, ensure it matches
+    if (group.length() &amp;amp;&amp;amp; chan-&amp;gt;groups-&amp;gt;find(group) == chan-&amp;gt;groups-&amp;gt;npos) {
+      continue;
+    }
     get_user_flagrec(u, &amp;amp;fr, chan-&amp;gt;dname);
-    if (real_chk_op(fr, chan, 0)) {
-        if (!first) { 
-          dprintf(idx, "%s %s access to %d channel%s:\n", handle ? u-&amp;gt;handle : "You", handle ? "has" : "have", total, (total &amp;gt; 1) ? "s" : "");
+    if (group.length() || real_chk_op(fr, chan, 0)) {
+      if (maxChannelLength &amp;lt; chname.length()) {
+        maxChannelLength = chname.length();
+      }
+      channelNames &amp;lt;&amp;lt; chname;
+      channels[chname] = chan;
+    }
+  }
           
-          first = 1;
+  if (channelNames.length()) {
+    char format[120] = "";
+    simple_snprintf(format, sizeof(format), "  %%c%%-%zus %%-s%%-s%%-s%%-s%%-s%%-s\n", (maxChannelLength+2));
+    if (group.length()) {
+      dprintf(idx, "group '%s' is in %zu channel%s:\n", group.c_str(), channelNames.length(), (channelNames.length() &amp;gt; 1) ? "s" : "");
+    } else {
+      dprintf(idx, "%s %s access to %zu channel%s:\n", handle ? u-&amp;gt;handle : "You", handle ? "has" : "have", channelNames.length(), (channelNames.length() &amp;gt; 1) ? "s" : "");
         }
-        dprintf(idx, format, !conf.bot-&amp;gt;hub &amp;amp;&amp;amp; me_op(chan) ? '&amp;lt; at &amp;gt;' : ' ', chan-&amp;gt;dname, !shouldjoin(chan) ? "(inactive) " : "", 
+
+    for (size_t i = 0; i &amp;lt; channelNames.length(); ++i) {
+      const bd::String chname(channelNames[i]);
+      const struct chanset_t* chan = channels[chname];
+      dprintf(idx, format, !conf.bot-&amp;gt;hub &amp;amp;&amp;amp; me_op(chan) ? '&amp;lt; at &amp;gt;' : ' ', chan-&amp;gt;dname, ((conf.bot-&amp;gt;hub &amp;amp;&amp;amp; channel_inactive(chan)) || (!conf.bot-&amp;gt;hub &amp;amp;&amp;amp; !shouldjoin(chan))) ? "(inactive) " : "",
            channel_privchan(chan) ? "(private)  " : "", chan-&amp;gt;manop ? "(no manop) " : "", 
            channel_bitch(chan) &amp;amp;&amp;amp; !channel_botbitch(chan) ? "(bitch)    " : channel_botbitch(chan) ? "(botbitch) " : "",
            channel_closed(chan) ?  "(closed) " : "", channel_backup(chan) ? "(backup)" : "");
     }
-  }
-  if (!first)
+  } else {
+    if (group.length()) {
+      dprintf(idx, "No channels found for group '%s'\n", group.c_str());
+    } else {
     dprintf(idx, "%s %s not have access to any channels.\n", handle ? u-&amp;gt;handle : "You", handle ? "does" : "do");
 }
+  }
+}
 
 /* Create a string with random letters and digits
  */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -614,9 +631,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int str_isdigit(const char *str)
  */
 void kill_bot(char *s1, char *s2)
 {
-  if (conf.bot-&amp;gt;hub)
     write_userfile(-1);
-  else
+  if (!conf.bot-&amp;gt;hub)
     server_die();
   chatout("*** %s\n", s1);
   botnet_send_chat(-1, conf.bot-&amp;gt;nick, s1);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -823,7 +839,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; restart(int idx)
 
   socks-&amp;gt;my_close();
 
-  if (conf.bot-&amp;gt;hub)
     write_userfile(idx);
 /*
   if (server_online) {
diff --git a/src/mod/Makefile.in b/src/mod/Makefile.in
index ea43226..d6c7ec1 100755
--- a/src/mod/Makefile.in
+++ b/src/mod/Makefile.in
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -38,7 +38,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; mod_objs = channels.mod_o \
 egg_ac_parameters = &amp;lt; at &amp;gt;egg_ac_parameters&amp;lt; at &amp;gt;
 
 MAKE_MOD = $(MAKE) 'MAKE=$(MAKE)' 'CXX=$(CXX)' 'LD=$(LD)' \
-'CCDEPMODE=$(CCDEPMODE)' \
+'CCDEPMODE=$(CCDEPMODE)' 'top_srcdir=$(MOD_UPDIR)$(top_srcdir)' \
 'STRIP=$(STRIP)' 'CXXFLAGS=$(MOD_CXXFLAGS)' 'CPPFLAGS=$(MOD_CPPFLAGS)' \
 'LIBS=$(LIBS)' 'SHELL=$(SHELL)'
 
diff --git a/src/mod/channels.mod/Makefile b/src/mod/channels.mod/Makefile
index b5e2305..e242b73 100755
--- a/src/mod/channels.mod/Makefile
+++ b/src/mod/channels.mod/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,12 +1,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 # Makefile for src/mod/channels.mod/
 
 srcdir = .
-depcomp = /bin/sh ../../../autotools/depcomp
+depcomp = /bin/sh ../../../build/autotools/depcomp
 
 #This line is simply for configure to generate .deps/
 OBJS = channels.o
 
 include ./.deps/includes
+include ../mod.mk
 
 doofus:
 &amp;lt; at &amp;gt;echo ""
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -16,14 +17,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; doofus:
 
 static: ../channels.o
 
-../channels.o:
-&amp;lt; at &amp;gt;echo -e "Compiling: \033[1mchannels\033[0m"
-source='channels.c' object='$&amp;lt; at &amp;gt;' depfile='.deps/channels.Po' tmpdepfile='.deps/channels.TPo' depmode=$(CCDEPMODE) $(depcomp) \
-$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/channels.c
-&amp;lt; at &amp;gt;rm -f ../channels.o
-&amp;lt; at &amp;gt;mv channels.o ../
-
-
 clean:
 &amp;lt; at &amp;gt;rm -f .depend *.o *~
 
diff --git a/src/mod/channels.mod/tclchan.c b/src/mod/channels.mod/chanmisc.c
similarity index 83%
rename from src/mod/channels.mod/tclchan.c
rename to src/mod/channels.mod/chanmisc.c
index be8368f..c5cd64f 100755
--- a/src/mod/channels.mod/tclchan.c
+++ b/src/mod/channels.mod/chanmisc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -306,7 +306,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int SplitList(char *resultBuf, const char *list, int *argcPtr, const char ***arg
  */
 int channel_modify(char *result, struct chanset_t *chan, int items, char **item, bool cmd)
 {
-  bool error = 0;
+  bool error = 0, changed_groups = false;
   int old_status = chan-&amp;gt;status,
       old_mode_mns_prot = chan-&amp;gt;mode_mns_prot,
       old_mode_pls_prot = chan-&amp;gt;mode_pls_prot;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -336,6 +336,20 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
       }
       strlcpy(s, item[i], sizeof(s));
       set_mode_protect(chan, s);
+    } else if (!strcmp(item[i], "groups")) {
+      i++;
+      if (i &amp;gt;= items) {
+if (result)
+  strlcpy(result, "channel groups needs argument", RESULT_LEN);
+return ERROR;
+      }
+      // Get string into right format
+      bd::String changroups(item[i]);
+      // Replace commas with spaces to be in proper format
+      changroups = changroups.sub(",", " ");
+      changroups.trim();
+      *(chan-&amp;gt;groups) = changroups.split(" ");
+      changed_groups = true;
     } else if (!strcmp(item[i], "topic")) {
       char *p = NULL;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -373,16 +387,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
       }
       chan-&amp;gt;limitraise = atoi(item[i]);
       chan-&amp;gt;limit_prot = 0;
-/*
-    } else if (!strcmp(item[i], "revenge-mode")) {
+    } else if (!strcmp(item[i], "fish-key")) {
       i++;
       if (i &amp;gt;= items) {
         if (result)
-          strlcpy(result, "channel revenge-mode needs argument", RESULT_LEN);
+          strlcpy(result, "channel fish-key needs argument", RESULT_LEN);
         return ERROR;
       }
-      chan-&amp;gt;revenge_mode = atoi(item[i]);
-*/
+      bd::String key(item[i]);
+      key.trim();
+      set_fish_key(chan-&amp;gt;dname, key);
+      strlcpy(chan-&amp;gt;fish_key, key.c_str(), sizeof(chan-&amp;gt;fish_key));
     } else if (!strcmp(item[i], "ban-time")) {
       i++;
       if (i &amp;gt;= items) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -407,6 +422,28 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
         return ERROR;
       }
       chan-&amp;gt;invite_time = atoi(item[i]);
+    } else if (!strcmp(item[i], "capslimit") || !strcmp(item[i], "caps-limit")) {
+      i++;
+      if (i &amp;gt;= items) {
+        if (result)
+          strlcpy(result, "channel caps-limit needs argument", RESULT_LEN);
+        return ERROR;
+      }
+      int capslimit = atoi(item[i]);
+      if (capslimit &amp;gt; 100 || capslimit &amp;lt; 0 || item[i][0] == '-') {
+        if (result)
+          strlcpy(result, "channel caps-limit out of range (0-100)", RESULT_LEN);
+        return ERROR;
+      }
+      chan-&amp;gt;capslimit = capslimit;
+    } else if (!strcmp(item[i], "colorlimit") || !strcmp(item[i], "color-limit")) {
+      i++;
+      if (i &amp;gt;= items) {
+        if (result)
+          strlcpy(result, "channel color-limit needs argument", RESULT_LEN);
+        return ERROR;
+      }
+      chan-&amp;gt;colorlimit = atoi(item[i]);
     } else if (!strcmp(item[i], "closed-ban")) {
       i++;
       if (i &amp;gt;= items) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -415,6 +452,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
         return ERROR;
       }
       chan-&amp;gt;closed_ban = atoi(item[i]);
+    } else if (!strcmp(item[i], "voice-moderate")) {
+      i++;
+      if (i &amp;gt;= items) {
+        if (result)
+          strlcpy(result, "channel voice-moderate needs argument", RESULT_LEN);
+        return ERROR;
+      }
+      chan-&amp;gt;voice_moderate = atoi(item[i]);
+      if (chan-&amp;gt;mode_mns_prot &amp;amp; CHANMODER &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate)
+        chan-&amp;gt;voice_moderate = 0;
     } else if (!strcmp(item[i], "closed-invite")) {
       i++;
       if (i &amp;gt;= items) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -475,6 +522,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
         return ERROR;
       }
       chan-&amp;gt;mop = deflag_translate(item[i]);
+    } else if (!strcmp(item[i], "revenge")) {
+      i++;
+      if (i &amp;gt;= items) {
+        if (result)
+          strlcpy(result, "channel revenge needs argument", RESULT_LEN);
+        return ERROR;
+      }
+      chan-&amp;gt;revenge = deflag_translate(item[i]);
     } else if (!strcmp(item[i], "knock")) {
       i++;
       if (i &amp;gt;= items) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -519,6 +574,27 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
         }
       } else
         chan-&amp;gt;flood_exempt_mode = atoi(item[i]);
+    } else if (!strcmp(item[i], "closed-exempt")) {
+      i++;
+      if (i &amp;gt;= items) {
+        if (result)
+          strlcpy(result, "channel closed-exempt needs argument", RESULT_LEN);
+        return ERROR;
+      }
+      if (!str_isdigit(item[i])) {
+        if (!strcasecmp("Op",  item[i]))
+          chan-&amp;gt;closed_exempt_mode = CHAN_FLAG_OP;
+        else if (!strcasecmp("Voice", item[i]))
+          chan-&amp;gt;closed_exempt_mode = CHAN_FLAG_VOICE;
+        else if (!strcasecmp("None", item[i]))
+          chan-&amp;gt;closed_exempt_mode = 0;
+        else {
+          if (result)
+            strlcpy(result, "channel closed-exempt only accepts Op|Voice|None", RESULT_LEN);
+          return ERROR;
+        }
+      } else
+        chan-&amp;gt;closed_exempt_mode = atoi(item[i]);
     } else if (!strcmp(item[i], "flood-lock-time")) {
       i++;
       if (i &amp;gt;= items) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -551,7 +627,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
         return ERROR;
       }
       chan-&amp;gt;protect_backup = atoi(item[i]);
-     
+    }
 
 /* Chanint template
  *  } else if (!strcmp(item[i], "temp")) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -563,9 +639,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
  *    }
  *    chan-&amp;gt;temp = atoi(item[i]);
  */
-    }
-
 
+    else if (!strcmp(item[i], "+floodban"))
+      chan-&amp;gt;status |= CHAN_FLOODBAN;
+    else if (!strcmp(item[i], "-floodban"))
+      chan-&amp;gt;status &amp;amp;= ~CHAN_FLOODBAN;
     else if (!strcmp(item[i], "+enforcebans"))
       chan-&amp;gt;status |= CHAN_ENFORCEBANS;
     else if (!strcmp(item[i], "-enforcebans"))
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -638,10 +716,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
       chan-&amp;gt;status |= CHAN_BOTBITCH;
     else if (!strcmp(item[i], "-botbitch"))
       chan-&amp;gt;status &amp;amp;= ~CHAN_BOTBITCH;
-    else if (!strcmp(item[i], "+nomassjoin"))
-      chan-&amp;gt;status |= CHAN_NOMASSJOIN;
-    else if (!strcmp(item[i], "-nomassjoin"))
-      chan-&amp;gt;status &amp;amp;= ~CHAN_NOMASSJOIN;
     else if (!strcmp(item[i], "+meankicks"))
       chan-&amp;gt;status |= CHAN_MEANKICKS;
     else if (!strcmp(item[i], "-meankicks"))
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -684,6 +758,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
     else if (!cmd &amp;amp;&amp;amp; !HAVE_TAKE &amp;amp;&amp;amp; !strcmp(item[i], "-take")) ;
     else if (!cmd &amp;amp;&amp;amp; !strcmp(item[i], "stopnethack-mode")) ;
     else if (!cmd &amp;amp;&amp;amp; !strcmp(item[i], "revenge-mode")) ;
+    else if (!cmd &amp;amp;&amp;amp; !strcmp(item[i], "+nomassjoin")) ;
+    else if (!cmd &amp;amp;&amp;amp; !strcmp(item[i], "-nomassjoin")) ;
     else if (!cmd &amp;amp;&amp;amp; !strcmp(item[i], "+revenge")) ;
     else if (!cmd &amp;amp;&amp;amp; !strcmp(item[i], "-revenge")) ;
     else if (!cmd &amp;amp;&amp;amp; !strcmp(item[i], "+revengebot")) ;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -742,10 +818,18 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
 
         chan-&amp;gt;flood_pub_thr = thr;
         chan-&amp;gt;flood_pub_time = time;
+        chan-&amp;gt;flood_mpub_thr = thr;
+        chan-&amp;gt;flood_mpub_time = time;
+        chan-&amp;gt;flood_bytes_thr = thr;
+        chan-&amp;gt;flood_bytes_time = time;
+        chan-&amp;gt;flood_mbytes_thr = thr;
+        chan-&amp;gt;flood_mbytes_time = time;
         chan-&amp;gt;flood_join_thr = thr;
         chan-&amp;gt;flood_join_time = time;
         chan-&amp;gt;flood_ctcp_thr = thr;
         chan-&amp;gt;flood_ctcp_time = time;
+        chan-&amp;gt;flood_mctcp_thr = thr;
+        chan-&amp;gt;flood_mctcp_time = time;
         chan-&amp;gt;flood_kick_thr = thr;
         chan-&amp;gt;flood_kick_time = time;
         chan-&amp;gt;flood_deop_thr = thr;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -757,6 +841,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
       } else if (!strcmp(item[i] + 6, "chan")) {
 pthr = &amp;amp;chan-&amp;gt;flood_pub_thr;
 ptime = &amp;amp;chan-&amp;gt;flood_pub_time;
+      } else if (!strcmp(item[i] + 6, "bytes")) {
+pthr = &amp;amp;chan-&amp;gt;flood_bytes_thr;
+ptime = &amp;amp;chan-&amp;gt;flood_bytes_time;
       } else if (!strcmp(item[i] + 6, "join")) {
 pthr = &amp;amp;chan-&amp;gt;flood_join_thr;
 ptime = &amp;amp;chan-&amp;gt;flood_join_time;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -775,6 +862,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
       } else if (!strcmp(item[i] + 6, "mjoin")) {
 pthr = &amp;amp;chan-&amp;gt;flood_mjoin_thr;
 ptime = &amp;amp;chan-&amp;gt;flood_mjoin_time;
+      } else if (!strcmp(item[i] + 6, "mpub")) {
+pthr = &amp;amp;chan-&amp;gt;flood_mpub_thr;
+ptime = &amp;amp;chan-&amp;gt;flood_mpub_time;
+      } else if (!strcmp(item[i] + 6, "mbytes")) {
+pthr = &amp;amp;chan-&amp;gt;flood_mbytes_thr;
+ptime = &amp;amp;chan-&amp;gt;flood_mbytes_time;
+      } else if (!strcmp(item[i] + 6, "mctcp")) {
+pthr = &amp;amp;chan-&amp;gt;flood_mctcp_thr;
+ptime = &amp;amp;chan-&amp;gt;flood_mctcp_time;
       } else { /* Ignore for optimal forward compatibility */
         i++;
         continue;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -811,15 +907,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
   }
 
   if ((chan-&amp;gt;status ^ old_status) &amp;amp; CHAN_TAKE)
-    chan-&amp;gt;status |= (CHAN_FASTOP|CHAN_BITCH);// to avoid bots still mass opping from +take from not using cookies
+    chan-&amp;gt;status |= CHAN_BITCH;// to avoid bots still mass opping from +take from not using cookies
 
   if (!conf.bot-&amp;gt;hub &amp;amp;&amp;amp; (chan != chanset_default)) {
-    if ((old_status ^ chan-&amp;gt;status) &amp;amp; (CHAN_INACTIVE | CHAN_BACKUP)) {
-      if (!shouldjoin(chan) &amp;amp;&amp;amp; (chan-&amp;gt;ircnet_status &amp;amp; (CHAN_ACTIVE | CHAN_PEND))) {
-        putlog(LOG_DEBUG, "*", "In %s, but I shouldn't be, parting...", chan-&amp;gt;dname);
-        dprintf(DP_SERVER, "PART %s\n", chan-&amp;gt;name[0] ? chan-&amp;gt;name : chan-&amp;gt;dname);
-      } else if (shouldjoin(chan))
-        join_chan(chan);
+    // Check if groups changed or +/-backup set
+    if (!restarting &amp;amp;&amp;amp; !loading &amp;amp;&amp;amp; (changed_groups || ((old_status ^ chan-&amp;gt;status) &amp;amp; (CHAN_INACTIVE | CHAN_BACKUP)))) {
+      check_shouldjoin(chan);
     }
     if (me_op(chan)) {
       if ((old_status ^ chan-&amp;gt;status) &amp;amp; (CHAN_ENFORCEBANS|CHAN_NOUSERBANS|CHAN_DYNAMICBANS|CHAN_NOUSEREXEMPTS|CHAN_NOUSERINVITES|CHAN_DYNAMICEXEMPTS|CHAN_DYNAMICINVITES)) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -875,6 +968,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void init_channel(struct chanset_t *chan, bool reset)
   chan-&amp;gt;channel.member-&amp;gt;nick[0] = 0;
   chan-&amp;gt;channel.member-&amp;gt;next = NULL;
   chan-&amp;gt;channel.topic = NULL;
+  chan-&amp;gt;channel.floodtime = new bd::HashTable&amp;lt;bd::String, bd::HashTable&amp;lt;flood_t, time_t&amp;gt; &amp;gt;;
+  chan-&amp;gt;channel.floodnum  = new bd::HashTable&amp;lt;bd::String, bd::HashTable&amp;lt;flood_t, int&amp;gt; &amp;gt;;
+  chan-&amp;gt;channel.cached_members = new bd::HashTable&amp;lt;bd::String, memberlist*&amp;gt;;
 }
 
 static void clear_masklist(masklist *m)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -901,7 +997,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void clear_channel(struct chanset_t *chan, bool reset)
     free(chan-&amp;gt;channel.topic);
   for (m = chan-&amp;gt;channel.member; m; m = m1) {
     m1 = m-&amp;gt;next;
-    free(m);
+    delete_member(m);
   }
 
   clear_masklist(chan-&amp;gt;channel.ban);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -916,6 +1012,29 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void clear_channel(struct chanset_t *chan, bool reset)
   chan-&amp;gt;ircnet_status = 0;
 //  chan-&amp;gt;ircnet_status &amp;amp;= ~CHAN_HAVEBANS;
 
+  delete chan-&amp;gt;channel.floodtime;
+  chan-&amp;gt;channel.floodtime = NULL;
+  delete chan-&amp;gt;channel.floodnum;
+  chan-&amp;gt;channel.floodnum = NULL;
+
+  if (chan-&amp;gt;channel.cached_members) {
+    if (chan-&amp;gt;channel.cached_members-&amp;gt;size()) {
+      bd::Array&amp;lt;bd::String&amp;gt; member_uhosts(chan-&amp;gt;channel.cached_members-&amp;gt;keys());
+      for (size_t i = 0; i &amp;lt; member_uhosts.length(); ++i) {
+        const bd::String uhost(member_uhosts[i]);
+
+        // Delete the cached member
+        m = (*chan-&amp;gt;channel.cached_members)[uhost];
+        delete_member(m);
+
+        // Remove the cached member (not technically needed as it is deleted below, but for completeness.)
+        chan-&amp;gt;channel.cached_members-&amp;gt;remove(uhost);
+      }
+    }
+    delete chan-&amp;gt;channel.cached_members;
+    chan-&amp;gt;channel.cached_members = NULL;
+  }
+
   if (reset)
     init_channel(chan, 1);
   for (size_t i = 0; i &amp;lt; MODES_PER_LINE_MAX; ++i) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -928,6 +1047,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void clear_channel(struct chanset_t *chan, bool reset)
       chan-&amp;gt;ccmode[i].op = NULL;
     }
   }
+
 }
 
 /* Create new channel and parse commands.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -989,31 +1109,45 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_add(char *result, const char *newname, char *options, bool isdefault
     chan-&amp;gt;closed_ban = 0;
     chan-&amp;gt;closed_private = 1;
     chan-&amp;gt;closed_invite = 1;
+    chan-&amp;gt;voice_moderate = 1;
     chan-&amp;gt;voice_non_ident = 1;
     chan-&amp;gt;auto_delay = 5;
     chan-&amp;gt;ban_type = 3;
+    chan-&amp;gt;revenge = DEFLAG_REACT;
 /* Chanint template
  *  chan-&amp;gt;temp = 0;
  */
+    chan-&amp;gt;groups = new bd::Array&amp;lt;bd::String&amp;gt;;
+    *(chan-&amp;gt;groups) &amp;lt;&amp;lt; "main";
     chan-&amp;gt;protect_backup = 1;
+    chan-&amp;gt;fish_key[0] = 0;
     chan-&amp;gt;knock_flags = 0;
     chan-&amp;gt;flood_lock_time = 120;
     chan-&amp;gt;flood_exempt_mode = 0;
-    chan-&amp;gt;flood_pub_thr = gfld_chan_thr;
-    chan-&amp;gt;flood_pub_time = gfld_chan_time;
-    chan-&amp;gt;flood_ctcp_thr = gfld_ctcp_thr;
-    chan-&amp;gt;flood_ctcp_time = gfld_ctcp_time;
-    chan-&amp;gt;flood_join_thr = gfld_join_thr;
-    chan-&amp;gt;flood_join_time = gfld_join_time;
-    chan-&amp;gt;flood_deop_thr = gfld_deop_thr;
-    chan-&amp;gt;flood_deop_time = gfld_deop_time;
-    chan-&amp;gt;flood_kick_thr = gfld_kick_thr;
-    chan-&amp;gt;flood_kick_time = gfld_kick_time;
-    chan-&amp;gt;flood_nick_thr = gfld_nick_thr;
-    chan-&amp;gt;flood_nick_time = gfld_nick_time;
+    chan-&amp;gt;flood_pub_thr = 0;
+    chan-&amp;gt;flood_pub_time = 0;
+    chan-&amp;gt;flood_bytes_thr = 0;
+    chan-&amp;gt;flood_bytes_time = 0;
+    chan-&amp;gt;flood_ctcp_thr = 5;
+    chan-&amp;gt;flood_ctcp_time = 30;
+    chan-&amp;gt;flood_join_thr = 0;
+    chan-&amp;gt;flood_join_time = 0;
+    chan-&amp;gt;flood_deop_thr = 8;
+    chan-&amp;gt;flood_deop_time = 10;
+    chan-&amp;gt;flood_kick_thr = 0;
+    chan-&amp;gt;flood_kick_time = 0;
+    chan-&amp;gt;flood_nick_thr = 0;
+    chan-&amp;gt;flood_nick_time = 0;
     chan-&amp;gt;flood_mjoin_thr = 6;
     chan-&amp;gt;flood_mjoin_time = 1;
-//    chan-&amp;gt;revenge_mode = global_revenge_mode;
+    chan-&amp;gt;capslimit = 0;
+    chan-&amp;gt;colorlimit = 0;
+    chan-&amp;gt;flood_mpub_thr = 20;
+    chan-&amp;gt;flood_mpub_time = 1;
+    chan-&amp;gt;flood_mbytes_thr = 1000;
+    chan-&amp;gt;flood_mbytes_time = 1;
+    chan-&amp;gt;flood_mctcp_thr = 7;
+    chan-&amp;gt;flood_mctcp_time = 1;
     chan-&amp;gt;limitraise = 20;
     chan-&amp;gt;ban_time = global_ban_time;
     chan-&amp;gt;exempt_time = global_exempt_time;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1025,6 +1159,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_add(char *result, const char *newname, char *options, bool isdefault
     chan-&amp;gt;channel.drone_jointime = 0;
     chan-&amp;gt;channel.drone_joins = 0;
     chan-&amp;gt;channel.last_eI = 0;
+    chan-&amp;gt;channel.floodtime = NULL;
+    chan-&amp;gt;channel.floodnum = NULL;
 
     /* We _only_ put the dname (display name) in here so as not to confuse
      * any code later on. chan-&amp;gt;name gets updated with the channel name as
diff --git a/src/mod/channels.mod/channels.c b/src/mod/channels.mod/channels.c
index 961801f..c00f429 100755
--- a/src/mod/channels.mod/channels.c
+++ b/src/mod/channels.mod/channels.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -54,7 +54,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 static bool use_info = 1;
 static char glob_chanmode[64] = "nt";/* Default chanmode (drummer,990731) */
-//static int global_revenge_mode = 3;
 static interval_t global_ban_time;
 static interval_tglobal_exempt_time;
 static interval_t global_invite_time;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -62,25 +61,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static interval_t global_invite_time;
 
 static char *lastdeletedmask = NULL;
 
-/* Global flood settings */
-static int gfld_chan_thr;
-static interval_t gfld_chan_time;
-static int gfld_deop_thr = 8;
-static interval_t gfld_deop_time = 10;
-static int gfld_kick_thr;
-static interval_t gfld_kick_time;
-static int gfld_join_thr;
-static interval_t gfld_join_time;
-static int gfld_ctcp_thr = 5;
-static interval_t gfld_ctcp_time = 30;
-static intgfld_nick_thr;
-static interval_tgfld_nick_time;
-
 static int killed_bots = 0;
 
 #include "channels.h"
 #include "cmdschan.c"
-#include "tclchan.c"
+#include "chanmisc.c"
 #include "userchan.c"
 
 /* This will close channels if the HUB:leaf count is skewed from config setting */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -582,6 +567,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void set_mode_protect(struct chanset_t *chan, char *set)
 
   if (chan-&amp;gt;mode_mns_prot &amp;amp; CHANINV &amp;amp;&amp;amp; chan-&amp;gt;closed_invite)
     chan-&amp;gt;closed_invite = 0;
+
+  if (chan-&amp;gt;mode_mns_prot &amp;amp; CHANMODER &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate)
+    chan-&amp;gt;voice_moderate = 0;
 }
 
 static void get_mode_protect(struct chanset_t *chan, char *s, size_t ssiz)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -721,6 +709,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void remove_channel(struct chanset_t *chan)
      free(chan-&amp;gt;key);
    if (chan-&amp;gt;rmkey)
      free(chan-&amp;gt;rmkey);
+   if (chan-&amp;gt;groups) {
+     delete(chan-&amp;gt;groups);
+   }
+   delete chan-&amp;gt;channel.floodtime;
+   delete chan-&amp;gt;channel.floodnum;
    free(chan);
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -800,8 +793,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void channels_report(int idx, int details)
         if (chan-&amp;gt;closed_private)
           strlcat(s2, "p", sizeof(s2));
       }
+      if (channel_voice(chan) &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate) {
+        strlcat(s2, "m", sizeof(s2));
+      }
 
-      if (shouldjoin(chan)) {
+      if (conf.bot-&amp;gt;hub || shouldjoin(chan)) {
 if (channel_active(chan)) {
   /* If it's a !chan, we want to display it's unique name too &amp;lt;cybah&amp;gt; */
   if (chan-&amp;gt;dname[0]=='!') {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -837,12 +833,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void channels_report(int idx, int details)
   i += my_strcpy(s + i, "userbans ");
 if (channel_bitch(chan))
   i += my_strcpy(s + i, "bitch ");
-/*
-if (channel_revenge(chan))
-  i += my_strcpy(s + i, "revenge ");
-if (channel_revenge(chan))
-  i += my_strcpy(s + i, "revengebot ");
-*/
 if (channel_secret(chan))
   i += my_strcpy(s + i, "secret ");
 if (channel_cycle(chan))
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -879,8 +869,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void channels_report(int idx, int details)
  *if (channel_temp(chan))
  *  i += my_strcpy(s + i, "temp ");
 */
-        if (channel_nomassjoin(chan))
-          i += my_strcpy(s + i, "nomassjoin ");
         if (channel_botbitch(chan))
           i += my_strcpy(s + i, "botbitch ");
         if (channel_backup(chan))
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -893,11 +881,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void channels_report(int idx, int details)
 dprintf(idx, "      Options: %s\n", s);
         if (chan-&amp;gt;limitraise)
           dprintf(idx, "      Raising limit +%d every 2 minutes\n", chan-&amp;gt;limitraise);
-/*
-        if (chan-&amp;gt;revenge_mode)
-          dprintf(idx, "      revenge-mode %d\n",
-                  chan-&amp;gt;revenge_mode);
-*/
        dprintf(idx, "    Bans last %d mins.\n", chan-&amp;gt;ban_time);
        dprintf(idx, "    Exemptions last %d mins.\n", chan-&amp;gt;exempt_time);
        dprintf(idx, "    Invitations last %d mins.\n", chan-&amp;gt;invite_time);
diff --git a/src/mod/channels.mod/channels.h b/src/mod/channels.mod/channels.h
index 7ce8377..7cb7617 100755
--- a/src/mod/channels.mod/channels.h
+++ b/src/mod/channels.mod/channels.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -53,7 +53,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *, struct chanset_t *, int, char **, bool);
 int channel_add(char *, const char *, char *, bool = 0);
 void clear_channel(struct chanset_t *, bool);
 int u_equals_mask(maskrec *, char *);
-bool u_match_mask(struct maskrec *, char *);
+bool u_match_mask(struct maskrec *, const char *);
 bool ismasked(masklist *, const char *);
 bool ismodeline(masklist *, const char *);
 void channels_report(int, int);
diff --git a/src/mod/channels.mod/cmdschan.c b/src/mod/channels.mod/cmdschan.c
index 0db703c..c49ae5a 100755
--- a/src/mod/channels.mod/cmdschan.c
+++ b/src/mod/channels.mod/cmdschan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1008,29 +1008,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_pls_chan(int idx, char *par)
   pls_chan(idx, par, NULL);
 }
 
-static void cmd_botjoin(int idx, char *par)
-{
-  char *bot = NULL;
-  struct userrec *botu = NULL;
-
-  putlog(LOG_CMDS, "*", "#%s# botjoin %s", dcc[idx].nick, par);
-
-  if (!par[0]) {
-    dprintf(idx, "Usage: botjoin &amp;lt;bot&amp;gt; [%s]&amp;lt;channel&amp;gt; [options]\n", CHANMETA);
-    return;
-  }
-  bot = newsplit(&amp;amp;par);
-  botu = get_user_by_handle(userlist, bot);
-  if (botu &amp;amp;&amp;amp; botu-&amp;gt;bot) {
-    pls_chan(idx, par, bot);
-  } else {
-    dprintf(idx, "Error: '%s' is not a bot.\n", bot);
-  }
-
-  dprintf(idx, "!!!! Warning: botjoin is an unfinished feature which will pretty much make all bots join the channel.\n");
-  dprintf(idx, "!!!! Warning: You should probably -chan the channel now to avoid problems/confusion later.\n");
-}
-
 static void mns_chan(int idx, char *par, char *bot)
 {
   char *chname = NULL, buf2[1024] = "";
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1084,27 +1061,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_mns_chan(int idx, char *par)
   mns_chan(idx, par, NULL);
 }
 
-static void cmd_botpart(int idx, char *par)
-{
-  char *bot = NULL;
-  struct userrec *botu = NULL;
-
-  putlog(LOG_CMDS, "*", "#%s# botpart %s", dcc[idx].nick, par);
-  
-  if (!par[0]) {
-    dprintf(idx, "Usage: botpart &amp;lt;bot&amp;gt; [%s]&amp;lt;channel&amp;gt; [options]\n", CHANMETA);
-    return;
-  }
-
-  bot = newsplit(&amp;amp;par);
-  botu = get_user_by_handle(userlist, bot);
-  if (botu &amp;amp;&amp;amp; botu-&amp;gt;bot) {
-    mns_chan(idx, par, bot);
-  } else {
-    dprintf(idx, "Error: '%s' is not a bot.\n", bot);
-  }
-}
-
 /* thanks Excelsior */
 #define FLAG_COLS 4
 static void show_flag(int idx, char *work, int *cnt, const char *name, unsigned int state, size_t worksiz)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1179,7 +1135,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void show_int(int idx, char *work, int *cnt, const char *desc, int state,
 
 #define SHOW_FLAG(name, state) show_flag(idx, work, &amp;amp;cnt, name, state, sizeof(work))
 #define SHOW_INT(desc, state, yes, no) show_int(idx, work, &amp;amp;cnt, desc, state, yes, no, sizeof(work))
-#define P_STR deflag == P_KICK ? "Kick" : (deflag == P_DEOP ? "Deop" : (deflag == P_DELETE ? "Remove" : NULL))
+#define DEFLAG_STR deflag == DEFLAG_KICK ? "Kick" : (deflag == DEFLAG_DEOP ? "Deop" : (deflag == DEFLAG_DELETE ? "Remove" : (deflag == DEFLAG_REACT ? "React" : NULL)))
 #define F_STR(x) x == CHAN_FLAG_OP ? "Op" : (x == CHAN_FLAG_VOICE ? "Voice" : (x == CHAN_FLAG_USER ? "User" : NULL))
 static void cmd_chaninfo(int idx, char *par)
 {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1228,6 +1184,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_chaninfo(int idx, char *par)
 /* FIXME: SHOW_CHAR() here */
     get_mode_protect(chan, work, sizeof(work));
     dprintf(idx, "Protect modes (chanmode): %s\n", work[0] ? work : "None");
+    dprintf(idx, "Groups: %s\n", chan-&amp;gt;groups &amp;amp;&amp;amp; chan-&amp;gt;groups-&amp;gt;length() ? static_cast&amp;lt;bd::String&amp;gt;(chan-&amp;gt;groups-&amp;gt;join(" ")).c_str() : "None");
+    dprintf(idx, "FiSH Key: %s\n", chan-&amp;gt;fish_key[0] ? chan-&amp;gt;fish_key : "not set");
 //    dprintf(idx, "Protect topic (topic)   : %s\n", chan-&amp;gt;topic[0] ? chan-&amp;gt;topic : "");
 /* Chanchar template
  *  dprintf(idx, "String temp: %s\n", chan-&amp;gt;temp[0] ? chan-&amp;gt;temp : "NULL");
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1242,15 +1200,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_chaninfo(int idx, char *par)
     SHOW_FLAG("cycle",channel_cycle(chan));
     SHOW_FLAG("enforcebans", channel_enforcebans(chan));
     SHOW_FLAG("fastop",channel_fastop(chan));
+    SHOW_FLAG("floodban", channel_floodban(chan));
     SHOW_FLAG("inactive",channel_inactive(chan));
     SHOW_FLAG("meankicks",channel_meankicks(chan));
     SHOW_FLAG("nodesynch",channel_nodesynch(chan));
-    SHOW_FLAG("nomassjoin",channel_nomassjoin(chan));
     SHOW_FLAG("private",channel_privchan(chan));
     SHOW_FLAG("protect",channel_protect(chan));
     SHOW_FLAG("rbl",channel_rbl(chan));
-//    SHOW_FLAG("revengebot",channel_revengebot(chan));
-//    SHOW_FLAG("revenge",channel_revenge(chan));
     if (HAVE_TAKE)
       SHOW_FLAG("take",channel_take(chan));
     SHOW_FLAG("voice",channel_voice(chan));
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1277,39 +1233,46 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_chaninfo(int idx, char *par)
     dprintf(idx, "Channel settings:\n");
     deflag = chan-&amp;gt;bad_cookie;
     SHOW_INT("Auto-delay: ", chan-&amp;gt;auto_delay, NULL, "None");
-    SHOW_INT("Bad-cookie:" , chan-&amp;gt;bad_cookie, P_STR, "Ignore");
+    SHOW_INT("Bad-cookie:" , chan-&amp;gt;bad_cookie, DEFLAG_STR, "Ignore");
     SHOW_INT("Ban-time: ", chan-&amp;gt;ban_time, NULL, "Forever");
     SHOW_INT("Ban-type: ", chan-&amp;gt;ban_type, NULL, "3");
     SHOW_INT("Closed-ban: ", chan-&amp;gt;closed_ban, NULL, "Don't!");
     SHOW_INT("Closed-invite:", chan-&amp;gt;closed_invite, NULL, "Don't!");
     SHOW_INT("Closed-Private:", chan-&amp;gt;closed_private, NULL, "Don't!");
+    SHOW_INT("Closed-Exempt:", chan-&amp;gt;closed_exempt_mode, F_STR(chan-&amp;gt;closed_exempt_mode), "None");
     SHOW_INT("Exempt-time: ", chan-&amp;gt;exempt_time, NULL, "Forever");
     SHOW_INT("Flood-exempt: ", chan-&amp;gt;flood_exempt_mode, F_STR(chan-&amp;gt;flood_exempt_mode), "None");
     SHOW_INT("Flood-lock-time: ", chan-&amp;gt;flood_lock_time, NULL, "Don't");
+    SHOW_INT("Caps-Limit(%): ", chan-&amp;gt;capslimit, NULL, "None");
+    SHOW_INT("Color-Limit: ", chan-&amp;gt;colorlimit, NULL, "None");
     SHOW_INT("Invite-time: ", chan-&amp;gt;invite_time, NULL, "Forever");
     SHOW_INT("Knock: ", chan-&amp;gt;knock_flags, F_STR(chan-&amp;gt;knock_flags), "None");
     SHOW_INT("Limit raise (limit): ", chan-&amp;gt;limitraise, NULL, "Disabled");
     deflag = chan-&amp;gt;manop;
-    SHOW_INT("Manop: ", chan-&amp;gt;manop, P_STR, "Ignore");
+    SHOW_INT("Manop: ", chan-&amp;gt;manop, DEFLAG_STR, "Ignore");
     deflag = chan-&amp;gt;mdop;
-    SHOW_INT("Mdop: ", chan-&amp;gt;mdop, P_STR, "Ignore");
+    SHOW_INT("Mdop: ", chan-&amp;gt;mdop, DEFLAG_STR, "Ignore");
     deflag = chan-&amp;gt;mop;
-    SHOW_INT("Mop: ", chan-&amp;gt;mop, P_STR, "Ignore");
-//    SHOW_INT("Revenge-mode: ", chan-&amp;gt;revenge_mode, NULL, NULL);
+    SHOW_INT("Mop: ", chan-&amp;gt;mop, DEFLAG_STR, "Ignore");
+    deflag = chan-&amp;gt;revenge;
+    SHOW_INT("Revenge: ", chan-&amp;gt;revenge, DEFLAG_STR, "Ignore");
     SHOW_INT("Protect-backup: ", chan-&amp;gt;protect_backup, "Do!", "Don't!");
     SHOW_INT("Voice-non-ident: ", chan-&amp;gt;voice_non_ident, "Do!", "Don't!");
+    SHOW_INT("Voice-moderate:", chan-&amp;gt;voice_moderate, NULL, "Don't!");
 
-    dprintf(idx, "Flood settings:   chan ctcp join kick deop nick mjoin\n");
-    dprintf(idx, "  number:          %3d  %3d  %3d  %3d  %3d  %3d  %3d\n",
-    chan-&amp;gt;flood_pub_thr, chan-&amp;gt;flood_ctcp_thr,
+    dprintf(idx, "Flood settings:   chan bytes ctcp join kick deop nick mjoin mpub mbytes mctcp\n");
+    dprintf(idx, "  number:          %3d  %4d  %3d  %3d  %3d  %3d  %3d   %3d  %3d   %4d   %3d\n",
+    chan-&amp;gt;flood_pub_thr, chan-&amp;gt;flood_bytes_thr, chan-&amp;gt;flood_ctcp_thr,
     chan-&amp;gt;flood_join_thr, chan-&amp;gt;flood_kick_thr,
     chan-&amp;gt;flood_deop_thr, chan-&amp;gt;flood_nick_thr,
-            chan-&amp;gt;flood_mjoin_thr);
-    dprintf(idx, "  time  :          %3u  %3u  %3u  %3u  %3u  %3u  %3u\n",
-    chan-&amp;gt;flood_pub_time, chan-&amp;gt;flood_ctcp_time,
+            chan-&amp;gt;flood_mjoin_thr, chan-&amp;gt;flood_mpub_thr,
+            chan-&amp;gt;flood_mbytes_thr, chan-&amp;gt;flood_mctcp_thr);
+    dprintf(idx, "  time  :          %3u  %4u  %3u  %3u  %3u  %3u  %3u   %3u  %3u   %4u  %4u\n",
+    chan-&amp;gt;flood_pub_time, chan-&amp;gt;flood_bytes_time, chan-&amp;gt;flood_ctcp_time,
     chan-&amp;gt;flood_join_time, chan-&amp;gt;flood_kick_time,
     chan-&amp;gt;flood_deop_time, chan-&amp;gt;flood_nick_time,
-            chan-&amp;gt;flood_mjoin_time);
+            chan-&amp;gt;flood_mjoin_time, chan-&amp;gt;flood_mpub_time,
+            chan-&amp;gt;flood_mbytes_time, chan-&amp;gt;flood_mctcp_time);
   }
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1419,8 +1382,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static cmd_t C_dcc_channels[] =
   {"-exempt","o|o",(Function) cmd_mns_exempt,NULL, AUTH},
   {"-invite","o|o",(Function) cmd_mns_invite,NULL, AUTH},
   {"bans","o|o",(Function) cmd_bans,NULL, 0},
-  {"botjoin","n",(Function) cmd_botjoin,NULL, 0},
-  {"botpart","n",(Function) cmd_botpart,NULL, 0},
   {"exempts","o|o",(Function) cmd_exempts,NULL, 0},
   {"invites","o|o",(Function) cmd_invites,NULL, 0},
   {"chaninfo","m|m",(Function) cmd_chaninfo,NULL, 0},
diff --git a/src/mod/channels.mod/userchan.c b/src/mod/channels.mod/userchan.c
index c692443..48a599e 100755
--- a/src/mod/channels.mod/userchan.c
+++ b/src/mod/channels.mod/userchan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -219,7 +219,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int u_equals_mask(maskrec *u, char *mask)
   return 0;
 }
 
-bool u_match_mask(maskrec *rec, char *mask)
+bool u_match_mask(maskrec *rec, const char *mask)
 {
   for (; rec; rec = rec-&amp;gt;next)
     if (wild_match(rec-&amp;gt;mask, mask) || match_cidr(rec-&amp;gt;mask, mask))
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -701,9 +701,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void write_chan(bd::Stream&amp;amp; stream, int idx, struct chanset_t* chan)
   putlog(LOG_DEBUG, "*", "writing channel %s to userfile..", chan-&amp;gt;dname);
 
   bool force_inactive = 0;
-  /* if a bot should explicitly NOT join, just set it +inactive ... */
-  if (idx &amp;gt;= 0 &amp;amp;&amp;amp; !botshouldjoin(dcc[idx].user, chan))
-    force_inactive = 1;
 
   stream &amp;lt;&amp;lt; bd::String::printf("+ channel add %s { ", chan-&amp;gt;dname);
   if (chan != chanset_default)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -717,34 +714,43 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; bd::String channel_to_string(struct chanset_t* chan, bool force_inactive) {
 
   get_mode_protect(chan, w, sizeof(w));
   return bd::String::printf("\
-chanmode { %s } bad-cookie %d manop %d mdop %d mop %d limit %d ban-type %d \
-flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
+chanmode { %s } groups { %s } bad-cookie %d manop %d mdop %d mop %d limit %d revenge %d ban-type %d \
+flood-chan %d:%d flood-bytes %d:%d flood-ctcp %d:%d flood-join %d:%d \
 flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d flood-mjoin %d:%d \
-closed-ban %d closed-invite %d closed-private %d ban-time %d \
-exempt-time %d invite-time %d voice-non-ident %d auto-delay %d \
-flood-exempt %d flood-lock-time %d knock %d \
-%cmeankicks %cenforcebans %cdynamicbans %cuserbans %cbitch \
+flood-mpub %d:%d flood-mbytes %d:%d flood-mctcp %d:%d \
+capslimit %d colorlimit %d closed-ban %d closed-invite %d closed-private %d closed-exempt %d ban-time %d \
+exempt-time %d invite-time %d voice-non-ident %d voice-moderate %d auto-delay %d \
+flood-exempt %d flood-lock-time %d knock %d fish-key { %s } \
+%cmeankicks %cenforcebans %cdynamicbans %cuserbans %cbitch %cfloodban \
 %cprivate %ccycle %cinactive %cdynamicexempts %cuserexempts \
 %cdynamicinvites %cuserinvites %cnodesynch %cclosed %cvoice \
-%cfastop %cautoop %cbotbitch %cbackup %cnomassjoin %crbl %cvoicebitch %cprotect protect-backup %d %c%s",
+%cfastop %cautoop %cbotbitch %cbackup %crbl %cvoicebitch %cprotect protect-backup %d %c%s",
 w,
 /* Chanchar template
  *      temp,
  * also include temp %s in dprintf.
  */
+        chan-&amp;gt;groups &amp;amp;&amp;amp; chan-&amp;gt;groups-&amp;gt;length() ? static_cast&amp;lt;bd::String&amp;gt;(chan-&amp;gt;groups-&amp;gt;join(" ")).c_str() : "",
 chan-&amp;gt;bad_cookie,
 chan-&amp;gt;manop,
 chan-&amp;gt;mdop,
 chan-&amp;gt;mop,
         chan-&amp;gt;limitraise,
+chan-&amp;gt;revenge,
         chan-&amp;gt;ban_type,
 chan-&amp;gt;flood_pub_thr, chan-&amp;gt;flood_pub_time,
+chan-&amp;gt;flood_bytes_thr, chan-&amp;gt;flood_bytes_time,
         chan-&amp;gt;flood_ctcp_thr, chan-&amp;gt;flood_ctcp_time,
         chan-&amp;gt;flood_join_thr, chan-&amp;gt;flood_join_time,
         chan-&amp;gt;flood_kick_thr, chan-&amp;gt;flood_kick_time,
         chan-&amp;gt;flood_deop_thr, chan-&amp;gt;flood_deop_time,
 chan-&amp;gt;flood_nick_thr, chan-&amp;gt;flood_nick_time,
 chan-&amp;gt;flood_mjoin_thr, chan-&amp;gt;flood_mjoin_time,
+chan-&amp;gt;flood_mpub_thr, chan-&amp;gt;flood_mpub_time,
+chan-&amp;gt;flood_mbytes_thr, chan-&amp;gt;flood_mbytes_time,
+chan-&amp;gt;flood_mctcp_thr, chan-&amp;gt;flood_mctcp_time,
+        chan-&amp;gt;capslimit,
+        chan-&amp;gt;colorlimit,
         chan-&amp;gt;closed_ban,
 /* Chanint template
  *      chan-&amp;gt;temp,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -752,19 +758,23 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; flood-exempt %d flood-lock-time %d knock %d \
  */
         chan-&amp;gt;closed_invite,
         chan-&amp;gt;closed_private,
+        chan-&amp;gt;closed_exempt_mode,
         chan-&amp;gt;ban_time,
         chan-&amp;gt;exempt_time,
         chan-&amp;gt;invite_time,
         chan-&amp;gt;voice_non_ident,
+        chan-&amp;gt;voice_moderate,
         chan-&amp;gt;auto_delay,
         chan-&amp;gt;flood_exempt_mode,
         chan-&amp;gt;flood_lock_time,
         chan-&amp;gt;knock_flags,
+        chan-&amp;gt;fish_key,
  PLSMNS(channel_meankicks(chan)),
  PLSMNS(channel_enforcebans(chan)),
 PLSMNS(channel_dynamicbans(chan)),
 PLSMNS(!channel_nouserbans(chan)),
 PLSMNS(channel_bitch(chan)),
+PLSMNS(channel_floodban(chan)),
 PLSMNS(channel_privchan(chan)),
 PLSMNS(channel_cycle(chan)),
         force_inactive ? '+' : PLSMNS(channel_inactive(chan)),
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -779,7 +789,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; flood-exempt %d flood-lock-time %d knock %d \
         PLSMNS(channel_autoop(chan)),
         PLSMNS(channel_botbitch(chan)),
         PLSMNS(channel_backup(chan)),
-        PLSMNS(channel_nomassjoin(chan)),
         PLSMNS(channel_rbl(chan)),
         PLSMNS(channel_voicebitch(chan)),
         PLSMNS(channel_protect(chan)),
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -825,11 +834,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void write_chans_compat(bd::Stream&amp;amp; stream, int idx)
     putlog(LOG_DEBUG, "*", "writing channel %s to userfile..", chan-&amp;gt;dname);
     get_mode_protect(chan, w, sizeof(w));
 
-    /* if a bot should explicitly NOT join, just set it +inactive ... */
-    if (idx &amp;gt;= 0 &amp;amp;&amp;amp; !botshouldjoin(dcc[idx].user, chan))
-      inactive = '+';
-    /* ... otherwise give the bot the *actual* setting */
-    else
       inactive = PLSMNS(channel_inactive(chan));
 
     stream &amp;lt;&amp;lt; bd::String::printf("\
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -837,12 +841,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void write_chans_compat(bd::Stream&amp;amp; stream, int idx)
 bad-cookie %d manop %d mdop %d mop %d limit %d \
 flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
 flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d \
-closed-ban %d closed-invite %d closed-private %d ban-time %d \
+caps-limit %d color-limit %d closed-ban %d closed-invite %d closed-private %d ban-time %d \
 exempt-time %d invite-time %d voice-non-ident %d auto-delay %d \
 %cenforcebans %cdynamicbans %cuserbans %cbitch \
 %cprivate %ccycle %cinactive %cdynamicexempts %cuserexempts \
 %cdynamicinvites %cuserinvites %cnodesynch %cclosed %cvoice \
-%cfastop %cautoop %cbotbitch %cbackup %cnomassjoin %c%s}\n",
+%cfastop %cautoop %cbotbitch %cbackup %c%s}\n",
 chan-&amp;gt;dname,
 w,
         chan-&amp;gt;added_by,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -858,6 +862,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; exempt-time %d invite-time %d voice-non-ident %d auto-delay %d \
         chan-&amp;gt;flood_kick_thr, chan-&amp;gt;flood_kick_time,
         chan-&amp;gt;flood_deop_thr, chan-&amp;gt;flood_deop_time,
 chan-&amp;gt;flood_nick_thr, chan-&amp;gt;flood_nick_time,
+        chan-&amp;gt;capslimit,
+        chan-&amp;gt;colorlimit,
         chan-&amp;gt;closed_ban,
         chan-&amp;gt;closed_invite,
         chan-&amp;gt;closed_private,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -884,7 +890,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; exempt-time %d invite-time %d voice-non-ident %d auto-delay %d \
         PLSMNS(channel_autoop(chan)),
         PLSMNS(channel_botbitch(chan)),
         PLSMNS(channel_backup(chan)),
-        PLSMNS(channel_nomassjoin(chan)),
 HAVE_TAKE ? PLSMNS(channel_take(chan)) : ' ',
         HAVE_TAKE ? "take " : " "
     );
diff --git a/src/mod/compress.mod/Makefile b/src/mod/compress.mod/Makefile
index f2937bf..e23efe3 100755
--- a/src/mod/compress.mod/Makefile
+++ b/src/mod/compress.mod/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,12 +1,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 # Makefile for src/mod/compress.mod/
 
 srcdir = .
-depcomp = /bin/sh ../../../autotools/depcomp
+depcomp = /bin/sh ../../../build/autotools/depcomp
 
 #This line is simply for configure to generate .deps/
 OBJS = compress.o
 
 include ./.deps/includes
+include ../mod.mk
 
 doofus:
 &amp;lt; at &amp;gt;echo ""
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -16,13 +17,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; doofus:
 
 static: ../compress.o
 
-../compress.o:
-&amp;lt; at &amp;gt;echo -e "Compiling: \033[1mcompress\033[0m"
-source='compress.c' object='$&amp;lt; at &amp;gt;' depfile='.deps/compress.Po' tmpdepfile='.deps/compress.TPo' depmode=$(CCDEPMODE) $(depcomp) \
-$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/compress.c
-&amp;lt; at &amp;gt;rm -f ../compress.o
-&amp;lt; at &amp;gt;mv compress.o ../
-
 clean:
 &amp;lt; at &amp;gt;rm -f .depend *.o *~
 
diff --git a/src/mod/console.mod/Makefile b/src/mod/console.mod/Makefile
index 3ce2068..8848bfd 100755
--- a/src/mod/console.mod/Makefile
+++ b/src/mod/console.mod/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,12 +1,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 # Makefile for src/mod/console.mod/
 
 srcdir = .
-depcomp = /bin/sh ../../../autotools/depcomp
+depcomp = /bin/sh ../../../build/autotools/depcomp
 
 #This line is simply for configure to generate .deps/
 OBJS = console.o
 
 include ./.deps/includes
+include ../mod.mk
 
 doofus:
 &amp;lt; at &amp;gt;echo ""
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -16,13 +17,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; doofus:
 
 static: ../console.o
 
-../console.o:
-&amp;lt; at &amp;gt;echo -e "Compiling: \033[1mconsole\033[0m"
-source='console.c' object='$&amp;lt; at &amp;gt;' depfile='.deps/console.Po' tmpdepfile='.deps/console.TPo' depmode=$(CCDEPMODE) $(depcomp) \
-$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/console.c
-&amp;lt; at &amp;gt;rm -f ../console.o
-&amp;lt; at &amp;gt;mv console.o ../
-
 clean:
 &amp;lt; at &amp;gt;rm -f .depend *.o *~
 
diff --git a/src/mod/ctcp.mod/Makefile b/src/mod/ctcp.mod/Makefile
index ef3ddf2..b316405 100755
--- a/src/mod/ctcp.mod/Makefile
+++ b/src/mod/ctcp.mod/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,12 +1,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 # Makefile for src/mod/ctcp.mod/
 
 srcdir = .
-depcomp = /bin/sh ../../../autotools/depcomp
+depcomp = /bin/sh ../../../build/autotools/depcomp
 
 #This line is simply for configure to generate .deps/
 OBJS = ctcp.o
 
 include ./.deps/includes
+include ../mod.mk
 
 doofus:
 &amp;lt; at &amp;gt;echo ""
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -16,13 +17,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; doofus:
 
 static: ../ctcp.o
 
-../ctcp.o:
-&amp;lt; at &amp;gt;echo -e "Compiling: \033[1mctcp\033[0m"
-source='ctcp.c' object='$&amp;lt; at &amp;gt;' depfile='.deps/ctcp.Po' tmpdepfile='.deps/ctcp.TPo' depmode=$(CCDEPMODE) $(depcomp) \
-$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/ctcp.c
-&amp;lt; at &amp;gt;rm -f ../ctcp.o
-&amp;lt; at &amp;gt;mv ctcp.o ../
-
 clean:
 &amp;lt; at &amp;gt;rm -f .depend *.o *~
 
diff --git a/src/mod/ctcp.mod/ctcp.c b/src/mod/ctcp.mod/ctcp.c
index 470e93d..6d9b0cf 100755
--- a/src/mod/ctcp.mod/ctcp.c
+++ b/src/mod/ctcp.mod/ctcp.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -407,7 +407,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ctcp_FINGER(char *nick, char *uhost, struct userrec *u, char *object,
   bd::String msg;
   msg = bd::String::printf("\001%s %s (%s) Idle %d second%s\001", keyword, "",
                    botuserhost, (int) idletime, idletime == 1 ? "" : "s");
-  notice(nick, msg.c_str(), DP_HELP);
+  notice(nick, msg, DP_HELP);
   return BIND_RET_BREAK;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -418,7 +418,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ctcp_ECHO(char *nick, char *uhost, struct userrec *u, char *object, c
   strlcpy(reply, text, sizeof(reply));
   bd::String msg;
   msg = bd::String::printf("\001%s %s\001", keyword, reply);
-  notice(nick, msg.c_str(), DP_HELP);
+  notice(nick, msg, DP_HELP);
   return BIND_RET_BREAK;
 }
 static int ctcp_PING(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -426,7 +426,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ctcp_PING(char *nick, char *uhost, struct userrec *u, char *object, c
   if (strlen(text) &amp;lt;= 80) {       /* bitchx ignores &amp;gt; 80 */
     bd::String msg;
     msg = bd::String::printf("\001%s %s\001", keyword, text);
-    notice(nick, msg.c_str(), DP_HELP);
+    notice(nick, msg, DP_HELP);
   }
   return BIND_RET_BREAK;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -476,11 +476,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ctcp_VERSION(char *nick, char *uhost, struct userrec *u, char *object
 
   bd::String msg;
   msg = bd::String::printf("\001%s %s%s\001", keyword, ctcpversion, s);
-  notice(nick, msg.c_str(), queue);
+  notice(nick, msg, queue);
 
   if (ctcpversion2[0]) {
     msg = bd::String::printf("\001%s %s\001", keyword, ctcpversion2);
-    notice(nick, msg.c_str(), DP_HELP);
+    notice(nick, msg, DP_HELP);
   }
   return BIND_RET_BREAK;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -490,7 +490,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ctcp_WHOAMI(char *nick, char *uhost, struct userrec *u, char *object,
   if (cloak_script &amp;gt; 0 &amp;amp;&amp;amp; cloak_script &amp;lt; 9) {
     bd::String msg;
     msg = bd::String::printf("\002BitchX\002: Access Denied");
-    notice(nick, msg.c_str(), DP_HELP);
+    notice(nick, msg, DP_HELP);
   }
   return BIND_RET_BREAK;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -506,7 +506,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ctcp_OP(char *nick, char *uhost, struct userrec *u, char *object, cha
       *p = 0;
     bd::String msg;
     msg = bd::String::printf("\002BitchX\002: I'm not on %s or I'm not opped", chan);
-    notice(nick, msg.c_str(), DP_HELP);
+    notice(nick, msg, DP_HELP);
   }
   return BIND_RET_BREAK;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -526,14 +526,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ctcp_INVITE_UNBAN(char *nick, char *uhost, struct userrec *u, char *o
       if (chan-&amp;gt;ircnet_status &amp;amp; CHAN_ACTIVE) {
         if (!strcasecmp(chan-&amp;gt;name, chname)) {
           msg = bd::String::printf("\002BitchX\002: Access Denied");
-          notice(nick, msg.c_str(), DP_HELP);
+          notice(nick, msg, DP_HELP);
           return BIND_RET_LOG;
         }
       }
       chan = chan-&amp;gt;next;
     }
     msg = bd::String::printf("\002BitchX\002: I'm not on that channel");
-    notice(nick, msg.c_str(), DP_HELP);
+    notice(nick, msg, DP_HELP);
   }
   return BIND_RET_BREAK;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -548,7 +548,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ctcp_USERINFO(char *nick, char *uhost, struct userrec *u, char *objec
   }
   bd::String msg;
   msg = bd::String::printf("\001%s %s\001", keyword, ctcpuserinfo);
-  notice(nick, msg.c_str(), DP_HELP);
+  notice(nick, msg, DP_HELP);
   return BIND_RET_BREAK;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -610,11 +610,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ctcp_CLIENTINFO(char *nick, char *uhost, struct userrec *u, char *obj
     strlcpy(buf, "UPTIME my uptime", sizeof(buf));
   else {
     msg = bd::String::printf("\001ERRMSG %s is not a valid function\001", text);
-    notice(nick, msg.c_str(), DP_HELP);
+    notice(nick, msg, DP_HELP);
     return BIND_RET_LOG;
   }
   msg = bd::String::printf("\001%s %s\001", keyword, buf);
-  notice(nick, msg.c_str(), DP_HELP);
+  notice(nick, msg, DP_HELP);
   return BIND_RET_BREAK;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -625,7 +625,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ctcp_TIME(char *nick, char *uhost, struct userrec *u, char *object, c
   strlcpy(tms, ctime(&amp;amp;now), sizeof(tms));
   bd::String msg;
   msg = bd::String::printf("\001%s %s\001", keyword, tms);
-  notice(nick, msg.c_str(), DP_HELP);
+  notice(nick, msg, DP_HELP);
   return BIND_RET_BREAK;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -658,8 +658,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ctcp_CHAT(char *nick, char *uhost, struct userrec *u, char *object, c
        * CTCP replies are NOTICE's this has to be a PRIVMSG
        * -poptix 5/1/1997 */
       bd::String msg;
-      msg = bd::String::printf("\001DCC CHAT chat %lu %u\001", iptolong(getmyip()), dcc[ix].port);
-      privmsg(nick, msg.c_str(), DP_SERVER);
+      msg = bd::String::printf("+p \001DCC CHAT chat %lu %u\001", iptolong(getmyip()), dcc[ix].port);
+      privmsg(nick, msg, DP_SERVER);
     }
     return BIND_RET_BREAK;
 }
diff --git a/src/mod/irc.mod/Makefile b/src/mod/irc.mod/Makefile
index 2ebfa06..5c99408 100755
--- a/src/mod/irc.mod/Makefile
+++ b/src/mod/irc.mod/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,13 +1,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 # Makefile for src/mod/irc.mod/
 
 srcdir = .
-depcomp = /bin/sh ../../../autotools/depcomp
+depcomp = /bin/sh ../../../build/autotools/depcomp
 
 
 #This line is simply for configure to generate .deps/
 OBJS = irc.o
 
 include ./.deps/includes
+include ../mod.mk
 
 doofus:
 &amp;lt; at &amp;gt;echo ""
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -17,14 +18,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; doofus:
 
 static: ../irc.o
 
-../irc.o:
-&amp;lt; at &amp;gt;echo -e "Compiling: \033[1mirc\033[0m"
-source='irc.c' object='$&amp;lt; at &amp;gt;' depfile='.deps/irc.Po' tmpdepfile='.deps/irc.TPo' depmode=$(CCDEPMODE) $(depcomp) \
-$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/irc.c
-&amp;lt; at &amp;gt;rm -f ../irc.o
-&amp;lt; at &amp;gt;mv irc.o ../
-
-
 clean:
 &amp;lt; at &amp;gt;rm -f .depend *.o *~
 
diff --git a/src/mod/irc.mod/chan.c b/src/mod/irc.mod/chan.c
index 38d4259..628ca70 100755
--- a/src/mod/irc.mod/chan.c
+++ b/src/mod/irc.mod/chan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -59,7 +59,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void resolv_member_callback(int id, void *client_data, const char *host,
   }
 
   memberlist *m = NULL;
-  char *pe = NULL, s[UHOSTLEN + 1], user[15] = "";
+  char *pe = NULL, user[15] = "";
   bool matched_user = 0;
 
   /* Apply lookup results to all matching members by host */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -69,9 +69,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void resolv_member_callback(int id, void *client_data, const char *host,
       if (pe &amp;amp;&amp;amp; !strcmp(pe + 1, r-&amp;gt;host)) {
         strlcpy(user, m-&amp;gt;userhost, pe - m-&amp;gt;userhost + 1);
         simple_snprintf(m-&amp;gt;userip, sizeof(m-&amp;gt;userip), "%s&amp;lt; at &amp;gt;%s", user, bd::String(ips[0]).c_str());
+        simple_snprintf(m-&amp;gt;fromip, sizeof(m-&amp;gt;fromip), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userip);
         if (!m-&amp;gt;user) {
-          simple_snprintf(s, sizeof(s), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userip);
-          m-&amp;gt;user = get_user_by_host(s);
+          m-&amp;gt;user = get_user_by_host(m-&amp;gt;fromip);
 
           /* Act on this lookup */
           if (m-&amp;gt;user)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -280,19 +280,23 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static memberlist *newmember(struct chanset_t *chan, char *nick)
   }
 
   ++(chan-&amp;gt;channel.members);
+  n-&amp;gt;floodtime = new bd::HashTable&amp;lt;flood_t, time_t&amp;gt;;
+  n-&amp;gt;floodnum  = new bd::HashTable&amp;lt;flood_t, int&amp;gt;;
   return n;
 }
 
+void delete_member(memberlist* m) {
+  delete m-&amp;gt;floodtime;
+  delete m-&amp;gt;floodnum;
+  free(m);
+}
+
 static bool member_getuser(memberlist* m, bool act_on_lookup) {
   if (!m) return 0;
   if (!m-&amp;gt;user &amp;amp;&amp;amp; !m-&amp;gt;tried_getuser) {
-    static char s[UHOSTLEN] = "";
-
-    simple_snprintf(s, sizeof(s), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
-    m-&amp;gt;user = get_user_by_host(s);
+    m-&amp;gt;user = get_user_by_host(m-&amp;gt;from);
     if (!m-&amp;gt;user &amp;amp;&amp;amp; m-&amp;gt;userip[0]) {
-      simple_snprintf(s, sizeof(s), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userip);
-      m-&amp;gt;user = get_user_by_host(s);
+      m-&amp;gt;user = get_user_by_host(m-&amp;gt;fromip);
     }
     m-&amp;gt;tried_getuser = 1;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -363,7 +367,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static char *getchanmode(struct chanset_t *chan)
   return s;
 }
 
-static void check_exemptlist(struct chanset_t *chan, char *from)
+static void check_exemptlist(struct chanset_t *chan, const char *from)
 {
   if (!use_exempts)
     return;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -449,7 +453,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void priority_do(struct chanset_t * chan, bool opsonly, int action, bool
                   flush_mode(chan, QUICK);
                 return;
               }
-            } else if ((action == PRIO_KICK) &amp;amp;&amp;amp; !chan_sentkick(m)) {
+            } else if ((action == PRIO_KICK) &amp;amp;&amp;amp; !chan_sentkick(m) &amp;amp;&amp;amp;
+                // Check closed-exempt
+                !((chan_hasop(m) &amp;amp;&amp;amp; chan-&amp;gt;closed_exempt_mode == CHAN_FLAG_OP) ||
+                  ((chan_hasvoice(m) || chan_hasop(m)) &amp;amp;&amp;amp; chan-&amp;gt;closed_exempt_mode == CHAN_FLAG_VOICE))) {
               ++actions;
               ++sent;
               if (chan-&amp;gt;closed_ban)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -542,30 +549,28 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void do_mask(struct chanset_t *chan, masklist *m, char *mask, char Mode)
 /* This is a clone of detect_flood, but works for channel specificity now
  * and handles kick &amp;amp; deop as well.
  */
-static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
-     struct chanset_t *chan, int which, char *victim)
+static bool detect_chan_flood(memberlist* m, const char *from, struct chanset_t *chan, flood_t which, const char *msg)
 {
-  if (!chan || (which &amp;lt; 0) || (which &amp;gt;= FLOOD_CHAN_MAX))
+  /* Do not punish non-existant channel members and IRC services like
+   * ChanServ
+   */
+  if (!chan || (which &amp;lt; 0) || (which &amp;gt;= FLOOD_CHAN_MAX) || !m)
     return 0;
 
   /* Okay, make sure i'm not flood-checking myself */
-  if (match_my_nick(floodnick))
+  if (m-&amp;gt;is_me) {
     return 0;
-  if (!strcasecmp(floodhost, botuserhost))
+  }
+  if (!strcasecmp(m-&amp;gt;userhost, botuserhost))
     return 0;
   /* My user&amp;lt; at &amp;gt;host (?) */
 
-  /* Do not punish non-existant channel members and IRC services like
-   * ChanServ
-   */
-  memberlist *m = ismember(chan, floodnick);
-
-  if (!m &amp;amp;&amp;amp; (which != FLOOD_JOIN) &amp;amp;&amp;amp; (which != FLOOD_PART))
-    return 0;
-
   struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };
+  struct userrec *u = NULL;
 
-  get_user_flagrec(get_user_by_host(from), &amp;amp;fr, chan-&amp;gt;dname, chan);
+  member_getuser(m);
+  u = m-&amp;gt;user;
+  get_user_flagrec(u, &amp;amp;fr, chan-&amp;gt;dname, chan);
   if (glob_bot(fr) ||
       ((which == FLOOD_DEOP) &amp;amp;&amp;amp;
        (glob_master(fr) || chan_master(fr))) ||
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -578,10 +583,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
       )))
     return 0;
 
-  char h[UHOSTLEN] = "", ftype[12] = "", *p = NULL;
-  struct userrec *u = NULL;
-  int thr = 0;
-  time_t lapse = 0;
+  char h[UHOSTLEN] = "", ftype[14] = "", *p = NULL;
+  int thr = 0, mthr = 0;
+  int increment = 1;
+  time_t lapse = 0, mlapse = 0;
 
   /* Determine how many are necessary to make a flood. */
   switch (which) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -589,12 +594,24 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
   case FLOOD_NOTICE:
     thr = chan-&amp;gt;flood_pub_thr;
     lapse = chan-&amp;gt;flood_pub_time;
+    mthr = chan-&amp;gt;flood_mpub_thr;
+    mlapse = chan-&amp;gt;flood_mpub_time;
     strlcpy(ftype, "pub", sizeof(ftype));
     break;
+  case FLOOD_BYTES:
+    thr = chan-&amp;gt;flood_bytes_thr;
+    lapse = chan-&amp;gt;flood_bytes_time;
+    mthr = chan-&amp;gt;flood_mbytes_thr;
+    mlapse = chan-&amp;gt;flood_mbytes_time;
+    strlcpy(ftype, "bytes", sizeof(ftype));
+    increment = static_cast&amp;lt;int&amp;gt;(strlen(msg));
+    break;
   case FLOOD_CTCP:
     thr = chan-&amp;gt;flood_ctcp_thr;
     lapse = chan-&amp;gt;flood_ctcp_time;
-    strlcpy(ftype, "pub", sizeof(ftype));
+    mthr = chan-&amp;gt;flood_mctcp_thr;
+    mlapse = chan-&amp;gt;flood_mctcp_time;
+    strlcpy(ftype, "ctcp", sizeof(ftype));
     break;
   case FLOOD_NICK:
     thr = chan-&amp;gt;flood_nick_thr;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -618,56 +635,110 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
     strlcpy(ftype, "kick", sizeof(ftype));
     break;
   }
-  if ((thr == 0) || (lapse == 0))
-    return 0;/* no flood protection */
 
   if ((which == FLOOD_KICK) || (which == FLOOD_DEOP))
-    p = floodnick;
+    p = m-&amp;gt;nick;
   else {
-    p = strchr(floodhost, '&amp;lt; at &amp;gt;');
+    p = strchr(m-&amp;gt;userhost, '&amp;lt; at &amp;gt;');
     if (p) {
       p++;
     }
     if (!p)
       return 0;
   }
-  if (rfc_casecmp(chan-&amp;gt;floodwho[which], p)) {/* new */
-    strlcpy(chan-&amp;gt;floodwho[which], p, sizeof(chan-&amp;gt;floodwho[which]));
-    chan-&amp;gt;floodtime[which] = now;
-    chan-&amp;gt;floodnum[which] = 1;
+
+  // Track across all clients in the channel
+  if (mlapse &amp;amp;&amp;amp; mthr) {
+    if (!chan-&amp;gt;channel.floodtime-&amp;gt;contains("all")) {
+      (*chan-&amp;gt;channel.floodtime)["all"][which] = now;
+      (*chan-&amp;gt;channel.floodnum)["all"][which] = increment;
     return 0;
   }
-  if (chan-&amp;gt;floodtime[which] &amp;lt; now - lapse) {
+
+    bd::HashTable&amp;lt;flood_t, time_t&amp;gt;      *global_floodtime = &amp;amp;(*chan-&amp;gt;channel.floodtime)["all"];
+    bd::HashTable&amp;lt;flood_t, int&amp;gt;         *global_floodnum = &amp;amp;(*chan-&amp;gt;channel.floodnum)["all"];
+
+    if ((*global_floodtime)[which] &amp;lt; now - mlapse) {
     /* Flood timer expired, reset it */
-    chan-&amp;gt;floodtime[which] = now;
-    chan-&amp;gt;floodnum[which] = 1;
+      (*global_floodtime)[which] = now;
+      (*global_floodnum)[which] = increment;
+    } else {
+      (*global_floodnum)[which] += increment;
+
+      if ((*global_floodnum)[which] &amp;gt;= mthr) {/* FLOOD */
+        /* Reset counters */
+        (*global_floodnum).remove(which);
+        (*global_floodtime).remove(which);
+        if (!chan-&amp;gt;channel.drone_set_mode) {
+          lockdown_chan(chan, FLOOD_MASS_FLOOD, ftype);
+        }
+      }
+    }
+  }
+
+  if ((thr == 0) || (lapse == 0)) {
+    return 0;/* no flood protection */
+  }
+
+  // Track individual hosts/clients
+  bd::HashTable&amp;lt;flood_t, time_t&amp;gt;      *floodtime; // floodtime[FLOOD_PRIVMSG] = now;
+  bd::HashTable&amp;lt;flood_t, int&amp;gt;         *floodnum;  //  floodnum[FLOOD_PRIVMSG] = 1;
+
+  switch (which) {
+    // These 2 don't have a persistent member, use chan list
+    case FLOOD_JOIN:
+    case FLOOD_PART:
+      // If not found, add them and start the count for next iteration
+      if (!chan-&amp;gt;channel.floodtime-&amp;gt;contains(m-&amp;gt;userhost)) {
+        (*chan-&amp;gt;channel.floodtime)[m-&amp;gt;userhost][which] = now;
+        (*chan-&amp;gt;channel.floodnum)[m-&amp;gt;userhost][which] = increment;
     return 0;
+      } else {
+        floodtime = &amp;amp;(*chan-&amp;gt;channel.floodtime)[m-&amp;gt;userhost];
+        floodnum = &amp;amp;(*chan-&amp;gt;channel.floodnum)[m-&amp;gt;userhost];
   }
-  /* Deop'n the same person, sillyness ;) - so just ignore it */
-  if (which == FLOOD_DEOP) {
-    if (!rfc_casecmp(chan-&amp;gt;deopd, victim))
+      break;
+    default:
+      // Everything else, log to the member
+      // If not found, add them and start the count for next iteration
+      if (!m-&amp;gt;floodtime-&amp;gt;contains(which)) {
+        (*m-&amp;gt;floodtime)[which] = now;
+        (*m-&amp;gt;floodnum)[which] = increment;
       return 0;
-    else
-      strlcpy(chan-&amp;gt;deopd, victim, sizeof(chan-&amp;gt;deopd));
+      } else {
+        floodtime = m-&amp;gt;floodtime;
+        floodnum = m-&amp;gt;floodnum;
+      }
+      break;
   }
-  chan-&amp;gt;floodnum[which]++;
-  if (chan-&amp;gt;floodnum[which] &amp;gt;= thr) {/* FLOOD */
+
+  if ((*floodtime)[which] &amp;lt; now - lapse) {
+    /* Flood timer expired, reset it */
+    (*floodtime)[which] = now;
+    (*floodnum)[which] = increment;
+    return 0;
+  }
+  (*floodnum)[which] += increment;
+
+  if ((*floodnum)[which] &amp;gt;= thr) {/* FLOOD */
     /* Reset counters */
-    chan-&amp;gt;floodnum[which] = 0;
-    chan-&amp;gt;floodtime[which] = 0;
-    chan-&amp;gt;floodwho[which][0] = 0;
-    if (which == FLOOD_DEOP)
-      chan-&amp;gt;deopd[0] = 0;
-    u = get_user_by_host(from);
+    (*floodnum).remove(which);
+    (*floodtime).remove(which);
     switch (which) {
     case FLOOD_PRIVMSG:
     case FLOOD_NOTICE:
     case FLOOD_CTCP:
+    case FLOOD_BYTES:
       /* Flooding chan! either by public or notice */
       if (!chan_sentkick(m) &amp;amp;&amp;amp; me_op(chan)) {
-putlog(LOG_MODES, chan-&amp;gt;dname, "Channel flood from %s -- kicking", floodnick);
-        dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan-&amp;gt;name, floodnick, kickprefix, response(RES_FLOOD));
-m-&amp;gt;flags |= SENTKICK;
+        if (channel_floodban(chan)) {
+          putlog(LOG_MODES, chan-&amp;gt;dname, "Channel flood from %s -- banning", m-&amp;gt;nick);
+          char *s1 = quickban(chan, from);
+          u_addmask('b', chan, s1, conf.bot-&amp;gt;nick, "channel flood", now + (60 * chan-&amp;gt;ban_time), 0);
+        } else {
+          const char *response = punish_flooder(chan, m);
+          putlog(LOG_MODES, chan-&amp;gt;dname, "Channel flood from %s -- %s", m-&amp;gt;nick, response);
+        }
       }
       return 1;
     case FLOOD_JOIN:
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -689,16 +760,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
 putlog(LOG_MISC | LOG_JOIN, chan-&amp;gt;dname, "JOIN flood from &amp;lt; at &amp;gt;%s!  Banning.", p);
       else
 putlog(LOG_MISC | LOG_JOIN, chan-&amp;gt;dname, "NICK flood from &amp;lt; at &amp;gt;%s!  Banning.", p);
-      strlcpy(ftype + 4, " flood", sizeof(ftype) - 4);
+      strlcat(ftype, " flood", sizeof(ftype));
       u_addmask('b', chan, h, conf.bot-&amp;gt;nick, ftype, now + (60 * chan-&amp;gt;ban_time), 0);
       if (which == FLOOD_PART)
         add_mode(chan, '+', 'b', h);
       if (!channel_enforcebans(chan) &amp;amp;&amp;amp; me_op(chan)) {
-  char s[UHOSTLEN];
   for (m = chan-&amp;gt;channel.member; m &amp;amp;&amp;amp; m-&amp;gt;nick[0]; m = m-&amp;gt;next) {  
-    simple_snprintf(s, sizeof(s), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
-    if (!chan_sentkick(m) &amp;amp;&amp;amp; wild_match(h, s) &amp;amp;&amp;amp;
-(m-&amp;gt;joined &amp;gt;= chan-&amp;gt;floodtime[which]) &amp;amp;&amp;amp;
+    if (!chan_sentkick(m) &amp;amp;&amp;amp; wild_match(h, m-&amp;gt;from) &amp;amp;&amp;amp;
+(m-&amp;gt;joined &amp;gt;= (*floodtime)[which]) &amp;amp;&amp;amp;
 !m-&amp;gt;is_me &amp;amp;&amp;amp; me_op(chan)) {
       m-&amp;gt;flags |= SENTKICK;
       if (which == FLOOD_JOIN)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -711,8 +780,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
       return 1;
     case FLOOD_KICK:
       if (me_op(chan) &amp;amp;&amp;amp; !chan_sentkick(m)) {
-putlog(LOG_MODES, chan-&amp;gt;dname, "Kicking %s, for mass kick.", floodnick);
-        dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan-&amp;gt;name, floodnick, kickprefix, response(RES_KICKFLOOD));
+putlog(LOG_MODES, chan-&amp;gt;dname, "Kicking %s, for mass kick.", m-&amp;gt;nick);
+        dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, response(RES_KICKFLOOD));
 m-&amp;gt;flags |= SENTKICK;
       }
       if (channel_protect(chan))
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -722,14 +791,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
       if (me_op(chan) &amp;amp;&amp;amp; !chan_sentkick(m)) {
 putlog(LOG_MODES, chan-&amp;gt;dname,
        "Mass deop on %s by %s", chan-&amp;gt;dname, from);
-        dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan-&amp;gt;name, floodnick, kickprefix, response(RES_MASSDEOP));
+        dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, response(RES_MASSDEOP));
 m-&amp;gt;flags |= SENTKICK;
       }
       if (u) {
         char s[256] = "";
 
         simple_snprintf(s, sizeof(s), "Mass deop on %s by %s", chan-&amp;gt;dname, from);
-        deflag_user(u, DEFLAG_MDOP, s, chan);
+        deflag_user(u, DEFLAG_EVENT_MDOP, s, chan);
       }
       if (channel_protect(chan))
         do_protect(chan, "Mass Deop");
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -740,23 +809,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
 }
 
 /* Given a chan/m do all necesary exempt checks and ban. */
-static void refresh_ban_kick(struct chanset_t*, memberlist *, char *);
+static void refresh_ban_kick(struct chanset_t*, memberlist *, const char *);
 static void do_closed_kick(struct chanset_t *chan, memberlist *m)
 {
   if (!chan || !m) return;
 
-  char s[UHOSTLEN] = "", *s1 = NULL;
-
-  simple_snprintf(s, sizeof(s), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
+  char *s1 = NULL;
 
   if (!(use_exempts &amp;amp;&amp;amp;
-        (u_match_mask(global_exempts,s) ||
-         u_match_mask(chan-&amp;gt;exempts, s)))) {
-    if (u_match_mask(global_bans, s) || u_match_mask(chan-&amp;gt;bans, s))
-      refresh_ban_kick(chan, m, s);
+        (u_match_mask(global_exempts, m-&amp;gt;from) ||
+         u_match_mask(chan-&amp;gt;exempts, m-&amp;gt;from)))) {
+    if (u_match_mask(global_bans, m-&amp;gt;from) || u_match_mask(chan-&amp;gt;bans, m-&amp;gt;from))
+      refresh_ban_kick(chan, m, m-&amp;gt;from);
 
-    check_exemptlist(chan, s);
-    s1 = quickban(chan, s);
+    check_exemptlist(chan, m-&amp;gt;from);
+    s1 = quickban(chan, m-&amp;gt;from);
     u_addmask('b', chan, s1, conf.bot-&amp;gt;nick, "joined closed chan", now + (60 * chan-&amp;gt;ban_time), 0);
   }
   return;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -764,7 +831,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void do_closed_kick(struct chanset_t *chan, memberlist *m)
 
 /* Given a nick!user&amp;lt; at &amp;gt;host, place a quick ban on them on a chan.
  */
-static char *quickban(struct chanset_t *chan, char *from)
+static char *quickban(struct chanset_t *chan, const char *from)
 {
   static char s1[512] = "";
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -779,27 +846,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static char *quickban(struct chanset_t *chan, char *from)
 static void kick_all(struct chanset_t *chan, char *hostmask, const char *comment, int bantype)
 {
   int flushed = 0;
-  char s[UHOSTLEN] = "", sip[UHOSTLEN] = "";
   struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };
 
   for (memberlist *m = chan-&amp;gt;channel.member; m &amp;amp;&amp;amp; m-&amp;gt;nick[0]; m = m-&amp;gt;next) {
-    simple_snprintf(s, sizeof(s), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
-    if (m-&amp;gt;userip[0])
-      simple_snprintf(sip, sizeof(sip), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userip);
-    else
-      sip[0] = 0;
     get_user_flagrec(m-&amp;gt;user, &amp;amp;fr, chan-&amp;gt;dname, chan);
-    if ((wild_match(hostmask, s) || match_cidr(hostmask, s) ||
-          (sip[0] &amp;amp;&amp;amp; (wild_match(hostmask, sip) || match_cidr(hostmask, sip)))) &amp;amp;&amp;amp;
+    if ((wild_match(hostmask, m-&amp;gt;from) || match_cidr(hostmask, m-&amp;gt;from) ||
+          (m-&amp;gt;userip[0] &amp;amp;&amp;amp; (wild_match(hostmask, m-&amp;gt;fromip) || match_cidr(hostmask, m-&amp;gt;fromip)))) &amp;amp;&amp;amp;
         !chan_sentkick(m) &amp;amp;&amp;amp;
 !m-&amp;gt;is_me &amp;amp;&amp;amp; !chan_issplit(m) &amp;amp;&amp;amp;
 !(use_exempts &amp;amp;&amp;amp;
-  ((bantype &amp;amp;&amp;amp; (isexempted(chan, s) || (chan-&amp;gt;ircnet_status &amp;amp; CHAN_ASKED_EXEMPTS))) ||
-   (u_match_mask(global_exempts, s) ||
-    u_match_mask(chan-&amp;gt;exempts, s) ||
-            (sip[0] &amp;amp;&amp;amp;
-             (u_match_mask(global_exempts, sip) ||
-              u_match_mask(chan-&amp;gt;exempts, sip))))))) {
+  ((bantype &amp;amp;&amp;amp; (isexempted(chan, m-&amp;gt;from) || (chan-&amp;gt;ircnet_status &amp;amp; CHAN_ASKED_EXEMPTS))) ||
+   (u_match_mask(global_exempts, m-&amp;gt;from) ||
+    u_match_mask(chan-&amp;gt;exempts, m-&amp;gt;from) ||
+            (m-&amp;gt;userip[0] &amp;amp;&amp;amp;
+             (u_match_mask(global_exempts, m-&amp;gt;fromip) ||
+              u_match_mask(chan-&amp;gt;exempts, m-&amp;gt;fromip))))))) {
       if (!flushed) {
 /* We need to kick someone, flush eventual bans first */
 flush_mode(chan, QUICK);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -815,7 +876,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void kick_all(struct chanset_t *chan, char *hostmask, const char *comment
 
 /* If any bans match this wildcard expression, refresh them on the channel.
  */
-static void refresh_ban_kick(struct chanset_t* chan, memberlist *m, char *user)
+static void refresh_ban_kick(struct chanset_t* chan, memberlist *m, const char *user)
 {
   if (!m || chan_sentkick(m))
     return;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -871,7 +932,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void refresh_exempt(struct chanset_t *chan, char *user)
   }
 }
 
-static void refresh_invite(struct chanset_t *chan, char *user)
+static void refresh_invite(struct chanset_t *chan, const char *user)
 {
   maskrec *i = NULL;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -901,14 +962,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void enforce_bans(struct chanset_t *chan)
   if ((chan-&amp;gt;ircnet_status &amp;amp; CHAN_ASKED_EXEMPTS))
     return;
 
-  char me[UHOSTLEN] = "", meip[UHOSTLEN] = "";
-
-  simple_snprintf(me, sizeof(me), "%s!%s", botname, botuserhost);
-  simple_snprintf(meip, sizeof(meip), "%s!%s", botname, botuserip);
+  const memberlist *me = ismember(chan, botname);
 
   /* Go through all bans, kicking the users. */
   for (masklist *b = chan-&amp;gt;channel.ban; b &amp;amp;&amp;amp; b-&amp;gt;mask[0]; b = b-&amp;gt;next) {
-    if (!(wild_match(b-&amp;gt;mask, me) || match_cidr(b-&amp;gt;mask, meip)) &amp;amp;&amp;amp; !isexempted(chan, b-&amp;gt;mask))
+    if (!(wild_match(b-&amp;gt;mask, me-&amp;gt;from) || match_cidr(b-&amp;gt;mask, me-&amp;gt;fromip)) &amp;amp;&amp;amp; !isexempted(chan, b-&amp;gt;mask))
       kick_all(chan, b-&amp;gt;mask, "You are banned", 1);
   }
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1018,14 +1076,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void check_this_ban(struct chanset_t *chan, char *banmask, bool sticky)
   if (!me_op(chan))
     return;
 
-  char user[UHOSTLEN] = "";
+  const char *user = NULL;
 
   for (memberlist *m = chan-&amp;gt;channel.member; m &amp;amp;&amp;amp; m-&amp;gt;nick[0]; m = m-&amp;gt;next) {
     for (int i = 0; i &amp;lt; (m-&amp;gt;userip[0] ? 2 : 1); ++i) {
       if (i == 0 &amp;amp;&amp;amp; m-&amp;gt;userip[0]) // Check userip first in case userhost is already an ip
-        simple_snprintf(user, sizeof(user), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userip);
+        user = m-&amp;gt;fromip;
       else
-        simple_snprintf(user, sizeof(user), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
+        user = m-&amp;gt;from;
       if ((wild_match(banmask, user)  || match_cidr(banmask, user)) &amp;amp;&amp;amp;
           !(use_exempts &amp;amp;&amp;amp;
             (u_match_mask(global_exempts, user) ||
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1068,6 +1126,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void recheck_channel_modes(struct chanset_t *chan)
       mns &amp;amp;= ~CHANPRIV;
     }
   }
+  if (channel_voice(chan) &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate) {
+    pls |= CHANMODER;
+    mns &amp;amp;= ~CHANMODER;
+  }
 
   if (!(chan-&amp;gt;ircnet_status &amp;amp; CHAN_ASKEDMODES)) {
     if (pls &amp;amp; CHANINV &amp;amp;&amp;amp; !(cur &amp;amp; CHANINV))
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1174,12 +1236,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void check_this_member(struct chanset_t *chan, char *nick, struct flag_re
     }
   }
 
-  char s[UHOSTLEN] = "";
+  const char *s = NULL;
   for (int i = 0; i &amp;lt; (m-&amp;gt;userip[0] ? 2 : 1); ++i) {
     if (i == 0 &amp;amp;&amp;amp; m-&amp;gt;userip[0]) // Check userip first in case userhost is already an ip
-      simple_snprintf(s, sizeof(s), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userip);
+      s = m-&amp;gt;fromip;
     else
-      simple_snprintf(s, sizeof(s), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
+      s = m-&amp;gt;from;
 
     /* check vs invites */
     if (use_invites &amp;amp;&amp;amp;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1231,11 +1293,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void check_this_user(char *hand, int del, char *host)
           u = NULL; // Pretend user doesn't exist when checking
       } else if (0 &amp;amp;&amp;amp; del == 2) { //-host, may now match on a diff user and need to act on them
         /*
+        const char *s = NULL;
         for (int i = 0; i &amp;lt; (m-&amp;gt;userip[0] ? 2 : 1); ++i) {
           if (i == 0 &amp;amp;&amp;amp; m-&amp;gt;userip[0]) // Check userip first in case userhost is already an ip
-            simple_snprintf(s, sizeof(s), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userip);
+            s = m-&amp;gt;fromip;
           else
-            simple_snprintf(s, sizeof(s), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
+            s = m-&amp;gt;from;
           if (wild_match(host, s) ||
               (i == 0 &amp;amp;&amp;amp; m-&amp;gt;userip[0] &amp;amp;&amp;amp; match_cidr(host, s))) {
             check_member = 1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1668,7 +1731,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int got341(char *from, char *msg)
   putlog(LOG_MISC, "*", "HIJACKED invite detected: %s to %s", nick, chan-&amp;gt;dname);
   bd::String msg;
   msg = bd::String::printf("ALERT! \002%s was invited via a hijacked connection/process.\002", nick);
-  privmsg(chan-&amp;gt;name, msg.c_str(), DP_MODE_NEXT);
+  privmsg(chan-&amp;gt;name, msg, DP_MODE_NEXT);
   return 0;
 }
 #endif /* CACHE */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1889,12 +1952,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int got352or4(struct chanset_t *chan, char *user, char *host, char *nick,
 
     /* Store the userhost */
     simple_snprintf(m-&amp;gt;userhost, sizeof(m-&amp;gt;userhost), "%s&amp;lt; at &amp;gt;%s", user, host);
+    simple_snprintf(m-&amp;gt;from, sizeof(m-&amp;gt;from), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
+    member_update_from_cache(chan, m);
 
     if (!m-&amp;gt;userip[0]) {
       if (ip)
         simple_snprintf(m-&amp;gt;userip, sizeof(m-&amp;gt;userip), "%s&amp;lt; at &amp;gt;%s", user, ip);
       else if (is_dotted_ip(host))
         simple_snprintf(m-&amp;gt;userip, sizeof(m-&amp;gt;userip), "%s&amp;lt; at &amp;gt;%s", user, host);
+      simple_snprintf(m-&amp;gt;fromip, sizeof(m-&amp;gt;fromip), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userip);
     }
   }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1942,6 +2008,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int got352or4(struct chanset_t *chan, char *user, char *host, char *nick,
       resolve_to_rbl(chan, m-&amp;gt;userip);
   }
 
+  // If there's an opped bot, queue op to request_op
+  if (m-&amp;gt;user &amp;amp;&amp;amp; m-&amp;gt;user-&amp;gt;bot &amp;amp;&amp;amp; chan_hasop(m)) {
+    chan-&amp;gt;channel.do_opreq = 1;
+  }
+
   return 0;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2056,9 +2127,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int got315(char *from, char *msg)
       recheck_channel(chan, 2);
     else if (chan-&amp;gt;channel.members == 1)
       chan-&amp;gt;ircnet_status |= CHAN_STOP_CYCLE;
-    else if (any_ops(chan))
+    else if (chan-&amp;gt;channel.do_opreq) {
       request_op(chan);
   }
+  }
   /* do not check for i-lines here. */
   return 0;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2425,6 +2497,37 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int got475(char *from, char *msg)
   return 0;
 }
 
+/* got 478: Channel ban list is full
+ * [&amp;lt; at &amp;gt;] irc.blessed.net 478 wtest #wraith-devel *!*&amp;lt; at &amp;gt;host.com :Channel ban list is full
+ */
+static int got478(char *from, char *msg)
+{
+  char *chname = NULL;
+  struct chanset_t *chan = NULL;
+
+  newsplit(&amp;amp;msg);
+  chname = newsplit(&amp;amp;msg);
+
+  /* !channel short names (also referred to as 'description names'
+   * can be received by skipping over the unique ID.
+   */
+  if ((chname[0] == '!') &amp;amp;&amp;amp; (strlen(chname) &amp;gt; CHANNEL_ID_LEN)) {
+    chname += CHANNEL_ID_LEN;
+    chname[0] = '!';
+  }
+  /* We use dname because name is first set on JOIN and we might not
+   * have joined the channel yet.
+   */
+  chan = findchan_by_dname(chname);
+  if (chan &amp;amp;&amp;amp; shouldjoin(chan)) {
+    // Only lockdown if not already locked down
+    if (!chan-&amp;gt;channel.drone_set_mode) {
+      lockdown_chan(chan, FLOOD_BANLIST);
+    }
+  }
+  return 0;
+}
+
 /* got invitation
  */
 static int gotinvite(char *from, char *msg)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2590,8 +2693,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotjoin(char *from, char *chname)
 
     chan-&amp;gt;ircnet_status &amp;amp;= ~CHAN_STOP_CYCLE;
 
-    detect_chan_flood(nick, uhost, from, chan, FLOOD_JOIN, NULL);
-
     if ((host = strchr(uhost, '&amp;lt; at &amp;gt;')))
       ++host;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2625,6 +2726,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotjoin(char *from, char *chname)
           if (!m-&amp;gt;user &amp;amp;&amp;amp; !m-&amp;gt;userip[0] &amp;amp;&amp;amp; doresolv(chan)) {
             if (is_dotted_ip(host)) {
               strlcpy(m-&amp;gt;userip, uhost, sizeof(m-&amp;gt;userip));
+              simple_snprintf(m-&amp;gt;fromip, sizeof(m-&amp;gt;fromip), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userip);
               if (channel_rbl(chan))
                 resolve_to_rbl(chan, m-&amp;gt;userip);
             } else
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2637,8 +2739,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotjoin(char *from, char *chname)
 m = newmember(chan, nick);
 m-&amp;gt;joined = m-&amp;gt;last = now;
 strlcpy(m-&amp;gt;userhost, uhost, sizeof(m-&amp;gt;userhost));
-        if (is_dotted_ip(host))
+        member_update_from_cache(chan, m);
+        simple_snprintf(m-&amp;gt;from, sizeof(m-&amp;gt;from), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
+        if (is_dotted_ip(host)) {
           strlcpy(m-&amp;gt;userip, uhost, sizeof(m-&amp;gt;userip));
+          simple_snprintf(m-&amp;gt;fromip, sizeof(m-&amp;gt;fromip), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userip);
+        }
         m-&amp;gt;user = get_user_by_host(from);
         m-&amp;gt;tried_getuser = 1;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2650,6 +2756,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotjoin(char *from, char *chname)
 //m-&amp;gt;flags |= STOPWHO;
 
 if (match_my_nick(nick)) {
+          m-&amp;gt;is_me = 1;
   /* It was me joining! Need to update the channel record with the
    * unique name for the channel (as the server see's it). &amp;lt;cybah&amp;gt;
    */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2668,6 +2775,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotjoin(char *from, char *chname)
      reset_chan_info(chan);
 } else {
           irc_log(chan, "Join: %s (%s)", nick, uhost);
+          detect_chan_flood(m, from, chan, FLOOD_JOIN);
   set_handle_laston(chan-&amp;gt;dname, m-&amp;gt;user, now);
 }
       }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2681,7 +2789,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotjoin(char *from, char *chname)
         bool is_op = chk_op(fr, chan);
 
         /* Check for a mass join */
-        if (!splitjoin &amp;amp;&amp;amp; channel_nomassjoin(chan) &amp;amp;&amp;amp; !is_op) {
+        if (!splitjoin &amp;amp;&amp;amp; chan-&amp;gt;flood_mjoin_time &amp;amp;&amp;amp; chan-&amp;gt;flood_mjoin_thr &amp;amp;&amp;amp; !is_op) {
           if (chan-&amp;gt;channel.drone_jointime &amp;lt; now - chan-&amp;gt;flood_mjoin_time) {      //expired, reset counter
             chan-&amp;gt;channel.drone_joins = 0;
           }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2689,7 +2797,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotjoin(char *from, char *chname)
           chan-&amp;gt;channel.drone_jointime = now;
 
           if (!chan-&amp;gt;channel.drone_set_mode &amp;amp;&amp;amp; chan-&amp;gt;channel.drone_joins &amp;gt;= chan-&amp;gt;flood_mjoin_thr) {  //flood from dronenet, let's attempt to set +im
-            detected_drone_flood(chan, m);
+            lockdown_chan(chan, FLOOD_MASSJOIN);
           }
         }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2820,7 +2928,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotpart(char *from, char *msg)
     set_handle_laston(chan-&amp;gt;dname, u, now);
 
     if (m) {
-      detect_chan_flood(nick, m-&amp;gt;userhost, from, chan, FLOOD_PART, NULL);
+      detect_chan_flood(m, from, chan, FLOOD_PART);
       killmember(chan, nick);
     }
     if (msg[0])
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2858,44 +2966,57 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotkick(char *from, char *origmsg)
   }
   if (channel_active(chan)) {
     char *whodid = NULL, s1[UHOSTLEN] = "", buf[UHOSTLEN] = "", *uhost = buf;
-    memberlist *m = NULL;
-    struct userrec *u = NULL;
+    memberlist *m = NULL, *mv = NULL;
     struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };
 
     fixcolon(msg);
-    u = get_user_by_host(from);
-    if (!u || (u &amp;amp;&amp;amp; !u-&amp;gt;bot))
-      chan-&amp;gt;channel.fighting++;
     strlcpy(uhost, from, sizeof(buf));
     whodid = splitnick(&amp;amp;uhost);
-    detect_chan_flood(whodid, uhost, from, chan, FLOOD_KICK, nick);
 
     chan = findchan(chname);
     if (!chan)
       return 0;     
 
     m = ismember(chan, whodid);
-    if (m)
+    if (m) {
+      detect_chan_flood(m, from, chan, FLOOD_KICK);
+
       m-&amp;gt;last = now;
+      member_getuser(m);
+      if (m-&amp;gt;user) {
     /* This _needs_ to use chan-&amp;gt;dname &amp;lt;cybah&amp;gt; */
-    get_user_flagrec(u, &amp;amp;fr, chan-&amp;gt;dname, chan);
-    set_handle_laston(chan-&amp;gt;dname, u, now);
+        get_user_flagrec(m-&amp;gt;user, &amp;amp;fr, chan-&amp;gt;dname, chan);
+        set_handle_laston(chan-&amp;gt;dname, m-&amp;gt;user, now);
+      }
+    }
  
-    chan = findchan(chname);
-    if (!chan)
-      return 0;
+    if ((!m || !m-&amp;gt;user) || (m &amp;amp;&amp;amp; m-&amp;gt;user &amp;amp;&amp;amp; !m-&amp;gt;user-&amp;gt;bot)) {
+      chan-&amp;gt;channel.fighting++;
+    }
 
-    if ((m = ismember(chan, nick))) {
-      member_getuser(m);
-      if (m-&amp;gt;user)
-        set_handle_laston(chan-&amp;gt;dname, m-&amp;gt;user, now);
-//      maybe_revenge(chan, from, s1, REVENGE_KICK);
+    mv = ismember(chan, nick);
+
+    member_getuser(mv);
+    if (mv-&amp;gt;user) {
+      // Revenge kick clients that kick our bots
+      if (chan-&amp;gt;revenge &amp;amp;&amp;amp; !mv-&amp;gt;is_me &amp;amp;&amp;amp; m &amp;amp;&amp;amp; m != mv &amp;amp;&amp;amp; mv-&amp;gt;user-&amp;gt;bot &amp;amp;&amp;amp; !(m-&amp;gt;user &amp;amp;&amp;amp; m-&amp;gt;user-&amp;gt;bot)) {
+        if (role &amp;lt; 5 &amp;amp;&amp;amp; !chan_sentkick(m) &amp;amp;&amp;amp; me_op(chan)) {
+          m-&amp;gt;flags |= SENTKICK;
+          dprintf(DP_MODE_NEXT, "KICK %s %s :%s%s\r\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, response(RES_REVENGE));
     } else {
-      simple_snprintf(s1, sizeof(s1), "%s!*&amp;lt; at &amp;gt;could.not.loookup.hostname", nick);
+          if (m-&amp;gt;user) {
+            char tmp[128] = "";
+            simple_snprintf(tmp, sizeof(tmp), "Kicked bot %s on %s", mv-&amp;gt;nick, chan-&amp;gt;dname);
+            deflag_user(m-&amp;gt;user, DEFLAG_EVENT_REVENGE_KICK, tmp, chan);
+          }
+        }
+      }
+
+      set_handle_laston(chan-&amp;gt;dname, mv-&amp;gt;user, now);
     }
     irc_log(chan, "%s was kicked by %s (%s)", s1, from, msg);
     /* Kicked ME?!? the sods! */
-    if (match_my_nick(nick)) {
+    if (mv-&amp;gt;is_me) {
       check_rejoin(chan);
     } else {
       killmember(chan, nick);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2940,10 +3061,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotnick(char *from, char *msg)
       if (rfc_casecmp(nick, msg)) {
         /* Someone on channel with old nick?! */
 if ((mm = ismember(chan, msg)))
-  killmember(chan, mm-&amp;gt;nick);
+  killmember(chan, mm-&amp;gt;nick, false);
       }
 
       strlcpy(m-&amp;gt;nick, msg, sizeof(m-&amp;gt;nick));
+      strlcpy(m-&amp;gt;from, s1, sizeof(m-&amp;gt;from));
 
       /*
        * Banned?
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2951,7 +3073,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotnick(char *from, char *msg)
 
       memberlist_reposition(chan, m);
 
-      detect_chan_flood(msg, uhost, from, chan, FLOOD_NICK, NULL);
+      detect_chan_flood(m, from, chan, FLOOD_NICK);
 
       /* don't fill the serverqueue with modes or kicks in a nickflood */
       if (chan_sentkick(m) || chan_sentdeop(m) || chan_sentop(m) ||
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3123,8 +3245,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotmsg(char *from, char *msg)
   memberlist *m = ismember(chan, nick);
 
   /* Only check if flood-ctcp is active */
-  if (flood_ctcp.count &amp;amp;&amp;amp; detect_avalanche(msg)) {
-    u = get_user_by_host(from);
+  if (m &amp;amp;&amp;amp; flood_ctcp.count &amp;amp;&amp;amp; detect_avalanche(msg)) {
+    member_getuser(m);
+    u = m-&amp;gt;user;
     get_user_flagrec(u, &amp;amp;fr, chan-&amp;gt;dname, chan);
     /* Discard -- kick user if it was to the channel */
     if (m &amp;amp;&amp;amp; me_op(chan) &amp;amp;&amp;amp; 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3170,13 +3293,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotmsg(char *from, char *msg)
       ctcp = buf2;
       strlcpy(ctcp, p1, sizeof(buf2));
       strcpy(p1 - 1, p + 1);
-      detect_chan_flood(nick, uhost, from, chan,
-strncmp(ctcp, "ACTION ", 7) ?
-FLOOD_CTCP : FLOOD_PRIVMSG, NULL);
-
-      chan = findchan(realto);
-      if (!chan)
-        return 0;
+      if (m) {
+        detect_chan_flood(m, from, chan, strncmp(ctcp, "ACTION ", 7) ? FLOOD_CTCP : FLOOD_PRIVMSG);
+        detect_chan_flood(m, from, chan, FLOOD_BYTES, msg);
+      }
 
       /* Respond to the first answer_ctcp */
       p = strchr(msg, 1);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3188,10 +3308,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotmsg(char *from, char *msg)
   if (!ignoring || trigger_on_ignore) {
     if (check_bind_ctcp(nick, uhost, u, to, code, ctcp) == BIND_RET_LOG) {
 
-      chan = findchan(realto); 
-      if (!chan)
-return 0;
-
       update_idle(chan-&amp;gt;dname, nick);
             }
       /* Log DCC, it's to a channel damnit! */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3224,13 +3340,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotmsg(char *from, char *msg)
     int botmatch = 0;
     char *my_msg = NULL, *my_ptr = NULL, *fword = NULL;
 
-#ifdef unfinished
     if (me_op(chan) &amp;amp;&amp;amp; doflood(chan))
       detect_offense(m, chan, msg);
-#endif
 
-    /* Check even if we're ignoring the host. (modified by Eule 17.7.99) */
-    detect_chan_flood(nick, uhost, from, chan, FLOOD_PRIVMSG, NULL);
+    if (m) {
+      detect_chan_flood(m, from, chan, FLOOD_PRIVMSG);
+      detect_chan_flood(m, from, chan, FLOOD_BYTES, msg);
+    }
     
     if (auth_chan) {
       my_msg = my_ptr = strdup(msg);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3242,7 +3358,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotmsg(char *from, char *msg)
       /* is it a cmd? */
       if (auth_prefix[0] &amp;amp;&amp;amp; fword &amp;amp;&amp;amp; fword[0] &amp;amp;&amp;amp; fword[1] &amp;amp;&amp;amp; ((botmatch &amp;amp;&amp;amp; fword[0] != auth_prefix[0]) || (fword[0] == auth_prefix[0]))) {
         Auth *auth = Auth::Find(uhost);
-
         if (auth &amp;amp;&amp;amp; auth-&amp;gt;Authed()) {
           if (fword[0] == auth_prefix[0])
             fword++;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3281,9 +3396,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotnotice(char *from, char *msg)
   fixcolon(msg);
   strlcpy(uhost, from, sizeof(buf));
   nick = splitnick(&amp;amp;uhost);
-  u = get_user_by_host(from);
-  if (flood_ctcp.count &amp;amp;&amp;amp; detect_avalanche(msg)) {
     memberlist *m = ismember(chan, nick);
+  if (m) {
+    member_getuser(m);
+    u = m-&amp;gt;user;
+  }
+
+  if (flood_ctcp.count &amp;amp;&amp;amp; detect_avalanche(msg)) {
 
     get_user_flagrec(u, &amp;amp;fr, chan-&amp;gt;dname, chan);
     /* Discard -- kick user if it was to the channel */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3320,13 +3439,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotnotice(char *from, char *msg)
       strlcpy(ctcp, p1, sizeof(buf2));
       strcpy(p1 - 1, p + 1);
       p = strchr(msg, 1);
-      detect_chan_flood(nick, uhost, from, chan,
-strncmp(ctcp, "ACTION ", 7) ?
-FLOOD_CTCP : FLOOD_PRIVMSG, NULL);
-
-      chan = findchan(realto); 
-      if (!chan)
-return 0;
+      if (m) {
+        detect_chan_flood(m, from, chan, strncmp(ctcp, "ACTION ", 7) ? FLOOD_CTCP : FLOOD_PRIVMSG);
+        detect_chan_flood(m, from, chan, FLOOD_BYTES, msg);
+      }
 
       if (ctcp[0] != ' ') {
 code = newsplit(&amp;amp;ctcp);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3343,12 +3459,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotnotice(char *from, char *msg)
     }
   }
   if (msg[0]) {
-    /* Check even if we're ignoring the host. (modified by Eule 17.7.99) */
-    detect_chan_flood(nick, uhost, from, chan, FLOOD_NOTICE, NULL);
-
-    chan = findchan(realto); 
-    if (!chan)
-      return 0;
+    if (m) {
+      detect_chan_flood(m, from, chan, FLOOD_NOTICE);
+      detect_chan_flood(m, from, chan, FLOOD_BYTES, msg);
+    }
 
     update_idle(chan-&amp;gt;dname, nick);
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3377,6 +3491,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static cmd_t irc_raw[] =
   {"473","",(Function) got473,"irc:473", LEAF},
   {"474","",(Function) got474,"irc:474", LEAF},
   {"475","",(Function) got475,"irc:475", LEAF},
+  {"478","",(Function) got478,"irc:478", LEAF},
   {"INVITE","",(Function) gotinvite,"irc:invite", LEAF},
   {"TOPIC","",(Function) gottopic,"irc:topic", LEAF},
   {"331","",(Function) got331,"irc:331", LEAF},
diff --git a/src/mod/irc.mod/cmdsirc.c b/src/mod/irc.mod/cmdsirc.c
index 6aaf4e6..a4a2711 100755
--- a/src/mod/irc.mod/cmdsirc.c
+++ b/src/mod/irc.mod/cmdsirc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -121,7 +121,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_act(int idx, char *par)
  chan-&amp;gt;dname, par);
   bd::String msg;
   msg = bd::String::printf("\001ACTION %s\001", par);
-  privmsg(chan-&amp;gt;name, msg.c_str(), DP_HELP);
+  privmsg(chan-&amp;gt;name, msg, DP_HELP);
   dprintf(idx, "Action to %s: %s\n", chan-&amp;gt;dname, par);
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -284,8 +284,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_kickban(int idx, char *par)
       dprintf(idx, "%s is not on %s\n", nick, chan-&amp;gt;dname);
       return;
     }
-    simple_snprintf(s, sizeof s, "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
-    u = get_user_by_host(s);
+    member_getuser(m);
+    u = m-&amp;gt;user;
+    strlcpy(s, m-&amp;gt;from, sizeof(s));
     get_user_flagrec(u, &amp;amp;victim, chan-&amp;gt;dname);
   
     if ((chan_master(victim) || glob_master(victim)) &amp;amp;&amp;amp;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -294,7 +295,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_kickban(int idx, char *par)
       dprintf(idx, "%s is a %s master.\n", nick, chan-&amp;gt;dname);
       return;
     }
-    if (glob_bot(victim) &amp;amp;&amp;amp; !(glob_owner(user) || chan_owner(user))) {
+    if (glob_bot(victim)) {
       if (all) goto next;
       dprintf(idx, "%s is another channel bot!\n", nick);
       return;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -484,7 +485,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_op(int idx, char *par)
   if (!all &amp;amp;&amp;amp; !chan)
     return;
 
-  char s[UHOSTLEN] = "";
   memberlist *m = NULL;
   struct userrec *u = NULL;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -528,8 +528,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_op(int idx, char *par)
     dprintf(idx, "%s is not on %s.\n", nick, chan-&amp;gt;dname);
     return;
   }
-  simple_snprintf(s, sizeof s, "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
-  u = get_user_by_host(s);
+  member_getuser(m);
+  u = m-&amp;gt;user;
   get_user_flagrec(u, &amp;amp;victim, chan-&amp;gt;dname);
   if (chk_deop(victim, chan)) {
     dprintf(idx, "%s is currently being auto-deopped  on %s.\n", m-&amp;gt;nick, chan-&amp;gt;dname);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -618,7 +618,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_mmode(int idx, char *par)
 {
   char *mode = newsplit(&amp;amp;par);
   if (strlen(mode) &amp;gt; 2 || !strchr("+-", mode[0]) || !par[0]) {
-    dprintf(idx, "Usage: mmode &amp;lt;(+|-)MODE&amp;gt; &amp;lt;#channel&amp;gt; &amp;lt;a|o|v|d|r&amp;gt; [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [simul] [local]\n");
+    dprintf(idx, "Usage: mmode &amp;lt;(+|-)MODE&amp;gt; &amp;lt;#channel&amp;gt; &amp;lt;a|o|v|d|r&amp;gt; [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [botbitch] [simul] [local]\n");
     dprintf(idx, "Ie. mmode -o #chan a\n");
     return;
   }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -651,7 +651,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_mmode(int idx, char *par)
     }
   }
   if (!chan || !chname || !chname[0]) {
-    dprintf(idx, "Usage: mmode &amp;lt;(+|-)MODE&amp;gt; &amp;lt;#channel&amp;gt; &amp;lt;a|o|v|d|r&amp;gt; [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [simul] [local]\n");
+    dprintf(idx, "Usage: mmode &amp;lt;(+|-)MODE&amp;gt; &amp;lt;#channel&amp;gt; &amp;lt;a|o|v|d|r&amp;gt; [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [botbitch] [simul] [local]\n");
     dprintf(idx, "Ie. mmode -o #chan a\n");
     return;
   }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -659,7 +659,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_mmode(int idx, char *par)
   char *who = newsplit(&amp;amp;par);
 
   if (strlen(who) &amp;gt; 1 || !strchr("aovdr", who[0])) {
-    dprintf(idx, "Usage: mmode &amp;lt;(+|-)MODE&amp;gt; &amp;lt;#channel&amp;gt; &amp;lt;a|o|v|d|r&amp;gt; [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [simul] [local]\n");
+    dprintf(idx, "Usage: mmode &amp;lt;(+|-)MODE&amp;gt; &amp;lt;#channel&amp;gt; &amp;lt;a|o|v|d|r&amp;gt; [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [botbitch] [simul] [local]\n");
     dprintf(idx, "Ie. mmode -o #chan a\n");
     dprintf(idx, "a = all.\n");
     dprintf(idx, "o = ops.\n");
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -716,7 +716,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_mmode(int idx, char *par)
   }
 
   int force_bots = 0, force_alines = 0, force_slines = 0, force_overlap = 0;
-  bool bitch = 0, simul = 0, local = 0;
+  bool bitch = 0, botbitch = 0, simul = 0, local = 0;
 
   while (par &amp;amp;&amp;amp; par[0]) {
     char *p = newsplit(&amp;amp;par);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -766,6 +766,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_mmode(int idx, char *par)
       }
     } else if (!strncasecmp(p, "bitch", 5)) {
       bitch = 1;
+    } else if (!strncasecmp(p, "botbitch", 8)) {
+      botbitch = 1;
     } else if (!strncasecmp(p, "simul", 5)) {
       simul = 1;
     } else if (!strncasecmp(p, "local", 5)) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -953,6 +955,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_mmode(int idx, char *par)
     chan-&amp;gt;status |= CHAN_BITCH;
     do_chanset(NULL, chan, "+bitch", DO_LOCAL | DO_NET);
   }
+  if (botbitch &amp;amp;&amp;amp; !simul) {
+    chan-&amp;gt;status |= CHAN_BOTBITCH;
+    do_chanset(NULL, chan, "+botbitch", DO_LOCAL | DO_NET);
+  }
   free(targets);
   free(overlaps);
   free(chanbots);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -970,7 +976,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_deop(int idx, char *par)
   if (!all &amp;amp;&amp;amp; !chan)
     return;
 
-  char s[UHOSTLEN] = "";
   memberlist *m = NULL;
   struct userrec *u = NULL;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1016,8 +1021,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_deop(int idx, char *par)
       dprintf(idx, "I'm not going to deop myself.\n");
       return;
     }
-    simple_snprintf(s, sizeof s, "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
-    u = get_user_by_host(s);
+    member_getuser(m);
+    u = m-&amp;gt;user;
     get_user_flagrec(u, &amp;amp;victim, chan-&amp;gt;dname);
 
     if ((chan_master(victim) || glob_master(victim)) &amp;amp;&amp;amp;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1026,6 +1031,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_deop(int idx, char *par)
       if (all) goto next;  
       return;
     }
+    if (glob_bot(victim)) {
+      dprintf(idx, "%s is another channel bot!\n", nick);
+      return;
+    }
     if (chk_op(victim, chan) &amp;amp;&amp;amp; !(chan_master(user) || glob_master(user))) {
       dprintf(idx, "%s has the op flag for %s.\n", m-&amp;gt;nick, chan-&amp;gt;dname);
       if (all) goto next;  
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1070,7 +1079,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_kick(int idx, char *par)
     return;
   }
 
-  char s[UHOSTLEN] = "";
   memberlist *m = NULL;
   struct userrec *u = NULL;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1107,8 +1115,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_kick(int idx, char *par)
       dprintf(idx, "%s is not on %s\n", nick, chan-&amp;gt;dname);
       return;
     }
-    simple_snprintf(s, sizeof s, "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
-    u = get_user_by_host(s);
+    member_getuser(m);
+    u = m-&amp;gt;user;
     get_user_flagrec(u, &amp;amp;victim, chan-&amp;gt;dname);
     if (chk_op(victim, chan) &amp;amp;&amp;amp; !(chan_master(user) || glob_master(user))) {
       if (all) goto next;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1121,7 +1129,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_kick(int idx, char *par)
       dprintf(idx, "%s is a %s master.\n", nick, chan-&amp;gt;dname);
       return;
     }
-    if (glob_bot(victim) &amp;amp;&amp;amp; !(glob_owner(user) || chan_owner(user))) {
+    if (glob_bot(victim)) {
       dprintf(idx, "%s is another channel bot!\n", nick);
       return;
     }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1199,7 +1207,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_mop(int idx, char *par)
   putlog(LOG_CMDS, "*", "#%s# (%s) mop %s", dcc[idx].nick, all ? "*" : chan-&amp;gt;dname, par);
 
   memberlist *m = NULL;
-  char s[256] = "";
 
   while (chan) {
     get_user_flagrec(dcc[idx].user, &amp;amp;user, chan-&amp;gt;dname);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1220,14 +1227,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_mop(int idx, char *par)
     }
     if (channel_active(chan) &amp;amp;&amp;amp; !channel_pending(chan)) {
       for (m = chan-&amp;gt;channel.member; m &amp;amp;&amp;amp; m-&amp;gt;nick[0]; m = m-&amp;gt;next) {
-        if (!m-&amp;gt;user) {
-          simple_snprintf(s, sizeof(s), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
-          m-&amp;gt;user = get_user_by_host(s);
-          if (!m-&amp;gt;user &amp;amp;&amp;amp; m-&amp;gt;userip[0]) {
-            simple_snprintf(s, sizeof(s), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userip);
-            m-&amp;gt;user = get_user_by_host(s);
-          }
-        }
+        member_getuser(m);
         if (m-&amp;gt;user &amp;amp;&amp;amp; u_pass_match(m-&amp;gt;user, "-"))
           continue;/* dont op users without a pass */
         get_user_flagrec(m-&amp;gt;user, &amp;amp;victim, chan-&amp;gt;dname);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1285,10 +1285,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_find(int idx, char *par)
 
       for (m = chan-&amp;gt;channel.member; m &amp;amp;&amp;amp; m-&amp;gt;nick[0]; m = m-&amp;gt;next) {
         member_getuser(m, 1);
-        char s[UHOSTLEN] = "";
 
-        simple_snprintf(s, sizeof(s), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
-        if ((!lookup_user &amp;amp;&amp;amp; wild_match(par, s)) || (lookup_user &amp;amp;&amp;amp; m-&amp;gt;user == u)) {
+        if ((!lookup_user &amp;amp;&amp;amp; wild_match(par, m-&amp;gt;from)) || (lookup_user &amp;amp;&amp;amp; m-&amp;gt;user == u)) {
           fcount++;
           if (!found) {
             found = (memberlist **) my_calloc(1, sizeof(memberlist *) * 100);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1722,8 +1720,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_adduser(int idx, char *par)
   }
   if (strlen(hand) &amp;gt; HANDLEN)
     hand[HANDLEN] = 0;
-  simple_snprintf(s, sizeof s, "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
-  if ((u = get_user_by_host(s))) {
+  member_getuser(m);
+  strlcpy(s, m-&amp;gt;from, sizeof(s));
+  if ((u = m-&amp;gt;user)) {
     dprintf(idx, "%s is already known as %s.\n", nick, u-&amp;gt;handle);
     return;
   }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1760,7 +1759,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_adduser(int idx, char *par)
 
     bd::String msg;
     msg = bd::String::printf("*** You've been add to this botnet as '%s' with the host '%s'. Ask a botnet admin for the msg cmds. Your initial password is: %s", hand, p1, s2);
-    privmsg(nick, msg.c_str(), DP_HELP);
+    privmsg(nick, msg, DP_HELP);
   } else {
     dprintf(idx, "Added hostmask %s to %s.\n", p1, u-&amp;gt;handle);
     addhost_by_handle(hand, p1);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1777,7 +1776,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_deluser(int idx, char *par)
     return;
   }
 
-  char *nick = NULL, s[UHOSTLEN] = "", *added = NULL;
+  char *nick = NULL, *added = NULL;
   struct chanset_t *chan = NULL;
   memberlist *m = NULL;
   struct userrec *u = NULL;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1794,8 +1793,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_deluser(int idx, char *par)
     return;
   }
   get_user_flagrec(dcc[idx].user, &amp;amp;user, chan-&amp;gt;dname);
-  simple_snprintf(s, sizeof s, "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
-  if (!(u = get_user_by_host(s))) {
+  member_getuser(m);
+  if (!(u = m-&amp;gt;user)) {
     dprintf(idx, "%s is not a valid user.\n", nick);
     return;
   }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1929,7 +1928,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_play(int idx, char *par)
   while (stream.tell() &amp;lt; stream.length()) {
     str = stream.getline().chomp();
     if (str.length()) {
-      privmsg(chan-&amp;gt;name, str.c_str(), DP_PLAY);
+      privmsg(chan-&amp;gt;name, str, DP_PLAY);
       ++lines;
     }
   }
diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index 18ae7bc..e3d2605 100755
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -61,6 +61,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 #include &amp;lt;stdarg.h&amp;gt;
 
+#include &amp;lt;math.h&amp;gt;
+
 #define PRIO_DEOP 1
 #define PRIO_KICK 2
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -112,39 +114,118 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; voice_ok(memberlist *m, struct chanset_t *chan)
 #include "cmdsirc.c"
 #include "msgcmds.c"
 
-#ifdef unfinished
-static void
+static int
 detect_offense(memberlist* m, struct chanset_t *chan, char *msg)
 {
+  if (!chan || !msg
+      || !(chan-&amp;gt;capslimit || chan-&amp;gt;colorlimit)
+      || chan_sentkick(m)) //sanity check
+    return 0;
+
   struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 };
   struct userrec *u = m-&amp;gt;user ? m-&amp;gt;user : get_user_by_host(m-&amp;gt;userhost);
-  int i = 0;
+  get_user_flagrec(u, &amp;amp;fr, chan-&amp;gt;dname, chan);
 
-  //size_t tot = strlen(msg);
+  if (glob_bot(fr) ||
+      (m &amp;amp;&amp;amp; chan-&amp;gt;flood_exempt_mode == CHAN_FLAG_OP &amp;amp;&amp;amp; chan_hasop(m)) ||
+      (m &amp;amp;&amp;amp; chan-&amp;gt;flood_exempt_mode == CHAN_FLAG_VOICE &amp;amp;&amp;amp; (chan_hasvoice(m) || chan_hasop(m))))
+    return 0;
 
-  get_user_flagrec(u, &amp;amp;fr, chan-&amp;gt;dname, chan);
+  int color_count = 0, hit_check = 0, hit_count = 0;
+  double caps_percentage = 0, caps_count = 0;
+  const double caps_limit = chan-&amp;gt;capslimit ? double(chan-&amp;gt;capslimit) / 100.0 : double(0);
 
-  for (; *msg; ++msg) {
-    if (egg_isupper(*msg))
-      i++;
+  // Need to know how long the message is, and want to ignore spaces, so avoid a strlen() and just loop to count
+  size_t tot = 0;
+  if (caps_limit) {
+    char *msg_check = msg;
+    while (msg_check &amp;amp;&amp;amp; *msg_check) {
+      if (!egg_isspace(*msg_check) &amp;amp;&amp;amp; *msg_check != 3 &amp;amp;&amp;amp; *msg_check != 2) {
+        ++tot;
+      }
+      ++msg_check;
   }
 
-/*  if ((chan-&amp;gt;capslimit)) { */
-  while (((msg) &amp;amp;&amp;amp; *msg)) {
-    if (egg_isupper(*msg))
-      i++;
-    msg++;
+    if (tot &amp;gt;= 30) {
+      hit_check = tot/5; //check in-between for hits to save waste of cpu
+    } else if (!tot &amp;amp;&amp;amp; !chan-&amp;gt;colorlimit) {
+      // Nothing to do, bail out
+      return 0;
+    }
   }
 
-/*
-  if (chan-&amp;gt;capslimit &amp;amp;&amp;amp; ((i / tot) &amp;gt;= chan-&amp;gt;capslimit)) {
-dprintf(DP_MODE, "PRIVMSG %s :flood stats for %s: %d/%d are CAP, percentage: %d\n", chan-&amp;gt;name, nick, i, tot, (i/tot)*100);
-  if ((((i / tot) * 100) &amp;gt;= 50)) {
-dprintf(DP_HELP, "PRIVMSG %s :cap flood.\n", chan-&amp;gt;dname);
+  while (msg &amp;amp;&amp;amp; *msg) {
+    // Skip spaces
+    if (egg_isspace(*msg)) {
+      ++msg;
+      continue;
+    }
+
+    if (egg_isupper(*msg)) {
+      ++caps_count;
+    } else if (*msg == 3 || *msg == 2) {
+      ++color_count;
+    }
+
+    if (hit_check &amp;amp;&amp;amp; !(hit_count % hit_check)) {
+      if (caps_limit) {
+        caps_percentage = (caps_count)/(double(tot));
+        if (caps_percentage &amp;gt;= caps_limit) {
+          break;
+        }
+      }
+      if (chan-&amp;gt;colorlimit &amp;amp;&amp;amp; color_count &amp;gt;= chan-&amp;gt;colorlimit) {
+        break;
+      }
+      ++hit_count;
+    }
+    ++msg;
+  }
+  if (chan-&amp;gt;capslimit &amp;amp;&amp;amp; caps_count &amp;amp;&amp;amp; tot &amp;gt;= 6) {
+    caps_percentage = (caps_count)/(double(tot));
+    if (caps_percentage &amp;gt;= caps_limit) {
+      const char *response = punish_flooder(chan, m);
+      putlog(LOG_MODES, chan-&amp;gt;name, "Caps flood (%d%%) from %s -- %s", int(caps_percentage * 100), m-&amp;gt;nick, response);
+      return 1;
+    }
+  } else if (chan-&amp;gt;colorlimit &amp;amp;&amp;amp; color_count) {
+    if (color_count &amp;gt;= chan-&amp;gt;colorlimit) {
+      const char *response = punish_flooder(chan, m);
+      putlog(LOG_MODES, chan-&amp;gt;name, "Color flood (%d) from %s -- %s", color_count, m-&amp;gt;nick, response);
+      return 1;
+    }
+  }
+  return 0;
+}
+
+void set_devoice(struct chanset_t *chan, memberlist* m) {
+  if (!(m-&amp;gt;flags &amp;amp; EVOICE)) {
+    putlog(LOG_DEBUG, "&amp;lt; at &amp;gt;", "Giving EVOICE flag to: %s (%s)", m-&amp;gt;nick, chan-&amp;gt;dname);
+    m-&amp;gt;flags |= EVOICE;
   }
-*/
 }
-#endif
+
+const char* punish_flooder(struct chanset_t* chan, memberlist* m, const char *reason) {
+  if (channel_voice(chan) &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate) {
+    if (!chan_sentdevoice(m)) {
+      add_mode(chan, '-', 'v', m-&amp;gt;nick);
+      m-&amp;gt;flags |= SENTDEVOICE;
+      set_devoice(chan, m);
+      return "devoicing";
+    } else {
+      return "devoiced";
+    }
+  } else {
+    if (!chan_sentkick(m)) {
+      dprintf(DP_SERVER, "KICK %s %s :%s%s\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, reason ? reason : response(RES_FLOOD));
+      m-&amp;gt;flags |= SENTKICK;
+      return "kicking";
+    } else {
+      return "kicked";
+    }
+  }
+  return "ignoring";
+}
 
 void unlock_chan(struct chanset_t *chan)
 {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -152,7 +233,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void unlock_chan(struct chanset_t *chan)
     char buf[3] = "", *p = buf;
     if ((chan-&amp;gt;channel.drone_set_mode &amp;amp; CHANINV) &amp;amp;&amp;amp; !(chan-&amp;gt;mode_pls_prot &amp;amp; CHANINV))
       *p++ = 'i';
-    if ((chan-&amp;gt;channel.drone_set_mode &amp;amp; CHANMODER) &amp;amp;&amp;amp; !(chan-&amp;gt;mode_pls_prot &amp;amp; CHANMODER))
+    if ((chan-&amp;gt;channel.drone_set_mode &amp;amp; CHANMODER) &amp;amp;&amp;amp; !((chan-&amp;gt;mode_pls_prot &amp;amp; CHANMODER) || (channel_voice(chan) &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate)))
       *p++ = 'm';
     *p = 0;
     dprintf(DP_MODE, "MODE %s :-%s\n", chan-&amp;gt;name[0] ? chan-&amp;gt;name : chan-&amp;gt;dname, buf);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -160,7 +241,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void unlock_chan(struct chanset_t *chan)
   chan-&amp;gt;channel.drone_set_mode = 0;
 }
 
-void detected_drone_flood(struct chanset_t* chan, memberlist* m) {
+void lockdown_chan(struct chanset_t* chan, flood_reason_t reason, const char* flood_type) {
+  if (!me_op(chan)) {
+    return;
+  }
   egg_timeval_t howlong;
 
   chan-&amp;gt;channel.drone_set_mode = 0;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -186,7 +270,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void detected_drone_flood(struct chanset_t* chan, memberlist* m) {
     howlong.usec = 0;
     timer_create_complex(&amp;amp;howlong, "unlock", (Function) unlock_chan, (void *) chan, 0);
 
-    putlog(LOG_MISC, "*", "Flood detected in %s! Locking for %d seconds.", chan-&amp;gt;dname, chan-&amp;gt;flood_lock_time);
+    if (reason == FLOOD_MASSJOIN) {
+      putlog(LOG_MISC, "*", "Join flood detected in %s! Locking for %d seconds.", chan-&amp;gt;dname, chan-&amp;gt;flood_lock_time);
+    } else if (reason == FLOOD_BANLIST) {
+      putlog(LOG_MISC, "*", "Banlist full in %s! Locking for %d seconds.", chan-&amp;gt;dname, chan-&amp;gt;flood_lock_time);
+    } else if (reason == FLOOD_MASS_FLOOD) {
+      putlog(LOG_MISC, "*", "Mass flood (%s) detected in %s! Locking for %d seconds.", flood_type, chan-&amp;gt;dname, chan-&amp;gt;flood_lock_time);
+    }
   }
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -201,7 +291,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void notice_invite(struct chanset_t *chan, char *handle, char *nick, char *uhost
   bd::String msg;
   msg = bd::String::printf("\001ACTION has invited %s(%s%s%s) to %s.%s\001",
     fhandle, nick, uhost ? "!" : "", uhost ? uhost : "", chan-&amp;gt;dname, op ? ops : "");
-  privmsg(chan-&amp;gt;name, msg.c_str(), DP_MODE);
+  privmsg(chan-&amp;gt;name, msg, DP_MODE);
 }
 
 #ifdef CACHE
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -598,8 +688,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; getin_request(char *botnick, char *code, char *par)
 
   if (what[0] != 'K') {
     if (!(channel_pending(chan) || channel_active(chan))) {
-      putlog(LOG_GETIN, "*", "%sreq from %s/%s %s %s - I'm not on %s right now.", type, botnick, nick, desc, 
-                             chan-&amp;gt;dname, chan-&amp;gt;dname);
       return;
     }
   }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -675,13 +763,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; getin_request(char *botnick, char *code, char *par)
     }
 
     // Does the remote bot have the same number of clients in its channel as me? And a shared member?
-    int members = atoi(tmp);
+    const char *bot_network = tmp;
 
     char *shared_nick = par[0] ? newsplit(&amp;amp;par) : NULL;
     memberlist* shared_member = shared_nick ? ismember(chan, shared_nick) : NULL;
     char *shared_host = par[0] ? newsplit(&amp;amp;par) : NULL;
-    if (!shared_nick || !shared_member || !shared_host || !((chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) == members) || strcmp(shared_host, shared_member-&amp;gt;userhost)) {
-      putlog(LOG_GETIN, "*", "opreq from %s/%s on %s - Bot seems to be on a different network???", botnick, nick, chan-&amp;gt;dname);
+    if (!shared_nick || !shared_member || !shared_host || (strcasecmp(curnetwork, bot_network)) || strcmp(shared_host, shared_member-&amp;gt;userhost)) {
+      putlog(LOG_GETIN, "*", "opreq from %s/%s on %s - Bot seems to be on a different network '%s' / me: '%s'", botnick, nick, chan-&amp;gt;dname, bot_network, curnetwork);
       return;
     }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -695,6 +783,27 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; getin_request(char *botnick, char *code, char *par)
 
     putlog(LOG_GETIN, "*", "opreq from %s/%s on %s - Opped", botnick, nick, chan-&amp;gt;dname);
   } else if (what[0] == 'i') {
+    // Should I respond to this request?
+    // If there's 18 eligible bots in the channel, and in-bots is 2, I have a 2/18 chance of replying.
+    int eligible_bots = 0;
+    for (memberlist* m = chan-&amp;gt;channel.member; m &amp;amp;&amp;amp; m-&amp;gt;nick[0]; m = m-&amp;gt;next) {
+      if (chan_hasop(m)) {
+        member_getuser(m, 0);
+        if (m-&amp;gt;user &amp;amp;&amp;amp; m-&amp;gt;user-&amp;gt;bot) {
+          ++eligible_bots;
+        }
+      }
+    }
+
+    if (!eligible_bots) {
+      return;
+    }
+
+    if (!((randint(eligible_bots) + 1) &amp;lt;= static_cast&amp;lt;unsigned int&amp;gt;(in_bots))) {
+      // Not my turn
+      return;
+    }
+
     if (mem) {
       putlog(LOG_GETIN, "*", "inreq from %s/%s for %s - %s is already on %s", botnick, nick, chan-&amp;gt;dname, nick, chan-&amp;gt;dname);
       return;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -722,17 +831,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; getin_request(char *botnick, char *code, char *par)
       return;
     }
 
+
     bool sendi = 0;
 
     if (chan-&amp;gt;channel.maxmembers) {
-      int lim = (chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) + 5, curlim = chan-&amp;gt;channel.maxmembers;
-      if (curlim &amp;lt; lim) {
-        char s2[6] = "";
-
-        sendi = 1;
-        simple_snprintf(s2, sizeof(s2), "%d", lim);
-        add_mode(chan, '+', 'l', s2);
-        putlog(LOG_GETIN, "*", "inreq from %s/%s for %s - Raised limit to %d", botnick, nick, chan-&amp;gt;dname, lim);
+      if (raise_limit(chan, 5)) {
+        putlog(LOG_GETIN, "*", "inreq from %s/%s for %s - Raised limit", botnick, nick, chan-&amp;gt;dname);
       }
     }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -816,8 +920,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; getin_request(char *botnick, char *code, char *par)
 static void
 request_op(struct chanset_t *chan)
 {
-  if (!chan || (chan &amp;amp;&amp;amp; (channel_pending(chan) || !shouldjoin(chan) || !channel_active(chan) || me_op(chan))))
+  if (!chan || (chan &amp;amp;&amp;amp; (channel_pending(chan) || !shouldjoin(chan) || !channel_active(chan) || me_op(chan)))) {
+    chan-&amp;gt;channel.do_opreq = 0;
     return;
+  }
 
   if (chan-&amp;gt;channel.no_op) {
     if (chan-&amp;gt;channel.no_op &amp;gt; now)      /* dont op until this time has passed */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -826,7 +932,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; request_op(struct chanset_t *chan)
       chan-&amp;gt;channel.no_op = 0;
   }
 
-  chan-&amp;gt;channel.do_opreq = 0;
   /* check server lag */
   if (server_lag &amp;gt; lag_threshold) {
     putlog(LOG_GETIN, "*", "Not asking for ops on %s - I'm too lagged", chan-&amp;gt;dname);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -921,7 +1026,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; request_op(struct chanset_t *chan)
   }
 
   /* first scan for bots on my server, ask first found for ops */
-  simple_snprintf(s, sizeof(s), "gi o %s %s %d %s %s", chan-&amp;gt;dname, botname, (chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers), shared_member-&amp;gt;nick, shared_member-&amp;gt;userhost);
+  simple_snprintf(s, sizeof(s), "gi o %s %s %s %s %s", chan-&amp;gt;dname, botname, curnetwork, shared_member-&amp;gt;nick, shared_member-&amp;gt;userhost);
 
   /* look for bots 0-1 hops away */
   for (i2 = 0; i2 &amp;lt; i; i2++) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -986,15 +1091,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; request_in(struct chanset_t *chan)
   }
 
   int foundBots = 0;
-  char* botops[MAX_BOTS];
+//  char* botops[MAX_BOTS];
 
   for (tand_t* bot = tandbot; bot &amp;amp;&amp;amp; (foundBots &amp;lt; MAX_BOTS); bot = bot-&amp;gt;next) {
     if (bot-&amp;gt;hub || !bot-&amp;gt;u)
       continue;
 
     get_user_flagrec(bot-&amp;gt;u, &amp;amp;fr, chan-&amp;gt;dname, chan);
-    if (bot_shouldjoin(bot-&amp;gt;u, &amp;amp;fr, chan) &amp;amp;&amp;amp; chk_op(fr, chan))
-      botops[foundBots++] = bot-&amp;gt;bot;
+    if (bot_shouldjoin(bot-&amp;gt;u, &amp;amp;fr, chan) &amp;amp;&amp;amp; chk_op(fr, chan)) {
+      ++foundBots;
+//      botops[foundBots++] = bot-&amp;gt;bot;
+    }
   }
 
   if (!foundBots) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1002,207 +1109,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; request_in(struct chanset_t *chan)
     return;
   }
 
-  int cnt = foundBots &amp;lt; in_bots ? foundBots : in_bots;
-  char s[255] = "";
-  char l[1024] = "";
-  size_t len = 0;
-
-  simple_snprintf(s, sizeof(s), "gi i %s %s %s!%s %s", chan-&amp;gt;dname, botname, botname, botuserhost, botuserip);
-
-  shuffleArray(botops, foundBots);
-  for (int n = 0; n &amp;lt; cnt; ++n) {
-    putbot(botops[n], s);
-
-    if (l[0])
-      len += strlcpy(l + len, ", ", sizeof(l) - len);
-    len += strlcpy(l + len, botops[n], sizeof(l) - len);
-  }
-  l[len] = 0;
-  putlog(LOG_GETIN, "*", "Requested help to join %s from %s", chan-&amp;gt;dname, l);
-}
-
-
-#ifdef REVENGE
-/* Contains the logic to decide wether we want to punish someone. Returns
- * true (1) if we want to, false (0) if not.
- */
-static bool
-want_to_revenge(struct chanset_t *chan, struct userrec *u,
-                struct userrec *u2, char *badnick, char *victimstr, bool mevictim)
-{
-  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 };
-
-  /* Do not take revenge upon ourselves. */
-  if (match_my_nick(badnick))
-    return 0;
-
-  get_user_flagrec(u, &amp;amp;fr, chan-&amp;gt;dname, chan);
-
-  /* Kickee didn't kick themself? */
-  if (rfc_casecmp(badnick, victimstr)) {
-    /* They kicked me? */
-    if (mevictim) {
-      /* ... and I'm allowed to take revenge? &amp;lt;snicker&amp;gt; */
-      if (channel_revengebot(chan))
-        return 1;
-      /* Do we revenge for our users ... and do we actually know the victim? */
-    } else if (channel_revenge(chan) &amp;amp;&amp;amp; u2) {
-      struct flag_record fr2 = { FR_GLOBAL | FR_CHAN, 0, 0, 0 };
-
-      get_user_flagrec(u2, &amp;amp;fr2, chan-&amp;gt;dname, chan);
-      /* Protecting friends? */
-      /* Protecting ops? */
-      if ((channel_protectops(chan) &amp;amp;&amp;amp; chk_op(fr2, chan)))
-        return 1;
-    }
-  }
-  return 0;
-}
-
-/* Dependant on revenge_mode, punish the offender.
- */
-static void
-punish_badguy(struct chanset_t *chan, char *whobad,
-              struct userrec *u, char *badnick, char *victimstr, bool mevictim, int type)
-{
-  memberlist *m = ismember(chan, badnick);
-
-  if (!m)
-    return;
-
-  char reason[1024] = "", ct[81] = "", *kick_msg = NULL;
-  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 };
-
-  get_user_flagrec(u, &amp;amp;fr, chan-&amp;gt;dname, chan);
-
-  /* Get current time into a string */
-  strftime(ct, sizeof ct, "%d %b %Z", gmtime(&amp;amp;now));
-
-  /* Put together log and kick messages */
-  reason[0] = 0;
-  switch (type) {
-    case REVENGE_KICK:
-      kick_msg = "don't kick my friends, bud";
-      simple_snprintf(reason, sizeof(reason), "kicked %s off %s", victimstr, chan-&amp;gt;dname);
-      break;
-    case REVENGE_DEOP:
-      simple_snprintf(reason, sizeof(reason), "deopped %s on %s", victimstr, chan-&amp;gt;dname);
-      kick_msg = "don't deop my friends, bud";
-      break;
-    default:
-      kick_msg = "revenge!";
-  }
-  putlog(LOG_MISC, chan-&amp;gt;dname, "Punishing %s (%s)", badnick, reason);
-
-  /* Set the offender +d */
-  if ((chan-&amp;gt;revenge_mode &amp;gt; 0) &amp;amp;&amp;amp;
-      /* ... unless there's no more to do */
-      !(chan_deop(fr) || glob_deop(fr))) {
-    char s[UHOSTLEN], s1[UHOSTLEN];
-    memberlist *mx = NULL;
-
-    /* Removing op */
-    if (chk_op(fr, chan)) {
-      fr.match = FR_CHAN;
-      if (chan_op(fr)) {
-        fr.chan &amp;amp;= ~USER_OP;
-      } else {
-        fr.chan |= USER_DEOP;
-      }
-      set_user_flagrec(u, &amp;amp;fr, chan-&amp;gt;dname);
-      putlog(LOG_MISC, "*", "No longer opping %s[%s] (%s)", u-&amp;gt;handle, whobad, reason);
-    }
-    /* ... or just setting to deop */
-    else if (u) {
-      /* In the user list already, cool :) */
-      fr.match = FR_CHAN;
-      fr.chan |= USER_DEOP;
-      set_user_flagrec(u, &amp;amp;fr, chan-&amp;gt;dname);
-      simple_snprintf(s, sizeof(s), "(%s) %s", ct, reason);
-      putlog(LOG_MISC, "*", "Now deopping %s[%s] (%s)", u-&amp;gt;handle, whobad, s);
-    }
-    /* ... or creating new user and setting that to deop */
-    else {
-      strlcpy(s1, whobad, sizeof(s1));
-      maskhost(s1, s);
-      strlcpy(s1, badnick, sizeof(s1));
-      /* If that handle exists use "badX" (where X is an increasing number)
-       * instead.
-       */
-      while (get_user_by_handle(userlist, s1)) {
-        if (!strncmp(s1, "bad", 3)) {
-          int i;
-
-          i = atoi(s1 + 3);
-          simple_snprintf(s1 + 3, sizeof(s1) - 3, "%d", i + 1);
-        } else
-          strlcpy(s1, "bad1", sizeof(s1));   /* Start with '1' */
-      }
-      userlist = adduser(userlist, s1, s, "-", 0, 0);
-      fr.match = FR_CHAN;
-      fr.chan = USER_DEOP;
-      u = get_user_by_handle(userlist, s1);
-      if ((mx = ismember(chan, badnick)))
-        mx-&amp;gt;user = u;
-      set_user_flagrec(u, &amp;amp;fr, chan-&amp;gt;dname);
-      simple_snprintf(s, sizeof(s), "(%s) %s (%s)", ct, reason, whobad);
-      set_user(&amp;amp;USERENTRY_COMMENT, u, (void *) s);
-      putlog(LOG_MISC, "*", "Now deopping %s (%s)", whobad, reason);
-    }
-  }
-
-  /* Always try to deop the offender */
-  if (!mevictim)
-    add_mode(chan, '-', 'o', badnick);
-  /* Ban. Should be done before kicking. */
-  if (chan-&amp;gt;revenge_mode &amp;gt; 2) {
-    char s[UHOSTLEN] = "", s1[UHOSTLEN] = "";
-
-    splitnick(&amp;amp;whobad);
-    maskhost(whobad, s1);
-    simple_snprintf(s, sizeof(s), "(%s) %s", ct, reason);
-    u_addmask('b', chan, s1, conf.bot-&amp;gt;nick, s, now + (60 * chan-&amp;gt;ban_time), 0);
-    if (!mevictim &amp;amp;&amp;amp; me_op(chan)) {
-      add_mode(chan, '+', 'b', s1);
-      flush_mode(chan, QUICK);
-    }
-  }
-  /* Kick the offender */
-  if ((chan-&amp;gt;revenge_mode &amp;gt; 1) &amp;amp;&amp;amp; !chan_sentkick(m) &amp;amp;&amp;amp;
-      /* ... and can I actually do anything about it? */
-      me_op(chan) &amp;amp;&amp;amp; !mevictim) {
-    dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan-&amp;gt;name, m-&amp;gt;nick, bankickprefix, response(RES_MEAN));
-    m-&amp;gt;flags |= SENTKICK;
-  }
-}
-
-/* Punishes bad guys under certain circumstances using methods as defined
- * by the revenge_mode flag.
- */
-static void
-maybe_revenge(struct chanset_t *chan, char *whobad, char *whovictim, int type)
-{
-  if (!chan || (type &amp;lt; 0))
-    return;
-
-  /* Get info about offender */
-  struct userrec *u = get_user_by_host(whobad), *u2 = NULL;
-  char *badnick = splitnick(&amp;amp;whobad), *victimstr = NULL;
-  bool mevictim;
-
-  /* Get info about victim */
-  u2 = get_user_by_host(whovictim);
-  victimstr = splitnick(&amp;amp;whovictim);
-  mevictim = match_my_nick(victimstr);
-
-  /* Do we want to revenge? */
-  if (!want_to_revenge(chan, u, u2, badnick, victimstr, mevictim))
-    return;                     /* No, leave them alone ... */
-
-  /* Haha! Do the vengeful thing ... */
-  punish_badguy(chan, whobad, u, badnick, victimstr, mevictim, type);
+  bd::String request(bd::String::printf("gi i %s %s %s!%s %s", chan-&amp;gt;dname, botname, botname, botuserhost, botuserip));
+  putallbots(request.c_str());
+  putlog(LOG_GETIN, "*", "Requested help to join %s", chan-&amp;gt;dname);
 }
-#endif
 
 /* Set the key.
  */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1236,7 +1146,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; new_mask(masklist *m, char *s, char *who)
 /* Removes a nick from the channel member list (returns 1 if successful)
  */
 static bool
-killmember(struct chanset_t *chan, char *nick)
+killmember(struct chanset_t *chan, char *nick, bool cacheMember)
 {
   memberlist *x = NULL, *old = NULL;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1252,8 +1162,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; killmember(struct chanset_t *chan, char *nick)
     old-&amp;gt;next = x-&amp;gt;next;
   else
     chan-&amp;gt;channel.member = x-&amp;gt;next;
-  free(x);
-  chan-&amp;gt;channel.members--;
+
+  if (cacheMember) {
+    x-&amp;gt;last = now;
+    // Don't delete here, will delete when it expires from the cache.
+    (*chan-&amp;gt;channel.cached_members)[x-&amp;gt;userhost] = x;
+  } else {
+    chan-&amp;gt;channel.cached_members-&amp;gt;remove(x-&amp;gt;userhost);
+    delete_member(x);
+  }
+
+  --chan-&amp;gt;channel.members;
 
   /* The following two errors should NEVER happen. We will try to correct
    * them though, to keep the bot from crashing.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1276,25 +1195,36 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; killmember(struct chanset_t *chan, char *nick)
   return 1;
 }
 
-/* Check if I am a chanop. Returns boolean 1 or 0.
+/**
+ * Update the member with cached information from a parted/quitted member
  */
-bool
-me_op(struct chanset_t *chan)
-{
-  memberlist *mx = ismember(chan, botname);
+static void member_update_from_cache(struct chanset_t* chan, memberlist *m) {
+  using std::swap;
 
-  if (!mx)
-    return 0;
-  if (chan_hasop(mx))
-    return 1;
-  else
-    return 0;
+  // Are they in the cache?
+  const bd::String userhost(m-&amp;gt;userhost);
+  if (chan-&amp;gt;channel.cached_members-&amp;gt;contains(userhost)) {
+    memberlist *cached_member = (*chan-&amp;gt;channel.cached_members)[userhost];
+
+    // Update important flood tracking information
+    swap(m-&amp;gt;floodtime, cached_member-&amp;gt;floodtime);
+    swap(m-&amp;gt;floodnum, cached_member-&amp;gt;floodnum);
+
+    // Update EVOICE flag
+    if (cached_member-&amp;gt;flags &amp;amp; EVOICE) {
+      m-&amp;gt;flags |= EVOICE;
+    }
+
+    // No longer need the cached member
+    delete_member(cached_member);
+    chan-&amp;gt;channel.cached_members-&amp;gt;remove(userhost);
+  }
 }
 
 /* Check whether I'm voice. Returns boolean 1 or 0.
  */
 bool
-me_voice(struct chanset_t *chan)
+me_voice(const struct chanset_t *chan)
 {
   memberlist *mx = ismember(chan, botname);
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1423,8 +1353,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_lonely_channel(struct chanset_t *chan)
       !shouldjoin(chan) || (chan-&amp;gt;channel.mode &amp;amp; CHANANON))
     return;
 
-  memberlist *m = NULL;
-  char s[UHOSTLEN] = "";
   static int whined = 0;
 
   if ((chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) == 1 &amp;amp;&amp;amp; channel_cycle(chan) &amp;amp;&amp;amp; !channel_stop_cycle(chan)) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1436,15 +1364,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_lonely_channel(struct chanset_t *chan)
     }
   } else if (any_ops(chan)) {
     whined = 0;
-    request_op(chan);
-/* need: op */
   } else {
     /* Other people here, but none are ops. If there are other bots make
      * them LEAVE!
      */
-    bool ok = 1;
-    struct userrec *u = NULL;
-
     if (!whined) {
       /* + is opless. Complaining about no ops when without special
        * help(services), we cant get them - Raist
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1453,10 +1376,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_lonely_channel(struct chanset_t *chan)
         putlog(LOG_MISC, "*", "%s is active but has no ops :(", chan-&amp;gt;dname);
       whined = 1;
     }
+#ifdef disabled
+    memberlist *m = NULL;
+    bool ok = 1;
+
     for (m = chan-&amp;gt;channel.member; m &amp;amp;&amp;amp; m-&amp;gt;nick[0]; m = m-&amp;gt;next) {
-      simple_snprintf(s, sizeof(s), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
-      u = get_user_by_host(s);
-      if (!m-&amp;gt;is_me &amp;amp;&amp;amp; (!u || !u-&amp;gt;bot)) {
+      member_getuser(m, 0);
+
+      if (!m-&amp;gt;is_me &amp;amp;&amp;amp; (!m-&amp;gt;user || !m-&amp;gt;user-&amp;gt;bot)) {
         ok = 0;
         break;
       }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1468,11 +1395,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_lonely_channel(struct chanset_t *chan)
 if (!m-&amp;gt;is_me)
   dprintf(DP_SERVER, "PRIVMSG %s :go %s\n", m-&amp;gt;nick, chan-&amp;gt;dname);
 */
-    } else {
-      /* Some humans on channel, but still op-less */
-      request_op(chan);
-/* need: op */
     }
+#endif
   }
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1525,44 +1449,59 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_netfight(struct chanset_t *chan)
   chan-&amp;gt;channel.fighting = 0;   /* we put this here because we need to clear it once per min */
 }
 
-void
-raise_limit(struct chanset_t *chan)
+bool
+raise_limit(struct chanset_t *chan, int default_limitraise)
 {
   if (!chan || !me_op(chan))
-    return;
+    return false;
 
   /* Don't bother setting limit if the user has set a protect -l */
   if (chan-&amp;gt;mode_mns_prot &amp;amp; CHANLIMIT)
-    return;
+    return false;
 
-  int nl = (chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) + chan-&amp;gt;limitraise;/* new limit */
-  int i = chan-&amp;gt;limitraise &amp;gt;&amp;gt; 2;/* DIV 4 */
+  const int limitraise = (chan-&amp;gt;limitraise ? ((chan-&amp;gt;limitraise % 2 == 0) ? chan-&amp;gt;limitraise : (chan-&amp;gt;limitraise + 1)) : default_limitraise);
+  if (limitraise) {
+    const int nl = (chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) + limitraise;/* new limit */
+    const int i = limitraise &amp;gt;&amp;gt; 2;/* DIV 4 */
   /* if the newlimit will be in the range made by these vars, dont change. */
-  int ul = nl + i;/* upper limit */
-  int ll = nl - i;/* lower limit */
+    const int ul = nl + i;/* upper limit */
+    const int ll = nl - i;/* lower limit */
 
-  if ((chan-&amp;gt;channel.maxmembers &amp;gt; ll) &amp;amp;&amp;amp; (chan-&amp;gt;channel.maxmembers &amp;lt; ul))
-    return;                     /* the current limit is in the range, so leave it. */
+    if ((chan-&amp;gt;channel.maxmembers &amp;gt;= ll) &amp;amp;&amp;amp; (chan-&amp;gt;channel.maxmembers &amp;lt;= ul)) {
+      return false;                     /* the current limit is in the range, so leave it. */
+    }
 
   if (nl != chan-&amp;gt;channel.maxmembers) {
     char s[6] = "";
 
     simple_snprintf(s, sizeof(s), "%d", nl);
     add_mode(chan, '+', 'l', s);
+
+      return true;
+    }
   }
 
+  return false;
 }
 
-static void
-check_expired_chanstuff(struct chanset_t *chan)
+void check_shouldjoin(struct chanset_t* chan)
 {
   if ((channel_active(chan) || channel_pending(chan)) &amp;amp;&amp;amp; !shouldjoin(chan)) {
     sdprintf("Active/Pending in %s but I shouldn't be there, parting...", chan-&amp;gt;dname);
-    dprintf(DP_MODE, "PART %s\n", chan-&amp;gt;name[0] ? chan-&amp;gt;name : chan-&amp;gt;dname);
-  } else if (channel_active(chan)) {
+    dprintf(DP_SERVER, "PART %s\n", chan-&amp;gt;name[0] ? chan-&amp;gt;name : chan-&amp;gt;dname);
+  } else if (shouldjoin(chan)) {
+    join_chan(chan);
+  }
+}
+
+static void
+check_expired_chanstuff(struct chanset_t *chan)
+{
+  memberlist *m = NULL;
+  check_shouldjoin(chan);
+  if (channel_active(chan) &amp;amp;&amp;amp; shouldjoin(chan)) {
     masklist *b = NULL, *e = NULL;
-    memberlist *m = NULL, *n = NULL;
-    char s[UHOSTLEN] = "";
+    memberlist *n = NULL;
     struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 };
 
     if (me_op(chan)) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1614,17 +1553,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_expired_chanstuff(struct chanset_t *chan)
       }
     } /* me_op */
 
-//    for (m = chan-&amp;gt;channel.member; m &amp;amp;&amp;amp; m-&amp;gt;nick[0]; m = m-&amp;gt;next) {
-    int splitmembers = 0;
+    size_t splitmembers = 0, bot_ops = 0;
+    const bool im_opped = me_op(chan);
     for (m = chan-&amp;gt;channel.member; m &amp;amp;&amp;amp; m-&amp;gt;nick[0]; m = n) {
       n = m-&amp;gt;next;
+      // Update split members
       if (m-&amp;gt;split) {
         ++splitmembers;
         if (now - m-&amp;gt;split &amp;gt; wait_split) {
-          simple_snprintf(s, sizeof(s), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
           putlog(LOG_JOIN, chan-&amp;gt;dname, "%s (%s) got lost in the net-split.", m-&amp;gt;nick, m-&amp;gt;userhost);
           --(chan-&amp;gt;channel.splitmembers);
-          killmember(chan, m-&amp;gt;nick);
+          killmember(chan, m-&amp;gt;nick, false);
           continue;
         }
       }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1640,7 +1579,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_expired_chanstuff(struct chanset_t *chan)
         }
       }
 
-      if (me_op(chan)) {
+      if (im_opped) {
         if (dovoice(chan) &amp;amp;&amp;amp; !loading) {      /* autovoice of +v users if bot is +y */
           if (!chan_hasop(m) &amp;amp;&amp;amp; !chan_hasvoice(m) &amp;amp;&amp;amp; !chan_sentvoice(m)) {
             member_getuser(m, 1);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1665,13 +1604,37 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_expired_chanstuff(struct chanset_t *chan)
           }
         }
       }
+      if (m-&amp;gt;user &amp;amp;&amp;amp; m-&amp;gt;user-&amp;gt;bot) {
+        ++bot_ops;
+      }
       m = n;
     }
     // Update minutely
     chan-&amp;gt;channel.splitmembers = splitmembers;
     check_lonely_channel(chan);
-  } else if (shouldjoin(chan))
-    join_chan(chan);
+    if (bot_ops &amp;amp;&amp;amp; !im_opped) {
+      request_op(chan);
+    }
+
+    if (role == 3) {
+      recheck_channel_modes(chan);
+    }
+  }
+  // Clear out expired cached members
+  if (chan-&amp;gt;channel.cached_members &amp;amp;&amp;amp; chan-&amp;gt;channel.cached_members-&amp;gt;size()) {
+    bd::Array&amp;lt;bd::String&amp;gt; member_uhosts(chan-&amp;gt;channel.cached_members-&amp;gt;keys());
+    for (size_t i = 0; i &amp;lt; member_uhosts.length(); ++i) {
+      const bd::String uhost(member_uhosts[i]);
+
+      m = (*chan-&amp;gt;channel.cached_members)[uhost];
+
+      // Delete the expired member
+      if (now - m-&amp;gt;last &amp;gt; wait_split) {
+        delete_member(m);
+        chan-&amp;gt;channel.cached_members-&amp;gt;remove(uhost);
+      }
+    }
+  }
 }
 
 void
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1794,23 +1757,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static cmd_t irc_bot[] = {
   {NULL, NULL, NULL, NULL, 0}
 };
 
-static void
-getin_5secondly()
-{
-  if (!server_online)
-    return;
-
-  for (register struct chanset_t *chan = chanset; chan; chan = chan-&amp;gt;next) {
-    if ((!channel_pending(chan) &amp;amp;&amp;amp; channel_active(chan)) &amp;amp;&amp;amp; !me_op(chan))
-      request_op(chan);
-  }
-}
-
 void
 irc_init()
 {
   timer_create_secs(60, "irc_minutely", (Function) irc_minutely);
-  timer_create_secs(5, "getin_5secondly", (Function) getin_5secondly);
 
   /* Add our commands to the imported tables. */
   add_builtins("dcc", irc_dcc);
diff --git a/src/mod/irc.mod/irc.h b/src/mod/irc.mod/irc.h
index 7234c1b..995876a 100755
--- a/src/mod/irc.mod/irc.h
+++ b/src/mod/irc.mod/irc.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -7,12 +7,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #define _EGG_MOD_IRC_IRC_H
 
 #include "src/auth.h"
+#include "src/chanprog.h"
 
 enum { BC_NOCOOKIE = 1, BC_SLACK, BC_HASH, BC_COUNTER };
 
-//#define REVENGE_KICK 1/* Kicked victim*/
-//#define REVENGE_DEOP 2/* Took op*/
-
 #define PRIO_DEOP 1
 #define PRIO_KICK 2
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -26,6 +24,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; namespace bd {
   class String;
 }
 
+enum flood_reason_t {
+  FLOOD_MASSJOIN,
+  FLOOD_BANLIST,
+  FLOOD_MASS_FLOOD
+};
+
 #ifdef CACHE
 typedef struct cache_chan_b {
   struct cache_chan_b *next;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -79,22 +83,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void do_protect(struct chanset_t* chan, const char* reason);
 #define resetexempts(chan)  resetmasks((chan), (chan)-&amp;gt;channel.exempt, (chan)-&amp;gt;exempts, global_exempts, 'e')
 #define resetinvites(chan)  resetmasks((chan), (chan)-&amp;gt;channel.invite, (chan)-&amp;gt;invites, global_invites, 'I')
 
-//static void detect_offense(memberlist*, struct chanset_t *, char *);
+static int detect_offense(memberlist*, struct chanset_t *, char *);
 /* static int target_priority(struct chanset_t *, memberlist *, int); */
 static bool do_op(char *, struct chanset_t *, bool, bool);
 static void request_op(struct chanset_t *);
 static void request_in(struct chanset_t *);
-//static void maybe_revenge(struct chanset_t *, char *, char *, int);
-static bool detect_chan_flood(char *, char *, char *, struct chanset_t *, int,
-     char *);
+static bool detect_chan_flood(memberlist *m, const char* from, struct chanset_t *chan, flood_t which, const char *msg = NULL);
 static bool new_mask(masklist *, char *, char *);
 static void do_closed_kick(struct chanset_t *, memberlist *);
-static char *quickban(struct chanset_t *, char *);
-static bool killmember(struct chanset_t *chan, char *nick);
+static char *quickban(struct chanset_t *, const char *);
+static bool killmember(struct chanset_t *chan, char *nick, bool cacheMember = true);
+static void member_update_from_cache(struct chanset_t* chan, memberlist *m);
 static void check_lonely_channel(struct chanset_t *chan);
 static int gotmode(char *, char *);
 void unset_im(struct chanset_t* chan);
-void detected_drone_flood(struct chanset_t* chan, memberlist*);
+void lockdown_chan(struct chanset_t* chan, flood_reason_t reason, const char* flood_type = NULL);
 static void send_chan_who(int queue, struct chanset_t* chan, bool chain = 0);
 #define newban(chan, mask, who)         new_mask((chan)-&amp;gt;channel.ban, mask, who)
 #define newexempt(chan, mask, who)      new_mask((chan)-&amp;gt;channel.exempt, mask, who)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -105,6 +108,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct resolvstruct resolv_member;
 void resolve_to_rbl(struct chanset_t *chan, const char *host, struct resolvstruct *r = NULL);
 static void do_mask(struct chanset_t *chan, masklist *m, char *mask, char Mode);
 static void get_channel_masks(struct chanset_t* chan);
+const char* punish_flooder(struct chanset_t* chan, memberlist* m, const char *reason = NULL);
+void set_devoice(struct chanset_t* chan, memberlist* m);
 
 #endif /* MAKING_IRC */
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -117,8 +122,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void notice_invite(struct chanset_t *, char *, char *, char *, bool);
 void real_add_mode(struct chanset_t *, const char, const char, const char *, bool);
 #define add_mode(chan, pls, mode, nick) real_add_mode(chan, pls, mode, nick, 0)
 #define add_cookie(chan, nick) real_add_mode(chan, '+', 'o', nick, 1)
-bool me_op(struct chanset_t *);
-bool me_voice(struct chanset_t *);
+/* Check if I am a chanop. Returns boolean 1 or 0.
+ */
+inline bool me_op(const struct chanset_t *chan)
+{
+  const memberlist *mx = ismember(chan, botname);
+  return mx &amp;amp;&amp;amp; chan_hasop(mx);
+}
+
+bool me_voice(const struct chanset_t *);
 
 void check_this_ban(struct chanset_t *, char *, bool);
 void check_this_exempt(struct chanset_t *, char *, bool);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -137,7 +149,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; inline void check_this_mask(const char type, struct chanset_t *chan, char *mask,
 }
 
 void check_this_user(char *, int, char *);
-void raise_limit(struct chanset_t *);
+bool raise_limit(struct chanset_t *, int default_limitraise = 0);
 void enforce_closed(struct chanset_t *);
 void recheck_channel(struct chanset_t *, int);
 void recheck_channel_modes(struct chanset_t *);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -145,6 +157,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void irc_report(int, int);
 void flush_modes();
 void reset_chan_info(struct chanset_t *);
 char *getnick(const char *, struct chanset_t *);
+void check_shouldjoin(struct chanset_t* chan);
+void delete_member(memberlist* m);
 
 extern intmax_bans, max_exempts, max_invites, max_modes;
 extern booluse_354, include_lk;
diff --git a/src/mod/irc.mod/mode.c b/src/mod/irc.mod/mode.c
index f78f50d..ecdf8ac 100755
--- a/src/mod/irc.mod/mode.c
+++ b/src/mod/irc.mod/mode.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -31,6 +31,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 /* Reversing this mode? */
 static bool reversing = 0;
+static bool massop = 0;
+static bool mdop_reversing = 1;
 
 #  define PLUS    BIT0
 #  define MINUS   BIT1
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -541,8 +543,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void
 got_op(struct chanset_t *chan, memberlist *m, memberlist *mv)
 {
   bool check_chan = 0;
-  bool me_opped = mv-&amp;gt;is_me;
+  const bool me_opped = mv-&amp;gt;is_me;
   bool meop = me_op(chan);
+  const bool was_op = chan_hasop(mv);
+
+  // No need to punish someone who was already opped.
+  if (massop &amp;amp;&amp;amp; was_op)
+    return;
 
   /* Did *I* just get opped? */
   if (!meop &amp;amp;&amp;amp; me_opped) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -550,7 +557,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; got_op(struct chanset_t *chan, memberlist *m, memberlist *mv)
     meop = 1;
   }
 
+  if (mv-&amp;gt;user) {
   get_user_flagrec(mv-&amp;gt;user, &amp;amp;victim, chan-&amp;gt;dname, chan);
+
+    // Did some other bot just get opped, and I'm not opped yet?
+    if (mv-&amp;gt;user-&amp;gt;bot &amp;amp;&amp;amp; !me_opped &amp;amp;&amp;amp; !meop) {
+      chan-&amp;gt;channel.do_opreq = 1;
+    }
+  }
   /* Flags need to be set correctly right from the beginning now, so that
    * add_mode() doesn't get irritated.
    */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -579,12 +593,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; got_op(struct chanset_t *chan, memberlist *m, memberlist *mv)
       size_t len = 0;
 /* should kick the oppee first, then deal with the opper */
 
+#ifdef old
       if (num == 4) {
         len = simple_snprintf(outbuf, sizeof(outbuf), "MODE %s -o %s\r\n", chan-&amp;gt;name, mv-&amp;gt;nick);
         mv-&amp;gt;flags |= SENTDEOP;
       } else if (num == 5) {
         len = simple_snprintf(outbuf, sizeof(outbuf), "MODE %s -o %s\r\n", chan-&amp;gt;name, m-&amp;gt;nick);
         m-&amp;gt;flags |= SENTDEOP;
+#endif
+      if (num == 5) {
+        add_mode(chan, '-', 'o', m-&amp;gt;nick);
       } else if (bitch &amp;amp;&amp;amp; num == 6) {
         len = simple_snprintf(outbuf, sizeof(outbuf), "KICK %s %s :%s\r\n", chan-&amp;gt;name, mv-&amp;gt;nick, response(RES_BITCHOPPED));
         mv-&amp;gt;flags |= SENTKICK;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -631,12 +649,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; got_op(struct chanset_t *chan, memberlist *m, memberlist *mv)
 static void
 got_deop(struct chanset_t *chan, memberlist *m, memberlist *mv, char *isserver)
 {
-  char s1[UHOSTLEN] = "";
+  const bool was_op = chan_hasop(mv);
   
-  if (m)
-    simple_snprintf(s1, sizeof(s1), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
+  if (mdop_reversing &amp;amp;&amp;amp; !was_op)
+    return;
 
+  /* m is NULL if a server made the change */
+  if (mv-&amp;gt;user) {
   get_user_flagrec(mv-&amp;gt;user, &amp;amp;victim, chan-&amp;gt;dname, chan);
+  }
 
   /* Flags need to be set correctly right from the beginning now, so that
    * add_mode() doesn't get irritated.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -651,19 +672,29 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; got_deop(struct chanset_t *chan, memberlist *m, memberlist *mv, char *isserver)
   /* Deop'd someone on my oplist? */
   if (me_op(chan)) {
     /* do we want to reop victim? */
-    if ((reversing) &amp;amp;&amp;amp; 
-        ((m &amp;amp;&amp;amp; !m-&amp;gt;is_me &amp;amp;&amp;amp; rfc_casecmp(mv-&amp;gt;nick, m-&amp;gt;nick)) || (!m)) &amp;amp;&amp;amp;
-        !mv-&amp;gt;is_me &amp;amp;&amp;amp;
-        (chk_op(victim, chan) || !chan_bitch(chan)))
+    if (
+        /* I didn't deop them, another bot didn't deop them and they didn't deop themselves. */
+        (was_op &amp;amp;&amp;amp; ((m &amp;amp;&amp;amp; !m-&amp;gt;is_me &amp;amp;&amp;amp; mv != m &amp;amp;&amp;amp; !(m-&amp;gt;user &amp;amp;&amp;amp; m-&amp;gt;user-&amp;gt;bot)) || (!m))) &amp;amp;&amp;amp; (
+          /*
+           * reversing
+           * They are either an op or this chan is -bitch
+           */
+          (reversing &amp;amp;&amp;amp; (!chan_bitch(chan) || chk_op(victim, chan))) ||
+          /* Reop bots to avoid them needing to ask */
+          (role == 3 &amp;amp;&amp;amp; mv-&amp;gt;user &amp;amp;&amp;amp; mv-&amp;gt;user-&amp;gt;bot &amp;amp;&amp;amp; chk_op(victim, chan))
+        )
+       ) {
       /* Then we'll bless the victim */
       do_op(mv-&amp;gt;nick, chan, 0, 0);
   }
+  }
 
   if (isserver[0])/* !m */
     putlog(LOG_MODES, chan-&amp;gt;dname, "TS resync (%s): %s deopped by %s", chan-&amp;gt;dname, mv-&amp;gt;nick, isserver);
   /* Check for mass deop */
-  else if (m)
-    detect_chan_flood(m-&amp;gt;nick, m-&amp;gt;userhost, s1, chan, FLOOD_DEOP, mv-&amp;gt;nick);
+  else if (m) {
+    detect_chan_flood(m, m-&amp;gt;from, chan, FLOOD_DEOP, mv-&amp;gt;nick);
+  }
   /* Having op hides your +v and +h  status -- so now that someone's lost ops,
    * check to see if they have +v or +h
    */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -685,30 +716,69 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; got_deop(struct chanset_t *chan, memberlist *m, memberlist *mv, char *isserver)
 /* need: op */
     if (!m)
       putlog(LOG_MODES, chan-&amp;gt;dname, "TS resync deopped me on %s :(", chan-&amp;gt;dname);
+  } else {
+    // Revenge kick clients that deop our bots
+    if (chan-&amp;gt;revenge &amp;amp;&amp;amp; m &amp;amp;&amp;amp; m != mv &amp;amp;&amp;amp; mv-&amp;gt;user &amp;amp;&amp;amp; mv-&amp;gt;user-&amp;gt;bot &amp;amp;&amp;amp; !(m-&amp;gt;user &amp;amp;&amp;amp; m-&amp;gt;user-&amp;gt;bot)) {
+      if (role &amp;lt; 5 &amp;amp;&amp;amp; !chan_sentkick(m) &amp;amp;&amp;amp; me_op(chan)) {
+        m-&amp;gt;flags |= SENTKICK;
+        dprintf(DP_MODE_NEXT, "KICK %s %s :%s%s\r\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, response(RES_REVENGE));
+      } else {
+        if (m-&amp;gt;user) {
+          char tmp[128] = "";
+          simple_snprintf(tmp, sizeof(tmp), "Deopped bot %s on %s", mv-&amp;gt;nick, chan-&amp;gt;dname);
+          deflag_user(m-&amp;gt;user, DEFLAG_EVENT_REVENGE_DEOP, tmp, chan);
+        }
+      }
   }
-  if (m) {
-    char s[UHOSTLEN] = "";
-
-    simple_snprintf(s, sizeof(s), "%s!%s", mv-&amp;gt;nick, mv-&amp;gt;userhost);
-//    maybe_revenge(chan, s1, s, REVENGE_DEOP);
   }
 }
 
 static void
 got_ban(struct chanset_t *chan, memberlist *m, char *mask, char *isserver)
 {
-  char me[UHOSTLEN] = "", meip[UHOSTLEN] = "", s[UHOSTLEN] = "";
+  const memberlist *me = ismember(chan, botname);
+  char s[UHOSTLEN] = "";
 
-  simple_snprintf(me, sizeof(me), "%s!%s", botname, botuserhost);
-  simple_snprintf(meip, sizeof(meip), "%s!%s", botname, botuserip);
   simple_snprintf(s, sizeof s, "%s!%s", m ? m-&amp;gt;nick : "", m ? m-&amp;gt;userhost : isserver);
-  if (newban(chan, mask, s))
+  if (m &amp;amp;&amp;amp; newban(chan, mask, m-&amp;gt;from))
     return; /* The ban was already set, don't bother with it */
 
   if (channel_pending(chan) || !me_op(chan))
     return;
 
-  if ((wild_match(mask, me) || match_cidr(mask, meip)) &amp;amp;&amp;amp; !isexempted(chan, me)) {
+  // Make an array of all matching users
+  bd::Array&amp;lt;memberlist*&amp;gt; matchedUserMembers;
+  memberlist *matched_bot = NULL;
+
+  for (memberlist *mv = chan-&amp;gt;channel.member; mv &amp;amp;&amp;amp; mv-&amp;gt;nick[0]; mv = mv-&amp;gt;next) {
+    member_getuser(mv);
+    if (mv-&amp;gt;user) {
+      if ((wild_match(mask, mv-&amp;gt;from) || match_cidr(mask, mv-&amp;gt;from))) {
+        if (!matched_bot &amp;amp;&amp;amp; mv != m &amp;amp;&amp;amp; mv-&amp;gt;user-&amp;gt;bot) {
+          matched_bot = mv;
+        }
+        if (mv-&amp;gt;user &amp;amp;&amp;amp; !isexempted(chan, mv-&amp;gt;from)) {
+          matchedUserMembers &amp;lt;&amp;lt; mv;
+        }
+      }
+    }
+  }
+
+  // Revenge kick clients that ban our bots
+  if (chan-&amp;gt;revenge &amp;amp;&amp;amp; m &amp;amp;&amp;amp; matched_bot &amp;amp;&amp;amp; !(m-&amp;gt;user &amp;amp;&amp;amp; m-&amp;gt;user-&amp;gt;bot)) {
+    if (role &amp;lt; 5 &amp;amp;&amp;amp; !chan_sentkick(m)) {
+      m-&amp;gt;flags |= SENTKICK;
+      dprintf(DP_MODE_NEXT, "KICK %s %s :%s%s\r\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, response(RES_REVENGE));
+    } else {
+      if (m-&amp;gt;user) {
+        char tmp[128] = "";
+        simple_snprintf(tmp, sizeof(tmp), "Banned bot %s (%s) on %s", matched_bot-&amp;gt;nick, mask, chan-&amp;gt;dname);
+        deflag_user(m-&amp;gt;user, DEFLAG_EVENT_REVENGE_BAN, tmp, chan);
+      }
+    }
+  }
+
+  if ((wild_match(mask, me-&amp;gt;from) || match_cidr(mask, me-&amp;gt;fromip)) &amp;amp;&amp;amp; !isexempted(chan, me-&amp;gt;from)) {
     add_mode(chan, '-', 'b', mask);
     reversing = 1;
     return;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -720,25 +790,19 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; got_ban(struct chanset_t *chan, memberlist *m, char *mask, char *isserver)
       return;
     }
     /* remove bans on ops unless a master/bot set it */
-    char s1[UHOSTLEN] = "";
-
-    for (memberlist *m2 = chan-&amp;gt;channel.member; m2 &amp;amp;&amp;amp; m2-&amp;gt;nick[0]; m2 = m2-&amp;gt;next) {
-      simple_snprintf(s1, sizeof s1, "%s!%s", m2-&amp;gt;nick, m2-&amp;gt;userhost);
-      if ((wild_match(mask, s1) || match_cidr(mask, s1))
-          &amp;amp;&amp;amp; !isexempted(chan, s1)) {
-        if (m2-&amp;gt;user || (!m2-&amp;gt;user &amp;amp;&amp;amp; (m2-&amp;gt;user = get_user_by_host(s1)))) {
-          get_user_flagrec(m2-&amp;gt;user, &amp;amp;victim, chan-&amp;gt;dname, chan);
+
+    for (size_t n = 0; n &amp;lt; matchedUserMembers.size(); ++n) {
+      const memberlist *mv = matchedUserMembers[n];
+      get_user_flagrec(mv-&amp;gt;user, &amp;amp;victim, chan-&amp;gt;dname, chan);
           if (!(glob_kick(victim) || chan_kick(victim)) &amp;amp;&amp;amp; 
               (((chk_op(victim, chan) &amp;amp;&amp;amp; !chan_master(user) &amp;amp;&amp;amp; !glob_master(user) &amp;amp;&amp;amp; !glob_bot(user)) || 
-              (m2-&amp;gt;user-&amp;gt;bot &amp;amp;&amp;amp; findbot(m2-&amp;gt;user-&amp;gt;handle))) &amp;amp;&amp;amp; !isexempted(chan, s1))) {
+            (mv-&amp;gt;user-&amp;gt;bot &amp;amp;&amp;amp; findbot(mv-&amp;gt;user-&amp;gt;handle))))) {
             /* if (target_priority(chan, m, 0)) */
             add_mode(chan, '-', 'b', mask);
             return;
           }
         }
       }
-    }
-  }
   refresh_exempt(chan, mask);
   /* This looks for bans added through bot and tacks on banned: if a description is found */
   if (m &amp;amp;&amp;amp; channel_enforcebans(chan)) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1015,7 +1079,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; gotmode(char *from, char *msg)
       memberlist *mv = NULL;
 
 
-      reversing = 0;
+      massop = reversing = 0;
 
       irc_log(chan, "%s!%s sets mode: %s", nick, from, msg);
       get_user_flagrec(u, &amp;amp;user, ch);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1086,9 +1150,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; gotmode(char *from, char *msg)
               } else {
                 if (u) {
                   simple_snprintf(tmp, sizeof(tmp), "Mass deop on %s by %s", chan-&amp;gt;dname, m-&amp;gt;nick);
-                  deflag_user(u, DEFLAG_MDOP, tmp, chan);
+                  deflag_user(u, DEFLAG_EVENT_MDOP, tmp, chan);
                 }
               }
+              reversing = mdop_reversing = 1;
             }
             if (channel_protect(chan))
               do_protect(chan, "Mass Deop");
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1105,13 +1170,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; gotmode(char *from, char *msg)
                 } else { 
                   if (u) {
                     simple_snprintf(tmp, sizeof(tmp), "Mass op on %s by %s", chan-&amp;gt;dname, m-&amp;gt;nick);
-                    deflag_user(u, DEFLAG_MOP, tmp, chan);
+                    deflag_user(u, DEFLAG_EVENT_MOP, tmp, chan);
                   }
                 }
               }
               // Don't mass deop if protect is set, it'll happen anyway below
               if (channel_bitch(chan) &amp;amp;&amp;amp; !channel_protect(chan))
                 enforce_bitch(chan);        /* deop quick! */
+              else
+                reversing = massop = 1; // Reverse via got_op
             }
             if (channel_protect(chan))
               do_protect(chan, "Mass OP");
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1170,8 +1237,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; gotmode(char *from, char *msg)
                   const size_t len = simple_snprintf(tmp, sizeof(tmp), "KICK %s %s :%s%s\r\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, response(RES_BADOP));
                   dprintf_real(DP_MODE_NEXT, tmp, len, sizeof(tmp));
                 }
-                simple_snprintf(tmp, sizeof(tmp), "%s!%s MODE %s %s", m-&amp;gt;nick, m-&amp;gt;userhost, chan-&amp;gt;dname, modes[modecnt - 1]);
-                deflag_user(u, DEFLAG_BADCOOKIE, tmp, chan);
+                simple_snprintf(tmp, sizeof(tmp), "%s MODE %s %s", m-&amp;gt;from, chan-&amp;gt;dname, modes[modecnt - 1]);
+                deflag_user(u, DEFLAG_EVENT_BADCOOKIE, tmp, chan);
               }
               /* Do the logging last as it can slow down the KICK pushing */
               putlog(LOG_WARNING, "*", "%s opped in %s with bad cookie(%d): %s", m-&amp;gt;nick, chan-&amp;gt;dname, isbadop, msg);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1209,8 +1276,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; gotmode(char *from, char *msg)
                     dprintf_real(DP_MODE_NEXT, tmp, len, sizeof(tmp));
                     m-&amp;gt;flags |= SENTKICK;
                   }
-                  simple_snprintf(tmp, sizeof(tmp), "%s!%s MODE %s %s", m-&amp;gt;nick, m-&amp;gt;userhost, chan-&amp;gt;dname, modes[modecnt - 1]);
-                  deflag_user(u, DEFLAG_MANUALOP, tmp, chan);
+                  simple_snprintf(tmp, sizeof(tmp), "%s MODE %s %s", m-&amp;gt;from, chan-&amp;gt;dname, modes[modecnt - 1]);
+                  deflag_user(u, DEFLAG_EVENT_MANUALOP, tmp, chan);
                 }
                 break;
               default:
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1415,8 +1482,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; gotmode(char *from, char *msg)
 
               if (msign == '+') {
                 if (mv-&amp;gt;flags &amp;amp; EVOICE) {
-                  /* FIXME: This is a lame check, we need to expand on this more */
-                  if (!chan_master(user) &amp;amp;&amp;amp; !glob_master(user) &amp;amp;&amp;amp; !chk_voice(victim, chan)) {
+                  if (!chk_op(user, chan) &amp;amp;&amp;amp; !chk_voice(victim, chan)) {
                     dv = 1;
                   } else {
                     mv-&amp;gt;flags &amp;amp;= ~EVOICE;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1442,14 +1508,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; gotmode(char *from, char *msg)
                     add_mode(chan, '+', 'v', mparam);
                     /* if they arent +v|v and VOICER is m+ then EVOICE them */
                   } else {
-                    /* FIXME: same thing here */
-                    if (!match_my_nick(nick) &amp;amp;&amp;amp; channel_voice(chan) &amp;amp;&amp;amp; !glob_bot(user) &amp;amp;&amp;amp;
-                        (glob_master(user) || chan_master(user)) &amp;amp;&amp;amp;
+                    if (!match_my_nick(nick) &amp;amp;&amp;amp; channel_voice(chan) &amp;amp;&amp;amp;
+                        (chk_op(user, chan) || glob_bot(user)) &amp;amp;&amp;amp;
                         rfc_casecmp(nick, mparam)) {
                       /* if the user is not +q set them norEVOICE. */
-                      if (!chan_quiet(victim) &amp;amp;&amp;amp; !(mv-&amp;gt;flags &amp;amp; EVOICE)) {
-                        putlog(LOG_DEBUG, "&amp;lt; at &amp;gt;", "Giving EVOICE flag to: %s (%s)", mv-&amp;gt;nick, chan-&amp;gt;dname);
-                        mv-&amp;gt;flags |= EVOICE;
+                      if (!chan_quiet(victim)) {
+                        set_devoice(chan, mv);
                       }
                     }
                   }
diff --git a/src/mod/irc.mod/msgcmds.c b/src/mod/irc.mod/msgcmds.c
index 6bcf4f7..dbb7ef1 100755
--- a/src/mod/irc.mod/msgcmds.c
+++ b/src/mod/irc.mod/msgcmds.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -44,7 +44,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int msg_bewm(char *nick, char *host, struct userrec *u, char *par)
 
   if (!u) {
     msg = bd::String::printf(STR("---- (%s!%s) attempted to gain secure invite, but is not a recognized user."), nick, host);
-    privmsg(chan-&amp;gt;name, msg.c_str(), DP_SERVER);
+    privmsg(chan-&amp;gt;name, msg, DP_SERVER);
 
     putlog(LOG_CMDS, "*", STR("(%s!%s) !*! BEWM"), nick, host);
     return BIND_RET_BREAK;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -59,12 +59,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int msg_bewm(char *nick, char *host, struct userrec *u, char *par)
   if (!chk_op(fr, chan))  {
     putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! !BEWM"), nick, host, u-&amp;gt;handle);
     msg = bd::String::printf(STR("---- %s (%s!%s) attempted to gain secure invite, but is missing a flag."), u-&amp;gt;handle, nick, host);
-    privmsg(chan-&amp;gt;name, msg.c_str(), DP_SERVER);
+    privmsg(chan-&amp;gt;name, msg, DP_SERVER);
     return BIND_RET_BREAK;
   }
 
   msg = bd::String::printf("\001ACTION has invited \002%s\002 (%s!%s) to %s.\001", u-&amp;gt;handle, nick, host, chan-&amp;gt;dname);
-  privmsg(chan-&amp;gt;name, msg.c_str(), DP_SERVER);
+  privmsg(chan-&amp;gt;name, msg, DP_SERVER);
 
   cache_invite(chan, nick, host, u-&amp;gt;handle, 0, 0);
   putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! BEWM"), nick, host, u-&amp;gt;handle);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -116,7 +116,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int msg_pass(char *nick, char *host, struct userrec *u, char *par)
   set_user(&amp;amp;USERENTRY_PASS, u, mynew);
   bd::String msg;
   msg = bd::String::printf("%s '%s'.", mynew == old ? "Password set to:" : "Password changed to:", mynew);
-  notice(nick, msg.c_str(), DP_HELP);
+  notice(nick, msg, DP_HELP);
   return BIND_RET_BREAK;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -143,7 +143,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int msg_op(char *nick, char *host, struct userrec *u, char *par)
         msg = bd::String::printf("---- (%s!%s) attempted to OP for %s but is not currently in %s.", nick, host, par, homechan);
       else
         msg = bd::String::printf("---- (%s!%s) attempted to OP but is not currently in %s.", nick, host, homechan);
-      privmsg(homechan, msg.c_str(), DP_SERVER);
+      privmsg(homechan, msg, DP_SERVER);
       return BIND_RET_BREAK;
     }
   }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -160,7 +160,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int msg_op(char *nick, char *host, struct userrec *u, char *par)
               putlog(LOG_CMDS, "*", "(%s!%s) !%s! OP %s", nick, host, u-&amp;gt;handle, par);
               if (manop_warn &amp;amp;&amp;amp; chan-&amp;gt;manop) {
                 msg = bd::String::printf("%s is currently set to punish for manual op.", chan-&amp;gt;dname);
-                notice(nick, msg.c_str(), DP_HELP);
+                notice(nick, msg, DP_HELP);
               }
             }
           }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -175,7 +175,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int msg_op(char *nick, char *host, struct userrec *u, char *par)
               stats++;
               if (manop_warn &amp;amp;&amp;amp; chan-&amp;gt;manop) {
                 msg = bd::String::printf("%s is currently set to punish for manual op.", chan-&amp;gt;dname);
-                notice(nick, msg.c_str(), DP_HELP);
+                notice(nick, msg, DP_HELP);
               }
             }
           }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -219,14 +219,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int msg_ident(char *nick, char *host, struct userrec *u, char *par)
       return BIND_RET_BREAK;
     } else if (u) {
       msg = bd::String::printf("You're not %s, you're %s.", who, u-&amp;gt;handle);
-      notice(nick, msg.c_str(), DP_HELP);
+      notice(nick, msg, DP_HELP);
       return BIND_RET_BREAK;
     } else {
       putlog(LOG_CMDS, "*", "(%s!%s) !*! IDENT %s", nick, host, who);
       simple_snprintf(s, sizeof s, "%s!%s", nick, host);
       maskaddr(s, s1, 0); /* *!user&amp;lt; at &amp;gt;host */
       msg = bd::String::printf("Added hostmask: %s", s1);
-      notice(nick, msg.c_str(), DP_HELP);
+      notice(nick, msg, DP_HELP);
       addhost_by_handle(who, s1);
       check_this_user(who, 0, NULL);
       return BIND_RET_BREAK;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -260,12 +260,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int msg_invite(char *nick, char *host, struct userrec *u, char *par)
     bd::String msg;
     if (!(chan = findchan_by_dname(par))) {
       msg = bd::String::printf("Usage: /MSG %s %s &amp;lt;pass&amp;gt; &amp;lt;channel&amp;gt;", botname, msginvite);
-      notice(nick, msg.c_str(), DP_HELP);
+      notice(nick, msg, DP_HELP);
       return BIND_RET_BREAK;
     }
     if (!channel_active(chan)) {
       msg = bd::String::printf("%s: Not on that channel right now.", par);
-      notice(nick, msg.c_str(), DP_HELP);
+      notice(nick, msg, DP_HELP);
       return BIND_RET_BREAK;
     }
     /* We need to check access here also (dw 991002) */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -319,7 +319,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int msg_authstart(char *nick, char *host, struct userrec *u, char *par)
   auth-&amp;gt;Status(AUTH_PASS);
   bd::String msg;
   msg = bd::String::printf(STR("auth%s %s"), u ? "." : "!", conf.bot-&amp;gt;nick);
-  privmsg(nick, msg.c_str(), DP_HELP);
+  privmsg(nick, msg, DP_HELP);
 
   return BIND_RET_BREAK;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -331,7 +331,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; AuthFinish(Auth *auth)
   auth-&amp;gt;Done();
   bd::String msg;
   msg = bd::String::printf(STR("You are now authorized for cmds, see %chelp"), auth_prefix[0]);
-  notice(auth-&amp;gt;nick, msg.c_str(), DP_HELP);
+  notice(auth-&amp;gt;nick, msg, DP_HELP);
 }
 
 static int msg_auth(char *nick, char *host, struct userrec *u, char *par)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -358,7 +358,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int msg_auth(char *nick, char *host, struct userrec *u, char *par)
       auth-&amp;gt;MakeHash();
       bd::String msg;
       msg = bd::String::printf(STR("-Auth %s %s"), auth-&amp;gt;rand, conf.bot-&amp;gt;nick);
-      privmsg(nick, msg.c_str(), DP_HELP);
+      privmsg(nick, msg, DP_HELP);
     } else {
       /* no auth_key and/or no SECPASS for the user, don't require a hash auth */
       AuthFinish(auth);
diff --git a/src/mod/mod.mk.in b/src/mod/mod.mk.in
new file mode 100644
index 0000000..f97b9f2
--- /dev/null
+++ b/src/mod/mod.mk.in
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+depcomp = /bin/sh $(top_srcdir)/build/autotools/depcomp
+
+../%.o: %.c $(top_srcdir)/src/stringfix $(top_srcdir)/build/cc1plus
+&amp;lt; at &amp;gt;echo -e "Compiling: \033[1m$*\033[0m"
+ifeq ($(CCDEPMODE),gcc3)
+if STRINGFIX='$(top_srcdir)/$(STRINGFIX)' $(CXX) -MT '$&amp;lt; at &amp;gt;' -MD -MP -MF '.deps/$*.TPo' -DSTRINGFIX=$(STRINGFIX) -B$(top_srcdir)/build $(CXXFLAGS) $(CPPFLAGS) -c $&amp;lt; -o $&amp;lt; at &amp;gt;; then \
+mv '.deps/$*.TPo' '.deps/$*.Po'; \
+else rm -f '.deps/$*.Tpo'; exit 1; \
+fi
+else
+# STRINGFIX included after CXX for ccache to recognize
+STRINGFIX="$(top_srcdir)/$(STRINGFIX)" libtool=no source='$&amp;lt;' object='$&amp;lt; at &amp;gt;' depfile='.deps/$*.Po' tmpdepfile='.deps/$*.TPo' depmode=$(CCDEPMODE) $(depcomp) \
+$(CXX) -DSTRINGFIX=$(STRINGFIX) -B$(top_srcdir)/build $(CXXFLAGS) $(CPPFLAGS) -c $&amp;lt; -o $&amp;lt; at &amp;gt;
+endif
diff --git a/src/mod/server.mod/Makefile b/src/mod/server.mod/Makefile
index eaa0e30..19b647b 100755
--- a/src/mod/server.mod/Makefile
+++ b/src/mod/server.mod/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,12 +1,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 # Makefile for src/mod/server.mod/
 
 srcdir = .
-depcomp = /bin/sh ../../../autotools/depcomp
+depcomp = /bin/sh ../../../build/autotools/depcomp
 
 #This line is simply for configure to generate .deps/
 OBJS = server.o
 
 include ./.deps/includes
+include ../mod.mk
 
 doofus:
 &amp;lt; at &amp;gt;echo ""
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -16,13 +17,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; doofus:
 
 static: ../server.o
 
-../server.o:
-&amp;lt; at &amp;gt;echo -e "Compiling: \033[1mserver\033[0m"
-source='server.c' object='$&amp;lt; at &amp;gt;' depfile='.deps/server.Po' tmpdepfile='.deps/server.TPo' depmode=$(CCDEPMODE) $(depcomp) \
-$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/server.c
-&amp;lt; at &amp;gt;rm -f ../server.o
-&amp;lt; at &amp;gt;mv server.o ../
-
 clean:
 &amp;lt; at &amp;gt;rm -f .depend *.o *~
 
diff --git a/src/mod/server.mod/cmdsserv.c b/src/mod/server.mod/cmdsserv.c
index 7567579..c8d2e00 100755
--- a/src/mod/server.mod/cmdsserv.c
+++ b/src/mod/server.mod/cmdsserv.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -39,7 +39,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_servers(int idx, char *par)
     i = 0;
     for (; x; x = x-&amp;gt;next) {
         simple_snprintf(s, sizeof s, "  %s:%d %s", x-&amp;gt;name, 
-     x-&amp;gt;port ? x-&amp;gt;port : default_port, 
+     x-&amp;gt;port ? x-&amp;gt;port : (ssl_use ? default_port_ssl : default_port),
      (i == curserv) ? "&amp;lt;- I am here" : "");
       dprintf(idx, "%s\n", s);
       i++;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -93,7 +93,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_jump(int idx, char *par)
         port = atoi(p);
     }
     if (!port)
-      port = default_port;
+      port = (ssl_use ? default_port_ssl : default_port);
     putlog(LOG_CMDS, "*", "#%s# jump %s %d %s", dcc[idx].nick, other, port, par);
     strlcpy(newserver, other, sizeof newserver);
     newserverport = port;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -105,6 +105,63 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_jump(int idx, char *par)
   cycle_time = 0;
 }
 
+static void cmd_keyx(int idx, char *par) {
+  putlog(LOG_CMDS, "*", "#%s# keyx %s", dcc[idx].nick, par);
+
+  if (!par[0]) {
+    dprintf(idx, "Usage: keyx &amp;lt;nick&amp;gt;\n");
+    return;
+  }
+
+  if (strchr(CHANMETA, par[0])) {
+    dprintf(idx, "Error: Cannot key-exchange with a channel.\n");
+    return;
+  }
+
+  if (!server_online) {
+    dprintf(idx, "Error: Not online.\n");
+    return;
+  }
+
+  char *nick = newsplit(&amp;amp;par);
+  keyx(nick);
+  return;
+}
+
+static void cmd_setkey(int idx, char *par) {
+  putlog(LOG_CMDS, "*", "#%s# setkey %s", dcc[idx].nick, par);
+
+  const bool target_is_chan = par[0] &amp;amp;&amp;amp; strchr(CHANMETA, par[0]);
+
+  if (!par[0] || target_is_chan) {
+    dprintf(idx, "Usage: setkey &amp;lt;nick&amp;gt; [key|rand]\n");
+    if (target_is_chan) {
+      dprintf(idx, "Use 'chanset fish-key' to set a key for a channel.\n");
+    }
+    return;
+  }
+
+  char *target = newsplit(&amp;amp;par);
+  char *newkey = newsplit(&amp;amp;par);
+  bool have_key = FishKeys.contains(target);
+
+  if (!newkey[0]) {
+    // Clear the key
+    if (have_key) {
+      set_fish_key(target, "");
+      dprintf(idx, "Key cleared for '%s'\n", target);
+    } else {
+      dprintf(idx, "No key found for '%s'\n", target);
+    }
+  } else {
+    // Set a new key
+    set_fish_key(target, newkey);
+    fish_data_t* fishData = FishKeys[target];
+    dprintf(idx, "Set key for '%s' to: %s", target, fishData-&amp;gt;sharedKey.c_str());
+  }
+  return;
+}
+
 static void cmd_clearqueue(int idx, char *par)
 {
   int msgs;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -167,7 +224,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static cmd_t C_dcc_serv[] =
   {"clearqueue","m",(Function) cmd_clearqueue,NULL, LEAF|AUTH},
   {"dump","a",(Function) cmd_dump,NULL, LEAF},
   {"jump","m",(Function) cmd_jump,NULL, LEAF},
+  {"keyx","o",(Function) cmd_keyx,NULL, LEAF},
   {"servers","m",(Function) cmd_servers,NULL, LEAF},
+  {"setkey","m",(Function) cmd_setkey,NULL, LEAF},
   {"umode","m",(Function) cmd_umode,NULL, LEAF},
   {NULL,NULL,NULL,NULL, 0}
 };
diff --git a/src/mod/server.mod/server.c b/src/mod/server.mod/server.c
index 95df645..6ef015f 100755
--- a/src/mod/server.mod/server.c
+++ b/src/mod/server.mod/server.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -58,12 +58,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int ctcp_mode;
 int serv = -1;/* sock # of server currently */
 int servidx = -1;/* idx of server */
 char newserver[121] = "";/* new server? */
-port_t newserverport = 0;/* new server port? */
+in_port_t newserverport = 0;/* new server port? */
 char newserverpass[121] = "";/* new server password? */
 static char serverpass[121] = "";
 static time_t trying_server;/* trying to connect to a server right now? */
 int curserv = 999;/* current position in server list: */
-port_t curservport = 0;
+in_port_t curservport = 0;
 rate_t flood_msg = { 5, 60 };
 rate_t flood_ctcp = { 3, 60 };
 char botuserhost[UHOSTLEN] = "";/* bot's user&amp;lt; at &amp;gt;host (refreshed whenever the bot joins a channel) */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -86,7 +86,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static const interval_t stoned_timeout = 500;
 struct server_list *serverlist = NULL;/* old-style queue, still used by
    server list */
 interval_t cycle_time;/* cycle time till next server connect */
-port_t default_port = 6667;/* default IRC port */
+in_port_t default_port = 6667;/* default IRC port */
+in_port_t default_port_ssl = 6697;/* default IRC SSL port */
 bool trigger_on_ignore;/* trigger bindings if user is ignored ? */
 int answer_ctcp = 1;/* answer how many stacked ctcp's ? */
 static bool resolvserv;/* in the process of resolving a server host */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -111,6 +112,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; bool in_callerid = 0;
 bool have_cprivmsg = 0;
 bool have_cnotice = 0;
 
+bd::HashTable&amp;lt;bd::String, fish_data_t*&amp;gt; FishKeys;
+
 static bool double_warned = 0;
 
 static void empty_msgq(void);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -800,7 +803,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void clearq(struct server_list *xx)
  *
  * -&amp;gt; if (*ptr == -1) then jump to that particular server
  */
-void next_server(int *ptr, char *servname, port_t *port, char *pass)
+void next_server(int *ptr, char *servname, in_port_t *port, char *pass)
 {
   struct server_list *x = serverlist;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -825,7 +828,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void next_server(int *ptr, char *servname, port_t *port, char *pass)
 
     x-&amp;gt;next = 0;
     x-&amp;gt;name = strdup(servname);
-    x-&amp;gt;port = *port ? *port : default_port;
+    x-&amp;gt;port = *port ? *port : (ssl_use ? default_port_ssl : default_port);
     if (pass &amp;amp;&amp;amp; pass[0]) {
       x-&amp;gt;pass = strdup(pass);
     } else
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -849,7 +852,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void next_server(int *ptr, char *servname, port_t *port, char *pass)
     *ptr = 0;
   }/* Start over at the beginning */
   strcpy(servname, x-&amp;gt;name);
-  *port = x-&amp;gt;port ? x-&amp;gt;port : default_port;
+  *port = x-&amp;gt;port ? x-&amp;gt;port : (ssl_use ? default_port_ssl : default_port);
   if (x-&amp;gt;pass)
     strcpy(pass, x-&amp;gt;pass);
   else
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1027,14 +1030,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void server_secondly()
       nick_available(1, 0);
     }
 
-    if (!loading) {
       static int cnt_10 = 0;
 
       // Every 10 seconds
       if (cnt_10 == 9) {
-        // Ensure that +D/+f are not conflicting
 
-        if (deaf_char) {
+      // Ensure that +D/+f are not conflicting
+      if (!loading &amp;amp;&amp;amp; deaf_char) {
           // +f or auth bots in used need to see channel chatter.
           bool need_chatter = doflood(NULL) || (Auth::ht_host.size() &amp;amp;&amp;amp; auth_chan &amp;amp;&amp;amp; strlen(auth_prefix));
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1049,10 +1051,32 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void server_secondly()
           }
         }
 
+      // Clear expired key exchanges that aren't finished (7 seconds)
+      const bd::Array&amp;lt;bd::String&amp;gt; fish_targets(FishKeys.keys());
+      for (size_t i = 0; i &amp;lt; fish_targets.length(); ++i) {
+        const bd::String target(fish_targets[i]);
+        fish_data_t* fishData = FishKeys[target];
+        bool should_delete = false;
+        if (fishData-&amp;gt;key_created_at &amp;amp;&amp;amp; !fishData-&amp;gt;sharedKey &amp;amp;&amp;amp; ((now - 7) &amp;gt;= fishData-&amp;gt;key_created_at)) {
+          putlog(LOG_DEBUG, "*", "Deleting expired DH1080 FiSH exchange with %s", target.c_str());
+          should_delete = true;
+        } else if (fishData-&amp;gt;key_created_at &amp;amp;&amp;amp; fishData-&amp;gt;sharedKey.length() &amp;amp;&amp;amp; ((now - 3600) &amp;gt;= fishData-&amp;gt;key_created_at)) {
+          putlog(LOG_DEBUG, "*", "Deleting expired (60 min) FiSH key with %s", target.c_str());
+          should_delete = true;
+        }
+
+        if (should_delete) {
+          FishKeys.remove(target);
+          delete fishData;
+        }
+      }
+
+
         cnt_10 = 0;
-      } else
+    } else {
         ++cnt_10;
     }
+
     if (connect_bursting &amp;amp;&amp;amp; (now - SERVER_CONNECT_BURST_TIME) &amp;gt;= connect_bursting) {
       end_burstmode();
       putlog(LOG_DEBUG, "*", "Ending server burst mode");
diff --git a/src/mod/server.mod/server.h b/src/mod/server.mod/server.h
index 9181ffe..9bb669a 100755
--- a/src/mod/server.mod/server.h
+++ b/src/mod/server.mod/server.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -9,6 +9,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include "src/binds.h"
 #include "src/dcc.h"
 #include "src/set.h"
+#include &amp;lt;bdlib/src/String.h&amp;gt;
+#include &amp;lt;bdlib/src/HashTable.h&amp;gt;
 
 #define DO_LOST 1
 #define NO_LOST 0
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -33,7 +35,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct server_list {
   struct server_list*next;
   char*name;
   char*pass;
-  port_t port;
+  in_port_t port;
 };
 
 /* Available net types.  */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -45,12 +47,19 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum {
 NETT_HYBRID_EFNET= 4/* new +e/+I Efnet hybrid.  */
 };
 
+typedef struct {
+  bd::String sharedKey;
+  bd::String myPrivateKey;
+  bd::String myPublicKeyB64;
+  time_t key_created_at;
+} fish_data_t;
+
 extern bind_table_t*BT_ctcp, *BT_ctcr;
 extern size_tnick_len;
 extern booltrigger_on_ignore, floodless, keepnick, in_deaf, in_callerid, have_cprivmsg, have_cnotice;
 extern int servidx, ctcp_mode, answer_ctcp, serv, curserv, default_alines, flood_count, burst;
 extern unsigned int     rolls;
-extern port_tdefault_port, newserverport, curservport;
+extern in_port_tdefault_port, default_port_ssl, newserverport, curservport;
 extern time_tserver_online, tried_jupenick, tried_nick, release_time, connect_bursting;
 extern interval_tcycle_time;
 extern charcursrvname[], botrealname[121], botuserhost[], ctcp_reply[1024],
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -58,6 +67,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern charcursrvname[], botrealname[121], botuserhost[], ctcp_reply[1024],
 extern struct server_list *serverlist;
 extern struct dcc_table SERVER_SOCKET;
 extern rate_tflood_msg, flood_ctcp, flood_callerid;
+extern bd::HashTable&amp;lt;bd::String, fish_data_t*&amp;gt; FishKeys;
 
 int check_bind_ctcpr(char *, char *, struct userrec *, char *, char *, char *, bind_table_t *);
 void nicks_available(char* buf, char delim = 0, bool buf_contains_available = 1);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -80,7 +90,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void rehash_monitor_list();
 void replay_cache(int, bd::Stream*);
 void join_chans();
 void check_hostmask();
-void next_server(int *, char *, port_t *, char *);
+void next_server(int *, char *, in_port_t *, char *);
 void server_send_ison();
 void reset_flood();
 
diff --git a/src/mod/server.mod/servmsg.c b/src/mod/server.mod/servmsg.c
index a3ba66c..7542ebb 100755
--- a/src/mod/server.mod/servmsg.c
+++ b/src/mod/server.mod/servmsg.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -155,6 +155,63 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int check_bind_raw(char *from, char *code, char *msg)
   int ret = 0;
 
   myfrom = p1 = strdup(from);
+
+  // Decrypt FiSH before processing
+  if (!strcmp(code, "PRIVMSG") || !strcmp(code, "NOTICE")) {
+    char* colon = strchr(msg, ':'), *first_word = strchr(msg, ' ');
+    bd::String target(msg, first_word - msg);
+
+    ++colon;
+    if (colon) {
+      if (!strncmp(colon, "+OK ", 4)) {
+        char *p = strchr(from, '!');
+        const bool target_is_chan = strchr(CHANMETA, target[0]);
+        bd::String ciphertext(colon), sharedKey, nick(from, p - from), key_target;
+
+        // If this is a channel msg, decrypt with the channel key
+        if (target_is_chan) {
+          key_target = target;
+        } else {
+          // Otherwise decrypt with the nick's key
+          key_target = nick;
+        }
+
+        const bool have_shared_key = FishKeys.contains(key_target);
+
+        if (have_shared_key) {
+          sharedKey = FishKeys[key_target]-&amp;gt;sharedKey;
+        } else {
+          struct userrec *u = get_user_by_host(from);
+          if (u) {
+            sharedKey = static_cast&amp;lt;char*&amp;gt;(get_user(&amp;amp;USERENTRY_SECPASS, u));
+          }
+        }
+
+        if (sharedKey.length()) {
+          // Decrypt the message before passing along to the binds
+          const bd::String decrypted(egg_bf_decrypt(ciphertext, sharedKey));
+          // Does the decrypted text make sense? If not, the key is probably invalid, reset it.
+          bool isValidCipherText = true;
+          for (size_t i = 0; i &amp;lt; decrypted.length(); ++i) {
+            if (!isprint(decrypted[i])) {
+              isValidCipherText = false;
+              break;
+            }
+          }
+          if (isValidCipherText) {
+            bd::String cleartext(bd::String(msg, colon - msg) + decrypted);
+            mymsg = p2 = strdup(cleartext.c_str());
+          } else if (!target_is_chan &amp;amp;&amp;amp; have_shared_key) {
+            // Delete the shared key
+            fish_data_t* fishData = FishKeys[key_target];
+            FishKeys.remove(key_target);
+            delete fishData;
+          }
+        }
+      }
+    }
+  }
+  if (!p2)
   mymsg = p2 = strdup(msg);
 
   ret = check_bind(BT_raw, code, NULL, myfrom, mymsg);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -734,12 +791,62 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotmsg(char *from, char *msg)
         }
         if (doit)
           check_bind_msg(my_code, nick, uhost, my_u, msg);
+
+        if (my_u &amp;amp;&amp;amp; FishKeys.contains(nick)) {
+          // FiSH paranoid mode. Invalidate the current key and re-key-exchange with the user.
+          if (fish_paranoid) {
+            keyx(nick);
+          }
+        }
       }
     }
   }
   return 0;
 }
 
+// Adapated from ZNC
+void handle_DH1080_init(const char* nick, const char* uhost, const char* from, struct userrec* u, const bd::String theirPublicKeyB64) {
+  bd::String myPublicKeyB64, myPrivateKey, sharedKey;
+
+  DH1080_gen(myPrivateKey, myPublicKeyB64);
+  if (!DH1080_comp(myPrivateKey, theirPublicKeyB64, sharedKey)) {
+    sdprintf("Error computing DH1080 for %s: %s", nick, sharedKey.c_str());
+    return;
+  }
+
+  putlog(LOG_MSGS, "*", "[FiSH] Received DH1080 public key from (%s!%s) - sending mine", nick, uhost);
+  fish_data_t* fishData = FishKeys.contains(nick) ? FishKeys[nick] : new fish_data_t;
+  fishData-&amp;gt;sharedKey.clear();
+  notice(nick, "DH1080_FINISH " + myPublicKeyB64, DP_HELP);
+  fishData-&amp;gt;myPublicKeyB64 = myPublicKeyB64;
+  fishData-&amp;gt;myPrivateKey = myPrivateKey;
+  fishData-&amp;gt;sharedKey = sharedKey;
+  fishData-&amp;gt;key_created_at = now;
+  FishKeys[nick] = fishData;
+  sdprintf("Set key for %s: %s", nick, sharedKey.c_str());
+  return;
+}
+
+void handle_DH1080_finish(const char* nick, const char* uhost, const char* from, struct userrec* u, const bd::String theirPublicKeyB64) {
+  if (!FishKeys.contains(nick)) {
+    putlog(LOG_MSGS, "*", "[FiSH] Unexpected DH1080_FINISH from (%s!%s) - ignoring", nick, uhost);
+    return;
+  }
+
+  fish_data_t* fishData = FishKeys[nick];
+  bd::String sharedKey;
+
+  if (!DH1080_comp(fishData-&amp;gt;myPrivateKey, theirPublicKeyB64, sharedKey)) {
+    sdprintf("Error computing DH1080 for %s: %s", nick, sharedKey.c_str());
+    return;
+  }
+
+  putlog(LOG_MSGS, "*", "[FiSH] Key successfully set for (%s!%s)", nick, uhost);
+  fishData-&amp;gt;sharedKey = sharedKey;
+  sdprintf("Set key for %s: %s", nick, sharedKey.c_str());
+  return;
+}
+
 /* Got a private notice.
  */
 static int gotnotice(char *from, char *msg)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -818,10 +925,22 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotnotice(char *from, char *msg)
       } else if (!ignoring) {
         detect_flood(nick, uhost, from, FLOOD_NOTICE);
         u = get_user_by_host(from);
+
+        bd::String smsg(msg);
+        bd::String which = newsplit(smsg);
+
+        if (which == "DH1080_INIT") {
+          bd::String theirPublicKeyB64(newsplit(smsg));
+          handle_DH1080_init(nick, uhost, from, u, theirPublicKeyB64);
+        } else if (which == "DH1080_FINISH") {
+          bd::String theirPublicKeyB64(newsplit(smsg));
+          handle_DH1080_finish(nick, uhost, from, u, theirPublicKeyB64);
+        } else {
         putlog(LOG_MSGS, "*", "-%s (%s)- %s", nick, uhost, msg);
       }
     }
   }
+  }
   return 0;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1376,7 +1495,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void server_activity(int idx, char *msg, int len)
 
   if (unlikely(trying_server)) {
     strlcpy(dcc[idx].nick, "(server)", sizeof(dcc[idx].nick));
+    if (ssl_use) {
+      putlog(LOG_SERV, "*", "Connected to %s with SSL", dcc[idx].host);
+    } else {
     putlog(LOG_SERV, "*", "Connected to %s", dcc[idx].host);
+    }
 
     trying_server = 0;
     /*
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1829,6 +1952,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int got718(char *from, char *msg)
         putlog(LOG_WALL, "*", "(CALLERID) !%s! (%s!%s) %s (Accepting user)", u-&amp;gt;handle, nick, uhost, msg);
         dprintf(DP_HELP, "ACCEPT %s\n", nick);
         dprintf(DP_HELP, "PRIVMSG %s :You have been accepted. Please send your message again.\n", nick);
+        if (fish_auto_keyx) {
+          keyx(nick);
+        }
       } else {
         putlog(LOG_WALL, "*", "(CALLERID) !%s! (%s!%s) %s (User is not +o or +v)", u-&amp;gt;handle, nick, uhost, msg);
       }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1893,7 +2019,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void connect_server(void)
 {
   char pass[121] = "", botserver[UHOSTLEN] = "";
   int newidx;
-  port_t botserverport = 0;
+  in_port_t botserverport = 0;
 
   waiting_for_awake = 0;
   /* trying_server = now; */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1924,7 +2050,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void connect_server(void)
     }
 
     next_server(&amp;amp;curserv, botserver, &amp;amp;botserverport, pass);
+
+    if (ssl_use) {
+      putlog(LOG_SERV, "*", "Trying SSL server %s:%d", botserver, botserverport);
+    } else {
     putlog(LOG_SERV, "*", "Trying server %s:%d", botserver, botserverport);
+    }
 
     dcc[newidx].port = botserverport;
     strlcpy(dcc[newidx].nick, "(server)", sizeof(dcc[newidx].nick));
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2027,6 +2158,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void server_dns_callback(int id, void *client_data, const char *host, bd:
     servidx = idx;
     sdprintf("Connecting to '%s' (serv: %d, servidx: %d)", dcc[idx].host, serv, servidx);
     setsockopt(serv, 6, TCP_NODELAY, &amp;amp;i, sizeof(int));
+#ifdef EGG_SSL_EXT
+    if (ssl_use) { /* kyotou */
+      if (net_switch_to_ssl(serv) == 0) {
+        putlog(LOG_SERV, "*", "SSL Failed to connect to %s (Error while switching to SSL)", dcc[servidx].host);
+        trying_server = 0;
+        lostdcc(servidx);
+        return;
+      }
+    }
+#endif
     /* Queue standard login */
     dcc[idx].timeval = now;
     SERVER_SOCKET.timeout_val = &amp;amp;server_timeout;
diff --git a/src/mod/share.mod/Makefile b/src/mod/share.mod/Makefile
index 1def196..0e8837b 100755
--- a/src/mod/share.mod/Makefile
+++ b/src/mod/share.mod/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,12 +1,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 # Makefile for src/mod/share.mod/
 
 srcdir = .
-depcomp = /bin/sh ../../../autotools/depcomp
+depcomp = /bin/sh ../../../build/autotools/depcomp
 
 #This line is simply for configure to generate .deps/
 OBJS = share.o
 
 include ./.deps/includes
+include ../mod.mk
 
 doofus:
 &amp;lt; at &amp;gt;echo ""
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -16,13 +17,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; doofus:
 
 static: ../share.o
 
-../share.o:
-&amp;lt; at &amp;gt;echo -e "Compiling: \033[1mshare\033[0m"
-source='share.c' object='$&amp;lt; at &amp;gt;' depfile='.deps/share.Po' tmpdepfile='.deps/share.TPo' depmode=$(CCDEPMODE) $(depcomp) \
-$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/share.c
-&amp;lt; at &amp;gt;rm -f ../share.o
-&amp;lt; at &amp;gt;mv share.o ../
-
 clean:
 &amp;lt; at &amp;gt;rm -f .depend *.o *~
 
diff --git a/src/mod/share.mod/share.c b/src/mod/share.mod/share.c
index fca9ed9..17681f3 100755
--- a/src/mod/share.mod/share.c
+++ b/src/mod/share.mod/share.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -533,6 +533,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; share_newuser(int idx, char *par)
       noshare = 0;
       if (conf.bot-&amp;gt;hub)
         putlog(LOG_CMDS, "&amp;lt; at &amp;gt;", "%s: newuser %s %s", dcc[idx].nick, nick, s);
+      write_userfile(-1);
     }
   }
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -551,6 +552,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; share_killuser(int idx, char *par)
       shareout_but(idx, "k %s\n", par);
       if (conf.bot-&amp;gt;hub)
         putlog(LOG_CMDS, "&amp;lt; at &amp;gt;", "%s: killuser %s", dcc[idx].nick, par);
+      write_userfile(-1);
     }
     noshare = 0;
   }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -670,6 +672,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; share_change(int idx, char *par)
       }
       noshare = 0;
     }
+
+    if (uet == &amp;amp;USERENTRY_BOTADDR) {
+      write_userfile(-1);
+    }
   }
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1444,6 +1450,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void share_read_stream(int idx, bd::Stream&amp;amp; stream) {
     Auth::FillUsers();
   }
 
+  write_userfile(-1);
+
   cmdpass_free(old_cmdpass);
 
   checkchans(1);                /* remove marked channels */
diff --git a/src/mod/transfer.mod/Makefile b/src/mod/transfer.mod/Makefile
index 92c808c..e19dc4a 100755
--- a/src/mod/transfer.mod/Makefile
+++ b/src/mod/transfer.mod/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,12 +1,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 # Makefile for src/mod/transfer.mod/
 
 srcdir = .
-depcomp = /bin/sh ../../../autotools/depcomp
+depcomp = /bin/sh ../../../build/autotools/depcomp
 
 #This line is simply for configure to generate .deps/
 OBJS = transfer.o
 
 include ./.deps/includes
+include ../mod.mk
 
 doofus:
 &amp;lt; at &amp;gt;echo ""
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -16,13 +17,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; doofus:
 
 static: ../transfer.o
 
-../transfer.o:
-&amp;lt; at &amp;gt;echo -e "Compiling: \033[1mtransfer\033[0m"
-source='transfer.c' object='$&amp;lt; at &amp;gt;' depfile='.deps/transfer.Po' tmpdepfile='.deps/transfer.TPo' depmode=$(CCDEPMODE) $(depcomp) \
-$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/transfer.c
-&amp;lt; at &amp;gt;rm -f ../transfer.o
-&amp;lt; at &amp;gt;mv transfer.o ../
-
 clean:
 &amp;lt; at &amp;gt;rm -f .depend *.o *~
 
diff --git a/src/mod/transfer.mod/transfer.c b/src/mod/transfer.mod/transfer.c
index 5937147..a1f9216 100755
--- a/src/mod/transfer.mod/transfer.c
+++ b/src/mod/transfer.mod/transfer.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -226,13 +226,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void eof_dcc_send(int idx)
 
 /* Determine byte order. Used for resend DCC startup packets.
  */
-static inline u_8bit_t byte_order_test(void)
+static inline uint8_t byte_order_test(void)
 {
-  u_16bit_t test = TRANSFER_REGET_PACKETID;
+  uint16_t test = TRANSFER_REGET_PACKETID;
 
-  if (*((u_8bit_t *)&amp;amp;test) == ((TRANSFER_REGET_PACKETID &amp;amp; 0xff00) &amp;gt;&amp;gt; 8))
+  if (*((uint8_t *)&amp;amp;test) == ((TRANSFER_REGET_PACKETID &amp;amp; 0xff00) &amp;gt;&amp;gt; 8))
     return 0;
-  if (*((u_8bit_t *)&amp;amp;test) == (TRANSFER_REGET_PACKETID &amp;amp; 0x00ff))
+  if (*((uint8_t *)&amp;amp;test) == (TRANSFER_REGET_PACKETID &amp;amp; 0x00ff))
     return 1;
   return 0;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -737,7 +737,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct dcc_table DCC_GET_PENDING =
 static void dcc_get_pending(int idx, char *buf, int len)
 {
   in_addr_t ip;
-  port_t port;
+  in_port_t port;
   int i;
   char s[UHOSTLEN] = "";
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -749,7 +749,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void dcc_get_pending(int idx, char *buf, int len)
   if (dcc[idx].sock == -1) {
     bd::String msg;
     msg = bd::String::printf("Bad connection (%s)", strerror(errno));
-    notice(dcc[idx].nick, msg.c_str(), DP_HELP);
+    notice(dcc[idx].nick, msg, DP_HELP);
     putlog(LOG_FILES, "*", "DCC bad connection: GET %s (%s!%s)",
    dcc[idx].u.xfer-&amp;gt;origname, dcc[idx].nick, dcc[idx].host);
     fclose(dcc[idx].u.xfer-&amp;gt;f);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -813,7 +813,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int raw_dcc_resend_send(char *filename, char *nick, char *from, int resen
 {
   int zz = -1;
   int i;
-  port_t port;
+  in_port_t port;
   char *buf = NULL;
   long dccfilesize;
   FILE *f = NULL, *dccfile = NULL;
diff --git a/src/mod/transfer.mod/transfer.h b/src/mod/transfer.mod/transfer.h
index 6c5d342..9998aa4 100755
--- a/src/mod/transfer.mod/transfer.h
+++ b/src/mod/transfer.mod/transfer.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -36,11 +36,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int raw_dcc_send(char *, char *, char *, int *);
 #define TRANSFER_REGET_PACKETID 0xfeab
 
 typedef struct {
-  u_32bit_t byte_offset;/* Number of bytes to skip relative to
+  uint32_t byte_offset;/* Number of bytes to skip relative to
    the file beginning*/
-  u_16bit_t packet_id;/* Identification ID, should be equal
+  uint16_t packet_id;/* Identification ID, should be equal
     to TRANSFER_REGET_PACKETID*/
-  u_8bit_t  byte_order;/* Byte ordering, see byte_order_test()*/
+  uint8_t  byte_order;/* Byte ordering, see byte_order_test()*/
 } transfer_reget;
 #endif/* MAKING_TRANSFER */
 
diff --git a/src/mod/update.mod/Makefile b/src/mod/update.mod/Makefile
index 72478bc..c63b2ad 100755
--- a/src/mod/update.mod/Makefile
+++ b/src/mod/update.mod/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,12 +1,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 # Makefile for src/mod/update.mod/
 
 srcdir = .
-depcomp = /bin/sh ../../../autotools/depcomp
+depcomp = /bin/sh ../../../build/autotools/depcomp
 
 #This line is simply for configure to generate .deps/
 OBJS = update.o
 
 include ./.deps/includes
+include ../mod.mk
 
 doofus:
 &amp;lt; at &amp;gt;echo ""
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -16,13 +17,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; doofus:
 
 static: ../update.o
 
-../update.o:
-&amp;lt; at &amp;gt;echo -e "Compiling: \033[1mupdate\033[0m"
-source='update.c' object='$&amp;lt; at &amp;gt;' depfile='.deps/update.Po' tmpdepfile='.deps/update.TPo' depmode=$(CCDEPMODE) $(depcomp) \
-$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(srcdir)/update.c
-&amp;lt; at &amp;gt;rm -f ../update.o
-&amp;lt; at &amp;gt;mv update.o ../
-
 clean:
 &amp;lt; at &amp;gt;rm -f .depend *.o *~
 
diff --git a/src/net.c b/src/net.c
index d79880d..18b0213 100755
--- a/src/net.c
+++ b/src/net.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -77,13 +77,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; jmp_bufalarmret;/* Env buffer for alarm() returns    */
 
 /* This *MUST* be an ip */
 char   firewall[121] = "";     /* Socks server for firewall                */
-port_t firewallport = 1080;    /* Default port of Sock4/5 firewalls        */
+in_port_t firewallport = 1080;    /* Default port of Sock4/5 firewalls        */
 /* Types of proxy */
 #define PROXY_SOCKS   1
 #define PROXY_SUN     2
 #define PROXY_HTTP    3
 
-
 /* I need an UNSIGNED long for dcc type stuff
  */
 unsigned long my_atoul(const char *s)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -153,6 +152,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void init_net()
   for (int i = 0; i &amp;lt; MAXSOCKS; i++) {
     bzero(&amp;amp;socklist[i], sizeof(socklist[i]));
     socklist[i].flags = SOCK_UNUSED;
+#ifdef EGG_SSL_EXT
+    socklist[i].ssl = NULL;
+#endif
     socklist[i].sock = -1;
   }
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -407,6 +409,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void real_killsock(register int sock, const char *file, int line)
 
   int i = -1;
   if ((i = findanysnum(sock)) != -1) {
+#ifdef EGG_SSL_EXT
+    if (socklist[i].ssl) {
+      SSL_shutdown(socklist[i].ssl);
+      SSL_free(socklist[i].ssl);
+      socklist[i].ssl = NULL;
+    }
+#endif
     close(socklist[i].sock);
     if (socklist[i].inbuf != NULL) {
       delete socklist[i].inbuf;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -429,7 +438,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void real_killsock(register int sock, const char *file, int line)
 
 /* Send connection request to proxy
  */
-static int proxy_connect(int sock, const char *ip, port_t port, int proxy_type)
+static int proxy_connect(int sock, const char *ip, in_port_t port, int proxy_type)
 {
   sdprintf("proxy_connect(%d, %s, %d, %d)", sock, ip, port, proxy_type);
 #ifdef USE_IPV6
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -476,7 +485,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int proxy_connect(int sock, const char *ip, port_t port, int proxy_type)
 }
 
 /* FIXME: REPLACE WITH SOCK_NAME() */
-void initialize_sockaddr(int af_type, const char *host, port_t port, union sockaddr_union *so)
+void initialize_sockaddr(int af_type, const char *host, in_port_t port, union sockaddr_union *so)
 {
     bzero(so, sizeof(*so));
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -513,9 +522,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void initialize_sockaddr(int af_type, const char *host, port_t port, union socka
  *   -1  strerror()/errno type error
  *   -2  can't resolve hostname
  */
-int open_telnet_raw(int sock, const char *ipIn, port_t sport, bool proxy_on, int identd)
+int open_telnet_raw(int sock, const char *ipIn, in_port_t sport, bool proxy_on, int identd)
 {
-  static port_t port = 0;
+  static in_port_t port = 0;
   union sockaddr_union so;
   char ip[121] = "";
   int is_resolved = 0;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -610,8 +619,59 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int open_telnet_raw(int sock, const char *ipIn, port_t sport, bool proxy_on, int
   return sock;
 }
 
+#ifdef EGG_SSL_EXT
+int net_switch_to_ssl(int sock) {
+  int i = 0;
+
+  debug0("net_switch_to_ssl()");
+  sleep(3); // Give some time to let the connect() go through.
+  i = findanysnum(sock);
+  if (i == MAXSOCKS) {
+    debug0("Error while swithing to SSL - sock not found in list");
+    return 0;
+  }
+
+  if (socklist[i].ssl) {
+    debug0("Error while swithing to SSL - already in ssl");
+    return 0;
+  }
+  socklist[i].ssl = SSL_new(ssl_ctx);
+  if (!socklist[i].ssl) {
+    debug0("Error while swithing to SSL - SSL_new() error");
+    return 0;
+  }
+
+  SSL_set_fd(socklist[i].ssl, socklist[i].sock);
+  int err = 0, timeout = 0;
+
+  while ((err = SSL_connect(socklist[i].ssl)) &amp;lt;= 0) {
+    if (timeout++ &amp;gt; 500) {
+      err = 0;
+      break;
+    }
+    int errs = SSL_get_error(socklist[i].ssl,err);
+    if ((errs != SSL_ERROR_WANT_READ) &amp;amp;&amp;amp; (errs != SSL_ERROR_WANT_WRITE) &amp;amp;&amp;amp; (errs != SSL_ERROR_WANT_X509_LOOKUP)) {
+      putlog(LOG_DEBUG, "*", "SSL_connect() = %d, %s", err, (char *)ERR_error_string(ERR_get_error(), NULL));
+      goto error;
+    }
+    usleep(1000);
+  }
+
+  if (err == 1) {
+    debug0("SSL_connect() success");
+    return 1;
+  }
+error:
+  debug0("Error while SSL_connect()");
+  SSL_shutdown(socklist[i].ssl);
+  SSL_free(socklist[i].ssl);
+  socklist[i].ssl = NULL;
+  return 0;
+}
+#endif
+
 /* Ordinary non-binary connection attempt */
-int open_telnet(const char *ip, port_t port, bool proxy, int identd)
+int open_telnet(const char *ip, in_port_t port, bool proxy, int identd)
 {
   int sock = -1;
   
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -631,9 +691,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int open_telnet(const char *ip, port_t port, bool proxy, int identd)
  * 'addr' is ignored if af_def is AF_INET6 -poptix (02/03/03)
  */
 #ifdef USE_IPV6
-int open_address_listen(const char* ip, int af_def, port_t *port) {
+int open_address_listen(const char* ip, int af_def, in_port_t *port) {
 #else
-int open_address_listen(const char* ip, port_t *port) {
+int open_address_listen(const char* ip, in_port_t *port) {
    int af_def = AF_INET;
 #endif /* USE_IPV6 */
 //  if (firewall[0]) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -750,7 +810,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int open_address_listen(const char* ip, port_t *port) {
 /* Returns a socket number for a listening socket that will accept any
  * connection -- port # is returned in port
  */
-int open_listen(port_t *port)
+int open_listen(in_port_t *port)
 {
 #ifdef USE_IPV6
   return open_address_listen(iptostr(getmyip()), AF_INET, port);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -763,7 +823,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int open_listen(port_t *port)
  * the above is being left in for compatibility, and should NOT LONGER BE USED IN THE CORE CODE.
  */
 
-int open_listen_by_af(port_t *port, int af_def)
+int open_listen_by_af(in_port_t *port, int af_def)
 {
 #ifdef USE_IPV6
   return open_address_listen(iptostr(getmyip()), af_def, port);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -772,7 +832,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int open_listen_by_af(port_t *port, int af_def)
 #endif /* USE_IPV6 */
 }
 
-int open_listen_addr_by_af(const char *ip, port_t *port, int af_def)
+int open_listen_addr_by_af(const char *ip, in_port_t *port, int af_def)
 {
   if (!ip)
     ip = iptostr(getmyip());
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -799,7 +859,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; char *iptostr(in_addr_t ip)
  * by open_listen ... returns hostname of the caller &amp;amp; the new socket
  * does NOT dispose of old "public" socket!
  */
-int answer(int sock, char *caller, in_addr_t *ip, port_t *port, int binary)
+int answer(int sock, char *caller, in_addr_t *ip, in_port_t *port, int binary)
 {
   int new_sock;
   socklen_t addrlen;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -881,7 +941,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int answer(int sock, char *caller, in_addr_t *ip, port_t *port, int binary)
  */
 int open_telnet_dcc(int sock, char *ip, char *port)
 {
-  port_t p;
+  in_port_t p;
   unsigned long addr;
   char sv[100] = "";
   unsigned char c[4] = "";
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -970,6 +1030,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int sockread(char *s, int *len)
     /* Something happened */
     for (i = 0; i &amp;lt; MAXSOCKS; i++) {
       if ((!(socklist[i].flags &amp;amp; SOCK_UNUSED)) &amp;amp;&amp;amp; ((FD_ISSET(socklist[i].sock, &amp;amp;fd)) ||
+#ifdef EGG_SSL_EXT
+            ((socklist[i].ssl) &amp;amp;&amp;amp; (SSL_pending(socklist[i].ssl))) ||
+#endif
   ((socklist[i].sock == STDOUT) &amp;amp;&amp;amp; (!backgrd) &amp;amp;&amp;amp; (FD_ISSET(STDIN, &amp;amp;fd))))) {
 if (socklist[i].flags &amp;amp; (SOCK_LISTEN | SOCK_CONNECT)) {
   /* Listening socket -- don't read, just return activity */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -990,9 +1053,41 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int sockread(char *s, int *len)
   return i;
 }
 errno = 0;
-if (unlikely((socklist[i].sock == STDOUT) &amp;amp;&amp;amp; !backgrd))
+if (unlikely((socklist[i].sock == STDOUT) &amp;amp;&amp;amp; !backgrd)) {
   x = read(STDIN, s, grab);
-else
+#ifdef EGG_SSL_EXT
+        } else if (socklist[i].ssl) {
+            x = SSL_read(socklist[i].ssl,s,grab);
+            if (x &amp;lt;= 0) {
+              int err = SSL_get_error(socklist[i].ssl, x);
+              x = -1;
+              switch (err) {
+                case SSL_ERROR_WANT_READ:
+                case SSL_ERROR_WANT_WRITE:
+                case SSL_ERROR_WANT_X509_LOOKUP:
+                  errno = EAGAIN;
+                  break;
+                case SSL_ERROR_SYSCALL:
+                  switch (ERR_get_error()) {
+                    case 0:
+                      // EOF
+                      break;
+                    case -1:
+                      // I/O error
+                      putlog(LOG_DEBUG, "*", "SSL_read() [IO] = %d, %s", err, (char *)ERR_error_string(ERR_get_error(), NULL));
+                      break;
+                    default:
+                      putlog(LOG_DEBUG, "*", "SSL_read() unknown error: %s", strerror(errno));
+                      break;
+                  }
+                  break;
+                case SSL_ERROR_SSL:
+                  putlog(LOG_DEBUG, "*", "SSL_read() = %d, %s", err, (char *)ERR_error_string(ERR_get_error(), NULL));
+                  break;
+              }
+            }
+#endif
+        } else
           x = read(socklist[i].sock, s, grab);
 
 if (x &amp;lt;= 0) {/* eof */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1279,6 +1374,39 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void tputs(register int z, const char *s, size_t len)
       *(socklist[i].outbuf) += bd::String(s, len);
       return;
     }
+#ifdef EGG_SSL_EXT
+    if (socklist[i].ssl) {
+      x = SSL_write(socklist[i].ssl,s,len);
+      if (x &amp;lt;= 0) {
+        int err = SSL_get_error(socklist[i].ssl, x);
+        x = -1;
+        switch (err) {
+          case SSL_ERROR_WANT_READ:
+          case SSL_ERROR_WANT_WRITE:
+          case SSL_ERROR_WANT_X509_LOOKUP:
+            errno = EAGAIN;
+            break;
+          case SSL_ERROR_SYSCALL:
+            switch (ERR_get_error()) {
+              case 0:
+                // EOF
+                break;
+              case -1:
+                // I/O error
+                putlog(LOG_DEBUG, "*", "SSL_write() [IO] = %d, %s", err, (char *)ERR_error_string(ERR_get_error(), NULL));
+                break;
+              default:
+                putlog(LOG_DEBUG, "*", "SSL_write() unknown error: %s", strerror(errno));
+                break;
+            }
+            break;
+          case SSL_ERROR_SSL:
+            putlog(LOG_DEBUG, "*", "SSL_write() = %d, %s", err, (char *)ERR_error_string(ERR_get_error(), NULL));
+            break;
+        }
+      }
+    } else
+#endif
     /* Try. */
     x = write(z, s, len);
     if (x == -1)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1369,6 +1497,39 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void dequeue_sockets()
 (socklist[i].outbuf != NULL) &amp;amp;&amp;amp; (FD_ISSET(socklist[i].sock, &amp;amp;wfds))) {
       /* Trick tputs into doing the work */
       errno = 0;
+#ifdef EGG_SSL_EXT
+      if (socklist[i].ssl) {
+           x = SSL_write(socklist[i].ssl, socklist[i].outbuf-&amp;gt;data(), socklist[i].outbuf-&amp;gt;length());
+           if (x &amp;lt;= 0) {
+             int err = SSL_get_error(socklist[i].ssl, x);
+             x = -1;
+             switch (err) {
+               case SSL_ERROR_WANT_READ:
+               case SSL_ERROR_WANT_WRITE:
+               case SSL_ERROR_WANT_X509_LOOKUP:
+                 errno = EAGAIN;
+                 break;
+               case SSL_ERROR_SYSCALL:
+                 switch (ERR_get_error()) {
+                   case 0:
+                     // EOF
+                     break;
+                   case -1:
+                     // I/O error
+                     putlog(LOG_DEBUG, "*", "SSL_write()/dequeue_sockets() [IO] = %d, %s", err, (char *)ERR_error_string(ERR_get_error(), NULL));
+                     break;
+                   default:
+                     putlog(LOG_DEBUG, "*", "SSL_write() unknown error: %s", strerror(errno));
+                     break;
+                 }
+                 break;
+               case SSL_ERROR_SSL:
+                 putlog(LOG_DEBUG, "*", "SSL_write()/dequeue_sockets() = %d, %s", err, (char *)ERR_error_string(ERR_get_error(), NULL));
+                 break;
+             }
+           }
+      } else
+#endif
       x = write(socklist[i].sock, socklist[i].outbuf-&amp;gt;data(), socklist[i].outbuf-&amp;gt;length());
       if ((x &amp;lt; 0) &amp;amp;&amp;amp; (errno != EAGAIN)
 #ifdef EBADSLT
diff --git a/src/net.h b/src/net.h
index 320a753..f474ebc 100755
--- a/src/net.h
+++ b/src/net.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -12,6 +12,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;setjmp.h&amp;gt;
 #include &amp;lt;bdlib/src/String.h&amp;gt;
 
+#include "openssl.h"
+
 namespace bd {
   class Stream;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -84,10 +86,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct {
   int iseed;                            /* botlink in seed */
   int gz; /* gzip compression */
   int enclink;/* new encrypted botlink */
+#ifdef EGG_SSL_EXT
+  SSL *ssl;
+#endif
   bd::String* inbuf;
   bd::String* outbuf;
   char *host;
-  port_t port;
+  in_port_t port;
   short          flags;
   char okey[ENC_KEY_LEN + 1];                        /* botlink enckey: out */
   char ikey[ENC_KEY_LEN + 1];                        /* botlink enckey: in  */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -114,20 +119,20 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int real_getsock(int, const char *, int);
 
 int sockprotocol(int);
 void real_killsock(int, const char *, int);
-int answer(int, char *, in_addr_t *, port_t *, int);
+int answer(int, char *, in_addr_t *, in_port_t *, int);
 int findanysnum(register int);
 int findanyidx(register int sock);
-int open_listen(port_t *);
-int open_listen_by_af(port_t *, int);
-int open_listen_addr_by_af(const char*, port_t *, int);
+int open_listen(in_port_t *);
+int open_listen_by_af(in_port_t *, int);
+int open_listen_addr_by_af(const char*, in_port_t *, int);
 #ifdef USE_IPV6
-int open_address_listen(const char*, int, port_t *);
+int open_address_listen(const char*, int, in_port_t *);
 #else
-int open_address_listen(const char*, port_t *);
+int open_address_listen(const char*, in_port_t *);
 #endif /* USE_IPV6 */
-int open_telnet(const char *, port_t, bool proxy = 0, int identd = 0);
+int open_telnet(const char *, in_port_t, bool proxy = 0, int identd = 0);
 int open_telnet_dcc(int, char *, char *);
-int open_telnet_raw(int, const char *, port_t, bool, int = 0);
+int open_telnet_raw(int, const char *, in_port_t, bool, int = 0);
 void tputs(int, const char *, size_t);
 void dequeue_sockets();
 int sockgets(char *, int *);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -139,6 +144,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void init_net(void);
 int sock_read(bd::Stream&amp;amp;);
 void sock_write(bd::Stream&amp;amp;, int);
 bool socket_run();
+int net_switch_to_ssl(int sock);
 
 extern union sockaddr_union cached_myip4_so;
 #ifdef USE_IPV6
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -149,7 +155,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern unsigned longnotalloc;
 extern charfirewall[], botuser[21];
 extern intMAXSOCKS, socks_total;
 extern boolidentd_hack, cached_ip;
-extern port_tfirewallport;
+extern in_port_tfirewallport;
 extern jmp_bufalarmret;
 extern sock_list*socklist;
 
diff --git a/src/openssl.c b/src/openssl.c
new file mode 100644
index 0000000..03da0a2
--- /dev/null
+++ b/src/openssl.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,162 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999 - 2002 Eggheads Development Team
+ * Copyright (C) 2002 - 2010 Bryan Drewery
+ *
+ * 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.
+ */
+
+/*
+ * openssl.c -- handles:
+ *   libcrypto / libssl handling
+ *
+ */
+
+
+#include "common.h"
+#include "main.h"
+#include "dl.h"
+#include &amp;lt;bdlib/src/String.h&amp;gt;
+#include &amp;lt;bdlib/src/Array.h&amp;gt;
+
+#include "libssl.h"
+#include "libcrypto.h"
+
+#ifdef EGG_SSL_EXT
+SSL_CTX *ssl_ctx = NULL;
+char*tls_rand_file = NULL;
+#endif
+int     ssl_use = 0; /* kyotou */
+
+static int seed_PRNG(void);
+
+#include "dhparam.c"
+
+static DH* tmp_dh_callback(SSL* ssl, int is_export, int keylength) {
+  DH *ret = NULL;
+
+  switch (keylength) {
+    case 2048:
+      ret = get_dh2048();
+      break;
+    case 1024:
+      ret = get_dh1024();
+      break;
+    case 512:
+      ret = get_dh512();
+      break;
+    default:
+      putlog(LOG_DEBUG, "*", "Missing DH key length: %d", keylength);
+      break;
+  }
+
+  return ret;
+}
+
+int init_openssl() {
+  load_libcrypto();
+  load_libssl();
+
+#ifdef EGG_SSL_EXT
+  /* good place to init ssl stuff */
+  SSL_load_error_strings();
+  OpenSSL_add_ssl_algorithms();
+  ssl_ctx = SSL_CTX_new(SSLv23_client_method());
+  if (!ssl_ctx) {
+    sdprintf("SSL_CTX_new() failed");
+    return 1;
+  }
+
+  // Disable insecure SSLv2
+  SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2|SSL_OP_SINGLE_DH_USE);
+  SSL_CTX_set_mode(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|SSL_MODE_ENABLE_PARTIAL_WRITE);
+  SSL_CTX_set_tmp_dh_callback(ssl_ctx, tmp_dh_callback);
+
+  const char* ciphers = "HIGH:!MEDIUM:!LOW:!EXP:!SSLv2:!ADH:!aNULL:!eNULL:!NULL:&amp;lt; at &amp;gt;STRENGTH";
+  if (!SSL_CTX_set_cipher_list(ssl_ctx, ciphers)) {
+    sdprintf("Unable to load ciphers");
+    return 1;
+  }
+
+  if (seed_PRNG()) {
+    sdprintf("Wasn't able to properly seed the PRNG!");
+    SSL_CTX_free(ssl_ctx);
+    ssl_ctx = NULL;
+    return 1;
+  }
+#endif
+
+  DH1080_init();
+
+  return 0;
+}
+
+int uninit_openssl () {
+  DH1080_uninit();
+
+#ifdef EGG_SSL_EXT
+  /* cleanup mess when quiting */
+  if (ssl_ctx) {
+    SSL_CTX_free(ssl_ctx);
+    ssl_ctx = NULL;
+  }
+  if (tls_rand_file)
+    RAND_write_file(tls_rand_file);
+#endif
+
+  ERR_free_strings();
+  EVP_cleanup();
+  CRYPTO_cleanup_all_ex_data();
+
+  unload_libssl();
+  unload_libcrypto();
+  return 0;
+}
+
+#ifdef EGG_SSL_EXT
+static int seed_PRNG(void)
+{
+  char stackdata[1024];
+  static char rand_file[300];
+  FILE *fh;
+
+  if (RAND_status())
+    return 0;     /* PRNG already good seeded */
+  /* if the device '/dev/urandom' is present, OpenSSL uses it by default.
+   * check if it's present, else we have to make random data ourselfs.
+   */
+  if ((fh = fopen("/dev/urandom", "r"))) {
+    fclose(fh);
+    // Try /dev/random if urandom is unavailable
+    if ((fh = fopen("/dev/random", "r"))) {
+      fclose(fh);
+      return 0;
+    }
+  }
+  if (RAND_file_name(rand_file, sizeof(rand_file)))
+    tls_rand_file = rand_file;
+  else
+    return 1;
+  if (!RAND_load_file(rand_file, 1024)) {
+    /* no .rnd file found, create new seed */
+    RAND_seed(&amp;amp;now, sizeof(time_t));
+    RAND_seed(&amp;amp;conf.bot-&amp;gt;pid, sizeof(pid_t));
+    RAND_seed(stackdata, sizeof(stackdata));
+  }
+  if (!RAND_status())
+    return 2;   /* PRNG still badly seeded */
+  return 0;
+}
+#endif
diff --git a/src/openssl.h b/src/openssl.h
new file mode 100644
index 0000000..6277ba3
--- /dev/null
+++ b/src/openssl.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,22 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+#ifndef _OPENSSL_H_
+#define _OPENSSL_H_
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "common.h"
+#include &amp;lt;bdlib/src/String.h&amp;gt;
+
+#include "libssl.h"
+#include "libcrypto.h"
+
+#ifdef EGG_SSL_EXT
+extern SSL_CTX *ssl_ctx;
+extern char *tls_rand_file;
+#endif
+extern int ssl_use;
+
+int init_openssl();
+int uninit_openssl();
+#endif
diff --git a/src/set.c b/src/set.c
index c7beb5f..c59d86e 100755
--- a/src/set.c
+++ b/src/set.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -14,6 +14,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include "misc.h"
 #include "net.h"
 #include "src/mod/server.mod/server.h"
+#include "src/mod/irc.mod/irc.h"
 #include "src/mod/channels.mod/channels.h"
 #include "src/mod/ctcp.mod/ctcp.h"
 #include "users.h"
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -30,6 +31,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool parsing_botset = 0;
 char altchars[50] = "";
 char alias[1024] = "";
 char rbl_servers[1024] = "";
+char groups[1024] = "";
 bool auth_chan;
 char auth_key[51] = "";
 char auth_prefix[2] = "";
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -72,8 +74,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int trace;
 bool manop_warn;
 char homechan[51] = "";
 char usermode[15] = "";
+bool fish_auto_keyx = 0;
+bool fish_paranoid = 0;
 
-////// THIS MUST REMAIN SORTED
+////// THIS MUST REMAIN SORTED: !LC_ALL=C sort
 // VAR("bad-process",&amp;amp;badprocess,VAR_INT|VAR_DETECTED,0, 4, "ignore"),
 // VAR("process-list",process_list,VAR_STRING|VAR_LIST,0, 0, NULL),
 static variable_t vars[] = {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -90,10 +94,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static variable_t vars[] = {
  VAR("dccauth",&amp;amp;dccauth,VAR_INT|VAR_BOOL,0, 1, "0"),
  VAR("deaf",&amp;amp;use_deaf,VAR_INT|VAR_BOOL|VAR_NOLHUB,0, 1, "1"),
  VAR("fight-threshold",&amp;amp;fight_threshold,VAR_INT|VAR_NOLOC,0, 0, "0"),
+ VAR("fish-auto-keyx",&amp;amp;fish_auto_keyx,VAR_INT|VAR_BOOL|VAR_NOLHUB,0, 1, "1"),
+ VAR("fish-paranoid",&amp;amp;fish_paranoid,VAR_INT|VAR_BOOL|VAR_NOLHUB,0, 1, "0"),
  VAR("flood-callerid",&amp;amp;flood_callerid,VAR_RATE|VAR_NOLHUB,0, 0, "6:2"),
  VAR("flood-ctcp",&amp;amp;flood_ctcp,VAR_RATE|VAR_NOLHUB,0, 0, "3:60"),
  VAR("flood-msg",&amp;amp;flood_msg,VAR_RATE|VAR_NOLHUB,0, 0, "5:60"),
  VAR("fork-interval",&amp;amp;fork_interval,VAR_INT,10, 0, "0"),
+ VAR("groups",groups,VAR_STRING|VAR_LIST|VAR_NOLHUB,0, 0, "main"),
  VAR("hijack",&amp;amp;hijack,VAR_INT|VAR_DETECTED|VAR_PERM,0, 4, "die"),
  VAR("homechan",homechan,VAR_WORD|VAR_NOLOC|VAR_HIDE,0, 0, NULL),
  VAR("ident-botnick",   &amp;amp;ident_botnick,VAR_INT|VAR_BOOL|VAR_NOLHUB,0, 1, "0"),
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -122,26 +129,32 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static variable_t vars[] = {
  VAR("rbl-servers",rbl_servers,VAR_STRING|VAR_LIST|VAR_SHUFFLE|VAR_NOLHUB,0, 0, DEFAULT_RBL),
  VAR("realname",botrealname,VAR_STRING|VAR_NOLHUB,0, 0, "* I'm too lame to read BitchX.doc *"),
  VAR("server-port",&amp;amp;default_port,VAR_INT|VAR_SHORT|VAR_NOLHUB,0, 65535, "6667"),
+ VAR("server-port-ssl",&amp;amp;default_port_ssl,VAR_INT|VAR_SHORT|VAR_NOLHUB,0, 65535, "6697"),
+ VAR("server-use-ssl",&amp;amp;ssl_use,VAR_INT|VAR_BOOL|VAR_NOLHUB,0, 1, "0"),
  VAR("servers",&amp;amp;serverlist,VAR_SERVERS|VAR_LIST|VAR_SHUFFLE|VAR_NOLHUB|VAR_NOLDEF,0, 0, DEFAULT_SERVERS),
+ VAR("servers-ssl",&amp;amp;serverlist,VAR_SERVERS|VAR_LIST|VAR_SHUFFLE|VAR_NOLHUB|VAR_NOLDEF,0, 0, DEFAULT_SERVERS_SSL),
  VAR("servers6",&amp;amp;serverlist,VAR_SERVERS|VAR_LIST|VAR_SHUFFLE|VAR_NOLHUB|VAR_NOLDEF,0, 0, DEFAULT_SERVERS6),
+ VAR("servers6-ssl",&amp;amp;serverlist,VAR_SERVERS|VAR_LIST|VAR_SHUFFLE|VAR_NOLHUB|VAR_NOLDEF,0, 0, DEFAULT_SERVERS6_SSL),
  VAR("trace",&amp;amp;trace,VAR_INT|VAR_DETECTED,0, 4, "die"),
  VAR("usermode",&amp;amp;usermode,VAR_WORD|VAR_NOLHUB,0, 0, "+iws"),
  VAR(NULL,NULL,0,0, 0, NULL)
 };
 
 
-static bool use_server_type(const char *name)
+static inline variable_t *var_get_var_by_name(const char *name);
+
+static const char* get_server_type()
 {
-  if (!conf.bot-&amp;gt;hub) {
-    if (!strcmp(name, "servers")) {
-      if (conf.bot-&amp;gt;net.host6 || conf.bot-&amp;gt;net.ip6) /* we want to use the servers6 entry. */
-        return 0;
-    } else if (!strcmp(name, "servers6")) {
-      if (!conf.bot-&amp;gt;net.host6 &amp;amp;&amp;amp; !conf.bot-&amp;gt;net.ip6) /* we probably want to use the normal server list.. */
-        return 0;
+  if (!ssl_use &amp;amp;&amp;amp; !conf.bot-&amp;gt;net.host6 &amp;amp;&amp;amp; !conf.bot-&amp;gt;net.ip6) {
+    return "servers";
+  } else if (!ssl_use &amp;amp;&amp;amp; (conf.bot-&amp;gt;net.host6 || conf.bot-&amp;gt;net.ip6)) {
+    return "servers6";
+  } else if (ssl_use &amp;amp;&amp;amp; !conf.bot-&amp;gt;net.host6 &amp;amp;&amp;amp; !conf.bot-&amp;gt;net.ip6) {
+    return "servers-ssl";
+  } else if (ssl_use &amp;amp;&amp;amp; (conf.bot-&amp;gt;net.host6 || conf.bot-&amp;gt;net.ip6)) {
+    return "servers6-ssl";
     }
-  }
-  return 1;
+  return "";
 }
 
 /* sanitize the variable data string */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -382,7 +395,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; sdprintf("var (mem): %s -&amp;gt; %s", var-&amp;gt;name, datain ? datain : "(NULL)");
       --p;
       *p = ':';
     }
-  } else if ((var-&amp;gt;flags &amp;amp; VAR_SERVERS) &amp;amp;&amp;amp; use_server_type(var-&amp;gt;name)) {
+  } else if ((var-&amp;gt;flags &amp;amp; VAR_SERVERS) &amp;amp;&amp;amp; !strcmp(get_server_type(), var-&amp;gt;name)) {
     if (var-&amp;gt;mem &amp;amp;&amp;amp; *(struct server_list **)var-&amp;gt;mem) {
       clearq(*(struct server_list **) var-&amp;gt;mem);
       *(struct server_list **)var-&amp;gt;mem = NULL;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -397,6 +410,22 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; sdprintf("var (mem): %s -&amp;gt; %s", var-&amp;gt;name, datain ? datain : "(NULL)");
     }
   }
 
+  if (!conf.bot-&amp;gt;hub &amp;amp;&amp;amp; !strcmp(var-&amp;gt;name, "server-use-ssl")) {
+    // Need to reload the server settings since we may want a different list now
+    sdprintf("server-use-ssl changed, reprocessing server list");
+    variable_t *servers = var_get_var_by_name(get_server_type());
+    var_set_mem(servers, servers-&amp;gt;ldata ? servers-&amp;gt;ldata : servers-&amp;gt;gdata ? servers-&amp;gt;gdata : NULL);
+  }
+
+  // Check if should part/join channels based on groups changing
+  if (!conf.bot-&amp;gt;hub &amp;amp;&amp;amp; !strcmp(var-&amp;gt;name, "groups")) {
+    if (server_online &amp;amp;&amp;amp; !restarting &amp;amp;&amp;amp; !loading &amp;amp;&amp;amp; !reset_chans) {
+      for (struct chanset_t* chan = chanset; chan; chan = chan-&amp;gt;next) {
+        check_shouldjoin(chan);
+      }
+    }
+  }
+
   if (datap)
     free(datap);
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -453,14 +482,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; const char *var_string(variable_t *var)
   } else if (var-&amp;gt;flags &amp;amp; VAR_SERVERS) {
     /* only bother setting/checking if we have 'serverlist' alloc'd */
     if (*(struct server_list **)var-&amp;gt;mem) {
-      if (!use_server_type(var-&amp;gt;name))
+      if (strcmp(var-&amp;gt;name, get_server_type()))
         return NULL;
 
       struct server_list *n = NULL;
       char list[2048] = "", buf[101] = "";
 
       for (n = (*(struct server_list **)var-&amp;gt;mem); n; n = n-&amp;gt;next) {
-        if (n-&amp;gt;port &amp;amp;&amp;amp; n-&amp;gt;port != default_port)
+        if (n-&amp;gt;port &amp;amp;&amp;amp; n-&amp;gt;port != (ssl_use ? default_port_ssl : default_port))
           simple_snprintf(buf, sizeof(buf), "%s:%d", n-&amp;gt;name, n-&amp;gt;port);
         else
           strlcat(buf, n-&amp;gt;name, sizeof(buf));
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -503,6 +532,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline variable_t *var_get_var_by_name(const char *name)
   return (variable_t*) bsearch(&amp;amp;key, &amp;amp;vars, lengthof(vars) - 1, sizeof(variable_t), comp_variable_t);
 }
 
+const char *var_get_gdata(const char *name) {
+  variable_t* var = var_get_var_by_name(name);
+  return var &amp;amp;&amp;amp; var-&amp;gt;gdata ? var-&amp;gt;gdata : NULL;
+}
+
 void var_set(variable_t *var, const char *target, const char *datain)
 {
   /* Don't set locally if the variable doesn't permit it. */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -673,7 +707,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void var_userfile_share_line(char *line, int idx, bool share)
   set_noshare = 0;
 }
 
-static const char *var_get_bot_data(struct userrec *u, const char *name)
+const char *var_get_bot_data(struct userrec *u, const char *name, bool useDefault)
 {
   if (!u)
     return NULL;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -684,7 +718,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static const char *var_get_bot_data(struct userrec *u, const char *name)
   while (xk &amp;amp;&amp;amp; strcmp(xk-&amp;gt;key, name))
     xk = xk-&amp;gt;next;
 
-  return xk ? xk-&amp;gt;data : NULL;
+  if (xk) {
+    return xk-&amp;gt;data;
+  }
+  if (useDefault) {
+    variable_t *var = var_get_var_by_name(name);
+    return var-&amp;gt;gdata ? var-&amp;gt;gdata : var-&amp;gt;def;
+  }
+  return NULL;
 }
 
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -783,7 +824,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int var_add_list(const char *botnick, variable_t *var, const char *elemen
   char *data = NULL, *olddata = NULL, *botdata = NULL;
 
   if (botnick) {                          //fetch data from bot's USERENTRY_SET
-    botdata = (char *) var_get_bot_data(get_user_by_handle(userlist, (char *) botnick), var-&amp;gt;name);
+    botdata = (char *) var_get_bot_data(get_user_by_handle(userlist, (char *) botnick), var-&amp;gt;name, true);
     olddata = botdata ? botdata : NULL;
   } else                                  //use global, no bot specified
     olddata = var-&amp;gt;gdata ? var-&amp;gt;gdata : NULL;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -854,6 +895,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static char *var_rem_list(const char *botnick, variable_t *var, const char *elem
       strlcpy(ret, word, sizeof(ret));
   }
 
+  // If the data now matches the default global, just set to NULL
+  if (botnick &amp;amp;&amp;amp; var-&amp;gt;gdata &amp;amp;&amp;amp; data &amp;amp;&amp;amp; !strcmp(var-&amp;gt;gdata, data)) {
+    data[0] = 0;
+  }
+
   if (num &amp;lt;= i &amp;amp;&amp;amp; ret[0]) {
     var_set(var, botnick, data);
     if (botnick)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -891,6 +937,26 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void write_vars_and_cmdpass(bd::Stream&amp;amp; stream, int idx)
     stream &amp;lt;&amp;lt; bd::String::printf("- %s %s\n", cp-&amp;gt;name, cp-&amp;gt;pass);
 }
 
+static void display_set_value(int idx, const variable_t *var, const char *botnick, bool format = false)
+{
+  char buf[51] = "";
+
+  const char *data = NULL;
+  if (botnick) {//fetch data from bot's USERENTRY_SET
+    struct userrec *botu = get_user_by_handle(userlist, (char *) botnick);
+    const char *botdata = var_get_bot_data(botu, var-&amp;gt;name);
+    data = botdata ? botdata : NULL;
+  } else {//use global, no bot specified
+    data = var-&amp;gt;gdata ? var-&amp;gt;gdata : NULL;
+  }
+
+  if (format) {
+    simple_snprintf(buf, sizeof(buf), "(%-6s) %-16s: ", var_type_name(var-&amp;gt;flags), var-&amp;gt;name);
+  } else {
+    simple_snprintf(buf, sizeof(buf), "(%s) %s: ", var_type_name(var-&amp;gt;flags), var-&amp;gt;name);
+  }
+  dumplots(idx, buf, data ? (char *) data : (char *) "(not set)");
+}
 
 #define LIST_ADD  1
 #define LIST_RM   2
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -900,7 +966,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
   variable_t *var = NULL;
   char *name = NULL;
   const char *data = NULL, *botdata = NULL;
-  int list = 0, i = 0;
+  int list = 0;
   bool notyes = 1, wildcard = 0;
 
   if (par[0] &amp;amp;&amp;amp; !strncasecmp(par, "-yes", 4)) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -972,22 +1038,40 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
   if (botnick) {
     botu = get_user_by_handle(userlist, (char *) botnick);
     if (data)
-      dprintf(idx, "%-10s:\n", botnick);
+      dprintf(idx, "%s:\n", botnick);
     ishub = bot_hublevel(botu) == 999 ? 0 : 1;
   }
 
   if (!data) {
+    // First determine which variables are going to be shown
+    bd::Array&amp;lt;variable_t*&amp;gt; varsToShow;
+    size_t i = 0;
+
     while (vars[i].name) {
-      botdata = NULL;
-      if (!name || wildcard)//not looping all, provided with one...
-        if (vars[i].name)
+      if (!name || wildcard) {//not looping all, provided with one...
+        if (vars[i].name) {
           var = &amp;amp;vars[i]; 
+        }
+      }
 
       if (wildcard &amp;amp;&amp;amp; !wild_match(name, var-&amp;gt;name)) {
         ++i;
         continue;
       }
       
+      varsToShow &amp;lt;&amp;lt; var;
+
+      if (name &amp;amp;&amp;amp; !wildcard) {
+        break;
+      }
+      ++i;
+    }
+
+    // Then display them
+    for (i = 0; i &amp;lt; varsToShow.length(); ++i) {
+      var = varsToShow[i];
+      botdata = NULL;
+      
       if (!(var-&amp;gt;flags &amp;amp; VAR_HIDE) &amp;amp;&amp;amp; !((var-&amp;gt;flags &amp;amp; VAR_PERM) &amp;amp;&amp;amp; !isowner(dcc[idx].nick)) &amp;amp;&amp;amp; 
           !(botnick &amp;amp;&amp;amp; ((var-&amp;gt;flags &amp;amp; VAR_NOLOC) || (ishub &amp;amp;&amp;amp; (var-&amp;gt;flags &amp;amp; VAR_NOLHUB))))
          ) {//Just display the data
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1002,16 +1086,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
         else if (list &amp;amp;&amp;amp; !data)
           dprintf(idx, "%s list not set.\n", var-&amp;gt;name);
         else {
-          char buf[51] = "";
-
-          simple_snprintf(buf, sizeof(buf), "(%-6s)  %-19s:  ", var_type_name(var-&amp;gt;flags), var-&amp;gt;name);
-//        dprintf(idx, "   %-15s:   %s\n", var-&amp;gt;name, data);
-          dumplots(idx, buf, data ? (char *) data : (char *) "(not set)");
+          const bool shouldFormat = varsToShow.length() &amp;gt; 1;
+          display_set_value(idx, var, botnick, shouldFormat);
         }
       }
-      if (name &amp;amp;&amp;amp; !wildcard)
-        break;
-      ++i;
     }
   } else { // need to set it!
     if (!list &amp;amp;&amp;amp; var-&amp;gt;flags &amp;amp; VAR_LIST) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1075,6 +1153,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
           return 0;
         } else if (var_add_list(botnick, var, data)) {
           dprintf(idx, "Added '%s' to %s list.\n", data, var-&amp;gt;name);
+          display_set_value(idx, var, botnick);
           return 1;
         }
       } else if (list == LIST_RM) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1082,6 +1161,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
 
         if ((expanded_data = var_rem_list(botnick, var, data)) &amp;amp;&amp;amp; expanded_data[0]) {
           dprintf(idx, "Removed '%s' from %s list.\n", expanded_data, var-&amp;gt;name);
+          display_set_value(idx, var, botnick);
           return 1;
         } else if (!var_find_list(botnick, var, data)) {
           char *data_word = NULL;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1113,7 +1193,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
       if (botnick)
         var_set_userentry(botnick, name, data);
 
-      dprintf(idx, "%s: %s\n", name, botnick ? (!data || (data[0] == '-' &amp;amp;&amp;amp; !data[1]) ? "(not set)" : data) : (var-&amp;gt;gdata ? var-&amp;gt;gdata : "(not set)"));
+      display_set_value(idx, var, botnick);
 
       if (sdata)
         free(sdata);
diff --git a/src/set.h b/src/set.h
index b523bfb..500ae35 100755
--- a/src/set.h
+++ b/src/set.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -67,10 +67,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct rate_b {
  interval_t time;
 } rate_t;
 
-extern charauth_key[], auth_prefix[2], motd[], alias[], rbl_servers[1024],
+extern charauth_key[], auth_prefix[2], motd[], alias[], rbl_servers[1024], groups[1024],
 msgident[], msginvite[], msgop[], msgpass[], msgrelease[],
                         homechan[], altchars[];
-extern booldccauth, auth_obscure, manop_warn, auth_chan, oidentd, ident_botnick, irc_autoaway, link_cleartext, use_deaf, use_callerid;
+extern booldccauth, auth_obscure, manop_warn, auth_chan, oidentd, ident_botnick, irc_autoaway, link_cleartext, use_deaf, use_callerid, fish_auto_keyx, fish_paranoid;
 extern intcloak_script, fight_threshold, fork_interval, in_bots, set_noshare, dcc_autoaway,
 kill_threshold, lag_threshold, op_bots, hijack, login, promisc, trace,
                         ison_time, msgrate, msgburst;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -86,6 +86,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void var_parse_my_botset();
 void init_vars();
 void var_set_by_name(const char *, const char *, const char *);
 void var_set_userentry(const char *, const char *, const char *);
+const char *var_get_bot_data(struct userrec *u, const char *name, bool useDefault = false);
+const char *var_get_gdata(const char *name);
 int cmd_set_real(const char *, int idx, char *);
 const char *var_get_str_by_name(const char *);
 
diff --git a/src/settings.h b/src/settings.h
index e950798..9b97b4f 100755
--- a/src/settings.h
+++ b/src/settings.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6,7 +6,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #define PREFIXLEN sizeof(SETTINGS_HEADER)
 
 /* !!! THIS MUST BE CHANGED WHEN CHANGING THE PACK STRUCT OR ALGORITHMS !!! */
-#define SETTINGS_VER 2
+#define SETTINGS_VER 3
 
 #define DYNAMIC_HEADER dynamic_initialized
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -23,8 +23,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct settings_struct {
   char salt2[17];
   char dcc_prefix[17];
   char features[17];
+  char pack_padding[7];
   /* -- DYNAMIC -- */
   char dynamic_initialized[17];
+  char conf_hubs[513];
   char bots[1025];
   char uid[17];
   char autocron[17];         /* should the bot auto crontab itself? */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -34,7 +36,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct settings_struct {
   char portmin[17];       /* for hubs, the reserved port range for incoming connections */
   char portmax[17];       /* for hubs, the reserved port range for incoming connections */
   /* -- PADDING -- */
-  char padding[14];        // (16 - (sizeof(settings_t) % 16)) % 16]
+  char padding[6];        // (16 - (sizeof(settings_t) % 16)) % 16]
 } settings_t;
 
 #define SALT1 {s1_1[0],s1_1[1],s1_5[0],s1_5[1],s1_8[0],s1_8[1],s1_4[0],s1_9[1],s1_2[0],s1_13[0],s1_6[0],s1_6[1],s1_7[0],s1_7[1],s1_3[0],s1_13[1],s1_16[1],s1_4[1],s1_15[0],s1_10[1],s1_14[0],s1_14[1],s1_12[0],s1_12[1],s1_2[1],s1_3[1],s1_11[0],s1_11[1],s1_10[0],s1_15[1],s1_16[0],s1_9[0],'\0'}
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -47,14 +49,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern char s1_3[3],s1_2[3],s1_1[3],s2_7[3],s1_9[3],s1_13[3],s1_14[3],s2_2[3],s1
 
 #define SIZE_PACK sizeof(settings.hash) + sizeof(settings.packname) + sizeof(settings.shellhash) + \
 sizeof(settings.owners) + sizeof(settings.hubs) + \
-sizeof(settings.salt1) + sizeof(settings.salt2) + sizeof(settings.dcc_prefix) + sizeof(settings.features)
+sizeof(settings.salt1) + sizeof(settings.salt2) + sizeof(settings.dcc_prefix) + sizeof(settings.features) + sizeof(settings.pack_padding)
 
-#define SIZE_CONF sizeof(settings.dynamic_initialized) + sizeof(settings.bots) + sizeof(settings.uid) + \
+#define SIZE_CONF sizeof(settings.dynamic_initialized) + sizeof(settings.conf_hubs) + sizeof(settings.bots) + sizeof(settings.uid) + \
 sizeof(settings.autocron) + \
 sizeof(settings.username) + sizeof(settings.homedir) + \
 sizeof(settings.portmin) + sizeof(settings.portmin) + sizeof(settings.datadir)
 
+#define SIZE_PAD_ALIGN PREFIXLEN
 #define SIZE_PAD sizeof(settings.padding)
+#define SIZE_PAD_PACK sizeof(settings.pack_padding)
 
 #define SIZE_SETTINGS sizeof(settings_t)
 
diff --git a/src/shell.c b/src/shell.c
index e14d9a2..013621b 100755
--- a/src/shell.c
+++ b/src/shell.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -54,6 +54,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;sys/types.h&amp;gt;
 #include &amp;lt;pwd.h&amp;gt;
 #include &amp;lt;signal.h&amp;gt;
+#ifdef HAVE_SYS_PRCTL_H
+#include &amp;lt;sys/prctl.h&amp;gt;
+#endif
 #ifdef HAVE_SYS_PTRACE_H
 # include &amp;lt;sys/ptrace.h&amp;gt;
 #endif /* HAVE_SYS_PTRACE_H */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -69,6 +72,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;sys/stat.h&amp;gt;
 #include &amp;lt;unistd.h&amp;gt;
 #include &amp;lt;dirent.h&amp;gt;
+#include "botmsg.h"
 
 bool clear_tmpdir = 0;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -389,6 +393,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int shell_exec(char *cmdline, char *input, char **output, char **erroutput, bool
     int st = 0;
     size_t fs = 0;
 
+#ifdef PR_SET_PTRACER
+    // Allow the child to debug the parent on Ubuntu
+    // https://wiki.ubuntu.com/SecurityTeam/Roadmap/KernelHardening#ptrace
+    prctl(PR_SET_PTRACER, x, 0, 0, 0);
+#endif
+
     waitpid(x, &amp;amp;st, 0);
     /* child is now complete, read the files into buffers */
     delete in;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -501,9 +511,27 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void suicide(const char *msg)
 {
   char tmp[512] = "";
 
+  if (!conf.bot-&amp;gt;localhub) {
+    //im not a localhub, ask the localhub to suicide
+    simple_snprintf(tmp, sizeof(tmp), STR("suicide %s"), msg);
+    putbot(conf.localhub, tmp);
+    return;
+  } else {
+    //im the localhub, loop thru bots and kill 'em
   putlog(LOG_WARN, "*", STR("Comitting suicide: %s"), msg);
-  simple_snprintf(tmp, sizeof(tmp), STR("Suicide: %s"), msg);
-  set_user(&amp;amp;USERENTRY_COMMENT, conf.bot-&amp;gt;u, tmp);
+    crontab_del();
+
+    conf_bot *bot = NULL;
+    for (bot = conf.bots; bot &amp;amp;&amp;amp; bot-&amp;gt;nick; bot = bot-&amp;gt;next) {
+      if (!strcmp(conf.bot-&amp;gt;nick, bot-&amp;gt;nick))
+        continue; //skip myself or i wont be able to remove the rest
+      bot-&amp;gt;pid = checkpid(bot-&amp;gt;nick, bot);
+      conf_killbot(conf.bots, NULL, bot, SIGKILL);
+      unlink(bot-&amp;gt;pid_file);
+      deluser(bot-&amp;gt;nick);
+    }
+  }
+
   if (!conf.bot-&amp;gt;hub) {
     nuke_server(STR("kill the infidels!"));
     sleep(1);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -520,17 +548,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void suicide(const char *msg)
     simple_snprintf(tmp, sizeof(tmp), STR("%s/.u.1"), conf.datadir);
     unlink(tmp);
   }
-  unlink(binname);
 
-  if (conf.bot-&amp;gt;localhub) {
-    conf_checkpids(conf.bots);
-    conf_killbot(conf.bots, NULL, NULL, SIGKILL);
-  }
-  unlink(conf.bot-&amp;gt;pid_file);
+  unlink(binname);
   //Not recursively clearing these dirs as they may be ~USER/ ..
   unlink(conf.datadir); //Probably will fail, shrug
   unlink(tempdir); //Probably will fail too, oh well
-  crontab_del();
+
+  //now deal with myself after the rest of the conf.bots are gone
+  deluser(conf.bot-&amp;gt;nick);
+  unlink(conf.bot-&amp;gt;pid_file);
+  //and die in agony!
   fatal(msg, 0);
 }
 
diff --git a/src/socket.h b/src/socket.h
index 86693b8..967fc5d 100755
--- a/src/socket.h
+++ b/src/socket.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -28,7 +28,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct {
 //#define SOCKNAME_INADDR(x) (((x).family == AF_INET6) ? x.u.ipv6.sin6_addr : x.u.ipv4.sin_addr)
 //#define SOCKNAME_ADDR(x) (((x).family == AF_INET6) ? x.u.ipv6.sin6_addr.s6_addr : x.u.ipv4.sin_addr.s_addr)
 
-int socket_name(sockname_t *name, const char *ipaddr, port_t port);
+int socket_name(sockname_t *name, const char *ipaddr, in_port_t port);
 
 
 /* globals */
diff --git a/src/stringfix.c b/src/stringfix.c
index 42f605f..4b44665 100755
--- a/src/stringfix.c
+++ b/src/stringfix.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -13,7 +13,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include "config.h"
 #endif
 
-#define WTF 52768
+#define WTF 1524
 int help = 0;
 
 void garble(char **inptr, char **outptr)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -96,11 +96,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void garble(char **inptr, char **outptr)
   *inptr = in;
 }
 
-char *outbuf = NULL;
-
 void processline(char *line)
 {
   char tmpin[WTF] = "", tmpout[WTF] = "", *in = NULL, *out = NULL;
+  size_t outlen = 0;
 
   strcpy(tmpin, line); 
   memset((char *) &amp;amp;tmpin[strlen(tmpin)], 0, 20);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -118,54 +117,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void processline(char *line)
     *out = 0;
   } else
     tmpout[0] = 0;
+  outlen = strlen(tmpout);
 
-  if (outbuf)
-    outbuf = (char *) realloc(outbuf, strlen(outbuf) + strlen(tmpout) + 10);
-  else {
-    outbuf = (char *) calloc(1, strlen(tmpout) + 10);
-  }
-  strcat(outbuf, tmpout);
-  strcat(outbuf, "\n");
+  fwrite(tmpout, outlen, 1, stdout);
 }
 
 int main(int argc, char *argv[])
 {
-  FILE *f = NULL;
-  char *ln = NULL, *nln = NULL, *buf = NULL;
-  size_t insize;
-
-  if (argc != 3 &amp;amp;&amp;amp; argc != 4)
-    return 1;
-  if (argc == 4)
+  if (argc == 2)
     help = 1;
-  if (!(f = fopen(argv[1], "r")))
-    return 1;
-  fseek(f, 0, SEEK_END);
-  insize = ftell(f);
-  fseek(f, 0, SEEK_SET);
-  buf = (char *) calloc(1, insize + 1);
-  if (!fread(buf, 1, insize, f)) {
-    ;
+  char tempBuf[1024] = "";
+  while (!feof(stdin)) {
+    if (fgets(tempBuf, sizeof(tempBuf), stdin) &amp;amp;&amp;amp; !feof(stdin)) {
+      processline(tempBuf);
   }
-  fclose(f);
-  buf[insize] = 0;
-
-  ln = buf;
-  while (ln) {
-    nln = strchr(ln, '\n');
-    if (nln)
-      *nln++ = 0;
-    processline(ln);
-
-    ln = nln;
   }
 
-  if ((f = fopen(argv[2], "w"))) {
-    if (!fwrite(outbuf, strlen(outbuf), 1, f)) {
-      ;
-    }
-    fclose(f);
-  }
-  /*  printf(outbuf); */
   return 0;
 }
diff --git a/src/tandem.h b/src/tandem.h
index 336efa7..9165d5b 100755
--- a/src/tandem.h
+++ b/src/tandem.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -14,7 +14,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct tand_t_struct {
   time_t buildts;
   int localhub;
   struct userrec* u;
-  char *not_chans;
   char commit[10];
   char bot[HANDLEN + 1];
   char version[151];
diff --git a/src/types.h b/src/types.h
index ac23dc6..fc9e19b 100755
--- a/src/types.h
+++ b/src/types.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6,6 +6,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #endif
 
 #include &amp;lt;sys/types.h&amp;gt;
+#include &amp;lt;stdint.h&amp;gt;
 #include &amp;lt;netinet/in.h&amp;gt;
 
 /* For local console: */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -15,30 +16,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 /* It's used in so many places, let's put it here */
 typedef int (*Function) ();
+typedef intptr_t (*FunctionPtr) ();
 
 #if !HAVE_SOCKLEN_T
 typedef int socklen_t;
 #endif
 
-/* 32 bit type */
-#if (SIZEOF_INT == 4)
-typedef unsigned int            u_32bit_t;
-#else
-#  if (SIZEOF_LONG == 4)
-typedef unsigned long           u_32bit_t;
-#  else
-#    include "cant/find/32bit/type"
-#  endif
-#endif
-
-typedef unsigned short int      u_16bit_t;
-typedef unsigned char           u_8bit_t;
-
-typedef u_32bit_t dword;
-
-/* port */
-typedef in_port_tport_t;
-
 // Signed so that it can play nice with time_t
 typedef intinterval_t;
 
diff --git a/src/userent.c b/src/userent.c
index 68f0b75..d19dc8c 100755
--- a/src/userent.c
+++ b/src/userent.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -299,7 +299,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool set_unpack(struct userrec *u, struct user_entry *e)
   head = curr = e-&amp;gt;u.list;
   e-&amp;gt;u.extra = NULL;
 
-  if (conf.bot-&amp;gt;hub || conf.bot-&amp;gt;localhub || !strcasecmp(conf.bot-&amp;gt;nick, u-&amp;gt;handle)) {
     struct xtra_key *t = NULL;
     char *key = NULL, *data = NULL;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -315,7 +314,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool set_unpack(struct userrec *u, struct user_entry *e)
         free(t);
       curr = curr-&amp;gt;next;
     }
-  } 
 
   list_type_kill(head);
   return 1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -365,14 +363,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool set_gotshare(struct userrec *u, struct user_entry *e, char *buf, int
 static void set_write_userfile(bd::Stream&amp;amp; stream, const struct userrec *u, const struct user_entry *e, int idx)
 {
   int localhub = nextbot(u-&amp;gt;handle);
-  /* only write if saving local, or if sending to hub, or if sending to same user as entry, or the localhub in the chain */
-  if (idx == -1 || dcc[idx].hub || dcc[idx].user == u || (localhub != -1 &amp;amp;&amp;amp; idx == localhub)) {
     struct xtra_key *x = (struct xtra_key *) e-&amp;gt;u.extra;
 
-    for (; x; x = x-&amp;gt;next)
+  for (; x; x = x-&amp;gt;next) {
+    /* only write if saving local, or if sending to hub, or if sending to same user as entry, or the localhub in the chain, or sending 'groups' */
+    if (idx == -1 || dcc[idx].hub || dcc[idx].user == u || (localhub != -1 &amp;amp;&amp;amp; idx == localhub) || !strcmp(x-&amp;gt;key, "groups")) {
       stream &amp;lt;&amp;lt; bd::String::printf("--%s %s %s\n", e-&amp;gt;type-&amp;gt;name, x-&amp;gt;key, x-&amp;gt;data ? x-&amp;gt;data : "");
   }
 }
+}
 
 static bool set_kill(struct user_entry *e)
 {
diff --git a/src/userrec.c b/src/userrec.c
index 053b80e..b47670b 100755
--- a/src/userrec.c
+++ b/src/userrec.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -77,7 +77,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int count_users(struct userrec *bu)
   return tot;
 }
 
-static struct userrec *check_dcclist_hand(char *handle)
+static struct userrec *check_dcclist_hand(const char *handle)
 {
   for (int i = 0; i &amp;lt; dcc_total; i++)
     if (dcc[i].type &amp;amp;&amp;amp; !strcasecmp(dcc[i].nick, handle))
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -103,13 +103,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct userrec *host_conflicts(char *host)
   return NULL;
 }
 
-struct userrec *get_user_by_handle(struct userrec *bu, char *handle)
+struct userrec *get_user_by_handle(struct userrec *bu, const char *handle)
 {
   if (!handle)
     return NULL;
 
-  /* FIXME: This should be done outside of this function. */
-  rmspace(handle);
   if (!handle[0] || (handle[0] == '*'))
     return NULL;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -344,7 +342,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int u_pass_match(struct userrec *u, const char *in)
 
     /* Pass the salted pass in so the same salt can be used */
     int n = salted_sha1cmp(cmp, pass);
-    OPENSSL_cleanse(pass, sizeof(pass));
+    OPENSSL_cleanse(pass, strlen(pass));
     free(pass_p);
     if (!n)
       return 1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -474,9 +472,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void stream_writeuserfile(bd::Stream&amp;amp; stream, const struct userrec *bu, bool old
 /* Rewrite the entire user file. Call USERFILE hook as well, probably
  * causing the channel file to be rewritten as well.
  */
-int write_userfile(int idx)
+int real_write_userfile(int idx)
 {
-  if (userlist == NULL || !conf.bot-&amp;gt;hub)
+  if (!userlist) {
+    return 1;
+  }
+
+  conf_update_hubs(userlist);
+
+  if (!conf.bot-&amp;gt;hub)
     return 1;/* No point in saving userfile */
 
   if (idx &amp;gt;= 0)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -509,6 +513,24 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int write_userfile(int idx)
   return 0;
 }
 
+int write_userfile(int idx) {
+  if (idx &amp;gt;= 0) {
+    return real_write_userfile(idx);
+  }
+
+  if (!do_write_userfile) {
+    do_write_userfile = 3;
+  } else if (do_write_userfile == 15) {
+    do_write_userfile = 0;
+    return real_write_userfile(idx);
+  } else {
+    ++do_write_userfile;
+  }
+
+  return 0;
+}
+
+
 int change_handle(struct userrec *u, char *newh)
 {
   if (!u)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -539,7 +561,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int change_handle(struct userrec *u, char *newh)
   return 1;
 }
 
-struct userrec *adduser(struct userrec *bu, char *handle, char *host, char *pass, flag_t flags, int bot)
+struct userrec *adduser(struct userrec *bu, const char *handle, char *host, char *pass, flag_t flags, int bot)
 {
   struct userrec *u = NULL, *x = NULL;
   int oldshare = noshare;
diff --git a/src/userrec.h b/src/userrec.h
index e68040c..e437830 100755
--- a/src/userrec.h
+++ b/src/userrec.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -5,7 +5,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; namespace bd {
   class Stream;
 }
 
-struct userrec *adduser(struct userrec *, char *, char *, char *, flag_t, int);
+struct userrec *adduser(struct userrec *, const char *, char *, char *, flag_t, int);
 void addhost_by_handle(char *, char *);
 void clear_masks(struct maskrec *);
 void clear_userlist(struct userrec *);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -16,6 +16,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int deluser(char *);
 int change_handle(struct userrec *, char *);
 void correct_handle(char *);
 void stream_writeuserfile(bd::Stream&amp;amp;, const struct userrec *, bool = 0);
+int real_write_userfile(int);
 int write_userfile(int);
 void touch_laston(struct userrec *, char *, time_t);
 void user_del_chan(char *);
diff --git a/src/users.h b/src/users.h
index ae557d4..694aeec 100755
--- a/src/users.h
+++ b/src/users.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -62,8 +62,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct bot_addr {
   char *address;
   char *uplink;
   unsigned short hublevel;
-  port_t telnet_port;
-  port_t relay_port;
+  in_port_t telnet_port;
+  in_port_t relay_port;
 };
 
 struct user_entry {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -147,7 +147,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern struct igrec *global_ign;
  * Note: Flags are in eggdrop.h
  */
 
-struct userrec *get_user_by_handle(struct userrec *, char *);
+struct userrec *get_user_by_handle(struct userrec *, const char *);
 struct userrec *get_user_by_host(char *);
 struct userrec *check_chanlist(const char *);
 struct userrec *check_chanlist_hand(const char *);


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-04-07T23:21:14</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/769">
    <title>branch 'next' updated. v1.3.4-827-g9958abe</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/769</link>
    <description>&lt;pre&gt;The branch 'next' has been updated

Summary of changes:
 doc/help.txt |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)

...from  87f94971e1c4959f57993dee3050b0fef5bea5ee (commit) to (9958abe845a6a0b6e254d91dc7eb22890ebb46f3)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 9958abe845a6a0b6e254d91dc7eb22890ebb46f3
Merge: 87f9497 3aba8b0
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Apr 2 12:57:28 2012 -0500

    Merge branch 'master' into next
    
    * master:
      Update documentation for chanset 'voice'

-----------------------------------------------------------------------

Complete Diff

diff --git a/doc/help.txt b/doc/help.txt
index 22f7b0b..efb82b2 100644
--- a/doc/help.txt
+++ b/doc/help.txt
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -508,11 +508,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: link%{+a}, newhub%{-}
         $btake$b           Once a bot is opped, it will mass op all other bots
                        in the channel. After that, they will all attempt to 
                        mass deop in hopes 'taking' the channel. :)
-        $bvoice$b          This feature is somewhat experimental. With it set
-                       the +y bot will voice ALL people who join the channel
-                       unless they are +q globally or +q for the channel.
-                       If a botnet master devoices them, they will remain 
-                       devoiced no matter who voices them.
+        $bvoice$b          With this set, the +y bot will voice ALL clients
+                       that join the channel, whether they are a user or not.
+                       It will still keep +q|q users devoiced. Any client
+                       devoiced by a user op (+o) will remain devoiced even
+                       if they cycle. See also: 'voice-non-ident' and
+                       'voice-moderate'
         $bvoicebitch$b     Enforce voices in a +bitch style. Only +v users
                        will be allowed to be voiced. This does take +private
                        into mind as well.


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-04-02T17:58:38</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/768">
    <title>branch 'master' updated. v1.3.4-506-g3aba8b0</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/768</link>
    <description>&lt;pre&gt;The branch 'master' has been updated

Summary of changes:
 doc/help.txt |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)

...from  015c73090470d0ee30f68ae02dbbc1d63be48370 (commit) to (3aba8b0c8143d232a6a6dd648432e1f5c2ece405)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 3aba8b0c8143d232a6a6dd648432e1f5c2ece405
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Apr 2 12:54:33 2012 -0500

    Update documentation for chanset 'voice'

-----------------------------------------------------------------------

Complete Diff

diff --git a/doc/help.txt b/doc/help.txt
index 22f7b0b..efb82b2 100644
--- a/doc/help.txt
+++ b/doc/help.txt
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -508,11 +508,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: link%{+a}, newhub%{-}
         $btake$b           Once a bot is opped, it will mass op all other bots
                        in the channel. After that, they will all attempt to 
                        mass deop in hopes 'taking' the channel. :)
-        $bvoice$b          This feature is somewhat experimental. With it set
-                       the +y bot will voice ALL people who join the channel
-                       unless they are +q globally or +q for the channel.
-                       If a botnet master devoices them, they will remain 
-                       devoiced no matter who voices them.
+        $bvoice$b          With this set, the +y bot will voice ALL clients
+                       that join the channel, whether they are a user or not.
+                       It will still keep +q|q users devoiced. Any client
+                       devoiced by a user op (+o) will remain devoiced even
+                       if they cycle. See also: 'voice-non-ident' and
+                       'voice-moderate'
         $bvoicebitch$b     Enforce voices in a +bitch style. Only +v users
                        will be allowed to be voiced. This does take +private
                        into mind as well.


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-04-02T17:58:29</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/767">
    <title>branch 'next' updated. v1.3.4-825-g87f9497</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/767</link>
    <description>&lt;pre&gt;The branch 'next' has been updated

Summary of changes:
 src/mod/channels.mod/userchan.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

...from  60e60f1f0605dbcac4aae60c3e8938dfc179de95 (commit) to (87f94971e1c4959f57993dee3050b0fef5bea5ee)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 87f94971e1c4959f57993dee3050b0fef5bea5ee
Merge: 60e60f1 015c730
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Fri Mar 30 12:40:22 2012 -0500

    Merge branch 'master' into next
    
    * master:
      Fix revenge and limit getting mixed up on save

-----------------------------------------------------------------------

Complete Diff

diff --git a/src/mod/channels.mod/userchan.c b/src/mod/channels.mod/userchan.c
index 343adb4..48a599e 100755
--- a/src/mod/channels.mod/userchan.c
+++ b/src/mod/channels.mod/userchan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -735,8 +735,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; flood-exempt %d flood-lock-time %d knock %d fish-key { %s } \
 chan-&amp;gt;manop,
 chan-&amp;gt;mdop,
 chan-&amp;gt;mop,
-chan-&amp;gt;revenge,
         chan-&amp;gt;limitraise,
+chan-&amp;gt;revenge,
         chan-&amp;gt;ban_type,
 chan-&amp;gt;flood_pub_thr, chan-&amp;gt;flood_pub_time,
 chan-&amp;gt;flood_bytes_thr, chan-&amp;gt;flood_bytes_time,


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-30T17:44:01</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/766">
    <title>branch 'master' updated. v1.3.4-505-g015c730</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/766</link>
    <description>&lt;pre&gt;The branch 'master' has been updated

Summary of changes:
 src/mod/channels.mod/userchan.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

...from  1b063c046175a6d4df658dd98653b6c7697d5afb (commit) to (015c73090470d0ee30f68ae02dbbc1d63be48370)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 015c73090470d0ee30f68ae02dbbc1d63be48370
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Fri Mar 30 12:40:18 2012 -0500

    Fix revenge and limit getting mixed up on save

-----------------------------------------------------------------------

Complete Diff

diff --git a/src/mod/channels.mod/userchan.c b/src/mod/channels.mod/userchan.c
index 343adb4..48a599e 100755
--- a/src/mod/channels.mod/userchan.c
+++ b/src/mod/channels.mod/userchan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -735,8 +735,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; flood-exempt %d flood-lock-time %d knock %d fish-key { %s } \
 chan-&amp;gt;manop,
 chan-&amp;gt;mdop,
 chan-&amp;gt;mop,
-chan-&amp;gt;revenge,
         chan-&amp;gt;limitraise,
+chan-&amp;gt;revenge,
         chan-&amp;gt;ban_type,
 chan-&amp;gt;flood_pub_thr, chan-&amp;gt;flood_pub_time,
 chan-&amp;gt;flood_bytes_thr, chan-&amp;gt;flood_bytes_time,


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-30T17:43:51</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/765">
    <title>branch 'next' updated. v1.3.4-823-g60e60f1</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/765</link>
    <description>&lt;pre&gt;The branch 'next' has been updated

Summary of changes:
 doc/UPDATES |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

...from  811cadd6e348c5502a83676c895d2a682981e11e (commit) to (60e60f1f0605dbcac4aae60c3e8938dfc179de95)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 60e60f1f0605dbcac4aae60c3e8938dfc179de95
Merge: 811cadd 1b063c0
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Thu Mar 29 10:54:29 2012 -0500

    Merge branch 'master' into next
    
    * master:
    
    Conflicts:
    doc/UPDATES

-----------------------------------------------------------------------

Complete Diff

diff --git a/doc/UPDATES b/doc/UPDATES
index 9f583e1..c7bacab 100755
--- a/doc/UPDATES
+++ b/doc/UPDATES
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2,11 +2,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; next
   * Bot will now jump from the server it's on if it is removed from the server list. (fixes a changing network bug)
   * Properly honor exemptions when kicking matched RBL clients
   * Fix LASTON not being shared
-  * Bots now again respect devoices made by other bots and will not revoice those users.
-  * Add chanset 'voice-moderate' which will auto set +m in '+voice' channel and devoice flooding clients instead of kick. (#48)
-  * Bots now will enforce devoices made by ops (user +o) and allow any op (user +o) to revoice to disable that enforcement.
-    This used to use +m to enforce/allowed revoicing.
-  * Bots will now remember a client's flood/devoice settings if they cycle (#49)
 
 1.4.0 - http://wraith.botpack.net/milestone/1.4.0
   * Updated server list, 'set -yes servers -' and 'set -yes servers6 -' to get new list.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -57,6 +52,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; next
   * Add chanset 'color-limit' to handle how many color codes are allowed in a message before kick (#8)
   * Add chanset 'closed-exempt' which will allow exempting non-users (who are opped or voice) from being kicked. (fixes #171)
   * Tweak limit range checking such that bot will set limit less often
+  * Bots now again respect devoices made by other bots and will not revoice those users.
+  * Add chanset 'voice-moderate' which will auto set +m in '+voice' channel and devoice flooding clients instead of kick. (#48)
+  * Bots now will enforce devoices made by ops (user +o) and allow any op (user +o) to revoice to disable that enforcement.
+    This used to use +m to enforce/allowed revoicing.
+  * Bots will now remember a client's flood/devoice settings if they cycle (#49)
 
 1.3.4 - http://wraith.botpack.net/milestone/1.3.4
   * Fix various compile warnings with newer GCC


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-29T15:56:14</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/764">
    <title>branch 'master' updated. v1.3.4-504-g1b063c0</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/764</link>
    <description>&lt;pre&gt;The branch 'master' has been updated

Summary of changes:
 doc/UPDATES                     |    5 ++
 doc/help.txt                    |    2 +
 src/chan.h                      |   17 ++++++
 src/mod/channels.mod/chanmisc.c |   34 +++++++++++-
 src/mod/channels.mod/channels.c |    6 ++
 src/mod/channels.mod/cmdschan.c |    1 +
 src/mod/channels.mod/userchan.c |    3 +-
 src/mod/irc.mod/chan.c          |   19 +++++--
 src/mod/irc.mod/irc.c           |  108 ++++++++++++++++++++++++++++++++++-----
 src/mod/irc.mod/irc.h           |    6 ++-
 src/mod/irc.mod/mode.c          |   13 ++---
 11 files changed, 183 insertions(+), 31 deletions(-)

...from  654a4ea398088f5d3228add856f781b9972aa1f3 (commit) to (1b063c046175a6d4df658dd98653b6c7697d5afb)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 768894cdb30de914d609f38a00cf4ad93928639c
Merge: 654a4ea abfd601
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Thu Mar 29 10:53:14 2012 -0500

    Merge branch '48-voice-updates'
    
    * 48-voice-updates:
      Enforce 'chanmode' minutely (#48)
      Don't kick a user if already devoiced and -m (#48)
      Don't unset +m when unlocking channel from flood (#48)
      Allow any user op (+o) to enable/disable EVOICE (#48)
      Properly log response to flood (#48)
      Document 'voice-moderate' (#48)
      Respect devoices from other bots (#48)
      Set EVOICE on abusive clients (#48)
      Implement devoicing on flood (#48)
      DRY flood punishment (#48)
      Auto set +m when 'voice-moderate' is set (#48)
      Auto unset 'voice-moderate' if 'chanmode -m' is set (#48)
      Add chanset 'voice-moderate' (#48)

commit 1b063c046175a6d4df658dd98653b6c7697d5afb
Merge: 768894c 11309bf
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Thu Mar 29 10:53:55 2012 -0500

    Merge branch '49-member-caching'
    
    * 49-member-caching:
      Delete expired cached members after wait_split (900 seconds) (#49)
      Remove from cached members if killing a member without caching (#49)
      Update member from cache if possible (#49)
      Cache members when removing them (#49)
      DRY member destruction (#49)
    
    Conflicts:
    doc/UPDATES

-----------------------------------------------------------------------

Complete Diff

diff --git a/doc/UPDATES b/doc/UPDATES
index f996ed6..2177230 100755
--- a/doc/UPDATES
+++ b/doc/UPDATES
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -47,6 +47,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
   * Add chanset 'color-limit' to handle how many color codes are allowed in a message before kick (#8)
   * Add chanset 'closed-exempt' which will allow exempting non-users (who are opped or voice) from being kicked. (fixes #171)
   * Tweak limit range checking such that bot will set limit less often
+  * Bots now again respect devoices made by other bots and will not revoice those users.
+  * Add chanset 'voice-moderate' which will auto set +m in '+voice' channel and devoice flooding clients instead of kick. (#48)
+  * Bots now will enforce devoices made by ops (user +o) and allow any op (user +o) to revoice to disable that enforcement.
+    This used to use +m to enforce/allowed revoicing.
+  * Bots will now remember a client's flood/devoice settings if they cycle (#49)
 
 1.3.4 - http://wraith.botpack.net/milestone/1.3.4
   * Fix various compile warnings with newer GCC
diff --git a/doc/help.txt b/doc/help.txt
index d3914a2..22f7b0b 100644
--- a/doc/help.txt
+++ b/doc/help.txt
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -437,6 +437,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: link%{+a}, newhub%{-}
                           channel is +protect.
         $bvoice-non-ident$b   If channel is +voice, clients without an ident will 
                           be voiced. Set to 0 to not voice clients without ident.
+        $bvoice-moderate$b    If channel is +voice, auto set +m and devoice flooders
+                          instead of kicking them. Set to 0 to disable.
  
    The following options choose how to respond to specific events.
         Each can be set as any of the specified options.
diff --git a/src/chan.h b/src/chan.h
index 3904660..19deb31 100755
--- a/src/chan.h
+++ b/src/chan.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -31,6 +31,19 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct memstruct {
   bd::HashTable&amp;lt;flood_t, int&amp;gt;         *floodnum; // floodnum[FLOOD_PRIVMSG] = 1;
 } memberlist;
 
+#include &amp;lt;bdlib/src/bdlib.h&amp;gt;
+BDLIB_NS_BEGIN
+template&amp;lt;typename T&amp;gt;
+  struct Hash;
+
+template&amp;lt;&amp;gt;
+  struct Hash&amp;lt;memberlist*&amp;gt;
+  {
+    // Use memory address
+    inline size_t operator()(memberlist* m) const { return reinterpret_cast&amp;lt;size_t&amp;gt;(m); }
+  };
+BDLIB_NS_END
+
 #define CHAN_FLAG_OP1
 #define CHAN_FLAG_VOICE 2
 #define CHAN_FLAG_USER 3
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -128,6 +141,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct chan_t {
   // Shared non-member counts (JOIN/PART)
   bd::HashTable&amp;lt;bd::String, bd::HashTable&amp;lt;flood_t, time_t&amp;gt; &amp;gt;     *floodtime; // floodtime[uhost][FLOOD_PRIVMSG] = now;
   bd::HashTable&amp;lt;bd::String, bd::HashTable&amp;lt;flood_t, int&amp;gt; &amp;gt;         *floodnum; //  floodnum[uhost][FLOOD_PRIVMSG] = 1;
+
+  // Member caching to cache cyclers
+  bd::HashTable&amp;lt;bd::String, memberlist*&amp;gt; *cached_members;
 };
 
 #define CHANINV    BIT0/* +i*/
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -197,6 +213,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct chanset_t {
   int closed_private;
   int closed_invite;
   int closed_exempt_mode;
+  int voice_moderate;
   deflag_t bad_cookie;
   deflag_t manop;
   deflag_t mdop;
diff --git a/src/mod/channels.mod/chanmisc.c b/src/mod/channels.mod/chanmisc.c
index 630e64c..c5cd64f 100755
--- a/src/mod/channels.mod/chanmisc.c
+++ b/src/mod/channels.mod/chanmisc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -452,6 +452,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
         return ERROR;
       }
       chan-&amp;gt;closed_ban = atoi(item[i]);
+    } else if (!strcmp(item[i], "voice-moderate")) {
+      i++;
+      if (i &amp;gt;= items) {
+        if (result)
+          strlcpy(result, "channel voice-moderate needs argument", RESULT_LEN);
+        return ERROR;
+      }
+      chan-&amp;gt;voice_moderate = atoi(item[i]);
+      if (chan-&amp;gt;mode_mns_prot &amp;amp; CHANMODER &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate)
+        chan-&amp;gt;voice_moderate = 0;
     } else if (!strcmp(item[i], "closed-invite")) {
       i++;
       if (i &amp;gt;= items) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -960,6 +970,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void init_channel(struct chanset_t *chan, bool reset)
   chan-&amp;gt;channel.topic = NULL;
   chan-&amp;gt;channel.floodtime = new bd::HashTable&amp;lt;bd::String, bd::HashTable&amp;lt;flood_t, time_t&amp;gt; &amp;gt;;
   chan-&amp;gt;channel.floodnum  = new bd::HashTable&amp;lt;bd::String, bd::HashTable&amp;lt;flood_t, int&amp;gt; &amp;gt;;
+  chan-&amp;gt;channel.cached_members = new bd::HashTable&amp;lt;bd::String, memberlist*&amp;gt;;
 }
 
 static void clear_masklist(masklist *m)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -986,9 +997,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void clear_channel(struct chanset_t *chan, bool reset)
     free(chan-&amp;gt;channel.topic);
   for (m = chan-&amp;gt;channel.member; m; m = m1) {
     m1 = m-&amp;gt;next;
-    delete m-&amp;gt;floodtime;
-    delete m-&amp;gt;floodnum;
-    free(m);
+    delete_member(m);
   }
 
   clear_masklist(chan-&amp;gt;channel.ban);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1008,6 +1017,24 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void clear_channel(struct chanset_t *chan, bool reset)
   delete chan-&amp;gt;channel.floodnum;
   chan-&amp;gt;channel.floodnum = NULL;
 
+  if (chan-&amp;gt;channel.cached_members) {
+    if (chan-&amp;gt;channel.cached_members-&amp;gt;size()) {
+      bd::Array&amp;lt;bd::String&amp;gt; member_uhosts(chan-&amp;gt;channel.cached_members-&amp;gt;keys());
+      for (size_t i = 0; i &amp;lt; member_uhosts.length(); ++i) {
+        const bd::String uhost(member_uhosts[i]);
+
+        // Delete the cached member
+        m = (*chan-&amp;gt;channel.cached_members)[uhost];
+        delete_member(m);
+
+        // Remove the cached member (not technically needed as it is deleted below, but for completeness.)
+        chan-&amp;gt;channel.cached_members-&amp;gt;remove(uhost);
+      }
+    }
+    delete chan-&amp;gt;channel.cached_members;
+    chan-&amp;gt;channel.cached_members = NULL;
+  }
+
   if (reset)
     init_channel(chan, 1);
   for (size_t i = 0; i &amp;lt; MODES_PER_LINE_MAX; ++i) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1082,6 +1109,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_add(char *result, const char *newname, char *options, bool isdefault
     chan-&amp;gt;closed_ban = 0;
     chan-&amp;gt;closed_private = 1;
     chan-&amp;gt;closed_invite = 1;
+    chan-&amp;gt;voice_moderate = 1;
     chan-&amp;gt;voice_non_ident = 1;
     chan-&amp;gt;auto_delay = 5;
     chan-&amp;gt;ban_type = 3;
diff --git a/src/mod/channels.mod/channels.c b/src/mod/channels.mod/channels.c
index a079685..c00f429 100755
--- a/src/mod/channels.mod/channels.c
+++ b/src/mod/channels.mod/channels.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -567,6 +567,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void set_mode_protect(struct chanset_t *chan, char *set)
 
   if (chan-&amp;gt;mode_mns_prot &amp;amp; CHANINV &amp;amp;&amp;amp; chan-&amp;gt;closed_invite)
     chan-&amp;gt;closed_invite = 0;
+
+  if (chan-&amp;gt;mode_mns_prot &amp;amp; CHANMODER &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate)
+    chan-&amp;gt;voice_moderate = 0;
 }
 
 static void get_mode_protect(struct chanset_t *chan, char *s, size_t ssiz)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -790,6 +793,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void channels_report(int idx, int details)
         if (chan-&amp;gt;closed_private)
           strlcat(s2, "p", sizeof(s2));
       }
+      if (channel_voice(chan) &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate) {
+        strlcat(s2, "m", sizeof(s2));
+      }
 
       if (conf.bot-&amp;gt;hub || shouldjoin(chan)) {
 if (channel_active(chan)) {
diff --git a/src/mod/channels.mod/cmdschan.c b/src/mod/channels.mod/cmdschan.c
index cbc117d..c49ae5a 100755
--- a/src/mod/channels.mod/cmdschan.c
+++ b/src/mod/channels.mod/cmdschan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1258,6 +1258,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_chaninfo(int idx, char *par)
     SHOW_INT("Revenge: ", chan-&amp;gt;revenge, DEFLAG_STR, "Ignore");
     SHOW_INT("Protect-backup: ", chan-&amp;gt;protect_backup, "Do!", "Don't!");
     SHOW_INT("Voice-non-ident: ", chan-&amp;gt;voice_non_ident, "Do!", "Don't!");
+    SHOW_INT("Voice-moderate:", chan-&amp;gt;voice_moderate, NULL, "Don't!");
 
     dprintf(idx, "Flood settings:   chan bytes ctcp join kick deop nick mjoin mpub mbytes mctcp\n");
     dprintf(idx, "  number:          %3d  %4d  %3d  %3d  %3d  %3d  %3d   %3d  %3d   %4d   %3d\n",
diff --git a/src/mod/channels.mod/userchan.c b/src/mod/channels.mod/userchan.c
index 1c6bfd2..343adb4 100755
--- a/src/mod/channels.mod/userchan.c
+++ b/src/mod/channels.mod/userchan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -719,7 +719,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; flood-chan %d:%d flood-bytes %d:%d flood-ctcp %d:%d flood-join %d:%d \
 flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d flood-mjoin %d:%d \
 flood-mpub %d:%d flood-mbytes %d:%d flood-mctcp %d:%d \
 capslimit %d colorlimit %d closed-ban %d closed-invite %d closed-private %d closed-exempt %d ban-time %d \
-exempt-time %d invite-time %d voice-non-ident %d auto-delay %d \
+exempt-time %d invite-time %d voice-non-ident %d voice-moderate %d auto-delay %d \
 flood-exempt %d flood-lock-time %d knock %d fish-key { %s } \
 %cmeankicks %cenforcebans %cdynamicbans %cuserbans %cbitch %cfloodban \
 %cprivate %ccycle %cinactive %cdynamicexempts %cuserexempts \
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -763,6 +763,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; flood-exempt %d flood-lock-time %d knock %d fish-key { %s } \
         chan-&amp;gt;exempt_time,
         chan-&amp;gt;invite_time,
         chan-&amp;gt;voice_non_ident,
+        chan-&amp;gt;voice_moderate,
         chan-&amp;gt;auto_delay,
         chan-&amp;gt;flood_exempt_mode,
         chan-&amp;gt;flood_lock_time,
diff --git a/src/mod/irc.mod/chan.c b/src/mod/irc.mod/chan.c
index afa8598..628ca70 100755
--- a/src/mod/irc.mod/chan.c
+++ b/src/mod/irc.mod/chan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -285,6 +285,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static memberlist *newmember(struct chanset_t *chan, char *nick)
   return n;
 }
 
+void delete_member(memberlist* m) {
+  delete m-&amp;gt;floodtime;
+  delete m-&amp;gt;floodnum;
+  free(m);
+}
+
 static bool member_getuser(memberlist* m, bool act_on_lookup) {
   if (!m) return 0;
   if (!m-&amp;gt;user &amp;amp;&amp;amp; !m-&amp;gt;tried_getuser) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -730,9 +736,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool detect_chan_flood(memberlist* m, const char *from, struct chanset_t
           char *s1 = quickban(chan, from);
           u_addmask('b', chan, s1, conf.bot-&amp;gt;nick, "channel flood", now + (60 * chan-&amp;gt;ban_time), 0);
         } else {
-          putlog(LOG_MODES, chan-&amp;gt;dname, "Channel flood from %s -- kicking", m-&amp;gt;nick);
-          dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, response(RES_FLOOD));
-          m-&amp;gt;flags |= SENTKICK;
+          const char *response = punish_flooder(chan, m);
+          putlog(LOG_MODES, chan-&amp;gt;dname, "Channel flood from %s -- %s", m-&amp;gt;nick, response);
         }
       }
       return 1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1121,6 +1126,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void recheck_channel_modes(struct chanset_t *chan)
       mns &amp;amp;= ~CHANPRIV;
     }
   }
+  if (channel_voice(chan) &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate) {
+    pls |= CHANMODER;
+    mns &amp;amp;= ~CHANMODER;
+  }
 
   if (!(chan-&amp;gt;ircnet_status &amp;amp; CHAN_ASKEDMODES)) {
     if (pls &amp;amp; CHANINV &amp;amp;&amp;amp; !(cur &amp;amp; CHANINV))
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1944,6 +1953,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int got352or4(struct chanset_t *chan, char *user, char *host, char *nick,
     /* Store the userhost */
     simple_snprintf(m-&amp;gt;userhost, sizeof(m-&amp;gt;userhost), "%s&amp;lt; at &amp;gt;%s", user, host);
     simple_snprintf(m-&amp;gt;from, sizeof(m-&amp;gt;from), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
+    member_update_from_cache(chan, m);
 
     if (!m-&amp;gt;userip[0]) {
       if (ip)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2729,6 +2739,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotjoin(char *from, char *chname)
 m = newmember(chan, nick);
 m-&amp;gt;joined = m-&amp;gt;last = now;
 strlcpy(m-&amp;gt;userhost, uhost, sizeof(m-&amp;gt;userhost));
+        member_update_from_cache(chan, m);
         simple_snprintf(m-&amp;gt;from, sizeof(m-&amp;gt;from), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
         if (is_dotted_ip(host)) {
           strlcpy(m-&amp;gt;userip, uhost, sizeof(m-&amp;gt;userip));
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3050,7 +3061,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotnick(char *from, char *msg)
       if (rfc_casecmp(nick, msg)) {
         /* Someone on channel with old nick?! */
 if ((mm = ismember(chan, msg)))
-  killmember(chan, mm-&amp;gt;nick);
+  killmember(chan, mm-&amp;gt;nick, false);
       }
 
       strlcpy(m-&amp;gt;nick, msg, sizeof(m-&amp;gt;nick));
diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index c7b0ed3..e3d2605 100755
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -184,29 +184,56 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; detect_offense(memberlist* m, struct chanset_t *chan, char *msg)
   if (chan-&amp;gt;capslimit &amp;amp;&amp;amp; caps_count &amp;amp;&amp;amp; tot &amp;gt;= 6) {
     caps_percentage = (caps_count)/(double(tot));
     if (caps_percentage &amp;gt;= caps_limit) {
-      putlog(LOG_MODES, chan-&amp;gt;name, "Caps flood (%d%%) from %s -- kicking", int(caps_percentage * 100), m-&amp;gt;nick);
-      dprintf(DP_SERVER, "KICK %s %s :%s%s\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, response(RES_FLOOD));
-      m-&amp;gt;flags |= SENTKICK;
+      const char *response = punish_flooder(chan, m);
+      putlog(LOG_MODES, chan-&amp;gt;name, "Caps flood (%d%%) from %s -- %s", int(caps_percentage * 100), m-&amp;gt;nick, response);
       return 1;
     }
   } else if (chan-&amp;gt;colorlimit &amp;amp;&amp;amp; color_count) {
     if (color_count &amp;gt;= chan-&amp;gt;colorlimit) {
-      putlog(LOG_MODES, chan-&amp;gt;name, "Color flood (%d) from %s -- kicking", color_count, m-&amp;gt;nick);
-      dprintf(DP_SERVER, "KICK %s %s :%s%s\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, response(RES_FLOOD));
-      m-&amp;gt;flags |= SENTKICK;
+      const char *response = punish_flooder(chan, m);
+      putlog(LOG_MODES, chan-&amp;gt;name, "Color flood (%d) from %s -- %s", color_count, m-&amp;gt;nick, response);
       return 1;
     }
   }
   return 0;
 }
 
+void set_devoice(struct chanset_t *chan, memberlist* m) {
+  if (!(m-&amp;gt;flags &amp;amp; EVOICE)) {
+    putlog(LOG_DEBUG, "&amp;lt; at &amp;gt;", "Giving EVOICE flag to: %s (%s)", m-&amp;gt;nick, chan-&amp;gt;dname);
+    m-&amp;gt;flags |= EVOICE;
+  }
+}
+
+const char* punish_flooder(struct chanset_t* chan, memberlist* m, const char *reason) {
+  if (channel_voice(chan) &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate) {
+    if (!chan_sentdevoice(m)) {
+      add_mode(chan, '-', 'v', m-&amp;gt;nick);
+      m-&amp;gt;flags |= SENTDEVOICE;
+      set_devoice(chan, m);
+      return "devoicing";
+    } else {
+      return "devoiced";
+    }
+  } else {
+    if (!chan_sentkick(m)) {
+      dprintf(DP_SERVER, "KICK %s %s :%s%s\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, reason ? reason : response(RES_FLOOD));
+      m-&amp;gt;flags |= SENTKICK;
+      return "kicking";
+    } else {
+      return "kicked";
+    }
+  }
+  return "ignoring";
+}
+
 void unlock_chan(struct chanset_t *chan)
 {
   if (chan-&amp;gt;channel.drone_set_mode) {
     char buf[3] = "", *p = buf;
     if ((chan-&amp;gt;channel.drone_set_mode &amp;amp; CHANINV) &amp;amp;&amp;amp; !(chan-&amp;gt;mode_pls_prot &amp;amp; CHANINV))
       *p++ = 'i';
-    if ((chan-&amp;gt;channel.drone_set_mode &amp;amp; CHANMODER) &amp;amp;&amp;amp; !(chan-&amp;gt;mode_pls_prot &amp;amp; CHANMODER))
+    if ((chan-&amp;gt;channel.drone_set_mode &amp;amp; CHANMODER) &amp;amp;&amp;amp; !((chan-&amp;gt;mode_pls_prot &amp;amp; CHANMODER) || (channel_voice(chan) &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate)))
       *p++ = 'm';
     *p = 0;
     dprintf(DP_MODE, "MODE %s :-%s\n", chan-&amp;gt;name[0] ? chan-&amp;gt;name : chan-&amp;gt;dname, buf);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1119,7 +1146,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; new_mask(masklist *m, char *s, char *who)
 /* Removes a nick from the channel member list (returns 1 if successful)
  */
 static bool
-killmember(struct chanset_t *chan, char *nick)
+killmember(struct chanset_t *chan, char *nick, bool cacheMember)
 {
   memberlist *x = NULL, *old = NULL;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1135,10 +1162,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; killmember(struct chanset_t *chan, char *nick)
     old-&amp;gt;next = x-&amp;gt;next;
   else
     chan-&amp;gt;channel.member = x-&amp;gt;next;
-  delete x-&amp;gt;floodtime;
-  delete x-&amp;gt;floodnum;
-  free(x);
-  chan-&amp;gt;channel.members--;
+
+  if (cacheMember) {
+    x-&amp;gt;last = now;
+    // Don't delete here, will delete when it expires from the cache.
+    (*chan-&amp;gt;channel.cached_members)[x-&amp;gt;userhost] = x;
+  } else {
+    chan-&amp;gt;channel.cached_members-&amp;gt;remove(x-&amp;gt;userhost);
+    delete_member(x);
+  }
+
+  --chan-&amp;gt;channel.members;
 
   /* The following two errors should NEVER happen. We will try to correct
    * them though, to keep the bot from crashing.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1161,6 +1195,32 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; killmember(struct chanset_t *chan, char *nick)
   return 1;
 }
 
+/**
+ * Update the member with cached information from a parted/quitted member
+ */
+static void member_update_from_cache(struct chanset_t* chan, memberlist *m) {
+  using std::swap;
+
+  // Are they in the cache?
+  const bd::String userhost(m-&amp;gt;userhost);
+  if (chan-&amp;gt;channel.cached_members-&amp;gt;contains(userhost)) {
+    memberlist *cached_member = (*chan-&amp;gt;channel.cached_members)[userhost];
+
+    // Update important flood tracking information
+    swap(m-&amp;gt;floodtime, cached_member-&amp;gt;floodtime);
+    swap(m-&amp;gt;floodnum, cached_member-&amp;gt;floodnum);
+
+    // Update EVOICE flag
+    if (cached_member-&amp;gt;flags &amp;amp; EVOICE) {
+      m-&amp;gt;flags |= EVOICE;
+    }
+
+    // No longer need the cached member
+    delete_member(cached_member);
+    chan-&amp;gt;channel.cached_members-&amp;gt;remove(userhost);
+  }
+}
+
 /* Check whether I'm voice. Returns boolean 1 or 0.
  */
 bool
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1437,10 +1497,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void check_shouldjoin(struct chanset_t* chan)
 static void
 check_expired_chanstuff(struct chanset_t *chan)
 {
+  memberlist *m = NULL;
   check_shouldjoin(chan);
   if (channel_active(chan) &amp;amp;&amp;amp; shouldjoin(chan)) {
     masklist *b = NULL, *e = NULL;
-    memberlist *m = NULL, *n = NULL;
+    memberlist *n = NULL;
     struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 };
 
     if (me_op(chan)) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1502,7 +1563,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_expired_chanstuff(struct chanset_t *chan)
         if (now - m-&amp;gt;split &amp;gt; wait_split) {
           putlog(LOG_JOIN, chan-&amp;gt;dname, "%s (%s) got lost in the net-split.", m-&amp;gt;nick, m-&amp;gt;userhost);
           --(chan-&amp;gt;channel.splitmembers);
-          killmember(chan, m-&amp;gt;nick);
+          killmember(chan, m-&amp;gt;nick, false);
           continue;
         }
       }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1554,6 +1615,25 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_expired_chanstuff(struct chanset_t *chan)
     if (bot_ops &amp;amp;&amp;amp; !im_opped) {
       request_op(chan);
     }
+
+    if (role == 3) {
+      recheck_channel_modes(chan);
+    }
+  }
+  // Clear out expired cached members
+  if (chan-&amp;gt;channel.cached_members &amp;amp;&amp;amp; chan-&amp;gt;channel.cached_members-&amp;gt;size()) {
+    bd::Array&amp;lt;bd::String&amp;gt; member_uhosts(chan-&amp;gt;channel.cached_members-&amp;gt;keys());
+    for (size_t i = 0; i &amp;lt; member_uhosts.length(); ++i) {
+      const bd::String uhost(member_uhosts[i]);
+
+      m = (*chan-&amp;gt;channel.cached_members)[uhost];
+
+      // Delete the expired member
+      if (now - m-&amp;gt;last &amp;gt; wait_split) {
+        delete_member(m);
+        chan-&amp;gt;channel.cached_members-&amp;gt;remove(uhost);
+      }
+    }
   }
 }
 
diff --git a/src/mod/irc.mod/irc.h b/src/mod/irc.mod/irc.h
index 2bf4daf..995876a 100755
--- a/src/mod/irc.mod/irc.h
+++ b/src/mod/irc.mod/irc.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -92,7 +92,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool detect_chan_flood(memberlist *m, const char* from, struct chanset_t
 static bool new_mask(masklist *, char *, char *);
 static void do_closed_kick(struct chanset_t *, memberlist *);
 static char *quickban(struct chanset_t *, const char *);
-static bool killmember(struct chanset_t *chan, char *nick);
+static bool killmember(struct chanset_t *chan, char *nick, bool cacheMember = true);
+static void member_update_from_cache(struct chanset_t* chan, memberlist *m);
 static void check_lonely_channel(struct chanset_t *chan);
 static int gotmode(char *, char *);
 void unset_im(struct chanset_t* chan);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -107,6 +108,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct resolvstruct resolv_member;
 void resolve_to_rbl(struct chanset_t *chan, const char *host, struct resolvstruct *r = NULL);
 static void do_mask(struct chanset_t *chan, masklist *m, char *mask, char Mode);
 static void get_channel_masks(struct chanset_t* chan);
+const char* punish_flooder(struct chanset_t* chan, memberlist* m, const char *reason = NULL);
+void set_devoice(struct chanset_t* chan, memberlist* m);
 
 #endif /* MAKING_IRC */
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -155,6 +158,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void flush_modes();
 void reset_chan_info(struct chanset_t *);
 char *getnick(const char *, struct chanset_t *);
 void check_shouldjoin(struct chanset_t* chan);
+void delete_member(memberlist* m);
 
 extern intmax_bans, max_exempts, max_invites, max_modes;
 extern booluse_354, include_lk;
diff --git a/src/mod/irc.mod/mode.c b/src/mod/irc.mod/mode.c
index 85add9a..ecdf8ac 100755
--- a/src/mod/irc.mod/mode.c
+++ b/src/mod/irc.mod/mode.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1482,8 +1482,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; gotmode(char *from, char *msg)
 
               if (msign == '+') {
                 if (mv-&amp;gt;flags &amp;amp; EVOICE) {
-                  /* FIXME: This is a lame check, we need to expand on this more */
-                  if (!chan_master(user) &amp;amp;&amp;amp; !glob_master(user) &amp;amp;&amp;amp; !chk_voice(victim, chan)) {
+                  if (!chk_op(user, chan) &amp;amp;&amp;amp; !chk_voice(victim, chan)) {
                     dv = 1;
                   } else {
                     mv-&amp;gt;flags &amp;amp;= ~EVOICE;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1509,14 +1508,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; gotmode(char *from, char *msg)
                     add_mode(chan, '+', 'v', mparam);
                     /* if they arent +v|v and VOICER is m+ then EVOICE them */
                   } else {
-                    /* FIXME: same thing here */
-                    if (!match_my_nick(nick) &amp;amp;&amp;amp; channel_voice(chan) &amp;amp;&amp;amp; !glob_bot(user) &amp;amp;&amp;amp;
-                        (glob_master(user) || chan_master(user)) &amp;amp;&amp;amp;
+                    if (!match_my_nick(nick) &amp;amp;&amp;amp; channel_voice(chan) &amp;amp;&amp;amp;
+                        (chk_op(user, chan) || glob_bot(user)) &amp;amp;&amp;amp;
                         rfc_casecmp(nick, mparam)) {
                       /* if the user is not +q set them norEVOICE. */
-                      if (!chan_quiet(victim) &amp;amp;&amp;amp; !(mv-&amp;gt;flags &amp;amp; EVOICE)) {
-                        putlog(LOG_DEBUG, "&amp;lt; at &amp;gt;", "Giving EVOICE flag to: %s (%s)", mv-&amp;gt;nick, chan-&amp;gt;dname);
-                        mv-&amp;gt;flags |= EVOICE;
+                      if (!chan_quiet(victim)) {
+                        set_devoice(chan, mv);
                       }
                     }
                   }


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-29T15:56:04</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/763">
    <title>branch 'next' updated. v1.3.4-820-g811cadd</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/763</link>
    <description>&lt;pre&gt;The branch 'next' has been updated

Summary of changes:
 doc/UPDATES                     |    1 +
 src/chan.h                      |   16 ++++++++++
 src/mod/channels.mod/chanmisc.c |   23 ++++++++++++--
 src/mod/irc.mod/chan.c          |   10 +++++-
 src/mod/irc.mod/irc.c           |   63 ++++++++++++++++++++++++++++++++++----
 src/mod/irc.mod/irc.h           |    4 ++-
 6 files changed, 105 insertions(+), 12 deletions(-)

...from  f751f4b00745ec0be48e2643c2a5dd2bff2d0081 (commit) to (811cadd6e348c5502a83676c895d2a682981e11e)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 30fc50e642a1cb3f6490a204f3825ad81085e040
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Wed Mar 28 14:16:54 2012 -0500

    DRY member destruction (#49)

commit 3caf6fb8b9ac156e3cab9681dcc7573ec825d24d
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Wed Mar 28 14:21:00 2012 -0500

    Cache members when removing them (#49)

commit 015109ee55ea9e0fdf1b37345b715ff6c7be9ff5
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Wed Mar 28 14:57:05 2012 -0500

    Update member from cache if possible (#49)
    
    This is only updating flood/EVOICE data to avoid using stale data.

commit f0e5f2732cd694d7dc6c7df63d379737e52e474c
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Wed Mar 28 15:02:36 2012 -0500

    Remove from cached members if killing a member without caching (#49)

commit 11309bf0f3231a3a731b3a49bc4cb4819720f4b6
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Wed Mar 28 15:07:19 2012 -0500

    Delete expired cached members after wait_split (900 seconds) (#49)

commit 811cadd6e348c5502a83676c895d2a682981e11e
Merge: f751f4b 11309bf
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Wed Mar 28 16:29:25 2012 -0500

    Merge branch '49-member-caching' into next
    
    * 49-member-caching:
      Delete expired cached members after wait_split (900 seconds) (#49)
      Remove from cached members if killing a member without caching (#49)
      Update member from cache if possible (#49)
      Cache members when removing them (#49)
      DRY member destruction (#49)
    
    Conflicts:
    doc/UPDATES

-----------------------------------------------------------------------

Complete Diff

diff --git a/doc/UPDATES b/doc/UPDATES
index 488c803..9f583e1 100755
--- a/doc/UPDATES
+++ b/doc/UPDATES
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6,6 +6,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; next
   * Add chanset 'voice-moderate' which will auto set +m in '+voice' channel and devoice flooding clients instead of kick. (#48)
   * Bots now will enforce devoices made by ops (user +o) and allow any op (user +o) to revoice to disable that enforcement.
     This used to use +m to enforce/allowed revoicing.
+  * Bots will now remember a client's flood/devoice settings if they cycle (#49)
 
 1.4.0 - http://wraith.botpack.net/milestone/1.4.0
   * Updated server list, 'set -yes servers -' and 'set -yes servers6 -' to get new list.
diff --git a/src/chan.h b/src/chan.h
index ffed9cb..19deb31 100755
--- a/src/chan.h
+++ b/src/chan.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -31,6 +31,19 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct memstruct {
   bd::HashTable&amp;lt;flood_t, int&amp;gt;         *floodnum; // floodnum[FLOOD_PRIVMSG] = 1;
 } memberlist;
 
+#include &amp;lt;bdlib/src/bdlib.h&amp;gt;
+BDLIB_NS_BEGIN
+template&amp;lt;typename T&amp;gt;
+  struct Hash;
+
+template&amp;lt;&amp;gt;
+  struct Hash&amp;lt;memberlist*&amp;gt;
+  {
+    // Use memory address
+    inline size_t operator()(memberlist* m) const { return reinterpret_cast&amp;lt;size_t&amp;gt;(m); }
+  };
+BDLIB_NS_END
+
 #define CHAN_FLAG_OP1
 #define CHAN_FLAG_VOICE 2
 #define CHAN_FLAG_USER 3
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -128,6 +141,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct chan_t {
   // Shared non-member counts (JOIN/PART)
   bd::HashTable&amp;lt;bd::String, bd::HashTable&amp;lt;flood_t, time_t&amp;gt; &amp;gt;     *floodtime; // floodtime[uhost][FLOOD_PRIVMSG] = now;
   bd::HashTable&amp;lt;bd::String, bd::HashTable&amp;lt;flood_t, int&amp;gt; &amp;gt;         *floodnum; //  floodnum[uhost][FLOOD_PRIVMSG] = 1;
+
+  // Member caching to cache cyclers
+  bd::HashTable&amp;lt;bd::String, memberlist*&amp;gt; *cached_members;
 };
 
 #define CHANINV    BIT0/* +i*/
diff --git a/src/mod/channels.mod/chanmisc.c b/src/mod/channels.mod/chanmisc.c
index 609a30a..c5cd64f 100755
--- a/src/mod/channels.mod/chanmisc.c
+++ b/src/mod/channels.mod/chanmisc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -970,6 +970,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void init_channel(struct chanset_t *chan, bool reset)
   chan-&amp;gt;channel.topic = NULL;
   chan-&amp;gt;channel.floodtime = new bd::HashTable&amp;lt;bd::String, bd::HashTable&amp;lt;flood_t, time_t&amp;gt; &amp;gt;;
   chan-&amp;gt;channel.floodnum  = new bd::HashTable&amp;lt;bd::String, bd::HashTable&amp;lt;flood_t, int&amp;gt; &amp;gt;;
+  chan-&amp;gt;channel.cached_members = new bd::HashTable&amp;lt;bd::String, memberlist*&amp;gt;;
 }
 
 static void clear_masklist(masklist *m)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -996,9 +997,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void clear_channel(struct chanset_t *chan, bool reset)
     free(chan-&amp;gt;channel.topic);
   for (m = chan-&amp;gt;channel.member; m; m = m1) {
     m1 = m-&amp;gt;next;
-    delete m-&amp;gt;floodtime;
-    delete m-&amp;gt;floodnum;
-    free(m);
+    delete_member(m);
   }
 
   clear_masklist(chan-&amp;gt;channel.ban);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1018,6 +1017,24 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void clear_channel(struct chanset_t *chan, bool reset)
   delete chan-&amp;gt;channel.floodnum;
   chan-&amp;gt;channel.floodnum = NULL;
 
+  if (chan-&amp;gt;channel.cached_members) {
+    if (chan-&amp;gt;channel.cached_members-&amp;gt;size()) {
+      bd::Array&amp;lt;bd::String&amp;gt; member_uhosts(chan-&amp;gt;channel.cached_members-&amp;gt;keys());
+      for (size_t i = 0; i &amp;lt; member_uhosts.length(); ++i) {
+        const bd::String uhost(member_uhosts[i]);
+
+        // Delete the cached member
+        m = (*chan-&amp;gt;channel.cached_members)[uhost];
+        delete_member(m);
+
+        // Remove the cached member (not technically needed as it is deleted below, but for completeness.)
+        chan-&amp;gt;channel.cached_members-&amp;gt;remove(uhost);
+      }
+    }
+    delete chan-&amp;gt;channel.cached_members;
+    chan-&amp;gt;channel.cached_members = NULL;
+  }
+
   if (reset)
     init_channel(chan, 1);
   for (size_t i = 0; i &amp;lt; MODES_PER_LINE_MAX; ++i) {
diff --git a/src/mod/irc.mod/chan.c b/src/mod/irc.mod/chan.c
index 465a400..9058e89 100755
--- a/src/mod/irc.mod/chan.c
+++ b/src/mod/irc.mod/chan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -293,6 +293,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static memberlist *newmember(struct chanset_t *chan, char *nick)
   return n;
 }
 
+void delete_member(memberlist* m) {
+  delete m-&amp;gt;floodtime;
+  delete m-&amp;gt;floodnum;
+  free(m);
+}
+
 static bool member_getuser(memberlist* m, bool act_on_lookup) {
   if (!m) return 0;
   if (!m-&amp;gt;user &amp;amp;&amp;amp; !m-&amp;gt;tried_getuser) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1955,6 +1961,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int got352or4(struct chanset_t *chan, char *user, char *host, char *nick,
     /* Store the userhost */
     simple_snprintf(m-&amp;gt;userhost, sizeof(m-&amp;gt;userhost), "%s&amp;lt; at &amp;gt;%s", user, host);
     simple_snprintf(m-&amp;gt;from, sizeof(m-&amp;gt;from), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
+    member_update_from_cache(chan, m);
 
     if (!m-&amp;gt;userip[0]) {
       if (ip)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2740,6 +2747,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotjoin(char *from, char *chname)
 m = newmember(chan, nick);
 m-&amp;gt;joined = m-&amp;gt;last = now;
 strlcpy(m-&amp;gt;userhost, uhost, sizeof(m-&amp;gt;userhost));
+        member_update_from_cache(chan, m);
         simple_snprintf(m-&amp;gt;from, sizeof(m-&amp;gt;from), "%s!%s", m-&amp;gt;nick, m-&amp;gt;userhost);
         if (is_dotted_ip(host)) {
           strlcpy(m-&amp;gt;userip, uhost, sizeof(m-&amp;gt;userip));
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3061,7 +3069,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotnick(char *from, char *msg)
       if (rfc_casecmp(nick, msg)) {
         /* Someone on channel with old nick?! */
 if ((mm = ismember(chan, msg)))
-  killmember(chan, mm-&amp;gt;nick);
+  killmember(chan, mm-&amp;gt;nick, false);
       }
 
       strlcpy(m-&amp;gt;nick, msg, sizeof(m-&amp;gt;nick));
diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index e21b6d2..e3d2605 100755
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1146,7 +1146,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; new_mask(masklist *m, char *s, char *who)
 /* Removes a nick from the channel member list (returns 1 if successful)
  */
 static bool
-killmember(struct chanset_t *chan, char *nick)
+killmember(struct chanset_t *chan, char *nick, bool cacheMember)
 {
   memberlist *x = NULL, *old = NULL;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1162,10 +1162,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; killmember(struct chanset_t *chan, char *nick)
     old-&amp;gt;next = x-&amp;gt;next;
   else
     chan-&amp;gt;channel.member = x-&amp;gt;next;
-  delete x-&amp;gt;floodtime;
-  delete x-&amp;gt;floodnum;
-  free(x);
-  chan-&amp;gt;channel.members--;
+
+  if (cacheMember) {
+    x-&amp;gt;last = now;
+    // Don't delete here, will delete when it expires from the cache.
+    (*chan-&amp;gt;channel.cached_members)[x-&amp;gt;userhost] = x;
+  } else {
+    chan-&amp;gt;channel.cached_members-&amp;gt;remove(x-&amp;gt;userhost);
+    delete_member(x);
+  }
+
+  --chan-&amp;gt;channel.members;
 
   /* The following two errors should NEVER happen. We will try to correct
    * them though, to keep the bot from crashing.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1188,6 +1195,32 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; killmember(struct chanset_t *chan, char *nick)
   return 1;
 }
 
+/**
+ * Update the member with cached information from a parted/quitted member
+ */
+static void member_update_from_cache(struct chanset_t* chan, memberlist *m) {
+  using std::swap;
+
+  // Are they in the cache?
+  const bd::String userhost(m-&amp;gt;userhost);
+  if (chan-&amp;gt;channel.cached_members-&amp;gt;contains(userhost)) {
+    memberlist *cached_member = (*chan-&amp;gt;channel.cached_members)[userhost];
+
+    // Update important flood tracking information
+    swap(m-&amp;gt;floodtime, cached_member-&amp;gt;floodtime);
+    swap(m-&amp;gt;floodnum, cached_member-&amp;gt;floodnum);
+
+    // Update EVOICE flag
+    if (cached_member-&amp;gt;flags &amp;amp; EVOICE) {
+      m-&amp;gt;flags |= EVOICE;
+    }
+
+    // No longer need the cached member
+    delete_member(cached_member);
+    chan-&amp;gt;channel.cached_members-&amp;gt;remove(userhost);
+  }
+}
+
 /* Check whether I'm voice. Returns boolean 1 or 0.
  */
 bool
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1464,10 +1497,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void check_shouldjoin(struct chanset_t* chan)
 static void
 check_expired_chanstuff(struct chanset_t *chan)
 {
+  memberlist *m = NULL;
   check_shouldjoin(chan);
   if (channel_active(chan) &amp;amp;&amp;amp; shouldjoin(chan)) {
     masklist *b = NULL, *e = NULL;
-    memberlist *m = NULL, *n = NULL;
+    memberlist *n = NULL;
     struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 };
 
     if (me_op(chan)) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1529,7 +1563,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_expired_chanstuff(struct chanset_t *chan)
         if (now - m-&amp;gt;split &amp;gt; wait_split) {
           putlog(LOG_JOIN, chan-&amp;gt;dname, "%s (%s) got lost in the net-split.", m-&amp;gt;nick, m-&amp;gt;userhost);
           --(chan-&amp;gt;channel.splitmembers);
-          killmember(chan, m-&amp;gt;nick);
+          killmember(chan, m-&amp;gt;nick, false);
           continue;
         }
       }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1586,6 +1620,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_expired_chanstuff(struct chanset_t *chan)
       recheck_channel_modes(chan);
     }
   }
+  // Clear out expired cached members
+  if (chan-&amp;gt;channel.cached_members &amp;amp;&amp;amp; chan-&amp;gt;channel.cached_members-&amp;gt;size()) {
+    bd::Array&amp;lt;bd::String&amp;gt; member_uhosts(chan-&amp;gt;channel.cached_members-&amp;gt;keys());
+    for (size_t i = 0; i &amp;lt; member_uhosts.length(); ++i) {
+      const bd::String uhost(member_uhosts[i]);
+
+      m = (*chan-&amp;gt;channel.cached_members)[uhost];
+
+      // Delete the expired member
+      if (now - m-&amp;gt;last &amp;gt; wait_split) {
+        delete_member(m);
+        chan-&amp;gt;channel.cached_members-&amp;gt;remove(uhost);
+      }
+    }
+  }
 }
 
 void
diff --git a/src/mod/irc.mod/irc.h b/src/mod/irc.mod/irc.h
index 1fe176d..995876a 100755
--- a/src/mod/irc.mod/irc.h
+++ b/src/mod/irc.mod/irc.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -92,7 +92,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool detect_chan_flood(memberlist *m, const char* from, struct chanset_t
 static bool new_mask(masklist *, char *, char *);
 static void do_closed_kick(struct chanset_t *, memberlist *);
 static char *quickban(struct chanset_t *, const char *);
-static bool killmember(struct chanset_t *chan, char *nick);
+static bool killmember(struct chanset_t *chan, char *nick, bool cacheMember = true);
+static void member_update_from_cache(struct chanset_t* chan, memberlist *m);
 static void check_lonely_channel(struct chanset_t *chan);
 static int gotmode(char *, char *);
 void unset_im(struct chanset_t* chan);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -157,6 +158,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void flush_modes();
 void reset_chan_info(struct chanset_t *);
 char *getnick(const char *, struct chanset_t *);
 void check_shouldjoin(struct chanset_t* chan);
+void delete_member(memberlist* m);
 
 extern intmax_bans, max_exempts, max_invites, max_modes;
 extern booluse_354, include_lk;


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-28T21:31:19</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/762">
    <title>branch 'next' updated. v1.3.4-814-gf751f4b</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/762</link>
    <description>&lt;pre&gt;The branch 'next' has been updated

Summary of changes:
 doc/UPDATES           |    2 +-
 src/cmds.c            |    2 +-
 src/mod/irc.mod/irc.c |   32 ++++++++++++++++++++++----------
 3 files changed, 24 insertions(+), 12 deletions(-)

...from  f6745d00a1250da8eab5d742ed57beb3dc582fc0 (commit) to (f751f4b00745ec0be48e2643c2a5dd2bff2d0081)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit d361efa0b43537bad7e07079d848df51756123d8
Merge: f6745d0 2edb8dc
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 21:22:28 2012 -0500

    Merge branch 'master' into next
    
    * master:
      Fix tcl protection

commit 354eee98f6fca70fb118cf7e975bf5f3f0c03fd6
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Wed Mar 28 08:57:54 2012 -0500

    Don't unset +m when unlocking channel from flood (#48)

commit 9e5133e29c6e369dcdc4d6369b730dfe48647b69
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Wed Mar 28 08:59:58 2012 -0500

    Don't kick a user if already devoiced and -m (#48)

commit abfd6010bba7251ce32675116c490ff7dc86da4d
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Wed Mar 28 11:27:29 2012 -0500

    Enforce 'chanmode' minutely (#48)

commit 2c95cd279efe6df389215a51d810a055f349ff04
Merge: d361efa 654a4ea
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Wed Mar 28 11:44:59 2012 -0500

    Merge branch 'master' into next
    
    * master:
    
    Conflicts:
    doc/UPDATES

commit f751f4b00745ec0be48e2643c2a5dd2bff2d0081
Merge: 2c95cd2 abfd601
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Wed Mar 28 11:45:02 2012 -0500

    Merge branch '48-voice-updates' into next
    
    * 48-voice-updates:
      Enforce 'chanmode' minutely (#48)
      Don't kick a user if already devoiced and -m (#48)
      Don't unset +m when unlocking channel from flood (#48)

-----------------------------------------------------------------------

Complete Diff

diff --git a/doc/UPDATES b/doc/UPDATES
index ebdac2e..488c803 100755
--- a/doc/UPDATES
+++ b/doc/UPDATES
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6,7 +6,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; next
   * Add chanset 'voice-moderate' which will auto set +m in '+voice' channel and devoice flooding clients instead of kick. (#48)
   * Bots now will enforce devoices made by ops (user +o) and allow any op (user +o) to revoice to disable that enforcement.
     This used to use +m to enforce/allowed revoicing.
-  * Tweak limit range checking such that bot will set limit less often
 
 1.4.0 - http://wraith.botpack.net/milestone/1.4.0
   * Updated server list, 'set -yes servers -' and 'set -yes servers6 -' to get new list.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -56,6 +55,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; next
   * Add chanset 'caps-limit' to handle % of message that can be in caps before kick (#8)
   * Add chanset 'color-limit' to handle how many color codes are allowed in a message before kick (#8)
   * Add chanset 'closed-exempt' which will allow exempting non-users (who are opped or voice) from being kicked. (fixes #171)
+  * Tweak limit range checking such that bot will set limit less often
 
 1.3.4 - http://wraith.botpack.net/milestone/1.3.4
   * Fix various compile warnings with newer GCC
diff --git a/src/cmds.c b/src/cmds.c
index 429541c..93b4e40 100755
--- a/src/cmds.c
+++ b/src/cmds.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1421,7 +1421,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_botcmd(int idx, char *par)
   if ((strchr(botm, '*') &amp;amp;&amp;amp; !findbot(botm)) || !strcmp(botm, "&amp;amp;") || botm[0] == '%') {
     if (!strncasecmp(cmd, "di", 2) || (!strncasecmp(cmd, "res", 3) &amp;amp;&amp;amp; strncasecmp(cmd, "reset", 5)) || !strncasecmp(cmd, "sui", 3) || !strncasecmp(cmd, "pl", 2) || !strncasecmp(cmd, "ac", 2) ||
         !strncasecmp(cmd, "j", 1) || (!strncasecmp(cmd, "dump", 4) &amp;amp;&amp;amp; (!strncasecmp(par, "privmsg", 7) || !strncasecmp(par, "notice", 6) || !strncasecmp(par, "quit", 4))) ||
-        ((!strncasecmp(cmd, "tcl", 3) || !strncasecmp(cmd, "script", 6)) &amp;amp;&amp;amp; strstr(cmd, "privmsg"))) {
+        ((!strncasecmp(cmd, "tcl", 3) || !strncasecmp(cmd, "script", 6)) &amp;amp;&amp;amp; strstr(par, "privmsg"))) {
       dprintf(idx, "Not a good idea.\n");
       return;
     } else if (strchr(botm, '*') &amp;amp;&amp;amp; !(dcc[idx].user-&amp;gt;flags &amp;amp; USER_OWNER)) {
diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index 93a6d13..e21b6d2 100755
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -206,15 +206,23 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void set_devoice(struct chanset_t *chan, memberlist* m) {
 }
 
 const char* punish_flooder(struct chanset_t* chan, memberlist* m, const char *reason) {
-  if (channel_voice(chan) &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate &amp;amp;&amp;amp; !chan_sentdevoice(m)) {
+  if (channel_voice(chan) &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate) {
+    if (!chan_sentdevoice(m)) {
     add_mode(chan, '-', 'v', m-&amp;gt;nick);
     m-&amp;gt;flags |= SENTDEVOICE;
     set_devoice(chan, m);
     return "devoicing";
-  } else if (!chan_sentkick(m)) {
+    } else {
+      return "devoiced";
+    }
+  } else {
+    if (!chan_sentkick(m)) {
     dprintf(DP_SERVER, "KICK %s %s :%s%s\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, reason ? reason : response(RES_FLOOD));
     m-&amp;gt;flags |= SENTKICK;
     return "kicking";
+    } else {
+      return "kicked";
+    }
   }
   return "ignoring";
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -225,7 +233,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void unlock_chan(struct chanset_t *chan)
     char buf[3] = "", *p = buf;
     if ((chan-&amp;gt;channel.drone_set_mode &amp;amp; CHANINV) &amp;amp;&amp;amp; !(chan-&amp;gt;mode_pls_prot &amp;amp; CHANINV))
       *p++ = 'i';
-    if ((chan-&amp;gt;channel.drone_set_mode &amp;amp; CHANMODER) &amp;amp;&amp;amp; !(chan-&amp;gt;mode_pls_prot &amp;amp; CHANMODER))
+    if ((chan-&amp;gt;channel.drone_set_mode &amp;amp; CHANMODER) &amp;amp;&amp;amp; !((chan-&amp;gt;mode_pls_prot &amp;amp; CHANMODER) || (channel_voice(chan) &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate)))
       *p++ = 'm';
     *p = 0;
     dprintf(DP_MODE, "MODE %s :-%s\n", chan-&amp;gt;name[0] ? chan-&amp;gt;name : chan-&amp;gt;dname, buf);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1573,6 +1581,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_expired_chanstuff(struct chanset_t *chan)
     if (bot_ops &amp;amp;&amp;amp; !im_opped) {
       request_op(chan);
     }
+
+    if (role == 3) {
+      recheck_channel_modes(chan);
+    }
   }
 }
 


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-28T16:47:26</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/761">
    <title>branch 'master' updated. v1.3.4-484-g654a4ea</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/761</link>
    <description>&lt;pre&gt;The branch 'master' has been updated

Summary of changes:
 doc/UPDATES           |    1 +
 src/cmds.c            |    2 +-
 src/mod/irc.mod/irc.c |   98 +++++++++++++++++++++++++------------------------
 src/mod/irc.mod/irc.h |    2 +-
 4 files changed, 53 insertions(+), 50 deletions(-)

...from  440e69e18f95aa715f5dc1fb48fea4e6e1123067 (commit) to (654a4ea398088f5d3228add856f781b9972aa1f3)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 2edb8dcd7c1d6cd5407d957d7fce88e6f8002652
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 21:22:23 2012 -0500

    Fix tcl protection

commit 26b72e921d7ea7f0716885afe8616aed25c252f5
Merge: 2edb8dc bd71760
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Wed Mar 28 11:43:48 2012 -0500

    Merge branch '44-getin-limit'
    
    * 44-getin-limit:
      Tweak limit range checking such that bot will set limit less often
      Raise limit by 5 if 'limit 0' is set for getin_request
      Only raise limit if needed, and use proper even value
      Avoid rounding errors by adding 1 to make limit even (#44)
      Ignore all getin requests unless eligible (#44)
      Only raise limit when inviting a bot if needed (#44)

commit 654a4ea398088f5d3228add856f781b9972aa1f3
Merge: 26b72e9 268ecee
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Wed Mar 28 11:44:36 2012 -0500

    Merge branch 'getin-network-check'
    
    * getin-network-check:
      Log which network I'm on if it doesn't match
      Ignore case when comparing network
      Fix shadowed variable 'network'
      Compare to network name, not number of members in channel for getin op sanity checking

-----------------------------------------------------------------------

Complete Diff

diff --git a/doc/UPDATES b/doc/UPDATES
index 4633cfb..f996ed6 100755
--- a/doc/UPDATES
+++ b/doc/UPDATES
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -46,6 +46,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
   * Add chanset 'caps-limit' to handle % of message that can be in caps before kick (#8)
   * Add chanset 'color-limit' to handle how many color codes are allowed in a message before kick (#8)
   * Add chanset 'closed-exempt' which will allow exempting non-users (who are opped or voice) from being kicked. (fixes #171)
+  * Tweak limit range checking such that bot will set limit less often
 
 1.3.4 - http://wraith.botpack.net/milestone/1.3.4
   * Fix various compile warnings with newer GCC
diff --git a/src/cmds.c b/src/cmds.c
index 429541c..93b4e40 100755
--- a/src/cmds.c
+++ b/src/cmds.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1421,7 +1421,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_botcmd(int idx, char *par)
   if ((strchr(botm, '*') &amp;amp;&amp;amp; !findbot(botm)) || !strcmp(botm, "&amp;amp;") || botm[0] == '%') {
     if (!strncasecmp(cmd, "di", 2) || (!strncasecmp(cmd, "res", 3) &amp;amp;&amp;amp; strncasecmp(cmd, "reset", 5)) || !strncasecmp(cmd, "sui", 3) || !strncasecmp(cmd, "pl", 2) || !strncasecmp(cmd, "ac", 2) ||
         !strncasecmp(cmd, "j", 1) || (!strncasecmp(cmd, "dump", 4) &amp;amp;&amp;amp; (!strncasecmp(par, "privmsg", 7) || !strncasecmp(par, "notice", 6) || !strncasecmp(par, "quit", 4))) ||
-        ((!strncasecmp(cmd, "tcl", 3) || !strncasecmp(cmd, "script", 6)) &amp;amp;&amp;amp; strstr(cmd, "privmsg"))) {
+        ((!strncasecmp(cmd, "tcl", 3) || !strncasecmp(cmd, "script", 6)) &amp;amp;&amp;amp; strstr(par, "privmsg"))) {
       dprintf(idx, "Not a good idea.\n");
       return;
     } else if (strchr(botm, '*') &amp;amp;&amp;amp; !(dcc[idx].user-&amp;gt;flags &amp;amp; USER_OWNER)) {
diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index 16c21ea..c7b0ed3 100755
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -736,13 +736,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; getin_request(char *botnick, char *code, char *par)
     }
 
     // Does the remote bot have the same number of clients in its channel as me? And a shared member?
-    int members = atoi(tmp);
+    const char *bot_network = tmp;
 
     char *shared_nick = par[0] ? newsplit(&amp;amp;par) : NULL;
     memberlist* shared_member = shared_nick ? ismember(chan, shared_nick) : NULL;
     char *shared_host = par[0] ? newsplit(&amp;amp;par) : NULL;
-    if (!shared_nick || !shared_member || !shared_host || !((chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) == members) || strcmp(shared_host, shared_member-&amp;gt;userhost)) {
-      putlog(LOG_GETIN, "*", "opreq from %s/%s on %s - Bot seems to be on a different network???", botnick, nick, chan-&amp;gt;dname);
+    if (!shared_nick || !shared_member || !shared_host || (strcasecmp(curnetwork, bot_network)) || strcmp(shared_host, shared_member-&amp;gt;userhost)) {
+      putlog(LOG_GETIN, "*", "opreq from %s/%s on %s - Bot seems to be on a different network '%s' / me: '%s'", botnick, nick, chan-&amp;gt;dname, bot_network, curnetwork);
       return;
     }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -756,6 +756,27 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; getin_request(char *botnick, char *code, char *par)
 
     putlog(LOG_GETIN, "*", "opreq from %s/%s on %s - Opped", botnick, nick, chan-&amp;gt;dname);
   } else if (what[0] == 'i') {
+    // Should I respond to this request?
+    // If there's 18 eligible bots in the channel, and in-bots is 2, I have a 2/18 chance of replying.
+    int eligible_bots = 0;
+    for (memberlist* m = chan-&amp;gt;channel.member; m &amp;amp;&amp;amp; m-&amp;gt;nick[0]; m = m-&amp;gt;next) {
+      if (chan_hasop(m)) {
+        member_getuser(m, 0);
+        if (m-&amp;gt;user &amp;amp;&amp;amp; m-&amp;gt;user-&amp;gt;bot) {
+          ++eligible_bots;
+        }
+      }
+    }
+
+    if (!eligible_bots) {
+      return;
+    }
+
+    if (!((randint(eligible_bots) + 1) &amp;lt;= static_cast&amp;lt;unsigned int&amp;gt;(in_bots))) {
+      // Not my turn
+      return;
+    }
+
     if (mem) {
       putlog(LOG_GETIN, "*", "inreq from %s/%s for %s - %s is already on %s", botnick, nick, chan-&amp;gt;dname, nick, chan-&amp;gt;dname);
       return;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -783,38 +804,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; getin_request(char *botnick, char *code, char *par)
       return;
     }
 
-    // Should I respond to this request?
-    // If there's 18 eligible bots in the channel, and in-bots is 2, I have a 2/18 chance of replying.
-    int eligible_bots = 0;
-    for (memberlist* m = chan-&amp;gt;channel.member; m &amp;amp;&amp;amp; m-&amp;gt;nick[0]; m = m-&amp;gt;next) {
-      if (chan_hasop(m)) {
-        member_getuser(m, 0);
-        if (m-&amp;gt;user &amp;amp;&amp;amp; m-&amp;gt;user-&amp;gt;bot) {
-          ++eligible_bots;
-        }
-      }
-    }
-
-    if (!eligible_bots) {
-      return;
-    }
-
-    if (!((randint(eligible_bots) + 1) &amp;lt;= static_cast&amp;lt;unsigned int&amp;gt;(in_bots))) {
-      // Not my turn
-      return;
-    }
 
     bool sendi = 0;
 
     if (chan-&amp;gt;channel.maxmembers) {
-      int lim = (chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) + 5, curlim = chan-&amp;gt;channel.maxmembers;
-      if (curlim &amp;lt; lim) {
-        char s2[6] = "";
-
-        sendi = 1;
-        simple_snprintf(s2, sizeof(s2), "%d", lim);
-        add_mode(chan, '+', 'l', s2);
-        putlog(LOG_GETIN, "*", "inreq from %s/%s for %s - Raised limit to %d", botnick, nick, chan-&amp;gt;dname, lim);
+      if (raise_limit(chan, 5)) {
+        putlog(LOG_GETIN, "*", "inreq from %s/%s for %s - Raised limit", botnick, nick, chan-&amp;gt;dname);
       }
     }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1004,7 +999,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; request_op(struct chanset_t *chan)
   }
 
   /* first scan for bots on my server, ask first found for ops */
-  simple_snprintf(s, sizeof(s), "gi o %s %s %d %s %s", chan-&amp;gt;dname, botname, (chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers), shared_member-&amp;gt;nick, shared_member-&amp;gt;userhost);
+  simple_snprintf(s, sizeof(s), "gi o %s %s %s %s %s", chan-&amp;gt;dname, botname, curnetwork, shared_member-&amp;gt;nick, shared_member-&amp;gt;userhost);
 
   /* look for bots 0-1 hops away */
   for (i2 = 0; i2 &amp;lt; i; i2++) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1394,32 +1389,39 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_netfight(struct chanset_t *chan)
   chan-&amp;gt;channel.fighting = 0;   /* we put this here because we need to clear it once per min */
 }
 
-void
-raise_limit(struct chanset_t *chan)
+bool
+raise_limit(struct chanset_t *chan, int default_limitraise)
 {
   if (!chan || !me_op(chan))
-    return;
+    return false;
 
   /* Don't bother setting limit if the user has set a protect -l */
   if (chan-&amp;gt;mode_mns_prot &amp;amp; CHANLIMIT)
-    return;
+    return false;
 
-  int nl = (chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) + chan-&amp;gt;limitraise;/* new limit */
-  int i = chan-&amp;gt;limitraise &amp;gt;&amp;gt; 2;/* DIV 4 */
+  const int limitraise = (chan-&amp;gt;limitraise ? ((chan-&amp;gt;limitraise % 2 == 0) ? chan-&amp;gt;limitraise : (chan-&amp;gt;limitraise + 1)) : default_limitraise);
+  if (limitraise) {
+    const int nl = (chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) + limitraise;/* new limit */
+    const int i = limitraise &amp;gt;&amp;gt; 2;/* DIV 4 */
   /* if the newlimit will be in the range made by these vars, dont change. */
-  int ul = nl + i;/* upper limit */
-  int ll = nl - i;/* lower limit */
+    const int ul = nl + i;/* upper limit */
+    const int ll = nl - i;/* lower limit */
 
-  if ((chan-&amp;gt;channel.maxmembers &amp;gt; ll) &amp;amp;&amp;amp; (chan-&amp;gt;channel.maxmembers &amp;lt; ul))
-    return;                     /* the current limit is in the range, so leave it. */
+    if ((chan-&amp;gt;channel.maxmembers &amp;gt;= ll) &amp;amp;&amp;amp; (chan-&amp;gt;channel.maxmembers &amp;lt;= ul)) {
+      return false;                     /* the current limit is in the range, so leave it. */
+    }
 
   if (nl != chan-&amp;gt;channel.maxmembers) {
     char s[6] = "";
 
     simple_snprintf(s, sizeof(s), "%d", nl);
     add_mode(chan, '+', 'l', s);
+
+      return true;
+    }
   }
 
+  return false;
 }
 
 void check_shouldjoin(struct chanset_t* chan)
diff --git a/src/mod/irc.mod/irc.h b/src/mod/irc.mod/irc.h
index 1cd32fc..2bf4daf 100755
--- a/src/mod/irc.mod/irc.h
+++ b/src/mod/irc.mod/irc.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -146,7 +146,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; inline void check_this_mask(const char type, struct chanset_t *chan, char *mask,
 }
 
 void check_this_user(char *, int, char *);
-void raise_limit(struct chanset_t *);
+bool raise_limit(struct chanset_t *, int default_limitraise = 0);
 void enforce_closed(struct chanset_t *);
 void recheck_channel(struct chanset_t *, int);
 void recheck_channel_modes(struct chanset_t *);


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-28T16:47:16</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/760">
    <title>branch 'next' updated. v1.3.4-805-gf6745d0</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/760</link>
    <description>&lt;pre&gt;The branch 'next' has been updated

Summary of changes:
 doc/UPDATES           |    1 +
 src/mod/irc.mod/irc.c |   34 ++++++++++++++++++----------------
 src/mod/irc.mod/irc.h |    2 +-
 3 files changed, 20 insertions(+), 17 deletions(-)

...from  a5e8ae87930399fff30d26e1775f0ac3859b39cd (commit) to (f6745d00a1250da8eab5d742ed57beb3dc582fc0)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 124248581f2fc655c8c2f9e6a5673917f48a820c
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 20:30:50 2012 -0500

    Only raise limit if needed, and use proper even value

commit 171200baa34e67199be70578dfd391f0716d4a43
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 20:32:29 2012 -0500

    Raise limit by 5 if 'limit 0' is set for getin_request

commit bd7176052a9f7248ff550139f3ccc46f1db7ee19
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 20:43:19 2012 -0500

    Tweak limit range checking such that bot will set limit less often

commit f6745d00a1250da8eab5d742ed57beb3dc582fc0
Merge: a5e8ae8 bd71760
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 20:46:18 2012 -0500

    Merge branch '44-getin-limit' into next
    
    * 44-getin-limit:
      Tweak limit range checking such that bot will set limit less often
      Raise limit by 5 if 'limit 0' is set for getin_request
      Only raise limit if needed, and use proper even value
    
    Conflicts:
    doc/UPDATES

-----------------------------------------------------------------------

Complete Diff

diff --git a/doc/UPDATES b/doc/UPDATES
index 3923929..ebdac2e 100755
--- a/doc/UPDATES
+++ b/doc/UPDATES
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6,6 +6,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; next
   * Add chanset 'voice-moderate' which will auto set +m in '+voice' channel and devoice flooding clients instead of kick. (#48)
   * Bots now will enforce devoices made by ops (user +o) and allow any op (user +o) to revoice to disable that enforcement.
     This used to use +m to enforce/allowed revoicing.
+  * Tweak limit range checking such that bot will set limit less often
 
 1.4.0 - http://wraith.botpack.net/milestone/1.4.0
   * Updated server list, 'set -yes servers -' and 'set -yes servers6 -' to get new list.
diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index 74122d5..93a6d13 100755
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -827,7 +827,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; getin_request(char *botnick, char *code, char *par)
     bool sendi = 0;
 
     if (chan-&amp;gt;channel.maxmembers) {
-      if (raise_limit(chan)) {
+      if (raise_limit(chan, 5)) {
         putlog(LOG_GETIN, "*", "inreq from %s/%s for %s - Raised limit", botnick, nick, chan-&amp;gt;dname);
       }
     }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1409,7 +1409,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_netfight(struct chanset_t *chan)
 }
 
 bool
-raise_limit(struct chanset_t *chan)
+raise_limit(struct chanset_t *chan, int default_limitraise)
 {
   if (!chan || !me_op(chan))
     return false;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1418,14 +1418,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; raise_limit(struct chanset_t *chan)
   if (chan-&amp;gt;mode_mns_prot &amp;amp; CHANLIMIT)
     return false;
 
-  const int nl = (chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) + chan-&amp;gt;limitraise;/* new limit */
-  const int limitraise = (chan-&amp;gt;limitraise % 2 == 0) ? chan-&amp;gt;limitraise : (chan-&amp;gt;limitraise + 1);
+  const int limitraise = (chan-&amp;gt;limitraise ? ((chan-&amp;gt;limitraise % 2 == 0) ? chan-&amp;gt;limitraise : (chan-&amp;gt;limitraise + 1)) : default_limitraise);
+  if (limitraise) {
+    const int nl = (chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) + limitraise;/* new limit */
   const int i = limitraise &amp;gt;&amp;gt; 2;/* DIV 4 */
   /* if the newlimit will be in the range made by these vars, dont change. */
   const int ul = nl + i;/* upper limit */
   const int ll = nl - i;/* lower limit */
 
-  if ((chan-&amp;gt;channel.maxmembers &amp;gt; ll) &amp;amp;&amp;amp; (chan-&amp;gt;channel.maxmembers &amp;lt; ul)) {
+    if ((chan-&amp;gt;channel.maxmembers &amp;gt;= ll) &amp;amp;&amp;amp; (chan-&amp;gt;channel.maxmembers &amp;lt;= ul)) {
     return false;                     /* the current limit is in the range, so leave it. */
   }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1437,6 +1438,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; raise_limit(struct chanset_t *chan)
 
     return true;
   }
+  }
 
   return false;
 }
diff --git a/src/mod/irc.mod/irc.h b/src/mod/irc.mod/irc.h
index 793c59f..1fe176d 100755
--- a/src/mod/irc.mod/irc.h
+++ b/src/mod/irc.mod/irc.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -148,7 +148,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; inline void check_this_mask(const char type, struct chanset_t *chan, char *mask,
 }
 
 void check_this_user(char *, int, char *);
-bool raise_limit(struct chanset_t *);
+bool raise_limit(struct chanset_t *, int default_limitraise = 0);
 void enforce_closed(struct chanset_t *);
 void recheck_channel(struct chanset_t *, int);
 void recheck_channel_modes(struct chanset_t *);


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-28T01:48:22</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/759">
    <title>branch 'next' updated. v1.3.4-801-ga5e8ae8</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/759</link>
    <description>&lt;pre&gt;The branch 'next' has been updated

Summary of changes:
 doc/UPDATES                     |    4 ++--
 doc/help.txt                    |    4 ++--
 src/cmds.c                      |    3 ++-
 src/mod/channels.mod/chanmisc.c |    6 +++---
 src/mod/channels.mod/userchan.c |    2 +-
 src/mod/irc.mod/chan.c          |    2 +-
 src/mod/irc.mod/irc.c           |    4 ++--
 src/mod/irc.mod/mode.c          |    8 ++++----
 8 files changed, 17 insertions(+), 16 deletions(-)

...from  cdd56e8535cfa460e822012f4581ed9d93afadaf (commit) to (a5e8ae87930399fff30d26e1775f0ac3859b39cd)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 1cf674c88a24768eb747229e7e2ffb6a89e39c8b
Merge: cdd56e8 173a773
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 15:07:27 2012 -0500

    Merge branch 'master' into next
    
    * master:
      Protect tcl/script commands

commit 56ee085e78258488f41b4d48cbb456f3eea49f32
Merge: 1cf674c 8094d5b
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 15:17:36 2012 -0500

    Merge branch 'master' into next
    
    * master:

commit 731862fc1ea5deb678fe993060f2ebb7bde9c33d
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 17:07:01 2012 -0500

    Revert "Merge branch 'set-list-new-value' into next"
    
    This reverts commit 3a8375bf318221e18c5de5a9e1eaa53660d8600b, reversing
    changes made to 3cbbd3c8bbca858aeb93246b67bab7c275ccee81.

commit 0e14f41294ef83ffbb3730088ed488af4c42ba0f
Merge: 731862f f4dae73
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 17:07:21 2012 -0500

    Merge branch 'set-list-new-value' into next
    
    * set-list-new-value:
      Lessen variable name format length
      Don't format var type if not needed
      Show proper value when adding to a list
      Display value when removing/adding to a list
      DRY displaying set data
      Don't pad botnick when using botset

commit 570631ddf9d449afb2485cc8b63025703175c3c5
Merge: 0e14f41 0dea3f5
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 18:45:29 2012 -0500

    Merge branch 'master' into next
    
    * master:
      Use consistent type format for caps-limit/color-limit

commit 4e5948a9699b12eecb3d0e815a31a30b54cee0c0
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 18:54:07 2012 -0500

    Ignore case when comparing network
    
      irc.efnet.pl: EFNet
      irc.servercentral.net: EFnet

commit 94372a678979170ce5da47e5258fe72362c61543
Merge: 570631d 4e5948a
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 18:54:30 2012 -0500

    Merge branch 'getin-network-check' into next
    
    * getin-network-check:
      Ignore case when comparing network

commit 268ecee8fe5becd15984d35d084dc0c4873e7b74
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 18:55:17 2012 -0500

    Log which network I'm on if it doesn't match

commit 0bd496922c9d1816d72632f20aa4efbc0d84e562
Merge: 94372a6 268ecee
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 18:55:21 2012 -0500

    Merge branch 'getin-network-check' into next
    
    * getin-network-check:
      Log which network I'm on if it doesn't match

commit a5e8ae87930399fff30d26e1775f0ac3859b39cd
Merge: 0bd4969 440e69e
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 19:06:40 2012 -0500

    Merge branch 'master' into next
    
    * master:
      Fix wrong nick getting logged for revenge deflags

-----------------------------------------------------------------------

Complete Diff

diff --git a/doc/UPDATES b/doc/UPDATES
index d73edb7..3923929 100755
--- a/doc/UPDATES
+++ b/doc/UPDATES
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -52,8 +52,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; next
   * Bot will now lockdown channel (+im) if a drone flood is detected (#37)
     * Add chansets 'flood-mchan', 'flood-mbytes', 'flood-mctcp' to control reactions to mass floods (#37)
   * Remove unneeded chanset 'nomassjoin'
-  * Add chanset 'capslimit' to handle % of message that can be in caps before kick (#8)
-  * Add chanset 'colorlimit' to handle how many color codes are allowed in a message before kick (#8)
+  * Add chanset 'caps-limit' to handle % of message that can be in caps before kick (#8)
+  * Add chanset 'color-limit' to handle how many color codes are allowed in a message before kick (#8)
   * Add chanset 'closed-exempt' which will allow exempting non-users (who are opped or voice) from being kicked. (fixes #171)
 
 1.3.4 - http://wraith.botpack.net/milestone/1.3.4
diff --git a/doc/help.txt b/doc/help.txt
index 21f0073..22f7b0b 100644
--- a/doc/help.txt
+++ b/doc/help.txt
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -369,10 +369,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: link%{+a}, newhub%{-}
                           enforce +p as well. The point is to notice the chan
                           and bots when an /invite is done. This is useful in 
                           seeing when a shell is hijacked ;)
-        $bcapslimit$b         If this is set, any +f bots will kick a client for using
+        $bcaps-limit$b        If this is set, any +f bots will kick a client for using
                           too many caps. This is a percentage (0-100) of how much of
                           their message can be caps before being kicked.
-        $bcolorlimit$b        If this is set, any +f bot will kick the client for
+        $bcolor-limit$b       If this is set, any +f bot will kick the client for
                           excess color codes. The setting is how many color/bold
                           character codes the message may contain before being kicked.
         $bban-time$b          Set here how long temporary bans will last (in
diff --git a/src/cmds.c b/src/cmds.c
index 8fb73a7..429541c 100755
--- a/src/cmds.c
+++ b/src/cmds.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1420,7 +1420,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_botcmd(int idx, char *par)
   // Restrict dangerous mass commands ('botcmd *' (any *) or 'botcmd &amp;amp;')
   if ((strchr(botm, '*') &amp;amp;&amp;amp; !findbot(botm)) || !strcmp(botm, "&amp;amp;") || botm[0] == '%') {
     if (!strncasecmp(cmd, "di", 2) || (!strncasecmp(cmd, "res", 3) &amp;amp;&amp;amp; strncasecmp(cmd, "reset", 5)) || !strncasecmp(cmd, "sui", 3) || !strncasecmp(cmd, "pl", 2) || !strncasecmp(cmd, "ac", 2) ||
-        !strncasecmp(cmd, "j", 1) || (!strncasecmp(cmd, "dump", 4) &amp;amp;&amp;amp; (!strncasecmp(par, "privmsg", 7) || !strncasecmp(par, "notice", 6) || !strncasecmp(par, "quit", 4)))) {
+        !strncasecmp(cmd, "j", 1) || (!strncasecmp(cmd, "dump", 4) &amp;amp;&amp;amp; (!strncasecmp(par, "privmsg", 7) || !strncasecmp(par, "notice", 6) || !strncasecmp(par, "quit", 4))) ||
+        ((!strncasecmp(cmd, "tcl", 3) || !strncasecmp(cmd, "script", 6)) &amp;amp;&amp;amp; strstr(cmd, "privmsg"))) {
       dprintf(idx, "Not a good idea.\n");
       return;
     } else if (strchr(botm, '*') &amp;amp;&amp;amp; !(dcc[idx].user-&amp;gt;flags &amp;amp; USER_OWNER)) {
diff --git a/src/mod/channels.mod/chanmisc.c b/src/mod/channels.mod/chanmisc.c
index a01b40a..609a30a 100755
--- a/src/mod/channels.mod/chanmisc.c
+++ b/src/mod/channels.mod/chanmisc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -426,13 +426,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
       i++;
       if (i &amp;gt;= items) {
         if (result)
-          strlcpy(result, "channel capslimit needs argument", RESULT_LEN);
+          strlcpy(result, "channel caps-limit needs argument", RESULT_LEN);
         return ERROR;
       }
       int capslimit = atoi(item[i]);
       if (capslimit &amp;gt; 100 || capslimit &amp;lt; 0 || item[i][0] == '-') {
         if (result)
-          strlcpy(result, "channel capslimit out of range (0-100)", RESULT_LEN);
+          strlcpy(result, "channel caps-limit out of range (0-100)", RESULT_LEN);
         return ERROR;
       }
       chan-&amp;gt;capslimit = capslimit;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -440,7 +440,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
       i++;
       if (i &amp;gt;= items) {
         if (result)
-          strlcpy(result, "channel colorlimit needs argument", RESULT_LEN);
+          strlcpy(result, "channel color-limit needs argument", RESULT_LEN);
         return ERROR;
       }
       chan-&amp;gt;colorlimit = atoi(item[i]);
diff --git a/src/mod/channels.mod/userchan.c b/src/mod/channels.mod/userchan.c
index cf251c3..343adb4 100755
--- a/src/mod/channels.mod/userchan.c
+++ b/src/mod/channels.mod/userchan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -841,7 +841,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void write_chans_compat(bd::Stream&amp;amp; stream, int idx)
 bad-cookie %d manop %d mdop %d mop %d limit %d \
 flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
 flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d \
-capslimit %d colorlimit %d closed-ban %d closed-invite %d closed-private %d ban-time %d \
+caps-limit %d color-limit %d closed-ban %d closed-invite %d closed-private %d ban-time %d \
 exempt-time %d invite-time %d voice-non-ident %d auto-delay %d \
 %cenforcebans %cdynamicbans %cuserbans %cbitch \
 %cprivate %ccycle %cinactive %cdynamicexempts %cuserexempts \
diff --git a/src/mod/irc.mod/chan.c b/src/mod/irc.mod/chan.c
index 8e2b568..465a400 100755
--- a/src/mod/irc.mod/chan.c
+++ b/src/mod/irc.mod/chan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3006,7 +3006,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotkick(char *from, char *origmsg)
         } else {
           if (m-&amp;gt;user) {
             char tmp[128] = "";
-            simple_snprintf(tmp, sizeof(tmp), "Kicked bot %s on %s", m-&amp;gt;nick, chan-&amp;gt;dname);
+            simple_snprintf(tmp, sizeof(tmp), "Kicked bot %s on %s", mv-&amp;gt;nick, chan-&amp;gt;dname);
             deflag_user(m-&amp;gt;user, DEFLAG_EVENT_REVENGE_KICK, tmp, chan);
           }
         }
diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index a5f6c87..74122d5 100755
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -760,8 +760,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; getin_request(char *botnick, char *code, char *par)
     char *shared_nick = par[0] ? newsplit(&amp;amp;par) : NULL;
     memberlist* shared_member = shared_nick ? ismember(chan, shared_nick) : NULL;
     char *shared_host = par[0] ? newsplit(&amp;amp;par) : NULL;
-    if (!shared_nick || !shared_member || !shared_host || (strcmp(curnetwork, bot_network)) || strcmp(shared_host, shared_member-&amp;gt;userhost)) {
-      putlog(LOG_GETIN, "*", "opreq from %s/%s on %s - Bot seems to be on a different network '%s'", botnick, nick, chan-&amp;gt;dname, bot_network);
+    if (!shared_nick || !shared_member || !shared_host || (strcasecmp(curnetwork, bot_network)) || strcmp(shared_host, shared_member-&amp;gt;userhost)) {
+      putlog(LOG_GETIN, "*", "opreq from %s/%s on %s - Bot seems to be on a different network '%s' / me: '%s'", botnick, nick, chan-&amp;gt;dname, bot_network, curnetwork);
       return;
     }
 
diff --git a/src/mod/irc.mod/mode.c b/src/mod/irc.mod/mode.c
index b211ba8..ecdf8ac 100755
--- a/src/mod/irc.mod/mode.c
+++ b/src/mod/irc.mod/mode.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -725,7 +725,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; got_deop(struct chanset_t *chan, memberlist *m, memberlist *mv, char *isserver)
       } else {
         if (m-&amp;gt;user) {
           char tmp[128] = "";
-          simple_snprintf(tmp, sizeof(tmp), "Deopped bot %s on %s", m-&amp;gt;nick, chan-&amp;gt;dname);
+          simple_snprintf(tmp, sizeof(tmp), "Deopped bot %s on %s", mv-&amp;gt;nick, chan-&amp;gt;dname);
           deflag_user(m-&amp;gt;user, DEFLAG_EVENT_REVENGE_DEOP, tmp, chan);
         }
       }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -748,14 +748,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; got_ban(struct chanset_t *chan, memberlist *m, char *mask, char *isserver)
 
   // Make an array of all matching users
   bd::Array&amp;lt;memberlist*&amp;gt; matchedUserMembers;
-  bool matched_bot = false;
+  memberlist *matched_bot = NULL;
 
   for (memberlist *mv = chan-&amp;gt;channel.member; mv &amp;amp;&amp;amp; mv-&amp;gt;nick[0]; mv = mv-&amp;gt;next) {
     member_getuser(mv);
     if (mv-&amp;gt;user) {
       if ((wild_match(mask, mv-&amp;gt;from) || match_cidr(mask, mv-&amp;gt;from))) {
         if (!matched_bot &amp;amp;&amp;amp; mv != m &amp;amp;&amp;amp; mv-&amp;gt;user-&amp;gt;bot) {
-          matched_bot = true;
+          matched_bot = mv;
         }
         if (mv-&amp;gt;user &amp;amp;&amp;amp; !isexempted(chan, mv-&amp;gt;from)) {
           matchedUserMembers &amp;lt;&amp;lt; mv;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -772,7 +772,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; got_ban(struct chanset_t *chan, memberlist *m, char *mask, char *isserver)
     } else {
       if (m-&amp;gt;user) {
         char tmp[128] = "";
-        simple_snprintf(tmp, sizeof(tmp), "Banned bot %s (%s) on %s", m-&amp;gt;nick, mask, chan-&amp;gt;dname);
+        simple_snprintf(tmp, sizeof(tmp), "Banned bot %s (%s) on %s", matched_bot-&amp;gt;nick, mask, chan-&amp;gt;dname);
         deflag_user(m-&amp;gt;user, DEFLAG_EVENT_REVENGE_BAN, tmp, chan);
       }
     }


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-28T00:07:30</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/758">
    <title>branch 'master' updated. v1.3.4-471-g440e69e</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/758</link>
    <description>&lt;pre&gt;The branch 'master' has been updated

Summary of changes:
 doc/UPDATES                     |    4 +-
 doc/help.txt                    |    4 +-
 src/cmds.c                      |    3 +-
 src/mod/channels.mod/chanmisc.c |   38 +++++++++++-----------
 src/mod/channels.mod/channels.c |   16 ----------
 src/mod/channels.mod/userchan.c |    2 +-
 src/mod/irc.mod/chan.c          |    2 +-
 src/mod/irc.mod/irc.c           |    9 ++---
 src/mod/irc.mod/mode.c          |    8 ++--
 src/set.c                       |   64 +++++++++++++++++++++++++++++---------
 10 files changed, 84 insertions(+), 66 deletions(-)

...from  c821e8d29797675b4c2fdf5d3cf78d00d0449b34 (commit) to (440e69e18f95aa715f5dc1fb48fea4e6e1123067)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 173a7738f00a9db1322c500bf0fb1b6ffbdd4bb7
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 15:07:22 2012 -0500

    Protect tcl/script commands

commit 8094d5b12fd2a53ae9ee4b8d4fe90db576333052
Merge: 173a773 b61a2bb
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 15:17:22 2012 -0500

    Merge branch 'flood-tweaks'
    
    * flood-tweaks:
      Update default flood settings
      Don't punish words 6 chars or less for CAPS
      Only bail out of offense check if there's no color check as well

commit ecd7ba788a4de968390ed45c0a45d12d84ab4366
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Sun Nov 27 12:54:40 2011 -0600

    Don't pad botnick when using botset

commit 491a9cb697b5703b755c1bd10cd91c2b76519f23
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Sun Nov 27 13:48:29 2011 -0600

    DRY displaying set data

commit cf84a0fb34bd78291d3102a1ddc1d2d874a74fbc
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Sun Nov 27 13:52:40 2011 -0600

    Display value when removing/adding to a list

commit 3b0af4a6ed0793f137517b1d98593b4abe95f073
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 19:18:36 2012 -0500

    Show proper value when adding to a list

commit b7578075533df4f0119d9f24a14b352fdaa9d890
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 19:30:21 2012 -0500

    Don't format var type if not needed

commit f4dae730b5381365e67f67527bedcad377e0c76c
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 19:34:21 2012 -0500

    Lessen variable name format length

commit 0a04cc916e43912337e725662c0ae74ebf4ebfb3
Merge: 8094d5b f4dae73
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 18:36:20 2012 -0500

    Merge branch 'set-list-new-value'
    
    * set-list-new-value:
      Lessen variable name format length
      Don't format var type if not needed
      Show proper value when adding to a list
      Display value when removing/adding to a list
      DRY displaying set data
      Don't pad botnick when using botset

commit 0dea3f5e85e16a7def0863291faaacea71642bbb
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 18:37:10 2012 -0500

    Use consistent type format for caps-limit/color-limit

commit 440e69e18f95aa715f5dc1fb48fea4e6e1123067
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 19:04:38 2012 -0500

    Fix wrong nick getting logged for revenge deflags

-----------------------------------------------------------------------

Complete Diff

diff --git a/doc/UPDATES b/doc/UPDATES
index 90ea705..4633cfb 100755
--- a/doc/UPDATES
+++ b/doc/UPDATES
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -43,8 +43,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
   * Bot will now lockdown channel (+im) if a drone flood is detected (#37)
     * Add chansets 'flood-mchan', 'flood-mbytes', 'flood-mctcp' to control reactions to mass floods (#37)
   * Remove unneeded chanset 'nomassjoin'
-  * Add chanset 'capslimit' to handle % of message that can be in caps before kick (#8)
-  * Add chanset 'colorlimit' to handle how many color codes are allowed in a message before kick (#8)
+  * Add chanset 'caps-limit' to handle % of message that can be in caps before kick (#8)
+  * Add chanset 'color-limit' to handle how many color codes are allowed in a message before kick (#8)
   * Add chanset 'closed-exempt' which will allow exempting non-users (who are opped or voice) from being kicked. (fixes #171)
 
 1.3.4 - http://wraith.botpack.net/milestone/1.3.4
diff --git a/doc/help.txt b/doc/help.txt
index fb09775..d3914a2 100644
--- a/doc/help.txt
+++ b/doc/help.txt
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -369,10 +369,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: link%{+a}, newhub%{-}
                           enforce +p as well. The point is to notice the chan
                           and bots when an /invite is done. This is useful in 
                           seeing when a shell is hijacked ;)
-        $bcapslimit$b         If this is set, any +f bots will kick a client for using
+        $bcaps-limit$b        If this is set, any +f bots will kick a client for using
                           too many caps. This is a percentage (0-100) of how much of
                           their message can be caps before being kicked.
-        $bcolorlimit$b        If this is set, any +f bot will kick the client for
+        $bcolor-limit$b       If this is set, any +f bot will kick the client for
                           excess color codes. The setting is how many color/bold
                           character codes the message may contain before being kicked.
         $bban-time$b          Set here how long temporary bans will last (in
diff --git a/src/cmds.c b/src/cmds.c
index 8fb73a7..429541c 100755
--- a/src/cmds.c
+++ b/src/cmds.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1420,7 +1420,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_botcmd(int idx, char *par)
   // Restrict dangerous mass commands ('botcmd *' (any *) or 'botcmd &amp;amp;')
   if ((strchr(botm, '*') &amp;amp;&amp;amp; !findbot(botm)) || !strcmp(botm, "&amp;amp;") || botm[0] == '%') {
     if (!strncasecmp(cmd, "di", 2) || (!strncasecmp(cmd, "res", 3) &amp;amp;&amp;amp; strncasecmp(cmd, "reset", 5)) || !strncasecmp(cmd, "sui", 3) || !strncasecmp(cmd, "pl", 2) || !strncasecmp(cmd, "ac", 2) ||
-        !strncasecmp(cmd, "j", 1) || (!strncasecmp(cmd, "dump", 4) &amp;amp;&amp;amp; (!strncasecmp(par, "privmsg", 7) || !strncasecmp(par, "notice", 6) || !strncasecmp(par, "quit", 4)))) {
+        !strncasecmp(cmd, "j", 1) || (!strncasecmp(cmd, "dump", 4) &amp;amp;&amp;amp; (!strncasecmp(par, "privmsg", 7) || !strncasecmp(par, "notice", 6) || !strncasecmp(par, "quit", 4))) ||
+        ((!strncasecmp(cmd, "tcl", 3) || !strncasecmp(cmd, "script", 6)) &amp;amp;&amp;amp; strstr(cmd, "privmsg"))) {
       dprintf(idx, "Not a good idea.\n");
       return;
     } else if (strchr(botm, '*') &amp;amp;&amp;amp; !(dcc[idx].user-&amp;gt;flags &amp;amp; USER_OWNER)) {
diff --git a/src/mod/channels.mod/chanmisc.c b/src/mod/channels.mod/chanmisc.c
index 83de7f1..630e64c 100755
--- a/src/mod/channels.mod/chanmisc.c
+++ b/src/mod/channels.mod/chanmisc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -426,13 +426,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
       i++;
       if (i &amp;gt;= items) {
         if (result)
-          strlcpy(result, "channel capslimit needs argument", RESULT_LEN);
+          strlcpy(result, "channel caps-limit needs argument", RESULT_LEN);
         return ERROR;
       }
       int capslimit = atoi(item[i]);
       if (capslimit &amp;gt; 100 || capslimit &amp;lt; 0 || item[i][0] == '-') {
         if (result)
-          strlcpy(result, "channel capslimit out of range (0-100)", RESULT_LEN);
+          strlcpy(result, "channel caps-limit out of range (0-100)", RESULT_LEN);
         return ERROR;
       }
       chan-&amp;gt;capslimit = capslimit;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -440,7 +440,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
       i++;
       if (i &amp;gt;= items) {
         if (result)
-          strlcpy(result, "channel colorlimit needs argument", RESULT_LEN);
+          strlcpy(result, "channel color-limit needs argument", RESULT_LEN);
         return ERROR;
       }
       chan-&amp;gt;colorlimit = atoi(item[i]);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1096,27 +1096,27 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_add(char *result, const char *newname, char *options, bool isdefault
     chan-&amp;gt;knock_flags = 0;
     chan-&amp;gt;flood_lock_time = 120;
     chan-&amp;gt;flood_exempt_mode = 0;
-    chan-&amp;gt;flood_pub_thr = gfld_chan_thr;
-    chan-&amp;gt;flood_pub_time = gfld_chan_time;
-    chan-&amp;gt;flood_bytes_thr = gfld_bytes_thr;
-    chan-&amp;gt;flood_bytes_time = gfld_bytes_time;
-    chan-&amp;gt;flood_ctcp_thr = gfld_ctcp_thr;
-    chan-&amp;gt;flood_ctcp_time = gfld_ctcp_time;
-    chan-&amp;gt;flood_join_thr = gfld_join_thr;
-    chan-&amp;gt;flood_join_time = gfld_join_time;
-    chan-&amp;gt;flood_deop_thr = gfld_deop_thr;
-    chan-&amp;gt;flood_deop_time = gfld_deop_time;
-    chan-&amp;gt;flood_kick_thr = gfld_kick_thr;
-    chan-&amp;gt;flood_kick_time = gfld_kick_time;
-    chan-&amp;gt;flood_nick_thr = gfld_nick_thr;
-    chan-&amp;gt;flood_nick_time = gfld_nick_time;
+    chan-&amp;gt;flood_pub_thr = 0;
+    chan-&amp;gt;flood_pub_time = 0;
+    chan-&amp;gt;flood_bytes_thr = 0;
+    chan-&amp;gt;flood_bytes_time = 0;
+    chan-&amp;gt;flood_ctcp_thr = 5;
+    chan-&amp;gt;flood_ctcp_time = 30;
+    chan-&amp;gt;flood_join_thr = 0;
+    chan-&amp;gt;flood_join_time = 0;
+    chan-&amp;gt;flood_deop_thr = 8;
+    chan-&amp;gt;flood_deop_time = 10;
+    chan-&amp;gt;flood_kick_thr = 0;
+    chan-&amp;gt;flood_kick_time = 0;
+    chan-&amp;gt;flood_nick_thr = 0;
+    chan-&amp;gt;flood_nick_time = 0;
     chan-&amp;gt;flood_mjoin_thr = 6;
     chan-&amp;gt;flood_mjoin_time = 1;
     chan-&amp;gt;capslimit = 0;
     chan-&amp;gt;colorlimit = 0;
-    chan-&amp;gt;flood_mpub_thr = 10;
+    chan-&amp;gt;flood_mpub_thr = 20;
     chan-&amp;gt;flood_mpub_time = 1;
-    chan-&amp;gt;flood_mbytes_thr = 500;
+    chan-&amp;gt;flood_mbytes_thr = 1000;
     chan-&amp;gt;flood_mbytes_time = 1;
     chan-&amp;gt;flood_mctcp_thr = 7;
     chan-&amp;gt;flood_mctcp_time = 1;
diff --git a/src/mod/channels.mod/channels.c b/src/mod/channels.mod/channels.c
index 94e70f6..a079685 100755
--- a/src/mod/channels.mod/channels.c
+++ b/src/mod/channels.mod/channels.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -61,22 +61,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static interval_t global_invite_time;
 
 static char *lastdeletedmask = NULL;
 
-/* Global flood settings */
-static int gfld_chan_thr;
-static interval_t gfld_chan_time;
-static int gfld_bytes_thr;
-static interval_t gfld_bytes_time;
-static int gfld_deop_thr = 8;
-static interval_t gfld_deop_time = 10;
-static int gfld_kick_thr;
-static interval_t gfld_kick_time;
-static int gfld_join_thr;
-static interval_t gfld_join_time;
-static int gfld_ctcp_thr = 5;
-static interval_t gfld_ctcp_time = 30;
-static intgfld_nick_thr;
-static interval_tgfld_nick_time;
-
 static int killed_bots = 0;
 
 #include "channels.h"
diff --git a/src/mod/channels.mod/userchan.c b/src/mod/channels.mod/userchan.c
index bcb0298..1c6bfd2 100755
--- a/src/mod/channels.mod/userchan.c
+++ b/src/mod/channels.mod/userchan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -840,7 +840,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void write_chans_compat(bd::Stream&amp;amp; stream, int idx)
 bad-cookie %d manop %d mdop %d mop %d limit %d \
 flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
 flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d \
-capslimit %d colorlimit %d closed-ban %d closed-invite %d closed-private %d ban-time %d \
+caps-limit %d color-limit %d closed-ban %d closed-invite %d closed-private %d ban-time %d \
 exempt-time %d invite-time %d voice-non-ident %d auto-delay %d \
 %cenforcebans %cdynamicbans %cuserbans %cbitch \
 %cprivate %ccycle %cinactive %cdynamicexempts %cuserexempts \
diff --git a/src/mod/irc.mod/chan.c b/src/mod/irc.mod/chan.c
index 1afe3bd..afa8598 100755
--- a/src/mod/irc.mod/chan.c
+++ b/src/mod/irc.mod/chan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2995,7 +2995,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int gotkick(char *from, char *origmsg)
         } else {
           if (m-&amp;gt;user) {
             char tmp[128] = "";
-            simple_snprintf(tmp, sizeof(tmp), "Kicked bot %s on %s", m-&amp;gt;nick, chan-&amp;gt;dname);
+            simple_snprintf(tmp, sizeof(tmp), "Kicked bot %s on %s", mv-&amp;gt;nick, chan-&amp;gt;dname);
             deflag_user(m-&amp;gt;user, DEFLAG_EVENT_REVENGE_KICK, tmp, chan);
           }
         }
diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index efd5381..16c21ea 100755
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -146,12 +146,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; detect_offense(memberlist* m, struct chanset_t *chan, char *msg)
       ++msg_check;
     }
 
-    if (!tot) {
-      return 0;
-    }
-
     if (tot &amp;gt;= 30) {
       hit_check = tot/5; //check in-between for hits to save waste of cpu
+    } else if (!tot &amp;amp;&amp;amp; !chan-&amp;gt;colorlimit) {
+      // Nothing to do, bail out
+      return 0;
     }
   }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -182,7 +181,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; detect_offense(memberlist* m, struct chanset_t *chan, char *msg)
     }
     ++msg;
   }
-  if (chan-&amp;gt;capslimit &amp;amp;&amp;amp; caps_count) {
+  if (chan-&amp;gt;capslimit &amp;amp;&amp;amp; caps_count &amp;amp;&amp;amp; tot &amp;gt;= 6) {
     caps_percentage = (caps_count)/(double(tot));
     if (caps_percentage &amp;gt;= caps_limit) {
       putlog(LOG_MODES, chan-&amp;gt;name, "Caps flood (%d%%) from %s -- kicking", int(caps_percentage * 100), m-&amp;gt;nick);
diff --git a/src/mod/irc.mod/mode.c b/src/mod/irc.mod/mode.c
index d85e6f9..85add9a 100755
--- a/src/mod/irc.mod/mode.c
+++ b/src/mod/irc.mod/mode.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -725,7 +725,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; got_deop(struct chanset_t *chan, memberlist *m, memberlist *mv, char *isserver)
       } else {
         if (m-&amp;gt;user) {
           char tmp[128] = "";
-          simple_snprintf(tmp, sizeof(tmp), "Deopped bot %s on %s", m-&amp;gt;nick, chan-&amp;gt;dname);
+          simple_snprintf(tmp, sizeof(tmp), "Deopped bot %s on %s", mv-&amp;gt;nick, chan-&amp;gt;dname);
           deflag_user(m-&amp;gt;user, DEFLAG_EVENT_REVENGE_DEOP, tmp, chan);
         }
       }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -748,14 +748,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; got_ban(struct chanset_t *chan, memberlist *m, char *mask, char *isserver)
 
   // Make an array of all matching users
   bd::Array&amp;lt;memberlist*&amp;gt; matchedUserMembers;
-  bool matched_bot = false;
+  memberlist *matched_bot = NULL;
 
   for (memberlist *mv = chan-&amp;gt;channel.member; mv &amp;amp;&amp;amp; mv-&amp;gt;nick[0]; mv = mv-&amp;gt;next) {
     member_getuser(mv);
     if (mv-&amp;gt;user) {
       if ((wild_match(mask, mv-&amp;gt;from) || match_cidr(mask, mv-&amp;gt;from))) {
         if (!matched_bot &amp;amp;&amp;amp; mv != m &amp;amp;&amp;amp; mv-&amp;gt;user-&amp;gt;bot) {
-          matched_bot = true;
+          matched_bot = mv;
         }
         if (mv-&amp;gt;user &amp;amp;&amp;amp; !isexempted(chan, mv-&amp;gt;from)) {
           matchedUserMembers &amp;lt;&amp;lt; mv;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -772,7 +772,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; got_ban(struct chanset_t *chan, memberlist *m, char *mask, char *isserver)
     } else {
       if (m-&amp;gt;user) {
         char tmp[128] = "";
-        simple_snprintf(tmp, sizeof(tmp), "Banned bot %s (%s) on %s", m-&amp;gt;nick, mask, chan-&amp;gt;dname);
+        simple_snprintf(tmp, sizeof(tmp), "Banned bot %s (%s) on %s", matched_bot-&amp;gt;nick, mask, chan-&amp;gt;dname);
         deflag_user(m-&amp;gt;user, DEFLAG_EVENT_REVENGE_BAN, tmp, chan);
       }
     }
diff --git a/src/set.c b/src/set.c
index aee14e7..c59d86e 100755
--- a/src/set.c
+++ b/src/set.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -937,6 +937,26 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void write_vars_and_cmdpass(bd::Stream&amp;amp; stream, int idx)
     stream &amp;lt;&amp;lt; bd::String::printf("- %s %s\n", cp-&amp;gt;name, cp-&amp;gt;pass);
 }
 
+static void display_set_value(int idx, const variable_t *var, const char *botnick, bool format = false)
+{
+  char buf[51] = "";
+
+  const char *data = NULL;
+  if (botnick) {//fetch data from bot's USERENTRY_SET
+    struct userrec *botu = get_user_by_handle(userlist, (char *) botnick);
+    const char *botdata = var_get_bot_data(botu, var-&amp;gt;name);
+    data = botdata ? botdata : NULL;
+  } else {//use global, no bot specified
+    data = var-&amp;gt;gdata ? var-&amp;gt;gdata : NULL;
+  }
+
+  if (format) {
+    simple_snprintf(buf, sizeof(buf), "(%-6s) %-16s: ", var_type_name(var-&amp;gt;flags), var-&amp;gt;name);
+  } else {
+    simple_snprintf(buf, sizeof(buf), "(%s) %s: ", var_type_name(var-&amp;gt;flags), var-&amp;gt;name);
+  }
+  dumplots(idx, buf, data ? (char *) data : (char *) "(not set)");
+}
 
 #define LIST_ADD  1
 #define LIST_RM   2
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -946,7 +966,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
   variable_t *var = NULL;
   char *name = NULL;
   const char *data = NULL, *botdata = NULL;
-  int list = 0, i = 0;
+  int list = 0;
   bool notyes = 1, wildcard = 0;
 
   if (par[0] &amp;amp;&amp;amp; !strncasecmp(par, "-yes", 4)) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1018,22 +1038,40 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
   if (botnick) {
     botu = get_user_by_handle(userlist, (char *) botnick);
     if (data)
-      dprintf(idx, "%-10s:\n", botnick);
+      dprintf(idx, "%s:\n", botnick);
     ishub = bot_hublevel(botu) == 999 ? 0 : 1;
   }
 
   if (!data) {
+    // First determine which variables are going to be shown
+    bd::Array&amp;lt;variable_t*&amp;gt; varsToShow;
+    size_t i = 0;
+
     while (vars[i].name) {
-      botdata = NULL;
-      if (!name || wildcard)//not looping all, provided with one...
-        if (vars[i].name)
+      if (!name || wildcard) {//not looping all, provided with one...
+        if (vars[i].name) {
           var = &amp;amp;vars[i]; 
+        }
+      }
 
       if (wildcard &amp;amp;&amp;amp; !wild_match(name, var-&amp;gt;name)) {
         ++i;
         continue;
       }
       
+      varsToShow &amp;lt;&amp;lt; var;
+
+      if (name &amp;amp;&amp;amp; !wildcard) {
+        break;
+      }
+      ++i;
+    }
+
+    // Then display them
+    for (i = 0; i &amp;lt; varsToShow.length(); ++i) {
+      var = varsToShow[i];
+      botdata = NULL;
+      
       if (!(var-&amp;gt;flags &amp;amp; VAR_HIDE) &amp;amp;&amp;amp; !((var-&amp;gt;flags &amp;amp; VAR_PERM) &amp;amp;&amp;amp; !isowner(dcc[idx].nick)) &amp;amp;&amp;amp; 
           !(botnick &amp;amp;&amp;amp; ((var-&amp;gt;flags &amp;amp; VAR_NOLOC) || (ishub &amp;amp;&amp;amp; (var-&amp;gt;flags &amp;amp; VAR_NOLHUB))))
          ) {//Just display the data
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1048,16 +1086,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
         else if (list &amp;amp;&amp;amp; !data)
           dprintf(idx, "%s list not set.\n", var-&amp;gt;name);
         else {
-          char buf[51] = "";
-
-          simple_snprintf(buf, sizeof(buf), "(%-6s)  %-19s:  ", var_type_name(var-&amp;gt;flags), var-&amp;gt;name);
-//        dprintf(idx, "   %-15s:   %s\n", var-&amp;gt;name, data);
-          dumplots(idx, buf, data ? (char *) data : (char *) "(not set)");
+          const bool shouldFormat = varsToShow.length() &amp;gt; 1;
+          display_set_value(idx, var, botnick, shouldFormat);
         }
       }
-      if (name &amp;amp;&amp;amp; !wildcard)
-        break;
-      ++i;
     }
   } else { // need to set it!
     if (!list &amp;amp;&amp;amp; var-&amp;gt;flags &amp;amp; VAR_LIST) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1121,6 +1153,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
           return 0;
         } else if (var_add_list(botnick, var, data)) {
           dprintf(idx, "Added '%s' to %s list.\n", data, var-&amp;gt;name);
+          display_set_value(idx, var, botnick);
           return 1;
         }
       } else if (list == LIST_RM) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1128,6 +1161,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
 
         if ((expanded_data = var_rem_list(botnick, var, data)) &amp;amp;&amp;amp; expanded_data[0]) {
           dprintf(idx, "Removed '%s' from %s list.\n", expanded_data, var-&amp;gt;name);
+          display_set_value(idx, var, botnick);
           return 1;
         } else if (!var_find_list(botnick, var, data)) {
           char *data_word = NULL;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1159,7 +1193,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
       if (botnick)
         var_set_userentry(botnick, name, data);
 
-      dprintf(idx, "%s: %s\n", name, botnick ? (!data || (data[0] == '-' &amp;amp;&amp;amp; !data[1]) ? "(not set)" : data) : (var-&amp;gt;gdata ? var-&amp;gt;gdata : "(not set)"));
+      display_set_value(idx, var, botnick);
 
       if (sdata)
         free(sdata);


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-28T00:07:16</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/757">
    <title>branch 'next' updated. v1.3.4-780-gcdd56e8</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/757</link>
    <description>&lt;pre&gt;The branch 'next' has been updated

Summary of changes:
 doc/UPDATES                     |    4 ++++
 doc/help.txt                    |    2 ++
 src/chan.h                      |    1 +
 src/mod/channels.mod/chanmisc.c |   11 +++++++++++
 src/mod/channels.mod/channels.c |    6 ++++++
 src/mod/channels.mod/cmdschan.c |    1 +
 src/mod/channels.mod/userchan.c |    3 ++-
 src/mod/irc.mod/chan.c          |    9 ++++++---
 src/mod/irc.mod/irc.c           |   37 ++++++++++++++++++++++++++++---------
 src/mod/irc.mod/irc.h           |    2 ++
 src/mod/irc.mod/mode.c          |   13 +++++--------
 11 files changed, 68 insertions(+), 21 deletions(-)

...from  26bd18a8f51a47c4391ca18b581e4220eba2e732 (commit) to (cdd56e8535cfa460e822012f4581ed9d93afadaf)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit a91ffe3c1406578f6bd4ad09e59df7e3554c5608
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 13:55:28 2012 -0500

    Add chanset 'voice-moderate' (#48)

commit 30b00340c3f87603d1d52ef06ab06efbcfc2a1ed
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 13:55:50 2012 -0500

    Auto unset 'voice-moderate' if 'chanmode -m' is set (#48)

commit 82b9bbd899ba48016bc48d5717fad81dbd3700df
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 13:57:06 2012 -0500

    Auto set +m when 'voice-moderate' is set (#48)

commit d7372b909c8f9d84e4c3a1718e8a43bb9146ba01
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 14:02:02 2012 -0500

    DRY flood punishment (#48)

commit 571b74975258409d9eebd3765d907391a6510194
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 14:07:54 2012 -0500

    Implement devoicing on flood (#48)

commit 13973888e5b7bb048132930966acbe3ba28fcc9c
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 14:11:53 2012 -0500

    Set EVOICE on abusive clients (#48)

commit a849b0ab29190b3aacc5183eb74e5fd7d5081357
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 14:12:16 2012 -0500

    Respect devoices from other bots (#48)

commit 975b5bd8868fe4e8685d9fa3c600ea9eed7ab489
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 14:12:55 2012 -0500

    Document 'voice-moderate' (#48)

commit d7f3387942a363d10f7cac7ef8defe3e548a74b0
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 14:14:40 2012 -0500

    Properly log response to flood (#48)

commit caeb36e375006ce0d4ce5d75fa97adbca054d523
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 14:26:48 2012 -0500

    Allow any user op (+o) to enable/disable EVOICE (#48)

commit dd7965a0f2ba0d59ad4a1a1359aa9c227511df6b
Merge: 26bd18a caeb36e
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 14:49:21 2012 -0500

    Merge branch '48-voice-updates' into next
    
    * 48-voice-updates:
      Allow any user op (+o) to enable/disable EVOICE (#48)
      Properly log response to flood (#48)
      Document 'voice-moderate' (#48)
      Respect devoices from other bots (#48)
      Set EVOICE on abusive clients (#48)
      Implement devoicing on flood (#48)
      DRY flood punishment (#48)
      Auto set +m when 'voice-moderate' is set (#48)
      Auto unset 'voice-moderate' if 'chanmode -m' is set (#48)
      Add chanset 'voice-moderate' (#48)
    
    Conflicts:
    doc/UPDATES

commit 68e8b2e074cd20e59c7229663512eee73e79e2de
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 14:52:13 2012 -0500

    Fix shadowed variable 'network'

commit cdd56e8535cfa460e822012f4581ed9d93afadaf
Merge: dd7965a 68e8b2e
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 14:52:19 2012 -0500

    Merge branch 'getin-network-check' into next
    
    * getin-network-check:
      Fix shadowed variable 'network'

-----------------------------------------------------------------------

Complete Diff

diff --git a/doc/UPDATES b/doc/UPDATES
index cbf786a..d73edb7 100755
--- a/doc/UPDATES
+++ b/doc/UPDATES
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2,6 +2,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; next
   * Bot will now jump from the server it's on if it is removed from the server list. (fixes a changing network bug)
   * Properly honor exemptions when kicking matched RBL clients
   * Fix LASTON not being shared
+  * Bots now again respect devoices made by other bots and will not revoice those users.
+  * Add chanset 'voice-moderate' which will auto set +m in '+voice' channel and devoice flooding clients instead of kick. (#48)
+  * Bots now will enforce devoices made by ops (user +o) and allow any op (user +o) to revoice to disable that enforcement.
+    This used to use +m to enforce/allowed revoicing.
 
 1.4.0 - http://wraith.botpack.net/milestone/1.4.0
   * Updated server list, 'set -yes servers -' and 'set -yes servers6 -' to get new list.
diff --git a/doc/help.txt b/doc/help.txt
index fb09775..21f0073 100644
--- a/doc/help.txt
+++ b/doc/help.txt
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -437,6 +437,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; See also: link%{+a}, newhub%{-}
                           channel is +protect.
         $bvoice-non-ident$b   If channel is +voice, clients without an ident will 
                           be voiced. Set to 0 to not voice clients without ident.
+        $bvoice-moderate$b    If channel is +voice, auto set +m and devoice flooders
+                          instead of kicking them. Set to 0 to disable.
  
    The following options choose how to respond to specific events.
         Each can be set as any of the specified options.
diff --git a/src/chan.h b/src/chan.h
index 3904660..ffed9cb 100755
--- a/src/chan.h
+++ b/src/chan.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -197,6 +197,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct chanset_t {
   int closed_private;
   int closed_invite;
   int closed_exempt_mode;
+  int voice_moderate;
   deflag_t bad_cookie;
   deflag_t manop;
   deflag_t mdop;
diff --git a/src/mod/channels.mod/chanmisc.c b/src/mod/channels.mod/chanmisc.c
index b29df24..a01b40a 100755
--- a/src/mod/channels.mod/chanmisc.c
+++ b/src/mod/channels.mod/chanmisc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -452,6 +452,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
         return ERROR;
       }
       chan-&amp;gt;closed_ban = atoi(item[i]);
+    } else if (!strcmp(item[i], "voice-moderate")) {
+      i++;
+      if (i &amp;gt;= items) {
+        if (result)
+          strlcpy(result, "channel voice-moderate needs argument", RESULT_LEN);
+        return ERROR;
+      }
+      chan-&amp;gt;voice_moderate = atoi(item[i]);
+      if (chan-&amp;gt;mode_mns_prot &amp;amp; CHANMODER &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate)
+        chan-&amp;gt;voice_moderate = 0;
     } else if (!strcmp(item[i], "closed-invite")) {
       i++;
       if (i &amp;gt;= items) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1082,6 +1092,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_add(char *result, const char *newname, char *options, bool isdefault
     chan-&amp;gt;closed_ban = 0;
     chan-&amp;gt;closed_private = 1;
     chan-&amp;gt;closed_invite = 1;
+    chan-&amp;gt;voice_moderate = 1;
     chan-&amp;gt;voice_non_ident = 1;
     chan-&amp;gt;auto_delay = 5;
     chan-&amp;gt;ban_type = 3;
diff --git a/src/mod/channels.mod/channels.c b/src/mod/channels.mod/channels.c
index a079685..c00f429 100755
--- a/src/mod/channels.mod/channels.c
+++ b/src/mod/channels.mod/channels.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -567,6 +567,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void set_mode_protect(struct chanset_t *chan, char *set)
 
   if (chan-&amp;gt;mode_mns_prot &amp;amp; CHANINV &amp;amp;&amp;amp; chan-&amp;gt;closed_invite)
     chan-&amp;gt;closed_invite = 0;
+
+  if (chan-&amp;gt;mode_mns_prot &amp;amp; CHANMODER &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate)
+    chan-&amp;gt;voice_moderate = 0;
 }
 
 static void get_mode_protect(struct chanset_t *chan, char *s, size_t ssiz)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -790,6 +793,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void channels_report(int idx, int details)
         if (chan-&amp;gt;closed_private)
           strlcat(s2, "p", sizeof(s2));
       }
+      if (channel_voice(chan) &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate) {
+        strlcat(s2, "m", sizeof(s2));
+      }
 
       if (conf.bot-&amp;gt;hub || shouldjoin(chan)) {
 if (channel_active(chan)) {
diff --git a/src/mod/channels.mod/cmdschan.c b/src/mod/channels.mod/cmdschan.c
index cbc117d..c49ae5a 100755
--- a/src/mod/channels.mod/cmdschan.c
+++ b/src/mod/channels.mod/cmdschan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1258,6 +1258,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_chaninfo(int idx, char *par)
     SHOW_INT("Revenge: ", chan-&amp;gt;revenge, DEFLAG_STR, "Ignore");
     SHOW_INT("Protect-backup: ", chan-&amp;gt;protect_backup, "Do!", "Don't!");
     SHOW_INT("Voice-non-ident: ", chan-&amp;gt;voice_non_ident, "Do!", "Don't!");
+    SHOW_INT("Voice-moderate:", chan-&amp;gt;voice_moderate, NULL, "Don't!");
 
     dprintf(idx, "Flood settings:   chan bytes ctcp join kick deop nick mjoin mpub mbytes mctcp\n");
     dprintf(idx, "  number:          %3d  %4d  %3d  %3d  %3d  %3d  %3d   %3d  %3d   %4d   %3d\n",
diff --git a/src/mod/channels.mod/userchan.c b/src/mod/channels.mod/userchan.c
index bcb0298..cf251c3 100755
--- a/src/mod/channels.mod/userchan.c
+++ b/src/mod/channels.mod/userchan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -719,7 +719,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; flood-chan %d:%d flood-bytes %d:%d flood-ctcp %d:%d flood-join %d:%d \
 flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d flood-mjoin %d:%d \
 flood-mpub %d:%d flood-mbytes %d:%d flood-mctcp %d:%d \
 capslimit %d colorlimit %d closed-ban %d closed-invite %d closed-private %d closed-exempt %d ban-time %d \
-exempt-time %d invite-time %d voice-non-ident %d auto-delay %d \
+exempt-time %d invite-time %d voice-non-ident %d voice-moderate %d auto-delay %d \
 flood-exempt %d flood-lock-time %d knock %d fish-key { %s } \
 %cmeankicks %cenforcebans %cdynamicbans %cuserbans %cbitch %cfloodban \
 %cprivate %ccycle %cinactive %cdynamicexempts %cuserexempts \
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -763,6 +763,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; flood-exempt %d flood-lock-time %d knock %d fish-key { %s } \
         chan-&amp;gt;exempt_time,
         chan-&amp;gt;invite_time,
         chan-&amp;gt;voice_non_ident,
+        chan-&amp;gt;voice_moderate,
         chan-&amp;gt;auto_delay,
         chan-&amp;gt;flood_exempt_mode,
         chan-&amp;gt;flood_lock_time,
diff --git a/src/mod/irc.mod/chan.c b/src/mod/irc.mod/chan.c
index 74bac47..8e2b568 100755
--- a/src/mod/irc.mod/chan.c
+++ b/src/mod/irc.mod/chan.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -738,9 +738,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool detect_chan_flood(memberlist* m, const char *from, struct chanset_t
           char *s1 = quickban(chan, from);
           u_addmask('b', chan, s1, conf.bot-&amp;gt;nick, "channel flood", now + (60 * chan-&amp;gt;ban_time), 0);
         } else {
-          putlog(LOG_MODES, chan-&amp;gt;dname, "Channel flood from %s -- kicking", m-&amp;gt;nick);
-          dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, response(RES_FLOOD));
-          m-&amp;gt;flags |= SENTKICK;
+          const char *response = punish_flooder(chan, m);
+          putlog(LOG_MODES, chan-&amp;gt;dname, "Channel flood from %s -- %s", m-&amp;gt;nick, response);
         }
       }
       return 1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1129,6 +1128,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void recheck_channel_modes(struct chanset_t *chan)
       mns &amp;amp;= ~CHANPRIV;
     }
   }
+  if (channel_voice(chan) &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate) {
+    pls |= CHANMODER;
+    mns &amp;amp;= ~CHANMODER;
+  }
 
   if (!(chan-&amp;gt;ircnet_status &amp;amp; CHAN_ASKEDMODES)) {
     if (pls &amp;amp; CHANINV &amp;amp;&amp;amp; !(cur &amp;amp; CHANINV))
diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index 6071298..a5f6c87 100755
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -184,22 +184,41 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; detect_offense(memberlist* m, struct chanset_t *chan, char *msg)
   if (chan-&amp;gt;capslimit &amp;amp;&amp;amp; caps_count &amp;amp;&amp;amp; tot &amp;gt;= 6) {
     caps_percentage = (caps_count)/(double(tot));
     if (caps_percentage &amp;gt;= caps_limit) {
-      putlog(LOG_MODES, chan-&amp;gt;name, "Caps flood (%d%%) from %s -- kicking", int(caps_percentage * 100), m-&amp;gt;nick);
-      dprintf(DP_SERVER, "KICK %s %s :%s%s\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, response(RES_FLOOD));
-      m-&amp;gt;flags |= SENTKICK;
+      const char *response = punish_flooder(chan, m);
+      putlog(LOG_MODES, chan-&amp;gt;name, "Caps flood (%d%%) from %s -- %s", int(caps_percentage * 100), m-&amp;gt;nick, response);
       return 1;
     }
   } else if (chan-&amp;gt;colorlimit &amp;amp;&amp;amp; color_count) {
     if (color_count &amp;gt;= chan-&amp;gt;colorlimit) {
-      putlog(LOG_MODES, chan-&amp;gt;name, "Color flood (%d) from %s -- kicking", color_count, m-&amp;gt;nick);
-      dprintf(DP_SERVER, "KICK %s %s :%s%s\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, response(RES_FLOOD));
-      m-&amp;gt;flags |= SENTKICK;
+      const char *response = punish_flooder(chan, m);
+      putlog(LOG_MODES, chan-&amp;gt;name, "Color flood (%d) from %s -- %s", color_count, m-&amp;gt;nick, response);
       return 1;
     }
   }
   return 0;
 }
 
+void set_devoice(struct chanset_t *chan, memberlist* m) {
+  if (!(m-&amp;gt;flags &amp;amp; EVOICE)) {
+    putlog(LOG_DEBUG, "&amp;lt; at &amp;gt;", "Giving EVOICE flag to: %s (%s)", m-&amp;gt;nick, chan-&amp;gt;dname);
+    m-&amp;gt;flags |= EVOICE;
+  }
+}
+
+const char* punish_flooder(struct chanset_t* chan, memberlist* m, const char *reason) {
+  if (channel_voice(chan) &amp;amp;&amp;amp; chan-&amp;gt;voice_moderate &amp;amp;&amp;amp; !chan_sentdevoice(m)) {
+    add_mode(chan, '-', 'v', m-&amp;gt;nick);
+    m-&amp;gt;flags |= SENTDEVOICE;
+    set_devoice(chan, m);
+    return "devoicing";
+  } else if (!chan_sentkick(m)) {
+    dprintf(DP_SERVER, "KICK %s %s :%s%s\n", chan-&amp;gt;name, m-&amp;gt;nick, kickprefix, reason ? reason : response(RES_FLOOD));
+    m-&amp;gt;flags |= SENTKICK;
+    return "kicking";
+  }
+  return "ignoring";
+}
+
 void unlock_chan(struct chanset_t *chan)
 {
   if (chan-&amp;gt;channel.drone_set_mode) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -736,13 +755,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; getin_request(char *botnick, char *code, char *par)
     }
 
     // Does the remote bot have the same number of clients in its channel as me? And a shared member?
-    const char *network = tmp;
+    const char *bot_network = tmp;
 
     char *shared_nick = par[0] ? newsplit(&amp;amp;par) : NULL;
     memberlist* shared_member = shared_nick ? ismember(chan, shared_nick) : NULL;
     char *shared_host = par[0] ? newsplit(&amp;amp;par) : NULL;
-    if (!shared_nick || !shared_member || !shared_host || (strcmp(curnetwork, network)) || strcmp(shared_host, shared_member-&amp;gt;userhost)) {
-      putlog(LOG_GETIN, "*", "opreq from %s/%s on %s - Bot seems to be on a different network???", botnick, nick, chan-&amp;gt;dname);
+    if (!shared_nick || !shared_member || !shared_host || (strcmp(curnetwork, bot_network)) || strcmp(shared_host, shared_member-&amp;gt;userhost)) {
+      putlog(LOG_GETIN, "*", "opreq from %s/%s on %s - Bot seems to be on a different network '%s'", botnick, nick, chan-&amp;gt;dname, bot_network);
       return;
     }
 
diff --git a/src/mod/irc.mod/irc.h b/src/mod/irc.mod/irc.h
index 3e55539..793c59f 100755
--- a/src/mod/irc.mod/irc.h
+++ b/src/mod/irc.mod/irc.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -107,6 +107,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct resolvstruct resolv_member;
 void resolve_to_rbl(struct chanset_t *chan, const char *host, struct resolvstruct *r = NULL);
 static void do_mask(struct chanset_t *chan, masklist *m, char *mask, char Mode);
 static void get_channel_masks(struct chanset_t* chan);
+const char* punish_flooder(struct chanset_t* chan, memberlist* m, const char *reason = NULL);
+void set_devoice(struct chanset_t* chan, memberlist* m);
 
 #endif /* MAKING_IRC */
 
diff --git a/src/mod/irc.mod/mode.c b/src/mod/irc.mod/mode.c
index d85e6f9..b211ba8 100755
--- a/src/mod/irc.mod/mode.c
+++ b/src/mod/irc.mod/mode.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1482,8 +1482,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; gotmode(char *from, char *msg)
 
               if (msign == '+') {
                 if (mv-&amp;gt;flags &amp;amp; EVOICE) {
-                  /* FIXME: This is a lame check, we need to expand on this more */
-                  if (!chan_master(user) &amp;amp;&amp;amp; !glob_master(user) &amp;amp;&amp;amp; !chk_voice(victim, chan)) {
+                  if (!chk_op(user, chan) &amp;amp;&amp;amp; !chk_voice(victim, chan)) {
                     dv = 1;
                   } else {
                     mv-&amp;gt;flags &amp;amp;= ~EVOICE;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1509,14 +1508,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; gotmode(char *from, char *msg)
                     add_mode(chan, '+', 'v', mparam);
                     /* if they arent +v|v and VOICER is m+ then EVOICE them */
                   } else {
-                    /* FIXME: same thing here */
-                    if (!match_my_nick(nick) &amp;amp;&amp;amp; channel_voice(chan) &amp;amp;&amp;amp; !glob_bot(user) &amp;amp;&amp;amp;
-                        (glob_master(user) || chan_master(user)) &amp;amp;&amp;amp;
+                    if (!match_my_nick(nick) &amp;amp;&amp;amp; channel_voice(chan) &amp;amp;&amp;amp;
+                        (chk_op(user, chan) || glob_bot(user)) &amp;amp;&amp;amp;
                         rfc_casecmp(nick, mparam)) {
                       /* if the user is not +q set them norEVOICE. */
-                      if (!chan_quiet(victim) &amp;amp;&amp;amp; !(mv-&amp;gt;flags &amp;amp; EVOICE)) {
-                        putlog(LOG_DEBUG, "&amp;lt; at &amp;gt;", "Giving EVOICE flag to: %s (%s)", mv-&amp;gt;nick, chan-&amp;gt;dname);
-                        mv-&amp;gt;flags |= EVOICE;
+                      if (!chan_quiet(victim)) {
+                        set_devoice(chan, mv);
                       }
                     }
                   }


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-27T19:53:49</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/756">
    <title>branch 'next' updated. v1.3.4-767-g26bd18a</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/756</link>
    <description>&lt;pre&gt;The branch 'next' has been updated

Summary of changes:
 src/mod/irc.mod/irc.c |   18 ++++++++++--------
 1 files changed, 10 insertions(+), 8 deletions(-)

...from  d4b48f29f25c823dc46934f237be70065179cce9 (commit) to (26bd18a8f51a47c4391ca18b581e4220eba2e732)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 26832d2d9953a1cf054bcc8cc398486d187f945e
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 13:38:45 2012 -0500

    Avoid rounding errors by adding 1 to make limit even (#44)

commit 8bee0f35f96886f66d69c8a2bef488e161a1a2ab
Merge: d4b48f2 26832d2
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 13:38:55 2012 -0500

    Merge branch '44-getin-limit' into next
    
    * 44-getin-limit:
      Avoid rounding errors by adding 1 to make limit even (#44)

commit adcd3ec38c3bce9277a09bb740161cbb2092ea54
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 13:39:34 2012 -0500

    Compare to network name, not number of members in channel for getin op sanity checking

commit 26bd18a8f51a47c4391ca18b581e4220eba2e732
Merge: 8bee0f3 adcd3ec
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Tue Mar 27 13:39:51 2012 -0500

    Merge branch 'getin-network-check' into next
    
    * getin-network-check:
      Compare to network name, not number of members in channel for getin op sanity checking

-----------------------------------------------------------------------

Complete Diff

diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index 12ce200..6071298 100755
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -736,12 +736,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; getin_request(char *botnick, char *code, char *par)
     }
 
     // Does the remote bot have the same number of clients in its channel as me? And a shared member?
-    int members = atoi(tmp);
+    const char *network = tmp;
 
     char *shared_nick = par[0] ? newsplit(&amp;amp;par) : NULL;
     memberlist* shared_member = shared_nick ? ismember(chan, shared_nick) : NULL;
     char *shared_host = par[0] ? newsplit(&amp;amp;par) : NULL;
-    if (!shared_nick || !shared_member || !shared_host || !((chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) == members) || strcmp(shared_host, shared_member-&amp;gt;userhost)) {
+    if (!shared_nick || !shared_member || !shared_host || (strcmp(curnetwork, network)) || strcmp(shared_host, shared_member-&amp;gt;userhost)) {
       putlog(LOG_GETIN, "*", "opreq from %s/%s on %s - Bot seems to be on a different network???", botnick, nick, chan-&amp;gt;dname);
       return;
     }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -999,7 +999,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; request_op(struct chanset_t *chan)
   }
 
   /* first scan for bots on my server, ask first found for ops */
-  simple_snprintf(s, sizeof(s), "gi o %s %s %d %s %s", chan-&amp;gt;dname, botname, (chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers), shared_member-&amp;gt;nick, shared_member-&amp;gt;userhost);
+  simple_snprintf(s, sizeof(s), "gi o %s %s %s %s %s", chan-&amp;gt;dname, botname, curnetwork, shared_member-&amp;gt;nick, shared_member-&amp;gt;userhost);
 
   /* look for bots 0-1 hops away */
   for (i2 = 0; i2 &amp;lt; i; i2++) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1399,14 +1399,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; raise_limit(struct chanset_t *chan)
   if (chan-&amp;gt;mode_mns_prot &amp;amp; CHANLIMIT)
     return false;
 
-  int nl = (chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) + chan-&amp;gt;limitraise;/* new limit */
-  int i = chan-&amp;gt;limitraise &amp;gt;&amp;gt; 2;/* DIV 4 */
+  const int nl = (chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) + chan-&amp;gt;limitraise;/* new limit */
+  const int limitraise = (chan-&amp;gt;limitraise % 2 == 0) ? chan-&amp;gt;limitraise : (chan-&amp;gt;limitraise + 1);
+  const int i = limitraise &amp;gt;&amp;gt; 2;/* DIV 4 */
   /* if the newlimit will be in the range made by these vars, dont change. */
-  int ul = nl + i;/* upper limit */
-  int ll = nl - i;/* lower limit */
+  const int ul = nl + i;/* upper limit */
+  const int ll = nl - i;/* lower limit */
 
-  if ((chan-&amp;gt;channel.maxmembers &amp;gt; ll) &amp;amp;&amp;amp; (chan-&amp;gt;channel.maxmembers &amp;lt; ul))
+  if ((chan-&amp;gt;channel.maxmembers &amp;gt; ll) &amp;amp;&amp;amp; (chan-&amp;gt;channel.maxmembers &amp;lt; ul)) {
     return false;                     /* the current limit is in the range, so leave it. */
+  }
 
   if (nl != chan-&amp;gt;channel.maxmembers) {
     char s[6] = "";


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-27T18:43:02</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/755">
    <title>branch 'next' updated. v1.3.4-763-gd4b48f2</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/755</link>
    <description>&lt;pre&gt;The branch 'next' has been updated

Summary of changes:
 src/mod/irc.mod/irc.c |   41 +++++++++++++++++++++--------------------
 1 files changed, 21 insertions(+), 20 deletions(-)

...from  7f30778952f01cf0ef4dd01c612c50d2f87754de (commit) to (d4b48f29f25c823dc46934f237be70065179cce9)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 7367f656ddf9a3ce4453fcff84ab3498591e8d3b
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 23:46:54 2012 -0500

    Ignore all getin requests unless eligible (#44)

commit d4b48f29f25c823dc46934f237be70065179cce9
Merge: 7f30778 7367f65
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 23:46:59 2012 -0500

    Merge branch '44-getin-limit' into next
    
    * 44-getin-limit:
      Ignore all getin requests unless eligible (#44)

-----------------------------------------------------------------------

Complete Diff

diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index d2c60a3..12ce200 100755
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -756,6 +756,27 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; getin_request(char *botnick, char *code, char *par)
 
     putlog(LOG_GETIN, "*", "opreq from %s/%s on %s - Opped", botnick, nick, chan-&amp;gt;dname);
   } else if (what[0] == 'i') {
+    // Should I respond to this request?
+    // If there's 18 eligible bots in the channel, and in-bots is 2, I have a 2/18 chance of replying.
+    int eligible_bots = 0;
+    for (memberlist* m = chan-&amp;gt;channel.member; m &amp;amp;&amp;amp; m-&amp;gt;nick[0]; m = m-&amp;gt;next) {
+      if (chan_hasop(m)) {
+        member_getuser(m, 0);
+        if (m-&amp;gt;user &amp;amp;&amp;amp; m-&amp;gt;user-&amp;gt;bot) {
+          ++eligible_bots;
+        }
+      }
+    }
+
+    if (!eligible_bots) {
+      return;
+    }
+
+    if (!((randint(eligible_bots) + 1) &amp;lt;= static_cast&amp;lt;unsigned int&amp;gt;(in_bots))) {
+      // Not my turn
+      return;
+    }
+
     if (mem) {
       putlog(LOG_GETIN, "*", "inreq from %s/%s for %s - %s is already on %s", botnick, nick, chan-&amp;gt;dname, nick, chan-&amp;gt;dname);
       return;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -783,26 +804,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; getin_request(char *botnick, char *code, char *par)
       return;
     }
 
-    // Should I respond to this request?
-    // If there's 18 eligible bots in the channel, and in-bots is 2, I have a 2/18 chance of replying.
-    int eligible_bots = 0;
-    for (memberlist* m = chan-&amp;gt;channel.member; m &amp;amp;&amp;amp; m-&amp;gt;nick[0]; m = m-&amp;gt;next) {
-      if (chan_hasop(m)) {
-        member_getuser(m, 0);
-        if (m-&amp;gt;user &amp;amp;&amp;amp; m-&amp;gt;user-&amp;gt;bot) {
-          ++eligible_bots;
-        }
-      }
-    }
-
-    if (!eligible_bots) {
-      return;
-    }
-
-    if (!((randint(eligible_bots) + 1) &amp;lt;= static_cast&amp;lt;unsigned int&amp;gt;(in_bots))) {
-      // Not my turn
-      return;
-    }
 
     bool sendi = 0;
 


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-27T04:47:24</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/754">
    <title>branch 'next' updated. v1.3.4-761-g7f30778</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/754</link>
    <description>&lt;pre&gt;The branch 'next' has been updated

Summary of changes:
 src/mod/irc.mod/irc.c |   21 +++++++++------------
 src/mod/irc.mod/irc.h |    2 +-
 2 files changed, 10 insertions(+), 13 deletions(-)

...from  3a8375bf318221e18c5de5a9e1eaa53660d8600b (commit) to (7f30778952f01cf0ef4dd01c612c50d2f87754de)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 02db2453a6f4e2b1fbe7b854409246366ffe8b43
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 20:00:42 2012 -0500

    Only raise limit when inviting a bot if needed (#44)

commit 7f30778952f01cf0ef4dd01c612c50d2f87754de
Merge: 3a8375b 02db245
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 20:03:05 2012 -0500

    Merge branch '44-getin-limit' into next
    
    * 44-getin-limit:
      Only raise limit when inviting a bot if needed (#44)

-----------------------------------------------------------------------

Complete Diff

diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index 16c21ea..d2c60a3 100755
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -807,14 +807,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; getin_request(char *botnick, char *code, char *par)
     bool sendi = 0;
 
     if (chan-&amp;gt;channel.maxmembers) {
-      int lim = (chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) + 5, curlim = chan-&amp;gt;channel.maxmembers;
-      if (curlim &amp;lt; lim) {
-        char s2[6] = "";
-
-        sendi = 1;
-        simple_snprintf(s2, sizeof(s2), "%d", lim);
-        add_mode(chan, '+', 'l', s2);
-        putlog(LOG_GETIN, "*", "inreq from %s/%s for %s - Raised limit to %d", botnick, nick, chan-&amp;gt;dname, lim);
+      if (raise_limit(chan)) {
+        putlog(LOG_GETIN, "*", "inreq from %s/%s for %s - Raised limit", botnick, nick, chan-&amp;gt;dname);
       }
     }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1394,15 +1388,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; check_netfight(struct chanset_t *chan)
   chan-&amp;gt;channel.fighting = 0;   /* we put this here because we need to clear it once per min */
 }
 
-void
+bool
 raise_limit(struct chanset_t *chan)
 {
   if (!chan || !me_op(chan))
-    return;
+    return false;
 
   /* Don't bother setting limit if the user has set a protect -l */
   if (chan-&amp;gt;mode_mns_prot &amp;amp; CHANLIMIT)
-    return;
+    return false;
 
   int nl = (chan-&amp;gt;channel.members - chan-&amp;gt;channel.splitmembers) + chan-&amp;gt;limitraise;/* new limit */
   int i = chan-&amp;gt;limitraise &amp;gt;&amp;gt; 2;/* DIV 4 */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1411,15 +1405,18 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; raise_limit(struct chanset_t *chan)
   int ll = nl - i;/* lower limit */
 
   if ((chan-&amp;gt;channel.maxmembers &amp;gt; ll) &amp;amp;&amp;amp; (chan-&amp;gt;channel.maxmembers &amp;lt; ul))
-    return;                     /* the current limit is in the range, so leave it. */
+    return false;                     /* the current limit is in the range, so leave it. */
 
   if (nl != chan-&amp;gt;channel.maxmembers) {
     char s[6] = "";
 
     simple_snprintf(s, sizeof(s), "%d", nl);
     add_mode(chan, '+', 'l', s);
+
+    return true;
   }
 
+  return false;
 }
 
 void check_shouldjoin(struct chanset_t* chan)
diff --git a/src/mod/irc.mod/irc.h b/src/mod/irc.mod/irc.h
index 1cd32fc..3e55539 100755
--- a/src/mod/irc.mod/irc.h
+++ b/src/mod/irc.mod/irc.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -146,7 +146,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; inline void check_this_mask(const char type, struct chanset_t *chan, char *mask,
 }
 
 void check_this_user(char *, int, char *);
-void raise_limit(struct chanset_t *);
+bool raise_limit(struct chanset_t *);
 void enforce_closed(struct chanset_t *);
 void recheck_channel(struct chanset_t *, int);
 void recheck_channel_modes(struct chanset_t *);


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-27T01:03:26</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/753">
    <title>branch 'next' updated. v1.3.4-759-g3a8375b</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/753</link>
    <description>&lt;pre&gt;The branch 'next' has been updated

Summary of changes:
 src/flags.c                     |    2 +-
 src/mod/channels.mod/chanmisc.c |   32 +++++++++++-----------
 src/mod/channels.mod/channels.c |   16 -----------
 src/mod/irc.mod/irc.c           |    9 +++---
 src/set.c                       |   53 ++++++++++++++++++++++++++++----------
 5 files changed, 60 insertions(+), 52 deletions(-)

...from  8bccf5fa8bea3cf04b3faa322f13393aedcd311d (commit) to (3a8375bf318221e18c5de5a9e1eaa53660d8600b)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 67bb61d7307ef7f36f8da8e847fe2dfe137ad2cb
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 11:27:23 2012 -0500

    Only bail out of offense check if there's no color check as well

commit 2a6af5a53bd1e20d189f2dd83d6e69832e151168
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 11:28:48 2012 -0500

    Don't punish words 6 chars or less for CAPS

commit b61a2bb8b76cbc23b961f96a95040b417ca240cb
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 13:18:32 2012 -0500

    Update default flood settings
    
    flood-ctcp 5:30
    flood-deop 8:10
    flood-mjoin 6:1
    flood-mpub 20:1
    flood-mbytes 1000:1
    flood-mctcp 7:1

commit e1841024696406050f8400087b29165c37407206
Merge: 8bccf5f b61a2bb
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 13:18:58 2012 -0500

    Merge branch 'flood-tweaks' into next
    
    * flood-tweaks:
      Update default flood settings
      Don't punish words 6 chars or less for CAPS
      Only bail out of offense check if there's no color check as well

commit 9207880984aac83af555defe955038f06739384a
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 13:21:13 2012 -0500

    Revert "Merge branch 'set-list-new-value' into next"
    
    This reverts commit e1ca1a6ada4d614477b641fde458d89cb596a1c7, reversing
    changes made to a4582efb94d2fbb20d8363b21466c2b4bb6d35c3.

commit 5a15dfd838c6e3664aa7af19d94dfe7bb8142f58
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Sun Nov 27 12:54:40 2011 -0600

    * Don't pad botnick when using botset

commit 0cdcb71a8b098df4064471e31a36eac2cfab515b
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Sun Nov 27 13:48:29 2011 -0600

    * DRY displaying set data

commit 95dd83a4db69b553ce156b73a481c1a32373ba47
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Sun Nov 27 13:52:40 2011 -0600

    * Display value when removing/adding to a list

commit 3cbbd3c8bbca858aeb93246b67bab7c275ccee81
Merge: 9207880 c821e8d
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 16:05:05 2012 -0500

    Merge branch 'master' into next
    
    * master:
      Raise buffer for deflag reasons

commit e9f2037c09b824f587ade248dcf7b5bfb43deead
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 19:18:36 2012 -0500

    Show proper value when adding to a list

commit 0a4eb43cde151cf29eff46cee723852169f23909
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 19:30:21 2012 -0500

    Don't format var type if not needed

commit 4f9de15958b4a852004bce1112318138cc9d17c7
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 19:34:21 2012 -0500

    Lessen variable name format length

commit 3a8375bf318221e18c5de5a9e1eaa53660d8600b
Merge: 3cbbd3c 4f9de15
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 19:34:41 2012 -0500

    Merge branch 'set-list-new-value' into next
    
    * set-list-new-value:
      Lessen variable name format length
      Don't format var type if not needed
      Show proper value when adding to a list
      * Display value when removing/adding to a list
      * DRY displaying set data
      * Don't pad botnick when using botset

-----------------------------------------------------------------------

Complete Diff

diff --git a/src/flags.c b/src/flags.c
index 2afd00a..53580eb 100755
--- a/src/flags.c
+++ b/src/flags.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -585,7 +585,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; deflag_t deflag_translate(const char *buf)
 
 void deflag_user(struct userrec *u, deflag_event_t why, const char *msg, const struct chanset_t *chan)
 {
-  char tmp[30] = "", tmp2[1024] = "";
+  char tmp[50] = "", tmp2[1024] = "";
   struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };
   int which = 0;
 
diff --git a/src/mod/channels.mod/chanmisc.c b/src/mod/channels.mod/chanmisc.c
index 83de7f1..b29df24 100755
--- a/src/mod/channels.mod/chanmisc.c
+++ b/src/mod/channels.mod/chanmisc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1096,27 +1096,27 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int channel_add(char *result, const char *newname, char *options, bool isdefault
     chan-&amp;gt;knock_flags = 0;
     chan-&amp;gt;flood_lock_time = 120;
     chan-&amp;gt;flood_exempt_mode = 0;
-    chan-&amp;gt;flood_pub_thr = gfld_chan_thr;
-    chan-&amp;gt;flood_pub_time = gfld_chan_time;
-    chan-&amp;gt;flood_bytes_thr = gfld_bytes_thr;
-    chan-&amp;gt;flood_bytes_time = gfld_bytes_time;
-    chan-&amp;gt;flood_ctcp_thr = gfld_ctcp_thr;
-    chan-&amp;gt;flood_ctcp_time = gfld_ctcp_time;
-    chan-&amp;gt;flood_join_thr = gfld_join_thr;
-    chan-&amp;gt;flood_join_time = gfld_join_time;
-    chan-&amp;gt;flood_deop_thr = gfld_deop_thr;
-    chan-&amp;gt;flood_deop_time = gfld_deop_time;
-    chan-&amp;gt;flood_kick_thr = gfld_kick_thr;
-    chan-&amp;gt;flood_kick_time = gfld_kick_time;
-    chan-&amp;gt;flood_nick_thr = gfld_nick_thr;
-    chan-&amp;gt;flood_nick_time = gfld_nick_time;
+    chan-&amp;gt;flood_pub_thr = 0;
+    chan-&amp;gt;flood_pub_time = 0;
+    chan-&amp;gt;flood_bytes_thr = 0;
+    chan-&amp;gt;flood_bytes_time = 0;
+    chan-&amp;gt;flood_ctcp_thr = 5;
+    chan-&amp;gt;flood_ctcp_time = 30;
+    chan-&amp;gt;flood_join_thr = 0;
+    chan-&amp;gt;flood_join_time = 0;
+    chan-&amp;gt;flood_deop_thr = 8;
+    chan-&amp;gt;flood_deop_time = 10;
+    chan-&amp;gt;flood_kick_thr = 0;
+    chan-&amp;gt;flood_kick_time = 0;
+    chan-&amp;gt;flood_nick_thr = 0;
+    chan-&amp;gt;flood_nick_time = 0;
     chan-&amp;gt;flood_mjoin_thr = 6;
     chan-&amp;gt;flood_mjoin_time = 1;
     chan-&amp;gt;capslimit = 0;
     chan-&amp;gt;colorlimit = 0;
-    chan-&amp;gt;flood_mpub_thr = 10;
+    chan-&amp;gt;flood_mpub_thr = 20;
     chan-&amp;gt;flood_mpub_time = 1;
-    chan-&amp;gt;flood_mbytes_thr = 500;
+    chan-&amp;gt;flood_mbytes_thr = 1000;
     chan-&amp;gt;flood_mbytes_time = 1;
     chan-&amp;gt;flood_mctcp_thr = 7;
     chan-&amp;gt;flood_mctcp_time = 1;
diff --git a/src/mod/channels.mod/channels.c b/src/mod/channels.mod/channels.c
index 94e70f6..a079685 100755
--- a/src/mod/channels.mod/channels.c
+++ b/src/mod/channels.mod/channels.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -61,22 +61,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static interval_t global_invite_time;
 
 static char *lastdeletedmask = NULL;
 
-/* Global flood settings */
-static int gfld_chan_thr;
-static interval_t gfld_chan_time;
-static int gfld_bytes_thr;
-static interval_t gfld_bytes_time;
-static int gfld_deop_thr = 8;
-static interval_t gfld_deop_time = 10;
-static int gfld_kick_thr;
-static interval_t gfld_kick_time;
-static int gfld_join_thr;
-static interval_t gfld_join_time;
-static int gfld_ctcp_thr = 5;
-static interval_t gfld_ctcp_time = 30;
-static intgfld_nick_thr;
-static interval_tgfld_nick_time;
-
 static int killed_bots = 0;
 
 #include "channels.h"
diff --git a/src/mod/irc.mod/irc.c b/src/mod/irc.mod/irc.c
index efd5381..16c21ea 100755
--- a/src/mod/irc.mod/irc.c
+++ b/src/mod/irc.mod/irc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -146,12 +146,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; detect_offense(memberlist* m, struct chanset_t *chan, char *msg)
       ++msg_check;
     }
 
-    if (!tot) {
-      return 0;
-    }
-
     if (tot &amp;gt;= 30) {
       hit_check = tot/5; //check in-between for hits to save waste of cpu
+    } else if (!tot &amp;amp;&amp;amp; !chan-&amp;gt;colorlimit) {
+      // Nothing to do, bail out
+      return 0;
     }
   }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -182,7 +181,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; detect_offense(memberlist* m, struct chanset_t *chan, char *msg)
     }
     ++msg;
   }
-  if (chan-&amp;gt;capslimit &amp;amp;&amp;amp; caps_count) {
+  if (chan-&amp;gt;capslimit &amp;amp;&amp;amp; caps_count &amp;amp;&amp;amp; tot &amp;gt;= 6) {
     caps_percentage = (caps_count)/(double(tot));
     if (caps_percentage &amp;gt;= caps_limit) {
       putlog(LOG_MODES, chan-&amp;gt;name, "Caps flood (%d%%) from %s -- kicking", int(caps_percentage * 100), m-&amp;gt;nick);
diff --git a/src/set.c b/src/set.c
index 0808e71..1f028dd 100755
--- a/src/set.c
+++ b/src/set.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -938,12 +938,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void write_vars_and_cmdpass(bd::Stream&amp;amp; stream, int idx)
     stream &amp;lt;&amp;lt; bd::String::printf("- %s %s\n", cp-&amp;gt;name, cp-&amp;gt;pass);
 }
 
-static void display_set_value(int idx, const variable_t *var, const char *data, bool format = false)
+static void display_set_value(int idx, const variable_t *var, const char *botnick, bool format = false)
 {
   char buf[51] = "";
 
+  const char *data = NULL;
+  if (botnick) {//fetch data from bot's USERENTRY_SET
+    struct userrec *botu = get_user_by_handle(userlist, (char *) botnick);
+    const char *botdata = var_get_bot_data(botu, var-&amp;gt;name);
+    data = botdata ? botdata : NULL;
+  } else {//use global, no bot specified
+    data = var-&amp;gt;gdata ? var-&amp;gt;gdata : NULL;
+  }
+
   if (format) {
-    simple_snprintf(buf, sizeof(buf), "(%-6s) %-19s: ", var_type_name(var-&amp;gt;flags), var-&amp;gt;name);
+    simple_snprintf(buf, sizeof(buf), "(%-6s) %-16s: ", var_type_name(var-&amp;gt;flags), var-&amp;gt;name);
   } else {
     simple_snprintf(buf, sizeof(buf), "(%s) %s: ", var_type_name(var-&amp;gt;flags), var-&amp;gt;name);
   }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -958,7 +967,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
   variable_t *var = NULL;
   char *name = NULL;
   const char *data = NULL, *botdata = NULL;
-  int list = 0, i = 0;
+  int list = 0;
   bool notyes = 1, wildcard = 0;
 
   if (par[0] &amp;amp;&amp;amp; !strncasecmp(par, "-yes", 4)) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1035,17 +1044,35 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
   }
 
   if (!data) {
+    // First determine which variables are going to be shown
+    bd::Array&amp;lt;variable_t*&amp;gt; varsToShow;
+    size_t i = 0;
+
     while (vars[i].name) {
-      botdata = NULL;
-      if (!name || wildcard)//not looping all, provided with one...
-        if (vars[i].name)
+      if (!name || wildcard) {//not looping all, provided with one...
+        if (vars[i].name) {
           var = &amp;amp;vars[i]; 
+        }
+      }
 
       if (wildcard &amp;amp;&amp;amp; !wild_match(name, var-&amp;gt;name)) {
         ++i;
         continue;
       }
       
+      varsToShow &amp;lt;&amp;lt; var;
+
+      if (name &amp;amp;&amp;amp; !wildcard) {
+        break;
+      }
+      ++i;
+    }
+
+    // Then display them
+    for (i = 0; i &amp;lt; varsToShow.length(); ++i) {
+      var = varsToShow[i];
+      botdata = NULL;
+      
       if (!(var-&amp;gt;flags &amp;amp; VAR_HIDE) &amp;amp;&amp;amp; !((var-&amp;gt;flags &amp;amp; VAR_PERM) &amp;amp;&amp;amp; !isowner(dcc[idx].nick)) &amp;amp;&amp;amp; 
           !(botnick &amp;amp;&amp;amp; ((var-&amp;gt;flags &amp;amp; VAR_NOLOC) || (ishub &amp;amp;&amp;amp; (var-&amp;gt;flags &amp;amp; VAR_NOLHUB))))
          ) {//Just display the data
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1060,12 +1087,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
         else if (list &amp;amp;&amp;amp; !data)
           dprintf(idx, "%s list not set.\n", var-&amp;gt;name);
         else {
-          display_set_value(idx, var, data, true);
+          const bool shouldFormat = varsToShow.length() &amp;gt; 1;
+          display_set_value(idx, var, botnick, shouldFormat);
         }
       }
-      if (name &amp;amp;&amp;amp; !wildcard)
-        break;
-      ++i;
     }
   } else { // need to set it!
     if (!list &amp;amp;&amp;amp; var-&amp;gt;flags &amp;amp; VAR_LIST) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1129,7 +1154,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
           return 0;
         } else if (var_add_list(botnick, var, data)) {
           dprintf(idx, "Added '%s' to %s list.\n", data, var-&amp;gt;name);
-          display_set_value(idx, var, data);
+          display_set_value(idx, var, botnick);
           return 1;
         }
       } else if (list == LIST_RM) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1137,7 +1162,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
 
         if ((expanded_data = var_rem_list(botnick, var, data)) &amp;amp;&amp;amp; expanded_data[0]) {
           dprintf(idx, "Removed '%s' from %s list.\n", expanded_data, var-&amp;gt;name);
-          display_set_value(idx, var, botnick ? (!var-&amp;gt;ldata || (var-&amp;gt;ldata[0] == '-' &amp;amp;&amp;amp; !var-&amp;gt;ldata[1]) ? "(not set)" : data) : (var-&amp;gt;gdata ? var-&amp;gt;gdata : "(not set)"));
+          display_set_value(idx, var, botnick);
           return 1;
         } else if (!var_find_list(botnick, var, data)) {
           char *data_word = NULL;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1169,7 +1194,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int cmd_set_real(const char *botnick, int idx, char *par)
       if (botnick)
         var_set_userentry(botnick, name, data);
 
-      display_set_value(idx, var, data);
+      display_set_value(idx, var, botnick);
 
       if (sdata)
         free(sdata);


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-27T00:36:32</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/752">
    <title>branch 'master' updated. v1.3.4-457-gc821e8d</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/752</link>
    <description>&lt;pre&gt;The branch 'master' has been updated

Summary of changes:
 src/flags.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

...from  183674744a4fc1bac909c5b483267123740c65be (commit) to (c821e8d29797675b4c2fdf5d3cf78d00d0449b34)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit c821e8d29797675b4c2fdf5d3cf78d00d0449b34
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Mon Mar 26 16:03:58 2012 -0500

    Raise buffer for deflag reasons

-----------------------------------------------------------------------

Complete Diff

diff --git a/src/flags.c b/src/flags.c
index 2afd00a..53580eb 100755
--- a/src/flags.c
+++ b/src/flags.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -585,7 +585,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; deflag_t deflag_translate(const char *buf)
 
 void deflag_user(struct userrec *u, deflag_event_t why, const char *msg, const struct chanset_t *chan)
 {
-  char tmp[30] = "", tmp2[1024] = "";
+  char tmp[50] = "", tmp2[1024] = "";
   struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };
   int which = 0;
 


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-27T00:36:20</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/751">
    <title>branch 'next' updated. v1.3.4-745-g8bccf5f</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/751</link>
    <description>&lt;pre&gt;The branch 'next' has been updated

Summary of changes:
 src/mod/irc.mod/cmdsirc.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

...from  06e38d079d790247142c60f034ec9cbeb230e87d (commit) to (8bccf5fa8bea3cf04b3faa322f13393aedcd311d)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 8bccf5fa8bea3cf04b3faa322f13393aedcd311d
Merge: 06e38d0 1836747
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Sun Mar 25 20:38:03 2012 -0500

    Merge branch 'master' into next
    
    * master:
      Fix cmd_adduser/cmd_kickban not using proper hostname

-----------------------------------------------------------------------

Complete Diff

diff --git a/src/mod/irc.mod/cmdsirc.c b/src/mod/irc.mod/cmdsirc.c
index 018e376..a4a2711 100755
--- a/src/mod/irc.mod/cmdsirc.c
+++ b/src/mod/irc.mod/cmdsirc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -286,6 +286,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_kickban(int idx, char *par)
     }
     member_getuser(m);
     u = m-&amp;gt;user;
+    strlcpy(s, m-&amp;gt;from, sizeof(s));
     get_user_flagrec(u, &amp;amp;victim, chan-&amp;gt;dname);
   
     if ((chan_master(victim) || glob_master(victim)) &amp;amp;&amp;amp;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1720,6 +1721,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_adduser(int idx, char *par)
   if (strlen(hand) &amp;gt; HANDLEN)
     hand[HANDLEN] = 0;
   member_getuser(m);
+  strlcpy(s, m-&amp;gt;from, sizeof(s));
   if ((u = m-&amp;gt;user)) {
     dprintf(idx, "%s is already known as %s.\n", nick, u-&amp;gt;handle);
     return;


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-26T01:38:30</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/750">
    <title>branch 'master' updated. v1.3.4-456-g1836747</title>
    <link>http://permalink.gmane.org/gmane.network.irc.bot.wraith.scm/750</link>
    <description>&lt;pre&gt;The branch 'master' has been updated

Summary of changes:
 src/mod/irc.mod/cmdsirc.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

...from  066136fa9684d2b61cf58f862729a39211e52487 (commit) to (183674744a4fc1bac909c5b483267123740c65be)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 183674744a4fc1bac909c5b483267123740c65be
Author: Bryan Drewery &amp;lt;bryan&amp;lt; at &amp;gt;shatow.net&amp;gt;
Date:   Sun Mar 25 20:28:21 2012 -0500

    Fix cmd_adduser/cmd_kickban not using proper hostname
    
    This was a regression from 'member-from'

-----------------------------------------------------------------------

Complete Diff

diff --git a/src/mod/irc.mod/cmdsirc.c b/src/mod/irc.mod/cmdsirc.c
index 018e376..a4a2711 100755
--- a/src/mod/irc.mod/cmdsirc.c
+++ b/src/mod/irc.mod/cmdsirc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -286,6 +286,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_kickban(int idx, char *par)
     }
     member_getuser(m);
     u = m-&amp;gt;user;
+    strlcpy(s, m-&amp;gt;from, sizeof(s));
     get_user_flagrec(u, &amp;amp;victim, chan-&amp;gt;dname);
   
     if ((chan_master(victim) || glob_master(victim)) &amp;amp;&amp;amp;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1720,6 +1721,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cmd_adduser(int idx, char *par)
   if (strlen(hand) &amp;gt; HANDLEN)
     hand[HANDLEN] = 0;
   member_getuser(m);
+  strlcpy(s, m-&amp;gt;from, sizeof(s));
   if ((u = m-&amp;gt;user)) {
     dprintf(idx, "%s is already known as %s.\n", nick, u-&amp;gt;handle);
     return;


hooks/post-receive
--
Wraith Botpack

&lt;/pre&gt;</description>
    <dc:creator>git&lt; at &gt;shatow.net</dc:creator>
    <dc:date>2012-03-26T01:38:22</dc:date>
  </item>
  <textinput rdf:about="http://search.gmane.org/?group=$group=gmane.network.irc.bot.wraith.scm">
    <title>Search Engine</title>
    <description>Search the mailing list at Gmane</description>
    <name>query</name>
    <link>http://search.gmane.org/?group=$group=gmane.network.irc.bot.wraith.scm</link>
  </textinput>
</rdf:RDF>

