Index: /trunk/Makefile.in
===================================================================
--- /trunk/Makefile.in	(revision 33)
+++ /trunk/Makefile.in	(revision 34)
@@ -1094,4 +1094,5 @@
 		$(srcsrc)/cutest_slib.c \
 		$(srcsrc)/cutest_zAVLTree.c \
+		$(srcsrc)/cutest_sh_hash.c \
 		$(srcsrc)/cutest_sh_tiger0.c
 
@@ -1101,4 +1102,5 @@
 	cutest_slib.o \
 	cutest_zAVLTree.o \
+	cutest_sh_hash.o \
 	cutest_sh_tiger0.o
 
Index: /trunk/docs/Changelog
===================================================================
--- /trunk/docs/Changelog	(revision 33)
+++ /trunk/docs/Changelog	(revision 34)
@@ -1,2 +1,5 @@
+	* Code cleanup
+	* fix manual version in spec file, noticed by Imre Gergely
+	
 2.2.0:
 	* patch by Jim Simmons for samhainadmin.pl.in
Index: /trunk/include/samhain.h
===================================================================
--- /trunk/include/samhain.h	(revision 33)
+++ /trunk/include/samhain.h	(revision 34)
@@ -302,14 +302,14 @@
  */
 int  safe_logger (int signal, int method, char * details);
