Index: trunk/src/cutest_sh_tiger0.c
===================================================================
--- trunk/src/cutest_sh_tiger0.c	(revision 443)
+++ trunk/src/cutest_sh_tiger0.c	(revision 444)
@@ -8,4 +8,5 @@
 
 #include "sh_tiger.h"
+#include "sh_checksum.h"
 
 #if defined(HAVE_PTHREAD) && defined(SH_STEALTH)
@@ -135,4 +136,5 @@
   char * expected;
   char hashbuf[KEYBUF_SIZE];
+  char hexdigest[SHA256_DIGEST_STRING_LENGTH];
   UINT64  length;
 
@@ -197,4 +199,23 @@
   actual = sh_tiger_generic_hash("cutest_foo", rval_open, &length, 0, hashbuf, sizeof(hashbuf));
   expected = "2FE65D1D995B8F8BC8B13F798C07E7E935A787ED00000000";
+  CuAssertStrEquals(tc, expected, actual);
+
+  result = sl_close(rval_open);
+  CuAssertTrue(tc, result == 0);
+
+  result = sh_tiger_hashtype("SHA256");
+  CuAssertTrue(tc, result == 0);
+
+  rval_open = sl_open_fastread (__FILE__, __LINE__, "cutest_foo", SL_YESPRIV);
+  CuAssertTrue(tc, rval_open >= 0);
+
+  /* same result as gpg --print-md SHA256
+   */
+  length = TIGER_NOLIM;
+  {
+    char * tmp = sh_tiger_generic_hash("cutest_foo", rval_open, &length, 0, hashbuf, sizeof(hashbuf));
+    actual = SHA256_Base2Hex(tmp, hexdigest);
+  }
+  expected = "235790848f95e96b2c627f1bf58a2b8c05c535ada8c0a3326aac34ce1391ad40";
   CuAssertStrEquals(tc, expected, actual);
 
Index: trunk/src/cutest_sh_utils.c
===================================================================
--- trunk/src/cutest_sh_utils.c	(revision 443)
+++ trunk/src/cutest_sh_utils.c	(revision 444)
@@ -139,5 +139,5 @@
 
   ret = sh_util_base64_enc (out, inp0, strlen((char*)inp0));
-  CuAssertIntEquals(tc, ret, 0);
+  CuAssertIntEquals(tc, 0, ret);
   CuAssertStrEquals(tc, "", (char*)out);
   ret = sh_util_base64_dec (ou2, out, strlen((char*)out));
Index: trunk/src/sh_error.c
===================================================================
--- trunk/src/sh_error.c	(revision 443)
+++ trunk/src/sh_error.c	(revision 444)
@@ -867,5 +867,50 @@
 }
 #endif
-  
+
+#if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE)
+#include "sh_checksum.h"
+static char * sh_error_replace(const char * msg)
+{
+  char * ret   = NULL;
+
+  if (sh_tiger_get_hashtype () == SH_SHA256)
+    {
+      char * store = NULL;
+
+#ifdef SH_USE_XML
+      char c_end  = '"';
+      char * str  = _("chksum_old=\"");
+      char * str2 = _("chksum_new=\"");
+#else
+      char c_end  = '>';
+      char * str  = _("chksum_old=<");
+      char * str2 = _("chksum_new=<");
+#endif
+
+      ret = SHA256_ReplaceBaseByHex(msg, str, c_end);
+
+      if (ret) {
+	store = ret;
+	ret   = SHA256_ReplaceBaseByHex(ret, str2, c_end);
+	if (ret)
+	  SH_FREE(store);
+	else
+	  ret = store;
+      } else {
+	ret   = SHA256_ReplaceBaseByHex(msg, str2, c_end);
+      }
+    }
+  return ret;
+}
+static void sh_replace_free(char * msg)
+{
+  if (msg)
+    SH_FREE(msg);
+  return;
+}
+#else
+static char * sh_error_replace(const char * msg) { (void) msg; return NULL; }
+static void sh_replace_free(char * msg) { (void) msg; return; }
+#endif
 
 /**********************************************************
@@ -910,4 +955,6 @@
 #endif
 
+  char   * hexmsg = NULL;
+
   static int    own_block = 0;
 
@@ -1083,4 +1130,5 @@
   own_block = 0;
 
+  hexmsg = sh_error_replace(lmsg->msg);
 
   /* Log to stderr.
@@ -1103,5 +1151,5 @@
 	   *  Reports first error after failure. Always tries.
 	   */
