commit-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Mailutils branch, master, updated. release-3.0-38-g57e0b97


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-3.0-38-g57e0b97
Date: Sun, 11 Dec 2016 16:18:00 +0000 (UTC)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Mailutils".

http://git.savannah.gnu.org/cgit/mailutils.git/commit/?id=57e0b97994f04b8d3f36ef3c45a99941b4f011bc

The branch, master has been updated
       via  57e0b97994f04b8d3f36ef3c45a99941b4f011bc (commit)
      from  44f87939efa0a33e8d1f26b9d9fa3e15c32d808a (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 57e0b97994f04b8d3f36ef3c45a99941b4f011bc
Author: Sergey Poznyakoff <address@hidden>
Date:   Sun Dec 11 18:10:47 2016 +0200

    Support for environment extension (RFC 5183).
    
    * include/mailutils/sieve.h (mu_sieve_require_environment): New proto.
    * libmu_sieve/Makefile.am: Add environment.c
    * libmu_sieve/environment.c: New file.
    * libmu_sieve/require.c: Handle "environment" keyword.
    * libmu_sieve/sieve-priv.h (mu_sieve_machine) <exenv>: New member.
    * libmu_sieve/sieve.l: Bugfixes
    * libmu_sieve/variables.c: Add missing static qualifiers
    * sieve/sieve.c: New option --environment

-----------------------------------------------------------------------

Summary of changes:
 gint                      |    2 +-
 include/mailutils/sieve.h |    7 ++
 libmu_sieve/Makefile.am   |    1 +
 libmu_sieve/environment.c |  226 +++++++++++++++++++++++++++++++++++++++++++++
 libmu_sieve/require.c     |    2 +
 libmu_sieve/sieve-priv.h  |    4 +-
 libmu_sieve/sieve.l       |   30 +++---
 libmu_sieve/variables.c   |    4 +-
 sieve/sieve.c             |   43 ++++++++-
 9 files changed, 301 insertions(+), 18 deletions(-)
 create mode 100644 libmu_sieve/environment.c

diff --git a/gint b/gint
index 42f4712..fd86bf7 160000
--- a/gint
+++ b/gint
@@ -1 +1 @@
-Subproject commit 42f4712085b40173eaea58e14b1a579291a6fe3a
+Subproject commit fd86bf7d44b0c970771830692ae7491447ebe8b1
diff --git a/include/mailutils/sieve.h b/include/mailutils/sieve.h
index bbaccb5..4e07497 100644
--- a/include/mailutils/sieve.h
+++ b/include/mailutils/sieve.h
@@ -205,6 +205,8 @@ int mu_sieve_require_relational (mu_sieve_machine_t mach, 
const char *name);
 int mu_sieve_require_variables (mu_sieve_machine_t mach);
 int mu_sieve_has_variables (mu_sieve_machine_t mach);
 
+int mu_sieve_require_environment (mu_sieve_machine_t mach);
+
 void *mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name);
 void mu_sieve_unload_ext (void *handle);
   
@@ -292,6 +294,11 @@ void mu_sieve_set_daemon_email (mu_sieve_machine_t mach, 
const char *email);
 
 int mu_sieve_get_message_sender (mu_message_t msg, char **ptext);
 
+int mu_sieve_get_environ (mu_sieve_machine_t mach, char const *name,
+                         char **retval);
+int mu_sieve_set_environ (mu_sieve_machine_t mach, char const *name,
+                         char const *value);
+
 /* Stream state saving & restoring */
 void mu_sieve_stream_save (mu_sieve_machine_t mach);
 void mu_sieve_stream_restore (mu_sieve_machine_t mach);
diff --git a/libmu_sieve/Makefile.am b/libmu_sieve/Makefile.am
index a0ce50b..fd96ac5 100644
--- a/libmu_sieve/Makefile.am
+++ b/libmu_sieve/Makefile.am
@@ -31,6 +31,7 @@ libmu_sieve_la_SOURCES = \
  conf.c\
  comparator.c\
  encoded.c\
+ environment.c\
  load.c\
  mem.c\
  prog.c\
