Commits

Palmer, 2E0EOL  committed 7f98014

Entire changeset 0.1.0 -> 0.1.1

  • Participants
  • Parent commits dbd7101
  • Tags overchat-0.1.1

Comments (0)

Files changed (161)

File 0.0.20checklist.txt

-Add safe allocator to allow SBeast to come into the project without fouling up memory...
-Write OCQ's chmail
-Ensure root or password '*' cannot login to OverChat
-Ensure OverChat does not allow a dynamic password update for user root
-Fix crash in DBR2 if database is missing
-Fix FreeBSD bind issue
-SO_REUSEADDR in Blake networking connect
 
 Nick Dagger <Dagsylad@Dagsylad.com>
 For BASIC port
+For Sarah Client
 
 Haesu Chun <Haesu@TowardEX.com>
 For run/recovery system and networking queries
 at least every server release.
 
 
+0.1.1
+-----
+Haesu & DDRP: Fix implicit std namespace expectation in DayboDep
+DDRP: Fix internal non-exploitable string based error in server_core
+DDRP: Fix mailing address for backups
+DDRP: Fix configure thinking .o was for Borland as well as GNU
+DDRP: Add configure option for enable/disable PCH
+DDRP: Fix e_SetChallengeHash()'s failure to return a value (core)
+DDRP: Fix order of BLAKE_AS_DLL import/export qualifier keywords
+DDRP: Fix building of Blake DLL for Dagsylad
+DDRP: Make OCQuery's chmail command work
+DDRP: Add OCQuery chpriv command for privellege reassignment
+DDRP: Add network_InitIPv4()
+DDRP: make mrproper to clean configuration too
+DDRP: Redefinition of BLAKEAPI (major changes)
+DDRP: Fix blake_SleepMS() not doing anything!
+DDRP: Fix slight logic error in TNetBuffer::Connect
+DDRP: OCQuery prints unspammable email addresses
+DDRP: Make testbed exit at point of failure
+DDRP: Add Blake library error French & Spanish translations
+DDRP: Better display of panic parameters in crash situation
+DDRP: Fix mailall compile issue(s) and make build with the tree
+DDRP: All code to use shared word checksummers
+DDRP: Corruption & logic testing in core
+DDRP: Add client information to login packet
+DDRP: Initialise internal NetBuffer buffers on socket closure
+DDRP: Ammend network_InstallIncomingCallback() documentation
+DDRP: Add blake_Here() (returns address of caller)
+DDRP: Added blake_GetClientIDString()
+DDRP: Security: Exploitable over-length strings in protocol fixed where found
+DDRP: Fix POSIX threading build, changes to configure too
+
 0.1.0
 -----
 DDRP: Disable DPCRTLMM log by default
 DDRP: Add blake_hashes.c and testbed component for it
 DDRP: Removed redundant use of current time in displaying title
 DDRP: Add double MD5 one way hash secure authentication, mandatory
+DDRP: uuencoded DB backups sent via email to administrators
 
 0.0.19
 ------

File Makefile.bor

 
 blake.lib:
 	cd blake
-	make -f $(THISFILE) blake_lib
+	make -f $(THISFILE)
 	cd ..
 
 overchat : overchat.exe

File Makefile.gnu

 	cd committee && $(TMAKE) -f $(THISFILE) depend
 	cd configure && $(TMAKE) -f $(THISFILE) depend
 	cd daybodep && $(TMAKE) -f Makefile_oc.gnu depend
-	cd daybocrypt && $(TMAKE) depend
-	cd db2fix && $(TMAKE) -f Makefile.gnu depend
+	cd daybocrypt && $(TMAKE) -f Makefile_oc.gnu depend
+	cd db2fix && $(TMAKE) -f $(THISFILE) depend
 	cd dlini && $(TMAKE) -f $(THISFILE) depend
 	cd dpcrtlmm && $(TMAKE) -f $(THISFILE) depend
 	cd mailall && $(TMAKE) -f $(THISFILE) depend
 	cd dlini && $(TMAKE) -f $(THISFILE)
 
 daybocrypt_lib:
-	cd daybocrypt && $(TMAKE) run
+	cd daybocrypt && $(TMAKE) -f Makefile_oc.gnu run
 
 overchat : overchatd
 
 
 mrproper : clean
 	-rm -rf .resp
+	cd configure ; $(TMAKE) -f $(THISFILE) clean
 
 clean : testbed_clean advtools_clean supdae_clean clients_clean cgi_clean overchat_clean blake_lib_clean dlini_lib_clean memory_debugger_clean daybocrypt_clean basictools_clean daybodep_clean
 	-rm -f core overchatd.core
 	cd dlini ; $(TMAKE) -f $(THISFILE) clean
 
 daybocrypt_clean:
-	cd daybocrypt ; $(TMAKE) clean
+	cd daybocrypt ; $(TMAKE) -f Makefile_oc.gnu clean
 
 basictools_clean:
 	cd buildnum ; $(TMAKE) -f $(THISFILE) clean
 	@echo "------------------------------------------------"
 	cd db2fix && $(TMAKE) -f $(THISFILE) all
 	cd tools && $(TMAKE) -f $(THISFILE) all
+	cd mailall && $(TMAKE) -f $(THISFILE) all
 
 advtools_clean:
 	cd db2fix && $(TMAKE) -f $(THISFILE) clean
 	cd tools && $(TMAKE) -f $(THISFILE) clean
+	cd mailall && $(TMAKE) -f $(THISFILE) clean
 
 _testbed:
 	@echo "------------------------------------------------"

File MasterMake.bor

-#  /*
-#  OverChat
-#  by David Duncan Ross Palmer <Overlord@DayboLogic.co.uk>
-#  Copyright 2002 Daybo Logic, all rights reserved.
-#
-#  This file was auto generated by OverChat's autoconfigurator.
-#  Although the contents of the file, because they are written by
-#  machine and not by human belong to nobody, the program which created
-#  the file (overchat/configure/configure) is owned by DDRP.
-#  */
-
-#
-# Autogenerated makeinclude, do not edit
-#
-
-STATIC=-static
-CC=bcc32
-CPPC=bcc32
-DEBUG=1
-BLAKEDB_R2=1
-OPTLEVEL=
-TMAKE=make
-ANSI=-A
-MASTER_CFLAGS=-D__WIN32__ -v -c
-MASTER_LFLAGS=-v
-H=.h
-LIB=.lib
-EXE=.exe
-C=.c
-CPP=.cpp
-O=.o
-WITH_PTH=1
-WITH_TV=1
+" " 

File MasterMake.gnu.old

-#
-# Master make file.  This makefile is included by all other makefiles
-# so anything defined here affects _all_ makefiles, master makefile,
-# source makefiles and individual target headers, except certain libs
-# which are maintained independently of OverChat.
-#
-# This header is intended to be built with GNU make.
-#
-# OverChat
-# (C)Copyright 2001-2002 Daybo Logic, all rights reserved.
-#
-
-# CC is the C compiler, it is set by default to cc, if you want to use
-# gcc or something else, uncomment and edit the line below.
-#CC=gcc
-
-# CPPC is the C++ compiler
-CPPC=g++
-
-# The make utility the build process uses _matters_.  BSD's make won't
-# suffice.  GNU make is what I use.  I'll point to gmake everywhere in
-# the tree if it matters.  If you want to point to another make program
-# change the line below.  Don't remove the line below.
-TMAKE=gmake
-
-# Debugging.  If you want debugging on the entire build, make sure
-# that DEBUG is defined, otherwise comment it out.
-DEBUG=1
-
-# If you want to use the new binary databases (R2) on the server and ocquery
-# you need to uncomment this line.
-BLAKEDB_R2=1
-
-# This specifies the default name of the makefile, don't remove it,
-# it's not optional.
-THISFILE=Makefile.gnu
-
-# This command lists the files in a directory, line by line
-# we had problems with ls -l1 and now use ls -1, perhaps we will make our
-# own tools if ls gives us any more problems.
-DIR=ls -1
-
-# The very strict ruleset applied to certain files.  If the build is broken
-# you might try altering this.
-ANSI=-ansi -pedantic -Wall
-
-# Default flags
-# CFLAGS specifies the default flags given to the compiler, they should
-# not conflict with specific overrides given by lower level makefiles.
-# The ruleset is very basic and you shouldn't need to mess with it.
-# LFLAGS specifies the default flags given to the linker when creating
-# executable programs.  Again, nothing here must conflict with lower
-# level makefiles or things will get broken.  All lower level Makefiles
-# should specify their CFLAGS like this:
-# CFLAGS=$(MASTER_CFLAGS) -pipe (or whatever)
-
-ifdef DEBUG
-
-MASTER_CFLAGS=-D__UNIX__ -g -c
-MASTER_LFLAGS=-g
-
-else
-
-MASTER_CFLAGS=-DNDEBUG -D__UNIX__ -O3 -c
-MASTER_LFLAGS=
-
-endif
-
-#
-# Filenme extensions section
-# This deals with differently named files on different systems,
-# for example Borland uses obj and UNIX uses o for object.
-# EXE file sometimes have an extension, sometimes not.
-# For all new makefiles please use these macros.
-#
-
-LIB=.a
-O=.o
-EXE=
-C=.c
-CPP=.cpp
-H=.h
-
-# Legacy database support.  Use the macro DB in the compiler flags of any
-# module which needs access to the user database.
-ifdef BLAKEDB_R2
-DB=-DBLAKEDB_R2=1
-else
-DB=
-endif

File NetBuffer/NetBuffer.cpp

   err = network_Connect(s, UseIPv6, Port, Address); // Connect to server
   if ( err != blakeSuccess ) // Fail
     Close(); // Socket cannot be used (clean up)
-
-  // Conencted to server, switch to nonblocking
-  network_MakeNonBlocking(s);
+  else
+    network_MakeNonBlocking(s); // Connected to server, switch to nonblocking
 
   return err;
 }
   if ( s ) {
     network_CloseSocket(s);
     s = 0;
+    InitBuffers(); /* Incase this net buffer is re-used */
   }
 }
 //---------------------------------------------------------------------------
 #endif //DEBUG
 //---------------------------------------------------------------------------
 static size_t GetExpectSz(const unsigned char* RawData)
