summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/driver/tpax_driver_ctx.c67
-rw-r--r--src/internal/tpax_driver_impl.h2
-rw-r--r--src/skin/tpax_skin_default.c5
3 files changed, 74 insertions, 0 deletions
diff --git a/src/driver/tpax_driver_ctx.c b/src/driver/tpax_driver_ctx.c
index 79518f0..dff6ef6 100644
--- a/src/driver/tpax_driver_ctx.c
+++ b/src/driver/tpax_driver_ctx.c
@@ -322,6 +322,12 @@ static void tpax_set_archive_block_size(struct tpax_common_ctx * cctx)
cctx->blksize = TPAX_USTAR_BLOCK_SIZE;
}
+static int tpax_driver_is_valid_keyval(struct argv_keyval * keyval)
+{
+ (void)keyval;
+ return 0;
+}
+
static struct tpax_driver_ctx_impl * tpax_driver_ctx_alloc(
struct argv_meta * meta,
const struct tpax_fd_ctx * fdctx,
@@ -333,6 +339,9 @@ static struct tpax_driver_ctx_impl * tpax_driver_ctx_alloc(
struct argv_entry * entry;
const char ** units;
int elements;
+ int nkeyval;
+ struct argv_keyval ** pkeyval;
+ struct argv_keyval * keyval;
size = sizeof(struct tpax_driver_ctx_alloc);
size += (nunits+1)*sizeof(const char *);
@@ -360,6 +369,22 @@ static struct tpax_driver_ctx_impl * tpax_driver_ctx_alloc(
if (!entry->fopt)
*units++ = entry->arg;
+ for (entry=meta->entries,nkeyval=0; entry->fopt || entry->arg; entry++)
+ if (entry->keyv)
+ for (keyval=entry->keyv; keyval->keyword; keyval++)
+ nkeyval++;
+
+ if (nkeyval && !(ictx->ctx.keyvalv = calloc(nkeyval+1,sizeof(*ictx->ctx.keyvalv)))) {
+ free(ictx);
+ return 0;
+ }
+
+ if ((pkeyval = ictx->ctx.keyvalv))
+ for (entry=meta->entries; entry->fopt || entry->arg; entry++)
+ if (entry->keyv)
+ for (keyval=entry->keyv; keyval->keyword; keyval++)
+ *pkeyval++ = keyval;
+
if (cctx->drvflags & TPAX_DRIVER_EXEC_MODE_WRITE_COPY) {
ictx->ctx.bufsize = TPAX_FILEIO_BUFLEN;
ictx->ctx.bufaddr = mmap(
@@ -369,6 +394,7 @@ static struct tpax_driver_ctx_impl * tpax_driver_ctx_alloc(
-1,0);
if (ictx->ctx.bufaddr == MAP_FAILED) {
+ free(ictx->ctx.keyvalv);
free(ictx);
return 0;
}
@@ -381,6 +407,7 @@ static struct tpax_driver_ctx_impl * tpax_driver_ctx_alloc(
if (ictx->ctx.dirbuff == MAP_FAILED) {
munmap(ictx->ctx.bufaddr,ictx->ctx.bufsize);
+ free(ictx->ctx.keyvalv);
free(ictx);
return 0;
}
@@ -399,6 +426,37 @@ static int tpax_get_driver_ctx_fail(struct argv_meta * meta)
return -1;
}
+static int tpax_driver_keyval_error(
+ struct tpax_driver_ctx_impl * ctx,
+ struct argv_keyval * keyval,
+ const char * program)
+{
+ const char * equal;
+
+ switch (keyval->flags) {
+ case ARGV_KEYVAL_ASSIGN:
+ equal = "=";
+ break;
+
+ case ARGV_KEYVAL_OVERRIDE:
+ equal = ":=";
+ break;
+
+ default:
+ equal = "";
+ }
+
+ tpax_dprintf(
+ ctx->fdctx.fderr,
+ "%s: unsupported keyval argument (%s%s%s)\n",
+ program,keyval->keyword,equal,
+ keyval->value ? keyval->value : "");
+
+ tpax_lib_free_driver_ctx(&ctx->ctx);
+
+ return TPAX_ERROR;
+}
+
int tpax_lib_get_driver_ctx(
char ** argv,
char ** envp,
@@ -413,6 +471,7 @@ int tpax_lib_get_driver_ctx(
struct argv_entry * entry;
struct argv_entry * archive;
struct argv_entry * operand;
+ struct argv_keyval ** pkeyval;
struct tpax_fd_ctx lfdctx;
size_t nunits;
const char * program;
@@ -699,6 +758,11 @@ int tpax_lib_get_driver_ctx(
return tpax_get_driver_ctx_fail(meta);
}
+ /* keyval validation */
+ for (pkeyval=ctx->keyvalv; pkeyval && *pkeyval; pkeyval++)
+ if (!tpax_driver_is_valid_keyval(*pkeyval))
+ return tpax_driver_keyval_error(ctx,*pkeyval,program);
+
if (archive) {
ctx->file = archive->arg;
ctx->ctx.file = &ctx->file;
@@ -725,6 +789,9 @@ static void tpax_free_driver_ctx_impl(struct tpax_driver_ctx_alloc * ictx)
ictx->ctx.dirents = (struct tpax_dirent_buffer *)next;
}
+ if (ictx->ctx.keyvalv)
+ free(ictx->ctx.keyvalv);
+
if (ictx->ctx.bufaddr)
munmap(ictx->ctx.bufaddr,ictx->ctx.bufsize);
diff --git a/src/internal/tpax_driver_impl.h b/src/internal/tpax_driver_impl.h
index 2bcb486..d340748 100644
--- a/src/internal/tpax_driver_impl.h
+++ b/src/internal/tpax_driver_impl.h
@@ -44,6 +44,7 @@ enum app_tags {
TAG_FILE,
TAG_FORMAT,
TAG_BLKSIZE,
+ TAG_OPTIONS,
TAG_RECURSE,
TAG_NORECURSE,
TAG_STRICT_PATH,
@@ -80,6 +81,7 @@ struct tpax_driver_ctx_impl {
struct tpax_fd_ctx fdctx;
const struct tpax_unit_ctx * euctx;
const char * eunit;
+ struct argv_keyval ** keyvalv;
struct tpax_error_info ** errinfp;
struct tpax_error_info ** erricap;
struct tpax_error_info * erriptr[64];
diff --git a/src/skin/tpax_skin_default.c b/src/skin/tpax_skin_default.c
index 33ab8b8..a618645 100644
--- a/src/skin/tpax_skin_default.c
+++ b/src/skin/tpax_skin_default.c
@@ -88,6 +88,11 @@ const tpax_hidden struct argv_option tpax_default_options[] = {
"or directory to the archive using the name of the "
"symbolic link."},
+ {"Woptions", 'o',TAG_OPTIONS,ARGV_OPTARG_REQUIRED,
+ ARGV_OPTION_HYBRID_ONLY|ARGV_OPTION_HYBRID_SPACE|ARGV_OPTION_KEYVAL_ARRAY,0,0,
+ "a user-provided, format-specific keyval array of the form "
+ "keyword[[:]=value][,keyword[[:]=value], ...]"},
+
{"Wstrict-device-id",
'X',TAG_STRICT_DEVICE_ID,ARGV_OPTARG_NONE,
ARGV_OPTION_HYBRID_ONLY,0,0,