diff options
-rw-r--r-- | src/driver/tpax_driver_ctx.c | 67 | ||||
-rw-r--r-- | src/internal/tpax_driver_impl.h | 2 | ||||
-rw-r--r-- | src/skin/tpax_skin_default.c | 5 |
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, |