-{
-  size_t sz = 0U;
-  unsigned char rawnumber[sizeof(unsigned short)];
-  char test[3];
-
-  test[0] = RawData[0];
-  test[1] = RawData[1];
-  test[2] = '\0';
-
-  if ( RawData ) {
-    unsigned short int* pnum;
-    memcpy(rawnumber, RawData, 2); /* Get first two bytes */
-    pnum = (unsigned short int*)rawnumber;
-    sz = *pnum;
-    /* Now do a swap */
-    sz = network_NetToHostShort((unsigned short int)sz);
-    /* Now cap */
-    sz = BLAKE_MIN(sz, OVERCHAT_NET_PKTMAXSZ - 2);
-  }
-#ifdef DEBUG
-  printf("DEBUG: sz==%u  TESTRAW(%c%c)\n", sz, test[0], test[1]);
-#endif /*DEBUG*/
+{
+  size_t sz = 0U;
+  unsigned char rawnumber[sizeof(unsigned short)];
+  char test[3];
+
+  test[0] = RawData[0];
+  test[1] = RawData[1];
+  test[2] = '\0';
+
+  if ( RawData ) {
+    unsigned short int* pnum;
+    memcpy(rawnumber, RawData, 2); /* Get first two bytes */
+    pnum = (unsigned short int*)rawnumber;
+    sz = *pnum;
+    /* Now do a swap */
+    sz = network_NetToHostShort((unsigned short int)sz);
+    /* Now cap */
+    sz = BLAKE_MIN(sz, OVERCHAT_NET_PKTMAXSZ - 2);
+  }
+#ifdef DEBUG
+  printf("DEBUG: sz==%u  TESTRAW(%c%c)\n", sz, test[0], test[1]);
+#endif /*DEBUG*/
   return sz;
 }
 //---------------------------------------------------------------------------

File blake/BccW32.cfg

+-w
+-R
+-v
+-WM-
+-vi
+-H
+-H=blake.csm

File blake/Makefile.bor

-# This Makefile builds the Blake library.  It's built
-# twice as a static library firstly and then a DLL.
-# This Makefile also builds and runs some tests.
+#
+# This makefile is a wrapper for blake.mak
+# It adds functionallity such as clean.
+# blake.mak should be regenerated when IDE changes are made
+#
+# Maintainer == DDRP <www.daybologic.co.uk/mailddrp>
+#
 
-#    !include ..\MasterMake.bor    <- Get this made integral to Blake on Borland ASAP
+!include ..\MasterMake.bor
+!include blake.mak
 
+clean :
+	if exist csblake.dll erase csblake.dll
+   if exist csblake.lib erase csblake.lib
+   if exist ssblake.lib erase ssblake.lib
+   if exist ssblaked.lib erase ssblaked.lib
+   if exist blake.#* erase blake.#*
+   if exist *.bak erase *.bak
+   if exist *.il? erase *.il?
+   if exist *.tds erase *.tds
+   if exist *.tr2 erase *.tr2
+   if exist *.csm erase *.csm
+   cd build_csblake
+   if exist *$(O) erase *$(O) > nul
+   if exist *$(O) erase *$(O) > nul
+   cd ..
+   cd build_ssblake
+   if exist *$(O) erase *$(O) > nul
+   if exist *$(O) erase *$(O) > nul
+   cd ..
+   cd build_ssblaked
+   if exist *$(O) erase *$(O) > nul
+   if exist *$(O) erase *$(O) > nul
+   cd ..
+   type empty.file > _deps.bor
+   if exist _files.bor  erase _files.bor
 
-# Force 32-bit link
-CC=bcc32 -v
-RC=brcc32
-LINKER=ilink32
-ERASE=..\rmw32\rmw32
+depend :
+	dir /b *.c >     _files.bor
+   dir /b *.h >>    _files.bor
+   dir /b *.cpp >>  _files.bor
+   ..\daybodep\daybodep @_files.bor > _deps.bor
 
-THISFILE=Makefile.bor
-TMPLINKFILE=linkfile.tmp
-TMPLINKFILE2=liblfile.tmp
-MDF=blake.def.bor
-BLAKE=..\blake.lib
-DEF=
-DPCRTLMM_PATH=..\dpcrtlmm
-IPATH=-I$(DPCRTLMM_PATH) -I..\src -I..\dlini
-LINK=$(CC)
-COMPILE=$(CC) $(IPATH) $(DEF) $(CFLAGS) -c
-COPY=copy
-DPCRTLMM=..\dpcrtlmm\dpcrtlmm.lib
-
-!ifdef BLAKEDB_R2
-BLAKEDB_OBJ=blakedb2.obj
-!else
-BLAKEDB_OBJ=blakedb1.obj
-!endif
-
-BLAKE_OBJ=blake.obj \
-          blake_cb.obj \
-          blake_fastqueue.obj \
-          blake_ll.obj \
-          blake_main.obj \
-          blake_network.obj \
-          blake_pendingloop.obj \
-          blake_portmutant.obj \
-          blake_protocol.obj \
-          criticalinteger.obj \
-          recursivemutant.obj \
-          $(BLAKEDB_OBJ) \
-          blake_nick.obj \
-          blake_portthread.obj \
-          blake_trace.obj \
-          blake_ansi.obj \
-          blake_strfunc.obj \
-          blake_logger.obj
-
-BLAKE_RES_OBJ=res\btfuck.obj \
-              res\murder_microsoft.obj \
-              res\sbeast.obj
-
-all : # Too complicated the build as one rule, needs seperate building and recompilation of objects
-	$(MAKE) -f $(THISFILE) blakei_lib   # DLL built as a side effect dep 
-	$(MAKE) -f $(THISFILE) blake_lib
-	$(MAKE) -f $(THISFILE) tests
-	@echo $(USERNAME) built a working Blake system from source.
-
-blake_lib : ..\blake.lib
-
-blakei_lib : ..\blakei.lib
-
-blake_dll : ..\blake.dll
-
-..\blakei.lib : ..\blake.dll
-	@echo Generating Borland import library for blake.dll
-	implib -c -f ..\blakei.lib ..\blake.dll
-
-..\blake.lib : $(BLAKE_OBJ) blake_obj_res_dep
-	$(ERASE) ..\blake.lib
-	tlib ..\blake.lib +blake_cb.obj
-	tlib ..\blake.lib +blake_fastqueue.obj
-	tlib ..\blake.lib +blake_ll.obj
-	tlib ..\blake.lib +blake_main.obj
-	tlib ..\blake.lib +blake_network.obj
-	tlib ..\blake.lib +blake_pendingloop.obj
-	tlib ..\blake.lib +blake_portmutant.obj
-	tlib ..\blake.lib +blake_protocol.obj
-	tlib ..\blake.lib +criticalinteger.obj
-	tlib ..\blake.lib +recursivemutant.obj
-	tlib ..\blake.lib +$(BLAKEDB_OBJ)
-	tlib ..\blake.lib +blake_nick.obj
-	tlib ..\blake.lib +blake_portthread.obj
-	tlib ..\blake.lib +blake_trace.obj
-	tlib ..\blake.lib +blake_ansi.obj
-	tlib ..\blake.lib +blake_strfunc.obj
-	tlib ..\blake.lib +blake_logger.obj
-	tlib ..\blake.lib +res\btfuck.obj
-	tlib ..\blake.lib +res\murder_microsoft.obj
-	tlib ..\blake.lib +res\sbeast.obj
-
-blake_obj_res_dep:
-	cd res
-	$(MAKE) -f $(THISFILE)
-	cd ..
-
-..\blake.dll : $(BLAKE_OBJ) blake.res $(MDF) blake_obj_res_dep
-	echo $(MAKEDIR)\..\lib\c0d32.obj + > $(TMPLINKFILE)
-	echo res\btfuck.obj + >> $(TMPLINKFILE)
-	echo res\murder_microsoft.obj + >> $(TMPLINKFILE)
-	echo res\sbeast.obj + >> $(TMPLINKFILE)
-	echo blake.obj + >> $(TMPLINKFILE)
-        echo blake_cb.obj + >> $(TMPLINKFILE)
-        echo blake_fastqueue.obj + >> $(TMPLINKFILE)
-        echo blake_ll.obj + >> $(TMPLINKFILE)
-        echo blake_main.obj + >> $(TMPLINKFILE)
-        echo blake_network.obj + >> $(TMPLINKFILE)
-        echo blake_pendingloop.obj + >> $(TMPLINKFILE)
-        echo blake_portmutant.obj + >> $(TMPLINKFILE)
-        echo blake_protocol.obj + >> $(TMPLINKFILE)
-        echo criticalinteger.obj + >> $(TMPLINKFILE)
-        echo recursivemutant.obj + >> $(TMPLINKFILE)
-	echo $(BLAKEDB_OBJ) + >> $(TMPLINKFILE)
-	echo blake_nick.obj + >> $(TMPLINKFILE)
-	echo blake_portthread.obj + >> $(TMPLINKFILE)
-	echo blake_trace.obj + >> $(TMPLINKFILE)
-	echo blake_ansi.obj + >> $(TMPLINKFILE)
-	echo blake_strfunc.obj + >> $(TMPLINKFILE)
-	echo blake_logger.obj + >> $(TMPLINKFILE)
-	echo $(MAKEDIR)\..\lib\cw32mti.lib + > $(TMPLINKFILE2)
-	echo $(MAKEDIR)\..\lib\import32.lib + >> $(TMPLINKFILE2)
-	echo ..\dpcrtlmm\dpcrtlmm.lib + >> $(TMPLINKFILE2)
-	$(LINKER) -Tpd -v4.0 -ap -x @$(TMPLINKFILE), ..\blake.dll, blake.map, @$(TMPLINKFILE2), $(MDF), blake.res
-
-blake.res : blake.rc blake.rh
-	$(RC) blake.rc
-
-tests : queuetest
-
-queuetest : queuetest.exe
-
-queuetest.exe : queuetest.obj $(DPCRTLMM)
-	$(LINK) queuetest.obj $(BLAKE) $(DPCRTLMM)
-
-.c.obj:
-	$(COMPILE) $<
-
-clean : clean_blakeobj clean_res
-	$(ERASE) ..\blake.lib ..\blakei.lib ..\blake.dll
-	$(ERASE) _blakemakeconfig.h
-	$(COPY) _blakemakeconfig.default _blakemakeconfig.h
-
-clean_blakeobj:
-	$(ERASE) blake.obj
-	$(ERASE) blake_cb.obj
-	$(ERASE) blake_fastqueue.obj
-	$(ERASE) blake_ll.obj
-	$(ERASE) blake_main.obj
-	$(ERASE) blake_network.obj
-	$(ERASE) blake_pendingloop.obj
-	$(ERASE) blake_portmutant.obj
-	$(ERASE) blake_protocol.obj
-	$(ERASE) blake_trace.obj
-	$(ERASE) blake_ansi.obj
-	$(ERASE) blake_strfunc.obj
-	$(ERASE) criticalinteger.obj
-	$(ERASE) recursivemutant.obj
-	$(ERASE) blakedb.obj
-	$(ERASE) blake_nick.obj
-	$(ERASE) blake_portthread.obj
-	$(ERASE) $(TMPLINKFILE) $(TMPLINKFILE2)
-	cd res
-	$(MAKE) -f $(THISFILE) clean
-	cd ..
-
-clean_res:
-	$(ERASE) blake.res
+!include _deps.bor

File blake/Makefile.bor.old

+# This Makefile builds the Blake library.  It's built
+# twice as a static library firstly and then a DLL.
+# This Makefile also builds and runs some tests.
+
+!include ..\MasterMake.bor
+
+
+# Force 32-bit link
+CC=bcc32 -v
+RC=brcc32
+LINKER=ilink32
+ERASE=..\rmw32\rmw32
+
+THISFILE=Makefile.bor
+TMPLINKFILE=linkfile.tmp
+TMPLINKFILE2=liblfile.tmp
+MDF=blake.def.bor
+BLAKE=..\blake$(LIB)
+DEF=
+DPCRTLMM_PATH=..\dpcrtlmm
+IPATH=-I$(DPCRTLMM_PATH) -I..\src -I..\dlini
+LINK=$(CC)
+COMPILE=$(CC) $(IPATH) $(DEF) $(CFLAGS) -c
+COPY=copy
+DPCRTLMM=..\dpcrtlmm\dpcrtlmm$(LIB)
+
+BLAKE_OBJ=blake$(O) \
+          blake_cb$(O) \
+          blake_fastqueue$(O) \
+          blake_ll$(O) \
+          blake_main$(O) \
+          blake_network$(O) \
+          blake_pendingloop$(O) \
+          blake_portmutant$(O) \
+          blake_protocol$(O) \
+          criticalinteger$(O) \
+          recursivemutant$(O) \
+          blakedb$(O) \
+          blake_nick$(O) \
+          blake_portthread$(O) \
+          blake_trace$(O) \
+          blake_ansi$(O) \
+          blake_strfunc$(O) \
+          blake_logger$(O)
+
+BLAKE_RES_OBJ=res\btfuck$(O) \
+              res\murder_microsoft$(O) \
+              res\sbeast$(O)
+
+all : # Too complicated the build as one rule, needs seperate building and recompilation of objects
+	$(MAKE) -f $(THISFILE) blakei_lib   # DLL built as a side effect dep
+	$(MAKE) -f $(THISFILE) blake_lib
+	$(MAKE) -f $(THISFILE) tests
+	@echo $(USERNAME) built a working Blake system from source.
+
+blake_lib : blake_dll
+
+blakei_lib : ..\blakei$(LIB)
+
+blake_dll : ..\blake.dll
+
+..\blakei.lib : ..\blake.dll
+	@echo Generating Borland import library for blake.dll
+	implib -c -f ..\blakei.lib ..\blake.dll
+
+..\blake.lib : $(BLAKE_OBJ) blake_obj_res_dep
+	$(ERASE) ..\blake.lib
+	tlib ..\blake.lib +blake_cb.obj
+	tlib ..\blake.lib +blake_fastqueue.obj
+	tlib ..\blake.lib +blake_ll.obj
+	tlib ..\blake.lib +blake_main.obj
+	tlib ..\blake.lib +blake_network.obj
+	tlib ..\blake.lib +blake_pendingloop.obj
+	tlib ..\blake.lib +blake_portmutant.obj
+	tlib ..\blake.lib +blake_protocol.obj
+	tlib ..\blake.lib +criticalinteger.obj
+	tlib ..\blake.lib +recursivemutant.obj
+	tlib ..\blake.lib +$(BLAKEDB_OBJ)
+	tlib ..\blake.lib +blake_nick.obj
+	tlib ..\blake.lib +blake_portthread.obj
+	tlib ..\blake.lib +blake_trace.obj
+	tlib ..\blake.lib +blake_ansi.obj
+	tlib ..\blake.lib +blake_strfunc.obj
+	tlib ..\blake.lib +blake_logger.obj
+	tlib ..\blake.lib +res\btfuck.obj
+	tlib ..\blake.lib +res\murder_microsoft.obj
+	tlib ..\blake.lib +res\sbeast.obj
+
+blake_obj_res_dep:
+	cd res
+	$(MAKE) -f $(THISFILE)
+	cd ..
+
+..\blake.dll : $(BLAKE_OBJ) blake.res $(MDF) blake_obj_res_dep
+	echo $(MAKEDIR)\..\lib\c0d32.obj + > $(TMPLINKFILE)
+	echo res\btfuck.obj + >> $(TMPLINKFILE)
+	echo res\murder_microsoft.obj + >> $(TMPLINKFILE)
+	echo res\sbeast.obj + >> $(TMPLINKFILE)
+	echo blake.obj + >> $(TMPLINKFILE)
+        echo blake_cb.obj + >> $(TMPLINKFILE)
+        echo blake_fastqueue.obj + >> $(TMPLINKFILE)
+        echo blake_ll.obj + >> $(TMPLINKFILE)
+        echo blake_main.obj + >> $(TMPLINKFILE)
+        echo blake_network.obj + >> $(TMPLINKFILE)
+        echo blake_pendingloop.obj + >> $(TMPLINKFILE)
+        echo blake_portmutant.obj + >> $(TMPLINKFILE)
+        echo blake_protocol.obj + >> $(TMPLINKFILE)
+        echo criticalinteger.obj + >> $(TMPLINKFILE)
+        echo recursivemutant.obj + >> $(TMPLINKFILE)
+	echo $(BLAKEDB_OBJ) + >> $(TMPLINKFILE)
+	echo blake_nick.obj + >> $(TMPLINKFILE)
+	echo blake_portthread.obj + >> $(TMPLINKFILE)
+	echo blake_trace.obj + >> $(TMPLINKFILE)
+	echo blake_ansi.obj + >> $(TMPLINKFILE)
+	echo blake_strfunc.obj + >> $(TMPLINKFILE)
+	echo blake_logger.obj + >> $(TMPLINKFILE)
+	echo $(MAKEDIR)\..\lib\cw32mti.lib + > $(TMPLINKFILE2)
+	echo $(MAKEDIR)\..\lib\import32.lib + >> $(TMPLINKFILE2)
+	echo ..\dpcrtlmm\dpcrtlmm.lib + >> $(TMPLINKFILE2)
+	$(LINKER) -Tpd -v4.0 -ap -x @$(TMPLINKFILE), ..\blake.dll, blake.map, @$(TMPLINKFILE2), $(MDF), blake.res
+
+blake.res : blake.rc blake.rh
+	$(RC) blake.rc
+
+tests : queuetest
+
+queuetest : queuetest.exe
+
+queuetest.exe : queuetest.obj $(DPCRTLMM)
+	$(LINK) queuetest.obj $(BLAKE) $(DPCRTLMM)
+
+.c.obj:
+	$(COMPILE) $<
+
+clean : clean_blakeobj clean_res
+	$(ERASE) ..\blake.lib ..\blakei.lib ..\blake.dll
+
+clean_blakeobj:
+	$(ERASE) blake.obj
+	$(ERASE) blake_cb.obj
+	$(ERASE) blake_fastqueue.obj
+	$(ERASE) blake_ll.obj
+	$(ERASE) blake_main.obj
+	$(ERASE) blake_network.obj
+	$(ERASE) blake_pendingloop.obj
+	$(ERASE) blake_portmutant.obj
+	$(ERASE) blake_protocol.obj
+	$(ERASE) blake_trace.obj
+	$(ERASE) blake_ansi.obj
+	$(ERASE) blake_strfunc.obj
+	$(ERASE) criticalinteger.obj
+	$(ERASE) recursivemutant.obj
+	$(ERASE) blakedb.obj
+	$(ERASE) blake_nick.obj
+	$(ERASE) blake_portthread.obj
+	$(ERASE) $(TMPLINKFILE) $(TMPLINKFILE2)
+	cd res
+	$(MAKE) -f $(THISFILE) clean
+	cd ..
+
+clean_res:
+	$(ERASE) blake.res

File blake/Makefile.gnu

         blake_panic$(O) \
         blake_debugtables$(O) \
         blake_hashes$(O) \
+        blake_chksum$(O) \
+        blake_here$(O) \
+        blake_authorisedclients$(O) \
         blakedb$(O) \
         criticalinteger$(O) \
         recursivemutant$(O)

File blake/_deps.bor

+ 

File blake/blake.DSW

Binary file removed.

File blake/blake.DSW_

Binary file added.

File blake/blake.OBR

Binary file removed.

File blake/blake.h

 */
 /* Visual C++ does this automatically for us so I might as well make use of it */
 #if ( defined(BLAKE_EXPORTS) || defined(BLAKE_IMPORTS) )
-#  define BLAKE_AS_DLL
+#  ifndef BLAKE_AS_DLL
+#    define BLAKE_AS_DLL
+#  endif
 #endif
 
 #if ( defined(BLAKE_AS_DLL) && defined(BLAKE_SOURCE) )
-#  define BLAKEAPI __declspec(dllexport) __stdcall
+#  define BLAKEAPI(ret) __declspec(dllexport) ##ret __stdcall
 #elif ( defined(BLAKE_AS_DLL) && !defined(BLAKE_SOURCE) )
-#  define BLAKEAPI __declspec(dllimport) __stdcall
+#  define BLAKEAPI(ret) __declspec(dllimport) ##ret __stdcall
 #else
-#  define BLAKEAPI
+#  define BLAKEAPI(ret) ret
 #endif
 
 /*
   bscchum_signoff,           /* One of your chums just signed off */
   bscchum_idle,              /* One of your chums went into or came out of an idle state */
   bscloginreply,             /* You have have failed or succeed to authorise */
-  bscisonlinereply           /* Reply to the last IsOnline request */
+  bscisonlinereply,          /* Reply to the last IsOnline request */
+  bscregisterreply           /* Reply to a client nickname registration request */
 };
 
 enum blakeClientCodes {   /* code sent from the client(s) to the server */
   bccchum_remove,            /* Removes a chum, terrible pitty */
   bccidle,                   /* Come out of or enter an idle state */
   bccisonline,               /* Test if a given user is online */
-  bccmessage2                /* Sub-protocol message */
+  bccmessage2,               /* Sub-protocol message */
+  bccregister                /* Register a nickname */
 };
 
 enum blakeErrorCodes {    /* These error are returned with serverCodes::goterror type packets */
   blrUnknownHash             /* The hash used to give the password to the server cannot be handled/unknown */
 };
 