-	  (void) sh_log_console (lmsg->msg);
+	  (void) sh_log_console (hexmsg ? hexmsg : lmsg->msg);
 	  print_block = 0;
 	}
@@ -1131,5 +1179,5 @@
 	       * Ignores errors. Always tries.
 	       */
-	      (void) sh_log_syslog (lmsg->severity, lmsg->msg);
+	      (void) sh_log_syslog (lmsg->severity, hexmsg ? hexmsg : lmsg->msg);
 	      syslog_block = 0;
 	    }
@@ -1153,5 +1201,5 @@
 	       *  Reports first error after failure. Always tries.
 	       */
-	      (void) sh_ext_execute ('l', 'o', 'g', lmsg->msg, 0);
+	      (void) sh_ext_execute ('l', 'o', 'g', hexmsg ? hexmsg : lmsg->msg, 0);
 	      external_block = 0;
 	    }
@@ -1270,7 +1318,7 @@
 	      BREAKEXIT(sh_nmail_msg);
 	      if ( (severity & SH_ERR_FATAL) == 0) 
-		retval = sh_nmail_pushstack (severity, lmsg->msg, NULL);
+		retval = sh_nmail_pushstack (severity, hexmsg ? hexmsg : lmsg->msg, NULL);
 	      else 
-		retval = sh_nmail_msg (severity, lmsg->msg, NULL);
+		retval = sh_nmail_msg (severity, hexmsg ? hexmsg : lmsg->msg, NULL);
 
 	      mail_block = 0;
@@ -1306,9 +1354,9 @@
 #if defined(HAVE_LIBPRELUDE) && defined(SH_WITH_SERVER) 
 	      (void) sh_prelude_alert (severity, (int) class, 
-				       lmsg->msg, lmsg->status, msg_id, 
+				       hexmsg ? hexmsg : lmsg->msg, lmsg->status, msg_id, 
 				       local_inet_peer_ip);
 #else
 	      (void) sh_prelude_alert (severity, (int) class, 
-				       lmsg->msg, lmsg->status, msg_id, 
+				       hexmsg ? hexmsg : lmsg->msg, lmsg->status, msg_id, 
 				       NULL);
 #endif
@@ -1351,5 +1399,5 @@
 		}
 #else
-              (void) sh_log_file (lmsg->msg, NULL);
+              (void) sh_log_file (hexmsg ? hexmsg : lmsg->msg, NULL);
 #endif
 	      /* sh_log_file (lmsg->msg); */
@@ -1366,4 +1414,5 @@
   if (lmsg->msg)
     SH_FREE( lmsg->msg );
+  sh_replace_free(hexmsg);
 
   memset ( lmsg, (int) '\0', sizeof(struct _log_t) );
Index: trunk/src/sh_hash.c
===================================================================
--- trunk/src/sh_hash.c	(revision 443)
+++ trunk/src/sh_hash.c	(revision 444)
@@ -34,4 +34,5 @@
 #include <sys/stat.h>
 #include <unistd.h>
+#include <ctype.h>
 
 #ifdef MAJOR_IN_MKDEV
@@ -3973,6 +3974,41 @@
 }
 
-
+int isHexKey(char * s)
+{
+  int i;
+  
+  for (i = 0; i < KEY_LEN; ++i)
+    {
+      if (*s)
+	{
+	  if ((*s >= '0' && *s <= '9') ||
+	      (*s >= 'A' && *s <= 'F') ||
+	      (*s >= 'a' && *s <= 'f'))
+	    {
+	      ++s;
+	      continue;
+	    }
+	}
+      return S_FALSE;
+    }
+  return S_TRUE;
+}
  
