commit fb12183c5284ded7277d4af5b686826be4d99852
parent 08ff1c56e7c5074803c575387c676a5e413a1547
Author: sin <sin@2f30.org>
Date: Thu, 30 Jan 2014 12:37:35 +0000
Add strlcpy()/strlcat()
Refactor recurse() routine in preparation to moving tar(1) over
to use it instead of the ftw() interface.
Diffstat:
5 files changed, 88 insertions(+), 16 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -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 */
+}