diff options
author | midipix <writeonce@midipix.org> | 2024-06-06 21:11:11 +0000 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2024-06-06 23:39:26 +0000 |
commit | 37f51391c8888c7f84e27ec6995fda5dd3af49c3 (patch) | |
tree | f9c296dc28aaffbb9e2df29c87e86c4b46fef4f8 /src/logic/tpax_archive_write.c | |
parent | b8874b3e640e74ff287b64e969ce74aece65de10 (diff) | |
download | tpax-37f51391c8888c7f84e27ec6995fda5dd3af49c3.tar.bz2 tpax-37f51391c8888c7f84e27ec6995fda5dd3af49c3.tar.xz |
driver: implemented and integrated the -H (follow symlink args) cmdline option.
Diffstat (limited to 'src/logic/tpax_archive_write.c')
-rw-r--r-- | src/logic/tpax_archive_write.c | 52 |
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), |