diff options
author | midipix <writeonce@midipix.org> | 2020-05-23 00:19:30 -0400 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2020-05-23 05:59:02 +0000 |
commit | 409008f8960e24f5f2b25a84642cbb0c043f0ab9 (patch) | |
tree | b99fa246b6564699dd8959c28fb34f0193bed5a0 /src | |
parent | 3db88843a12dfc0a523a1cf11d9efb5f4f3dd63f (diff) | |
download | tpax-409008f8960e24f5f2b25a84642cbb0c043f0ab9.tar.bz2 tpax-409008f8960e24f5f2b25a84642cbb0c043f0ab9.tar.xz |
library api: tpax_archive_seal(): initial implementation and integration.
Diffstat (limited to 'src')
-rw-r--r-- | src/internal/tpax_driver_impl.h | 74 | ||||
-rw-r--r-- | src/logic/tpax_archive_append.c | 69 |
2 files changed, 138 insertions, 5 deletions
diff --git a/src/internal/tpax_driver_impl.h b/src/internal/tpax_driver_impl.h index 7e610d0..4003305 100644 --- a/src/internal/tpax_driver_impl.h +++ b/src/internal/tpax_driver_impl.h @@ -52,12 +52,15 @@ struct tpax_driver_ctx_impl { struct tpax_error_info erribuf[64]; void * bufaddr; size_t bufsize; + off_t cpos; }; struct tpax_unit_ctx_impl { const char * path; struct tpax_unit_ctx uctx; struct stat st; + off_t hpos; + off_t dpos; const char * link; char linkbuf[1024]; union { @@ -80,6 +83,17 @@ static inline struct tpax_driver_ctx_impl * tpax_get_driver_ictx( return 0; } +static inline struct tpax_unit_ctx_impl * tpax_get_unit_ictx( + const struct tpax_unit_ctx * uctx) +{ + struct tpax_unit_ctx_impl * ictx; + uintptr_t addr; + + addr = (uintptr_t)uctx - offsetof(struct tpax_unit_ctx_impl,uctx); + ictx = (struct tpax_unit_ctx_impl *)addr; + return ictx; +} + static inline void * tpax_get_driver_anon_map_addr( const struct tpax_driver_ctx * dctx, size_t * size) @@ -143,4 +157,64 @@ static inline int tpax_driver_fddst(const struct tpax_driver_ctx * dctx) return fdctx.fddst; } +static inline off_t tpax_get_driver_cpos(const struct tpax_driver_ctx * dctx) +{ + struct tpax_driver_ctx_impl * ictx; + ictx = tpax_get_driver_ictx(dctx); + return ictx->cpos; +} + +static inline void tpax_set_driver_cpos(const struct tpax_driver_ctx * dctx, off_t cpos) +{ + struct tpax_driver_ctx_impl * ictx; + ictx = tpax_get_driver_ictx(dctx); + ictx->cpos = cpos; +} + +static inline off_t tpax_get_unit_hpos(const struct tpax_unit_ctx * uctx) +{ + struct tpax_unit_ctx_impl * ictx; + ictx = tpax_get_unit_ictx(uctx); + return ictx->hpos; +} + +static inline void tpax_set_unit_hpos(const struct tpax_unit_ctx * uctx, off_t hpos) +{ + struct tpax_unit_ctx_impl * ictx; + ictx = tpax_get_unit_ictx(uctx); + ictx->hpos = hpos; +} + +static inline off_t tpax_get_unit_dpos(const struct tpax_unit_ctx * uctx) +{ + struct tpax_unit_ctx_impl * ictx; + ictx = tpax_get_unit_ictx(uctx); + return ictx->dpos; +} + +static inline void tpax_set_unit_dpos(const struct tpax_unit_ctx * uctx, off_t dpos) +{ + struct tpax_unit_ctx_impl * ictx; + ictx = tpax_get_unit_ictx(uctx); + ictx->dpos = dpos; +} + +static inline ssize_t tpax_get_archive_block_size(const struct tpax_driver_ctx * dctx) +{ + if (dctx->cctx->drvflags & TPAX_DRIVER_WRITE_FORMAT_PAX) + return TPAX_PAX_BLOCK_SIZE; + + else if (dctx->cctx->drvflags & TPAX_DRIVER_WRITE_FORMAT_CPIO) + return TPAX_CPIO_BLOCK_SIZE; + + else if (dctx->cctx->drvflags & TPAX_DRIVER_WRITE_FORMAT_USTAR) + return TPAX_USTAR_BLOCK_SIZE; + + else if (dctx->cctx->drvflags & TPAX_DRIVER_WRITE_FORMAT_RUSTAR) + return TPAX_USTAR_BLOCK_SIZE; + + else + return 0; +} + #endif diff --git a/src/logic/tpax_archive_append.c b/src/logic/tpax_archive_append.c index ce357b5..dfdd92c 100644 --- a/src/logic/tpax_archive_append.c +++ b/src/logic/tpax_archive_append.c @@ -1,3 +1,4 @@ + /******************************************************/ /* tpax: a topological pax implementation */ /* Copyright (C) 2020 Z. Gilboa */ @@ -48,9 +49,12 @@ static int tpax_archive_append_memory_data( } static int tpax_archive_append_pad( - int fdout, - const struct stat * st) + const struct tpax_driver_ctx * dctx, + int fdout, + const struct stat * st) { + int ret; + off_t cpos; ssize_t nbytes; char buf[512]; @@ -62,8 +66,13 @@ static int tpax_archive_append_pad( memset(buf,0,nbytes); - return tpax_archive_append_memory_data( - fdout,buf,nbytes); + cpos = tpax_get_driver_cpos(dctx); + cpos += st->st_size + nbytes; + + if (!(ret = tpax_archive_append_memory_data(fdout,buf,nbytes))) + tpax_set_driver_cpos(dctx,cpos); + + return ret; } int tpax_archive_append( @@ -71,6 +80,8 @@ int tpax_archive_append( const struct tpax_unit_ctx * uctx) { struct tpax_ustar_header uhdr; + off_t hpos; + off_t dpos; int fdout; int fdtmp; ssize_t nread; @@ -89,6 +100,10 @@ int tpax_archive_append( /* driver */ fdout = tpax_driver_fdout(dctx); + /* header and data offsets: todo pax and cpio */ + hpos = tpax_get_driver_cpos(dctx); + dpos = hpos + sizeof(uhdr); + /* header */ if (tpax_init_ustar_header( dctx,*uctx->path,uctx->st, @@ -130,6 +145,8 @@ int tpax_archive_append( return TPAX_SYSTEM_ERROR(dctx); } + tpax_set_driver_cpos(dctx,dpos); + /* append data from snapshot */ if (fdtmp >= 0) { if (!buf) { @@ -170,5 +187,47 @@ int tpax_archive_append( } return tpax_archive_append_pad( - fdout,uctx->st); + dctx,fdout,uctx->st); +} + +int tpax_archive_seal(const struct tpax_driver_ctx * dctx) +{ + int fdout; + off_t cpos; + ssize_t nbytes; + ssize_t nwritten; + ssize_t blksize; + char buf[512]; + + blksize = tpax_get_archive_block_size(dctx); + cpos = tpax_get_driver_cpos(dctx); + + if (cpos % 512) + return TPAX_CUSTOM_ERROR(dctx,TPAX_ERR_FLOW_ERROR); + + fdout = tpax_driver_fdout(dctx); + memset(buf,0,sizeof(buf)); + + switch (cpos % blksize) { + case 0: + nbytes = cpos + blksize; + break; + + default: + nbytes = cpos / blksize; + nbytes *= blksize; + nbytes += blksize; + + if (nbytes-cpos == 512) + nbytes += blksize; + } + + for (nwritten=cpos; nwritten<nbytes; nwritten+=512) { + if (tpax_archive_append_memory_data(fdout,buf,512) < 0) + return TPAX_SYSTEM_ERROR(dctx); + + tpax_set_driver_cpos(dctx,nwritten); + } + + return 0; } |