summaryrefslogtreecommitdiffhomepage
path: root/src/driver/tpax_driver_ctx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/driver/tpax_driver_ctx.c')
-rw-r--r--src/driver/tpax_driver_ctx.c151
1 files changed, 149 insertions, 2 deletions
diff --git a/src/driver/tpax_driver_ctx.c b/src/driver/tpax_driver_ctx.c
index dff6ef6..5593ec6 100644
--- a/src/driver/tpax_driver_ctx.c
+++ b/src/driver/tpax_driver_ctx.c
@@ -6,6 +6,7 @@
#define _DEFAULT_SOURCE 1
+#include <regex.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -322,6 +323,109 @@ static void tpax_set_archive_block_size(struct tpax_common_ctx * cctx)
cctx->blksize = TPAX_USTAR_BLOCK_SIZE;
}
+static int tpax_add_replstr(
+ struct argv_entry * entry,
+ struct tpax_replstr * replstr,
+ char ** mark)
+{
+ const char * src;
+ char * dst;
+ char sep;
+ int nsep;
+
+ /* non-null separator character */
+ if (!(sep = entry->arg[0]))
+ return -1;
+
+ /* exactly three separator characters */
+ for (nsep=1,src=&entry->arg[1]; *src; src++) {
+ if ((src[0] == '\\') && (src[1] == sep)) {
+ src++;
+
+ } else if (src[0] == sep) {
+ nsep++;
+ }
+ }
+
+ if (nsep != 3)
+ return -1;
+
+ /* regexp */
+ for (src=&entry->arg[1],dst=*mark; (*src != sep); src++) {
+ if ((src[0] == '\\') && (src[1] == sep))
+ src++;
+
+ *dst++ = *src;
+ }
+
+ replstr->replarg = entry->arg;
+ replstr->replstr = ++dst;
+ replstr->regexp = *mark;
+
+ /* replstr */
+ for (++src; (*src != sep); src++) {
+ if ((src[0] == '\\') && (src[1] == sep))
+ src++;
+
+ *dst++ = *src;
+ }
+
+ src++;
+ dst++;
+
+ *mark = dst;
+
+ /* flags */
+ if (src[0] && src[1] && src[2])
+ return -1;
+
+ if (src[0] && (src[0] == src[1]))
+ return -1;
+
+ if (src[0] && (src[0] != 'g') && (src[0] != 'p'))
+ return -1;
+
+ if (src[0] && src[1] && (src[1] != 'g') && (src[1] != 'p'))
+ return -1;
+
+ if (src[0] && ((src[0] == 'g') || (src[1] == 'g')))
+ replstr->flags |= TPAX_REPL_GLOBAL;
+
+ if (src[0] && ((src[0] == 'p') || (src[1] == 'p')))
+ replstr->flags |= TPAX_REPL_PRINT;
+
+ /* regex */
+ if (regcomp(&replstr->regex,replstr->regexp,0)) {
+ replstr->regexp = 0;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int tpax_init_replstr_vector(
+ struct tpax_driver_ctx_impl * ctx,
+ struct argv_meta * meta)
+{
+ struct argv_entry * entry;
+ struct tpax_replstr * replstr;
+ char * mark;
+
+ if (!(replstr = ctx->replstrv))
+ return 0;
+
+ for (entry=meta->entries,mark=ctx->replstrs; entry->fopt || entry->arg; entry++) {
+ if (entry->tag == TAG_REPLSTR) {
+ if (tpax_add_replstr(entry,replstr,&mark) < 0)
+ return -1;
+
+ replstr++;
+ }
+ }
+
+ return 0;
+}
+
static int tpax_driver_is_valid_keyval(struct argv_keyval * keyval)
{
(void)keyval;
@@ -332,7 +436,9 @@ static struct tpax_driver_ctx_impl * tpax_driver_ctx_alloc(
struct argv_meta * meta,
const struct tpax_fd_ctx * fdctx,
const struct tpax_common_ctx * cctx,
- size_t nunits)
+ size_t nunits,
+ size_t nreplstr,
+ size_t sreplstr)
{
struct tpax_driver_ctx_alloc * ictx;
size_t size;
@@ -379,6 +485,19 @@ static struct tpax_driver_ctx_impl * tpax_driver_ctx_alloc(
return 0;
}
+ if (nreplstr && !(ictx->ctx.replstrv = calloc(++nreplstr,sizeof(*ictx->ctx.replstrv)))) {
+ free(ictx->ctx.keyvalv);
+ free(ictx);
+ return 0;
+ }
+
+ if (sreplstr && !(ictx->ctx.replstrs = calloc(sreplstr,1))) {
+ free(ictx->ctx.replstrv);
+ free(ictx->ctx.keyvalv);
+ free(ictx);
+ return 0;
+ }
+
if ((pkeyval = ictx->ctx.keyvalv))
for (entry=meta->entries; entry->fopt || entry->arg; entry++)
if (entry->keyv)
@@ -474,6 +593,8 @@ int tpax_lib_get_driver_ctx(
struct argv_keyval ** pkeyval;
struct tpax_fd_ctx lfdctx;
size_t nunits;
+ size_t nreplstr;
+ size_t sreplstr;
const char * program;
int fddst;
const char * ch;
@@ -497,6 +618,9 @@ int tpax_lib_get_driver_ctx(
program = argv_program_name(argv[0]);
memset(&cctx,0,sizeof(cctx));
+ nreplstr = 0;
+ sreplstr = 0;
+
cctx.drvflags = flags;
fddst = fdctx->fddst;
@@ -581,6 +705,12 @@ int tpax_lib_get_driver_ctx(
meta);
break;
+ case TAG_REPLSTR:
+ sreplstr += strlen(entry->arg);
+ sreplstr++;
+ nreplstr++;
+ break;
+
case TAG_RECURSE:
cctx.drvflags |= TPAX_DRIVER_DIR_MEMBER_RECURSE;
break;
@@ -751,13 +881,19 @@ int tpax_lib_get_driver_ctx(
}
/* driver ctx */
- if (!(ctx = tpax_driver_ctx_alloc(meta,fdctx,&cctx,nunits))) {
+ if (!(ctx = tpax_driver_ctx_alloc(meta,fdctx,&cctx,nunits,nreplstr,sreplstr))) {
if (cctx.drvflags & TPAX_DRIVER_EXEC_MODE_COPY)
close(fddst);
return tpax_get_driver_ctx_fail(meta);
}
+ /* replstr validation and vector initialization */
+ if (tpax_init_replstr_vector(ctx,meta) < 0) {
+ tpax_lib_free_driver_ctx(&ctx->ctx);
+ return TPAX_ERROR;
+ }
+
/* keyval validation */
for (pkeyval=ctx->keyvalv; pkeyval && *pkeyval; pkeyval++)
if (!tpax_driver_is_valid_keyval(*pkeyval))
@@ -781,6 +917,8 @@ static void tpax_free_driver_ctx_impl(struct tpax_driver_ctx_alloc * ictx)
size_t size;
char ** ppref;
+ struct tpax_replstr * replstrv;
+
for (; ictx->ctx.dirents; ) {
next = ictx->ctx.dirents->next;
size = ictx->ctx.dirents->size;
@@ -789,6 +927,15 @@ static void tpax_free_driver_ctx_impl(struct tpax_driver_ctx_alloc * ictx)
ictx->ctx.dirents = (struct tpax_dirent_buffer *)next;
}
+ for (replstrv=ictx->ctx.replstrv; replstrv && replstrv->regexp; replstrv++)
+ regfree(&replstrv->regex);
+
+ if (ictx->ctx.replstrv)
+ free(ictx->ctx.replstrv);
+
+ if (ictx->ctx.replstrs)
+ free(ictx->ctx.replstrs);
+
if (ictx->ctx.keyvalv)
free(ictx->ctx.keyvalv);