|
|
5874a9 |
/**************************************************************/
|
|
|
5874a9 |
/* tpax: a topological pax implementation */
|
|
|
bef28d |
/* Copyright (C) 2020--2024 SysDeer Technologies, LLC */
|
|
|
5874a9 |
/* Released under GPLv2 and GPLv3; see COPYING.TPAX. */
|
|
|
5874a9 |
/**************************************************************/
|
|
|
88751e |
|
|
|
88751e |
#ifndef TPAX_DRIVER_IMPL_H
|
|
|
88751e |
#define TPAX_DRIVER_IMPL_H
|
|
|
88751e |
|
|
|
88751e |
#include <stdint.h>
|
|
|
d7918a |
#include <dirent.h>
|
|
|
88751e |
#include <stdio.h>
|
|
|
239ac5 |
#include <sys/stat.h>
|
|
|
88751e |
#include <sys/types.h>
|
|
|
88751e |
|
|
|
88751e |
#include <tpax/tpax.h>
|
|
|
239ac5 |
#include <tpax/tpax_specs.h>
|
|
|
88751e |
#include "tpax_dprintf_impl.h"
|
|
|
88751e |
#include "argv/argv.h"
|
|
|
88751e |
|
|
|
88751e |
#define TPAX_OPTV_ELEMENTS 64
|
|
|
d7918a |
#define TPAX_DIRENT_BUFLEN 65536
|
|
|
b6c5aa |
#define TPAX_FILEIO_BUFLEN (4096 * 1024)
|
|
|
88751e |
|
|
|
239ac5 |
#define TPAX_DRIVER_EXEC_MODE_WRITE_COPY \
|
|
|
239ac5 |
(TPAX_DRIVER_EXEC_MODE_WRITE | \
|
|
|
239ac5 |
TPAX_DRIVER_EXEC_MODE_COPY)
|
|
|
239ac5 |
|
|
|
9f55a1 |
#define TPAX_ITEM_EXPLICIT 0X1
|
|
|
9f55a1 |
#define TPAX_ITEM_IMPLICIT 0X2
|
|
|
9f55a1 |
|
|
|
88751e |
extern const struct argv_option tpax_default_options[];
|
|
|
88751e |
|
|
|
88751e |
enum app_tags {
|
|
|
88751e |
TAG_HELP,
|
|
|
88751e |
TAG_VERSION,
|
|
|
893ea2 |
TAG_LIST,
|
|
|
893ea2 |
TAG_READ,
|
|
|
893ea2 |
TAG_WRITE,
|
|
|
893ea2 |
TAG_COPY,
|
|
|
8aa3fc |
TAG_FORMAT,
|
|
|
54c29f |
TAG_BLKSIZE,
|
|
|
23fa88 |
TAG_RECURSE,
|
|
|
23fa88 |
TAG_NORECURSE,
|
|
|
efbaf8 |
TAG_STRICT_PATH,
|
|
|
efbaf8 |
TAG_PURE_PATH,
|
|
|
88751e |
};
|
|
|
88751e |
|
|
|
d7918a |
struct tpax_dirent {
|
|
|
d7918a |
int fdat;
|
|
|
d7918a |
int depth;
|
|
|
9f55a1 |
int flags;
|
|
|
d7918a |
size_t nsize;
|
|
|
9f55a1 |
const char * prefix;
|
|
|
d7918a |
const struct tpax_dirent * parent;
|
|
|
d7918a |
struct dirent dirent;
|
|
|
d7918a |
};
|
|
|
d7918a |
|
|
|
d7918a |
struct tpax_dirent_buffer {
|
|
|
d7918a |
struct tpax_dirent_buffer * next;
|
|
|
d7918a |
size_t size;
|
|
|
d7918a |
size_t nfree;
|
|
|
d7918a |
struct tpax_dirent * cdent;
|
|
|
d7918a |
struct tpax_dirent dbuf[];
|
|
|
d7918a |
};
|
|
|
d7918a |
|
|
|
88751e |
struct tpax_driver_ctx_impl {
|
|
|
88751e |
struct tpax_common_ctx cctx;
|
|
|
88751e |
struct tpax_driver_ctx ctx;
|
|
|
88751e |
struct tpax_fd_ctx fdctx;
|
|
|
88751e |
const struct tpax_unit_ctx * euctx;
|
|
|
88751e |
const char * eunit;
|
|
|
88751e |
struct tpax_error_info ** errinfp;
|
|
|
88751e |
struct tpax_error_info ** erricap;
|
|
|
88751e |
struct tpax_error_info * erriptr[64];
|
|
|
88751e |
struct tpax_error_info erribuf[64];
|
|
|
9f55a1 |
char ** prefixv;
|
|
|
9f55a1 |
char ** prefixp;
|
|
|
9f55a1 |
char ** prefcap;
|
|
|
9f55a1 |
char * prefptr[64];
|
|
|
d7918a |
struct tpax_dirent_buffer * dirents;
|
|
|
a0e0a4 |
struct tpax_dirent * dirmark;
|
|
|
d7918a |
void * dirbuff;
|
|
|
76f8c5 |
void * bufaddr;
|
|
|
76f8c5 |
size_t bufsize;
|
|
|
1e49c7 |
size_t nqueued;
|
|
|
409008 |
off_t cpos;
|
|
|
88751e |
};
|
|
|
88751e |
|
|
|
88751e |
struct tpax_unit_ctx_impl {
|
|
|
88751e |
const char * path;
|
|
|
88751e |
struct tpax_unit_ctx uctx;
|
|
|
239ac5 |
struct stat st;
|
|
|
409008 |
off_t hpos;
|
|
|
409008 |
off_t dpos;
|
|
|
239ac5 |
const char * link;
|
|
|
239ac5 |
char linkbuf[1024];
|
|
|
dfe02c |
size_t hdrbuf[];
|
|
|
88751e |
};
|
|
|
88751e |
|
|
|
88751e |
|
|
|
88751e |
static inline struct tpax_driver_ctx_impl * tpax_get_driver_ictx(
|
|
|
88751e |
const struct tpax_driver_ctx * dctx)
|
|
|
88751e |
{
|
|
|
88751e |
uintptr_t addr;
|
|
|
88751e |
|
|
|
88751e |
if (dctx) {
|
|
|
88751e |
addr = (uintptr_t)dctx - offsetof(struct tpax_driver_ctx_impl,ctx);
|
|
|
88751e |
return (struct tpax_driver_ctx_impl *)addr;
|
|
|
88751e |
}
|
|
|
88751e |
|
|
|
88751e |
return 0;
|
|
|
88751e |
}
|
|
|
88751e |
|
|
|
409008 |
static inline struct tpax_unit_ctx_impl * tpax_get_unit_ictx(
|
|
|
409008 |
const struct tpax_unit_ctx * uctx)
|
|
|
409008 |
{
|
|
|
409008 |
struct tpax_unit_ctx_impl * ictx;
|
|
|
409008 |
uintptr_t addr;
|
|
|
409008 |
|
|
|
409008 |
addr = (uintptr_t)uctx - offsetof(struct tpax_unit_ctx_impl,uctx);
|
|
|
409008 |
ictx = (struct tpax_unit_ctx_impl *)addr;
|
|
|
409008 |
return ictx;
|
|
|
409008 |
}
|
|
|
409008 |
|
|
|
e407b8 |
static inline void * tpax_get_driver_anon_map_addr(
|
|
|
e407b8 |
const struct tpax_driver_ctx * dctx,
|
|
|
e407b8 |
size_t * size)
|
|
|
e407b8 |
{
|
|
|
e407b8 |
struct tpax_driver_ctx_impl * ictx = tpax_get_driver_ictx(dctx);
|
|
|
e407b8 |
*size = ictx->bufsize;
|
|
|
e407b8 |
return ictx->bufaddr;
|
|
|
e407b8 |
}
|
|
|
e407b8 |
|
|
|
d7918a |
static inline void * tpax_get_driver_getdents_buffer(
|
|
|
d7918a |
const struct tpax_driver_ctx * dctx)
|
|
|
d7918a |
{
|
|
|
d7918a |
struct tpax_driver_ctx_impl * ictx = tpax_get_driver_ictx(dctx);
|
|
|
d7918a |
return ictx->dirbuff;
|
|
|
d7918a |
}
|
|
|
d7918a |
|
|
|
88751e |
static inline void tpax_driver_set_ectx(
|
|
|
88751e |
const struct tpax_driver_ctx * dctx,
|
|
|
88751e |
const struct tpax_unit_ctx * uctx,
|
|
|
88751e |
const char * unit)
|
|
|
88751e |
{
|
|
|
88751e |
struct tpax_driver_ctx_impl * ictx;
|
|
|
88751e |
|
|
|
88751e |
ictx = tpax_get_driver_ictx(dctx);
|
|
|
88751e |
ictx->euctx = uctx;
|
|
|
88751e |
ictx->eunit = unit;
|
|
|
88751e |
}
|
|
|
88751e |
|
|
|
88751e |
static inline int tpax_driver_fdin(const struct tpax_driver_ctx * dctx)
|
|
|
88751e |
{
|
|
|
88751e |
struct tpax_fd_ctx fdctx;
|
|
|
88751e |
tpax_get_driver_fdctx(dctx,&fdctx);
|
|
|
88751e |
return fdctx.fdin;
|
|
|
88751e |
}
|
|
|
88751e |
|
|
|
88751e |
static inline int tpax_driver_fdout(const struct tpax_driver_ctx * dctx)
|
|
|
88751e |
{
|
|
|
88751e |
struct tpax_fd_ctx fdctx;
|
|
|
88751e |
tpax_get_driver_fdctx(dctx,&fdctx);
|
|
|
88751e |
return fdctx.fdout;
|
|
|
88751e |
}
|
|
|
88751e |
|
|
|
88751e |
static inline int tpax_driver_fderr(const struct tpax_driver_ctx * dctx)
|
|
|
88751e |
{
|
|
|
88751e |
struct tpax_fd_ctx fdctx;
|
|
|
88751e |
tpax_get_driver_fdctx(dctx,&fdctx);
|
|
|
88751e |
return fdctx.fderr;
|
|
|
88751e |
}
|
|
|
88751e |
|
|
|
88751e |
static inline int tpax_driver_fdlog(const struct tpax_driver_ctx * dctx)
|
|
|
88751e |
{
|
|
|
88751e |
struct tpax_fd_ctx fdctx;
|
|
|
88751e |
tpax_get_driver_fdctx(dctx,&fdctx);
|
|
|
88751e |
return fdctx.fdlog;
|
|
|
88751e |
}
|
|
|
88751e |
|
|
|
88751e |
static inline int tpax_driver_fdcwd(const struct tpax_driver_ctx * dctx)
|
|
|
88751e |
{
|
|
|
88751e |
struct tpax_fd_ctx fdctx;
|
|
|
88751e |
tpax_get_driver_fdctx(dctx,&fdctx);
|
|
|
88751e |
return fdctx.fdcwd;
|
|
|
88751e |
}
|
|
|
88751e |
|
|
|
88751e |
static inline int tpax_driver_fddst(const struct tpax_driver_ctx * dctx)
|
|
|
88751e |
{
|
|
|
88751e |
struct tpax_fd_ctx fdctx;
|
|
|
88751e |
tpax_get_driver_fdctx(dctx,&fdctx);
|
|
|
88751e |
return fdctx.fddst;
|
|
|
88751e |
}
|
|
|
88751e |
|
|
|
409008 |
static inline off_t tpax_get_driver_cpos(const struct tpax_driver_ctx * dctx)
|
|
|
409008 |
{
|
|
|
409008 |
struct tpax_driver_ctx_impl * ictx;
|
|
|
409008 |
ictx = tpax_get_driver_ictx(dctx);
|
|
|
409008 |
return ictx->cpos;
|
|
|
409008 |
}
|
|
|
409008 |
|
|
|
409008 |
static inline void tpax_set_driver_cpos(const struct tpax_driver_ctx * dctx, off_t cpos)
|
|
|
409008 |
{
|
|
|
409008 |
struct tpax_driver_ctx_impl * ictx;
|
|
|
409008 |
ictx = tpax_get_driver_ictx(dctx);
|
|
|
409008 |
ictx->cpos = cpos;
|
|
|
409008 |
}
|
|
|
409008 |
|
|
|
d7918a |
static inline struct tpax_dirent_buffer * tpax_get_driver_dirents(const struct tpax_driver_ctx * dctx)
|
|
|
d7918a |
{
|
|
|
d7918a |
struct tpax_driver_ctx_impl * ictx;
|
|
|
d7918a |
ictx = tpax_get_driver_ictx(dctx);
|
|
|
d7918a |
return ictx->dirents;
|
|
|
d7918a |
}
|
|
|
d7918a |
|
|
|
a0e0a4 |
static inline struct tpax_dirent * tpax_get_driver_dirmark(const struct tpax_driver_ctx * dctx)
|
|
|
a0e0a4 |
{
|
|
|
a0e0a4 |
struct tpax_driver_ctx_impl * ictx;
|
|
|
a0e0a4 |
ictx = tpax_get_driver_ictx(dctx);
|
|
|
a0e0a4 |
return ictx->dirmark;
|
|
|
a0e0a4 |
}
|
|
|
a0e0a4 |
|
|
|
a0e0a4 |
static inline void tpax_set_driver_dirmark(const struct tpax_driver_ctx * dctx, struct tpax_dirent * dirent)
|
|
|
a0e0a4 |
{
|
|
|
a0e0a4 |
struct tpax_driver_ctx_impl * ictx;
|
|
|
a0e0a4 |
ictx = tpax_get_driver_ictx(dctx);
|
|
|
a0e0a4 |
ictx->dirmark = dirent;
|
|
|
1e49c7 |
ictx->nqueued++;
|
|
|
a0e0a4 |
}
|
|
|
a0e0a4 |
|
|
|
409008 |
static inline off_t tpax_get_unit_hpos(const struct tpax_unit_ctx * uctx)
|
|
|
409008 |
{
|
|
|
409008 |
struct tpax_unit_ctx_impl * ictx;
|
|
|
409008 |
ictx = tpax_get_unit_ictx(uctx);
|
|
|
409008 |
return ictx->hpos;
|
|
|
409008 |
}
|
|
|
409008 |
|
|
|
409008 |
static inline void tpax_set_unit_hpos(const struct tpax_unit_ctx * uctx, off_t hpos)
|
|
|
409008 |
{
|
|
|
409008 |
struct tpax_unit_ctx_impl * ictx;
|
|
|
409008 |
ictx = tpax_get_unit_ictx(uctx);
|
|
|
409008 |
ictx->hpos = hpos;
|
|
|
409008 |
}
|
|
|
409008 |
|
|
|
409008 |
static inline off_t tpax_get_unit_dpos(const struct tpax_unit_ctx * uctx)
|
|
|
409008 |
{
|
|
|
409008 |
struct tpax_unit_ctx_impl * ictx;
|
|
|
409008 |
ictx = tpax_get_unit_ictx(uctx);
|
|
|
409008 |
return ictx->dpos;
|
|
|
409008 |
}
|
|
|
409008 |
|
|
|
409008 |
static inline void tpax_set_unit_dpos(const struct tpax_unit_ctx * uctx, off_t dpos)
|
|
|
409008 |
{
|
|
|
409008 |
struct tpax_unit_ctx_impl * ictx;
|
|
|
409008 |
ictx = tpax_get_unit_ictx(uctx);
|
|
|
409008 |
ictx->dpos = dpos;
|
|
|
409008 |
}
|
|
|
409008 |
|
|
|
409008 |
static inline ssize_t tpax_get_archive_block_size(const struct tpax_driver_ctx * dctx)
|
|
|
409008 |
{
|
|
|
409008 |
if (dctx->cctx->drvflags & TPAX_DRIVER_WRITE_FORMAT_PAX)
|
|
|
409008 |
return TPAX_PAX_BLOCK_SIZE;
|
|
|
409008 |
|
|
|
409008 |
else if (dctx->cctx->drvflags & TPAX_DRIVER_WRITE_FORMAT_CPIO)
|
|
|
409008 |
return TPAX_CPIO_BLOCK_SIZE;
|
|
|
409008 |
|
|
|
409008 |
else if (dctx->cctx->drvflags & TPAX_DRIVER_WRITE_FORMAT_USTAR)
|
|
|
409008 |
return TPAX_USTAR_BLOCK_SIZE;
|
|
|
409008 |
|
|
|
409008 |
else if (dctx->cctx->drvflags & TPAX_DRIVER_WRITE_FORMAT_RUSTAR)
|
|
|
409008 |
return TPAX_USTAR_BLOCK_SIZE;
|
|
|
409008 |
|
|
|
409008 |
else
|
|
|
409008 |
return 0;
|
|
|
409008 |
}
|
|
|
409008 |
|
|
|
88751e |
#endif
|