[PATCH] Add strlcpy()/strlcat()

From: sin <sin_AT_2f30.org>
Date: Thu, 30 Jan 2014 12:37:35 +0000

Refactor recurse() routine in preparation to moving tar(1) over
to use it instead of the ftw() interface.
---
 Makefile       |  4 +++-
 util.h         |  4 +++-
 util/recurse.c | 30 ++++++++++++++++--------------
 util/strlcat.c | 35 +++++++++++++++++++++++++++++++++++
 util/strlcpy.c | 31 +++++++++++++++++++++++++++++++
 5 files changed, 88 insertions(+), 16 deletions(-)
 create mode 100644 util/strlcat.c
 create mode 100644 util/strlcpy.c
diff --git a/Makefile b/Makefile
index 9fada0f..204e05c 100644
--- a/Makefile
+++ b/Makefile
_AT_@ -22,7 +22,9 @@ LIB = \
 	util/rm.o        \
 	util/sha1.o      \
 	util/sha256.o    \
-	util/sha512.o
+	util/sha512.o    \
+	util/strlcat.o   \
+	util/strlcpy.o
 
 SRC = \
 	basename.c \
diff --git a/util.h b/util.h
index f7e8780..4856bb3 100644
--- a/util.h
+++ b/util.h
_AT_@ -1,5 +1,5 @@
 /* See LICENSE file for copyright and license details. */
-
+#include <stddef.h>
 #include "arg.h"
 
 #define UTF8_POINT(c) (((c) & 0xc0) != 0x80)
_AT_@ -20,4 +20,6 @@ long estrtol(const char *, int);
 void fnck(const char *, const char *, int (*)(const char *, const char *));
 void putword(const char *);
 void recurse(const char *, void (*)(const char *));
+size_t strlcat(char *, const char *, size_t);
+size_t strlcpy(char *, const char *, size_t);
 void weprintf(const char *, ...);
diff --git a/util/recurse.c b/util/recurse.c
index b3d1f8c..6ac235e 100644
--- a/util/recurse.c
+++ b/util/recurse.c
_AT_@ -1,17 +1,19 @@
 /* See LICENSE file for copyright and license details. */
 #include <dirent.h>
-#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 #include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 #include "../util.h"
 
 void
 recurse(const char *path, void (*fn)(const char *))
 {
-	char *cwd;
+	char buf[PATH_MAX], *p;
 	struct dirent *d;
 	struct stat st;
 	DIR *dp;
_AT_@ -22,19 +24,19 @@ recurse(const char *path, void (*fn)(const char *))
 		eprintf("opendir %s:", path);
 	}
 
-	cwd = agetcwd();
-	if(chdir(path) == -1)
-		eprintf("chdir %s:", path);
-
 	while((d = readdir(dp))) {
-		if(strcmp(d->d_name, ".") && strcmp(d->d_name, ".."))
-			fn(d->d_name);
+		if (strcmp(d->d_name, ".") == 0 ||
+		    strcmp(d->d_name, "..") == 0)
+			continue;
+		strlcpy(buf, path, sizeof(buf));
+		p = strrchr(buf, '\0');
+		/* remove all trailing slashes */
+		while (--p >= buf && *p == '/') *p ='\0';
+		strlcat(buf, "/", sizeof(buf));
+		if (strlcat(buf, d->d_name, sizeof(buf)) >= sizeof(buf))
+			enprintf(EXIT_FAILURE, "path too long\n");
+		fn(buf);
 	}
 
 	closedir(dp);
-	if(chdir(cwd) == -1)
-		eprintf("chdir %s:", cwd);
-
-	free(cwd);
 }
-
diff --git a/util/strlcat.c b/util/strlcat.c
new file mode 100644
index 0000000..a50c612
--- /dev/null
+++ b/util/strlcat.c
_AT_@ -0,0 +1,35 @@
+/* Taken from OpenBSD */
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Appends src to string dst of size siz (unlike strncat, siz is the
+ * full size of dst, not space left).  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
+ * Returns strlen(src) + MIN(siz, strlen(initial dst)).
+ * If retval >= siz, truncation occurred.
+ */
+size_t
+strlcat(char *dst, const char *src, size_t siz)
+{
+        char *d = dst;
+        const char *s = src;
+        size_t n = siz;
+        size_t dlen;
+        /* Find the end of dst and adjust bytes left but don't go past end */
+        while (n-- != 0 && *d != '\0')
+                d++;
+        dlen = d - dst;
+        n = siz - dlen;
+        if (n == 0)
+                return(dlen + strlen(s));
+        while (*s != '\0') {
+                if (n != 1) {
+                        *d++ = *s;
+                        n--;
+                }
+                s++;
+        }
+        *d = '\0';
+        return(dlen + (s - src));       /* count does not include NUL */
+}
diff --git a/util/strlcpy.c b/util/strlcpy.c
new file mode 100644
index 0000000..3779c78
--- /dev/null
+++ b/util/strlcpy.c
_AT_@ -0,0 +1,31 @@
+/* Taken from OpenBSD */
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Copy src to string dst of size siz.  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+strlcpy(char *dst, const char *src, size_t siz)
+{
+        char *d = dst;
+        const char *s = src;
+        size_t n = siz;
+        /* Copy as many bytes as will fit */
+        if (n != 0) {
+                while (--n != 0) {
+                        if ((*d++ = *s++) == '\0')
+                                break;
+                }
+        }
+        /* Not enough room in dst, add NUL and traverse rest of src */
+        if (n == 0) {
+                if (siz != 0)
+                        *d = '\0';              /* NUL-terminate dst */
+                while (*s++)
+                        ;
+        }
+        return(s - src - 1);    /* count does not include NUL */
+}
-- 
1.8.5.3
--pWyiEgJYm5f9v55/--
Received on Mon Sep 17 2001 - 00:00:00 CEST

This archive was generated by hypermail 2.3.0 : Thu Jan 30 2014 - 15:24:03 CET