diff --git a/libmu_sieve/environment.c b/libmu_sieve/environment.c
new file mode 100644
index 0000000..9de4862
--- /dev/null
+++ b/libmu_sieve/environment.c
@@ -0,0 +1,226 @@
+/* The Sieve "environment" extension for GNU Mailutils
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   GNU Mailutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GNU Mailutils is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with GNU Mailutils.  If not, see
+   <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif  
+#include <sieve-priv.h>
+
+int
+retrieve_env (void *item, void *data, size_t idx, char **pval)
+{
+  mu_sieve_machine_t mach;
+
+  if (idx)
+    return MU_ERR_NOENT;
+  mach = data;
+  return mu_sieve_get_environ (mach, item, pval);
+}
+
+static int
+sieve_test_environment (mu_sieve_machine_t mach)
+{
+  mu_sieve_value_t *name, *key_list;
+  
+  name = mu_sieve_get_arg_untyped (mach, 0);
+  key_list = mu_sieve_get_arg_untyped (mach, 1);
+
+  return mu_sieve_vlist_compare (mach, name, key_list, retrieve_env, NULL,
+                                mach);
+}
+
+static mu_sieve_data_type environ_args[] = {
+  SVT_STRING,
+  SVT_STRING_LIST,
+  SVT_VOID
+};
+
+static mu_sieve_tag_group_t environ_tag_groups[] = {
+  { mu_sieve_match_part_tags, mu_sieve_match_part_checker },
+  { NULL }
+};
+
+int
+mu_sieve_require_environment (mu_sieve_machine_t mach)
+{
+  mu_sieve_register_test (mach, "environment", sieve_test_environment,
+                         environ_args, environ_tag_groups, 1);
+  return 0;
+}
+
+static char *
+std_name_get (mu_sieve_machine_t mach)
+{
+  return strdup (PACKAGE_NAME);
+}
+
+static char *
+std_version_get (mu_sieve_machine_t mach)
+{
+  return strdup (PACKAGE_VERSION);
+}
+
+/*  "host"    => The fully-qualified domain name of the host where
+                 the Sieve script is executing.
+*/
+static char *
+std_host_get (mu_sieve_machine_t mach)
+{
+  char *host;
+  int rc;
+  
+  rc = mu_get_host_name (&host);
+  if (rc == 0)
+    return host;
+  return NULL;
+}
+
+
+/*  "domain"  => The primary DNS domain associated with the Sieve
+                 execution context, usually but not always a proper
+                 suffix of the host name.
+*/
+static char *
+std_domain_get (mu_sieve_machine_t mach)
+{
+  char *host;
+  int rc;
+  
+  rc = mu_get_host_name (&host);
+  if (rc == 0)
+    {
+      char *p = strchr (host, '.');
+      if (p)
+       {
+         p = strdup (p + 1);
+         free (host);
+         return p;
+       }
+      return host;
+    }
+  return NULL;
+}
+
+/* FIXME: do we need set? If so, mu_set_host_name is also needed */
+
+struct stdenviron
+{
+  char *name;
+  char *(*get) (mu_sieve_machine_t);
+  int (*set) (mu_sieve_machine_t, char const *, char const *value);
+};
+
+static struct stdenviron stdenv[] =
+{
+  { "domain", std_domain_get, NULL },
+  { "host", std_host_get, NULL },
+  { "name", std_name_get, NULL },
+  { "version", std_version_get, NULL },
+  { NULL }
+};
+
+static struct stdenviron const *
+stdenv_find (char const *name)
+{
+  struct stdenviron const *p;
+
+  for (p = stdenv; p->name; p++)
+    if (strcmp (p->name, name) == 0)
+      return p;
+  return NULL;
+}
+
+static char *
+stdenv_get (mu_sieve_machine_t mach, char const *name)
+{
+  struct stdenviron const *p = stdenv_find (name);
+  if (!p)
+    return NULL;
+  return p->get (mach);
+}
+
+static int
+stdenv_set (mu_sieve_machine_t mach, char const *name, char const *value)
+{
+  struct stdenviron const *p = stdenv_find (name);
+  if (!p)
+    return MU_ERR_NOENT;
+  if (!p->set)
+    return EACCES;
+  return p->set (mach, name, value);
+}
+
+int
+mu_sieve_get_environ (mu_sieve_machine_t mach, char const *name, char **retval)
+{
+  char *p;
+
+  p = stdenv_get (mach, name);
+  if (p)
+    {
+      *retval = p;
+      return 0;
+    }
+
+  if (!mach->exenv)
+    return MU_ERR_NOENT;
+
+  p = mu_assoc_ref (mach->exenv, name);
+  if (p)
+    {
+      *retval = strdup (*(char**)p);
+      if (!*retval)
+       return errno;
+    }
+  else
+    return MU_ERR_NOENT;
+  return 0;
+}
+
+int
+mu_sieve_set_environ (mu_sieve_machine_t mach, char const *name,
+                     char const *value)
+{
+  int rc;
+
+  rc = stdenv_set (mach, name, value);
+  if (rc == MU_ERR_NOENT)
+    {
+      char **pptr;
+      
+      if (!mach->exenv)
+       {
+          int rc = mu_assoc_create (&mach->exenv, sizeof (char *), 0);
+         if (rc)
+           return rc;
+       }
+      rc = mu_assoc_ref_install (mach->exenv, name, (void **) &pptr);
+      if (rc == 0 || rc == MU_ERR_EXISTS)
+       {
+         char *copy = strdup (value);
+         if (!copy)
+           rc = errno;
+         else
+           {
+             *pptr = copy;
+             rc = 0;
+           }
+       }
+    }
+  return rc;
+}
+    
diff --git a/libmu_sieve/require.c b/libmu_sieve/require.c
index f0ff27c..c8f5b62 100644
--- a/libmu_sieve/require.c
+++ b/libmu_sieve/require.c
@@ -43,6 +43,8 @@ mu_sieve_require (mu_sieve_machine_t mach, mu_sieve_slice_t 
list)
        rc = mu_sieve_require_relational (mach, name);
       else if (strcmp (name, "encoded-character") == 0) /* RFC 5228, 2.4.2.4 */
        rc = mu_sieve_require_encoded_character (mach, name);
