diff options
-rw-r--r-- | include/tpax/tpax.h | 2 | ||||
-rw-r--r-- | src/internal/tpax_driver_impl.h | 1 | ||||
-rw-r--r-- | src/logic/tpax_archive_enqueue.c | 25 |
3 files changed, 23 insertions, 5 deletions
diff --git a/include/tpax/tpax.h b/include/tpax/tpax.h index fabcb7c..00271cb 100644 --- a/include/tpax/tpax.h +++ b/include/tpax/tpax.h @@ -60,6 +60,8 @@ extern "C" { #define TPAX_DRIVER_PAX_SYMLINK_ARGS 0x4000000 #define TPAX_DRIVER_PAX_SYMLINK_ITEMS 0x8000000 +#define TPAX_DRIVER_STRICT_DEVICE_ID 0X10000000 + /* error flags */ #define TPAX_ERROR_TOP_LEVEL 0x0001 #define TPAX_ERROR_NESTED 0x0002 diff --git a/src/internal/tpax_driver_impl.h b/src/internal/tpax_driver_impl.h index 7054dce..23e9e23 100644 --- a/src/internal/tpax_driver_impl.h +++ b/src/internal/tpax_driver_impl.h @@ -57,6 +57,7 @@ struct tpax_dirent { int fdat; int depth; int flags; + dev_t stdev; size_t nsize; const char * prefix; const struct tpax_dirent * parent; diff --git a/src/logic/tpax_archive_enqueue.c b/src/logic/tpax_archive_enqueue.c index 3afcb67..0d8c28f 100644 --- a/src/logic/tpax_archive_enqueue.c +++ b/src/logic/tpax_archive_enqueue.c @@ -192,6 +192,7 @@ static int tpax_archive_add_queue_item( const struct dirent * dirent, const struct tpax_dirent * parent, const char * prefix, + dev_t stdev, int depth, int flags, int fdat, @@ -231,6 +232,7 @@ static int tpax_archive_add_queue_item( cdent->fdat = fdat; cdent->depth = depth; cdent->flags = flags; + cdent->stdev = stdev; cdent->nsize = needed; cdent->parent = parent; cdent->prefix = prefix; @@ -272,6 +274,7 @@ static int tpax_archive_enqueue_dir_entries( int depth; bool fkeep; bool flinks; + bool fstdev; long nbytes; struct dirent * lnkent; struct dirent * dirent; @@ -316,8 +319,12 @@ static int tpax_archive_enqueue_dir_entries( lnkent = (struct dirent *)lnkbuf; flinks = (dctx->cctx->drvflags & TPAX_DRIVER_PAX_SYMLINK_ITEMS); + fstdev = (dctx->cctx->drvflags & TPAX_DRIVER_STRICT_DEVICE_ID); nbytes = tpax_getdents(fd,dirents,TPAX_DIRENT_BUFLEN); + /* debugging, struct stat initialization when fstdev is false */ + memset(&st,0,sizeof(st)); + while ((nbytes == -EINTR) || ((nbytes < 0) && (errno == EINTR))) nbytes = tpax_getdents(fd,dirents,TPAX_DIRENT_BUFLEN); @@ -344,11 +351,16 @@ static int tpax_archive_enqueue_dir_entries( if (S_ISDIR(st.st_mode)) { dirent->d_type = DT_DIR; } + } else if (fstdev) { + if (fstatat(fd,dirent->d_name,&st,AT_SYMLINK_NOFOLLOW)) + return tpax_archive_enqueue_ret( + TPAX_SYSTEM_ERROR(dctx), + uctx); } if (tpax_archive_add_queue_item( - dctx,dirent, - dent,0,depth, + dctx,dirent,dent,0, + st.st_dev,depth, TPAX_ITEM_IMPLICIT, fd,&fkeep) < 0) return tpax_archive_enqueue_ret( @@ -386,7 +398,8 @@ static int tpax_archive_enqueue_dir_entries( cdent->flags |= TPAX_ITEM_NAMEREF; if (tpax_archive_add_queue_item( - dctx,lnkent,cdent,0,depth+1, + dctx,lnkent,cdent,0, + lnkst.st_dev,depth+1, TPAX_ITEM_IMPLICIT|TPAX_ITEM_SYMLINK, fd,&fkeep) < 0) return tpax_archive_enqueue_ret( @@ -496,7 +509,8 @@ int tpax_archive_enqueue( /* add to queue */ if (tpax_archive_add_queue_item( - dctx,dirent,0,prefix,0, + dctx,dirent,0,prefix, + uctx->st->st_dev,0, TPAX_ITEM_EXPLICIT, fdat,&fkeep) < 0) return tpax_archive_enqueue_ret( @@ -528,7 +542,8 @@ int tpax_archive_enqueue( cdent->flags |= TPAX_ITEM_NAMEREF; if (tpax_archive_add_queue_item( - dctx,lnkent,cdent,0,1, + dctx,lnkent,cdent,0, + lnkst.st_dev,1, TPAX_ITEM_EXPLICIT|TPAX_ITEM_SYMLINK, fdat,&fkeep) < 0) return tpax_archive_enqueue_ret( |