blob: cae4da0954680a7ac4f40ebc755ab20eb75d0d0b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
/**************************************************************/
/* tpax: a topological pax implementation */
/* Copyright (C) 2020--2024 SysDeer Technologies, LLC */
/* Released under GPLv2 and GPLv3; see COPYING.TPAX. */
/**************************************************************/
#include <stdint.h>
#include <stdlib.h>
#include <tpax/tpax.h>
#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;
}
|