Add strlcpy()/strlcat()

Refactor recurse() routine in preparation to moving tar(1) over
to use it instead of the ftw() interface.
This commit is contained in:
sin 2014-01-30 12:37:35 +00:00
parent 08ff1c56e7
commit fb12183c52
5 changed files with 88 additions and 16 deletions

View File

@ -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 \

4
util.h
View File

@ -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 *, ...);

View File

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

35
util/strlcat.c Normal file
View File

@ -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 */
}

31
util/strlcpy.c Normal file
View File

@ -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 */
}