+enum blakeRegisterReplyCode {
+  brrSuccess,                /* Successful registration */
+  brrOffensive,              /* The nickname is considered too offensive */
+  brrEmailFaults,            /* Faults with email address */
+  brrHandleError,            /* Cannot aquire a handle for the database */
+  brrLockError,              /* Cannot lock the database */
+  brrNickOwned,              /* The nickname is already owned by another user */
+  brrMailError,              /* Registered but cannot send mail, try to recover password later */
+  brrCreateError,            /* Unknown error creating the user */
+  brrNickTooLong,            /* The nickname was too long */
+  brrInvalidChar,            /* The nickname contained invalid characters */
+  brrBeginSpace,             /* The nickname cannot begin with a space */
+  brrInvalidEmail,           /* The email address does not appear valid */
+  brrNoDomain,               /* The email address does not have a domain portion */
+  brrDomainResolution        /* The domain does not have a primary DNS A record (may look for MX records in the future) */
+};
+
 enum blakeCipherID {
   bcidPlain,                 /* Plaintext, no cipher */
   bcidCaesar,                /* Caesar's Cipher */
   bhtSha1                    /* PGP SHA1 */
 };
 
+/* Only authorised clients will be allowed into the system */
+enum blakeClientID {
+  bClientIdOberChatten,      /* DDRP's Win32 client */
+  bClientIdOCTurboUNIX,      /* DDRP's UNIX version of octurbo */
+  bClientIdOCLogin,          /* DDRP's test client */
+  bClientIdDDRPLogin,        /* DDRP's personal client */
+  bClientIdOC32,             /* Total Konfuzion's Win32 client */
+  bClientIdJava,             /* Java based client */
+  bClientIdSarah             /* Dagsylad's Win32 client */
+};
+
 /*
   Privelleges are used internally by the server and are requested by
   clients.  Use one of the privelleges here, if it corrosponds to the value
   blake_byte_t boolean; /* Whether the person is online or not */
 };
 