-void safe_fatal  (int signal, int method, char * details, char *f, int l);
+void safe_fatal  (char * details, char *f, int l);
 
 #define SH_VALIDATE_EQ(a,b) \
      do { \
-         if ((a) != (b)) safe_fatal(0, 0, #a " != " #b, FIL__, __LINE__);\
+         if ((a) != (b)) safe_fatal(#a " != " #b, FIL__, __LINE__);\
      } while (0)
 
 #define SH_VALIDATE_NE(a,b) \
      do { \
-         if ((a) == (b)) safe_fatal(0, 0, #a " == " #b, FIL__, __LINE__);\
+         if ((a) == (b)) safe_fatal(#a " == " #b, FIL__, __LINE__);\
      } while (0)
 
Index: /trunk/include/sh_utils.h
===================================================================
--- /trunk/include/sh_utils.h	(revision 33)
+++ /trunk/include/sh_utils.h	(revision 34)
@@ -144,5 +144,5 @@
 /* returns freshly allocated memory, return value should be free'd
  */
-char * sh_util_filename(char * fullpath);
+char * sh_util_dirname(const char * fullpath);
 
 /* returns freshly allocated memory, return value should be free'd
@@ -160,5 +160,5 @@
 /* returns freshly allocated memory, return value should be free'd
  */
-char * sh_util_basename(char * fullpath);
+char * sh_util_basename(const char * fullpath);
 
 #endif
Index: /trunk/include/slib.h
===================================================================
--- /trunk/include/slib.h	(revision 33)
+++ /trunk/include/slib.h	(revision 34)
@@ -401,4 +401,8 @@
   int sl_ok_subi (int a, int b);
 
+  int sl_ok_muls (size_t a, size_t b);
+  int sl_ok_adds (size_t a, size_t b);
+
+
 #ifdef  __cplusplus
 }
Index: /trunk/samhain.spec.in
===================================================================
--- /trunk/samhain.spec.in	(revision 33)
+++ /trunk/samhain.spec.in	(revision 34)
@@ -179,5 +179,5 @@
 %dir @mylogdir@
 %doc docs/BUGS COPYING docs/Changelog docs/TODO
-%doc LICENSE docs/FAQ.html docs/HOWTO* docs/MANUAL-2_0.* docs/README*
+%doc LICENSE docs/FAQ.html docs/HOWTO* docs/MANUAL-2_2.* docs/README*
 @mydataroot@
 %if "%{withstg_prg}" == "xsamhain_stealth"
@@ -196,4 +196,7 @@
 
 %changelog
+* Tue May 16 2006 Rainer Wichmann
+- fix manual version, noticed by Imre Gergely
+
 * Tue Apr 05 2005 Rainer Wichmann
 - disable automatic stripping, use sstrip
Index: /trunk/scripts/redhat_i386.client.spec.in
===================================================================
--- /trunk/scripts/redhat_i386.client.spec.in	(revision 33)
+++ /trunk/scripts/redhat_i386.client.spec.in	(revision 34)
@@ -136,5 +136,5 @@
 %dir /var/log
 #%doc docs/BUGS COPYING docs/Changelog docs/TODO
-#%doc LICENSE docs/HOWTO* docs/MANUAL-2_0.* docs/README*
+#%doc LICENSE docs/HOWTO* docs/MANUAL-2_2.* docs/README*
 /etc
 /usr/local/sbin/samhain
Index: /trunk/scripts/samhain.spec.in
===================================================================
--- /trunk/scripts/samhain.spec.in	(revision 33)
+++ /trunk/scripts/samhain.spec.in	(revision 34)
@@ -122,5 +122,5 @@
 %dir %{_localstatedir}/log
 %doc docs/BUGS COPYING docs/Changelog docs/TODO
-%doc LICENSE docs/HOWTO* docs/MANUAL-2_0.* docs/README*
+%doc LICENSE docs/HOWTO* docs/MANUAL-2_2.* docs/README*
 %{_localstatedir}/lib/%{name}
 %{_sbindir}/%{name}
Index: /trunk/src/cutest_sh_utils.c
===================================================================
--- /trunk/src/cutest_sh_utils.c	(revision 33)
+++ /trunk/src/cutest_sh_utils.c	(revision 34)
@@ -6,4 +6,107 @@
 #include "samhain.h"
 #include "sh_utils.h"
+
+void Test_sh_util_strdup_ok (CuTest *tc) {
+  char * ret = 0;
+  char   inp[] = "foobar";
+
+  ret = sh_util_strdup(inp);
+  CuAssertPtrNotNull(tc, ret);
+  CuAssert(tc, "expected inp != ret, but inp == ret", (inp != ret)); 
+  CuAssertStrEquals(tc, "foobar", ret);
+  return;
+}
+
+void Test_sh_util_strconcat_ok (CuTest *tc) {
+  char * ret = 0;
+
+  ret = sh_util_strconcat("foo", NULL);
+  CuAssertPtrNotNull(tc, ret);
+  CuAssertStrEquals(tc, "foo", ret);
+
+  ret = sh_util_strconcat("foo", "bar", NULL);
+  CuAssertPtrNotNull(tc, ret);
+  CuAssertStrEquals(tc, "foobar", ret);
+
+  ret = sh_util_strconcat("/", "foo", "/", "bar", NULL);
+  CuAssertPtrNotNull(tc, ret);
+  CuAssertStrEquals(tc, "/foo/bar", ret);
+
+  return;
+}
+
+void Test_sh_util_dirname_ok (CuTest *tc) {
+  char * ret = 0;
+
+  char input0[] = "/foo/bar";
+  char res0[] = "/foo";
+
+  char input1[] = "/foo/bar/";
+  char res1[] = "/foo";
+
+  char input2[] = "/foo";
+  char res2[] = "/";
+
+  char input3[] = "/";
+  char res3[] = "/";
+
+  ret = sh_util_dirname(input0);
+  CuAssertPtrNotNull(tc, ret);
+  CuAssertStrEquals(tc, res0, ret);
+
+  ret = sh_util_dirname(input1);
+  CuAssertPtrNotNull(tc, ret);
+  CuAssertStrEquals(tc, res1, ret);
+
+  ret = sh_util_dirname(input2);
+  CuAssertPtrNotNull(tc, ret);
+  CuAssertStrEquals(tc, res2, ret);
+
+  ret = sh_util_dirname(input3);
+  CuAssertPtrNotNull(tc, ret);
+  CuAssertStrEquals(tc, res3, ret);
+  return;
+}
+
+void Test_sh_util_basename_ok (CuTest *tc) {
+  char * ret = 0;
+
+  char input0[] = "/foo/bar";
+  char res0[] = "bar";
+
+  char input1[] = "/foo/";
+  char res1[] = "foo";
+
+  char input2[] = "/foo";
+  char res2[] = "foo";
+
+  char input3[] = "/";
+  char res3[] = "/";
+
+  char input4[] = "/foo/bar/";
+  char res4[] = "bar";
+
+  ret = sh_util_basename(input0);
+  CuAssertPtrNotNull(tc, ret);
+  CuAssertStrEquals(tc, res0, ret);
+
+  ret = sh_util_basename(input1);
+  CuAssertPtrNotNull(tc, ret);
+  CuAssertStrEquals(tc, res1, ret);
+
+  ret = sh_util_basename(input2);
+  CuAssertPtrNotNull(tc, ret);
+  CuAssertStrEquals(tc, res2, ret);
+
+  ret = sh_util_basename(input3);
+  CuAssertPtrNotNull(tc, ret);
+  CuAssertStrEquals(tc, res3, ret);
+
+  ret = sh_util_basename(input4);
+  CuAssertPtrNotNull(tc, ret);
+  CuAssertStrEquals(tc, res4, ret);
+
+  return;
+}
 
 void Test_sh_util_obscure_ok (CuTest *tc) {
Index: /trunk/src/samhain.c
===================================================================
--- /trunk/src/samhain.c	(revision 33)
+++ /trunk/src/samhain.c	(revision 34)
@@ -817,5 +817,5 @@
   if (!fp)
     { if (errno != ENOENT) perror(_("fopen")); return 0; }
-  if (NULL == fgets(line, 255, fp))
+  if (NULL == fgets(line, sizeof(line), fp))
     { perror(_("fgets")); (void) fclose(fp); return 0; }
   (void) fclose(fp); 
@@ -1114,5 +1114,5 @@
 
 #if defined (SH_STEALTH_NOCL)
-  char  * command_line;
+  char    command_line[256];
   int     my_argc = 0;
   char  * my_argv[32];
@@ -1280,11 +1280,10 @@
       strlen(argv[1]) > 0 && strlen(NOCL_CODE) > 0)
     {
-      if ( 0 == strcmp(argv[1], NOCL_CODE) &&
-	   NULL != (command_line = (char *) SH_ALLOC(256 * sizeof(char))))
+      if ( 0 == strcmp(argv[1], NOCL_CODE) )
 	{
 	  my_argv[0] = argv[0]; ++my_argc;  
 	  command_line[0] = '\0';
-	  (void*) fgets (command_line, 255, stdin);
-	  command_line[255] = '\0';
+	  (void*) fgets (command_line, sizeof(command_line), stdin);
+	  command_line[sizeof(command_line)-1] = '\0';
 	  do {
 	    my_argv[my_argc] = 
@@ -1301,5 +1300,4 @@
 
 	  (void) sh_getopt_get (my_argc, my_argv);
-	  SH_FREE (command_line);
 	}
       else
Index: /trunk/src/samhain_stealth.c
===================================================================
--- /trunk/src/samhain_stealth.c	(revision 33)
+++ /trunk/src/samhain_stealth.c	(revision 34)
@@ -390,5 +390,5 @@
 
       fprintf(stdout, _(" .. hide %s in %s .. \n"), argv[3], argv[2]);
-      while (fgets(buf, 1023, infil))
+      while (fgets(buf, sizeof(buf), infil))
 	{
 	  lseek(fd, off_data, SEEK_SET);
Index: /trunk/src/sh_err_log.c
===================================================================
--- /trunk/src/sh_err_log.c	(revision 33)
+++ /trunk/src/sh_err_log.c	(revision 34)
@@ -390,5 +390,5 @@
 		  (void) fflush(stdout); 
 		  key[0] = '\0';
-		  (void) fgets(key, KEY_LEN+2, stdin);
+		  (void) fgets(key, sizeof(key), stdin);
 		  if (key[0] != '\n') 
 		    {
@@ -553,5 +553,7 @@
         {
 	  tmp  = sh_util_safe_name (logfile);
-	  len      = 6 + sl_strlen(tmp);
+	  len      = sl_strlen(tmp);
+	  if (sl_ok_adds (6, len))
+	    len += 6;
 	  lockfile = SH_ALLOC(len);
 	  (void) sl_strlcpy(lockfile,        tmp, len);
@@ -634,5 +636,5 @@
 
   SL_TICKET            fd = -1;
-  long int             status;
+  size_t               status;
   struct _sh_log_buf   log_msg;
 
@@ -749,5 +751,10 @@
    */
 
-  status      = (long) sl_strlen (errmsg);
+  status      =  sl_strlen (errmsg);
+  if (!sl_ok_adds(status, (2*KEY_LEN)) || !sl_ok_adds((2*KEY_LEN + status),32))
+    {
+      SL_RETURN ((-1), _("sh_log_file"));
+    }
+      
   log_msg.msg = (char *) SH_ALLOC ((size_t) (2*KEY_LEN + status + 32)); 
 
Index: /trunk/src/sh_error.c
===================================================================
--- /trunk/src/sh_error.c	(revision 33)
+++ /trunk/src/sh_error.c	(revision 34)
@@ -1144,5 +1144,8 @@
 	       */
               export_block = 1;
-	      ex_len = 64 + sl_strlen(lmsg->msg) + 1;
+	      /* ex_len = 64 + sl_strlen(lmsg->msg) + 1; */
+	      ex_len = sl_strlen(lmsg->msg);
+	      if (sl_ok_adds(ex_len, 65))
+		ex_len = 64 + ex_len + 1;
 	      ex_msg = SH_ALLOC (ex_len);
 
@@ -1497,5 +1500,8 @@
       /*@i@*/required = sl_vsnprintf(&(lmsg->msg[len]), 
 				     (lmsg->msg_len - len), lmsg->format, vl);
-      if ( (required + len) > (lmsg->msg_len - 4) )
+      if ((required >= 0) && 
+	  sl_ok_adds(required, len) &&
+	  sl_ok_adds((required+len), 4) &&
+	  ((required + len) > (lmsg->msg_len - 4)) )
 	{
 	  /*@i@*/p = SH_ALLOC(required + len + 4);
Index: /trunk/src/sh_extern.c
===================================================================
--- /trunk/src/sh_extern.c	(revision 33)
+++ /trunk/src/sh_extern.c	(revision 34)
@@ -664,4 +664,8 @@
     sv = strlen(val) + 1;
 
+  if (!sl_ok_adds(sk, sv))
+    {
+      SL_RETURN (-1, _("sh_ext_tas_add_envv"));
+    }
   si = tas->envc;
   tas->envv[si] = SH_ALLOC(sk + sv);
@@ -845,4 +849,6 @@
 int sh_ext_add_envv(const char * key, const char * val)
 {
+  int retval; 
+
   SL_ENTER(_("sh_ext_add_envv"));
 
@@ -854,7 +860,10 @@
     }
 
-  (void) sh_ext_tas_add_envv(&(ext_coms->tas), key, val);
-
-  SL_RETURN (0, _("sh_ext_add_envv"));
+  retval = sh_ext_tas_add_envv(&(ext_coms->tas), key, val);
+
+  if (retval >= 0) 
+    retval = 0;
+
+  SL_RETURN (retval, _("sh_ext_add_envv"));
 }
 
Index: /trunk/src/sh_files.c
===================================================================
--- /trunk/src/sh_files.c	(revision 33)
+++ /trunk/src/sh_files.c	(revision 34)
@@ -200,5 +200,5 @@
 
   dirstack_t * ptr;
-  char       * base;
+  char       * dir;
   char       * file;
   
@@ -215,6 +215,6 @@
       if (ptr->checked == S_FALSE)
 	{
-	  base = sh_util_basename (ptr->name);
-	  file = sh_util_filename (ptr->name);
+	  dir  = sh_util_dirname (ptr->name);
+	  file = sh_util_basename (ptr->name);
 #if defined(WITH_TPT)
 	  tmp = sh_util_safe_name (ptr->name);
@@ -231,5 +231,5 @@
 
 	  BREAKEXIT(sh_files_filecheck);
-	  status = sh_files_filecheck (ptr->class, base, file, 
+	  status = sh_files_filecheck (ptr->class, dir, file, 
 				       (int *) &(ptr->reported), 0);
 	  
@@ -348,5 +348,5 @@
 	    }
 	  SH_FREE(file);
-	  SH_FREE(base);
+	  SH_FREE(dir);
 
 	  ptr->checked = S_TRUE;
@@ -729,5 +729,5 @@
 #endif
 
-int sh_files_push_file_int (int class, const char * str_s, int len)
+int sh_files_push_file_int (int class, const char * str_s, size_t len)
 {
   dirstack_t * new_item_ptr;
@@ -777,5 +777,5 @@
 static int sh_files_pushfile (int class, const char * str_s)
 {
-  int     len;
+  size_t  len;
   char  * tmp;
   char  * p;
@@ -1132,5 +1132,5 @@
 }
 
-int sh_files_push_dir_int (int class, char * tail, int len, int rdepth)
+int sh_files_push_dir_int (int class, char * tail, size_t len, int rdepth)
 {
   zAVLTree   * tree;
@@ -1194,5 +1194,5 @@
 {
   char  * tmp;
-  int     len;
+  size_t  len;
   int     rdepth = 0;
   char  * tail = NULL;
@@ -1326,5 +1326,5 @@
   SH_FREE(p);
   SL_RETURN((0), _("sh_files_pushdir"));
-}  
+}
 
 struct sh_dirent {
@@ -1354,13 +1354,13 @@
 {
   struct sh_dirent * this;
-  int i;
+  size_t len;
 
   if (thisEntry == NULL)
     return dirlist;
   
-  i = sl_strlen(thisEntry->d_name);
-  if (i == 0)
+  len = sl_strlen(thisEntry->d_name);
+  if (len == 0)
     return dirlist;
-  ++i;
+  ++len;
   
   this = SH_ALLOC(sizeof(struct sh_dirent));
@@ -1368,6 +1368,6 @@
     return dirlist;
 
-  this->sh_d_name = SH_ALLOC(i);
-  sl_strlcpy(this->sh_d_name, thisEntry->d_name, i);
+  this->sh_d_name = SH_ALLOC(len);
+  sl_strlcpy(this->sh_d_name, thisEntry->d_name, len);
 
   this->next = dirlist;
@@ -1492,5 +1492,7 @@
 
   int             hardlink_num = 0;
-
+#if !defined(HOST_IS_DARWIN)
+  size_t          len;
+#endif
 
   SL_ENTER(_("sh_files_checkdir"));
@@ -1866,6 +1868,9 @@
       if (0 != sh_files_hle_test(hardlink_num-theDir.NumDirs, iname))
 	{
-	  tmpcat = SH_ALLOC(strlen(tmpname) + 256);
-	  sl_snprintf(tmpcat, strlen(tmpname) + 256, 
+	  len = strlen(tmpname);
+	  if (sl_ok_adds(len, 256)) 
+	    len += 256;
+	  tmpcat = SH_ALLOC(len);
+	  sl_snprintf(tmpcat, len, 
 		      _("%s: subdirectory count (%d) != hardlinks (%d)"),
 		      tmpname, theDir.NumDirs, hardlink_num);
@@ -1886,5 +1891,5 @@
 
 static ShFileType sh_files_filecheck (int class, char * dirName, 
-				      char * fileName,
+				      char * infileName,
 				      int * reported, 
 				      int rsrcflag)
@@ -1898,4 +1903,5 @@
   char          * tmpdir;
   char          * tmpname;
+  char          * fileName;
   struct utimbuf  utime_buf;
 
@@ -1905,4 +1911,14 @@
   if (0 == (rand() % 2))
     (void) sh_derr();
+
+  if (dirName && infileName && (dirName[0] == '/') && (dirName[1] == '\0')
+      && (infileName[0] == '/') && (infileName[1] == '\0'))
+    {
+      fileName = NULL;
+    }
+  else
+    {
+      fileName = infileName;
+    }
 
   /* fileName may be NULL if this is a directory
Index: /trunk/src/sh_forward.c
===================================================================
--- /trunk/src/sh_forward.c	(revision 33)
+++ /trunk/src/sh_forward.c	(revision 34)
@@ -139,5 +139,5 @@
 #include "rijndael-api-fst.h"
 char * sh_tools_makePack (unsigned char * header, 
-			  char * payload, int payload_size,
+			  char * payload, unsigned long payload_size,
 			  keyInstance * keyInstE);
 char * sh_tools_revertPack (unsigned char * header, char * message,
@@ -305,6 +305,8 @@
     }
 
-  len = sl_strlen(salt) + sl_strlen(skey->vernam) + 1;
-  if (nounce != NULL) 
+  len = sl_strlen(salt) + 1;
+  if (sl_ok_adds(len, sl_strlen(skey->vernam)))
+    len += sl_strlen(skey->vernam);
+  if (nounce != NULL && sl_ok_adds(len, sl_strlen(nounce))) 
     len += sl_strlen(nounce);
   
@@ -394,5 +396,5 @@
     {
       put_header (head, (int)protocol, &length, micro);
-      msg2buf  = sh_tools_makePack (head, msgbuf, (int) length, 
+      msg2buf  = sh_tools_makePack (head, msgbuf, length, 
 				    &(skey->keyInstE));
       /*@-usedef@*/
@@ -406,5 +408,9 @@
       blkfac  = length/B_SIZ;
       rem     = (int) (length - (B_SIZ * blkfac));
-      length2 = (B_SIZ * blkfac) + ((rem == 0) ? 0 : B_SIZ);
+      length2 = (B_SIZ * blkfac);
+      if ((rem > 0) && (length2+B_SIZ) > length2) 
+	length2 += B_SIZ;
+      else
+	rem = 0;
 
       msg2buf = SH_ALLOC((size_t)length2);
@@ -549,4 +555,10 @@
   SL_ENTER(_("sh_forward_receive_intern"));
 
+#ifdef SH_ENCRYPT
+  /* make sure length is not multiple of B_SIZ, see below 
+   */
+  ASSERT_RET((length % B_SIZ != 0), _("length % 16 != 0"), flag_err);
+#endif
+
   if (micro != NULL)
     micro[4]     = '\0';
@@ -608,6 +620,14 @@
       head_length = (unsigned long) (256 * (unsigned int)head[1] + 
 				     (unsigned int)head[2]);
-      head_length = (head_length > length ? length : head_length);
-      length      = head_length;
+
+      /* 
+       * revertPack returns header with length <= (original_length-16), so
+       * the following msgbuf[length] = '\0' is always safe.
+       * Nevertheless, check for proper length.
+       */
+      if (head_length <= (length-1))
+	length      = head_length;
+      else
+	--length;
 
       memcpy(msgbuf, tmp, (size_t)length);
@@ -627,5 +647,5 @@
        */
       blkfac  = countbytes/B_SIZ;
-      /* length2 = (B_SIZ * blkfac); */
+
       p       = msgbuf;
       q       = msgbuf;
@@ -638,4 +658,7 @@
 			_("sh_forward_receive_intern: cipherInit"));
 
+      /* here we want to have (length % B_SIZ != 0), such that the
+       * terminating '\0' cannot be overwritten
+       */
       for (j = 0; j < blkfac; ++j)
 	{
@@ -648,6 +671,6 @@
 			    _("sh_forward_receive_intern: blockDecrypt"));
 	  memcpy(q, outBlock, B_SIZ);
-	  p += 16;
-	  q += 16;
+	  p += B_SIZ;
+	  q += B_SIZ;
 	}
     }
@@ -1047,5 +1070,5 @@
 	  timeout_val *= 2;
 	  sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOAUTH);
-	  memset(answer, 0, sizeof(answer));
+	  memset(answer, 0, 512);
 	  MUNLOCK(answer, 512);
 	  SH_FREE(answer);
@@ -1238,5 +1261,5 @@
 	  timeout_val *= 2;
 	  sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOAUTH);
-	  memset(answer, '\0', sizeof(answer));
+	  memset(answer, '\0', 512);
 	  MUNLOCK(answer, 512);
 	  SH_FREE(answer);
@@ -1257,5 +1280,5 @@
     {
       timeout_val = 1;
-      memset(answer, 0, sizeof(answer));
+      memset(answer, 0, 512);
       MUNLOCK(answer, 512);
       SH_FREE(answer);
@@ -1626,5 +1649,5 @@
 					    head_u, 
 					    answer, 
-					    TRANS_BYTES + 256);
+					    TRANS_BYTES + 255);
 
 		TPT(( 0, FIL__, __LINE__, 
@@ -2004,5 +2027,5 @@
     }
   
-  if (sepnum == 2 && sep[0] > 0)
+  if ((sepnum == 2) && (sep[0] > 0) && (sep[1] > sep[0]))
     {
       newclt = SH_ALLOC (sizeof(client_t));
@@ -2222,5 +2245,5 @@
 			       int docrypt)
 {
-  register unsigned long i;
+  /* register unsigned long i; */
   unsigned long           length2;
 
@@ -2251,5 +2274,9 @@
       blkfac  = length/B_SIZ;
       rem     = length - (B_SIZ * blkfac);
-      length2 = (B_SIZ * blkfac) + ((rem == 0) ? 0 : B_SIZ);
+      length2 = (B_SIZ * blkfac);
+      if (rem > 0 && (length2 + B_SIZ) > length2) 
+	length2 += B_SIZ;
+      else
+	rem = 0;
     }
   else
@@ -2289,5 +2316,6 @@
 				     &(conn->client_entry->keyInstE));
     }
-  else if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_ENC) != 0))
+  else if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_ENC) != 0) &&
+	   ((length2 + 1) > length2))
     {
       conn->buf       = SH_ALLOC(length2 + 1);
@@ -2337,16 +2365,24 @@
   else
     {
+      if ((length2 + 1) < length2) --length2;
       conn->buf       = SH_ALLOC(length2 + 1);
 
+      memcpy(conn->buf, msg, length2);
+      /*
       for (i = 0; i < length2; ++i) 
 	conn->buf[i] = msg[i];
+      */
       conn->buf[length2] = '\0';
       TPT((0, FIL__, __LINE__, _("msg=<no encryption done>\n") ));
     }
 #else
+  if ((length2 + 1) < length2) --length2;
   conn->buf       = SH_ALLOC(length2 + 1);
 
+  memcpy(conn->buf, msg, length2);
+  /*
   for (i = 0; i < length; ++i) 
     conn->buf[i] = msg[i];
+  */
   conn->buf[length2] = '\0';
   TPT((0, FIL__, __LINE__, _("msg=<no encryption done>\n") ));
@@ -2856,6 +2892,12 @@
 		  conn->K = NULL;
 		}
-	      len = sl_strlen(&(conn->buf[KEY_LEN])) + KEY_LEN + 1;
-	      conn->K = SH_ALLOC(len);
+
+	      /* FIXME
+	      len = sl_strlen(&(conn->buf[KEY_LEN])) + 1;
+	      if (sl_ok_adds(len, KEY_LEN))
+		len += KEY_LEN;
+	      len = (len < (KEY_LEN+1)) ? (KEY_LEN+1) : len;
+	      */
+	      conn->K = SH_ALLOC(KEY_LEN+1);
 
 	      sl_strlcpy (conn->K, 
@@ -3316,6 +3358,6 @@
 		  conn->K = NULL;
 		}
-	      len = sl_strlen(&(conn->buf[KEY_LEN])) + KEY_LEN + 1;
-	      conn->K = SH_ALLOC(len);
+	      /* FIXME len = sl_strlen(&(conn->buf[KEY_LEN])) + KEY_LEN + 1; */
+	      conn->K = SH_ALLOC(KEY_LEN + 1);
 
 	      sl_strlcpy (conn->K, 
@@ -4327,5 +4369,5 @@
 	  if (conn->buf != NULL)
 	    SH_FREE (conn->buf);
-	  conn->buf       = SH_ALLOC (conn->bytes_to_get + 1);
+	  conn->buf = SH_ALLOC(conn->bytes_to_get + 1); /* <= TRANS_BYTES+1 */
 	  conn->bytecount = 0;
 	}
@@ -4863,4 +4905,10 @@
   maxconn = (((int)FD_SETSIZE) < maxconn) ? FD_SETSIZE : maxconn;
 
+  if (maxconn < 0 || !sl_ok_muls(maxconn, sizeof(sh_conn_t)))
+    {
+      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_START_SRV,
+		      0, sock);
+      aud_exit (FIL__, __LINE__, EXIT_FAILURE);
+    }
   conns   = SH_ALLOC (sizeof(sh_conn_t) * maxconn);
 
