Index: trunk/COPYING
===================================================================
--- trunk/COPYING	(revision 17)
+++ trunk/COPYING	(revision 18)
@@ -241,4 +241,28 @@
    either version 2 of the License, or (at your option) any later version."
 
+   (x) Unit testing uses the 'cutest' framework by Asim Jalis, (files
+   CuTest.h, CuTest.c, make-tests.sh) which is licensed under the zlib license:
+
+     * Copyright (c) 2003 Asim Jalis
+     *
+     * This software is provided 'as-is', without any express or implied
+     * warranty. In no event will the authors be held liable for any damages
+     * arising from the use of this software.
+     *
+     * Permission is granted to anyone to use this software for any purpose,
+     * including commercial applications, and to alter it and redistribute it
+     * freely, subject to the following restrictions:
+     *
+     * 1. The origin of this software must not be misrepresented; you must not
+     * claim that you wrote the original software. If you use this software in
+     * a product, an acknowledgment in the product documentation would be
+     * appreciated but is not required.
+     *
+     * 2. Altered source versions must be plainly marked as such, and must not
+     * be misrepresented as being the original software.
+     *
+     * 3. This notice may not be removed or altered from any source
+     * distribution.
+
 
 Other
Index: trunk/Makefile.in
===================================================================
--- trunk/Makefile.in	(revision 17)
+++ trunk/Makefile.in	(revision 18)
@@ -57,4 +57,5 @@
 XOR_CODE = @xor_code@
 SH_LKM   = @sh_lkm@
+TIGER_SRC = @tiger_src@
 
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -63,4 +64,5 @@
 
 CC = @CC@
+# DBGDEF = -pg -DSH_PROFILE=1
 DBGDEF = @mydebugdef@
 DEFS = $(DBGDEF) @DEFS@ -I. -I$(top_srcdir)/include
@@ -98,5 +100,5 @@
 	lzoconf.h minilzo.h rijndael-alg-fst.h rijndael-api-fst.h \
 	rijndael-boxes-fst.h sh_socket.h sh_ignore.h sh_prelude.h \
-	sh_mounts.h sh_userfiles.h sh_static.h sh_prelink.h
+	sh_mounts.h sh_userfiles.h sh_static.h sh_prelink.h 
 
 
@@ -130,9 +132,10 @@
 	$(srcsrc)/sh_userfiles.c $(srcsrc)/sh_prelude.c \
 	$(srcsrc)/sh_prelink.c $(srcsrc)/sh_static.c \
-	$(srcsrc)/sh_prelude_old.c
-
-OBJECTS = samhain.o sh_unix.o sh_utils.o sh_error.o sh_files.o \
-	sh_getopt.o sh_readconf.o sh_tiger0.o sh_tiger1.o sh_tiger2.o \
-	sh_tiger1_64.o sh_tiger2_64.o sh_hash.o sh_mail.o sh_mem.o \
+	$(srcsrc)/sh_prelude_old.c 
+
+OBJECTS = sh_files.o sh_tiger0.o sh_tiger2.o sh_tiger2_64.o \
+	samhain.o sh_unix.o sh_utils.o sh_error.o \
+	sh_getopt.o sh_readconf.o \
+	sh_hash.o sh_mail.o sh_mem.o \
 	sh_entropy.o sh_forward.o sh_modules.o sh_utmp.o sh_kern.o \
 	sh_suidchk.o sh_srp.o sh_fifo.o sh_tools.o sh_html.o sh_gpg.o \
@@ -141,5 +144,6 @@
 	trustfile.o rijndael-alg-fst.o rijndael-api-fst.o slib.o \
 	zAVLTree.o sh_socket.o sh_ignore.o sh_prelude.o \
-	sh_mounts.o sh_userfiles.o sh_prelink.o sh_static.o sh_prelude_old.o
+	sh_mounts.o sh_userfiles.o sh_prelink.o sh_static.o \
+	sh_prelude_old.o 
 
 KERN = kern_head.h kern_head.c
@@ -1057,4 +1061,8 @@
 	rm x_`echo $@ |sed 's%\.o$$%%'`.c
 
+sh_tiger_i.o: $(srcsrc)/$(TIGER_SRC) Makefile config_xor.h 
+	@echo "$(COMPILE) $(VFLAG) -o sh_tiger_i.o -c $(srcsrc)/$(TIGER_SRC)";\
+	$(COMPILE) $(VFLAG) -o sh_tiger_i.o -c $(srcsrc)/$(TIGER_SRC);
+
 samhain_setpwd: encode config_xor.h $(srcsrc)/samhain_setpwd.c
 	@echo '$(COMPILE)  -o samhain_setpwd $(srcsrc)/samhain_setpwd.c'; \
@@ -1075,10 +1083,33 @@
 	rm x_yulectl.c
 
-$(SAMHAIN): internal.h $(OBJECTS)
+$(SAMHAIN): internal.h $(OBJECTS) sh_tiger_i.o
 	@-rm -f $(SAMHAIN)
-	@echo "$(LINK) $(OBJECTS) $(LIBS_TRY)"; \
-	$(LINK) $(OBJECTS) $(LIBS_TRY)
-
-
+	@echo "$(LINK) sh_tiger_i.o $(OBJECTS) $(LIBS_TRY)"; \
+	$(LINK) sh_tiger_i.o $(OBJECTS) $(LIBS_TRY)
+
+
+CUTEST_SOURCES = $(srcsrc)/cutest_sh_tools.c \
+		$(srcsrc)/cutest_zAVLTree.c \
+		$(srcsrc)/cutest_sh_tiger0.c
+
+CUTEST_OBJECTS = cutest_sh_tools.o cutest_zAVLTree.o cutest_sh_tiger0.o
+
+$(CUTEST_OBJECTS): $(CUTEST_SOURCES)
+	@echo "./encode $(XOR_CODE) $(srcsrc)/`echo $@ |sed 's%\.o$$%%'`.c --> x_`echo $@ |sed 's%\.o$$%%'`.c"; \
+	./encode $(XOR_CODE) $(srcsrc)/`echo $@ |sed 's%\.o$$%%'`.c; \
+	echo "$(COMPILE) $(VFLAG) -o `echo $@ |sed 's%.*/%%'` -c x_`echo $@ |sed 's%\.o$$%%'`.c"; \
+	$(COMPILE) $(VFLAG) -o `echo $@ |sed 's%.*/%%'` -c x_`echo $@ |sed 's%\.o$$%%'`.c; \
+	rm x_`echo $@ |sed 's%\.o$$%%'`.c
+
+cutest: internal.h $(OBJECTS) $(CUTEST_OBJECTS) sh_tiger_i.o $(srcsrc)/make-tests.sh
+	cd $(srcsrc)/ && ./make-tests.sh >CuTestMain.c
+	@$(COMPILE) -o CuTestMain.o -c $(srcsrc)/CuTestMain.c; \
+	$(COMPILE) -o CuTest.o -c $(srcsrc)/CuTest.c; \
+	rm -f samhain.o; \
+	./encode $(XOR_CODE) $(srcsrc)/samhain.c; \
+	$(COMPILE) $(VFLAG) -DSH_CUTEST=1 -o samhain.o -c x_samhain.c; \
+	rm x_samhain.c; \
+	$(LINK) sh_tiger_i.o $(CUTEST_OBJECTS) CuTestMain.o CuTest.o $(OBJECTS) $(LIBS_TRY); \
+	./cutest
 
 samhain_hide.o: $(srcsrc)/samhain_hide.c samhain_erase.o
@@ -1596,2 +1627,3 @@
 sh_static.o: $(srcsrc)/sh_static.c Makefile config_xor.h 
 sh_prelude_old.o: $(srcsrc)/sh_prelude_old.c Makefile config_xor.h $(srcinc)/slib.h $(srcinc)/sh_mem.h $(srcinc)/sh_cat.h $(srcinc)/sh_error_min.h $(srcinc)/sh_prelude.h $(srcinc)/sh_static.h 
+sh_async.o: $(srcsrc)/sh_async.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_calls.h $(srcinc)/sh_error.h 
Index: trunk/aclocal.m4
===================================================================
--- trunk/aclocal.m4	(revision 17)
+++ trunk/aclocal.m4	(revision 18)
@@ -1202,4 +1202,135 @@
 ])dnl
 