+struct blakeRegisterReply {
+  blake_byte_t failcode; /* See blakeRegisterReplyCode */
+  blake_byte_t password[OVERCHAT_PASS_LIMIT];
+  blake_byte_t reserved[32]; /* A little leaway incase I need to do anything else */
+};
+
 /* -------- */
 
 struct blakeLogin {                           /* Client side */
   blake_byte_t _username[OVERCHAT_NICK_LIMIT]; /* Your username, use padding, no NULL terminator is full length */
   blake_word8_t hashtype; /* enum blakeHashType */
-  blake_byte_t passworddigest[256]; /* Large space to allow expansion of hashtype */
+  blake_byte_t _passworddigest[128]; /* Large space to allow expansion of hashtype, allows for a 1,024-bit hash */
+  blake_byte_t reserved[120]; /* Reserved */
+  blake_word32_t clientid; /* The client's unique identifer */
+  blake_word32_t clientver; /* The version of that client */
   blake_byte_t language; /* This will be supported in the future, at the moment it's zero, meaning English (of course) */
 };
 
   blake_byte_t username[OVERCHAT_NICK_LIMIT];
 };
 
+struct blakeRegister {
+  blake_byte_t username[OVERCHAT_NICK_LIMIT];
+  blake_byte_t email[OVERCHAT_EMAIL_LIMIT];
+  blake_byte_t reserved[64];
+};
+
 /* What a packet looks like */
 struct blakePacket {
   blake_word16_t len; /* Length of complete packet and extended packet, including self */
     struct blakeChumIdle _chumidle;
     struct blakeLoginReply _loginreply;
     struct blakeIsOnlineReply _isonlinereply;
+    struct blakeRegisterReply _registerreply;
     /* ---- client side type packets ---- */
     struct blakeLogin _login;
     struct blakeSuperRequest _superrequest;
     struct blakeChumRemove _chumremove;
     struct blakeIdle _idle;
     struct blakeIsOnline _isonline;
+    struct blakeRegister _register;
   } info; /* Packet dependent portion */
   blake_word16_t extendedPacketLength; /* If any data follows the packet's fixed structure it's length is here, read on for dynamic messages such as IM */
 };
   initialisation automatically.  However, if you rely on this and don't
   call this function, the code won't port to other platforms.
 */
-bool BLAKEAPI blake_Init(void);
+BLAKEAPI(bool) blake_Init(void);
 
 /*
   Before a process exits, it is expected to call blake_Cleanup() as a matter
   with this cleanup automatically.  However, if you rely on this and don't
   call this function, the code won't port to other platforms.
 */
-bool BLAKEAPI blake_Cleanup(void);
+BLAKEAPI(bool) blake_Cleanup(void);
 
 /*
   When blakeError codes are returned from the Blake library and the
   of the string which would have been returned, this allows the caller
   to allocate a buffer to copy the string.
 */
-unsigned int BLAKEAPI blake_GetErrorMessage(const enum blakeError BlakeError, char* Buff, size_t MaxSize, enum blakeLang Language);
+BLAKEAPI(unsigned int) blake_GetErrorMessage(const enum blakeError BlakeError, char* Buff, size_t MaxSize, enum blakeLang Language);
 
 /*
   In order for code to dynamically determine the number of error messages
   doesn't accept a language modifier.  It is not possible to enumerate
   all languages presently.
 */
-unsigned int BLAKEAPI blake_GetNumberOfErrorMessages(void);
+BLAKEAPI(unsigned int) blake_GetNumberOfErrorMessages(void);
 
 /*
   OverChat; being a very large project often gets confusing and is hard
   call this function wherever you do not know if code is executing or not.
   Use the macro blake_Trace( ), not the direct call to blake_dTrace( ).
 */
-void BLAKEAPI blake_dTrace(const char* File, const unsigned int Line, const char* Message);
+BLAKEAPI(void) blake_dTrace(const char* File, const unsigned int Line, const char* Message);
 #define blake_Trace(msg) \
           blake_dTrace(__FILE__, __LINE__, (msg))
 
   This typically means that the process is out of memory.  There is
   no arbitary limit on the number of mutants a process may make.
 */
-BLAKE_MUTANT_HANDLE BLAKEAPI blake_CreateMutant(void);
+BLAKEAPI(BLAKE_MUTANT_HANDLE) blake_CreateMutant(void);
 
 /*
   To lock a mutant, call this function, failures cannot be seen for speed,
   behaviour must not be relied upon and I may exclude this behaviour at some
   point to force compatibilly with POSIX.
 */
-void BLAKEAPI blake_LockMutant(BLAKE_MUTANT_HANDLE MutantHandle);
+BLAKEAPI(void) blake_LockMutant(BLAKE_MUTANT_HANDLE MutantHandle);
 
 /*
   blake_TryLockMutant() was added to support an attempt to lock a mutant
   interface.  The function returns false if the mutant cannot be immediately
   locked.
 */
-bool BLAKEAPI blake_TryLockMutant(BLAKE_MUTANT_HANDLE MutantHandle);
+BLAKEAPI(bool) blake_TryLockMutant(BLAKE_MUTANT_HANDLE MutantHandle);
 
 /*
   It is critical that a locked mutant be unlocked as soon as possible,
   failure to unlock a mutant could result in a deadlocked thread.
 */
-void BLAKEAPI blake_UnlockMutant(BLAKE_MUTANT_HANDLE MutantHandle);
+BLAKEAPI(void) blake_UnlockMutant(BLAKE_MUTANT_HANDLE MutantHandle);
 
 /*
   Once a mutant has no further use, it should be destroyed.  It should
   not be destroyed whilst it is locked.  If so, the behaviour is
   undefined.  Don't do it.
 */
-void BLAKEAPI blake_DestroyMutant(BLAKE_MUTANT_HANDLE MutantHandle);
+BLAKEAPI(void) blake_DestroyMutant(BLAKE_MUTANT_HANDLE MutantHandle);
 
 /*
   This function simply validates if a mustant handle is valid.  It
   returns no other information about the state of the mutant.  It
   cannot be used for recursive mutants.
 */
-bool BLAKEAPI blake_ValidateMutant(const BLAKE_MUTANT_HANDLE MutantHandle);
+BLAKEAPI(bool) blake_ValidateMutant(const BLAKE_MUTANT_HANDLE MutantHandle);
 
 /*
   The following functions work in the same way as the normal mutant
   have wrapped mutants with a C++ wrapper it should pass on the correct
   details and not give the line number of the actual call.
 */
-BLAKE_MUTANT_HANDLE BLAKEAPI blake_DebugCreateMutant(const char* SourceFile, const unsigned int SourceLine);
-void BLAKEAPI blake_DebugLockMutant(BLAKE_MUTANT_HANDLE MutantHandle, const char* SourceFile, const unsigned int SourceLine);
-bool BLAKEAPI blake_DebugTryLockMutant(BLAKE_MUTANT_HANDLE MutantHandle, const char* SourceFile, const unsigned int SourceLine);
-void BLAKEAPI blake_DebugUnlockMutant(BLAKE_MUTANT_HANDLE MutantHandle, const char* SourceFile, const unsigned int SourceLine);
-void BLAKEAPI blake_DebugDestroyMutant(BLAKE_MUTANT_HANDLE MutantHandle, const char* SourceFile, const unsigned int SourceLine);
-bool BLAKEAPI blake_DebugValidateMutant(const BLAKE_MUTANT_HANDLE MutantHandle, const char* SourceFile, const unsigned int SourceLine);
+BLAKEAPI(BLAKE_MUTANT_HANDLE) blake_DebugCreateMutant(const char* SourceFile, const unsigned int SourceLine);
+BLAKEAPI(void) blake_DebugLockMutant(BLAKE_MUTANT_HANDLE MutantHandle, const char* SourceFile, const unsigned int SourceLine);
+BLAKEAPI(bool) blake_DebugTryLockMutant(BLAKE_MUTANT_HANDLE MutantHandle, const char* SourceFile, const unsigned int SourceLine);
+BLAKEAPI(void) blake_DebugUnlockMutant(BLAKE_MUTANT_HANDLE MutantHandle, const char* SourceFile, const unsigned int SourceLine);
+BLAKEAPI(void) blake_DebugDestroyMutant(BLAKE_MUTANT_HANDLE MutantHandle, const char* SourceFile, const unsigned int SourceLine);
+BLAKEAPI(bool) blake_DebugValidateMutant(const BLAKE_MUTANT_HANDLE MutantHandle, const char* SourceFile, const unsigned int SourceLine);
 
 /*
   If you have defined DEBUG I default to redirecting normal mutant
   If it fails it will return false, no cleanup is neccersary in this case.
   Normally, cleanup is required with blake_DestroyRecursiveMutant()
 */
-bool BLAKEAPI blake_InitRecursiveMutant(recursiveMutant* PMutant);
+BLAKEAPI(bool) blake_InitRecursiveMutant(recursiveMutant* PMutant);
 
 /*
   When a recursive mutant has no further use, destroy it with this
   function.  Do not destroy mutants which are locked.
 */
-void BLAKEAPI blake_DestroyRecursiveMutant(recursiveMutant* PMutant);
+BLAKEAPI(void) blake_DestroyRecursiveMutant(recursiveMutant* PMutant);
 
 /*
   To lock a recursive mutant, don't use the ordinary mutant locker,
   use this function.  The calling thread's ID must be passed so
   recursive mutants can keep track of the right owners.
 */
-void BLAKEAPI blake_LockRecursiveMutant(recursiveMutant* PMutant, const int ThreadID);
+BLAKEAPI(void) blake_LockRecursiveMutant(recursiveMutant* PMutant, const int ThreadID);
 
 /*
   To unlock a recursive mutant which must be done an equal number of time
   as locking by the thread which locked the mutant, call this function.
   The current thread's ID must be passed.
 */
-void BLAKEAPI blake_UnlockRecursiveMutant(recursiveMutant* PMutant, const int ThreadID);
+BLAKEAPI(void) blake_UnlockRecursiveMutant(recursiveMutant* PMutant, const int ThreadID);
 
 /*
   A critical integer is a very useful object which is an integer which is
   call critInt_Init() and after the object is finished with call
   critInt_Destroy()
 */
-void BLAKEAPI blake_InitCriticalInteger(critInt* CriticalInteger); /* Initialize a critical integer */
-void BLAKEAPI blake_DestroyCriticalInteger(critInt* CriticalInteger); /* Destroy & cleanup a critical integer */
+BLAKEAPI(void) blake_InitCriticalInteger(critInt* CriticalInteger); /* Initialize a critical integer */
+BLAKEAPI(void) blake_DestroyCriticalInteger(critInt* CriticalInteger); /* Destroy & cleanup a critical integer */
 
 /*
   To portably cause a timed blocking event call this function.  It will
   the return value, it will only fail if Blake is not initialised.
   Zero can be used to surrender the calling thread's timeslice.
 */
-enum blakeError BLAKEAPI blake_Sleep(unsigned int Seconds);
+BLAKEAPI(enum blakeError) blake_Sleep(unsigned int Seconds);
 
 /*
   Alternatively for finer precision use blake_SleepMS() which is times
   in 1000ths of a second.
 */
-enum blakeError BLAKEAPI blake_SleepMS(unsigned int Seconds);
+BLAKEAPI(enum blakeError) blake_SleepMS(unsigned int Seconds);
 
 /*
   This is a linked list based on pointers, it's used for all sorts
   list based on pointers, however, zero sized NodeSizes are logically
   corrected to prevent a crash to 1 byte.
 */
