Blame src/logic/tpax_queue_vector.c

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