diff options
-rw-r--r-- | package/deps.mak | 5 | ||||
-rw-r--r-- | src/include/skalibs/djbunix.h | 4 | ||||
-rw-r--r-- | src/libstddjb/hiercopy.c | 2 | ||||
-rw-r--r-- | src/libstddjb/hiercopy_internal.c | 88 | ||||
-rw-r--r-- | src/libstddjb/hiercopy_loose.c | 9 | ||||
-rw-r--r-- | src/libstddjb/hiercopy_loose_tmp.c | 8 | ||||
-rw-r--r-- | src/libstddjb/hiercopy_tmp.c | 82 |
7 files changed, 114 insertions, 84 deletions
diff --git a/package/deps.mak b/package/deps.mak index 6a9f2f9..16110ba 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -344,7 +344,10 @@ src/libstddjb/genwrite_stdout.o src/libstddjb/genwrite_stdout.lo: src/libstddjb/ src/libstddjb/getlnmax.o src/libstddjb/getlnmax.lo: src/libstddjb/getlnmax.c src/include/skalibs/buffer.h src/include/skalibs/siovec.h src/include/skalibs/skamisc.h src/libstddjb/getlnmaxsep.o src/libstddjb/getlnmaxsep.lo: src/libstddjb/getlnmaxsep.c src/include/skalibs/buffer.h src/include/skalibs/siovec.h src/include/skalibs/skamisc.h src/libstddjb/hiercopy.o src/libstddjb/hiercopy.lo: src/libstddjb/hiercopy.c src/include/skalibs/djbunix.h src/include/skalibs/skamisc.h -src/libstddjb/hiercopy_tmp.o src/libstddjb/hiercopy_tmp.lo: src/libstddjb/hiercopy_tmp.c src/include/skalibs/direntry.h src/include/skalibs/djbunix.h src/include/skalibs/stralloc.h +src/libstddjb/hiercopy_internal.o src/libstddjb/hiercopy_internal.lo: src/libstddjb/hiercopy_internal.c src/include/skalibs/direntry.h src/include/skalibs/djbunix.h src/include/skalibs/stralloc.h +src/libstddjb/hiercopy_loose.o src/libstddjb/hiercopy_loose.lo: src/libstddjb/hiercopy_loose.c src/include/skalibs/djbunix.h src/include/skalibs/skamisc.h +src/libstddjb/hiercopy_loose_tmp.o src/libstddjb/hiercopy_loose_tmp.lo: src/libstddjb/hiercopy_loose_tmp.c src/include/skalibs/djbunix.h +src/libstddjb/hiercopy_tmp.o src/libstddjb/hiercopy_tmp.lo: src/libstddjb/hiercopy_tmp.c src/include/skalibs/djbunix.h src/libstddjb/int160_scan.o src/libstddjb/int160_scan.lo: src/libstddjb/int160_scan.c src/libstddjb/fmtscan-internal.h src/include/skalibs/uint16.h src/libstddjb/int16_fmtlist.o src/libstddjb/int16_fmtlist.lo: src/libstddjb/int16_fmtlist.c src/libstddjb/fmtscan-internal.h src/include/skalibs/uint16.h src/libstddjb/int16_scan.o src/libstddjb/int16_scan.lo: src/libstddjb/int16_scan.c src/libstddjb/fmtscan-internal.h src/include/skalibs/uint16.h src/include/skalibs/uint64.h diff --git a/src/include/skalibs/djbunix.h b/src/include/skalibs/djbunix.h index 5401515..0f654c7 100644 --- a/src/include/skalibs/djbunix.h +++ b/src/include/skalibs/djbunix.h @@ -155,7 +155,9 @@ extern int filecopy_unsafe (char const *, char const *, unsigned int) ; extern int filecopy_suffix (char const *, char const *, unsigned int, char const *) ; extern int sals (char const *, stralloc *, size_t *) ; extern int hiercopy (char const *, char const *) ; -extern int hiercopy_tmp (char const *, char const *, stralloc *) ; +extern int hiercopy_loose (char const *, char const *) ; +extern int hiercopy_loose_tmp (char const *, char const *, stralloc *) ; +extern int hiercopy_internal (char const *, char const *, stralloc *, unsigned int) ; /* Simple spawn functions with 0 or 1 communicating fds. */ diff --git a/src/libstddjb/hiercopy.c b/src/libstddjb/hiercopy.c index 3fc4d2f..53f9850 100644 --- a/src/libstddjb/hiercopy.c +++ b/src/libstddjb/hiercopy.c @@ -5,5 +5,5 @@ int hiercopy (char const *src, char const *dst) { - return hiercopy_tmp(src, dst, &satmp) ; + return hiercopy_internal(src, dst, &satmp, 0) ; } diff --git a/src/libstddjb/hiercopy_internal.c b/src/libstddjb/hiercopy_internal.c new file mode 100644 index 0000000..c512463 --- /dev/null +++ b/src/libstddjb/hiercopy_internal.c @@ -0,0 +1,88 @@ +/* ISC license. */ + +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <errno.h> +#include <fcntl.h> + +#include <skalibs/stralloc.h> +#include <skalibs/direntry.h> +#include <skalibs/djbunix.h> + +static int dircopy (char const *src, char const *dst, mode_t mode, stralloc *tmp, unsigned int options) +{ + size_t tmpbase = tmp->len ; + size_t maxlen = 0 ; + if (sals(src, tmp, &maxlen) == -1) return 0 ; + + if (mkdir(dst, S_IRWXU) < 0) + { + struct stat st ; + if (errno != EEXIST) goto err ; + if (stat(dst, &st) < 0) goto err ; + if (!S_ISDIR(st.st_mode)) { errno = ENOTDIR ; goto err ; } + } + { + size_t srclen = strlen(src) ; + size_t dstlen = strlen(dst) ; + size_t i = tmpbase ; + char srcbuf[srclen + maxlen + 2] ; + char dstbuf[dstlen + maxlen + 2] ; + memcpy(srcbuf, src, srclen) ; + memcpy(dstbuf, dst, dstlen) ; + srcbuf[srclen] = '/' ; + dstbuf[dstlen] = '/' ; + while (i < tmp->len) + { + size_t n = strlen(tmp->s + i) + 1 ; + memcpy(srcbuf + srclen + 1, tmp->s + i, n) ; + memcpy(dstbuf + dstlen + 1, tmp->s + i, n) ; + i += n ; + hiercopy_internal(srcbuf, dstbuf, tmp, 0) ; + } + } + if (chmod(dst, mode) < 0 && !(options & 1)) goto err ; + tmp->len = tmpbase ; + return 1 ; +err: + tmp->len = tmpbase ; + return 0 ; +} + +int hiercopy_internal (char const *src, char const *dst, stralloc *tmp, unsigned int options) +{ + struct stat st ; + if (lstat(src, &st) < 0) return 0 ; + if (S_ISREG(st.st_mode)) + { + if (!filecopy_unsafe(src, dst, st.st_mode)) return 0 ; + } + else if (S_ISDIR(st.st_mode)) + { + if (!dircopy(src, dst, st.st_mode, tmp, options)) return 0 ; + } + else if (S_ISFIFO(st.st_mode)) + { + if (mkfifo(dst, st.st_mode) < 0) return 0 ; + } + else if (S_ISLNK(st.st_mode)) + { + size_t tmpbase = tmp->len ; + if (sareadlink(tmp, src) < 0) return 0 ; + if (!stralloc_0(tmp) || symlink(tmp->s + tmpbase, dst) < 0) + { + tmp->len = tmpbase ; + return 0 ; + } + tmp->len = tmpbase ; + } + else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) || S_ISSOCK(st.st_mode)) + { + if (mknod(dst, st.st_mode, st.st_rdev) < 0) return 0 ; + } + else return (errno = ENOTSUP, 0) ; + lchown(dst, st.st_uid, st.st_gid) ; + if (!S_ISLNK(st.st_mode)) chmod(dst, st.st_mode) ; + return 1 ; +} diff --git a/src/libstddjb/hiercopy_loose.c b/src/libstddjb/hiercopy_loose.c new file mode 100644 index 0000000..38e47b5 --- /dev/null +++ b/src/libstddjb/hiercopy_loose.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/skamisc.h> +#include <skalibs/djbunix.h> + +int hiercopy_loose (char const *src, char const *dst) +{ + return hiercopy_internal(src, dst, &satmp, 1) ; +} diff --git a/src/libstddjb/hiercopy_loose_tmp.c b/src/libstddjb/hiercopy_loose_tmp.c new file mode 100644 index 0000000..81eae4a --- /dev/null +++ b/src/libstddjb/hiercopy_loose_tmp.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/djbunix.h> + +int hiercopy_loose_tmp (char const *src, char const *dst, stralloc *tmp) +{ + return hiercopy_internal(src, dst, tmp, 1) ; +} diff --git a/src/libstddjb/hiercopy_tmp.c b/src/libstddjb/hiercopy_tmp.c index 3e147be..c820f84 100644 --- a/src/libstddjb/hiercopy_tmp.c +++ b/src/libstddjb/hiercopy_tmp.c @@ -1,88 +1,8 @@ /* ISC license. */ -#include <string.h> -#include <unistd.h> -#include <sys/stat.h> -#include <errno.h> -#include <fcntl.h> - -#include <skalibs/stralloc.h> -#include <skalibs/direntry.h> #include <skalibs/djbunix.h> -static int dircopy (char const *src, char const *dst, mode_t mode, stralloc *tmp) -{ - size_t tmpbase = tmp->len ; - size_t maxlen = 0 ; - if (sals(src, tmp, &maxlen) == -1) return 0 ; - - if (mkdir(dst, S_IRWXU) < 0) - { - struct stat st ; - if (errno != EEXIST) goto err ; - if (stat(dst, &st) < 0) goto err ; - if (!S_ISDIR(st.st_mode)) { errno = ENOTDIR ; goto err ; } - } - { - size_t srclen = strlen(src) ; - size_t dstlen = strlen(dst) ; - size_t i = tmpbase ; - char srcbuf[srclen + maxlen + 2] ; - char dstbuf[dstlen + maxlen + 2] ; - memcpy(srcbuf, src, srclen) ; - memcpy(dstbuf, dst, dstlen) ; - srcbuf[srclen] = '/' ; - dstbuf[dstlen] = '/' ; - while (i < tmp->len) - { - size_t n = strlen(tmp->s + i) + 1 ; - memcpy(srcbuf + srclen + 1, tmp->s + i, n) ; - memcpy(dstbuf + dstlen + 1, tmp->s + i, n) ; - i += n ; - hiercopy_tmp(srcbuf, dstbuf, tmp) ; - } - } - if (chmod(dst, mode) < 0) goto err ; - tmp->len = tmpbase ; - return 1 ; -err: - tmp->len = tmpbase ; - return 0 ; -} - int hiercopy_tmp (char const *src, char const *dst, stralloc *tmp) { - struct stat st ; - if (lstat(src, &st) < 0) return 0 ; - if (S_ISREG(st.st_mode)) - { - if (!filecopy_unsafe(src, dst, st.st_mode)) return 0 ; - } - else if (S_ISDIR(st.st_mode)) - { - if (!dircopy(src, dst, st.st_mode, tmp)) return 0 ; - } - else if (S_ISFIFO(st.st_mode)) - { - if (mkfifo(dst, st.st_mode) < 0) return 0 ; - } - else if (S_ISLNK(st.st_mode)) - { - size_t tmpbase = tmp->len ; - if (sareadlink(tmp, src) < 0) return 0 ; - if (!stralloc_0(tmp) || symlink(tmp->s + tmpbase, dst) < 0) - { - tmp->len = tmpbase ; - return 0 ; - } - tmp->len = tmpbase ; - } - else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) || S_ISSOCK(st.st_mode)) - { - if (mknod(dst, st.st_mode, st.st_rdev) < 0) return 0 ; - } - else return (errno = ENOTSUP, 0) ; - lchown(dst, st.st_uid, st.st_gid) ; - if (!S_ISLNK(st.st_mode)) chmod(dst, st.st_mode) ; - return 1 ; + return hiercopy_internal(src, dst, tmp, 0) ; } |