-void BLAKEAPI blake_InitLinkPtrs(struct blake_link_ptrs* Obj, size_t NodeSize);
-void BLAKEAPI blake_DebugInitLinkPtrs(const char* SourceFile, const unsigned int SourceLine, struct blake_link_ptrs* Obj, size_t NodeSize);
+BLAKEAPI(void) blake_InitLinkPtrs(struct blake_link_ptrs* Obj, size_t NodeSize);
+BLAKEAPI(void) blake_DebugInitLinkPtrs(const char* SourceFile, const unsigned int SourceLine, struct blake_link_ptrs* Obj, size_t NodeSize);
 
 #if ( defined(DEBUG) && !defined(BLAKE_LL_SOURCE) )
 # define blake_InitLinkPtrs(o, ns) \
   is not guarenteed to be accurate and was an add on to the linked
   list after the design was long since finished.
 */
-void BLAKEAPI blake_DebugDumpLinkLists(void);
+BLAKEAPI(void) blake_DebugDumpLinkLists(void);
 #endif /*DEBUG*/
 
 /*
   later.  Do not over do any of these values or blakeNotEnoughMem will
   return.
 */
-enum blakeError BLAKEAPI blake_InitFastQueue(struct blakeFastQueue* PQueue, const unsigned int UBound, const size_t ElemSize);
+BLAKEAPI(enum blakeError) blake_InitFastQueue(struct blakeFastQueue* PQueue, const unsigned int UBound, const size_t ElemSize);
 
 /*
   To add an item to the back of the queue call this function.
   data basis into the back of the queue.  It shall not be topped
   until all other pending items in front of it have been popped.
 */
-enum blakeError BLAKEAPI blake_PushFastQueue(struct blakeFastQueue* PQueue, const void* NewItem);
+BLAKEAPI(enum blakeError) blake_PushFastQueue(struct blakeFastQueue* PQueue, const void* NewItem);
 
 /*
   To "top" a fast queue, call this function with a pointer to the
   is returned and the element is cleared.  The same element will
   always be returned until the queue is popped.
 */
-enum blakeError BLAKEAPI blake_TopFastQueue(struct blakeFastQueue* PQueue, void* PReceiveItem, const size_t SizeItem);
+BLAKEAPI(enum blakeError) blake_TopFastQueue(struct blakeFastQueue* PQueue, void* PReceiveItem, const size_t SizeItem);
 
 /*
   This function "pops" a queue.  What that means is that the element
   at the front of the queue is discarded, normally done after "topping"
   the queue.
 */
-enum blakeError BLAKEAPI blake_PopFastQueue(struct blakeFastQueue* PQueue);
+BLAKEAPI(enum blakeError) blake_PopFastQueue(struct blakeFastQueue* PQueue);
 
 /*
   This functions is a simple call which does not return extended
   with the Count variable but is inadvisable, CountFastQueue()
   follows proper locking symantics.
 */
-unsigned int BLAKEAPI blake_CountFastQueue(struct blakeFastQueue* PQueue);
+BLAKEAPI(unsigned int) blake_CountFastQueue(struct blakeFastQueue* PQueue);
 
 /*
   In order to free the resources allocated inside a fast queue
   to free.  This function will fail gracefully with a blakeBadObject
   if you try it.
 */
-enum blakeError BLAKEAPI blake_DestroyFastQueue(struct blakeFastQueue* PQueue);
+BLAKEAPI(enum blakeError) blake_DestroyFastQueue(struct blakeFastQueue* PQueue);
 
 /*
   If a client receives data from the server, it contains a raw stream (TCOP)
   if the callback was executed but failed for whatever reason.  Two is
   returned if the callback was called and reported success.
 */
-enum blakeError BLAKEAPI blake_CrackPacket(int Socket, const void* PacketBuffer, const size_t BufferLength);
+BLAKEAPI(enum blakeError) blake_CrackPacket(int Socket, const void* PacketBuffer, const size_t BufferLength);
 
 /*
   In order to handle logging messages which Blake sometimes
   to capture them.  This is a per-process thing.  To stop handling
   messages again call this again with the argument NULL.
 */
-void BLAKEAPI blake_InstallLogger(void (*Handler)(const char* Message));
+BLAKEAPI(void) blake_InstallLogger(void (*Handler)(const char* Message));
 
 /*
   When a packet has been received by the server or the client and has
   is acceptable or your own numbering system.  but don't get the two systems
   confused!
 */
-enum blakeError BLAKEAPI blake_InstallCallback(const int ThreadID, bool IsServer, WORD Code, bool (*UserCallback)(int, const void*, const void*));
+BLAKEAPI(enum blakeError) blake_InstallCallback(const int ThreadID, bool IsServer, WORD Code, bool (*UserCallback)(int, const void*, const void*));
 
 /*
   Networking
   connection.  This function does not generally fail, unless Blake has
   not been initialised.
 */
-enum blakeError BLAKEAPI network_InstallBrokenPipeCallback(void (*NewCallback)(int SockDesc));
+BLAKEAPI(enum blakeError) network_InstallBrokenPipeCallback(void (*NewCallback)(int SockDesc));
 
 /*
   To close a socket previously created by network_CreateSocket(), call
   this function.  The function returns no value.  This is way to
   break a connection to the server/client.
 */
-void BLAKEAPI network_CloseSocket(int SocketDesc);
+BLAKEAPI(void) network_CloseSocket(int SocketDesc);
 
 /*
   To create a net socket of type int call network_CreateSocket().
   See other manuals for in depth conversation on this.
   On failure the function returns -1.
 */
-int BLAKEAPI network_CreateSocket(bool IPv6, bool Datagram, bool NonBlocking);
+BLAKEAPI(int) network_CreateSocket(bool IPv6, bool Datagram, bool NonBlocking);
 
 
 /*
   I have provided this nice, portable way of switching the socket
   mode.
 */
-void BLAKEAPI network_MakeNonBlocking(int SocketDesc);
+BLAKEAPI(void) network_MakeNonBlocking(int SocketDesc);
 
 /*
   The traditonal resolvers for UNIX and WinSock were not thread safe,
   can fail for other reasons such as bad parameters or library not
   initialised.
 */
-enum blakeError BLAKEAPI network_Resolve(const char* HostNameIn, OVERCHAT_IP* IPOut);
+BLAKEAPI(enum blakeError) network_Resolve(const char* HostNameIn, OVERCHAT_IP* IPOut);
 
 /*
   It is simple to determine whether an IP is zero or not but this
   returns false if the IP is OK.  It returns true if no address is passed
   or the IP is zero (for example 0.0.0.0).
 */
-bool BLAKEAPI network_IsZeroIP(const OVERCHAT_IP* PIP);
+BLAKEAPI(bool) network_IsZeroIP(const OVERCHAT_IP* PIP);
 
 /*
   This function is experimental, it prints an IP to stdout but may be
   scrapped as it is of limited use, it might be better to use the Get
   IP as string function.
 */
-void BLAKEAPI network_PrintIP(const OVERCHAT_IP* IP);
+BLAKEAPI(void) network_PrintIP(const OVERCHAT_IP* IP);
 
 /*
   This function compares two IPs and returns true if they are the same,
   that is, NULL and NULL match (true), NULL and an IP, even if that IP is
   zero, do not match (false).
 */
-bool BLAKEAPI network_CompareIP(const OVERCHAT_IP* IP1, const OVERCHAT_IP* IP2);
+BLAKEAPI(bool) network_CompareIP(const OVERCHAT_IP* IP1, const OVERCHAT_IP* IP2);
 
 /*
   This function cracks an a traditional IP (32-bit value), IPv4 from a
   functions such as get as string.  It splits apart the DWORD into the
   four byte portions ready for dotted notation.
 */
-enum blakeError BLAKEAPI network_CrackIPv4(const DWORD dwIPIn, OVERCHAT_IP* IPOut);
+BLAKEAPI(enum blakeError) network_CrackIPv4(const DWORD dwIPIn, OVERCHAT_IP* IPOut);
 
 /*
   See the above cracker, this function re-concatinates the IP into
   a DWORD for easy and smaller storage and for network interaction.
 */
-enum blakeError BLAKEAPI network_DecrackIPv4(const OVERCHAT_IP* IPIn, DWORD* dwIPOut);
+BLAKEAPI(enum blakeError) network_DecrackIPv4(const OVERCHAT_IP* IPIn, DWORD* dwIPOut);
 /*
   This function connects a client to the server.  A socket open on the
   client side should be passed.  The socket should have been returned
   returns blakeSuccess then the socket has been successfully connected to
   the server, congratulation.
 */
-enum blakeError BLAKEAPI network_Connect(int Socket, bool IPv6, const unsigned short int Port, const OVERCHAT_IP* IP);
+BLAKEAPI(enum blakeError) network_Connect(int Socket, bool IPv6, const unsigned short int Port, const OVERCHAT_IP* IP);
 /*
   To allow your program to be called when raw data arrives on a socket,
   a special raw data callback must be installed.  Simply pass the number
   callback you must return as soon as possible as you will be stalling
   the pending loop.  The function can fail if there is already an
   assosiated callback.  To remove a callback first pass NULL.  Passing
-  -1 and NULL removes all callbacks, passing -1 and an address of a call-
-  back is illegal.  Note: The callback returns nothing and accepts the
-  socket number.
+  -1 and NULL removes all callbacks, passing -1 and an address of an
+  existing call-back is illegal.  Passing -1 and a new callback causes
+  the callback to be called for all sockets Blake knows about.
+  Note: The callback returns nothing and accepts the socket number.
 */
-enum blakeError BLAKEAPI network_InstallIncomingCallback(int Socket, void (*DataReader)(int S));
+BLAKEAPI(enum blakeError) network_InstallIncomingCallback(int Socket, void (*DataReader)(int S));
 
 /*
   Attention: This is an import function, one outgoing callback is allowed per
     blakeRegAlready - This already was the callback (redundant)
     blakeNotStarted - Blake was not started
 */
-enum blakeError BLAKEAPI network_InstallOutgoingCallback(void (*Sender)(int Socket, const void* RawData, size_t RawDataSize));
+BLAKEAPI(enum blakeError) network_InstallOutgoingCallback(void (*Sender)(int Socket, const void* RawData, size_t RawDataSize));
 
 /*
   This function returns the next available socket for writing.  It returns
   process.  In order for Blake to know which sockets to test for writabillty,
   the process must have installed them with network_InstallIncomingCallback( ).
 */
-int BLAKEAPI network_ReturnWritableSocket(void);
+BLAKEAPI(int) network_ReturnWritableSocket(void);
+
+/*
+  This function initialises the IP, effectively a call to network_LoadIP()
+  with NULL as a source.  Do not use with IPv6 IPs
+*/
+BLAKEAPI(enum blakeError) network_InitIPv4(OVERCHAT_IP* PIP);
 
 /*
   This is the Blake pending loop.  It must be called frequently in order
   from inside any callback such as those installed by
   network_InstallRawCallback() can deadlock the thread.
 */
-void BLAKEAPI blake_PendingLoop(bool RunForever);
+BLAKEAPI(void) blake_PendingLoop(bool RunForever);
 /*
   When the pending loop is running in 'RunForever' mode it should
   be cancelled before the process is cleaned up.  To do this
   will return.  When pending loop is used is not running in
   'RunForever' mode, this function has no effect whatsoever.
 */
