/**************************************************************/ /* tpax: a topological pax implementation */ /* Copyright (C) 2020--2024 SysDeer Technologies, LLC */ /* Released under GPLv2 and GPLv3; see COPYING.TPAX. */ /**************************************************************/ #include #include #include #include "tpax_driver_impl.h" #include "tpax_errinfo_impl.h" #include "tpax_visibility_impl.h" #define TPAX_MAX_DEPTH 512 tpax_hidden const char * tpax_queue_item_full_path( const struct tpax_driver_ctx * dctx, const struct tpax_dirent * cdent) { char * ch; char * pathbuf; const struct tpax_dirent * pparent; const struct tpax_dirent ** pdirent; const struct tpax_dirent * dirstck[TPAX_MAX_DEPTH]; if (cdent->depth >= TPAX_MAX_DEPTH) return 0; ch = pathbuf = (tpax_get_driver_ictx(dctx))->dirbuff; for (pparent=cdent,pdirent=dirstck; pparent; pparent=pparent->parent) *pdirent++ = pparent; *pdirent-- = 0; if (pdirent[0]->prefix) ch += sprintf(ch,"%s",pdirent[0]->prefix); for (; pdirent > dirstck; ) { if (!(pdirent[0]->flags & TPAX_ITEM_SYMLINK)) ch += sprintf(ch,"%s/",pdirent[0]->dirent.d_name); pdirent--; } if (pdirent[0]->flags & TPAX_ITEM_SYMLINK) { *--ch = '\0'; } else { sprintf(ch,"%s",pdirent[0]->dirent.d_name); } return pathbuf; } tpax_hidden int tpax_update_queue_vector(const struct tpax_driver_ctx * dctx) { uintptr_t addr; struct tpax_driver_ctx_impl * ictx; struct tpax_dirent_buffer * dentbuf; struct tpax_dirent ** direntv; struct tpax_dirent * cdent; struct tpax_dirent * cnext; size_t arrsize; /* driver */ ictx = tpax_get_driver_ictx(dctx); /* vector alloc */ if (ictx->direntv) free(ictx->direntv); arrsize = ictx->nqueued + 1; if (!(ictx->direntv = calloc(arrsize,sizeof(struct tpax_dirent *)))) return TPAX_SYSTEM_ERROR(dctx); if (ictx->nqueued == 0) return 0; /* queue vector */ dentbuf = tpax_get_driver_dirents(dctx); cdent = dentbuf->dbuf; for (direntv=ictx->direntv; cdent; direntv++) { *direntv = cdent; addr = (uintptr_t)cdent; addr += cdent->nsize; cnext = (struct tpax_dirent *)addr; if (cnext == dentbuf->cdent) { dentbuf = dentbuf->next; cnext = dentbuf ? dentbuf->dbuf : 0; } cdent = cnext; } return 0; }