+      else if (strcmp (name, "environment") == 0) /* RFC 5183 */
+       rc = mu_sieve_require_environment (mach);
       else if (strncmp (name, "comparator-", 11) == 0)
        rc = mu_sieve_registry_require (mach, name + 11,
                                        mu_sieve_record_comparator);
diff --git a/libmu_sieve/sieve-priv.h b/libmu_sieve/sieve-priv.h
index f5fb38a..b288f21 100644
--- a/libmu_sieve/sieve-priv.h
+++ b/libmu_sieve/sieve-priv.h
@@ -107,7 +107,9 @@ struct mu_sieve_machine
 
   int dry_run;               /* Dry-run mode */
   jmp_buf errbuf;            /* Target location for non-local exits */
-  
+
+  mu_assoc_t exenv;          /* Execution environment (RFC 5183) */
+
   mu_mailbox_t mailbox;      /* Mailbox to operate upon */
   size_t    msgno;           /* Current message number */
   mu_message_t msg;          /* Current message */
diff --git a/libmu_sieve/sieve.l b/libmu_sieve/sieve.l
index b18cd4a..ffc7a4a 100644
--- a/libmu_sieve/sieve.l
+++ b/libmu_sieve/sieve.l
@@ -41,10 +41,11 @@ static int strip_tabs;
 static int number (void);
 static int string (void);
 static void line_begin (void);
-static void line_add (char *text, size_t len);
+static void line_add (char const *text, size_t len);
+static void line_addz (char const *text); 
 static void line_finish (void);
 static void multiline_begin (void);
-static void multiline_add (char *);
+static void multiline_add (void);
 static void multiline_finish (void);
 static char *multiline_strip_tabs (char *text);
 static void ident (const char *text);
@@ -286,8 +287,8 @@ true    return TRUE;
 \"[^\\"\n]*\"                 { return string (); }
 \"[^\\"\n]*\\.    { BEGIN(STR);
                     line_begin ();
-                   line_add (str_unescape (yytext + 1, yyleng - 1), 0); }
-<STR>[^\\"\n]*\\. { line_add (str_unescape (yytext, yyleng), 0); }
+                   line_addz (str_unescape (yytext + 1, yyleng - 1)); }
+<STR>[^\\"\n]*\\. { line_addz (str_unescape (yytext, yyleng)); }
 <STR>[^\\"\n]*\" { BEGIN(INITIAL);
                   if (yyleng > 1) 
                      line_add (yytext, yyleng - 1); 
@@ -303,7 +304,7 @@ text:-?\\?{IDENT}[ \t]*#.*\n { BEGIN(ML);
 text:-?\\?{IDENT}[ \t]*\n    { BEGIN(ML);
                                multiline_begin (); }
 <ML>#[ \t]*include.*\n    { if (multiline_delimiter[0] == '\\')
-                              multiline_add (NULL);
+                              multiline_add ();
                             else
                               sieve_include (); }
 <ML>.*\n { char *p = multiline_strip_tabs (yytext);
@@ -318,7 +319,7 @@ text:-?\\?{IDENT}[ \t]*\n    { BEGIN(ML);
               multiline_finish ();
               return MULTILINE;
             }
-           multiline_add (NULL); } 
+           multiline_add (); } 
 {WS}     ;
          /* Other tokens */
 \n       ;
