Hi,

This is in preparation to moving tar(1) over to recurse()
instead of ftw().

The caller of recurse() doesn't need to prepare a full path
manually anymore.

cheers,
sin
>From 0697ac3a64dca3f4a3857784f1e1a15dd82827ee Mon Sep 17 00:00:00 2001
From: sin <s...@2f30.org>
Date: Thu, 30 Jan 2014 12:37:35 +0000
Subject: [PATCH] Add strlcpy()/strlcat()

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
@@ -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
@@ -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)
@@ -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
@@ -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;
@@ -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
@@ -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
@@ -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

Reply via email to