summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/tpax/tpax.h1
-rw-r--r--project/common.mk1
-rw-r--r--project/tree.mk1
-rw-r--r--src/helper/tpax_path_copy.c86
4 files changed, 89 insertions, 0 deletions
diff --git a/include/tpax/tpax.h b/include/tpax/tpax.h
index 059dbac..5281ea1 100644
--- a/include/tpax/tpax.h
+++ b/include/tpax/tpax.h
@@ -147,6 +147,7 @@ tpax_api int tpax_set_driver_fdctx (struct tpax_driver_ctx *, const struct
/* core api */
/* helper api */
+tpax_api int tpax_path_copy (char *, const char *, size_t, uint32_t, size_t *);
/* utility api */
tpax_api int tpax_main (char **, char **,
diff --git a/project/common.mk b/project/common.mk
index 54f7d11..ca6bc81 100644
--- a/project/common.mk
+++ b/project/common.mk
@@ -2,6 +2,7 @@ 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/logic/tpax_init_ustar_header.c \
src/output/tpax_output_error.c \
src/skin/tpax_skin_default.c \
diff --git a/project/tree.mk b/project/tree.mk
index ab26f1e..548db6f 100644
--- a/project/tree.mk
+++ b/project/tree.mk
@@ -1,5 +1,6 @@
TREE_DIRS = bin lib src \
src/driver \
+ src/helper \
src/internal \
src/logic \
src/output \
diff --git a/src/helper/tpax_path_copy.c b/src/helper/tpax_path_copy.c
new file mode 100644
index 0000000..0df6c17
--- /dev/null
+++ b/src/helper/tpax_path_copy.c
@@ -0,0 +1,86 @@
+/******************************************************/
+/* tpax: a topological pax implementation */
+/* Copyright (C) 2020 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.TPAX. */
+/******************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <tpax/tpax.h>
+#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;
+}