/******************************************************/ /* tpax: a topological pax implementation */ /* Copyright (C) 2020 Z. Gilboa */ /* 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; }