commit d0b38944c50dab81755fca50a983a1bddefbfadf
parent 96078d63fcd4acd96983a42abac5ab8604bc80ca
Author: Laurent Bercot <ska-skaware@skarnet.org>
Date: Thu, 1 Jun 2023 03:46:48 +0000
Refactor to add hiercopy_loose (for s6-l-i)
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat:
7 files changed, 114 insertions(+), 84 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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) ;
}