summaryrefslogtreecommitdiff
path: root/libmu_sieve
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-10-24 00:15:01 +0300
committerSergey Poznyakoff <gray@gnu.org>2018-10-24 00:26:15 +0300
commit35c9ae8024466f176ddc77306c08b5edc21bc0a2 (patch)
tree694d9061bfba7aaea01997c8bb4efa801c49a05c /libmu_sieve
parent00b8be32a86c183c049ebfd40e67450878792bd0 (diff)
downloadmailutils-35c9ae8024466f176ddc77306c08b5edc21bc0a2.tar.gz
mailutils-35c9ae8024466f176ddc77306c08b5edc21bc0a2.tar.bz2
sieve: set variables from command line
The new command line option --variable initializes the RFC 5229 variable. * NEWS: Update. * doc/texinfo/programs.texi: Fix description of sieve command line options. * include/mailutils/sieve.h (mu_sieve_variable_initialize): New proto. * libmu_sieve/runtime.c (sieve_run): Call mu_i_sv_init_variables to clear and initialize the table of variables. * libmu_sieve/sieve-gram.y (mu_sieve_machine_dup): Copy variables. (mu_sieve_machine_destroy): Destroy table of variables and initializer list. * libmu_sieve/sieve-priv.h (mu_sieve_machine) <init_var>: New member. (mu_sieve_variable_initializer): New type. (mu_i_sv_init_variables): New proto. * libmu_sieve/variables.c (mu_sieve_variable_initialize): New function. (mu_i_sv_copy_variables): Copy initializers as well. (mu_i_sv_init_variables): New function. * sieve/sieve.c: New command line option --variable. * sieve/tests/variables.at: Test the --variable option.
Diffstat (limited to 'libmu_sieve')
-rw-r--r--libmu_sieve/runtime.c3
-rw-r--r--libmu_sieve/sieve-gram.y7
-rw-r--r--libmu_sieve/sieve-priv.h12
-rw-r--r--libmu_sieve/variables.c151
4 files changed, 145 insertions, 28 deletions
diff --git a/libmu_sieve/runtime.c b/libmu_sieve/runtime.c
index 0d58e366a..f7deedb82 100644
--- a/libmu_sieve/runtime.c
+++ b/libmu_sieve/runtime.c
@@ -233,8 +233,7 @@ sieve_run (mu_sieve_machine_t mach)
{
mach->action_count = 0;
- if (mu_sieve_has_variables (mach))
- mu_assoc_clear (mach->vartab);
+ mu_i_sv_init_variables (mach);
for (mach->pc = 1; mach->prog[mach->pc].handler; )
(*mach->prog[mach->pc++].instr) (mach);
diff --git a/libmu_sieve/sieve-gram.y b/libmu_sieve/sieve-gram.y
index 898d4fd64..c1ff7df94 100644
--- a/libmu_sieve/sieve-gram.y
+++ b/libmu_sieve/sieve-gram.y
@@ -1232,7 +1232,9 @@ mu_sieve_machine_dup (mu_sieve_machine_t const in, mu_sieve_machine_t *out)
mu_locus_range_copy (&mach->dbg_locus, &in->dbg_locus);
copy_stream_state (mach, in);
-
+
+ mu_i_sv_copy_variables (mach, in);
+
mach->data = in->data;
mach->logger = in->logger;
mach->daemon_email = in->daemon_email;
@@ -1412,6 +1414,9 @@ mu_sieve_machine_destroy (mu_sieve_machine_t *pmach)
mu_sieve_free (mach, mach->idspace);
mu_opool_destroy (&mach->string_pool);
mu_list_destroy (&mach->memory_pool);
+ mu_assoc_destroy (&mach->vartab);
+ mu_list_destroy (&mach->init_var);
+
free (mach);
*pmach = NULL;
}
diff --git a/libmu_sieve/sieve-priv.h b/libmu_sieve/sieve-priv.h
index 77a6521d5..ed6ea5e3f 100644
--- a/libmu_sieve/sieve-priv.h
+++ b/libmu_sieve/sieve-priv.h
@@ -95,7 +95,8 @@ struct mu_sieve_machine
regmatch_t *match_buf; /* Offsets of parenthesized groups */
size_t match_count; /* Actual number of elements used in match_buf */
size_t match_max; /* Total number of elements available in match_buf */
-
+ mu_list_t init_var; /* List of variable initializers */
+
/* Call environment */
const char *identifier; /* Name of action or test being executed */
size_t argstart; /* Index of the first argument in valspace */
@@ -175,6 +176,12 @@ struct mu_sieve_node_list
struct mu_sieve_node *head, *tail;
};
+struct mu_sieve_variable_initializer
+{
+ char *name;
+ char *value;
+};
+
int mu_sieve_yyerror (const char *s);
int mu_sieve_yylex (void);
@@ -249,4 +256,7 @@ void mu_i_sv_copy_variables (mu_sieve_machine_t child,
mu_sieve_machine_t parent);
int mu_i_sv_expand_variables (char const *input, size_t len,
char **exp, void *data);
+void mu_i_sv_init_variables (mu_sieve_machine_t mach);
+
+
diff --git a/libmu_sieve/variables.c b/libmu_sieve/variables.c
index 37a9daf47..60a0abbf7 100644
--- a/libmu_sieve/variables.c
+++ b/libmu_sieve/variables.c
@@ -160,26 +160,11 @@ findprec (char const *name)
abort ();
}
-static int
-sieve_action_set (mu_sieve_machine_t mach)
+static void
+variable_set (mu_sieve_machine_t mach, char const *name, char *value)
{
- size_t i;
- char *name;
- char *value;
struct sieve_variable *var, **vptr;
int rc;
-
- mu_sieve_get_arg (mach, 0, SVT_STRING, &name);
- mu_sieve_get_arg (mach, 1, SVT_STRING, &value);
-
- value = mu_sieve_strdup (mach, value);
- for (i = 0; i < mach->tagcount; i++)
- {
- mu_sieve_value_t *p = mu_sieve_get_tag_n (mach, i);
- char *str = findprec (p->tag)->modify (mach, value);
- mu_sieve_free (mach, value);
- value = str;
- }
rc = mu_assoc_install_ref (mach->vartab, name, &vptr);
switch (rc)
@@ -188,7 +173,7 @@ sieve_action_set (mu_sieve_machine_t mach)
var = malloc (sizeof (*var));
if (!var)
{
- mu_sieve_error (mach, "%s", mu_strerror (errno));
+ mu_sieve_error (mach, "variable_set: %s", mu_strerror (rc));
mu_sieve_abort (mach);
}
*vptr = var;
@@ -200,12 +185,87 @@ sieve_action_set (mu_sieve_machine_t mach)
break;
default:
- mu_sieve_error (mach, "mu_assoc_ref_install: %s", mu_strerror (rc));
+ mu_sieve_error (mach, "variable_set: %s", mu_strerror (rc));
mu_sieve_abort (mach);
}
var->value = value;
+}
+
+static int
+sieve_action_set (mu_sieve_machine_t mach)
+{
+ size_t i;
+ char *name;
+ char *value;
+
+ mu_sieve_get_arg (mach, 0, SVT_STRING, &name);
+ mu_sieve_get_arg (mach, 1, SVT_STRING, &value);
+
+ value = mu_sieve_strdup (mach, value);
+ for (i = 0; i < mach->tagcount; i++)
+ {
+ mu_sieve_value_t *p = mu_sieve_get_tag_n (mach, i);
+ char *str = findprec (p->tag)->modify (mach, value);
+ mu_sieve_free (mach, value);
+ value = str;
+ }
+
+ variable_set (mach, name, value);
return 0;
-}
+}
+
+static int
+varini_append (mu_sieve_machine_t mach,
+ struct mu_sieve_variable_initializer *vini)
+{
+ if (!mu_sieve_has_variables (mach))
+ return EINVAL;
+ if (!mach->init_var)
+ {
+ mu_list_create (&mach->init_var);
+ mu_list_set_destroy_item (mach->init_var, mu_list_free_item);
+ }
+ return mu_list_append (mach->init_var, vini);
+}
+
+static struct mu_sieve_variable_initializer *
+varini_alloc (const char *name, const char *value)
+{
+ struct mu_sieve_variable_initializer *vini;
+ size_t namelen;
+
+ namelen = strlen (name);
+ vini = malloc (sizeof (*vini) + namelen + strlen (value) + 2);
+ if (vini)
+ {
+ char *p = (char*) (vini + 1);
+ vini->name = p;
+ vini->value = p + namelen + 1;
+ strcpy (vini->name, name);
+ strcpy (vini->value, value);
+ }
+ return vini;
+}
+
+int
+mu_sieve_variable_initialize (mu_sieve_machine_t mach, char const *name,
+ char const *value)
+{
+ struct mu_sieve_variable_initializer *vini;
+ int rc;
+
+ if (!name || !value)
+ return EINVAL;
+ if (!mu_sieve_has_variables (mach))
+ return EINVAL;
+ vini = varini_alloc (name, value);
+ if (!vini)
+ return ENOMEM;
+ rc = varini_append (mach, vini);
+ if (rc)
+ free (vini);
+ return rc;
+}
static int
set_tag_checker (mu_sieve_machine_t mach)
@@ -414,15 +474,32 @@ mu_sieve_has_variables (mu_sieve_machine_t mach)
return mach->vartab != NULL;
}
+static int
+copy_init_var (void *item, void *data)
+{
+ struct mu_sieve_variable_initializer *vini = item, *vini_new;
+ mu_sieve_machine_t mach = data;
+ vini_new = varini_alloc (vini->name, vini->value);
+ if (!vini_new)
+ return ENOMEM;
+ return varini_append (mach, vini_new);
+}
+
void
mu_i_sv_copy_variables (mu_sieve_machine_t child, mu_sieve_machine_t parent)
{
mu_iterator_t itr;
-
+ int rc;
+
mu_sieve_require_variables (child);
- mu_assoc_get_iterator (parent->vartab, &itr);
-
+ rc = mu_assoc_get_iterator (parent->vartab, &itr);
+ if (rc)
+ {
+ mu_sieve_error (child, "mu_assoc_get_iterator: %s", mu_strerror (rc));
+ mu_sieve_abort (child);
+ }
+
for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
mu_iterator_next (itr))
{
@@ -438,7 +515,33 @@ mu_i_sv_copy_variables (mu_sieve_machine_t child, mu_sieve_machine_t parent)
mu_assoc_install (child->vartab, name, newval);
}
- mu_iterator_destroy (&itr);
+ mu_iterator_destroy (&itr);
+
+ rc = mu_list_foreach (parent->init_var, copy_init_var, child);
+ if (rc)
+ {
+ mu_sieve_error (child, "copy_init_var: %s", mu_strerror (rc));
+ mu_sieve_abort (child);
+ }
+}
+
+static int
+sieve_setvar (void *item, void *data)
+{
+ struct mu_sieve_variable_initializer *vini = item;
+ mu_sieve_machine_t mach = data;
+ variable_set (mach, vini->name, mu_sieve_strdup (mach, vini->value));
+ return 0;
+}
+
+void
+mu_i_sv_init_variables (mu_sieve_machine_t mach)
+{
+ if (mu_sieve_has_variables (mach))
+ {
+ mu_assoc_clear (mach->vartab);
+ mu_list_foreach (mach->init_var, sieve_setvar, mach);
+ }
}

Return to:

Send suggestions and report system problems to the System administrator.