summaryrefslogtreecommitdiffhomepage
path: root/src/logic/tpax_archive_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/logic/tpax_archive_write.c')
-rw-r--r--src/logic/tpax_archive_write.c52
1 files changed, 50 insertions, 2 deletions
diff --git a/src/logic/tpax_archive_write.c b/src/logic/tpax_archive_write.c
index 1a641bf..98d7dfc 100644
--- a/src/logic/tpax_archive_write.c
+++ b/src/logic/tpax_archive_write.c
@@ -80,8 +80,10 @@ static int tpax_archive_write_impl(
struct tpax_unit_ctx * uctx;
struct tpax_ustar_header uhdr;
const struct stat * st;
+ struct stat stbuf;
const char * path;
const char * slnk;
+ const char * mlnk;
off_t hpos;
off_t dpos;
int fdtmp;
@@ -91,6 +93,12 @@ static int tpax_archive_write_impl(
size_t buflen;
size_t cmplen;
void * membuf;
+ char * ch;
+ char pathbuf[PATH_MAX];
+
+ /* followed symlink? */
+ if (cdent->flags & TPAX_ITEM_NAMEREF)
+ return 0;
/* full path */
if (!(path = tpax_queue_item_full_path(dctx,cdent)))
@@ -104,6 +112,44 @@ static int tpax_archive_write_impl(
st = uctx->st;
slnk = uctx->link[0];
+ mlnk = 0;
+
+ if (cdent->flags & TPAX_ITEM_SYMLINK) {
+ st = &stbuf;
+ mlnk = slnk;
+ slnk = 0;
+ ch = 0;
+
+ if (mlnk[0] != '/') {
+ if (strlen(path) >= PATH_MAX)
+ return tpax_archive_write_ret(
+ TPAX_CUSTOM_ERROR(
+ dctx,
+ TPAX_ERR_FLOW_ERROR),
+ uctx);
+
+ strcpy(pathbuf,path);
+
+ ch = strrchr(pathbuf,'/');
+ }
+
+ if (ch && (++ch - pathbuf >= PATH_MAX))
+ return tpax_archive_write_ret(
+ TPAX_CUSTOM_ERROR(
+ dctx,
+ TPAX_ERR_FLOW_ERROR),
+ uctx);
+
+ if (ch) {
+ strcpy(ch,mlnk);
+ mlnk = pathbuf;
+ }
+
+ if (fstatat(fdcwd,mlnk,&stbuf,0) < 0)
+ return tpax_archive_write_ret(
+ TPAX_SYSTEM_ERROR(dctx),
+ uctx);
+ }
/* record errors */
tpax_driver_set_ectx(
@@ -136,14 +182,16 @@ static int tpax_archive_write_impl(
/* snapshot */
if (membuf) {
if (tpax_io_create_memory_snapshot(
- dctx,fdcwd,path,
+ dctx,fdcwd,
+ mlnk ? mlnk : path,
st,membuf) < 0)
return tpax_archive_write_ret(
TPAX_NESTED_ERROR(dctx),
uctx);
} else {
if ((fdtmp = tpax_io_create_tmpfs_snapshot(
- dctx,fdcwd,path,
+ dctx,fdcwd,
+ mlnk ? mlnk : path,
st)) < 0)
return tpax_archive_write_ret(
TPAX_NESTED_ERROR(dctx),