@@ -527,19 +528,22 @@ multiline_strip_tabs (char *text)
 }
 
 static void
-line_add (char *text, size_t len)
+line_add (char const *text, size_t len)
 {
-  if (len == 0)
-    len = strlen (text);
   mu_opool_append (mu_sieve_machine->string_pool, text, len);
 }
 
 static void
-multiline_add (char *s)
+line_addz (char const *text)
 {
-  if (!s)
-    s = multiline_strip_tabs (yytext);
-  mu_opool_appendz (mu_sieve_machine->string_pool, s);
+  mu_opool_appendz (mu_sieve_machine->string_pool, text);
+}
+
+static void
+multiline_add (void)
+{
+  mu_opool_appendz (mu_sieve_machine->string_pool,
+                   multiline_strip_tabs (yytext));
 }
 
 static void
diff --git a/libmu_sieve/variables.c b/libmu_sieve/variables.c
index 3474577..c73b7e8 100644
--- a/libmu_sieve/variables.c
+++ b/libmu_sieve/variables.c
@@ -284,13 +284,13 @@ sieve_test_string (mu_sieve_machine_t mach)
                                 retrieve_string, fold_string, mach);
 }
 
-mu_sieve_data_type string_args[] = {
+static mu_sieve_data_type string_args[] = {
   SVT_STRING_LIST,
   SVT_STRING_LIST,
   SVT_VOID
 };
 
-mu_sieve_tag_group_t string_tag_groups[] = {
+static mu_sieve_tag_group_t string_tag_groups[] = {
   { mu_sieve_match_part_tags, mu_sieve_match_part_checker },
   { NULL }
 };
diff --git a/sieve/sieve.c b/sieve/sieve.c
index 4831307..edf3b75 100644
--- a/sieve/sieve.c
+++ b/sieve/sieve.c
@@ -61,6 +61,21 @@ static int sieve_print_locus = 1; /* Should the log messages 
include the
                                     locus */
 static int no_program_name;
 
+static mu_list_t env_list;
+
+static int
+sieve_setenv (void *item, void *data)
+{
+  char *str = item;
+  mu_sieve_machine_t mach = data;
+  int rc = mu_sieve_set_environ (mach, str, str + strlen (str) + 1);
+  if (rc)
+    mu_error (_("can't set environment item %s: %s"),
+             str, mu_strerror (rc));
+  return 0;
+}
+
+
 static void
 modify_debug_flags (mu_debug_level_t set, mu_debug_level_t clr)
 {
@@ -125,6 +140,27 @@ cli_email (struct mu_parseopt *po, struct mu_option *opt, 
char const *arg)
     mu_parseopt_error (po, _("invalid email: %s"), mu_strerror (rc));
 }
 
+static void
+cli_env (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  char *p = strchr (arg, '=');
+  if (p == NULL)
+    mu_parseopt_error (po, _("malformed environment setting: %s"), arg);
+  else
+    {
+      char *str;
+
+      str = mu_strdup (arg);
+      str[p - arg] = 0;
+      if (!env_list)
+       {
+         mu_list_create (&env_list);
+         mu_list_set_destroy_item (env_list, mu_list_free_item);
+       }
+      mu_list_append (env_list, str);
+    }
+}
+
 static struct mu_option sieve_options[] = {
   { "dry-run", 'n', NULL, MU_OPTION_DEFAULT,
     N_("do not execute any actions, just print what would be done"),
@@ -163,6 +199,9 @@ static struct mu_option sieve_options[] = {
   { "no-program-name", 0, NULL, MU_OPTION_DEFAULT,
     N_("do not prefix diagnostic messages with the program name"),
     mu_c_int, &no_program_name },
+  { "environment", 0, N_("NAME=VALUE"), MU_OPTION_DEFAULT,
+    N_("set sieve environment value"),
+    mu_c_string, NULL, cli_env },
   MU_OPTION_END
 }, *options[] = { sieve_options, NULL };
 
@@ -445,7 +484,9 @@ main (int argc, char *argv[])
       mu_error (_("cannot initialize sieve machine: %s"), mu_strerror (rc));
       return EX_SOFTWARE;
     }
-
+  mu_list_foreach (env_list, sieve_setenv, mach);
+  mu_list_destroy (&env_list);
+    
   if (verbose)
     mu_sieve_set_logger (mach, _sieve_action_log);
 


hooks/post-receive
-- 
GNU Mailutils



reply via email to

[Prev in Thread] Current Thread [Next in Thread]