+dnl checks for a known 64 bit programming environment
+dnl AC_RUN_IFELSE(PROGRAM,
+dnl               [ACTION-IF-TRUE], [ACTION-IF-FALSE],
+dnl               [ACTION-IF-CROSS-COMPILING = RUNTIME-ERROR])
+dnl
+AC_DEFUN([SAMHAIN_PRG_ENV],[
+    AC_MSG_CHECKING([for a known 64 bit programming environment])
+    # Compile and run a program that determines the programming environment
+    AC_RUN_IFELSE([
+      AC_LANG_SOURCE([[
+#include <stdio.h>
+int main(int argc,char **argv)
+{
+  if (argc > 1) {
+#if defined(__arch64__)
+  printf("__arch64__\n");
+#elif defined(__ia64__)
+  printf("__ia64__\n");
+#elif defined(__x86_64__)
+  printf("__x86_64__\n");
+#elif defined(__LP64__)
+  printf("__LP64__\n");
+#elif defined(__64BIT__)
+  printf("__64BIT__\n");
+#elif defined(_LP64)
+  printf("_LP64\n");
+#elif defined(_M_IA64)
+  printf("_M_IA64\n");
+#elif defined(_MIPS_SZLONG) && (_MIPS_SZLONG == 64)
+  printf("_MIPS_64\n");
+#else
+choke me
+#endif
+  }
+  return 0;
+}
+      ]])
+    ],[
+      # Program compiled and ran, so get version by adding argument.
+      samhain_prg_ENV=`./conftest$ac_exeext x`
+      samhain_64=yes
+      AC_MSG_RESULT([$samhain_prg_ENV])
+    ],[
+      AC_MSG_RESULT([none])
+	],[
+      AC_MSG_RESULT([none])
+	])
+])dnl
+
+AC_DEFUN([SAMHAIN_X86_64],[
+	AC_MSG_CHECKING([for x86_64])
+	AC_TRY_RUN([
+int main() {
+__asm__ volatile (
+"movq %rax, %rax"
+);
+return 0;
+}
+	],
+	[
+	AC_MSG_RESULT(yes)
+	samhain_64=yes
+	tiger_src=sh_tiger1_64.c
+	AC_DEFINE([TIGER_OPT_ASM],1,[Define to use tiger x86_64 optimized assembly])
+	],
+	[
+	AC_MSG_RESULT([no])
+	],[
+	AC_MSG_RESULT([no])
+	])
+])dnl
+
+
+AC_DEFUN([SAMHAIN_64],[
+samhain_64=no
+tiger_src=sh_tiger1.c
+#
+# if sizeof(unsigned long) = 4, try compiler macros for 64bit
+#
+if test "x$ac_cv_sizeof_unsigned_long" = x4; then
+  if test "x$ac_cv_sizeof_unsigned_long_long" = x8; then
+	SAMHAIN_PRG_ENV
+	if test "x$samhain_64" = xyes; then
+	  tiger_src=sh_tiger1_64.c
+        fi
+	#
+	# if GCC and __i386__, use precompiled assembler
+	#
+	if test "x$GCC" = xyes; then
+	  AC_MSG_CHECKING([for i386])
+	  samhain_i386=no
+	  touch conf_foo.h 
+	  $CC -E -dM conf_foo.h | egrep '__i386__' >/dev/null 2>&1 && samhain_i386=yes
+	  rm -f conf_foo.h
+	  if test "x$samhain_i386" = xyes; then
+	    tiger_src=sh_tiger1.s
+	    AC_DEFINE([TIGER_32_BIT_S],1,[Define to use tiger 32 bit i386 assembler])
+          fi
+	  AC_MSG_RESULT([$samhain_i386])
+	fi
+	#
+	#
+	#
+  else
+	samhain_64=no
+	tiger_src=sh_tiger1.c
+  fi
+else
+  #
+  # sizeof(unsigned long) = 8
+  #
+  tiger_src=sh_tiger1_64.c
+  samhain_64=yes
+  #
+  # check for x86_64 (enables assembly optimizations)
+  #
+  if test "x$GCC" = xyes; then
+    SAMHAIN_X86_64
+  fi
+fi
+if test "x$samhain_64" = xyes; then 
+	AC_DEFINE([TIGER_64_BIT],1,[Define to use tiger 64 bit implementation])
+fi
+AC_MSG_CHECKING([for 64 bit environment])
+AC_MSG_RESULT([$samhain_64])
+AC_MSG_CHECKING([for tiger source to use])
+AC_MSG_RESULT([$tiger_src])
+AC_SUBST(tiger_src)
+])dnl
+
+
 dnl Autoconf macros for libprelude
 dnl $id$
Index: trunk/configure.ac
===================================================================
--- trunk/configure.ac	(revision 17)
+++ trunk/configure.ac	(revision 18)
@@ -37,5 +37,5 @@
 dnl start
 dnl
-AM_INIT_AUTOMAKE(samhain, 2.1.1a)
+AM_INIT_AUTOMAKE(samhain, 2.2.0rc1)
 AC_CANONICAL_HOST
 
@@ -439,4 +439,10 @@
 fi
 
+dnl 
+dnl check for 64 bit programming environment
+dnl
+SAMHAIN_64
+
+
 dnl *****************************************
 dnl     checks for structures