Index: /trunk/src/sh_gpg.c
===================================================================
--- /trunk/src/sh_gpg.c	(revision 33)
+++ /trunk/src/sh_gpg.c	(revision 34)
@@ -690,5 +690,5 @@
   errno = 0;
 
-  while (NULL != fgets(line, 255, source.pipe))
+  while (NULL != fgets(line, sizeof(line), source.pipe))
     {
 
@@ -805,5 +805,5 @@
   errno = 0;
 
-  while (NULL != fgets(line, 255, source.pipe))
+  while (NULL != fgets(line, sizeof(line), source.pipe))
     {
       if (line[strlen(line)-1] == '\n')
Index: /trunk/src/sh_hash.c
===================================================================
--- /trunk/src/sh_hash.c	(revision 33)
+++ /trunk/src/sh_hash.c	(revision 34)
@@ -69,8 +69,9 @@
 #define QUOTE_CHAR '='
 
-static char * unquote_string (char * str)
-{
-  int    i = 0, j, k = 0, len, t1, t2, l2;
+char * unquote_string (const char * str)
+{
+  int    i = 0, t1, t2;
   char * tmp = NULL;
+  size_t len, l2, j, k = 0;
 
   SL_ENTER(_("unquote_string"));
@@ -115,26 +116,18 @@
 char * int2hex (unsigned char i)
 {
-  int j, k;
-
-  j = i / 16;
-  k = i - (j*16);
-  if (j < 10) 
-    i2h[0] = '0'+j;
-  else
-    i2h[0] = 'A'+(j-10);
-  
-  if (k < 10) 
-    i2h[1] = '0'+k;
-  else
-    i2h[1] = 'A'+(k-10);
+  static char hexchars[] = "0123456789ABCDEF";
+
+  i2h[0] = hexchars[(((i) & 0xF0) >> 4)]; /* high */
+  i2h[1] = hexchars[((i) & 0x0F)];        /* low  */
 
   return i2h;
 }
 
-static char * quote_string (char * str)
-{
-  int    i = 0, j, k = 0, len;
+
+char * quote_string (const char * str)
+{
   char * tmp;
   char * tmp2;
+  size_t len, l2, j, i = 0, k = 0;
 
   SL_ENTER(_("quote_string"));
@@ -150,5 +143,17 @@
     if (str[j] == '\n' || str[j] == QUOTE_CHAR) ++i;
 
-  tmp = SH_ALLOC(len + 1 + 3*i);
+  l2 = len + 1;
+  if (sl_ok_muls(3, i) && sl_ok_adds(l2, (3*i)))
+    {
+      tmp = SH_ALLOC(len + 1 + 3*i);
+    }
+  else
+    {
+      sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
+		      _("integer overflow"), 
+		      _("quote_string"));
+      SL_RETURN(NULL, _("quote_string"));
+    }
+
   for (j = 0; j <= len; ++j)
     {
@@ -492,5 +497,5 @@
       if (0 != i)
 	{
-	  ptr = sh_util_basename (p->fullpath);
+	  ptr = sh_util_dirname (p->fullpath);
 	  if (ptr)
 	    {
@@ -724,5 +729,5 @@
 
   if (sizeofline < 2) {
-    line[0] = '\0';
+    if (sizeofline > 0) line[0] = '\0';
     return 0;
   }
@@ -736,5 +741,5 @@
   if (n > 1) {
     --n;
-    line[n] = '\0';
+    line[n] = '\0'; /* remove terminating '\n' */
   }
   return n;
@@ -791,5 +796,5 @@
   while (1) 
     {
-      i =  sh_hash_getline (sh_fin_fd, line, size-1);
+      i =  sh_hash_getline (sh_fin_fd, line, size);
       if (i < 0 ) 
 	{
@@ -860,4 +865,5 @@
   sh_filestore_t ft;
   long i;
+  size_t len;
   char * fullpath;
   char * linkpath;
@@ -910,5 +916,5 @@
   /* Read next record -- Part Two -- Fullpath
    */
-  i =  sh_hash_getline (sh_fin_fd, line, size-1);
+  i =  sh_hash_getline (sh_fin_fd, line, size);
   if (i < 0 ) 
     {
@@ -926,15 +932,15 @@
 
   tmp = unquote_string (line);
-  i = sl_strlen(tmp)+1;
-  fullpath = SH_ALLOC(i);
-  sl_strlcpy (fullpath, tmp, i);
+  len = sl_strlen(tmp)+1;
+  fullpath = SH_ALLOC(len);
+  (void) sl_strlcpy (fullpath, tmp, len);
   if (tmp)
     SH_FREE(tmp);
-  if (fullpath[i-2] == '\n')
-    fullpath[i-2] = '\0';
+  if (fullpath[len-2] == '\n')
+    fullpath[len-2] = '\0';
 
   /* Read next record -- Part Three -- Linkpath
    */
-  i =  sh_hash_getline (sh_fin_fd, line, size-1);
+  i =  sh_hash_getline (sh_fin_fd, line, size);
   if (i < 0 ) 
     {
@@ -953,11 +959,11 @@
 
   tmp = unquote_string (line);
-  i = sl_strlen(tmp)+1;
-  linkpath = SH_ALLOC(i);
-  sl_strlcpy (linkpath, tmp, i);
+  len = sl_strlen(tmp)+1;
+  linkpath = SH_ALLOC(len);
+  (void) sl_strlcpy (linkpath, tmp, len);
   if (tmp)
     SH_FREE(tmp);
-  if (linkpath[i-2] == '\n')
-    linkpath[i-2] = '\0';
+  if (linkpath[len-2] == '\n')
+    linkpath[len-2] = '\0';
 
   /* Read next record -- Part Four -- Decode
@@ -1004,4 +1010,7 @@
 void sh_hash_init ()
 {
+
+#define FGETS_BUF 16384
+
   sh_file_t * p;
   SL_TICKET fd    = (-1);
@@ -1111,12 +1120,10 @@
 
   fin_cp = fdopen(get_the_fd(fd), "rb");
-  buf = (char *) SH_ALLOC(8192);
-
-
-  /* while ( (bufc = sh_unix_getline (fd, buf, 8191)) > 0) */
-  while (NULL != fgets(buf, 8192, fin_cp))
+  buf = SH_ALLOC(FGETS_BUF);
+
+  while (NULL != fgets(buf, FGETS_BUF, fin_cp))
     {
       bufc = 0; 
-      while (bufc < 8192) { 
+      while (bufc < FGETS_BUF) { 
 	if (buf[bufc] == '\n') { ++bufc; break; }
 	++bufc;
@@ -1273,8 +1280,6 @@
 int sh_hash_version_string(const char * str)
 {
-  int i;
   if (str)
     {
-      i = sl_strlen(str);
       if (sh_db_version_string != NULL) {
 	SH_FREE(sh_db_version_string);
@@ -1285,6 +1290,5 @@
 	  return 0;
 	}
-      sh_db_version_string = SH_ALLOC(i+1);
-      sl_strlcpy(sh_db_version_string, str, i+1);
+      sh_db_version_string = sh_util_strdup(str);
       return 0;
     }
@@ -1292,15 +1296,4 @@
 }
 
-#if 0
-void sh_hash_pushdata_reset ()
-{
-  if (!SL_ISERROR(pushdata_fd))
-    {
-      sl_close(pushdata_fd);
-      pushdata_fd = -1;
-    }
-  pushdata_isfirst =  1;
-}
-#endif
 
 void sh_hash_pushdata (file_type * buf, char * fileHash)
@@ -1457,5 +1450,5 @@
 #endif
 
-    if (tmp_len <= MAX_PATH_STORE) 
+    if (tmp && tmp_len <= MAX_PATH_STORE) 
       {
 	sl_strlcpy(fullpath, buf->fullpath, MAX_PATH_STORE+1);
@@ -1475,14 +1468,16 @@
 		   KEY_LEN+1);
       }
+    if (tmp) SH_FREE(tmp);
+  }
+
+#if defined(SH_STEALTH)
+  sh_do_encode(fullpath, sl_strlen(fullpath));
+#endif
+
+  tmp = quote_string(fullpath);
+  if (tmp) {
+    sl_strlcpy(fullpath, tmp, MAX_PATH_STORE+1);
     SH_FREE(tmp);
   }
-
-#if defined(SH_STEALTH)
-  sh_do_encode(fullpath, sl_strlen(fullpath));
-#endif
-
-  tmp = quote_string(fullpath);
-  sl_strlcpy(fullpath, tmp, MAX_PATH_STORE+1);
-  SH_FREE(tmp);
 
   if (buf != NULL && buf->c_mode[0] == 'l' && buf->linkpath != NULL) 
@@ -1499,5 +1494,5 @@
 #endif
 
-      if (tmp_len <= MAX_PATH_STORE) 
+      if (tmp && tmp_len <= MAX_PATH_STORE) 
 	{
 	  sl_strlcpy(linkpath, buf->linkpath, MAX_PATH_STORE+1);  
@@ -1510,5 +1505,5 @@
 		     KEY_LEN+1);
 	}
-      SH_FREE(tmp);
+      if (tmp) SH_FREE(tmp);
 
 #if defined(SH_STEALTH)
@@ -1516,6 +1511,9 @@
 #endif
       tmp = quote_string(linkpath);
-      sl_strlcpy(linkpath, tmp, MAX_PATH_STORE+1);
-      SH_FREE(tmp);
+      if (tmp)
+	{
+	  sl_strlcpy(linkpath, tmp, MAX_PATH_STORE+1);
+	  SH_FREE(tmp);
+	}
     }
 
@@ -1977,5 +1975,6 @@
   sh_file_t    * fp;
   sh_filestore_t p;
-  long i;
+
+  size_t len;
   char * fullpath;
   char * linkpath;
@@ -2014,9 +2013,9 @@
   fp->modi_mask = 0L;
 
-  i = sl_strlen(buf->fullpath);
-  if (i <= MAX_PATH_STORE) 
-    {
-      fullpath = SH_ALLOC(i+ 1);
-      sl_strlcpy(fullpath, buf->fullpath, i+1);
+  len = sl_strlen(buf->fullpath);
+  if (len <= MAX_PATH_STORE) 
+    {
+      fullpath = SH_ALLOC(len+1);
+      sl_strlcpy(fullpath, buf->fullpath, len+1);
     } 
   else 
@@ -2024,5 +2023,5 @@
       fullpath = SH_ALLOC(KEY_LEN + 1);
       sl_strlcpy(fullpath, 
-		 sh_tiger_hash (buf->fullpath, TIGER_DATA, i), 
+		 sh_tiger_hash (buf->fullpath, TIGER_DATA, len), 
 		 KEY_LEN+1);
     }
@@ -2031,9 +2030,9 @@
   if (buf->c_mode[0] == 'l')
     {  
-      i = sl_strlen(buf->linkpath);
-      if (i <= MAX_PATH_STORE) 
-	{
-	  linkpath = SH_ALLOC(i+ 1);
-	  sl_strlcpy(linkpath, buf->linkpath, i+1);
+      len = sl_strlen(buf->linkpath);
+      if (len <= MAX_PATH_STORE) 
+	{
+	  linkpath = SH_ALLOC(len+1);
+	  sl_strlcpy(linkpath, buf->linkpath, len+1);
 	} 
       else 
@@ -2041,5 +2040,5 @@
 	  linkpath = SH_ALLOC(KEY_LEN + 1);
 	  sl_strlcpy(linkpath, 
-		     sh_tiger_hash (buf->linkpath, TIGER_DATA, i), 
+		     sh_tiger_hash (buf->linkpath, TIGER_DATA, len), 
 		     KEY_LEN+1);
 	}
@@ -2942,7 +2941,5 @@
 	      if (p->linkpath != NULL)
 		SH_FREE(p->linkpath);
-	      p->linkpath = (char*)SH_ALLOC (sl_strlen(theFile->linkpath) + 1);
-	      sl_strlcpy(p->linkpath, theFile->linkpath, 
-			 sl_strlen(theFile->linkpath) + 1);
+	      p->linkpath = sh_util_strdup(theFile->linkpath);
 	    }
 #endif
@@ -3026,7 +3023,5 @@
                   if (p->linkpath != NULL)
 		    SH_FREE(p->linkpath);
-		  p->linkpath = SH_ALLOC(1 + strlen(theFile->linkpath));
-		  sl_strlcpy(p->linkpath, theFile->linkpath, 
-			     1 + strlen(theFile->linkpath));
+		  p->linkpath = sh_util_strdup(theFile->linkpath);
 		}
 	      else
Index: /trunk/src/sh_html.c
===================================================================
--- /trunk/src/sh_html.c	(revision 33)
+++ /trunk/src/sh_html.c	(revision 34)
@@ -108,5 +108,5 @@
   if (!SL_ISERROR(fd))
     {
-      while (!SL_ISERROR(status) && sh_unix_getline (fd, line, 511) > 0) 
+      while (!SL_ISERROR(status) && sh_unix_getline (fd, line, sizeof(line)) > 0) 
 	{
 	  formatted = replace_stat (line);
@@ -121,5 +121,5 @@
   else
     {
-      qstr = sh_util_filename(DEFAULT_HTML_FILE);
+      qstr = sh_util_basename(DEFAULT_HTML_FILE);
       if (qstr != NULL)
 	{
@@ -217,5 +217,5 @@
   if (!SL_ISERROR(fd))
     {
-      while (!SL_ISERROR(status) && sh_unix_getline (fd, line, 511) > 0) 
+      while (!SL_ISERROR(status) && sh_unix_getline (fd, line, sizeof(line)) > 0) 
 	{
 	  status = sl_write_line (ticket, line, sl_strlen(line));
@@ -289,5 +289,5 @@
   if (!SL_ISERROR(fd))
     {
-      while (!SL_ISERROR(retval) && sh_unix_getline (fd, line, 511) > 0) 
+      while (!SL_ISERROR(retval) && sh_unix_getline (fd, line, sizeof(line)) > 0) 
 	{
 	  line_size = sl_strlen(line);
Index: /trunk/src/sh_kern.c
===================================================================
--- /trunk/src/sh_kern.c	(revision 33)
+++ /trunk/src/sh_kern.c	(revision 34)
@@ -257,5 +257,5 @@
 }
 
-extern int sh_util_hextobinary (char * binary, char * hex, int bytes);
+extern int sh_util_hextobinary (char * binary, const char * hex, int bytes);
 
 static char * sh_kern_db2pop (char * name, unsigned long * addr, 
Index: /trunk/src/sh_mail.c
===================================================================
--- /trunk/src/sh_mail.c	(revision 33)
+++ /trunk/src/sh_mail.c	(revision 34)
@@ -173,8 +173,8 @@
       /* get signature and number 
        */
-      (void) sh_unix_getline (fd, key, (int)(  sizeof(key)-1));
+      (void) sh_unix_getline (fd, key, (int)sizeof(key));
       key[KEY_LEN] = '\0';
 
-      (void) sh_unix_getline (fd, number, (int)(sizeof(number)-1));
+      (void) sh_unix_getline (fd, number, (int)sizeof(number));
       number[(2*SH_MINIBUF) - 2]   = '\0';
       numsig = atol (number);
@@ -742,18 +742,28 @@
 static char * sh_mail_realloc (char * inbuf, size_t * insize, size_t increase)
 {
-  size_t newsize = (*insize) + increase + 1;
-  char * outbuf;
+  size_t newsize;
+  char * outbuf = inbuf;
 
   SL_ENTER(_("sh_mail_realloc"));
 
-  outbuf = SH_ALLOC(newsize);
-  MLOCK(outbuf, newsize);
-  (void) sl_strlcpy(outbuf, inbuf, newsize);
-
-  memset (inbuf, 0, (*insize));
-  MUNLOCK(inbuf, (*insize));
-  SH_FREE(inbuf);
-
-  *insize = newsize;
+  if (sl_ok_adds((*insize), 1))
+    {
+      newsize = (*insize) + 1;
+
+      if (sl_ok_adds(newsize, increase))
+	{
+	  newsize += increase;
+
+	  outbuf = SH_ALLOC(newsize);
+	  MLOCK(outbuf, newsize);
+	  (void) sl_strlcpy(outbuf, inbuf, newsize);
+
+	  memset (inbuf, 0, (*insize));
+	  MUNLOCK(inbuf, (*insize));
+	  SH_FREE(inbuf);
+
+	  *insize = newsize;
+	}
+    }
 
   SL_RETURN( (outbuf), _("sh_mail_realloc"));
@@ -1227,6 +1237,4 @@
 int sh_mail_set_relay (const char * str_s)
 {
-  size_t i = 0;
-
   SL_ENTER(_("sh_mail_set_relay"));
 
@@ -1235,18 +1243,16 @@
 
   if (relay_host != NULL)
-    SH_FREE (relay_host);
+    {
+      SH_FREE (relay_host);
+      relay_host = NULL;
+    }
 
   if (0 == sl_strncmp(str_s, _("NULL"), 4))
     {
-      relay_host = NULL;
       SL_RETURN( 0, _("sh_mail_set_relay"));
     }
 
-  i = sl_strlen(str_s) + 1;
-  relay_host = SH_ALLOC (i);
-  if (relay_host != NULL)
-    (void) sl_strlcpy(relay_host, str_s, i);
-  else
-    fprintf(stderr, _("ERROR:  sh_mail_set_relay: Out of memory"));
+  relay_host = sh_util_strdup(str_s);
+
   SL_RETURN( 0, _("sh_mail_set_relay"));
 }
@@ -1802,12 +1808,21 @@
     return NULL;
 
-  size   = strlen(str);
-  /* fprintf(stderr, "orig = %d\n", size); */
+  size   = strlen(str) + 1;
   blocks = 1 + (size / SPLIT_AT);
   
-  size   = size + (2*blocks) + 1;
+  if (sl_ok_muls(2, blocks) && sl_ok_adds(size, (2*blocks)))
+    {
+      size   = size + (2*blocks);
+    }
+  else
+    {
+      /* integer overflow, do not split */
+      p = sh_util_strdup(str);
+      return p;
+    }
+
   p = SH_ALLOC(size);
   memset(p, 0, size);
-  /* fprintf(stderr, "alloc = %d\n", size); */
+
   p0 = p;
 
@@ -1897,5 +1912,6 @@
   unsigned char * comp_dn, * eom;
   HEADER * header;
-  int      count, index, type, rdlength, pref;
+  int      type, rdlength, pref;
+  unsigned int count, index;
   dnsrep * retval;
 
@@ -1978,5 +1994,12 @@
   /* allocate space for the results */
 
+  if (!sl_ok_muls(count, sizeof (mx)))
+    {
+      SH_FREE   (retval);
+      SL_RETURN (NULL, _("get_mx"));
+    }
+
   result        = SH_ALLOC (count * sizeof (mx));
+  
   if (!result)
     {
Index: /trunk/src/sh_mounts.c
===================================================================
--- /trunk/src/sh_mounts.c	(revision 33)
+++ /trunk/src/sh_mounts.c	(revision 34)
@@ -450,6 +450,5 @@
   
   while ((c = getc (fd)) == '*') {
-    while (((c = getc (fd)) != '\n') && (c != EOF)) {
-    }
+    while (((c = getc (fd)) != '\n') && (c != EOF)) {} /* do nothing */
   }
 }
Index: /trunk/src/sh_prelink.c
===================================================================
--- /trunk/src/sh_prelink.c	(revision 33)
+++ /trunk/src/sh_prelink.c	(revision 34)
@@ -40,5 +40,4 @@
 int sh_prelink_set_path (const char * str)
 {
-  size_t len;
   SL_ENTER(_("sh_prelink_set_path"));
   if (prelink_path != NULL)
@@ -49,7 +48,7 @@
       SL_RETURN((-1), _("sh_prelink_set_path")); 
     }
-  len = sl_strlen (str);
-  prelink_path = SH_ALLOC(len+1);
-  (void) sl_strlcpy(prelink_path, str, len+1);
+
+  prelink_path = sh_util_strdup(str);
+
   SL_RETURN(0, _("sh_prelink_set_path")); 
 }
Index: /trunk/src/sh_schedule.c
===================================================================
--- /trunk/src/sh_schedule.c	(revision 33)
+++ /trunk/src/sh_schedule.c	(revision 34)
@@ -347,10 +347,4 @@
     }
 
-  /*
-  for (i = 0; i < 5; ++i)
-    printf("%2d MIN  %3d  MAX  %3d  STEP  %3d\n", 
-	   i, isched->min[i], isched->max[i], isched->step[i]);
-  */
-
   isched->last_exec = (time_t)-1;
   isched->first     = 0;
Index: /trunk/src/sh_socket.c
===================================================================
--- /trunk/src/sh_socket.c	(revision 33)
+++ /trunk/src/sh_socket.c	(revision 34)
@@ -352,5 +352,5 @@
     {
       size = sl_strlen(DEFAULT_PIDDIR) + 1 + sl_strlen(SH_INSTALL_NAME) + 6;
-      sh_sockname = SH_ALLOC(size);
+      sh_sockname = SH_ALLOC(size); /* compile-time constant */
       sl_strlcpy(sh_sockname, DEFAULT_PIDDIR, size);
       sl_strlcat(sh_sockname, "/", size);
Index: /trunk/src/sh_srp.c
===================================================================
--- /trunk/src/sh_srp.c	(revision 33)
+++ /trunk/src/sh_srp.c	(revision 34)
@@ -197,5 +197,5 @@
 
   char           *combi;
-  size_t          len;
+  size_t          len, l2;
   register int i;
   unsigned char * dez = NULL;
@@ -221,5 +221,8 @@
   skey->vernam[KEY_LEN] = '\0';
 
-  len = sl_strlen(salt) + sl_strlen(skey->vernam) + 1;
+  len = sl_strlen(salt) + 1;
+  l2  = sl_strlen(skey->vernam);
+  if (sl_ok_adds(len, l2))
+    len += l2;
 
   /* H(s,P)
@@ -240,5 +243,5 @@
 {
   char           *combi;
-  size_t          len;
+  size_t          len, l2, l3;
   static char     hash[KEY_LEN+1];
   
@@ -248,5 +251,12 @@
 	     _("x1 != NULL && x2 != NULL && x3 !=NULL"), NULL);
 
-  len = sl_strlen(x1) + sl_strlen(x2) + sl_strlen(x3) + 1;
+  len = sl_strlen(x1) + 1;
+  l2  = sl_strlen(x2); 
+  l3  = sl_strlen(x3);
+
+  if (sl_ok_adds(len, l2))
+    len += l2;
+  if (sl_ok_adds(len, l3))
+    len += l3;
   
   /* H(x1,x2,x3)
@@ -392,5 +402,4 @@
   char    *str;
   char    *combi;
-  size_t   len;
   bigerr_t res;
 
@@ -408,9 +417,5 @@
   
   if (str != NULL)
-    {
-      len = sl_strlen(str) + 1;
-      combi = SH_ALLOC(len);
-      (void) sl_strlcpy (combi, str, len);
-    }
+    combi = sh_util_strdup(str);
   else
     combi = NULL;
@@ -430,5 +435,4 @@
   char    *str;
   char    *combi;
-  long     len;
   bigerr_t res;
 
@@ -469,10 +473,5 @@
   
   if (str != NULL)
-    {
-      len = sl_strlen(str) + 1;
-      combi = SH_ALLOC(len);
-      sl_strlcpy (combi, str, len);
-      /* fprintf(stderr, "OK2a %ld %s\n", len, combi); */
-    }
+    combi = sh_util_strdup(str);
   else
     combi = NULL;
@@ -496,5 +495,4 @@
   char    *str;
   char    *combi;
-  size_t   len;
   bigerr_t res;
 
@@ -571,9 +569,5 @@
 
   if (str != NULL)
-    {
-      len = sl_strlen(str) + 1;
-      combi = SH_ALLOC(len);
-      (void) sl_strlcpy (combi, str, len);
-    }
+    combi = sh_util_strdup(str);
   else
     combi = NULL;
@@ -601,5 +595,4 @@
   char    *str;
   char    *combi;
-  size_t   len;
   bigerr_t res;
 
@@ -651,9 +644,5 @@
   
   if (str != NULL)
-    {
-      len = sl_strlen(str) + 1;
-      combi = SH_ALLOC(len);
-      (void) sl_strlcpy (combi, str, len);
-    }
+    combi = sh_util_strdup(str);
   else
     combi = NULL;
@@ -679,5 +668,4 @@
   char    *combi;
   char    *str;
-  size_t   len;
   bigerr_t res;
   
@@ -700,9 +688,5 @@
   
   if (str != NULL)
-    {
-      len = sl_strlen(str) + 1;
-      combi = SH_ALLOC(len);
-      (void) sl_strlcpy (combi, str, len);
-    }
+    combi = sh_util_strdup(str);
   else
     combi = NULL;
Index: /trunk/src/sh_suidchk.c
===================================================================
--- /trunk/src/sh_suidchk.c	(revision 33)
+++ /trunk/src/sh_suidchk.c	(revision 34)
@@ -854,7 +854,5 @@
 					else
 					  {
-					    basetmp = SH_ALLOC(1 + sl_strlen(theFile.fullpath));
-					    (void) sl_strlcpy(basetmp, theFile.fullpath, 
-						       1 + sl_strlen(theFile.fullpath));
+					    basetmp = sh_util_strdup(theFile.fullpath);
 					    filetmp = SH_ALLOC(PATH_MAX+1);
 					    (void) sl_snprintf(filetmp, PATH_MAX+1, "%s/%s", 
Index: /trunk/src/sh_tiger0.c
===================================================================
--- /trunk/src/sh_tiger0.c	(revision 33)
+++ /trunk/src/sh_tiger0.c	(revision 34)
@@ -1665,5 +1665,5 @@
     }
 
-  if (what == TIGER_FILE)
+  if (what == TIGER_FILE && sl_ok_adds(sl_strlen (filename), (2 + 48 + 6)))
     len = sl_strlen (filename) + 2 + 48 + 6;
   else
Index: /trunk/src/sh_tools.c
===================================================================
--- /trunk/src/sh_tools.c	(revision 33)
+++ /trunk/src/sh_tools.c	(revision 34)
@@ -129,5 +129,5 @@
   char   tmp[4];
   char * outstr;
-  int    len = 1;
+  size_t len = 1;
   int    i = 0;
   unsigned char   val_octal = '\0';
@@ -138,5 +138,21 @@
 
   if (instr)
-    len = (3 * strlen(instr)) + 4;
+    {
+      len = strlen(instr);
+      if (sl_ok_muls (3, len) && sl_ok_adds ((3*len), 4))
+	{
+	  len = (3 * len) + 4;
+	  p = instr;
+	}
+      else
+	{
+	  len = 1;
+	  p   = NULL;
+	}
+    }
+  else
+    {
+      p = NULL;
+    }
 
   outstr = SH_ALLOC(len);
@@ -144,6 +160,4 @@
   outstr[0] = '\0';
   tmp[3]    = '\0';
-
-  p = instr;
 
 #if !defined(SH_USE_XML)
@@ -460,5 +474,4 @@
 
   int    retval;
-  size_t len;
 
   sin_cache * check_cache = conn_cache;
@@ -534,10 +547,5 @@
 		  else
 		    {
-		      len = sl_strlen(host_entry->h_name) + 1;
-		      host_name = SH_ALLOC(len);
-		      if (len > 1)
-			sl_strlcpy(host_name, host_entry->h_name, len);
-		      else
-			host_name[0] = '\0';
+		      host_name = sh_util_strdup(host_entry->h_name);
 		    }
 
@@ -1096,5 +1104,5 @@
  */
 char * sh_tools_makePack (unsigned char * header, 
-			  char * payload, int payload_size,
+			  char * payload, unsigned long payload_size,
 			  keyInstance * keyInstE)
 {
@@ -1102,9 +1110,9 @@
   unsigned char   head[16];
   double epad;
-  int    i_epad = 0;
-  int    i_blk = payload_size / 16;
-  int    i_blkmax = SH_V2_FULLSIZE / 16;
-  int    pads = 0;
-  int    full_size;
+  unsigned long    i_epad = 0;
+  unsigned long    i_blk = payload_size / 16;
+  unsigned long    i_blkmax = SH_V2_FULLSIZE / 16;
+  unsigned long    pads = 0;
+  size_t full_size;
   char * full_ret;
 
@@ -1116,4 +1124,5 @@
   int                     err_num;
   int                     blkfac;
+  int                     oflow = 0;
 
   /* 
@@ -1152,5 +1161,5 @@
     fprintf(stderr, "PAD1 <%d> <%f>\n", pads, epad);
 #endif
-    i_epad = (int) (pads * epad);
+    i_epad = (unsigned long) (pads * epad);
 #ifdef DEBUG_EN2
     fprintf(stderr, "PAD2 <%d> <%d>\n", i_epad, (i_epad*16));
@@ -1158,16 +1167,28 @@
   }
 
-  full_size = 
-  /* head     */ 16 + 
-  /* payload  */ (i_blk*16) + /* payload_size + */ 
-  /* pad      */ (i_epad * 16);
+  full_size =  16;                        /* head     */
+  if (sl_ok_muls(i_blk, 16) && sl_ok_adds(full_size, (i_blk*16)))
+    full_size =  full_size + (i_blk*16);  /* payload  */
+  else
+    oflow = 1;
+  if (sl_ok_adds(full_size, (i_epad*16)))
+    full_size =  full_size + (i_epad*16); /* pad      */
+  else
+    i_epad = 0;
+
+  if (oflow)
+    {
+      sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
+		      _("integer overflow"), 
+		      _("sh_tools_makePack"));
+    }
 
   full_ret = SH_ALLOC(full_size);
   memcpy(full_ret,                   head,    16);
-  if (payload != NULL)
+  if (payload != NULL && !oflow)
     {
       memcpy(&full_ret[16],              payload, payload_size);
     }
-  if ((i_blk*16) > payload_size) 
+  if ((i_blk*16) > payload_size && !oflow) 
     {
 #ifdef DEBUG_EN2
@@ -1354,5 +1375,5 @@
 {
   char           hash[KEY_LEN+1];
-  char         * temp;
+  char         * temp = NULL;
   register int   i;
   int            total = 0;
@@ -1374,14 +1395,22 @@
   sl_strlcpy(hash, theSig, KEY_LEN+1);
 
-
-  total = KEY_LEN + buflen;
-  temp  = SH_ALLOC (total);
-
-  for (i = 0; i < KEY_LEN; ++i)
-    temp[i] = hash[i];
-
-  for (i = 0; i < buflen; ++i)
-    temp[i+KEY_LEN] = buf[i];
-
+  if (sl_ok_adds(buflen, KEY_LEN))
+    {
+      total = KEY_LEN + buflen;
+      temp  = SH_ALLOC (total);
+
+      for (i = 0; i < KEY_LEN; ++i)
+	temp[i] = hash[i];
+
+      for (i = 0; i < buflen; ++i)
+	temp[i+KEY_LEN] = buf[i];
+    }
+  else
+    {
+      sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
+		      _("integer overflow"), 
+		      _("hash_me"));
+      temp = sh_util_strdup(buf);
+    }
   SL_RETURN(temp, _("hash_me"));
 }
@@ -1423,16 +1452,18 @@
 {
   char * ret;
-  int    size, status;
+  int    status;
   struct stat buf;
   char * base;
+  size_t size;
 
   SL_ENTER(_("get_client_conf_file"));
 
-  size = sl_strlen(DEFAULT_DATAROOT);
-  base = SH_ALLOC(size + 1);
-  sl_strlcpy(base, DEFAULT_DATAROOT, size + 1); 
-
-  size = sl_strlen(base) + sl_strlen(peer) + 5;
-  ++size;
+  base = sh_util_strdup(DEFAULT_DATAROOT);
+
+  size = sl_strlen(base);
+  if (sl_ok_adds(size, sl_strlen(peer)))
+      size += sl_strlen(peer);
+  if (sl_ok_adds(size, 6))
+    size += 6;
 
   ret = SH_ALLOC(size);
@@ -1461,4 +1492,5 @@
 
   SH_FREE(base);
+  SH_FREE(ret);
   *length=0;
   SL_RETURN(NULL, _("get_client_conf_file"));
@@ -1480,18 +1512,19 @@
 {
   char * ret;
-  int    size, status;
+  int    status;
   struct stat buf;
 
   char * base;
+  size_t size;
 
   SL_ENTER(_("get_client_data_file"));
 
-  size = sl_strlen(DEFAULT_DATAROOT);
-  base = SH_ALLOC(size + 1);
-  sl_strlcpy(base, DEFAULT_DATAROOT, size + 1); 
-
-  size = sl_strlen(base) + sl_strlen(peer) + 7;
-
-  ++size;
+  base = sh_util_strdup(DEFAULT_DATAROOT);
+
+  size = sl_strlen(base);
+  if (sl_ok_adds(size, sl_strlen(peer)))
+      size += sl_strlen(peer);
+  if (sl_ok_adds(size, 8))
+    size += 8;
 
   ret = SH_ALLOC(size);
@@ -1523,4 +1556,5 @@
   *length = 0;
   SH_FREE(base);
+  SH_FREE(ret);
   SL_RETURN(NULL, _("get_client_data_file"));
 
@@ -1553,21 +1587,14 @@
   int           status = BAD;
   char        * my_tmp_dir;
-  int           len;
 
   SL_ENTER(_("open_tmp"));
 
 #if defined(SH_TMPDIR)
-  len        = sl_strlen(SH_TMPDIR) + 1;
-  my_tmp_dir = SH_ALLOC(len);
-  sl_strlcpy(my_tmp_dir, SH_TMPDIR, len); 
+  my_tmp_dir = sh_util_strdup(SH_TMPDIR); 
 #else
 #if defined(SH_WITH_SERVER)
-  len        = sl_strlen(DEFAULT_LOGDIR) + 1;
-  my_tmp_dir = SH_ALLOC(len);
-  sl_strlcpy(my_tmp_dir, DEFAULT_LOGDIR, len); 
+  my_tmp_dir = sh_util_strdup(DEFAULT_LOGDIR); 
 #else
-  len        = sl_strlen(sh.effective.home) + 1;
-  my_tmp_dir = SH_ALLOC(len);
-  sl_strlcpy(my_tmp_dir, sh.effective.home, len);
+  my_tmp_dir = sh_util_strdup(sh.effective.home);
 #endif 
 #endif
Index: /trunk/src/sh_unix.c
===================================================================
--- /trunk/src/sh_unix.c	(revision 33)
+++ /trunk/src/sh_unix.c	(revision 34)
@@ -331,5 +331,5 @@
 int safe_logger (int signal, int method, char * details)
 {
-  int i = 0;
+  unsigned int i = 0;
   int status = -1;
   struct stat buf;
@@ -429,10 +429,13 @@
 }
 
-void safe_fatal (int signal, int method, char * details, 
-		char * file, int line)
+void safe_fatal (char * details, 
+		 char * file, int line)
 {
   char msg[128];
   char str[128];
   char * p;
+  int  signal = 0;
+  int  method = 0;
+
   p = safe_itoa((int) line, str, 128);
   sl_strlcpy(msg, _("FATAL: "), 128);
@@ -2374,7 +2377,9 @@
 
   if (sizeofline < 2) {
-    line[n] = '\0';
+    line[0] = '\0';
     SL_RETURN((0), _("sh_unix_getline"));
   }
+
+  --sizeofline;
 
   while (n < sizeofline) {
@@ -2872,12 +2877,4 @@
 
   path = theFile->fullpath;
-
-#if 0
-  {
-    char pwd[256];
-    printf("%d %s %s %s (%s)\n", flagrel, theFile->fullpath, filename, path,
-	   getcwd (pwd, 256)); 
-  }
-#endif
 
   SL_ENTER(_("sh_unix_getinfo"));
@@ -3231,5 +3228,5 @@
     else 
       {
-	tmp = sh_util_basename(theFile->fullpath);
+	tmp = sh_util_dirname(theFile->fullpath);
 	sl_strlcpy (theFile->linkpath, 
 		    tmp, 
@@ -3392,5 +3389,5 @@
       /* read the PID in the lock file
        */
-      status = sh_unix_getline (fd, line_in, sizeof(line_in)-1);
+      status = sh_unix_getline (fd, line_in, sizeof(line_in));
 
       /* convert to numeric
@@ -3487,5 +3484,6 @@
 int sh_unix_write_lock_file(char * filename)
 {
-  int i;
+  size_t len;
+  int    res;
   char * lockfile;
 
@@ -3493,11 +3491,13 @@
     return (-1);
 
-  i        = 6 + sl_strlen(filename);
-  lockfile = SH_ALLOC(i);
-  sl_strlcpy(lockfile, filename,   i);
-  sl_strlcat(lockfile, _(".lock"), i);
-  i = sh_unix_test_and_lock(filename, lockfile);
+  len = sl_strlen(filename);
+  if (sl_ok_adds(len, 6))
+    len += 6;
+  lockfile = SH_ALLOC(len);
+  sl_strlcpy(lockfile, filename,   len);
+  sl_strlcat(lockfile, _(".lock"), len);
+  res = sh_unix_test_and_lock(filename, lockfile);
   SH_FREE(lockfile);
-  return i;
+  return res;
 }
 
@@ -3541,5 +3541,6 @@
 int sh_unix_rm_lock_file(char * filename)
 {
-  int i;
+  size_t len;
+  int res;
   char * lockfile;
 
@@ -3547,11 +3548,14 @@
     return (-1);
 
-  i        = 6 + sl_strlen(filename);
-  lockfile = SH_ALLOC(i);
-  sl_strlcpy(lockfile, filename,   i);
-  sl_strlcat(lockfile, _(".lock"), i);
-  i = sh_unix_unlock(lockfile, filename);
+  len = sl_strlen(filename);
+  if (sl_ok_adds(len, 6))
+    len += 6;
+  lockfile = SH_ALLOC(len);
+  sl_strlcpy(lockfile, filename,   len);
+  sl_strlcat(lockfile, _(".lock"), len);
+
+  res = sh_unix_unlock(lockfile, filename);
   SH_FREE(lockfile);
-  return i;
+  return res;
 }
 
@@ -4075,7 +4079,4 @@
 #if  !defined(SH_STEALTH_MICRO)
 
-static unsigned long off_data = 0;
-static unsigned long max_data = 0;
-static int           stealth_init = BAD;
 
 int hideout_hex_block(SL_TICKET fd, unsigned char * str, int len);
@@ -4087,7 +4088,11 @@
 int sh_unix_getline_stealth (SL_TICKET fd, char * str, int len)
 {
-  int add_off, llen;
+  int           add_off, llen;
+  unsigned long off_data = 0;
+  unsigned long max_data = 0;
+  static int    stealth_init = BAD;
 
   SL_ENTER(_("sh_unix_getline_stealth"));
+
 
   /* --- Initialize. ---
@@ -4132,4 +4137,8 @@
 
   SL_ENTER(_("hideout_hex_block"));
+
+  ASSERT_RET((len > 1), _("len > 1"), (0));
+
+  --len;
 
   i = 0;
@@ -4151,5 +4160,5 @@
 		} while (num == 0 && errno == EINTR);
 		if (num == 0) 
-		  SL_RETURN((-1), _("hideout_hex_block"));
+		  SL_RETURN((0), _("hideout_hex_block"));
 		++here; 
 	      } while (c == '\n' || c == '\t' || c == '\r' || 
@@ -4174,5 +4183,5 @@
     str[i] = '\0';
   else
-    str[i+1] = '\0';
+    str[i+1] = '\0'; /* keep newline and terminate */
   retval += here;
 
@@ -4184,10 +4193,11 @@
 unsigned long first_hex_block(SL_TICKET fd, unsigned long * max)
 {
-  int           i;
-  register int  num = 1;
+  unsigned int  i;
+  long          num = 1;
+  unsigned long lnum;
   char          c;
   int           nothex = 0;
   unsigned long retval = 0;
-  int           this_line = 0;
+  unsigned int  this_line = 0;
   char          theline[SH_BUFSIZE];
 
@@ -4201,5 +4211,5 @@
       this_line  = 0;
       c          = '\0';
-      while (c != '\n' && num > 0)
+      while (c != '\n' && num > 0 && this_line < (sizeof(theline)-1))
 	{
 	  do {
@@ -4210,5 +4220,5 @@
 	  else           
 	    SL_RETURN((0), _("first_hex_block"));
-	  this_line += num;
+	  ++this_line;
 	}
       theline[this_line] = '\0';
@@ -4239,13 +4249,17 @@
 	      num = sl_read (fd, theline, SH_BUFSIZE);
 	    } while (num == 0 && errno == EINTR);
-	    for (i = 0; i < num; ++i)
-	      { 
-		c = theline[i];
-		if (c == '\n' || c == '\t' || c == '\r' || c == ' ') 
-		  ;
-		else if (!isxdigit((int)c))
-		  break;
-		else
-		  *max += 1;
+	    if (num > 0)
+	      {
+		lnum = (unsigned long) num;
+		for (i = 0; i < lnum; ++i)
+		  { 
+		    c = theline[i];
+		    if (c == '\n' || c == '\t' || c == '\r' || c == ' ') 
+		      ;
+		    else if (!isxdigit((int)c))
+		      break;
+		    else
+		      *max += 1;
+		  }
 	      }
 	  } while (num > 0);
Index: /trunk/src/sh_utils.c
===================================================================
--- /trunk/src/sh_utils.c	(revision 33)
+++ /trunk/src/sh_utils.c	(revision 34)
@@ -270,6 +270,10 @@
   size = sl_strlen(formatt);
 
-  fmt = (char *) SH_ALLOC(size + 1);
-  (void) sl_strlcpy(fmt, formatt, size + 1);
+  if (!sl_ok_adds(size, 1))
+    SL_RETURN(NULL, _("sh_util_formatted"));
+
+  ++size;
+  fmt = SH_ALLOC(size);
+  (void) sl_strlcpy(fmt, formatt, size);
 
   p = fmt;
@@ -319,5 +323,5 @@
 		{
 		  isiz = sl_strlen(ftab[j].data_str);
-		  if (isiz > 0)
+		  if (isiz > 0 && sl_ok_adds(size, isiz))
 		    {
 		      size += isiz;
@@ -339,5 +343,5 @@
 		  /*@+bufferoverflowhigh@*/
 		  isiz = sl_strlen(ftab[j].data_str);
-		  if (isiz > 0)
+		  if (isiz > 0 && sl_ok_adds(size, isiz))
 		    {
 		      size += isiz;
@@ -359,5 +363,5 @@
 		  /*@+bufferoverflowhigh@*/
 		  isiz = sl_strlen(ftab[j].data_str);
-		  if (isiz > 0)
+		  if (isiz > 0 && sl_ok_adds(size, isiz))
 		    {
 		      size += isiz;
@@ -391,5 +395,5 @@
 		    }
 		  isiz = sl_strlen(ftab[j].data_str);
-		  if (isiz > 0)
+		  if (isiz > 0 && sl_ok_adds(size, isiz))
 		    {
 		      size += isiz;
@@ -431,5 +435,6 @@
   /* -- closing '\0' --
    */
-  size++;
+  if (sl_ok_adds(size, 1))
+    size++;
   outstr = (char *) SH_ALLOC(size);
 
@@ -441,5 +446,6 @@
 		      clist[8],  clist[9], clist[10], clist[11], 
 		      clist[12], clist[13], clist[14], clist[15]); 
-  
+  outstr[size-1] = '\0';
+
   /* -- cleanup --
    */
@@ -491,5 +497,8 @@
   SL_ENTER(_("sh_util_hextobinary"));
 
-  while (i < bytes)
+  if (bytes < 2)
+    SL_RETURN((-1), _("sh_util_hextobinary"));
+
+  while (i < (bytes-1))
     {
       SH_HEXCHAR(hex[i],   k);
@@ -498,16 +507,4 @@
       binary[l] = (char)(k * 16 + j);
       ++l; i+= 2;
-
-      /* k = sh_util_hexchar(hex[i]); j = sh_util_hexchar(hex[i+1]); 
-      if (k != -1 && j != -1) 
-        {
-          binary[l] = (char)(k * 16 + j);
-          ++l; i+= 2;
-        }
-      else
-        {
-	  SL_RETURN((-1), _("sh_util_hextobinary"));
-        }
-      */
     }
   
@@ -581,14 +578,25 @@
     }
 
-  inner = (char *) SH_ALLOC (textlen + KEY_BLOCK); 
-
-  for (i = 0; i < KEY_BLOCK; ++i)
-    {
-      outer[i]  = K[i] ^ opad[i];
-      inner[i]  = K[i] ^ ipad[i];
-    }
-  for (i = KEY_BLOCK; i < (KEY_BLOCK+textlen); ++i)
-    {
-      inner[i] = text[i - KEY_BLOCK];
+  if (sl_ok_adds(textlen, KEY_BLOCK))
+    {
+      inner = (char *) SH_ALLOC (textlen + KEY_BLOCK); 
+
+      for (i = 0; i < KEY_BLOCK; ++i)
+	{
+	  outer[i]  = K[i] ^ opad[i];
+	  inner[i]  = K[i] ^ ipad[i];
+	}
+      for (i = KEY_BLOCK; i < (KEY_BLOCK+textlen); ++i)
+	{
+	  inner[i] = text[i - KEY_BLOCK];
+	}
+    }
+  else
+    {
+      sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
+		      _("integer overflow"), 
+		      _("sh_util_hmac_tiger"));
+      res = sh_tiger_hash (NULL, TIGER_DATA, 0);
+      SL_RETURN(res, _("sh_util_hmac_tiger"));
     }
 
@@ -1421,8 +1429,48 @@
 /* returns freshly allocated memory, return value should be free'd
  */
-char * sh_util_basename(char * fullpath)
+char * sh_util_dirname(const char * fullpath)
 {
   char * retval;
-  size_t i;
+  size_t len;
+
+  SL_ENTER(_("sh_util_dirname"));
+
+  ASSERT_RET ((fullpath != NULL), _("fullpath != NULL"), (NULL))
+
+  len = sl_strlen (fullpath);  /* fullpath[i] is terminating '\0' */
+
+  if (len > 1 && fullpath[len-1] == '/') /* skip trailing '/' */
+    --len;
+
+  while (len > 0) {
+    --len;
+    if (fullpath[len] == '/') 
+      {
+	if (len == 0) ++len; /* copy the '/' to output */
+	break;
+      }
+  }
+
+  /* -- Not an absolute path. --
+   */
+  if ((len == 0) && (fullpath[len] != '/'))
+    { 
+      SL_RETURN(NULL, _("sh_util_dirname"));
+    }
+
+  retval = SH_ALLOC(len + 1);
+  (void) sl_strlcpy (retval, fullpath, len+1);
+
+  SL_RETURN(retval, _("sh_util_dirname"));
+}
+
+/* returns freshly allocated memory, return value should be free'd
+ */
+char * sh_util_basename(const char * fullpath)
+{
+  char * retval = NULL;
+  char * tmp;
+  char * c;
+  size_t len;
 
   SL_ENTER(_("sh_util_basename"));
@@ -1430,46 +1478,31 @@
   ASSERT_RET ((fullpath != NULL), _("fullpath != NULL"), (NULL))
 
-  i = sl_strlen (fullpath);  /* fullpath[i] is terminating '\0' */
-
-  while (i > 0) {
-    --i;
-    if (fullpath[i] == '/') break;
-  }
-
-  /* -- Not a valid path. --
-   */
-  if ((fullpath[i] != '/') && (i == 0) ) 
-    SL_RETURN(NULL, _("sh_util_basename"));
-
-  retval = SH_ALLOC(i + 1);
-
-  (void) sl_strlcpy (retval, fullpath, i+1);
+  c = strrchr(fullpath, '/');
+  len = sl_strlen (c);
+
+  if (c == fullpath)
+    {
+      if (len <= 1)
+	retval = sh_util_strdup(c);
+      else
+	retval = sh_util_strdup(++c);
+    }
+  else
+    {
+      if (len > 1)
+	{
+	  retval = sh_util_strdup(++c);
+	}
+      else
+	{
+	  /* input ends in '/' */
+	  tmp = sh_util_strdup(fullpath);
+	  tmp[strlen(tmp)-1] = '\0';
+	  retval = sh_util_basename(tmp);
+	  SH_FREE(tmp);
+	}
+    }
 
   SL_RETURN(retval, _("sh_util_basename"));
-}
-
-/* returns freshly allocated memory, return value should be free'd
- */
-char * sh_util_filename(char * fullpath)
-{
-  char * retval;
-  char * c;
-  size_t i;
-
-  SL_ENTER(_("sh_util_filename"));
-
-  ASSERT_RET ((fullpath != NULL), _("fullpath != NULL"), (NULL))
-
-  c = strrchr(fullpath, '/');
-  i = sl_strlen (c);
-  if (i <= 1) SL_RETURN(NULL, _("sh_util_filename")); /* ends in '/' */
-  ++c;
-  --i;
-
-  retval = SH_ALLOC(i + 1);
-
-  (void) sl_strlcpy (retval, c, i+1);
-
-  SL_RETURN(retval, _("sh_util_filename"));
 }
 
@@ -1484,4 +1517,5 @@
   char          oct[32];
   char          format[16];
+  size_t        len;
 
   SL_ENTER(_("sh_util_safe_name"));
@@ -1500,13 +1534,32 @@
   */
 
+  len = sl_strlen(name);
+  p   = name;
+
 #ifdef SH_USE_XML
-  retval = SH_ALLOC(6 * sl_strlen(name) + 2);
+  if (sl_ok_muls (6, len) && sl_ok_adds ((6*len), 2))
+    { retval = SH_ALLOC(6 * len + 2); }
+  else
+    {
+      /* return an allocated array
+       */
+      retval = SH_ALLOC(11);
+      (void) sl_strlcpy(retval, _("(overflow)"), 11);
+      SL_RETURN(retval, _("sh_util_safe_name"));
+    }
 #else
-  retval = SH_ALLOC(4 * sl_strlen(name) + 2);
+  if (sl_ok_muls (4, len) && sl_ok_adds ((4*len), 2))
+    { retval = SH_ALLOC(4 * len + 2); }
+  else
+    {
+      /* return an allocated array
+       */
+      retval = SH_ALLOC(11);
+      (void) sl_strlcpy(retval, _("(overflow)"), 11);
+      SL_RETURN(retval, _("sh_util_safe_name"));
+    }
 #endif 
 
   (void) sl_strncpy(format, _("%c%03o"), 16);
-
-  p = name;
 
   while (*p != '\0') {
@@ -1613,5 +1666,5 @@
 char * sh_util_strconcat (const char * arg1, ...)
 {
-  size_t    length;
+  size_t    length, l2;
   char    * s;
   char    * strnew;
@@ -1628,10 +1681,18 @@
   while (s != NULL)
     {
-      length = length + sl_strlen (s);
+      l2 = sl_strlen (s);
+      if (sl_ok_adds(length, l2))
+	length += l2;
+      else
+	SL_RETURN(NULL, _("sh_util_strconcat"));
       s = va_arg (vl, char * );
     }
   va_end (vl);
 
-  strnew = SH_ALLOC( length + 2 ); 
+  if (sl_ok_adds(length, 2))
+    strnew = SH_ALLOC( length + 2 );
+  else
+    SL_RETURN(NULL, _("sh_util_strconcat"));
+
   strnew[0] = '\0';
 
@@ -1680,7 +1741,7 @@
   if (status != 0 && status != REG_NOMATCH) 
     {
-      errbuf = SH_ALLOC(BUFSIZ+2);
+      errbuf = SH_ALLOC(BUFSIZ);
       (void) regerror(status, &preg, errbuf, BUFSIZ); 
-      errbuf[BUFSIZ] = '\0';
+      errbuf[BUFSIZ-1] = '\0';
       sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_REGEX,
 		       errbuf, regex_str);
Index: /trunk/src/sh_utmp.c
===================================================================
--- /trunk/src/sh_utmp.c	(revision 33)
+++ /trunk/src/sh_utmp.c	(revision 34)
@@ -440,5 +440,5 @@
   memcpy (&c, &bar[2], 1);
   memcpy (&d, &bar[3], 1);
-  sprintf(foo, "%d.%d.%d.%d",                          /* known to fit  */
+  sprintf(foo, _("%d.%d.%d.%d"),                        /* known to fit  */
 	  (int) a, (int) b, (int) c, (int) d);
   return foo;
@@ -1064,10 +1064,4 @@
 		      ))
       sh_utmp_addlogin (ut);
-    /*************************************************
-    printf("%8s | %10s | %10s | %3d %5d | %16s | %ld\n", 
-	   ut->ut_name, ut->ut_id, ut->ut_line, 
-	   (int) ut->ut_type, (int) ut->ut_pid, 
-	   ut->ut_host, ut->ut_time);
-    ***************************************************/
     ++this_read;
   }
Index: /trunk/src/slib.c
===================================================================
--- /trunk/src/slib.c	(revision 33)
+++ /trunk/src/slib.c	(revision 34)
@@ -7,4 +7,8 @@
 #include <string.h>
 #include <limits.h>
+#ifdef HAVE_STDINT_H
+/* for SIZE_MAX */
+#include <stdint.h>
+#endif
 
 #include <unistd.h>
@@ -2506,7 +2510,18 @@
  * ---------------------------------------------------------------- */
 
+#ifndef SIZE_MAX
+#define SIZE_MAX              (4294967295U)
+#endif
+
 int sl_ok_muli (int a, int b) /* a*b */
 {
-  if (a >= (INT_MIN / b) && a <= (INT_MAX / b))
+  if ((b == 0) || (a >= (INT_MIN / b) && a <= (INT_MAX / b)))
+    return SL_TRUE; /* no overflow */
+  return SL_FALSE;
+}
+
+int sl_ok_muls (size_t a, size_t b) /* a*b */
+{
+  if ((b == 0) || (a <= (SIZE_MAX / b)))
     return SL_TRUE; /* no overflow */
   return SL_FALSE;
@@ -2540,4 +2555,12 @@
 }
 
+int sl_ok_adds (size_t a, size_t b) /* a+b */
+{
+  if (a <= (SIZE_MAX - b))
+    return SL_TRUE; /* no overflow */
+  else
+    return SL_FALSE;
+}
+
 int sl_ok_subi (int a, int b) /* a-b */
 {
Index: /trunk/src/yulectl.c
===================================================================
--- /trunk/src/yulectl.c	(revision 33)
+++ /trunk/src/yulectl.c	(revision 34)
@@ -392,5 +392,5 @@
       return;
     }
-  if (NULL == fgets(message2, SH_MAXMSG, fp))
+  if (NULL == fgets(message2, sizeof(message2), fp))
     {
       fprintf (stderr, 
@@ -545,5 +545,5 @@
       else
 	{
-	  fprintf(stderr, "ERROR: this command requires a hostname\n");
+	  fprintf(stderr, _("ERROR: this command requires a hostname\n"));
 	  usage(argv[0]);
 	  return (EXIT_FAILURE);
@@ -567,6 +567,9 @@
       return (EXIT_FAILURE);
     }
+#ifdef HAVE_VSNPRINTF
+  snprintf(sockname, size, _("%s/%s.sock"), clientcd, CLIENT);
+#else
   sprintf(sockname, _("%s/%s.sock"), clientcd, CLIENT);
-
+#endif
 
   /* Make the socket.
Index: /trunk/test/testrc_2.in
===================================================================
--- /trunk/test/testrc_2.in	(revision 33)
+++ /trunk/test/testrc_2.in	(revision 34)
@@ -40,4 +40,6 @@
 file = /tmp
 file = /etc
+
+dir=1/usr
 
 [EventSeverity]
Index: /trunk/test/testrun_2.sh
===================================================================
--- /trunk/test/testrun_2.sh	(revision 33)
+++ /trunk/test/testrun_2.sh	(revision 34)
@@ -239,4 +239,7 @@
 	ORIGINAL_4="# SetClientTimeLimit=1800"
 	REPLACEMENT_4="SetClientTimeLimit=20"
+	# takes too much time if we leave that in
+	ORIGINAL_5="dir=1"
+	REPLACEMENT_5="#dir=1"
         ex $RCFILE <<EOF
 %s/${ORIGINAL_1}/${REPLACEMENT_1}/g
@@ -244,4 +247,5 @@
 %s/${ORIGINAL_3}/${REPLACEMENT_3}/g
 %s/${ORIGINAL_4}/${REPLACEMENT_4}/g
+%s/${ORIGINAL_5}/${REPLACEMENT_5}/g
 wq
 EOF