+#include "sh_checksum.h"
+
+static char * KEYBUFtolower (char * s, char * result)
+{
+  char * r = result;
+  if (s)
+    {
+      for (; *s; ++s)
+	{ 
+	  *r = tolower((unsigned char) *s); ++r;
+	}
+      *r = '\0';
+    }
+  return result;
+}
+
 void sh_hash_list_db_entry_full_detail (sh_file_t * p)
 {
@@ -3980,4 +4016,6 @@
   char * esc;
   char   str[81];
+  char   hexdigest[SHA256_DIGEST_STRING_LENGTH];
+  char   keybuffer[KEYBUF_SIZE];
 
   if (ListWithDelimiter == S_TRUE)
@@ -4020,5 +4058,9 @@
   if (ListWithDelimiter == S_TRUE)
     putchar(',');
-  printf( _(" %s"), p->theFile.checksum);
+
+  if (isHexKey(p->theFile.checksum))
+    printf( _(" %s"), KEYBUFtolower(p->theFile.checksum, keybuffer));
+  else
+    printf( _(" %s"), SHA256_Base2Hex(p->theFile.checksum, hexdigest));
   if (ListWithDelimiter == S_TRUE)
     putchar(',');
Index: trunk/src/sh_tiger0.c
===================================================================
--- trunk/src/sh_tiger0.c	(revision 443)
+++ trunk/src/sh_tiger0.c	(revision 444)
@@ -1386,13 +1386,19 @@
 /*@+type@*/
 
+#include "sh_checksum.h"
+
+#define SH_VAR_SHA1   0
+#define SH_VAR_SHA256 1
+
 /* Compute SHA1 message digest for bytes read from STREAM.  The
    resulting message digest number will be written into the 16 bytes
    beginning at RESBLOCK.  */
-static int sha1_stream(char * filename, void *resblock, 
-		       UINT64 * Length, int timeout, SL_TICKET fd)
+static int SHA_stream(char * filename, void *resblock, 
+		      UINT64 * Length, int timeout, SL_TICKET fd, int variant)
 {
   /* Important: BLOCKSIZE must be a multiple of 64.  */
   static const int BLOCKSIZE = 4096;
   struct sha_ctx ctx;
+  SHA256_CTX ctx_sha2;
   char * buffer = SH_ALLOC(4168); /* BLOCKSIZE + 72 AIX compiler chokes */
   off_t sum = 0;
@@ -1410,5 +1416,8 @@
 
   /* Initialize the computation context.  */
-  (void) sha_init(&ctx);
+  if (variant == SH_VAR_SHA256)
+    (void) SHA256_Init(&ctx_sha2);
+  else
+    (void) sha_init(&ctx);
 
   if (SL_ISERROR (fd))
@@ -1506,5 +1515,8 @@
        BLOCKSIZE % 64 == 0
     */
-    sha_update(&ctx, (sha_word8*) buffer, (sha_word32) BLOCKSIZE);
+    if (variant == SH_VAR_SHA256)
+      SHA256_Update(&ctx_sha2, (sha2_byte*) buffer, (size_t) BLOCKSIZE);
+    else
+      sha_update(&ctx, (sha_word8*) buffer, (sha_word32) BLOCKSIZE);
     sh.statistics.bytes_hashed += BLOCKSIZE;
 
@@ -1528,12 +1540,22 @@
   if (sum > 0)
     {
-      sha_update(&ctx, (sha_word8*) buffer, (sha_word32) sum);
+      if (variant == SH_VAR_SHA256)
+	SHA256_Update(&ctx_sha2, (sha2_byte*) buffer, (size_t) sum);
+      else
+	sha_update(&ctx, (sha_word8*) buffer, (sha_word32) sum);
       sh.statistics.bytes_hashed += sum;
     }
 
-  sha_final (&ctx);
-
   /* Construct result in desired memory.  */
-  sha_digest (&ctx, resblock);
+  if (variant == SH_VAR_SHA256)
+    {
+      SHA256_End(&ctx_sha2, resblock);
+    }
+  else
+    {
+      sha_final (&ctx);
+      sha_digest (&ctx, resblock);
+    }
+
   *Length = bcount;
   SH_FREE(buffer);
@@ -1550,5 +1572,5 @@
   unsigned char sha1buffer[20];
 
-  (void) sha1_stream (filename, sha1buffer, Length, timeout, what);
+  (void) SHA_stream (filename, sha1buffer, Length, timeout, what, SH_VAR_SHA1);
 
   /*@-bufferoverflowhigh -usedef@*/
@@ -1565,8 +1587,20 @@
 }
 
+static char * sh_tiger_sha256_hash  (char * filename, TigerType what, 
+				     UINT64 * Length, int timeout, 
+				     char * out, size_t len)
+{
+  char outbuf[KEYBUF_SIZE];
+
+  (void) SHA_stream (filename, outbuf, Length, timeout, what, SH_VAR_SHA256);
+
+  sl_strlcpy(out, outbuf, len);
+  return out;
+}
+
 /* ifdef USE_SHA1 */
 #endif
 
-static int hash_type = 0;
+static int hash_type = SH_TIGER192;
 
 int sh_tiger_get_hashtype ()
@@ -1585,12 +1619,16 @@
 
   if (0 == strcmp(c, _("TIGER192")))
-    hash_type = 0;
+    hash_type = SH_TIGER192;
 #ifdef USE_SHA1
   else if (0 == strcmp(c, _("SHA1")))    
-    hash_type = 1;
+    hash_type = SH_SHA1;
 #endif
 #ifdef USE_MD5
   else if (0 == strcmp(c, _("MD5")))    
-    hash_type = 2;
+    hash_type = SH_MD5;
+#endif
+#ifdef USE_SHA1
+  else if (0 == strcmp(c, _("SHA256")))    
+    hash_type = SH_SHA256;
 #endif
   else
@@ -1618,10 +1656,14 @@
 {
 #ifdef USE_SHA1
-  if (hash_type == 1)
+  if (hash_type == SH_SHA1)
     return sh_tiger_sha1_hash    (filename, what, Length, timeout, out, len);
 #endif
 #ifdef USE_MD5
-  if (hash_type == 2)
+  if (hash_type == SH_MD5)
     return sh_tiger_md5_hash     (filename, what, Length, timeout, out, len);
+#endif
+#ifdef USE_SHA1
+  if (hash_type == SH_SHA256)
+    return sh_tiger_sha256_hash  (filename, what, Length, timeout, out, len);
 #endif
   return sh_tiger_hash_internal  (filename, what, Length, timeout, out, len);
Index: trunk/src/sh_utils.c
===================================================================
--- trunk/src/sh_utils.c	(revision 443)
+++ trunk/src/sh_utils.c	(revision 444)
@@ -2239,34 +2239,37 @@
   if (bto64[0] != '\0')
     {
-      if (instr && *instr)
+      if (instr /* && *instr *//* need to handle binary data */)
 	{
 	  if (lin == 0)
 	    lin = strlen((const char *)instr);
 
-	  do {
-	    ll = 0;
-
-	    if (len < lin) 
-	      { a = *instr; ++instr; ++len; ++ll; }
-	    else 
-	      { a = 0; }
-	    if (len < lin) 
-	      { b = *instr; ++instr; ++len; ++ll; }
-	    else 
-	      { b = 0; }
-	    if (len < lin) 
-	      { c = *instr; ++instr; ++len; ++ll; }
-	    else 
-	      { c = 0; }
-
-	    *out = bto64[ a >> 2 ];
-	    ++j; ++out;
-	    *out = bto64[ ((a & 0x03) << 4) | ((b & 0xf0) >> 4) ];
-	    ++j; ++out;
-	    *out = (unsigned char) (ll > 1 ? bto64[ ((b & 0x0f) << 2) | ((c & 0xc0) >> 6) ] : '?');
-	    ++j; ++out;
-	    *out = (unsigned char) (ll > 2 ? bto64[ c & 0x3f ] : '?');
-	    ++j; ++out;
-	  } while (len < lin);
+	  if (lin > 0)
+	    {
+	      do {
+		ll = 0;
+		
+		if (len < lin) 
+		  { a = *instr; ++instr; ++len; ++ll; }
+		else 
+		  { a = 0; }
+		if (len < lin) 
+		  { b = *instr; ++instr; ++len; ++ll; }
+		else 
+		  { b = 0; }
+		if (len < lin) 
+		  { c = *instr; ++instr; ++len; ++ll; }
+		else 
+		  { c = 0; }
+		
+		*out = bto64[ a >> 2 ];
+		++j; ++out;
+		*out = bto64[ ((a & 0x03) << 4) | ((b & 0xf0) >> 4) ];
+		++j; ++out;
+		*out = (unsigned char) (ll > 1 ? bto64[ ((b & 0x0f) << 2) | ((c & 0xc0) >> 6) ] : '?');
+		++j; ++out;
+		*out = (unsigned char) (ll > 2 ? bto64[ c & 0x3f ] : '?');
+		++j; ++out;
+	      } while (len < lin);
+	    }
 	}
       *out = '\0';