-void BLAKEAPI blake_CancelPendingLoop(void);
-bool BLAKEAPI network_Write(int SocketDesc, const void* Buffer, const size_t BufferSize);
-int BLAKEAPI network_Read(int SocketDesc, void* Buffer, const size_t BufferSize); /* This works the same way as recv() */
-void BLAKEAPI network_LoadIP(OVERCHAT_IP* PDest, OVERCHAT_IP* PSource); /* Copies an IP address, NULL as PSource maybe used to init an IP address */
-void BLAKEAPI network_GetIPOnSocket(OVERCHAT_IP* PDest, int SocketDesc); /* Loads the IP holder with the IP when given the socket descriptor for the user */
-void BLAKEAPI network_GetIPAsString(char* DestBuff, UINT DestMaxLen, OVERCHAT_IP* IPStore); /* Get IP as a string for printing */
-unsigned long int BLAKEAPI network_HostToNetLong(unsigned long int Value); /* Change byte order for network */
-unsigned short int BLAKEAPI network_HostToNetShort(unsigned short int Value);
-unsigned long int BLAKEAPI network_NetToHostLong(unsigned long int Value); /* Change byte order from network */
-unsigned short int BLAKEAPI network_NetToHostShort(unsigned short int Value);
-bool BLAKEAPI network_WriteString(int SocketDesc, const char* Str); /* Writes a string to the socket */
-bool BLAKEAPI network_WriteChar(int SocketDesc, char Char); /* Faster if you only have one byte to write */
+BLAKEAPI(void) blake_CancelPendingLoop(void);
+BLAKEAPI(bool) network_Write(int SocketDesc, const void* Buffer, const size_t BufferSize);
+BLAKEAPI(int) network_Read(int SocketDesc, void* Buffer, const size_t BufferSize); /* This works the same way as recv() */
+BLAKEAPI(void) network_LoadIP(OVERCHAT_IP* PDest, OVERCHAT_IP* PSource); /* Copies an IP address, NULL as PSource maybe used to init an IP address */
+BLAKEAPI(void) network_GetIPOnSocket(OVERCHAT_IP* PDest, int SocketDesc); /* Loads the IP holder with the IP when given the socket descriptor for the user */
+BLAKEAPI(void) network_GetIPAsString(char* DestBuff, UINT DestMaxLen, OVERCHAT_IP* IPStore); /* Get IP as a string for printing */
+BLAKEAPI(unsigned long int) network_HostToNetLong(unsigned long int Value); /* Change byte order for network */
+BLAKEAPI(unsigned short int) network_HostToNetShort(unsigned short int Value);
+BLAKEAPI(unsigned long int) network_NetToHostLong(unsigned long int Value); /* Change byte order from network */
+BLAKEAPI(unsigned short int) network_NetToHostShort(unsigned short int Value);
+BLAKEAPI(bool) network_WriteString(int SocketDesc, const char* Str); /* Writes a string to the socket */
+BLAKEAPI(bool) network_WriteChar(int SocketDesc, char Char); /* Faster if you only have one byte to write */
 
 /*
   This function is for incoming connections to the server.  This
   listening with network_StartListening().
 */
 #ifdef BLAKE_SERVER
-enum blakeError BLAKEAPI network_InstallCC(int PortSocket, void Ccb(int SocketNumber));
+BLAKEAPI(enum blakeError) network_InstallCC(int PortSocket, void Ccb(int SocketNumber));
 #endif /*BLAKE_SERVER*/
 
 /*
   change if direct instant message connection becomes possible.
 */
 #ifdef BLAKE_SERVER
-enum blakeError BLAKEAPI network_StartListening(int PortSocket, unsigned short PortNumber);
+BLAKEAPI(enum blakeError) network_StartListening(int PortSocket, unsigned short PortNumber);
 #endif /*BLAKE_SERVER*/
 
 /*
   asks a client to login with an amount of time.
 */
 #ifdef BLAKE_SERVER
-bool BLAKEAPI blake_Challenge(int Sock, USHORT MaxSecs, const unsigned char ChallengeDigest[BLAKE_MD5HASHLEN]);
-bool BLAKEAPI blake_LoginReply(int Sock, enum blakeLoginReplyCode LoginReplyCode);
+BLAKEAPI(bool) blake_Challenge(int Sock, USHORT MaxSecs, const unsigned char ChallengeDigest[BLAKE_MD5HASHLEN]);
+BLAKEAPI(bool) blake_LoginReply(int Sock, enum blakeLoginReplyCode LoginReplyCode);
 #endif /*BLAKE_SERVER*/
 /*
   To login normally pass Username and Password, to login as a guest pass NULL
   defaults to langEnglish.  Other languages are supported by the server
   and will affect all OverChat system messages being passed to a user.
   OverChat cannot convert foreign user's languages so that you can talk to
-  them.  The challenge gigest will have been received when you got the challenge,
+  them.  The challenge digest will have been received when you got the challenge,
   you must know it in order for blake_Login() to generate the correct secure
-  hash for passing the password to the server.
+  hash for passing the password to the server.  The client ID and version
+  are required for securing the system against unauthorised clients.  They
+  must be correct or later security questions by the server will fail.
 */
-bool BLAKEAPI blake_Login(int Sock, const char* Username, const char* Password, enum blakeLang Language, const unsigned char ChallengeDigest[BLAKE_MD5HASHLEN]);
+BLAKEAPI(bool) blake_Login(int Sock, const char* Username, const char* Password, enum blakeLang Language, const unsigned char ChallengeDigest[BLAKE_MD5HASHLEN], const enum blakeClientID ClientID, const unsigned long ClientVersion);
 /*
   Functions called by the server to make the client "shaddup" occasionally.
   Listen to the server when you receive these packets!  Else the server
   will kill you!
 */
 #ifdef BLAKE_SERVER
-bool BLAKEAPI blake_Suspend(int Sock, const unsigned long Seconds); /* if Seconds == 0UL client waits for a resume */
-bool BLAKEAPI blake_Resume(int Sock);
+BLAKEAPI(bool) blake_Suspend(int Sock, const unsigned long Seconds); /* if Seconds == 0UL client waits for a resume */
+BLAKEAPI(bool) blake_Resume(int Sock);
 #endif /*BLAKE_SERVER*/
 
 /*
   identifiying the encryption cipher the message has been encoded with, note
   that I recommend plain text is never used over the internet.
 */
-enum blakeError BLAKEAPI blake_Msg(int Sock, const char* NickName, const char* Msg, enum blakeCipherID BCID);
+BLAKEAPI(enum blakeError) blake_Msg(int Sock, const char* NickName, const char* Msg, enum blakeCipherID BCID);
 
 /*
   blake_Msg2() is the function which doesn't message a user, it is very
   similar to blake_Msg(), except that it messages the server (or the client).
   Bi-directional just like IM type messages.
 */
-enum blakeError BLAKEAPI blake_Msg2(int Sock, const char* Msg);
+BLAKEAPI(enum blakeError) blake_Msg2(int Sock, const char* Msg);
 
 /*
   blake_Whois() is a function which requests whois info about a person who
   When a whois is requested, a whois info is returned, so ensure you
   have a callback to collect the data when it comes through.
 */
-enum blakeError BLAKEAPI blake_Whois(int Sock, const char* NickName);
+BLAKEAPI(enum blakeError) blake_Whois(int Sock, const char* NickName);
 
 /*
   blake_WhoisInfo() is a server side only function which is used to reply
   structure is modified.
 */
 #ifdef BLAKE_SERVER
-enum blakeError BLAKEAPI blake_WhoisInfo(int Sock, const struct blakeWhoisInfo* PWhoisInfo);
+BLAKEAPI(enum blakeError) blake_WhoisInfo(int Sock, const struct blakeWhoisInfo* PWhoisInfo);
 #endif /*BLAKE_SERVER*/
 
 /*
   is not returned to indicate to whom the isOnline was addressed, only the
   client really knows.
 */
-enum blakeError BLAKEAPI blake_IsOnline(int Sock, const char* NickName);
+BLAKEAPI(enum blakeError) blake_IsOnline(int Sock, const char* NickName);
 #ifdef BLAKE_SERVER
-enum blakeError BLAKEAPI blake_IsOnlineReply(int Sock, const char* NickName, bool Yes);
+BLAKEAPI(enum blakeError) blake_IsOnlineReply(int Sock, const char* NickName, bool Yes);
 #endif /*BLAKE_SERVER*/
 
 /*
   (clearance) level and the server to reply with the privellege.
   Set reserved to zero.
 */
-enum blakeError BLAKEAPI blake_SuperRequest(int Sock, blake_word8_t Reserved);
+BLAKEAPI(enum blakeError) blake_SuperRequest(int Sock, blake_word8_t Reserved);
 #ifdef BLAKE_SERVER
-enum blakeError BLAKEAPI blake_Super(int Sock, blake_word8_t Clearance);
+BLAKEAPI(enum blakeError) blake_Super(int Sock, blake_word8_t Clearance);
 #endif /*BLAKE_SERVER*/
 
 /*
   is used when somebody you're messing isn't online, etc.  Note:
   The Snear is used to tell the user they are a loser generally.
 */
-enum blakeError BLAKEAPI blake_Kill(int Sock, const char* NickName, const char* Snear);
+BLAKEAPI(enum blakeError) blake_Kill(int Sock, const char* NickName, const char* Snear);
 #ifdef BLAKE_SERVER
-enum blakeError BLAKEAPI blake_Killed(int Sock, const char* NickOfKiller, const char* Snear);
+BLAKEAPI(enum blakeError) blake_Killed(int Sock, const char* NickOfKiller, const char* Snear);
+#endif /*BLAKE_SERVER*/
+
+/*
+  These two functions are for the purpose of registering users.  Generally
+  a client will allow a user to register a few nicknames per session.
+  It would be appreciated if client developers disable their registration
+  commands after about three nicknames and re-enable them in a few hours
+  to prevent abuse.  This is a measure to protect the registration system
+  while the server developer(s) find a way to block abuse on the server side.
+*/
+BLAKEAPI(enum blakeError) blake_Register(int Sock, const char* Nick, const char* Email);
+#ifdef BLAKE_SERVER
+BLAKEAPI(enum blakeError) blake_RegisterReply(int Sock, const enum blakeRegisterReplyCode ReplyCode, const char* Password);
 #endif /*BLAKE_SERVER*/
 
 /*
   can be written to the packet's len member so that the other side of
   the conversation can read the packet and know when it truely ends.
 */
-blake_word16_t BLAKEAPI blake_RecalculateRealPktSz(struct blakePacket* PPacket);
+BLAKEAPI(blake_word16_t) blake_RecalculateRealPktSz(struct blakePacket* PPacket);
 
 /*
   This function may do nothing depending on what version of Blake
   indicated as having memory allocated by the name of blake_fastqueue.c
   you know a queue is allocated etc.
 */
-void BLAKEAPI blake_DebugDump(const char* FileName);
+BLAKEAPI(void) blake_DebugDump(const char* FileName);
 
 /*
   If you encounter a deadlock and you use mutants in your program,
   debug information about the state and owner of the affected mutant
   to stderr.
 */
