summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/driver/tpax_driver_ctx.c13
-rw-r--r--src/internal/tpax_driver_impl.h9
-rw-r--r--src/logic/tpax_archive_append.c55
3 files changed, 75 insertions, 2 deletions
diff --git a/src/driver/tpax_driver_ctx.c b/src/driver/tpax_driver_ctx.c
index 0a92537..c621bb6 100644
--- a/src/driver/tpax_driver_ctx.c
+++ b/src/driver/tpax_driver_ctx.c
@@ -276,6 +276,12 @@ static struct tpax_driver_ctx_impl * tpax_driver_ctx_alloc(
ictx->ctx.errinfp = &ictx->ctx.erriptr[0];
ictx->ctx.erricap = &ictx->ctx.erriptr[--elements];
+ elements = sizeof(ictx->ctx.prefptr) / sizeof(*ictx->ctx.prefptr);
+
+ ictx->ctx.prefixv = &ictx->ctx.prefptr[0];
+ ictx->ctx.prefixp = &ictx->ctx.prefptr[0];
+ ictx->ctx.prefcap = &ictx->ctx.prefptr[--elements];
+
ictx->meta = meta;
for (entry=meta->entries,units=ictx->units; entry->fopt || entry->arg; entry++)
@@ -561,6 +567,7 @@ static void tpax_free_driver_ctx_impl(struct tpax_driver_ctx_alloc * ictx)
{
void * next;
size_t size;
+ char ** ppref;
for (; ictx->ctx.dirents; ) {
next = ictx->ctx.dirents->next;
@@ -576,6 +583,12 @@ static void tpax_free_driver_ctx_impl(struct tpax_driver_ctx_alloc * ictx)
if (ictx->ctx.dirbuff)
munmap(ictx->ctx.dirbuff,TPAX_DIRENT_BUFLEN);
+ for (ppref=ictx->ctx.prefixv; *ppref; ppref++)
+ free(*ppref);
+
+ if (ictx->ctx.prefixv != ictx->ctx.prefptr)
+ free(ictx->ctx.prefixv);
+
argv_free(ictx->meta);
free(ictx);
}
diff --git a/src/internal/tpax_driver_impl.h b/src/internal/tpax_driver_impl.h
index 5fabb0a..ea02185 100644
--- a/src/internal/tpax_driver_impl.h
+++ b/src/internal/tpax_driver_impl.h
@@ -26,6 +26,9 @@
(TPAX_DRIVER_EXEC_MODE_WRITE | \
TPAX_DRIVER_EXEC_MODE_COPY)
+#define TPAX_ITEM_EXPLICIT 0X1
+#define TPAX_ITEM_IMPLICIT 0X2
+
extern const struct argv_option tpax_default_options[];
enum app_tags {
@@ -46,7 +49,9 @@ enum app_tags {
struct tpax_dirent {
int fdat;
int depth;
+ int flags;
size_t nsize;
+ const char * prefix;
const struct tpax_dirent * parent;
struct dirent dirent;
};
@@ -69,6 +74,10 @@ struct tpax_driver_ctx_impl {
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_buffer * dirents;
void * dirbuff;
void * bufaddr;
diff --git a/src/logic/tpax_archive_append.c b/src/logic/tpax_archive_append.c
index 4bc3d2f..d8ac12f 100644
--- a/src/logic/tpax_archive_append.c
+++ b/src/logic/tpax_archive_append.c
@@ -49,6 +49,49 @@ static int tpax_archive_append_memory_data(
return 0;
}
+static char * tpax_append_prefix_item(
+ const struct tpax_driver_ctx * dctx,
+ const char * prefix)
+{
+ struct tpax_driver_ctx_impl * ictx;
+ char ** prefv;
+ char ** psrc;
+ char ** pdst;
+ off_t elements;
+ char * pitem;
+
+ ictx = tpax_get_driver_ictx(dctx);
+
+ for (psrc=ictx->prefixv; *psrc; psrc++)
+ if (!strcmp(*psrc,prefix))
+ return *psrc;
+
+ if (ictx->prefixp == ictx->prefcap) {
+ elements = ictx->prefcap - ictx->prefixv;
+ elements += 256;
+
+ if (!(prefv = calloc(elements,sizeof(char *))))
+ return 0;
+
+ for (psrc=ictx->prefixv,pdst=prefv; *psrc; psrc++,pdst++)
+ *pdst = *psrc;
+
+ if (ictx->prefixv != ictx->prefptr)
+ free(ictx->prefixv);
+
+ ictx->prefixv = prefv;
+ ictx->prefixp = pdst;
+ ictx->prefcap = &prefv[--elements];
+ }
+
+ if (!(pitem = strdup(prefix)))
+ return 0;
+
+ *ictx->prefixp++ = pitem;
+
+ return pitem;
+}
+
static int tpax_archive_append_pad(
const struct tpax_driver_ctx * dctx,
int fdout,
@@ -144,11 +187,12 @@ static int tpax_archive_append_queue_item(
const struct tpax_driver_ctx * dctx,
const struct dirent * dirent,
const struct tpax_dirent * parent,
+ const char * prefix,
struct tpax_unit_ctx * unit,
int depth,
+ int flags,
int fd,
bool * fkeep)
-
{
struct tpax_dirent_buffer * dentbuf;
struct tpax_dirent * cdent;
@@ -183,8 +227,10 @@ static int tpax_archive_append_queue_item(
cdent->fdat = fd;
cdent->depth = depth;
+ cdent->flags = flags;
cdent->nsize = needed;
cdent->parent = parent;
+ cdent->prefix = prefix;
memset(&cdent->dirent,0,offsetof(struct dirent,d_name));
@@ -510,7 +556,8 @@ static int tpax_archive_append_dir(
if (dirent->d_type == DT_DIR) {
if (tpax_archive_append_queue_item(
dctx,dirent,
- parent,unit,depth,
+ parent,0,unit,depth,
+ TPAX_ITEM_IMPLICIT,
fd,&fkeep) < 0)
return tpax_archive_append_ret(
TPAX_NESTED_ERROR(dctx),
@@ -598,6 +645,10 @@ int tpax_archive_append(
for (++prefix; *prefix=='/'; prefix++)
(void)0;
+ if (prefix)
+ if (!(prefix = tpax_append_prefix_item(dctx,prefix)))
+ return TPAX_BUFFER_ERROR(dctx);
+
/* append explicit item */
tpax_archive_append_impl(dctx,uctx,0,prefix,0);