diff --git a/include/tpax/tpax.h b/include/tpax/tpax.h index ad596c4..89c3bfc 100644 --- a/include/tpax/tpax.h +++ b/include/tpax/tpax.h @@ -157,9 +157,9 @@ tpax_api int tpax_archive_write (const struct tpax_driver_ctx *); tpax_api int tpax_archive_seal (const struct tpax_driver_ctx *); -/* helper api */ -tpax_api int tpax_path_copy (char *, const char *, size_t, uint32_t, size_t *); -tpax_api int tpax_stat_compare (const struct stat *, const struct stat *); +/* utility helper interfaces */ +tpax_api int tpax_util_path_copy (char *, const char *, size_t, uint32_t, size_t *); +tpax_api int tpax_util_stat_compare (const struct stat *, const struct stat *); /* utility api */ tpax_api int tpax_main (char **, char **, diff --git a/project/common.mk b/project/common.mk index e569cbd..637c282 100644 --- a/project/common.mk +++ b/project/common.mk @@ -2,8 +2,6 @@ API_SRCS = \ src/driver/tpax_amain.c \ src/driver/tpax_driver_ctx.c \ src/driver/tpax_unit_ctx.c \ - src/helper/tpax_path_copy.c \ - src/helper/tpax_stat_compare.c \ src/logic/tpax_archive_append.c \ src/logic/tpax_archive_write.c \ src/logic/tpax_init_ustar_header.c \ @@ -12,6 +10,8 @@ API_SRCS = \ src/logic/tpax_queue_vector.c \ src/output/tpax_output_error.c \ src/skin/tpax_skin_default.c \ + src/util/tpax_path_copy.c \ + src/util/tpax_stat_compare.c \ INTERNAL_SRCS = \ src/internal/$(PACKAGE)_dprintf_impl.c \ diff --git a/project/tree.mk b/project/tree.mk index 548db6f..2f68c9e 100644 --- a/project/tree.mk +++ b/project/tree.mk @@ -1,10 +1,10 @@ TREE_DIRS = bin lib src \ src/driver \ - src/helper \ src/internal \ src/logic \ src/output \ src/skin \ + src/util \ tree.tag: mkdir -p $(TREE_DIRS) diff --git a/src/helper/tpax_path_copy.c b/src/helper/tpax_path_copy.c deleted file mode 100644 index 084cc73..0000000 --- a/src/helper/tpax_path_copy.c +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************/ -/* tpax: a topological pax implementation */ -/* Copyright (C) 2020--2024 SysDeer Technologies, LLC */ -/* Released under GPLv2 and GPLv3; see COPYING.TPAX. */ -/**************************************************************/ - -#include -#include -#include -#include -#include - -#include -#include "tpax_driver_impl.h" - -int tpax_path_copy( - char * dstpath, - const char * srcpath, - size_t bufsize, - uint32_t flags, - size_t * nwritten) -{ - const char * src; - char * dst; - char * cap; - - if (!bufsize) { - errno = ENOBUFS; - return -1; - } - - src = srcpath; - dst = dstpath; - cap = &dst[bufsize]; - - if ((src[0] == '/') && (src[1] == '/') && (src[2] != '/')) { - *dst++ = *src++; - *dst++ = *src++; - } - - if (flags & TPAX_DRIVER_PURE_PATH_OUTPUT) - if ((src[0] == '.') && (src[1] == '/')) - for (++src; *src=='/'; src++) - (void)0; - - for (; *src; ) { - if ((src[0] == '.') && (src[1] == '.')) { - if ((src[2] == '/') || (src[2] == '\0')) { - if (flags & TPAX_DRIVER_STRICT_PATH_INPUT) { - errno = EINVAL; - return -1; - } - } - } - - if (flags & TPAX_DRIVER_PURE_PATH_OUTPUT) { - if ((src[0] == '.') && (src[1] == '/') && (src[-1] == '/')) { - for (++src; *src=='/'; src++) - (void)0; - - } else if ((src[0] == '/')) { - for (src++; *src=='/'; src++) - (void)0; - - *dst++ = '/'; - - } else { - *dst++ = *src++; - } - } else { - *dst++ = *src++; - } - - if (dst == cap) { - errno = ENOBUFS; - return -1; - } - } - - if (nwritten) - *nwritten = dst - dstpath; - - *dst = '\0'; - - return 0; -} diff --git a/src/helper/tpax_stat_compare.c b/src/helper/tpax_stat_compare.c deleted file mode 100644 index 398e45c..0000000 --- a/src/helper/tpax_stat_compare.c +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************/ -/* tpax: a topological pax implementation */ -/* Copyright (C) 2020--2024 SysDeer Technologies, LLC */ -/* Released under GPLv2 and GPLv3; see COPYING.TPAX. */ -/**************************************************************/ - -#include -#include -#include -#include -#include - -#include -#include "tpax_driver_impl.h" - -#define TPAX_STAT_COMPARE(member) \ - if (src -> member - dst -> member) \ - return (src -> member > dst -> member) \ - ? (1) : (-1) - -int tpax_stat_compare( - const struct stat * src, - const struct stat * dst) -{ - TPAX_STAT_COMPARE(st_dev); - TPAX_STAT_COMPARE(st_ino); - - TPAX_STAT_COMPARE(st_mode); - TPAX_STAT_COMPARE(st_uid); - TPAX_STAT_COMPARE(st_gid); - - TPAX_STAT_COMPARE(st_rdev); - TPAX_STAT_COMPARE(st_size); - TPAX_STAT_COMPARE(st_blksize); - TPAX_STAT_COMPARE(st_blocks); - - TPAX_STAT_COMPARE(st_mtim.tv_sec); - TPAX_STAT_COMPARE(st_mtim.tv_nsec); - - return 0; -} diff --git a/src/logic/tpax_file_create_memory_snapshot.c b/src/logic/tpax_file_create_memory_snapshot.c index 0cd0f0c..504a4a1 100644 --- a/src/logic/tpax_file_create_memory_snapshot.c +++ b/src/logic/tpax_file_create_memory_snapshot.c @@ -53,7 +53,7 @@ int tpax_file_create_memory_snapshot( close(fd); return TPAX_SYSTEM_ERROR(dctx); - } else if (tpax_stat_compare(srcst,&dstst)) { + } else if (tpax_util_stat_compare(srcst,&dstst)) { close(fd); return TPAX_CUSTOM_ERROR(dctx,TPAX_ERR_FILE_CHANGED); } @@ -86,7 +86,7 @@ int tpax_file_create_memory_snapshot( close(fd); return TPAX_SYSTEM_ERROR(dctx); - } else if (tpax_stat_compare(srcst,&dstst)) { + } else if (tpax_util_stat_compare(srcst,&dstst)) { close(fd); return TPAX_CUSTOM_ERROR(dctx,TPAX_ERR_FILE_CHANGED); } diff --git a/src/logic/tpax_file_create_tmpfs_snapshot.c b/src/logic/tpax_file_create_tmpfs_snapshot.c index 5939ff4..2e92211 100644 --- a/src/logic/tpax_file_create_tmpfs_snapshot.c +++ b/src/logic/tpax_file_create_tmpfs_snapshot.c @@ -64,7 +64,7 @@ int tpax_file_create_tmpfs_snapshot( close(fdtmp); return TPAX_SYSTEM_ERROR(dctx); - } else if (tpax_stat_compare(srcst,&dstst)) { + } else if (tpax_util_stat_compare(srcst,&dstst)) { close(fdsrc); close(fdtmp); return TPAX_CUSTOM_ERROR(dctx,TPAX_ERR_FILE_CHANGED); @@ -114,7 +114,7 @@ int tpax_file_create_tmpfs_snapshot( close(fdtmp); return TPAX_SYSTEM_ERROR(dctx); - } else if (tpax_stat_compare(srcst,&dstst)) { + } else if (tpax_util_stat_compare(srcst,&dstst)) { close(fdsrc); close(fdtmp); return TPAX_CUSTOM_ERROR(dctx,TPAX_ERR_FILE_CHANGED); diff --git a/src/util/tpax_path_copy.c b/src/util/tpax_path_copy.c new file mode 100644 index 0000000..046ddde --- /dev/null +++ b/src/util/tpax_path_copy.c @@ -0,0 +1,86 @@ +/**************************************************************/ +/* tpax: a topological pax implementation */ +/* Copyright (C) 2020--2024 SysDeer Technologies, LLC */ +/* Released under GPLv2 and GPLv3; see COPYING.TPAX. */ +/**************************************************************/ + +#include +#include +#include +#include +#include + +#include +#include "tpax_driver_impl.h" + +int tpax_util_path_copy( + char * dstpath, + const char * srcpath, + size_t bufsize, + uint32_t flags, + size_t * nwritten) +{ + const char * src; + char * dst; + char * cap; + + if (!bufsize) { + errno = ENOBUFS; + return -1; + } + + src = srcpath; + dst = dstpath; + cap = &dst[bufsize]; + + if ((src[0] == '/') && (src[1] == '/') && (src[2] != '/')) { + *dst++ = *src++; + *dst++ = *src++; + } + + if (flags & TPAX_DRIVER_PURE_PATH_OUTPUT) + if ((src[0] == '.') && (src[1] == '/')) + for (++src; *src=='/'; src++) + (void)0; + + for (; *src; ) { + if ((src[0] == '.') && (src[1] == '.')) { + if ((src[2] == '/') || (src[2] == '\0')) { + if (flags & TPAX_DRIVER_STRICT_PATH_INPUT) { + errno = EINVAL; + return -1; + } + } + } + + if (flags & TPAX_DRIVER_PURE_PATH_OUTPUT) { + if ((src[0] == '.') && (src[1] == '/') && (src[-1] == '/')) { + for (++src; *src=='/'; src++) + (void)0; + + } else if ((src[0] == '/')) { + for (src++; *src=='/'; src++) + (void)0; + + *dst++ = '/'; + + } else { + *dst++ = *src++; + } + } else { + *dst++ = *src++; + } + + if (dst == cap) { + errno = ENOBUFS; + return -1; + } + } + + if (nwritten) + *nwritten = dst - dstpath; + + *dst = '\0'; + + return 0; +} diff --git a/src/util/tpax_stat_compare.c b/src/util/tpax_stat_compare.c new file mode 100644 index 0000000..2de6922 --- /dev/null +++ b/src/util/tpax_stat_compare.c @@ -0,0 +1,41 @@ +/**************************************************************/ +/* tpax: a topological pax implementation */ +/* Copyright (C) 2020--2024 SysDeer Technologies, LLC */ +/* Released under GPLv2 and GPLv3; see COPYING.TPAX. */ +/**************************************************************/ + +#include +#include +#include +#include +#include + +#include +#include "tpax_driver_impl.h" + +#define TPAX_STAT_COMPARE(member) \ + if (src -> member - dst -> member) \ + return (src -> member > dst -> member) \ + ? (1) : (-1) + +int tpax_util_stat_compare( + const struct stat * src, + const struct stat * dst) +{ + TPAX_STAT_COMPARE(st_dev); + TPAX_STAT_COMPARE(st_ino); + + TPAX_STAT_COMPARE(st_mode); + TPAX_STAT_COMPARE(st_uid); + TPAX_STAT_COMPARE(st_gid); + + TPAX_STAT_COMPARE(st_rdev); + TPAX_STAT_COMPARE(st_size); + TPAX_STAT_COMPARE(st_blksize); + TPAX_STAT_COMPARE(st_blocks); + + TPAX_STAT_COMPARE(st_mtim.tv_sec); + TPAX_STAT_COMPARE(st_mtim.tv_nsec); + + return 0; +}