@@ -651,5 +657,5 @@
 LIBWRAP_INC=""
 AC_ARG_WITH(libwrap,
-[ --with-libwrap[=PATH]	Compile in libwrap (TCP Wrappers) support],
+[  --with-libwrap[=PATH]		Compile in libwrap (TCP Wrappers) support],
 [ AC_MSG_RESULT($withval)
   case "$withval" in
@@ -711,10 +717,10 @@
 
 AC_ARG_WITH(libprelude-prefix,
-          [  --with-libprelude-prefix=PFX   Prefix where libprelude is installed (optional)],
+          [  --with-libprelude-prefix=PFX	Prefix where libprelude is installed (optional)],
           libprelude_config_prefix="$withval", libprelude_config_prefix="")
 
 AC_MSG_CHECKING(whether to use prelude)
 AC_ARG_WITH(prelude,  
-        [  --with-prelude	Prelude IDS support [[no]]],
+        [  --with-prelude		Prelude IDS support [[no]]],
         [
         if test "x${withval}" = "xno"; then
@@ -1156,5 +1162,5 @@
 
 AC_ARG_WITH(console,
-        [  --with-console=PATH          set path to console device [[/dev/console]]],
+        [  --with-console=PATH           set path to console device [[/dev/console]]],
         [
 	if test "x${withval}" != xno; then
@@ -1165,5 +1171,5 @@
 
 AC_ARG_WITH(altconsole,
-        [  --with-altconsole=PATH       set path to second console device [[none]]],
+        [  --with-altconsole=PATH        set path to second console device [[none]]],
         [
 	if test "x${withval}" != xno; then
@@ -1177,5 +1183,5 @@
 
 AC_ARG_WITH(timeserver,
-        [  --with-timeserver=HOST       set host address for time server [[none]]],
+        [  --with-timeserver=HOST        set host address for time server [[none]]],
         [
 	if test "x${withval}" != xno; then
@@ -1190,5 +1196,5 @@
 
 AC_ARG_WITH(alttimeserver,
-        [  --with-alttimeserver=HOST    set address for backup time server [[none]]],
+        [  --with-alttimeserver=HOST     set address for backup time server [[none]]],
         [
 	if test "x${withval}" != xno; then
@@ -1212,5 +1218,5 @@
 
 AC_ARG_ENABLE(mounts-check,
-        [  --enable-mounts-check       check mount options on filesystems [[no]]],
+        [  --enable-mounts-check		check mount options on filesystems [[no]]],
         [
         if test "x${enable_mounts_check}" = xyes; then
@@ -1221,5 +1227,5 @@
 
 AC_ARG_ENABLE(userfiles,
-       [  --enable-userfiles           check for users' config files [[no]]],
+       [  --enable-userfiles		check for users' config files [[no]]],
        [
        if test "x${enableval}" = "xyes"; then
@@ -1648,5 +1654,5 @@
 sh_syscalltable="0x0"
 AC_ARG_ENABLE(khide,
-	[  --enable-khide=SYSTEM_MAP		use kernel module to hide (Linux only)[[/boot/System.map]]],
+	[  --enable-khide=SYSTEM_MAP	use kernel module to hide (Linux only)[[/boot/System.map]]],
 	[
 	if test "x${enable_khide}" != xno; then
@@ -1750,5 +1756,5 @@
 sh_libkvm=""
 AC_ARG_WITH(kcheck,
-	[  --with-kcheck=SYSTEM_MAP	check Linux kernel integrity [[/boot/System.map]]],
+	[  --with-kcheck[[=SYSTEM_MAP]]	check Linux/FreeBSD/OpenBSD kernel integrity [[/boot/System.map]]],
 	[
 	if test "x${withval}" != "xno"; then 
@@ -1988,4 +1994,6 @@
 	do
 		case ${sh_item} in
+		*@localhost)
+		;;
 		*@*.*)
 		sh_tmp=`echo ${sh_item} | awk '{ if ($1 ~ [/^[a-zA-Z0-9][a-zA-Z0-9\-_\.]*@[a-zA-Z0-9\-\.]+\.([a-zA-Z]+|[0-9]+)$/]) {print 1; } else { print 0}}'`
Index: trunk/depend.dep
===================================================================
--- trunk/depend.dep	(revision 17)
+++ trunk/depend.dep	(revision 18)
@@ -58,4 +58,5 @@
 sh_prelink.o: $(srcsrc)/sh_prelink.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_extern.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h 
 sh_static.o: $(srcsrc)/sh_static.c Makefile config_xor.h 
+sh_prelude_old.o: $(srcsrc)/sh_prelude_old.c Makefile config_xor.h $(srcinc)/slib.h $(srcinc)/sh_mem.h $(srcinc)/sh_cat.h $(srcinc)/sh_error_min.h $(srcinc)/sh_prelude.h $(srcinc)/sh_static.h 
 kern_head.o: $(srcsrc)/kern_head.c Makefile config.h $(srcinc)/kern_head.h $(srcinc)/kern_head.h 
-sh_prelude_old.o: $(srcsrc)/sh_prelude_old.c Makefile config_xor.h $(srcinc)/slib.h $(srcinc)/sh_mem.h $(srcinc)/sh_cat.h $(srcinc)/sh_error_min.h $(srcinc)/sh_prelude.h $(srcinc)/sh_static.h 
+sh_async.o: $(srcsrc)/sh_async.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_calls.h $(srcinc)/sh_error.h 
Index: trunk/depend.sum
===================================================================
--- trunk/depend.sum	(revision 17)
+++ trunk/depend.sum	(revision 18)
@@ -1,1 +1,1 @@
-1152497988
+3476546078
Index: trunk/docs/Changelog
===================================================================
--- trunk/docs/Changelog	(revision 17)
+++ trunk/docs/Changelog	(revision 18)
@@ -1,2 +1,21 @@
+2.2.0:
+	* added a bit of unit testing
+	* improved the windows howto according to suggestions by 
+	  Jorge Morgado
+	* minor optimizations in various places
+	* optimized implementation of tiger checksum algorithm
+	* read in 64k blocks (faster than 4k)
+	* sh_unix.c, sh_hash.c: support file flags on *BSD, update Linux
+	  file attribute code
+	* kern_head: fix compilation of kernel check module on OpenBSD
+	* updated samhainrc.linux, samhainrc.freebsd
+	* sh_unix.c: fix setrlimit (RLIMIT_NOFILE, ..)
+	* sh_files.c: fix missing use of flag_err_info
+	* sh_tiger0.c: remove repetitive use of mlock
+	* slib.c: remove fcntl's from sl_read_timeout (caller sets O_NONBLOCK),
+	  add function sl_read_timeout_prep
+
+2.1.2 (10-01-2006):
+        * fix startup error with combination of gpg+prelude
 
 2.1.1a (22-12-2005):
Index: trunk/docs/HOWTO-samhain-on-windows.html
===================================================================
--- trunk/docs/HOWTO-samhain-on-windows.html	(revision 17)
+++ trunk/docs/HOWTO-samhain-on-windows.html	(revision 18)
@@ -135,5 +135,6 @@
 <b>Cygwin</b> POSIX emulation layer, and how to install it as a service. 
 These instructions have been written by Kris Dom,
-who has tested this on WinXP Professional.
+who has tested this on WinXP Professional, with additions by Geries Handal
+and Jorge Morgado.
 </p>
 <div class="block">
@@ -150,5 +151,6 @@
 logging) because Interix does not provide some of the required functionality 
 to build the email module. This issue should be fixed as of samhain 
-version 2.0.7 (not tested).<br />[Based on information kindly provided by Geries Handal].
+version 2.0.7 (not tested).<br />
+[Based on information kindly provided by Geries Handal].
 </p>
 </div>
@@ -192,4 +194,21 @@
 </li>
 </ul>
+<div class="block">
+<p>
+You don't need to download and install All packages. It is enough to keep
+the Default and then add the following additional packages:
+</p>
+<p>
+  Category Devel -> gcc: C compiler upgrade helper<br/>
+  Category Devel -> make: The GNU version of the 'make' utility<br/>
+  Category Libs  -> minires: A simple synchronous non caching stub resolver<br/>
+</p>
+<p>
+When selecting these packages, Cygwin installer will automatically add
+other packages based on their dependencies.
+The package minires is only necessary for a minimal Cygwin installation
+(below). [Kindly pointed out by Jorge Morgado].
+</p>
+</div>
 
 <h3>Cygwin installation</h3>
@@ -301,4 +320,28 @@
  </li>
  </ul>
+</li>
+<li>
+Files needed from c:\Cygwin\bin to create the /etc/passwd and /etc/group files:
+ <ul>
+ <li>
+ mkpasswd.exe
+ </li>
+ <li>
+ mkgroup.exe
+ </li>
+ </ul>
+<p>
+To generate these files on a minimal Cygwin installation execute - on a
+Windows Command Prompt:
+</p><p>
+&nbsp; &nbsp;<tt>mkdir c:\etc</tt><br />
+&nbsp; &nbsp;<tt>path\to\mkpasswd.exe -l > c:\etc\passwd</tt><br />
+&nbsp; &nbsp;<tt>path\to\mkgroup.exe -l > c:\etc\group</tt>
+</p><p>
+IMPORTANT NOTE: You should re-create these two files, each time the
+Windows users and groups accounts database changes. Failing to do this
+might generate critical log messages (depending on your configuration
+file).
+</p>
 </li>
 <li>
@@ -331,6 +374,6 @@
   </li>
   <li>Under the newly created &quot;Parameters&quot; key, add a new String 
-  value called &quot;Applications&quot;.<br />
-  &nbsp; &nbsp;The value for &quot;Applications&quot;
+  value called &quot;Application&quot;.<br />
+  &nbsp; &nbsp;The value for &quot;Application&quot;
   should be &quot;c:\usr\local\sbin\samhain.exe&quot;.</li>
   </ul>
@@ -348,4 +391,8 @@
 </li>
 </ul>
+<p>
+Also see <a href="http://support.microsoft.com/kb/q137890/">http://support.microsoft.com/kb/q137890/</a> for information regarding the creation of a 
+user-defined service.
+</p>
 <p>
 Note: the first time I tried to install samhain as an NT service, I first
@@ -354,4 +401,44 @@
 Samhain as a service.
 </p>
+
+
+<h2>Troubleshooting samhain</h2>
+
+<p>
+[Tip from Jorge Morgado] If you, like me, have a Windows server not part of any domain and (for
+security reasons) you even turn off DNS resolution, you might probably get
+the following error when initializing the baseline database:
+</p>
+<pre>
+  ---------   sh_unix.c  ---   1487 ---------
+  According to uname, your nodename is yourcomputername, but your resolver
+  library cannot resolve this nodename to a FQDN.
+  Rather, it resolves this to yourcomputername.
+  For more information, see the entry about self-resolving under
+  'Most frequently' in the FAQ that you will find in the docs/ subdirectory
+  ----------------------------------------------
+</pre>
+<p>
+To fix this problem open the Registry Editor and create the following
+entries under the key
+HKLM\System\CurrentControlSet\Services\Tcpip\Parameters
+</p>
+<p>
+<tt>
+Name: Domain<br/>
+Type: REG_SZ<br/>
+Data: your.domain.name
+</tt>
+</p><p>
+<tt>
+Name: NV Domain<br/>
+Type: REG_SZ<br/>
+Data: your.domain.name
+</tt>
+</p><p>
+The NV Domain registry value contains the computer's primary DNS suffix
+while the Domain registry value contains the computer's primary DNS
+domain. This will make the warning message go away.
+</p>
 </div>
 </body>
Index: trunk/docs/README.UPGRADE
===================================================================
--- trunk/docs/README.UPGRADE	(revision 17)
+++ trunk/docs/README.UPGRADE	(revision 18)
@@ -1,2 +1,9 @@
+since 2.1.0: update and daemon mode can be combined
+
+  -- this implies that '-t update' will start a daemon process if running as
+     daemon is the default specified in the config file. use '--foreground'
+     to avoid starting a daemon process
+
+
 
 from 1.7.x to 1.8.x: client/server encryption protocol has been enhanced
Index: trunk/docs/TODO
===================================================================
--- trunk/docs/TODO	(revision 17)
+++ trunk/docs/TODO	(revision 18)
@@ -1,6 +1,1 @@
 
-Wishlist:
-
- - yule -> yule relay
- - partial checksum of growing logfiles
- 
Index: trunk/include/samhain.h
===================================================================
--- trunk/include/samhain.h	(revision 17)
+++ trunk/include/samhain.h	(revision 18)
@@ -60,8 +60,4 @@
  */
 #define PW_LEN     8
-
-/* Buffer for privileged content.
- */
-#define PRIV_MAX  4096   
 
 #undef  GOOD
Index: trunk/samhainrc.linux
===================================================================
--- trunk/samhainrc.linux	(revision 17)
+++ trunk/samhainrc.linux	(revision 18)
@@ -177,4 +177,6 @@
 dir = -1/var/tmp
 dir = -1/var/lib/texmf
+dir = -1/var/lib/scrollkeeper
+
 
 [Attributes]
@@ -229,4 +231,5 @@
 file = /var/log/*.old
 file = /var/log/*/*.[0-9].gz
+file = /var/log/*/*.[0-9][0-9].gz
 file = /var/log/*/*.log.[0-9]
 
Index: trunk/src/samhain.c
===================================================================
--- trunk/src/samhain.c	(revision 17)
+++ trunk/src/samhain.c	(revision 18)
@@ -1075,5 +1075,9 @@
  *
  *******************************************************/
+#if !defined(SH_CUTEST)
 int main(int argc, char * argv[])
+#else
+int undef_main(int argc, char * argv[])
+#endif
 {
 #if defined(INET_SYSLOG)
Index: trunk/src/sh_database.c
===================================================================
--- trunk/src/sh_database.c	(revision 17)
+++ trunk/src/sh_database.c	(revision 18)
@@ -1064,4 +1064,15 @@
 	}
 
+      /* Read in defaults from /etc/my.cnf and associated files,
+       * suggested by arjones at simultan dyndns org
+       * see: - http://dev.mysql.com/doc/refman/5.0/en/option-files.html
+       *        for the my.cnf format,
+       *      - http://dev.mysql.com/doc/refman/5.0/en/mysql-options.html
+       *        for possible options
+       * We don't check the return value because it's useless (failure due 
+       * to lack of access permission is not reported).
+       */
+      mysql_options(db_conn, MYSQL_READ_DEFAULT_GROUP, _("samhain"));
+
       status = 0;
   
Index: trunk/src/sh_hash.c
===================================================================
--- trunk/src/sh_hash.c	(revision 17)
+++ trunk/src/sh_hash.c	(revision 18)
@@ -396,9 +396,10 @@
 static int hashfunc(char *s) 
 {
-  unsigned n = 0; 
+  unsigned int n = 0; 
 
   for ( ; *s; s++) 
     n = 31 * n + *s; 
-  return n & 0xFFFF;/* % TABSIZE*/; 
+
+  return n & (TABSIZE - 1); /* % TABSIZE */; 
 } 
 
Index: trunk/src/sh_tiger0.c
===================================================================
--- trunk/src/sh_tiger0.c	(revision 17)
+++ trunk/src/sh_tiger0.c	(revision 18)
@@ -25,9 +25,13 @@
 #include "sh_utils.h"
 
-#if defined(HAVE_LONG_64) || defined(HAVE_LONG_LONG_64)
+#define PRIV_MAX  32768
+
+#if defined(TIGER_64_BIT)
 #if defined(HAVE_LONG_64)
 typedef unsigned long int word64;
+#elif defined(HAVE_LONG_LONG_64)
+typedef unsigned long long int word64;
 #else
-typedef unsigned long long int word64;
+#error No 64 bit type found !
 #endif
 #endif
@@ -46,5 +50,5 @@
 #define GPGFORMAT (_("%08X %08X %08X  %08X %08X %08X"))
 #else
-#error No 32 byte type found !
+#error No 32 bit type found !
 #endif
 
@@ -54,6 +58,6 @@
 #define FIL__  _("sh_tiger0.c")
 
-#if defined(HAVE_LONG_64) || defined(HAVE_LONG_LONG_64)
-/* #ifdef HAVE_LONG_64 */
+#if defined(TIGER_64_BIT)
+
 void tiger_t(word64 *str, word64 length, word64 * res);
 void tiger(word64 *str, word64 length, word64 * res);
@@ -97,6 +101,5 @@
 static sh_byte buffer[PRIV_MAX + 72];
 
-#if defined(HAVE_LONG_64) || defined(HAVE_LONG_LONG_64)
-/* #ifdef HAVE_LONG_64 */
+#if defined(TIGER_64_BIT)
 static
 word64 * sh_tiger_hash_val (char * filename, TigerType what, 
@@ -114,5 +117,4 @@
   char    * tmp;
   sh_byte * bptr;
-  /* sh_byte buffer[PRIV_MAX + 72]; */
   sh_byte bbuf[64];
 
@@ -131,6 +133,5 @@
 #endif
 
-#if defined(HAVE_LONG_64) || defined(HAVE_LONG_LONG_64)
-  /* #ifdef HAVE_LONG_64 */
+#if defined(TIGER_64_BIT)
 #define TIGER_CAST (word64*)
   static word64 res[3];
@@ -254,5 +255,5 @@
 	  }
 	
-	if (blk < 64) /* this must be (PRIV_MAX / 64) */
+	if (blk < (PRIV_MAX / 64)) /* this must be (PRIV_MAX / 64) */
 	  break;
 
@@ -359,11 +360,14 @@
     bptr = buffer;
 
-    memcpy(bptr, bbuf,    64); bptr +=   64;
-    memcpy(bptr, bbuf,    64); bptr +=   64;
-    memcpy(bptr, buffer, 128); bptr +=  128;
-    memcpy(bptr, buffer, 256); bptr +=  256;
-    memcpy(bptr, buffer, 512); bptr +=  512;
-    memcpy(bptr, buffer,1024); bptr += 1024;
-    memcpy(bptr, buffer,2048);
+    memcpy(bptr, bbuf,     64); bptr +=    64;
+    memcpy(bptr, bbuf,     64); bptr +=    64;
+    memcpy(bptr, buffer,  128); bptr +=   128;
+    memcpy(bptr, buffer,  256); bptr +=   256;
+    memcpy(bptr, buffer,  512); bptr +=   512;
+    memcpy(bptr, buffer, 1024); bptr +=  1024;
+    memcpy(bptr, buffer, 2048); bptr +=  2048;
+    memcpy(bptr, buffer, 4096); bptr +=  4096;
+    memcpy(bptr, buffer, 8192); bptr +=  8192;
+    memcpy(bptr, buffer,16384);
 
     if (what == TIGER_FILE)
@@ -814,4 +818,5 @@
 		       MSG_E_SUBGEN, _("Not TIGER_FD"), 
 		       _("sh_tiger_md5_hash"));
+      out[0] = '\0';
       return out;
     }
@@ -1328,4 +1333,5 @@
 		       MSG_E_SUBGEN, _("Not TIGER_FD"), 
 		       _("sh_tiger_sha1_hash"));
+      out[0] = '\0';
       return out;
     }
@@ -1410,6 +1416,5 @@
 				      unsigned long Length, int timeout)
 {
-#if defined(HAVE_LONG_64) || defined(HAVE_LONG_LONG_64)
-  /* #ifdef HAVE_LONG_64 */
+#if defined(TIGER_64_BIT)
   word64 * res;
 #else
@@ -1425,6 +1430,5 @@
     {
       /*@-bufferoverflowhigh -formatconst@*/
-#if defined(HAVE_LONG_64) || defined(HAVE_LONG_LONG_64)
-      /* #ifdef HAVE_LONG_64 */
+#if defined(TIGER_64_BIT)
       sprintf(out,                                   /* known to fit  */
 	      MYFORMAT,
@@ -1461,6 +1465,5 @@
   char * out;
   char   outhash[48+6+1];
-#if defined(HAVE_LONG_64) || defined(HAVE_LONG_LONG_64)
-  /* #ifdef HAVE_LONG_64 */
+#if defined(TIGER_64_BIT)
   word64 * res;
 #else
@@ -1474,6 +1477,5 @@
     {
       /*@-bufferoverflowhigh -formatconst@*/
-#if defined(HAVE_LONG_64) || defined(HAVE_LONG_LONG_64)
-      /* #ifdef HAVE_LONG_64 */
+#if defined(TIGER_64_BIT)
       sprintf(outhash,                               /* known to fit  */
 	      GPGFORMAT,
@@ -1530,6 +1532,5 @@
 			       unsigned long Length)
 {
-#if defined(HAVE_LONG_64) || defined(HAVE_LONG_LONG_64)
-  /* #ifdef HAVE_LONG_64 */
+#if defined(TIGER_64_BIT)
   word64 * res;
 #else
@@ -1548,6 +1549,5 @@
   if (res != NULL)
     {
-#if defined(HAVE_LONG_64) || defined(HAVE_LONG_LONG_64)
-      /* #ifdef HAVE_LONG_64 */
+#if defined(TIGER_64_BIT)
 	out[0] =  (UINT32)(res[0]>>32); 
 	out[1] =  (UINT32)(res[0]);
Index: trunk/src/sh_tiger1.c
===================================================================
--- trunk/src/sh_tiger1.c	(revision 17)
+++ trunk/src/sh_tiger1.c	(revision 18)
@@ -5,6 +5,9 @@
 #include "config_xor.h"
 
-
-#if !defined(HAVE_LONG_64) && !defined(HAVE_LONG_LONG_64)
+/* we already inline in the function used for file checksums */
+/* #define UNROLL_COMPRESS */
+#undef UNROLL_COMPRESS
+
+#if !defined(TIGER_64_BIT)
 
 /* Tiger: A Fast New Hash Function
@@ -37,5 +40,5 @@
 typedef unsigned short sh_word32;
 #else
-#error No 32 byte type found !
+#error No 32 bit type found !
 #endif
 
@@ -46,9 +49,4 @@
 #define BIG_ENDIAN
 #endif
-
-/* NOTE that this code is NOT FULLY OPTIMIZED for any  */
-/* machine. Assembly code might be much faster on some */
-/* machines, especially if the code is compiled with   */
-/* gcc.                                                */
 
 /* The number of passes of the hash function.          */
@@ -65,5 +63,5 @@
 #define t4 (tiger_table+256*3)
 
-#define sh_sub64(s0, s1, p0, p1) \
+#define sub64(s0, s1, p0, p1) \
       temps0 = (p0); \
       tcarry = s0 < temps0; \
@@ -71,5 +69,5 @@
       s1 -= (p1) + tcarry;
 
-#define sh_add64(s0, s1, p0, p1) \
+#define add64(s0, s1, p0, p1) \
       temps0 = (p0); \
       s0 += temps0; \
@@ -77,26 +75,26 @@
       s1 += (p1) + tcarry;
 
-#define sh_xor64(s0, s1, p0, p1) \
+#define xor64(s0, s1, p0, p1) \
       s0 ^= (p0); \
       s1 ^= (p1);
 
-#define sh_mul5(s0, s1) \
+#define mul5(s0, s1) \
       tempt0 = s0<<2; \
       tempt1 = (s1<<2)|(s0>>30); \
-      sh_add64(s0, s1, tempt0, tempt1);
-
-#define sh_mul7(s0, s1) \
+      add64(s0, s1, tempt0, tempt1);
+
+#define mul7(s0, s1) \
       tempt0 = s0<<3; \
       tempt1 = (s1<<3)|(s0>>29); \
-      sh_sub64(tempt0, tempt1, s0, s1); \
+      sub64(tempt0, tempt1, s0, s1); \
       s0 = tempt0; \
       s1 = tempt1;
 
-#define sh_mul9(s0, s1) \
+#define mul9(s0, s1) \
       tempt0 = s0<<3; \
       tempt1 = (s1<<3)|(s0>>29); \
-      sh_add64(s0, s1, tempt0, tempt1);
-
-#define sh_save_abc \
+      add64(s0, s1, tempt0, tempt1);
+
+#define save_abc \
       aa0 = a0; \
       aa1 = a1; \
@@ -106,6 +104,6 @@
       cc1 = c1;
 
-#define sh_round(a0,a1,b0,b1,c0,c1,x0,x1,mul) \
-      sh_xor64(c0, c1, x0, x1); \
+#define roundX(a0,a1,b0,b1,c0,c1,x0,x1) \
+      xor64(c0, c1, x0, x1); \
       temp0  = t1[((c0)>>(0*8))&0xFF][0] ; \
       temp1  = t1[((c0)>>(0*8))&0xFF][1] ; \
@@ -116,5 +114,5 @@
       temp0 ^= t4[((c1)>>(2*8))&0xFF][0] ; \
       temp1 ^= t4[((c1)>>(2*8))&0xFF][1] ; \
-      sh_sub64(a0, a1, temp0, temp1); \
+      sub64(a0, a1, temp0, temp1); \
       temp0  = t4[((c0)>>(1*8))&0xFF][0] ; \
       temp1  = t4[((c0)>>(1*8))&0xFF][1] ; \
@@ -125,79 +123,108 @@
       temp0 ^= t1[((c1)>>(3*8))&0xFF][0] ; \
       temp1 ^= t1[((c1)>>(3*8))&0xFF][1] ; \
-      sh_add64(b0, b1, temp0, temp1); \
-      if((mul)==5) \
-	{sh_mul5(b0, b1);} \
-      else \
-	if((mul)==7) \
-	  {sh_mul7(b0, b1);} \
-	else \
-	  {sh_mul9(b0, b1)};
-
-#define sh_pass(a0,a1,b0,b1,c0,c1,mul) \
-      sh_round(a0,a1,b0,b1,c0,c1,x00,x01,mul); \
-      sh_round(b0,b1,c0,c1,a0,a1,x10,x11,mul); \
-      sh_round(c0,c1,a0,a1,b0,b1,x20,x21,mul); \
-      sh_round(a0,a1,b0,b1,c0,c1,x30,x31,mul); \
-      sh_round(b0,b1,c0,c1,a0,a1,x40,x41,mul); \
-      sh_round(c0,c1,a0,a1,b0,b1,x50,x51,mul); \
-      sh_round(a0,a1,b0,b1,c0,c1,x60,x61,mul); \
-      sh_round(b0,b1,c0,c1,a0,a1,x70,x71,mul);
-
-#define sh_key_schedule \
-      sh_sub64(x00, x01, x70^0xA5A5A5A5, x71^0xA5A5A5A5); \
-      sh_xor64(x10, x11, x00, x01); \
-      sh_add64(x20, x21, x10, x11); \
-      sh_sub64(x30, x31, x20^((~x10)<<19), ~x21^(((x11)<<19)|((x10)>>13))); \
-      sh_xor64(x40, x41, x30, x31); \
-      sh_add64(x50, x51, x40, x41); \
-      sh_sub64(x60, x61, ~x50^(((x40)>>23)|((x41)<<9)), x51^((~x41)>>23)); \
-      sh_xor64(x70, x71, x60, x61); \
-      sh_add64(x00, x01, x70, x71); \
-      sh_sub64(x10, x11, x00^((~x70)<<19), ~x01^(((x71)<<19)|((x70)>>13))); \
-      sh_xor64(x20, x21, x10, x11); \
-      sh_add64(x30, x31, x20, x21); \
-      sh_sub64(x40, x41, ~x30^(((x20)>>23)|((x21)<<9)), x31^((~x21)>>23)); \
-      sh_xor64(x50, x51, x40, x41); \
-      sh_add64(x60, x61, x50, x51); \
-      sh_sub64(x70, x71, x60^0x89ABCDEF, x61^0x01234567);
-
-#define sh_feedforward \
-      sh_xor64(a0, a1, aa0, aa1); \
-      sh_sub64(b0, b1, bb0, bb1); \
-      sh_add64(c0, c1, cc0, cc1);
-
-#ifdef UNROLL_COMPRESS
-#define sh_compress \
-      sh_save_abc \
-      sh_pass(a0,a1,b0,b1,c0,c1,5); \
-      sh_key_schedule; \
-      sh_pass(c0,c1,a0,a1,b0,b1,7); \
-      sh_key_schedule; \
-      sh_pass(b0,b1,c0,c1,a0,a1,9); \
-      for(pass_no=3; pass_no<PASSES; pass_no++) { \
-        sh_key_schedule \
-	sh_pass(a0,a1,b0,b1,c0,c1,9); \
-	tmpa=a0; a0=c0; c0=b0; b0=tmpa; \
-	tmpa=a1; a1=c1; c1=b1; b1=tmpa;} \
-      sh_feedforward
-#else
-#define sh_compress \
-      sh_save_abc \
-      for(pass_no=0; pass_no<PASSES; pass_no++) { \
-        if(pass_no != 0) {sh_key_schedule} \
-	sh_pass(a0,a1,b0,b1,c0,c1,(pass_no==0?5:pass_no==1?7:9)) \
-	tmpa=a0; a0=c0; c0=b0; b0=tmpa; \
-	tmpa=a1; a1=c1; c1=b1; b1=tmpa;} \
-      sh_feedforward
-#endif
+      add64(b0, b1, temp0, temp1); 
+
+
+#define round5(a0,a1,b0,b1,c0,c1,x0,x1) \
+      roundX(a0,a1,b0,b1,c0,c1,x0,x1); \
+      mul5(b0, b1);
+
+#define round7(a0,a1,b0,b1,c0,c1,x0,x1) \
+      roundX(a0,a1,b0,b1,c0,c1,x0,x1); \
+      mul7(b0, b1);
+
+#define round9(a0,a1,b0,b1,c0,c1,x0,x1) \
+      roundX(a0,a1,b0,b1,c0,c1,x0,x1); \
+      mul9(b0, b1);
+
+
+/* mixed with key_schedule
+ */
+#define pass5(a0,a1,b0,b1,c0,c1) \
+      round5(a0,a1,b0,b1,c0,c1,x00,x01); \
+      sub64(x00, x01, x70^0xA5A5A5A5, x71^0xA5A5A5A5); \
+      round5(b0,b1,c0,c1,a0,a1,x10,x11); \
+      xor64(x10, x11, x00, x01); \
+      round5(c0,c1,a0,a1,b0,b1,x20,x21); \
+      add64(x20, x21, x10, x11); \
+      round5(a0,a1,b0,b1,c0,c1,x30,x31); \
+      sub64(x30, x31, x20^((~x10)<<19), ~x21^(((x11)<<19)|((x10)>>13))); \
+      round5(b0,b1,c0,c1,a0,a1,x40,x41); \
+      xor64(x40, x41, x30, x31); \
+      round5(c0,c1,a0,a1,b0,b1,x50,x51); \
+      add64(x50, x51, x40, x41); \
+      round5(a0,a1,b0,b1,c0,c1,x60,x61); \
+      sub64(x60, x61, ~x50^(((x40)>>23)|((x41)<<9)), x51^((~x41)>>23)); \
+      round5(b0,b1,c0,c1,a0,a1,x70,x71);
+
+/* mixed with key_schedule
+ */
+#define pass7(a0,a1,b0,b1,c0,c1) \
+      round7(a0,a1,b0,b1,c0,c1,x00,x01); \
+      sub64(x00, x01, x70^0xA5A5A5A5, x71^0xA5A5A5A5); \
+      round7(b0,b1,c0,c1,a0,a1,x10,x11); \
+      xor64(x10, x11, x00, x01); \
+      round7(c0,c1,a0,a1,b0,b1,x20,x21); \
+      add64(x20, x21, x10, x11); \
+      round7(a0,a1,b0,b1,c0,c1,x30,x31); \
+      sub64(x30, x31, x20^((~x10)<<19), ~x21^(((x11)<<19)|((x10)>>13))); \
+      round7(b0,b1,c0,c1,a0,a1,x40,x41); \
+      xor64(x40, x41, x30, x31); \
+      round7(c0,c1,a0,a1,b0,b1,x50,x51); \
+      add64(x50, x51, x40, x41); \
+      round7(a0,a1,b0,b1,c0,c1,x60,x61); \
+      sub64(x60, x61, ~x50^(((x40)>>23)|((x41)<<9)), x51^((~x41)>>23)); \
+      round7(b0,b1,c0,c1,a0,a1,x70,x71);
+
+/* mixed with key_schedule
+ */
+#define pass9(a0,a1,b0,b1,c0,c1) \
+      round9(a0,a1,b0,b1,c0,c1,x00,x01); \
+      sub64(x00, x01, x70^0xA5A5A5A5, x71^0xA5A5A5A5); \
+      round9(b0,b1,c0,c1,a0,a1,x10,x11); \
+      xor64(x10, x11, x00, x01); \
+      round9(c0,c1,a0,a1,b0,b1,x20,x21); \
+      add64(x20, x21, x10, x11); \
+      round9(a0,a1,b0,b1,c0,c1,x30,x31); \
+      sub64(x30, x31, x20^((~x10)<<19), ~x21^(((x11)<<19)|((x10)>>13))); \
+      round9(b0,b1,c0,c1,a0,a1,x40,x41); \
+      xor64(x40, x41, x30, x31); \
+      round9(c0,c1,a0,a1,b0,b1,x50,x51); \
+      add64(x50, x51, x40, x41); \
+      round9(a0,a1,b0,b1,c0,c1,x60,x61); \
+      sub64(x60, x61, ~x50^(((x40)>>23)|((x41)<<9)), x51^((~x41)>>23)); \
+      round9(b0,b1,c0,c1,a0,a1,x70,x71);
+
+#define key_schedule \
+      xor64(x70, x71, x60, x61); \
+      add64(x00, x01, x70, x71); \
+      sub64(x10, x11, x00^((~x70)<<19), ~x01^(((x71)<<19)|((x70)>>13))); \
+      xor64(x20, x21, x10, x11); \
+      add64(x30, x31, x20, x21); \
+      sub64(x40, x41, ~x30^(((x20)>>23)|((x21)<<9)), x31^((~x21)>>23)); \
+      xor64(x50, x51, x40, x41); \
+      add64(x60, x61, x50, x51); \
+      sub64(x70, x71, x60^0x89ABCDEF, x61^0x01234567);
+
+#define feedforward \
+      xor64(a0, a1, aa0, aa1); \
+      sub64(b0, b1, bb0, bb1); \
+      add64(c0, c1, cc0, cc1);
+
+#define compress \
+      pass5(a0,a1,b0,b1,c0,c1); \
+      key_schedule; \
+      pass7(c0,c1,a0,a1,b0,b1); \
+      key_schedule; \
+      pass9(b0,b1,c0,c1,a0,a1); \
+      feedforward
 
 #define tiger_compress_macro(str, state) \
 { \
-  register sh_word32 a0, a1, b0, b1, c0, c1, tmpa; \
+  register sh_word32 a0, a1, b0, b1, c0, c1; \
   sh_word32 aa0, aa1, bb0, bb1, cc0, cc1; \
   sh_word32 x00, x01, x10, x11, x20, x21, x30, x31, \
-         x40, x41, x50, x51, x60, x61, x70, x71; \
-  register sh_word32 temp0, temp1, tempt0, tempt1, temps0, tcarry; \
-  int pass_no; \
+                  x40, x41, x50, x51, x60, x61, x70, x71; \
+  sh_word32 temp0, temp1, tempt0, tempt1, temps0, tcarry; \
 \
   a0 = state[0]; \
@@ -208,4 +235,6 @@
   c1 = state[5]; \
 \
+      save_abc \
+\
   x00=str[0*2]; x01=str[0*2+1]; x10=str[1*2]; x11=str[1*2+1]; \
   x20=str[2*2]; x21=str[2*2+1]; x30=str[3*2]; x31=str[3*2+1]; \
@@ -213,5 +242,5 @@
   x60=str[6*2]; x61=str[6*2+1]; x70=str[7*2]; x71=str[7*2+1]; \
 \
-  sh_compress; \
+  compress; \
 \
   state[0] = a0; \
@@ -223,10 +252,11 @@
 }
 
-#ifdef UNROLL_COMPRESS
+#if defined(UNROLL_COMPRESS)
 /* The compress function is inlined */
 #define tiger_compress(str, state) \
   tiger_compress_macro(((sh_word32*)str), ((sh_word32*)state))
-#else
-/* The compress function is a function */
+
+#else
+
 void
 tiger_compress(sh_word32 *str, sh_word32 state[6])
@@ -249,8 +279,8 @@
 #ifdef BIG_ENDIAN
       for(j=0; j<64; j++)
-	temp[j^3] = ((sh_byte*)str)[j];
-      tiger_compress(((sh_word32*)temp), res);
-#else
-      tiger_compress(str, res);
+        temp[j^3] = ((sh_byte*)str)[j];
+      tiger_compress_macro(((sh_word32*)temp), res);
+#else
+      tiger_compress_macro(str, res);
 #endif
       str += 16;
@@ -258,9 +288,18 @@
 }
 
-void
-tiger(sh_word32 *str, sh_word32 length, sh_word32 res[6])
+
+void tiger(sh_word32 *str, sh_word32 length, sh_word32 res[6])
 {
   register sh_word32 i, j;
   sh_byte temp[64];
+
+  /*
+   * res[0]=0x89ABCDEF;
+   * res[1]=0x01234567;
+   * res[2]=0x76543210;
+   * res[3]=0xFEDCBA98;
+   * res[4]=0xC3B2E187;
+   * res[5]=0xF096A5B4;
+   */
 
   for(i=length; i>=64; i-=64)
@@ -307,18 +346,4 @@
 }
 
-#else
-void dummy_1 (int a)
-{
-  (void) a;
-  return;
-}
-#endif
-
-
-
-
-
-
-
-
-
+#endif
+
Index: trunk/src/sh_tiger1_64.c
===================================================================
--- trunk/src/sh_tiger1_64.c	(revision 17)
+++ trunk/src/sh_tiger1_64.c	(revision 18)
@@ -5,13 +5,14 @@
 #include "config_xor.h"
 
-#if defined(HAVE_LONG_64) || defined(HAVE_LONG_LONG_64)
-
-/*@-incondefs -macroparens -macroassign -macroparams -macrostmt @*/
-/*@-fixedformalarray +charindex -type -paramuse -predboolint -exportlocal@*/
+#if defined(TIGER_64_BIT)
+
+/* #if defined(HAVE_LONG_64) || defined(HAVE_LONG_LONG_64) */
+
+#undef USE_MEMSET
+
 /* Big endian:                                         */
 #ifdef WORDS_BIGENDIAN
 #define BIG_ENDIAN
 #endif
-
 
 /* Tiger: A Fast New Hash Function
@@ -38,6 +39,8 @@
 #if defined(HAVE_LONG_64)
 typedef unsigned long int word64;
-#else
+#elif defined(HAVE_LONG_LONG_64)
 typedef unsigned long long int word64;
+#else
+#error No 64 bit type found !
 #endif
 
@@ -49,34 +52,26 @@
 typedef unsigned short sh_word32;
 #else
-#error No 32 byte type found !
+#error No 32 bit type found !
 #endif
 
 typedef unsigned char sh_byte;
 
-/* Big endian:                                         
-   #if !(defined(__alpha)||defined(__i386__)||defined(__vax__))
-   #define BIG_ENDIAN
-   #endif
-*/
-
-/* The following macro denotes that an optimization    */
-/* for Alpha is required. It is used only for          */
-/* optimization of time. Otherwise it does nothing.    */
-#ifdef __alpha
-#define OPTIMIZE_FOR_ALPHA
-#endif
-
-/* NOTE that this code is NOT FULLY OPTIMIZED for any  */
-/* machine. Assembly code might be much faster on some */
-/* machines, especially if the code is compiled with   */
-/* gcc.                                                */
-
-/* The number of passes of the hash function.          */
-/* Three passes are recommended.                       */
-/* Use four passes when you need extra security.       */
-/* Must be at least three.                             */
+#if defined(TIGER_OPT_ASM)
+#define TIGER_ASM64_2 1
+#else
+#define TIGER_C 1
+#endif
+
+/* The number of passes of the hash function.		   */
+/* Three passes are recommended.			   */
+/* Use four passes when you need extra security.	   */
+/* Must be at least three.				   */
 #define PASSES 3
 
 extern word64 tiger_table[4*256];
+
+/* Volatile can help if compiler is smart enough to use memory operand */
+static /*volatile*/ const word64 XOR_CONST1=0xA5A5A5A5A5A5A5A5LL;
+static /*volatile*/ const word64 XOR_CONST2=0x0123456789ABCDEFLL;
 
 #define t1 (tiger_table)
@@ -85,97 +80,279 @@
 #define t4 (tiger_table+256*3)
 
+#define pass_start
+#define pass_end
+
+
+
 #define save_abc \
-      aa = a; \
-      bb = b; \
-      cc = c;
-
-#ifdef OPTIMIZE_FOR_ALPHA
-/* This is the official definition of round */
-#define round(a,b,c,x,mul) \
-      c ^= x; \
-      a -= t1[((c)>>(0*8))&0xFF] ^ t2[((c)>>(2*8))&0xFF] ^ \
-	   t3[((c)>>(4*8))&0xFF] ^ t4[((c)>>(6*8))&0xFF] ; \
-      b += t4[((c)>>(1*8))&0xFF] ^ t3[((c)>>(3*8))&0xFF] ^ \
-	   t2[((c)>>(5*8))&0xFF] ^ t1[((c)>>(7*8))&0xFF] ; \
-      b *= mul;
-#else
-/* This code works faster when compiled on 32-bit machines */
-/* (but works slower on Alpha) */
-#define round(a,b,c,x,mul) \
-      c ^= x; \
-      a -= t1[(sh_byte)(c)] ^ \
-           t2[(sh_byte)(((sh_word32)(c))>>(2*8))] ^ \
-	   t3[(sh_byte)((c)>>(4*8))] ^ \
-           t4[(sh_byte)(((sh_word32)((c)>>(4*8)))>>(2*8))] ; \
-      b += t4[(sh_byte)(((sh_word32)(c))>>(1*8))] ^ \
-           t3[(sh_byte)(((sh_word32)(c))>>(3*8))] ^ \
-	   t2[(sh_byte)(((sh_word32)((c)>>(4*8)))>>(1*8))] ^ \
-           t1[(sh_byte)(((sh_word32)((c)>>(4*8)))>>(3*8))]; \
-      b *= mul;
-#endif
-
-#define pass(a,b,c,mul) \
-      round(a,b,c,x0,mul) \
-      round(b,c,a,x1,mul) \
-      round(c,a,b,x2,mul) \
-      round(a,b,c,x3,mul) \
-      round(b,c,a,x4,mul) \
-      round(c,a,b,x5,mul) \
-      round(a,b,c,x6,mul) \
-      round(b,c,a,x7,mul)
+	  aa = a; \
+	  bb = b; \
+	  cc = c;
+
+#ifdef TIGER_C
+
+#define BN(x,n) (((x)>>((n)*8))&0xFF)
+
+
+/* Depending on outer code one of these two can be better*/
+#define roundX(a,b,c,x) \
+	c ^= x; \
+	a -= t1[BN(c,0)] ^ t2[BN(c,2)] ^ \
+	     t3[BN(c,4)] ^ t4[BN(c,6)] ; \
+	b += t4[BN(c,1)] ^ t3[BN(c,3)] ^ \
+	     t2[BN(c,5)] ^ t1[BN(c,7)] ;
+
+#define round5(a,b,c,x) roundX(a,b,c,x) b = b+b*4;
+#define round7(a,b,c,x) roundX(a,b,c,x) b = b*8-b;
+#define round9(a,b,c,x) roundX(a,b,c,x) b = b+b*8;
+
+#endif
+
+
+#ifdef TIGER_OPT_ASM
+
+#define MASK0		0xFFL
+#define MASK8		0xFF00L
+#define MASK16		0xFF0000L
+#define MASK32		0xFF00000000LL
+#define MASK40		0xFF0000000000LL
+#define MASK48		0xFF000000000000LL
+
+#define roundstart	__asm__ (
+
+/* a will be moved into different reg each round
+ * using register substitution feature of  GCC asm
+ * b will be moved in 2-nd pass rounds only
+ */
+
+
+#define roundend(a,b,c,x) \
+ : "+r" (a), "+r" (b), "+r" (c) \
+ : "0" (a), "1" (b), "2" (c), "m" (x), "r" (&tiger_table),\
+  "i" (MASK0), "i" (MASK8), "i" (MASK16), "r" (MASK32), "r" (MASK40), "r" (MASK48) \
+ : "3", "%rax","%rbx","%rcx","%rdx","%rsi", "%edi", "%r8"  );
+
+
+/*	c ^= x; 
+	a -= t1[BN(c,0)] ^ t2[BN(c,2)] ^ 
+	t3[BN(c,4)] ^ t4[BN(c,6)] ; 
+	b += t4[BN(c,1)] ^ t3[BN(c,3)] ^ 
+	t2[BN(c,5)] ^ t1[BN(c,7)] ; 	*/
+
+#define roundX(a,b,c,x)   \
+"	movl	%10, %%ebx	\n"\
+"	movq	%11, %%rcx	\n"\
+"	movq	%13, %%rdx	\n"\
+"	movq	%6, %%r8  \n"\
+"	xorq	%%r8, %2		 \n" \
+"	andq	%2, %%rbx  \n"\
+"	andq	%2, %%rcx  \n"\
+"	andq	%2, %%rdx  \n"\
+"	shrl	$(16-3), %%ebx	\n"\
+"	shrq	$(32-3), %%rcx	\n"\
+"	shrq	$(48-3), %%rdx	\n"\
+"	movzbl	%2b, %%eax	\n"\
+"	movzwl	%2w, %%edi	\n"\
+"	movq	(%7,%%rax,8), %%rsi  \n"\
+"	shrl	$(8), %%edi  \n" \
+"	movq	%2, %%rax  \n" \
+"	xorq	(2048*1)(%7,%%rbx), %%rsi  \n"\
+"	movq	%2, %%rbx  \n"\
+"	shrl	$24, %%eax \n"\
+"	andq	%12, %%rbx	\n"\
+"	xorq	(2048*2)(%7,%%rcx), %%rsi  \n"\
+"	shrq	$(40-3), %%rbx \n"\
+"	movq	%2, %%rcx  \n"\
+"	xorq	(2048*3)(%7,%%rdx), %%rsi  \n"\
+"	movq	(2048*3)(%7,%%rdi,8), %%rdx  \n"\
+"	shrq	$56, %%rcx \n"\
+"	xorq	(2048*2)(%7,%%rax,8), %%rdx  \n"\
+"	xorq	(2048*1)(%7,%%rbx), %%rdx  \n" \
+"	subq	 %%rsi, %0 \n"\
+"	xorq	(%7,%%rcx,8), %%rdx  \n"\
+"	addq	 %%rdx, %1 \n"
+
+#define round5(a,b,c,x) \
+	roundstart \
+	roundX(a,b,c,x) \
+	/* b*=5; */ \
+	"leaq	(%1,%1,4), %1\n" \
+	roundend(a,b,c,x)
+
+
+#define round7(a,b,c,x) \
+	roundstart \
+	roundX(a,b,c,x) \
+	roundend(a,b,c,x) \
+	/* b*=7; */ \
+	__asm__ ( \
+	"leaq	(%1,%1,8), %0\n" \
+	"addq  %1, %1 \n" \
+	"subq  %1, %0 " \
+	:"=&r" (b): "r"(b): "1" );
+
+#define round9(a,b,c,x) \
+	roundstart \
+	roundX(a,b,c,x) \
+	"leaq	(%1,%1,8), %1\n" \
+	roundend(a,b,c,x)
+
+#endif
+
+
+
+
+/* ============== Common macros ================== */
 
 #define key_schedule \
-      x0 -= x7 ^ 0xA5A5A5A5A5A5A5A5LL; \
-      x1 ^= x0; \
-      x2 += x1; \
-      x3 -= x2 ^ ((~x1)<<19); \
-      x4 ^= x3; \
-      x5 += x4; \
-      x6 -= x5 ^ ((~x4)>>23); \
-      x7 ^= x6; \
-      x0 += x7; \
-      x1 -= x0 ^ ((~x7)<<19); \
-      x2 ^= x1; \
-      x3 += x2; \
-      x4 -= x3 ^ ((~x2)>>23); \
-      x5 ^= x4; \
-      x6 += x5; \
-      x7 -= x6 ^ 0x0123456789ABCDEFLL;
+	x0 -= x7 ^ XOR_CONST1; \
+	x1 ^= x0; \
+	x2 += x1;\
+	x3 -= x2 ^ ((~x1)<<19);\
+	x4 ^= x3;\
+	x5 += x4;\
+	x6 -= x5 ^ ((~x4)>>23); \
+	x7 ^= x6; \
+	x0 += x7; \
+	x1 -= x0 ^ ((~x7)<<19); \
+	x2 ^= x1; \
+	x3 += x2; \
+	x4 -= x3 ^ ((~x2)>>23); \
+	x5 ^= x4; \
+	x6 += x5; \
+	x7 -= x6 ^ XOR_CONST2;
+
+#define pass5n(a,b,c) \
+	  round5(a,b,c,x0) \
+	x0 -= x7 ^ XOR_CONST1; \
+	  round5(b,c,a,x1) \
+	x1 ^= x0; \
+	  round5(c,a,b,x2) \
+	x2 += x1; \
+	  round5(a,b,c,x3) \
+	x3 -= x2 ^ ((~x1)<<19); \
+	  round5(b,c,a,x4) \
+	x4 ^= x3; \
+	  round5(c,a,b,x5) \
+	x5 += x4; \
+	  round5(a,b,c,x6) \
+	x6 -= x5 ^ ((~x4)>>23); \
+	  round5(b,c,a,x7) \
+	x7 ^= x6; \
+	x0 += x7; \
+	x1 -= x0 ^ ((~x7)<<19); \
+	x2 ^= x1; \
+	x3 += x2; \
+	x4 -= x3 ^ ((~x2)>>23); \
+	x5 ^= x4; \
+	x6 += x5; \
+	x7 -= x6 ^ XOR_CONST2;
+
+#define pass7n(a,b,c) \
+	  round7(a,b,c,x0) \
+	x0 -= x7 ^ XOR_CONST1; \
+	  round7(b,c,a,x1) \
+	x1 ^= x0; \
+	  round7(c,a,b,x2) \
+	x2 += x1; \
+	  round7(a,b,c,x3) \
+	x3 -= x2 ^ ((~x1)<<19); \
+	  round7(b,c,a,x4) \
+	x4 ^= x3; \
+	  round7(c,a,b,x5) \
+	x5 += x4; \
+	  round7(a,b,c,x6) \
+	x6 -= x5 ^ ((~x4)>>23); \
+	  round7(b,c,a,x7) \
+	x7 ^= x6; \
+	x0 += x7; \
+	x1 -= x0 ^ ((~x7)<<19); \
+	x2 ^= x1; \
+	x3 += x2; \
+	x4 -= x3 ^ ((~x2)>>23); \
+	x5 ^= x4; \
+	x6 += x5; \
+	x7 -= x6 ^ XOR_CONST2;
+
+#define pass5(a,b,c) \
+	pass_start \
+	  round5(a,b,c,x0) \
+	  round5(b,c,a,x1) \
+	  round5(c,a,b,x2) \
+	  round5(a,b,c,x3) \
+	  round5(b,c,a,x4) \
+	  round5(c,a,b,x5) \
+	  round5(a,b,c,x6) \
+	  round5(b,c,a,x7) \
+	pass_end
+
+#define pass7(a,b,c) \
+	pass_start \
+	  round7(a,b,c,x0) \
+	  round7(b,c,a,x1) \
+	  round7(c,a,b,x2) \
+	  round7(a,b,c,x3) \
+	  round7(b,c,a,x4) \
+	  round7(c,a,b,x5) \
+	  round7(a,b,c,x6) \
+	  round7(b,c,a,x7) \
+	pass_end
+
+
+#define pass9(a,b,c) \
+	pass_start \
+	  round9(a,b,c,x0) \
+	  round9(b,c,a,x1) \
+	  round9(c,a,b,x2) \
+	  round9(a,b,c,x3) \
+	  round9(b,c,a,x4) \
+	  round9(c,a,b,x5) \
+	  round9(a,b,c,x6) \
+	  round9(b,c,a,x7) \
+	pass_end
 
 #define feedforward \
-      a ^= aa; \
-      b -= bb; \
-      c += cc;
-
-#ifdef OPTIMIZE_FOR_ALPHA
-/* The loop is unrolled: works better on Alpha */
+	  a ^= aa; \
+	  b -= bb; \
+	  c += cc;
+
+
+/* This version works ok with C variant and also with new asm version 
+ * that just wastes a register r8 
+ * reason? who knows, write forwarding is faster than keeping value 
+ * in register? :) 
+ */
 #define compress \
-      save_abc \
-      pass(a,b,c,5) \
-      key_schedule \
-      pass(c,a,b,7) \
-      key_schedule \
-      pass(b,c,a,9) \
-      for(pass_no=3; pass_no<PASSES; pass_no++) { \
-        key_schedule \
-	pass(a,b,c,9) \
-	tmpa=a; a=c; c=b; b=tmpa;} \
-      feedforward
-#else
-/* loop: works better on PC and Sun (smaller cache?) */
-#define compress \
-      save_abc \
-      for(pass_no=0; pass_no<PASSES; pass_no++) { \
-        if(pass_no != 0) {key_schedule} \
-	pass(a,b,c,(pass_no==0?5:pass_no==1?7:9)); \
-	tmpa=a; a=c; c=b; b=tmpa;} \
-      feedforward
-#endif
+	save_abc \
+	  pass5n(a,b,c) \
+	  pass7n(c,a,b) \
+	  pass9(b,c,a) \
+	  for(pass_no=3; pass_no<PASSES; pass_no++) { \
+		key_schedule \
+		pass9(a,b,c) \
+		tmpa=a; a=c; c=b; b=tmpa; \
+	  } \
+	feedforward
+
+#define compress_old \
+	save_abc \
+	  pass5(a,b,c) \
+	  key_schedule \
+	  pass7(c,a,b) \
+	  key_schedule \
+	  pass9(b,c,a) \
+	  for(pass_no=3; pass_no<PASSES; pass_no++) { \
+		key_schedule \
+		pass9(a,b,c) \
+		tmpa=a; a=c; c=b; b=tmpa; \
+	  } \
+	feedforward
 
 #define tiger_compress_macro(str, state) \
 { \
-  register word64 a, b, c, tmpa; \
+  register word64 a, b, c; \
+  register word64 tmpa; \
   word64 aa, bb, cc; \
-  register word64 x0, x1, x2, x3, x4, x5, x6, x7; \
+  word64 x0, x1, x2, x3, x4, x5, x6, x7; \
   int pass_no; \
 \
@@ -194,19 +371,8 @@
 }
 
-/* The compress function is a function. Requires smaller cache?    */
 void tiger_compress(word64 *str, word64 state[3])
 {
-#ifndef S_SPLINT_S
   tiger_compress_macro(((word64*)str), ((word64*)state));
-#endif
 }
-
-#ifdef OPTIMIZE_FOR_ALPHA
-/* The compress function is inlined: works better on Alpha.        */
-/* Still leaves the function above in the code, in case some other */
-/* module calls it directly.                                       */
-#define tiger_compress(str, state) \
-  tiger_compress_macro(((word64*)str), ((word64*)state))
-#endif
 
 void tiger_t(word64 *str, word64 length, word64 res[3])
@@ -220,8 +386,8 @@
 
   /*
-    res[0]=0x0123456789ABCDEFLL;
-    res[1]=0xFEDCBA9876543210LL;
-    res[2]=0xF096A5B4C3B2E187LL;
-  */
+   * res[0]=0x0123456789ABCDEFLL;
+   * res[1]=0xFEDCBA9876543210LL;
+   * res[2]=0xF096A5B4C3B2E187LL;
+   */
 
   for(i=length; i>=64; i-=64)
@@ -229,5 +395,5 @@
 #ifdef BIG_ENDIAN
       for(j=0; j<64; j++)
-	temp[j^7] = ((sh_byte*)str)[j];
+        temp[j^7] = ((sh_byte*)str)[j];
       tiger_compress(((word64*)temp), res);
 #else
@@ -236,5 +402,4 @@
       str += 8;
     }
-
 }
 
@@ -246,8 +411,8 @@
 
   /*
-    res[0]=0x0123456789ABCDEFLL;
-    res[1]=0xFEDCBA9876543210LL;
-    res[2]=0xF096A5B4C3B2E187LL;
-  */
+   * res[0]=0x0123456789ABCDEFLL;
+   * res[1]=0xFEDCBA9876543210LL;
+   * res[2]=0xF096A5B4C3B2E187LL;
+   */
 
   for(i=length; i>=64; i-=64)
@@ -255,5 +420,5 @@
 #ifdef BIG_ENDIAN
       for(j=0; j<64; j++)
-	temp[j^7] = ((sh_byte*)str)[j];
+        temp[j^7] = ((sh_byte*)str)[j];
       tiger_compress(((word64*)temp), res);
 #else
@@ -272,41 +437,39 @@
     temp[j^7] = 0;
 #else
+
+#ifndef USE_MEMSET
   for(j=0; j<i; j++)
     temp[j] = ((sh_byte*)str)[j];
-
+#else
+  memcpy( temp, str, j=i );
+#endif
   temp[j++] = 0x01;
   for(; j&7; j++)
-    temp[j] = 0;
-#endif
+	temp[j] = 0;
+
+#endif
+
   if(j>56)
     {
+#ifndef USE_MEMSET
       for(; j<64; j++)
 	temp[j] = 0;
+#else
+      memset( temp+j, 0, 64-j);
+#endif
       tiger_compress(((word64*)temp), res);
       j=0;
     }
 
+#ifndef USE_MEMSET
   for(; j<56; j++)
     temp[j] = 0;
+#else
+  memset( temp+j, 0, 56-j);
+#endif
+
   ((word64*)(&(temp[56])))[0] = ((word64)length)<<3;
   tiger_compress(((word64*)temp), res);
 }
 
-#else
-
-void dummy_1_64 (int a)
-{
-  (void) a;
-  return;
-}
-
-#endif
-
-
-
-
-
-
-
-
-
+#endif
Index: trunk/src/sh_tiger2.c
===================================================================
--- trunk/src/sh_tiger2.c	(revision 17)
+++ trunk/src/sh_tiger2.c	(revision 18)
@@ -23,10 +23,20 @@
 
 
-#if !defined(HAVE_LONG_64) && !defined(HAVE_LONG_LONG_64)
-
+#if !defined(TIGER_64_BIT)
+
+/* #if !defined(HAVE_LONG_64) && !defined(HAVE_LONG_LONG_64) */
 
 /* sboxes32.c: Tiger S boxes for 32-bit-only compilers */
-typedef unsigned long word32;
-word32 tiger_table[4*256][2] = {
+#if defined(HAVE_INT_32)
+typedef unsigned int sh_word32;
+#elif defined(HAVE_LONG_32)
+typedef unsigned long sh_word32;
+#elif defined(HAVE_SHORT_32)
+typedef unsigned short sh_word32;
+#else
+#error No 32 bit type found !
+#endif
+
+sh_word32 tiger_table[4*256][2] = {
   { 0xF7E90C5E, 0x02AAB17C /*    0 */},  {  0xE243A8EC, 0xAC424B03 /*    1 */},
   { 0x0DD5FCD3, 0x72CD5BE3 /*    2 */},  {  0xF6F97F3A, 0x6D019B93 /*    3 */},
Index: trunk/src/sh_tiger2_64.c
===================================================================
--- trunk/src/sh_tiger2_64.c	(revision 17)
+++ trunk/src/sh_tiger2_64.c	(revision 18)
@@ -22,6 +22,7 @@
 #include "config_xor.h"
 
-
-#if defined(HAVE_LONG_64) || defined(HAVE_LONG_LONG_64)
+#if defined(TIGER_64_BIT)
+
+/* #if defined(HAVE_LONG_64) || defined(HAVE_LONG_LONG_64) */
 
 /*@-type@*/
@@ -30,6 +31,8 @@
 #if defined(HAVE_LONG_64)
 typedef unsigned long int word64;
+#elif defined(HAVE_LONG_LONG_64)
+typedef unsigned long long int word64;
 #else
-typedef unsigned long long int word64;
+#error No 64 bit type found !
 #endif
 
Index: trunk/src/sh_tools.c
===================================================================
--- trunk/src/sh_tools.c	(revision 17)
+++ trunk/src/sh_tools.c	(revision 18)
@@ -125,5 +125,5 @@
 char * sh_tools_safe_name (const char * instr, int flag)
 {
-  unsigned char c;
+  unsigned char c, d;
   const  char * p;
   char   *q;
@@ -133,4 +133,6 @@
   int    i = 0;
   unsigned char   val_octal = '\0';
+  static char ctable[16] = { '0', '1', '2', '3', '4', '5', '6', '7', 
+			     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 
 
   SL_ENTER(_("sh_tools_safe_name"));
@@ -202,5 +204,8 @@
 	    {
 	      --i;
-	      sprintf(&outstr[i], "=%02x", c);          /* known to fit  */
+	      d = c % 16; c = c / 16;
+	      outstr[i] = '=';       ++i;
+	      outstr[i] = ctable[c]; ++i;
+	      outstr[i] = ctable[d]; ++i;
 	    }
 
@@ -274,5 +279,5 @@
 	    break;
 	  default:
-	    if (strlen(p) < 3)
+	    if (strlen(p) < 3) /* certainly not an octal number, skip */
 	      {
 		p += strlen(p);
@@ -284,6 +289,8 @@
 		if (val_octal != '\0') { 
 		  c = val_octal;
-		  sprintf(&outstr[i], "=%02x", c);       /* known to fit  */
-		  i+=3;
+		  d = c % 16; c = c / 16;
+		  outstr[i] = '=';       ++i;
+		  outstr[i] = ctable[c]; ++i;
+		  outstr[i] = ctable[d]; ++i;
 		} 
 		p += 3;
@@ -294,6 +301,9 @@
 	{
 	  ++p;
-	  if (!p || !(*p)) 
-	    break;
+	  if (!p || !(*p))
+	    {
+	      outstr[i] = '&'; ++i;
+	      break;
+	    }
 
 	  if (p[0] == 'a' && p[1] == 'm' && p[2] == 'p' && p[3] == ';')
Index: trunk/src/sh_unix.c
===================================================================
--- trunk/src/sh_unix.c	(revision 17)
+++ trunk/src/sh_unix.c	(revision 18)
@@ -1283,4 +1283,14 @@
      */
     if (0 == sl_strncmp((*env), _("MYSQL_UNIX_PORT="), 16))
+      {
+	++(env);
+	continue;
+      }
+    if (0 == sl_strncmp((*env), _("MYSQL_TCP_PORT="), 15))
+      {
+	++(env);
+	continue;
+      }
+    if (0 == sl_strncmp((*env), _("MYSQL_HOME="), 11))
       {
 	++(env);
