2005-04-02 Andrew J. Schorr <ajschorr@alumni.princeton.edu>

	* str.c: Replace strlcpy and strlcat with actual working versions
	  copied from rsync-2.6.2/lib/compat.c.
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 8aaf382..c372e66 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,5 +1,10 @@
 2005-04-02 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
 
+	* str.c: Replace strlcpy and strlcat with actual working versions
+	  copied from rsync-2.6.2/lib/compat.c.
+
+2005-04-02 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
+
 	* if.h: Remove define for IFINDEX_INTERNBASE and add define
 	  IFINDEX_INTERNAL 0, since all internal (i.e. non-kernel) pseudo-
 	  interfaces should have ifindex set to 0.
diff --git a/lib/str.c b/lib/str.c
index 18a5d8e..00d0319 100644
--- a/lib/str.c
+++ b/lib/str.c
@@ -1,11 +1,19 @@
 /*
  * zebra string function
  *
- * these functions are just very basic wrappers around exiting ones and
- * do not offer the protection that might be expected against buffer
- * overruns etc
+ * XXX This version of snprintf does not check bounds!
  */
 
+/*
+ The implementations of strlcpy and strlcat are copied from rsync (GPL):
+    Copyright (C) Andrew Tridgell 1998
+    Copyright (C) 2002 by Martin Pool
+
+ Note that these are not terribly efficient, since they make more than one
+ pass over the argument strings.  At some point, they should be optimized.
+*/
+
+
 #include <zebra.h>
 
 #ifndef HAVE_SNPRINTF
@@ -25,37 +33,51 @@
 #endif
 
 #ifndef HAVE_STRLCPY
-/*
- * strlcpy is a safer version of strncpy(), checking the total
- * size of the buffer
- */
+/**
+ * Like strncpy but does not 0 fill the buffer and always null 
+ * terminates.
+ *
+ * @param bufsize is the size of the destination buffer.
+ *
+ * @return index of the terminating byte.
+ **/
 size_t
-strlcpy(char *dst, const char *src, size_t size)
+strlcpy(char *d, const char *s, size_t bufsize)
 {
-  strncpy(dst, src, size);
-
-  return (strlen(dst));
+	size_t len = strlen(s);
+	size_t ret = len;
+	if (bufsize > 0) {
+		if (len >= bufsize)
+			len = bufsize-1;
+		memcpy(d, s, len);
+		d[len] = 0;
+	}
+	return ret;
 }
 #endif
 
 #ifndef HAVE_STRLCAT
-/*
- * strlcat is a safer version of strncat(), checking the total
- * size of the buffer
- */
+/**
+ * Like strncat() but does not 0 fill the buffer and always null 
+ * terminates.
+ *
+ * @param bufsize length of the buffer, which should be one more than
+ * the maximum resulting string length.
+ **/
 size_t
-strlcat(char *dst, const char *src, size_t size)
+strlcat(char *d, const char *s, size_t bufsize)
 {
-  /* strncpy(dst, src, size - strlen(dst)); */
+	size_t len1 = strlen(d);
+	size_t len2 = strlen(s);
+	size_t ret = len1 + len2;
 
-  /* I've just added below code only for workable under Linux.  So
-     need rewrite -- Kunihiro. */
-  if (strlen (dst) + strlen (src) >= size)
-    return -1;
-
-  strcat (dst, src);
-
-  return (strlen(dst));
+	if (len1 < bufsize - 1) {
+		if (len2 >= bufsize - len1)
+			len2 = bufsize - len1 - 1;
+		memcpy(d+len1, s, len2);
+		d[len1+len2] = 0;
+	}
+	return ret;
 }
 #endif