-enum blakeError BLAKEAPI blake_DeadMan(void);
+BLAKEAPI(enum blakeError) blake_DeadMan(void);
 
 /*
   Here's another debugging function, call this to dump the entire
   is present in the build of Blake.  Either mutant logging has to
   be on or the dead man has to be included.
 */
-enum blakeError BLAKEAPI blake_MutantDump(void);
+BLAKEAPI(enum blakeError) blake_MutantDump(void);
 
 /*
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   Always ensure the handle is unlocked before releasing it.  Releasing
   is done by blakedb_DestroyDBHandle( ).
 */
-enum blakeError BLAKEAPI blakedb_CreateDBHandle(const char* InDBFN, BLAKE_DATABASE_HANDLE* PHandleOut);
+BLAKEAPI(enum blakeError) blakedb_CreateDBHandle(const char* InDBFN, BLAKE_DATABASE_HANDLE* PHandleOut);
 
 /*
   blakedb_DestroyDBHandle( )
   program clean up or whenever the database will be no longer required.
   Failure to do so will leak memory.
 */
-enum blakeError BLAKEAPI blakedb_DestroyDBHandle(BLAKE_DATABASE_HANDLE DBHandle);
+BLAKEAPI(enum blakeError) blakedb_DestroyDBHandle(BLAKE_DATABASE_HANDLE DBHandle);
 
 /*
   blakedb_LockDatabase( )
   state during this call as well as an internal mutant state change.
   Misuse of locking functions will cause a failure.
 */
-enum blakeError BLAKEAPI blakedb_LockDatabase(BLAKE_DATABASE_HANDLE DBHandle);
+BLAKEAPI(enum blakeError) blakedb_LockDatabase(BLAKE_DATABASE_HANDLE DBHandle);
 
 /*
   blakedb_UnlockDatabase( )
   may result in deadlock and will lead to a locked file which can no longer
   be accessed.
 */
-void BLAKEAPI blakedb_UnlockDatabase(BLAKE_DATABASE_HANDLE DBHandle);
+BLAKEAPI(void) blakedb_UnlockDatabase(BLAKE_DATABASE_HANDLE DBHandle);
 
 /*
   blakedb_RemoteBackup( )
   via a dedicated email address which should receive nothing else!
 */
 #ifdef BLAKE_SERVER
-bool BLAKEAPI blakedb_RemoteBackup(const char* DBFN);
+BLAKEAPI(bool) blakedb_RemoteBackup(const char* DBFN);
 #endif /*BLAKE_SERVER*/
 
 /*
   a record's saving and check it on it's retrieval.  However, it may be useful
   for repair tools.
 */
-blake_word16_t BLAKEAPI blakedb_Checksum16(const struct blakedb_User* UserRecord);
+BLAKEAPI(blake_word16_t) blakedb_Checksum16(const struct blakedb_User* UserRecord);
 
 /*
   blakedb_GetUserData( )
   only), the function may return blakeDbRecordCorrupt.  Should this happen,
   take evasive action, the best thing to do is to delete the user.
 */
-enum blakeError BLAKEAPI blakedb_GetUserData(BLAKE_DATABASE_HANDLE DBH, unsigned int UserIndex, struct blakedb_User* PUserData, size_t SizeOfUserData);
+BLAKEAPI(enum blakeError) blakedb_GetUserData(BLAKE_DATABASE_HANDLE DBH, unsigned int UserIndex, struct blakedb_User* PUserData, size_t SizeOfUserData);
 
 /*
   blakedb_CreateUser( )
   for the caller to worry about this.  Any checksum sent to the creator will
   be disregarded and overwritten.
 */
-enum blakeError BLAKEAPI blakedb_CreateUser(BLAKE_DATABASE_HANDLE DBH, struct blakedb_User* PNewUserDataIn, unsigned int* PUserIndexOut);
+BLAKEAPI(enum blakeError) blakedb_CreateUser(BLAKE_DATABASE_HANDLE DBH, struct blakedb_User* PNewUserDataIn, unsigned int* PUserIndexOut);
 
 /*
   blakedb_GetUserIndex( )
   to see if the person you're looking for is real.  NickName is not
   case sensitive.
 */
-unsigned int BLAKEAPI blakedb_GetUserIndex(BLAKE_DATABASE_HANDLE DBHandle, const char* NickName);
+BLAKEAPI(unsigned int) blakedb_GetUserIndex(BLAKE_DATABASE_HANDLE DBHandle, const char* NickName);
 
 /*
   This simple function initialises a blakedb_User structure.
 */
-void BLAKEAPI blakedb_InitUser(struct blakedb_User* PUserData, size_t UserDataSz);
+BLAKEAPI(void) blakedb_InitUser(struct blakedb_User* PUserData, size_t UserDataSz);
 
 /*
   This function sets an exisitng user record with updated data.
   The Checksum field in the user record will be automatically recalculated
   before it is stored, there is no need to manually change this field.
 */
-enum blakeError BLAKEAPI blakedb_UpdateUser(BLAKE_DATABASE_HANDLE DBHandle, unsigned int Index, struct blakedb_User* NewUserRecord, size_t UserRecordSz);
+BLAKEAPI(enum blakeError) blakedb_UpdateUser(BLAKE_DATABASE_HANDLE DBHandle, unsigned int Index, struct blakedb_User* NewUserRecord, size_t UserRecordSz);
 
 /*
   This functions allows one to retrieve the header of the database.  Usually
   people don't bother with this.
 */
-enum blakeError BLAKEAPI blakedb_GetHeader(BLAKE_DATABASE_HANDLE DBHandle, struct blakedb_Header* PHeaderOut);
+BLAKEAPI(enum blakeError) blakedb_GetHeader(BLAKE_DATABASE_HANDLE DBHandle, struct blakedb_Header* PHeaderOut);
 
 /*
   This function allows one to count how many users have been registered,
   database (it doesn't really exist), don't forget these rules when using
   the database yourself.
 */
-unsigned long int BLAKEAPI blakedb_CountUsers(BLAKE_DATABASE_HANDLE DBHandle);
+BLAKEAPI(unsigned long int) blakedb_CountUsers(BLAKE_DATABASE_HANDLE DBHandle);
 
 /*
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   is illegal.
   If the nick is too long the TooLong flag is set.
 */
-bool BLAKEAPI blake_NickTest(const char* Nickname, bool* PTooLong, char* PSingleInvalidCharacter);
+BLAKEAPI(bool) blake_NickTest(const char* Nickname, bool* PTooLong, char* PSingleInvalidCharacter);
 
 /*
   This function works in exactly the same way as the nickname tester but it
   is designed for passwords.
 */
-bool BLAKEAPI blake_PassTest(const char* Password, bool* PTooLong, char* PSingleInvalidCharacter);
+BLAKEAPI(bool) blake_PassTest(const char* Password, bool* PTooLong, char* PSingleInvalidCharacter);
 
 /*
   blake_NickCompare( ) returns true if the nicks are the same false if
   they are not.  "Toad" and "t   oaD" are deemed the same nick.
   "David" and "dA v1d" are not.
 */
-bool BLAKEAPI blake_NickCompare(const char* Nick1, const char* Nick2);
+BLAKEAPI(bool) blake_NickCompare(const char* Nick1, const char* Nick2);
 #define blake_ChatCompare(cr1, cr2) \
           blake_NickCompare((cr1), (cr2))
 
   converts to uppercase for the comparision and strips and trailing or
   leading space.
 */
-bool BLAKEAPI blake_EmailCompare(const char* Email1, const char* Email2);
+BLAKEAPI(bool) blake_EmailCompare(const char* Email1, const char* Email2);
 
 /*
   blake_NickRude( ) returns true if a nickname is considered to be rude.
   that substring using nicks like: fucktard, shitfaced and cuntbreath
   cannot be used.
 */
-bool BLAKEAPI blake_NickRude(const char* RudeFileName, const char* Nick);
+BLAKEAPI(bool) blake_NickRude(const char* RudeFileName, const char* Nick);
 
 /*
   blake_RandPass( ) returns a password of random length containing
   Reinit is used to determine whether Blake reseeds the random number
   generator.  It takes five seconds to seed the generator.
 */
-enum blakeError BLAKEAPI blake_RandPass(char* BufferOut, size_t BuffSize, bool Reinit);
+BLAKEAPI(enum blakeError) blake_RandPass(char* BufferOut, size_t BuffSize, bool Reinit);
 
 /*
   This function is used to convert a security clearance level into a user
   should be passed so the function can avoid overwriting a buffer which is
   not large enough.
 */
-unsigned int BLAKEAPI blake_GetClearanceString(unsigned int Level, char* Buff, size_t MaxBuffSize);
+BLAKEAPI(unsigned int) blake_GetClearanceString(unsigned int Level, char* Buff, size_t MaxBuffSize);
+
+/*
+  Elite script kiddies like to speak in a silly way.  It's a load of hassle
+  to master.  You can use this function in a client to allow the user to
+  use it automatically.  The source message is modified, there is no reliable
+  way to reverse the effect.
+*/
+BLAKEAPI(enum blakeError) blake_13375p34k(char* Message);
 
 /*
   Blake has some ANSI replacements for things which aren't natively available
   worrying that the functions may not exist on the target machine.
   They work exactly the same as the normal non-ANSI C equivilants.
 */
-int BLAKEAPI blake_stricmp(const char* s1, const char* s2);
+BLAKEAPI(int) blake_stricmp(const char* s1, const char* s2);
 
-char* BLAKEAPI blake_strlwr(char* s);
-char* BLAKEAPI blake_strupr(char* s);
-char* BLAKEAPI blake_strdup(const char* s);
+BLAKEAPI(char*) blake_strlwr(char* s);
+BLAKEAPI(char*) blake_strupr(char* s);
+BLAKEAPI(char*) blake_strdup(const char* s);
 
 /*
   Raw strip manipulation functions which have never been in C languages to my
   knowledge.
 */
-void BLAKEAPI blake_LTrim(char* Str);
-void BLAKEAPI blake_RTrim(char* Str);
-void BLAKEAPI blake_Trim(char* Str);
+BLAKEAPI(void) blake_LTrim(char* Str);
+BLAKEAPI(void) blake_RTrim(char* Str);
+BLAKEAPI(void) blake_Trim(char* Str);
 
 /************************************************************************
   Blake non-portable file system support.  Internally, these things are
   the function.  Always check the return value before checking values.
   If anything other than blakeSuccess, do not close the handle.
 */
-enum blakeError BLAKEAPI blake_ExclusiveFileOpen(const char* FileName, bool NeedWrite, FILE** PHandle);
+BLAKEAPI(enum blakeError) blake_ExclusiveFileOpen(const char* FileName, bool NeedWrite, FILE** PHandle);
 
 /*
   This function must only be used on handles returned from
   handle but I need more information on this.  I presently do not unlock
   on UNIX.
 */
-void BLAKEAPI blake_ExclusiveFileClose(FILE* Handle);
+BLAKEAPI(void) blake_ExclusiveFileClose(FILE* Handle);
 
 /*
   Language features (blake_lang.c).
   not modify the returned pointer as it it part of a Blake internal
   array.  If the language is unknown, NULL is returned.
 */
-const char* BLAKEAPI blake_LangShortcut(enum blakeLang LangCode);
+BLAKEAPI(const char*) blake_LangShortcut(enum blakeLang LangCode);
 
 /*
   blake_LangName() returns the name of the language in the language
   language" is returned in whatever language you select.  If both languages
   are unknown, the message "unknown language" is returned in English.
 */
