/**************************************************************/ /* tpax: a topological pax implementation */ /* Copyright (C) 2020--2024 SysDeer Technologies, LLC */ /* Released under GPLv2 and GPLv3; see COPYING.TPAX. */ /**************************************************************/ #ifndef TPAX_DRIVER_IMPL_H #define TPAX_DRIVER_IMPL_H #include #include #include #include #include #include #include #include #include "tpax_dprintf_impl.h" #include "argv/argv.h" #define TPAX_OPTV_ELEMENTS 64 #define TPAX_DIRENT_BUFLEN 65536 #define TPAX_FILEIO_BUFLEN (4096 * 1024) #define TPAX_DRIVER_EXEC_MODE_WRITE_COPY \ (TPAX_DRIVER_EXEC_MODE_WRITE | \ TPAX_DRIVER_EXEC_MODE_COPY) #define TPAX_ITEM_EXPLICIT 0X1 #define TPAX_ITEM_IMPLICIT 0X2 #define TPAX_ITEM_SYMLINK 0X4 #define TPAX_ITEM_NAMEREF 0x8 #define TPAX_REPL_GLOBAL 0x01 #define TPAX_REPL_PRINT 0x02 extern const struct argv_option tpax_default_options[]; enum app_tags { TAG_HELP, TAG_VERSION, TAG_VERBOSE, TAG_LIST, TAG_READ, TAG_WRITE, TAG_COPY, TAG_FILE, TAG_FORMAT, TAG_BLKSIZE, TAG_OPTIONS, TAG_REPLSTR, TAG_RECURSE, TAG_NORECURSE, TAG_STRICT_PATH, TAG_PURE_PATH, TAG_PRESERVE_ATIME, TAG_PAX_SYMLINK_ARGS, TAG_PAX_SYMLINK_ITEMS, TAG_STRICT_DEVICE_ID, }; struct tpax_dirent { int fdat; int depth; int flags; dev_t srdev; dev_t stdev; ino_t stino; size_t nsize; const char * prefix; const struct tpax_dirent * parent; struct dirent dirent; }; struct tpax_dirent_buffer { struct tpax_dirent_buffer * next; size_t size; size_t nfree; struct tpax_dirent * cdent; struct tpax_dirent dbuf[]; }; struct tpax_replstr { const char * replarg; const char * replstr; const char * regexp; regex_t regex; uint32_t flags; }; struct tpax_driver_ctx_impl { const char * file; struct tpax_common_ctx cctx; struct tpax_driver_ctx ctx; struct tpax_fd_ctx fdctx; const struct tpax_unit_ctx * euctx; const char * eunit; struct argv_keyval ** keyvalv; struct tpax_replstr * replstrv; char * replstrs; struct tpax_error_info ** errinfp; struct tpax_error_info ** erricap; struct tpax_error_info * erriptr[64]; struct tpax_error_info erribuf[64]; char ** prefixv; char ** prefixp; char ** prefcap; char * prefptr[64]; struct tpax_dirent ** direntv; struct tpax_dirent_buffer * dirents; struct tpax_dirent * dirmark; void * dirbuff; void * bufaddr; size_t bufsize; size_t nqueued; 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]; size_t hdrbuf[]; }; static inline struct tpax_driver_ctx_impl * tpax_get_driver_ictx( const struct tpax_driver_ctx * dctx) { uintptr_t addr; if (dctx) { addr = (uintptr_t)dctx - offsetof(struct tpax_driver_ctx_impl,ctx); return (struct tpax_driver_ctx_impl *)addr; } 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) { struct tpax_driver_ctx_impl * ictx = tpax_get_driver_ictx(dctx); *size = ictx->bufsize; return ictx->bufaddr; } static inline void * tpax_get_driver_getdents_buffer( const struct tpax_driver_ctx * dctx) { struct tpax_driver_ctx_impl * ictx = tpax_get_driver_ictx(dctx); return ictx->dirbuff; } static inline void tpax_driver_set_ectx( const struct tpax_driver_ctx * dctx, const struct tpax_unit_ctx * uctx, const char * unit) { struct tpax_driver_ctx_impl * ictx; ictx = tpax_get_driver_ictx(dctx); ictx->euctx = uctx; ictx->eunit = unit; } static inline int tpax_driver_fdin(const struct tpax_driver_ctx * dctx) { struct tpax_fd_ctx fdctx; tpax_lib_get_driver_fdctx(dctx,&fdctx); return fdctx.fdin; } static inline int tpax_driver_fdout(const struct tpax_driver_ctx * dctx) { struct tpax_fd_ctx fdctx; tpax_lib_get_driver_fdctx(dctx,&fdctx); return fdctx.fdout; } static inline int tpax_driver_fderr(const struct tpax_driver_ctx * dctx) { struct tpax_fd_ctx fdctx; tpax_lib_get_driver_fdctx(dctx,&fdctx); return fdctx.fderr; } static inline int tpax_driver_fdlog(const struct tpax_driver_ctx * dctx) { struct tpax_fd_ctx fdctx; tpax_lib_get_driver_fdctx(dctx,&fdctx); return fdctx.fdlog; } static inline int tpax_driver_fdcwd(const struct tpax_driver_ctx * dctx) { struct tpax_fd_ctx fdctx; tpax_lib_get_driver_fdctx(dctx,&fdctx); return fdctx.fdcwd; } static inline int tpax_driver_fddst(const struct tpax_driver_ctx * dctx) { struct tpax_fd_ctx fdctx; tpax_lib_get_driver_fdctx(dctx,&fdctx); 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 struct tpax_dirent_buffer * tpax_get_driver_dirents(const struct tpax_driver_ctx * dctx) { struct tpax_driver_ctx_impl * ictx; ictx = tpax_get_driver_ictx(dctx); return ictx->dirents; } static inline struct tpax_dirent * tpax_get_driver_dirmark(const struct tpax_driver_ctx * dctx) { struct tpax_driver_ctx_impl * ictx; ictx = tpax_get_driver_ictx(dctx); return ictx->dirmark; } static inline void tpax_set_driver_dirmark(const struct tpax_driver_ctx * dctx, struct tpax_dirent * dirent) { struct tpax_driver_ctx_impl * ictx; ictx = tpax_get_driver_ictx(dctx); ictx->dirmark = dirent; ictx->nqueued++; } 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; } int tpax_update_queue_vector(const struct tpax_driver_ctx * dctx); const char * tpax_queue_item_full_path( const struct tpax_driver_ctx *, const struct tpax_dirent *); #endif