-const char* BLAKEAPI blake_LangName(enum blakeLang LangCode, enum blakeLang InLanguage);
+BLAKEAPI(const char*) blake_LangName(enum blakeLang LangCode, enum blakeLang InLanguage);
 
 /***********************************************************************
   OverChat safe memory allocations section.  Use this in your clients
   treating the block differently (virtual/real) and the file might be already
   outside limits.
 */
-enum blakeError BLAKEAPI blake_SafeAllocateGetBlockFlags(BLAKE_SA_HANDLE Handle, BLAKE_SA_FLAGS* PFlagsOut);
+BLAKEAPI(enum blakeError) blake_SafeAllocateGetBlockFlags(BLAKE_SA_HANDLE Handle, BLAKE_SA_FLAGS* PFlagsOut);
 
 /*
   Safe allocator's main function to allocate new memory.  The memory which
   Always use BLAKE_SA_FLAGS_DEFAULT as the flags unless you know what
   you're doing.  That function will apply defaults to the flags.
 */
-enum blakeError BLAKEAPI blake_SafeAllocate(unsigned long int Size, BLAKE_SA_FLAGS Flags, BLAKE_SA_HANDLE* PHandleOut);
+BLAKEAPI(enum blakeError) blake_SafeAllocate(unsigned long int Size, BLAKE_SA_FLAGS Flags, BLAKE_SA_HANDLE* PHandleOut);
 
 /*
   Safe allocate limits only matter if the block was created with
   a self growing array to a stupid size, if not using growable arrays
   it is useless.
 */
-enum blakeError BLAKEAPI blake_SetSafeAllocateLimits(BLAKE_SA_HANDLE Handle, unsigned long int Minimum, unsigned long int Maximum);
+BLAKEAPI(enum blakeError) blake_SetSafeAllocateLimits(BLAKE_SA_HANDLE Handle, unsigned long int Minimum, unsigned long int Maximum);
 
 /*
   To free a block which has been allocated earlier use this function, it
   is essential that it is used.  Blake will trap anything not freed with a
   fatal crash.  Blake will fire a fatal trap if the handle is invalid.
 */
-void BLAKEAPI blake_SafeFree(BLAKE_SA_HANDLE Handle);
+BLAKEAPI(void) blake_SafeFree(BLAKE_SA_HANDLE Handle);
 
 /*
   To get global statistics about safe allocations use this function and point
   to your structure to receive the data.
 */
-enum blakeError BLAKEAPI blake_GetSafeAllocateGlobalStats(BLAKE_SA_GSTATS* PGlobalOut);
+BLAKEAPI(enum blakeError) blake_GetSafeAllocateGlobalStats(BLAKE_SA_GSTATS* PGlobalOut);
 
 /*
   To get local statistics for a specific block use this local stats grabber.
 */
-enum blakeError BLAKEAPI blake_GetSafeAllocateLocalStats(BLAKE_SA_HANDLE Handle, BLAKE_SA_LSTATS* PLocalOut);
+BLAKEAPI(enum blakeError) blake_GetSafeAllocateLocalStats(BLAKE_SA_HANDLE Handle, BLAKE_SA_LSTATS* PLocalOut);
 
 /*
   Sets the growth factor for a block, this is useful only of the block supports
   block.  This function will fail if the block does not support growth.
   The default growth factor is BLAKE_SA_DEFAULTGROWTH.
 */
-enum blakeError BLAKEAPI blake_SetSafeAllocateGrowthFactor(BLAKE_SA_HANDLE Handle, unsigned int NewGrowthFactor);
+BLAKEAPI(enum blakeError) blake_SetSafeAllocateGrowthFactor(BLAKE_SA_HANDLE Handle, unsigned int NewGrowthFactor);
 
 /*
   The following is a last resort and should not be used if you can avoid it.
   blake_SafeAllocateResetSum() on the data!  Ottherwise corruption will
   be reported!
 */
-void* BLAKEAPI blake_SafeAllocateExposePointer(BLAKE_SA_HANDLE Handle);
+BLAKEAPI(void*) blake_SafeAllocateExposePointer(BLAKE_SA_HANDLE Handle);
 
 /*
   Manual traps are useful if you _know_ something is wrong, I can't think of
   that the TrapCode be blakeSAtrapCodeUser only to prevent confusion with
   Blake generated traps.
 */
-void BLAKEAPI blake_SafeAllocateTrap(BLAKE_SA_HANDLE Handle, enum blakeSAtrapCode TrapCode, const char* Description);
+BLAKEAPI(void) blake_SafeAllocateTrap(BLAKE_SA_HANDLE Handle, enum blakeSAtrapCode TrapCode, const char* Description);
 
 /*
   This is called internally everytime any operation is performed on a block of
   change data themselves.  It reset the internal checksum which keeps an eye
   out for corruption.
 */
-void BLAKEAPI blake_SafeAllocateResetSum(BLAKE_SA_HANDLE Handle);
+BLAKEAPI(void) blake_SafeAllocateResetSum(BLAKE_SA_HANDLE Handle);
 
 /*
   This is used to copy data into a block from a raw pointer.
   If the block is self growing the size up may fail, if it is fixed size
   or limited it's possible that a trap may occur, crashing the program.
 */
-enum blakeError BLAKEAPI blake_SafeAllocateRawToBlock(BLAKE_SA_HANDLE Handle, const void* SourceData, unsigned int DestinationIndex);
+BLAKEAPI(enum blakeError) blake_SafeAllocateRawToBlock(BLAKE_SA_HANDLE Handle, const void* SourceData, unsigned int DestinationIndex);
 
 /*
   The opposite of the above, copying out of the block back into a raw memory
   pointer
 */
-void BLAKEAPI blake_SafeAllocateBlockToRaw(BLAKE_SA_HANDLE Handle, unsigned int SourceIndex, void* DestinationPointer);
+BLAKEAPI(void) blake_SafeAllocateBlockToRaw(BLAKE_SA_HANDLE Handle, unsigned int SourceIndex, void* DestinationPointer);
 
 /*
   This clears the current contents of a block of memory under the control
   of the safe allocator.
 */
-void BLAKEAPI blake_SafeAllocateClear(BLAKE_SA_HANDLE Handle);	
+BLAKEAPI(void) blake_SafeAllocateClear(BLAKE_SA_HANDLE Handle);	
 
 /*
   *******************************************************************
 */
 typedef unsigned short int BLAKE_STOPCODE;
 
-void BLAKEAPI blake_Panic(const char* File, unsigned int Line, BLAKE_STOPCODE StopCode, unsigned int ParamCount, blake_word32_t Params[]);
+BLAKEAPI(void) blake_Panic(const char* File, unsigned int Line, BLAKE_STOPCODE StopCode, unsigned int ParamCount, blake_word32_t Params[]);
 #define PANIC(sc, pm, params) \
   blake_Panic(__FILE__, __LINE__, (sc), (pm), (params))
 
   BLAKESTOP_CORE_LIST_CORRUPT and that translates to number 4 (example only),
   this function will return "BLAKESTOP_CORE_LIST_CORRUPT"
 */
-const char* BLAKEAPI blake_StopCodeString(BLAKE_STOPCODE StopCode);
+BLAKEAPI(const char*) blake_StopCodeString(BLAKE_STOPCODE StopCode);
 
 /*
   This function returns a pointer to a useful descriptive string for the
   with language support.  Users shouldn't see these strings in general
   operation and they are only of use to nerds.
 */
-const char* BLAKEAPI blake_StopCodeDescription(BLAKE_STOPCODE StopCode);
+BLAKEAPI(const char*) blake_StopCodeDescription(BLAKE_STOPCODE StopCode);
 
 /* Hash based security features. */
 
   are the same and false if they differ.  It is safe against NULL pointers
   and works in a logical fashion with them
 */
-bool BLAKEAPI blake_MD5CompareDigests(const unsigned char Digest0[BLAKE_MD5HASHLEN], const unsigned char Digest1[BLAKE_MD5HASHLEN]);
+BLAKEAPI(bool) blake_MD5CompareDigests(const unsigned char Digest0[BLAKE_MD5HASHLEN], const unsigned char Digest1[BLAKE_MD5HASHLEN]);
 
 /*
   The random hash function returns a securely random MD5 hash which is
   securely dynamic within a second hash of the password hash + the random
   hash.
 */
-unsigned char* BLAKEAPI blake_MD5SecureRandomHash(unsigned char HashOut[BLAKE_MD5HASHLEN]);
+BLAKEAPI(unsigned char*) blake_MD5SecureRandomHash(unsigned char HashOut[BLAKE_MD5HASHLEN]);
 
 /*
   The double password hash creates a hash based on a random hash and a password,
   this is a one way hash, it is computionally difficult to get the password
   back from this function and should take several months to complete.
 */
-enum blakeError BLAKEAPI blake_MD5SecureDoublePasswordHash(unsigned char HashOut[BLAKE_MD5HASHLEN], const char* Password, const unsigned char HashIn[BLAKE_MD5HASHLEN]);
+BLAKEAPI(enum blakeError) blake_MD5SecureDoublePasswordHash(unsigned char HashOut[BLAKE_MD5HASHLEN], const char* Password, const unsigned char HashIn[BLAKE_MD5HASHLEN]);
+
+/*
+  Checksumming features.  Please use these instead od writing
+  your own routines to keep overhead down.  I'm using pointers
+  for these, this provides us for expansion for other types
+  such as 64-bit support on systems which won't allow us to pass
+  a 64-bit value.  64-bit will of course return via a second
+  parameter.
+*/
+BLAKEAPI(blake_word16_t) blake_Sum16OfWord8(const blake_word8_t* PWord8);
+BLAKEAPI(blake_word16_t) blake_Sum16OfWord16(const blake_word16_t* PWord16);
+BLAKEAPI(blake_word16_t) blake_Sum16OfWord32(const blake_word32_t* PWord32);
+BLAKEAPI(blake_word32_t) blake_Sum32OfWord8(const blake_word8_t* PWord8);
+BLAKEAPI(blake_word32_t) blake_Sum32OfWord16(const blake_word16_t* PWord16);
+BLAKEAPI(blake_word32_t) blake_Sum32OfWord32(const blake_word32_t* PWord32);
+
+/*
+  This function returns the address of the caller.  Please don't rely on it
+  for calculations or critical things, just use it for debugging purposes
+  or logging.  I don't know how portable it is across different systems.
+  Cast the return value to an void* if you want to dereference it for some
+  reason.  The variable 'x' can be anything, just pass 0, it's use for internal
+  stack logic and it's value doesn't matter, just it's position on the stack.
+*/
+BLAKEAPI(unsigned int) blake_Here(unsigned int x);
+
+/*
+  Functions for dealing with the new client/server authentication scheme
+  (used to lock unauthorised clients out).
+  There are mostly for the server only.
+*/
+
+/*
+  This function returns the desription of an authorised client of OverChat.
+  The length is the return value and you must allocate emough memory
+  to get the string on the second call.
+*/
+BLAKEAPI(unsigned int) blake_GetClientIDString(const enum blakeClientID ClientID, char* PBuffOut, const size_t MaxBuffSz);