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-2.2-247-g38d688c


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-247-g38d688c
Date: Thu, 02 Dec 2010 08:25:08 +0000

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=38d688c17f9545c032e22f117189b970e858697d

The branch, master has been updated
       via  38d688c17f9545c032e22f117189b970e858697d (commit)
      from  0fac46ab0e306070a46c5016cf2cf52c776c791c (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 38d688c17f9545c032e22f117189b970e858697d
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Dec 2 10:14:43 2010 +0200

    Avoid using strtok(_r)
    
    * TODO: Update.
    * gnulib.modules: Remove strtok_r
    * imap4d/auth_gsasl.c (auth_gsasl_capa_init): Use mu_wordsplit instead
    of strtok.
    * imap4d/imap4d.h (strtok_r): Remove declaration.
    * lib/mailcap.c (mime_context) <no_ask_str>: Remove. All uses updated.
    (mime_context_fill): Use mu_wordsplit instead
    of strtok.
    (mime_context_write_input): Tolerate ENOSYS return from mu_stream_seek.
    (display_stream_mailcap): Use mu_wordsplit instead
    of strtok.
    * libmailutils/diag/gdebug.c (mu_debug_level_from_string)
    (mu_global_debug_from_string): Use mu_wordsplit instead of strtok.
    * libmu_cfg/sieve.c (_add_path): Likewise.
    * libmu_sieve/extensions/list.c: Likewise.
    * mail/escape.c (quote0): Likewise.
    
    * mail/util.c (util_header_expand): Likewise.
    (util_rfc2047_decode): Use mu_parse_lc_all.
    * mh/mh_init.c (mh_charset): Use mu_parse_lc_all.
    * frm/common.c (get_charset): Use mu_parse_lc_all.
    
    * libmailutils/base/lcall.c: New file.
    * libmailutils/base/Makefile.am (libbase_la_SOURCES): Add lcall.c
    * libmailutils/string/strlst.c: New file.
    * libmailutils/string/Makefile.am (libstring_la_SOURCES): Add strlst.c.
    * include/mailutils/cstr.h: Include mailutils/types.h
    (mu_string_split): New proto.
    * include/mailutils/nls.h (MU_LC_LANG, MU_LC_TERR)
    (MU_LC_CSET,MU_LC_MOD): New flags.
    (mu_lc_all): New struct.
    (mu_parse_lc_all, mu_lc_all_free): New protos.
    (mu_charset_lookup): New proto (from util.h).
    * include/mailutils/util.h (mu_charset_lookup): Move to nls.h
    
    * libmailutils/base/tempfile.c (mu_tempname): Shut up compiler
    warning.

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

Summary of changes:
 TODO                            |   10 +++-
 frm/common.c                    |   24 ++------
 gnulib.modules                  |    1 -
 imap4d/auth_gsasl.c             |   34 ++++++++---
 imap4d/imap4d.h                 |    4 -
 include/mailutils/cstr.h        |    4 +
 include/mailutils/nls.h         |   18 +++++
 include/mailutils/util.h        |    1 -
 lib/mailcap.c                   |   85 ++++++++++++++++---------
 libmailutils/base/Makefile.am   |    1 +
 libmailutils/base/lcall.c       |  131 +++++++++++++++++++++++++++++++++++++++
 libmailutils/base/tempfile.c    |    2 +-
 libmailutils/diag/gdebug.c      |   39 +++++++++---
 libmailutils/stream/streamref.c |    2 +-
 libmailutils/string/Makefile.am |    1 +
 libmailutils/string/strlst.c    |   72 +++++++++++++++++++++
 libmu_cfg/sieve.c               |    8 +--
 libmu_sieve/extensions/list.c   |   69 +++++++++++++-------
 mail/escape.c                   |   28 +++-----
 mail/util.c                     |   91 ++++++++++++++-------------
 mh/mh_init.c                    |   25 +++-----
 sieve/sieve.c                   |    2 +-
 22 files changed, 464 insertions(+), 188 deletions(-)
 create mode 100644 libmailutils/base/lcall.c
 create mode 100644 libmailutils/string/strlst.c

diff --git a/TODO b/TODO
index e8c21f6..bf074a4 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-GNU mailutils TODO list. 2010-12-01
+GNU mailutils TODO list. 2010-12-02
 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 Free
 Software Foundation, Inc.
 
@@ -12,7 +12,9 @@ Software Foundation, Inc.
 
 * use the above in message_stream.
 
-* eliminate uses of strtok(_r)
+* envelope: date returned by mu_envelope_?get_date must not end with a \n
+
+See also mu_rfc2822_in_reply_to.
 
 * mail: rewrite I/O support using streams.
 
@@ -51,6 +53,10 @@ See guimb/scm/Makefile.am for a discussion.
 
 * lib/mailcap.c: rewrite using streams
 
+* sieve: needs an option to add directory at the head of the search path
+
+* sieve: extension tests
+
 * mu_address_createv: pass hints as in mu_address_create_hint?
 
 * fix Python support
diff --git a/frm/common.c b/frm/common.c
index a604a2d..0045e60 100644
--- a/frm/common.c
+++ b/frm/common.c
@@ -63,10 +63,6 @@ get_charset ()
   if (!output_charset)
     {
       char *tmp;
-      const char *str = NULL;
-      char locale[32];
-      
-      memset (locale, 0, sizeof (locale));
 
       /* Try to deduce the charset from LC_ALL or LANG variables */
 
@@ -76,24 +72,14 @@ get_charset ()
 
       if (tmp)
        {
-         char *sp = NULL;
-         char *lang;
-         char *terr;
-
-         strncpy (locale, tmp, sizeof (locale) - 1);
+         struct mu_lc_all lc_all;
          
-         lang = strtok_r (locale, "_", &sp);
-         terr = strtok_r (NULL, ".", &sp);
-         str = strtok_r (NULL, "@", &sp);
-
-         if (!str)
-           str = mu_charset_lookup (lang, terr);
+         if (mu_parse_lc_all (tmp, &lc_all, MU_LC_CSET) == 0)
+           output_charset = lc_all.charset;
        }
       
-      if (!str)
-       str = "ASCII";
-
-      output_charset = xstrdup (str);
+      if (!output_charset)
+       output_charset = xstrdup ("ASCII");
     }
   return output_charset;
 }
diff --git a/gnulib.modules b/gnulib.modules
index cedbcb7..b161796 100644
--- a/gnulib.modules
+++ b/gnulib.modules
@@ -21,5 +21,4 @@ obstack
 realloc
 setenv
 stdint
-strtok_r
 xalloc
diff --git a/imap4d/auth_gsasl.c b/imap4d/auth_gsasl.c
index 0c09d2c..54e206a 100644
--- a/imap4d/auth_gsasl.c
+++ b/imap4d/auth_gsasl.c
@@ -181,21 +181,37 @@ static void
 auth_gsasl_capa_init (int disable)
 {
   int rc;
-  char *listmech, *name, *s;
-
+  char *listmech;
+  struct mu_wordsplit ws;
+  
   rc =  gsasl_server_mechlist (ctx, &listmech);
   if (rc != GSASL_OK)
     return;
 
-  for (name = strtok_r (listmech, " ", &s); name;
-       name = strtok_r (NULL, " ", &s))
+  ws.ws_delim = " ";
+  if (mu_wordsplit (listmech, &ws,
+                   MU_WRDSF_DELIM|MU_WRDSF_SQUEEZE_DELIMS|
+                   MU_WRDSF_NOVAR|MU_WRDSF_NOCMD))
     {
-      if (disable)
-       auth_remove (name);
-      else
-       auth_add (strdup (name), auth_gsasl);
+      mu_error (_("cannot split line `%s': %s"), listmech,
+               mu_wordsplit_strerror (&ws));
+    }
+  else
+    {
+      size_t i;
+
+      for (i = 0; i < ws.ws_wordc; i++)
+       {
+         if (disable)
+           auth_remove (ws.ws_wordv[i]);
+         else
+           {
+             auth_add (ws.ws_wordv[i], auth_gsasl);
+             ws.ws_wordv[i] = NULL;
+           }
+       }
+      mu_wordsplit_free (&ws);
     }
-      
   free (listmech);
 }
 
diff --git a/imap4d/imap4d.h b/imap4d/imap4d.h
index e542908..5798a51 100644
--- a/imap4d/imap4d.h
+++ b/imap4d/imap4d.h
@@ -201,10 +201,6 @@ extern mu_list_t imap4d_id_list;
 extern int imap4d_argc;                 
 extern char **imap4d_argv;
 
-#ifndef HAVE_STRTOK_R
-extern char *strtok_r (char *s, const char *delim, char **save_ptr);
-#endif
-
 /* Input functions */
 extern mu_stream_t iostream;
 extern int  io_untagged_response (int, const char *, ...) MU_PRINTFLIKE(2,3);
diff --git a/include/mailutils/cstr.h b/include/mailutils/cstr.h
index 0914df7..631271c 100644
--- a/include/mailutils/cstr.h
+++ b/include/mailutils/cstr.h
@@ -22,6 +22,8 @@
 extern "C" {
 #endif
 
+# include <mailutils/types.h>
+  
 int mu_strlower (char *);
 int mu_strupper (char *);
 
@@ -41,6 +43,8 @@ char *mu_str_skip_class_comp (const char *str, int __class);
 char *mu_str_skip_cset_comp (const char *str, const char *cset);
 
 char *mu_str_stripws (char *string);  
+
+int mu_string_split (const char *string, char *delim, mu_list_t list);
   
 #ifdef __cplusplus
 }
diff --git a/include/mailutils/nls.h b/include/mailutils/nls.h
index 9617d0b..2ad68c8 100644
--- a/include/mailutils/nls.h
+++ b/include/mailutils/nls.h
@@ -46,6 +46,24 @@ extern void mu_init_nls (void);
 extern char *mu_set_locale (const char *locale);
 void mu_restore_locale (void);
 
+#define MU_LC_LANG 0x01
+#define MU_LC_TERR 0x02
+#define MU_LC_CSET 0x04
+#define MU_LC_MOD  0x08
+
+struct mu_lc_all
+{
+  int flags;
+  char *language;
+  char *territory;
+  char *charset;
+  char *modifier;
+};
+
+int mu_parse_lc_all (const char *arg, struct mu_lc_all *str, int flags);  
+void mu_lc_all_free (struct mu_lc_all *str);
+const char *mu_charset_lookup (char *lang, char *terr);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mailutils/util.h b/include/mailutils/util.h
index 0df84a8..fe0327a 100644
--- a/include/mailutils/util.h
+++ b/include/mailutils/util.h
@@ -176,7 +176,6 @@ int mu_getpass (mu_stream_t in, mu_stream_t out, const char 
*prompt,
 /* Get the host name, doing a gethostbyname() if possible. */
 int mu_get_host_name (char **host);
 int mu_spawnvp(const char *prog, char *av[], int *stat);
-const char *mu_charset_lookup (char *lang, char *terr);
 int mu_scheme_autodetect_p (mu_url_t);
 
 struct timeval; 
diff --git a/lib/mailcap.c b/lib/mailcap.c
index cbe9e1e..d675ebc 100644
--- a/lib/mailcap.c
+++ b/lib/mailcap.c
@@ -53,7 +53,6 @@ struct mime_context
   char *temp_file;
   int unlink_temp_file;
 
-  char *no_ask_str;
   mu_list_t no_ask_types;
   int debug_level;
   int flags;
@@ -66,15 +65,28 @@ mime_context_fill (struct mime_context *ctx, const char 
*file,
                   mu_stream_t input, mu_header_t hdr, const char *no_ask,
                   int interactive, int dry_run, int debug_level)
 {
-  char *p, *sp;
- 
+  struct mu_wordsplit ws;
+  size_t i;
+  
   memset (ctx, 0, sizeof *ctx);
   ctx->input = input;
   ctx->hdr = hdr;
   if (mu_header_aget_value (hdr, MU_HEADER_CONTENT_TYPE,
-                        &ctx->content_type_buffer))
+                           &ctx->content_type_buffer))
     return 1;
-  ctx->content_type = strtok_r (ctx->content_type_buffer, ";", &sp);
+  ws.ws_delim = ";";
+  if (mu_wordsplit (ctx->content_type_buffer, &ws,
+                   MU_WRDSF_DELIM|MU_WRDSF_SQUEEZE_DELIMS|MU_WRDSF_WS|
+                   MU_WRDSF_NOVAR|MU_WRDSF_NOCMD))
+    {
+      mu_error (_("cannot split line `%s': %s"),
+               ctx->content_type_buffer,
+               mu_wordsplit_strerror (&ws));
+      return 1;
+    }
+
+  ctx->content_type = ws.ws_wordv[0];
+  ws.ws_wordv[0] = NULL;
   ctx->temp_file = file ? strdup (file) : NULL; 
   ctx->unlink_temp_file = 0;
 
@@ -85,24 +97,20 @@ mime_context_fill (struct mime_context *ctx, const char 
*file,
   ctx->debug_level = debug_level;
   
   mu_list_create (&ctx->values);
-  while ((p = strtok_r (NULL, ";", &sp)))
+
+  for (i = 1; i < ws.ws_wordc; i++)
     {
-      while (*p && isspace (*p))
-       p++;
-      mu_list_append (ctx->values, p);
+      mu_list_append (ctx->values, ws.ws_wordv[i]);
+      ws.ws_wordv[i] = NULL;
     }
+  mu_wordsplit_free (&ws);
   
   if (no_ask)
     {
-      ctx->no_ask_str = xstrdup (no_ask);
       mu_list_create (&ctx->no_ask_types);
-      for (p = strtok_r (ctx->no_ask_str, ",", &sp); p;
-          p = strtok_r (NULL, ",", &sp))
-       {
-         while (*p && isspace (*p))
-           p++;
-         mu_list_append (ctx->no_ask_types, p);
-       }
+      mu_list_set_destroy_item (ctx->no_ask_types, mu_list_free_item);
+      if (mu_string_split (no_ask, ",", ctx->no_ask_types))
+       return 1;
     }
   return 0;
 }
@@ -115,7 +123,6 @@ mime_context_release (struct mime_context *ctx)
     unlink (ctx->temp_file);
   free (ctx->temp_file);
   mu_list_destroy (&ctx->values);
-  free (ctx->no_ask_str);
   mu_list_destroy (&ctx->no_ask_types);
 }
 
@@ -208,8 +215,11 @@ mime_context_write_input (struct mime_context *ctx, int fd)
   
   mime_context_get_input (ctx, &input);
   status = mu_stream_seek (input, 0, SEEK_SET, NULL);
-  if (status)
-    abort (); /* FIXME */
+  if (status && status != ENOSYS)
+    {
+      mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_seek", NULL, status);
+      abort (); /* FIXME */
+    }
   while ((status = mu_stream_read (input, buf, sizeof buf, &n)) == 0
         && n)
     write (fd, buf, n);
@@ -661,8 +671,8 @@ display_stream_mailcap (const char *ident, mu_stream_t 
stream, mu_header_t hdr,
                        const char *no_ask, int interactive, int dry_run,
                        int debug_level)
 {
-  char *p, *sp;
-  char *mailcap_path;
+  char *mailcap_path, *mailcap_path_tmp = NULL;
+  struct mu_wordsplit ws;
   struct mime_context ctx;
   int rc = 1;
   
@@ -673,24 +683,37 @@ display_stream_mailcap (const char *ident, mu_stream_t 
stream, mu_header_t hdr,
   if (!mailcap_path)
     {
       char *home = mu_get_homedir ();
-      mu_asprintf (&mailcap_path, "%s/.mailcap:%s", home, DEFAULT_MAILCAP);
+      mailcap_path_tmp = mu_make_file_name_suf (home, ".mailcap:",
+                                               DEFAULT_MAILCAP);
       free (home);
-      if (!mailcap_path)
+      if (!mailcap_path_tmp)
         return 1;
+      mailcap_path = mailcap_path_tmp;
     }
-  else
-    mailcap_path = strdup (mailcap_path);
   
   obstack_init (&expand_stack);
-  
-  for (p = strtok_r (mailcap_path, ":", &sp); p; p = strtok_r (NULL, ":", &sp))
+
+  ws.ws_delim = ":";
+  if (mu_wordsplit (mailcap_path, &ws,
+                   MU_WRDSF_DELIM|MU_WRDSF_SQUEEZE_DELIMS|
+                   MU_WRDSF_NOVAR|MU_WRDSF_NOCMD))
     {
-      if ((rc = find_entry (p, &ctx)) == 0)
-       break;
+      mu_error (_("cannot split line `%s': %s"), mailcap_path,
+               mu_wordsplit_strerror (&ws));
     }
+  else
+    {
+      size_t i;
 
+      for (i = 0; i < ws.ws_wordc; i++)
+       {
+         if ((rc = find_entry (ws.ws_wordv[i], &ctx)) == 0)
+           break;
+       }
+      mu_wordsplit_free (&ws);
+    }
   obstack_free (&expand_stack, NULL);
-  free (mailcap_path);
+  free (mailcap_path_tmp);
   mime_context_release (&ctx);
   return rc;
 }
diff --git a/libmailutils/base/Makefile.am b/libmailutils/base/Makefile.am
index 8160e04..ae9d2a9 100644
--- a/libmailutils/base/Makefile.am
+++ b/libmailutils/base/Makefile.am
@@ -36,6 +36,7 @@ libbase_la_SOURCES = \
  hostname.c\
  iterator.c\
  kwd.c\
+ lcall.c\
  list.c\
  listlist.c\
  locale.c\
diff --git a/libmailutils/base/lcall.c b/libmailutils/base/lcall.c
new file mode 100644
index 0000000..0485699
--- /dev/null
+++ b/libmailutils/base/lcall.c
@@ -0,0 +1,131 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+   Copyright (C) 2003, 2009, 2010 Free Software Foundation, Inc.
+
+   This library 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 of the License, or (at your option) any later version.
+
+   This library 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 this library.  If not, see 
+   <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <mailutils/nls.h>
+
+static int
+_parse_lc_all (const char *arg, struct mu_lc_all *str, int flags)
+{
+  char *s;
+  size_t n;
+  
+  n = strcspn (arg, "_.@");
+  if (flags & MU_LC_LANG)
+    {
+      s = malloc (n + 1);
+      if (!s)
+       return ENOMEM;
+      memcpy (s, arg, n);
+      s[n] = 0;
+      str->language = s;
+      str->flags |= MU_LC_LANG;
+    }
+  else
+    str->language = NULL;
+  arg += n;
+
+  if (arg[0] == '_')
+    {
+      arg++;
+  
+      n = strcspn (arg, ".@");
+      if (flags & MU_LC_TERR)
+       {
+         s = malloc (n + 1);
+         if (!s)
+           return ENOMEM;
+         memcpy (s, arg, n);
+         s[n] = 0;
+         str->territory = s;
+         str->flags |= MU_LC_TERR;
+       }
+      else
+       str->territory = NULL;
+      arg += n;
+    }
+
+  if (arg[0] == '.')
+    {
+      arg++;
+
+      n = strcspn (arg, "@");
+      if (flags & MU_LC_CSET)
+       {
+         s = malloc (n + 1);
+         if (!s)
+           return ENOMEM;
+         memcpy (s, arg, n);
+         s[n] = 0;
+         str->charset = s;
+         str->flags |= MU_LC_CSET;
+       }
+      else
+       str->charset = NULL;
+      arg += n;
+    }
+
+  if (arg[0])
+    {
+      arg++;
+      if (flags & MU_LC_MOD)
+       {
+         str->modifier = strdup (arg);
+         if (!str->modifier)
+           return ENOMEM;
+         str->flags |= MU_LC_MOD;
+       }
+    }
+  return 0;
+}
+
+void
+mu_lc_all_free (struct mu_lc_all *str)
+{
+  free (str->language);
+  free (str->territory);
+  free (str->charset);
+  free (str->modifier);
+}
+
+int
+mu_parse_lc_all (const char *arg, struct mu_lc_all *str, int flags)
+{
+  int rc;
+  
+  memset (str, 0, sizeof (str[0]));
+  rc = _parse_lc_all (arg, str, flags);
+  if (rc == 0 && !str->charset)
+    {
+      const char *charset = mu_charset_lookup (str->language, str->territory);
+      if (charset)
+       {
+         str->charset = strdup (charset);
+         if (!str->charset)
+           rc = ENOMEM;
+       }
+    }
+  if (rc)
+    mu_lc_all_free (str);
+  return rc;
+}
diff --git a/libmailutils/base/tempfile.c b/libmailutils/base/tempfile.c
index f494a3a..bc7da6f 100644
--- a/libmailutils/base/tempfile.c
+++ b/libmailutils/base/tempfile.c
@@ -220,7 +220,7 @@ mu_tempname (const char *tmpdir)
   struct mu_tempfile_hints hints;
   char *filename = NULL;
   int fd;
-  hints.tmpdir = tmpdir;
+  hints.tmpdir = (char*)tmpdir;
   if (mu_tempfile (&hints, MU_TEMPFILE_TMPDIR, &fd, &filename))
     return NULL;
   close (fd);
diff --git a/libmailutils/diag/gdebug.c b/libmailutils/diag/gdebug.c
index d2d89d5..edeef3e 100644
--- a/libmailutils/diag/gdebug.c
+++ b/libmailutils/diag/gdebug.c
@@ -118,15 +118,25 @@ mu_debug_level_from_string (const char *string, 
mu_log_level_t *plev,
     }
   else
     {
-      char *p = strdup (string);
-      size_t len = strlen (p);
-      if (len > 0 && p[len-1] == '\n')
-       p[len-1] = 0;
-      for (q = strtok (p, ","); q; q = strtok (NULL, ","))
+      size_t i;
+      struct mu_wordsplit ws;
+
+      if (mu_wordsplit (string, &ws,
+                       MU_WRDSF_DELIM|MU_WRDSF_SQUEEZE_DELIMS|
+                       MU_WRDSF_WS|
+                       MU_WRDSF_NOVAR|MU_WRDSF_NOCMD))
+       {
+         mu_error (_("cannot split line `%s': %s"), string,
+                   mu_wordsplit_strerror (&ws));
+         return MU_ERR_FAILURE;
+       }
+
+      for (i = 0; i < ws.ws_wordc; i++)
        {
          int flag;
          int revert = 0;
          int upto = 0;
+         const char *q = ws.ws_wordv[i];
          
          if (*q == '!')
            {
@@ -158,7 +168,7 @@ mu_debug_level_from_string (const char *string, 
mu_log_level_t *plev,
                level |= MU_DEBUG_LEVEL_MASK (flag);
            }
        }
-      free (p);
+      mu_wordsplit_free (&ws);
     }
   *plev = level;
   return 0;
@@ -207,12 +217,24 @@ mu_global_debug_from_string (const char *string, const 
char *errpfx)
            }
          else
            {
-             char *q;
-             for (q = strtok (p, ","); q; q = strtok (NULL, ","))
+             size_t j;
+             struct mu_wordsplit ws1;
+
+             ws.ws_delim = ",";
+             if (mu_wordsplit (p, &ws1,
+                               MU_WRDSF_DELIM|MU_WRDSF_NOVAR|MU_WRDSF_NOCMD))
+               {
+                 mu_error (_("cannot split line `%s': %s"), p,
+                           mu_wordsplit_strerror (&ws));
+                 return MU_ERR_FAILURE;
+               }
+
+             for (j = 0; j < ws1.ws_wordc; j++)
                {
                  int flag;
                  int revert = 0;
                  int upto = 0;
+                 const char *q = ws1.ws_wordv[j];
                  
                  if (*q == '!')
                    {
@@ -243,6 +265,7 @@ mu_global_debug_from_string (const char *string, const char 
*errpfx)
                        level |= MU_DEBUG_LEVEL_MASK (flag);
                    }
                }
+             mu_wordsplit_free (&ws1);
            }   
        }         
       else
diff --git a/libmailutils/stream/streamref.c b/libmailutils/stream/streamref.c
index 2faff48..f454d39 100644
--- a/libmailutils/stream/streamref.c
+++ b/libmailutils/stream/streamref.c
@@ -267,7 +267,7 @@ mu_streamref_create_abridged (mu_stream_t *pref, 
mu_stream_t str,
   int flags;
   struct _mu_streamref *sp;
   
-  rc = mu_stream_seek (str, 0, MU_SEEK_SET, &off);
+  rc = mu_stream_seek (str, 0, MU_SEEK_SET, &off);//FIXME: SEEK_CUR?
   if (rc)
     return rc;
   mu_stream_get_flags (str, &flags);
diff --git a/libmailutils/string/Makefile.am b/libmailutils/string/Makefile.am
index 5cb6a23..9c91e73 100644
--- a/libmailutils/string/Makefile.am
+++ b/libmailutils/string/Makefile.am
@@ -27,6 +27,7 @@ libstring_la_SOURCES = \
  strltrim.c\
  strskip.c\
  stripws.c\
+ strlst.c\
  strrtrim.c\
  trueans.c\
  unfold.c\
diff --git a/libmailutils/string/strlst.c b/libmailutils/string/strlst.c
new file mode 100644
index 0000000..e555e73
--- /dev/null
+++ b/libmailutils/string/strlst.c
@@ -0,0 +1,72 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009,
+   2010 Free Software Foundation, Inc.
+
+   This library 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 of the License, or (at your option) any later version.
+
+   This library 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 this library.  If not, see 
+   <http://www.gnu.org/licenses/>. */
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <mailutils/errno.h>
+#include <mailutils/list.h>
+#include <mailutils/wordsplit.h>
+#include <mailutils/cstr.h>
+
+int
+mu_string_split (const char *string, char *delim, mu_list_t list)
+{
+  size_t i;
+  struct mu_wordsplit ws;
+  int rc = 0;
+
+  if (!string || !delim || !list)
+    return EINVAL;
+
+  /* Split the string */
+  ws.ws_delim = delim;
+  if (mu_wordsplit (string, &ws,
+                   MU_WRDSF_DELIM|MU_WRDSF_SQUEEZE_DELIMS|
+                   MU_WRDSF_NOVAR|MU_WRDSF_NOCMD))
+    return errno;
+
+  for (i = 0; i < ws.ws_wordc; i++)
+    {
+      rc = mu_list_append (list, ws.ws_wordv[i]);
+      if (rc)
+       break;
+    }
+
+  if (rc)
+    {
+      /* If failed, restore LIST to the state before entering this
+        function. */
+      size_t j;
+      mu_list_comparator_t cptr =
+       mu_list_set_comparator (list, NULL);
+      mu_list_destroy_item_t dptr =
+       mu_list_set_destroy_item (list, NULL);
+
+      for (j = 0; j < i; j++)
+       mu_list_remove (list, ws.ws_wordv[j]);
+      mu_list_set_destroy_item (list, dptr);
+      mu_list_set_comparator (list, cptr);
+    }
+  else
+    /* Make sure ws.ws_wordv[x] are not freed */
+    ws.ws_wordc = 0;
+  mu_wordsplit_free (&ws);
+  return rc;
+}
diff --git a/libmu_cfg/sieve.c b/libmu_cfg/sieve.c
index 911cedc..9c3287a 100644
--- a/libmu_cfg/sieve.c
+++ b/libmu_cfg/sieve.c
@@ -61,7 +61,6 @@ cb_clear_include_path (mu_debug_t debug, void *data, 
mu_config_value_t *val)
 static int
 _add_path (mu_debug_t debug, const char *arg, void *data)
 {
-  char *p, *tmp;
   mu_list_t *plist = data;
     
   if (!*plist)
@@ -75,12 +74,7 @@ _add_path (mu_debug_t debug, const char *arg, void *data)
        }
       mu_list_set_destroy_item (*plist, mu_list_free_item);
     }
-  /* FIXME: Use mu_argcv */
-  tmp = strdup (arg);
-  for (p = strtok (tmp, ":"); p; p = strtok (NULL, ":"))
-    mu_list_append (*plist, strdup (p));
-  free (tmp);
-  return 0;
+  return mu_string_split (arg, ":", *plist);
 }
 
 static int
diff --git a/libmu_sieve/extensions/list.c b/libmu_sieve/extensions/list.c
index 452228e..99d8f8a 100644
--- a/libmu_sieve/extensions/list.c
+++ b/libmu_sieve/extensions/list.c
@@ -31,41 +31,63 @@
 
 
 /* Auxiliary functions */
-struct header_closure {
-  mu_header_t header;        /* Message header */
+struct header_closure
+{
+  mu_header_t header;     /* Message header */
   int index;              /* Header index */
   char *delim;            /* List delimiter */
-  char *value;            /* Retrieved header value */
-  char *save;             /* Save pointer for strtok_r */
+  char **valv;            /* Retrieved and split-out header values */
+  size_t valc;            /* Number of values in valv */
+  size_t vali;            /* Current index in valv */  
 };
 
 static void
 cleanup (struct header_closure *hc)
 {
-  free (hc->value);
-  hc->value = hc->save = NULL;
+  mu_argcv_free (hc->valc, hc->valv);
+  hc->valv = NULL;
+  hc->valc = hc->vali = 0;
 }
 
 static int
 retrieve_next_header (struct header_closure *hc, char *name, char **pval)
 {
-  char buf[512];
-  size_t n;
+  const char *buf;
 
   cleanup (hc);
-  while (!mu_header_get_field_name (hc->header, hc->index, buf, sizeof(buf), 
&n))
+  while (!mu_header_sget_field_name (hc->header, hc->index, &buf))
     {
       int i = hc->index++;
       if (mu_c_strcasecmp (buf, name) == 0)
        {
-         if (mu_header_aget_field_value (hc->header, i, &hc->value))
+         const char *value;
+         struct mu_wordsplit ws;
+         
+         if (mu_header_sget_field_value (hc->header, i, &value))
            return 1;
-         *pval = strtok_r (hc->value, hc->delim, &hc->save);
-         if (*pval == NULL)
+         ws.ws_delim = hc->delim;
+         if (mu_wordsplit (value, &ws,
+                           MU_WRDSF_DELIM|MU_WRDSF_SQUEEZE_DELIMS|
+                           MU_WRDSF_WS|
+                           MU_WRDSF_NOVAR|MU_WRDSF_NOCMD))
+           {
+             mu_error (_("cannot split line `%s': %s"), value,
+                       mu_wordsplit_strerror (&ws));
+             return 1;
+           }
+         if (ws.ws_wordc == 0)
            {
              cleanup (hc);
+             mu_wordsplit_free (&ws);
              return 1;
            }
+         hc->valv = ws.ws_wordv;
+         hc->valc = ws.ws_wordc;
+         hc->vali = 0;
+         ws.ws_wordv = NULL;
+         ws.ws_wordc = 0;
+         mu_wordsplit_free (&ws);
+         *pval = hc->valv[hc->vali++];
          return 0;
        }
     }
@@ -84,20 +106,18 @@ list_retrieve_header (void *item, void *data, int idx, 
char **pval)
 
   while (1)
     {
-      if (!hc->value)
+      if (!hc->valv)
        {
          if (retrieve_next_header (hc, (char*) item, &p))
            return 1;
        }
-      else
+      else if (hc->vali == hc->valc)
        {
-         p = strtok_r (NULL, hc->delim, &hc->save);
-         if (!p)
-           {
-             cleanup (hc);
-             continue;
-           }
-       }
+         cleanup (hc);
+         continue;
+       }         
+      else
+       p = hc->valv[hc->vali++];
   
       *pval = strdup (p);
       return 0;
@@ -163,9 +183,10 @@ list_test (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags)
     }
 
   mu_message_get_header (mu_sieve_get_message (mach), &clos.header);
-  result = mu_sieve_vlist_compare (h, v, comp, mu_sieve_get_relcmp (mach, 
tags),
-                               list_retrieve_header,
-                               &clos, NULL) > 0;
+  result = mu_sieve_vlist_compare (h, v, comp,
+                                  mu_sieve_get_relcmp (mach, tags),
+                                  list_retrieve_header,
+                                  &clos, NULL) > 0;
   cleanup (&clos);
   return result; 
 }
diff --git a/mail/escape.c b/mail/escape.c
index 27d8c2f..18e60e0 100644
--- a/mail/escape.c
+++ b/mail/escape.c
@@ -443,7 +443,8 @@ quote0 (msgset_t *mspec, mu_message_t mesg, void *data)
   mu_header_t hdr;
   mu_body_t body;
   mu_stream_t stream;
-  char buffer[512];
+  char *buffer = NULL;
+  size_t size = 0;
   size_t n = 0;
   char *prefix = "\t";
   
@@ -465,22 +466,18 @@ quote0 (msgset_t *mspec, mu_message_t mesg, void *data)
          mu_header_sget_field_name (hdr, i, &sptr);
          if (mail_header_is_visible (sptr))
            {
-             char *value;
+             const char *value;
              
              fprintf (ofile, "%s%s: ", prefix, sptr);
-             if (mu_header_aget_value (hdr, sptr, &value) == 0)
+             if (mu_header_sget_value (hdr, sptr, &value) == 0)
                {
-                 int i;
-                 char *p, *s;
-
-                 for (i = 0, p = strtok_r (value, "\n", &s); p;
-                      p = strtok_r (NULL, "\n", &s), i++)
+                 for (; *value; value++)
                    {
-                     if (i)
+                     fputc (*value, ofile);
+                     if (*value == '\n')
                        fprintf (ofile, "%s", prefix);
-                     fprintf (ofile, "%s\n", p);
                    }
-                 free (value);
+                 fputc ('\n', ofile);
                }
            }
        }
@@ -498,12 +495,9 @@ quote0 (msgset_t *mspec, mu_message_t mesg, void *data)
     }
 
   /* FIXME: Use mu_stream_copy? */
-  while (mu_stream_readline (stream, buffer, sizeof buffer - 1, &n) == 0
-        && n != 0)
-    {
-      buffer[n] = '\0';
-      fprintf (ofile, "%s%s", prefix, buffer);
-    }
+  while (mu_stream_getline (stream, &buffer, &size, &n) == 0 && n != 0)
+    fprintf (ofile, "%s%s", prefix, buffer);
+  free (buffer);
   mu_stream_destroy (&stream);
   return 0;
 }
diff --git a/mail/util.c b/mail/util.c
index 393504a..d8e87b3 100644
--- a/mail/util.c
+++ b/mail/util.c
@@ -935,36 +935,45 @@ util_header_expand (mu_header_t *phdr)
   mu_header_get_field_count (*phdr, &nfields);
   for (i = 1; i <= nfields; i++)
     {
-      char *name, *value;
+      const char *name, *value;
       
-      if (mu_header_aget_field_name (*phdr, i, &name))
+      if (mu_header_sget_field_name (*phdr, i, &name))
        continue;
 
-      if (mu_header_aget_field_value (*phdr, i, &value))
-       {
-         free (name);
-         continue;
-       }
+      if (mu_header_sget_field_value (*phdr, i, &value))
+       continue;
       
       if (is_address_field (name))
        {
-         char *p, *s, *exp = NULL;
+         const char *s;
          mu_address_t addr = NULL;
-
-         if (mu_header_aget_value (hdr, name, &exp) == 0)
+         struct mu_wordsplit ws;
+         size_t j;
+         
+         if (mu_header_sget_value (hdr, name, &s) == 0)
+           mu_address_create (&addr, s);
+
+         ws.ws_delim = ",";
+         if (mu_wordsplit (value, &ws,
+                           MU_WRDSF_DELIM|MU_WRDSF_SQUEEZE_DELIMS|
+                           MU_WRDSF_WS|
+                           MU_WRDSF_NOVAR|MU_WRDSF_NOCMD))
            {
-             mu_address_create (&addr, exp);
-             free (exp);
+             errcnt++;
+             mu_error (_("cannot split line `%s': %s"), value,
+                       mu_wordsplit_strerror (&ws));
+             break;
            }
-         
-         for (p = strtok_r (value, ",", &s); p; p = strtok_r (NULL, ",", &s))
+
+         for (j = 0; j < ws.ws_wordc; j++)
            {
+             const char *exp;
              mu_address_t new_addr;
+             char *p = ws.ws_wordv[j];
              
-             while (*p && mu_isspace (*p))
-               p++;
              /* If inplacealiases was set, the value was already expanded */
-             if (mailvar_get (NULL, "inplacealiases", mailvar_type_boolean, 0))
+             if (mailvar_get (NULL, "inplacealiases",
+                              mailvar_type_boolean, 0))
                exp = alias_expand (p);
              rc = mu_address_create (&new_addr, exp ? exp : p);
              if (rc)
@@ -978,28 +987,25 @@ util_header_expand (mu_header_t *phdr)
                                p, mu_strerror (rc));
                }
              
-             free (exp);
              mu_address_union (&addr, new_addr);
              mu_address_destroy (&new_addr);
            }
          
          if (addr)
            {
+             char *newvalue;
              size_t n = 0;
              
-             free (value);
              mu_address_to_string (addr, NULL, 0, &n);
-             value = xmalloc (n + 1);
-             mu_address_to_string (addr, value, n + 1, NULL);
+             newvalue = xmalloc (n + 1);
+             mu_address_to_string (addr, newvalue, n + 1, NULL);
              mu_address_destroy (&addr);
-             mu_header_set_value (hdr, name, value, 1);
+             mu_header_set_value (hdr, name, newvalue, 1);
+             free (newvalue);
            }
        }
       else
        mu_header_set_value (hdr, name, value, 0);
-      
-      free (value);
-      free (name);
     }
 
   if (errcnt == 0)
@@ -1083,8 +1089,7 @@ util_run_cached_commands (mu_list_t *list)
 void
 util_rfc2047_decode (char **value)
 {
-  char locale[32];
-  const char *charset = NULL;
+  char *charset = NULL;
   char *tmp;
   int rc;
 
@@ -1093,29 +1098,25 @@ util_rfc2047_decode (char **value)
 
   if (mu_c_strcasecmp (charset, "auto") == 0)
     {
-      memset (locale, 0, sizeof (locale));
-
-      /* Try to deduce the charset from LC_ALL or LANG variables */
+      static char *saved_charset;
 
-      tmp = getenv ("LC_ALL");
-      if (!tmp)
-       tmp = getenv ("LANG");
-
-      if (tmp)
+      if (!saved_charset)
        {
-         char *sp;
-         char *lang;
-         char *terr;
-
-         strncpy (locale, tmp, sizeof (locale) - 1);
+         /* Try to deduce the charset from LC_ALL or LANG variables */
 
-         lang = strtok_r (locale, "_", &sp);
-         terr = strtok_r (NULL, ".", &sp);
-         charset = strtok_r (NULL, "@", &sp);
+         tmp = getenv ("LC_ALL");
+         if (!tmp)
+           tmp = getenv ("LANG");
 
-         if (!charset)
-           charset = mu_charset_lookup (lang, terr);
+         if (tmp)
+           {
+             struct mu_lc_all lc_all;
+             
+             if (mu_parse_lc_all (tmp, &lc_all, MU_LC_CSET) == 0)
+               saved_charset = lc_all.charset;
+           }
        }
+      charset = saved_charset; /* NOTE: a minor memory leak */
     }
 
   if (!charset)
diff --git a/mh/mh_init.c b/mh/mh_init.c
index b41dc37..02e5e24 100644
--- a/mh/mh_init.c
+++ b/mh/mh_init.c
@@ -930,25 +930,16 @@ mh_charset (const char *dfl)
     return NULL;
   if (mu_c_strcasecmp (charset, "auto") == 0)
     {
-      /* Try to deduce the charset from LC_ALL variable */
-      
-      char *lc_all = getenv ("LC_ALL");
-      if (lc_all)
-       {
-         char *sp;
-         char *lang;
-         char *terr;
-
-         char *tmp = strdup (lc_all);
-         lang = strtok_r (tmp, "_", &sp);
-         terr = strtok_r (NULL, ".", &sp);
-         charset = strtok_r (NULL, "@", &sp);
+      static char *saved_charset;
 
-         if (!charset)
-           charset = mu_charset_lookup (lang, terr);
-         
-         free (tmp);
+      if (!saved_charset)
+       {
+         /* Try to deduce the charset from LC_ALL variable */
+         struct mu_lc_all lc_all;
+         if (mu_parse_lc_all (getenv ("LC_ALL"), &lc_all, MU_LC_CSET) == 0)
+           saved_charset = lc_all.charset; /* FIXME: Memory leak */
        }
+      charset = saved_charset;
     }
   return charset;
 }
diff --git a/sieve/sieve.c b/sieve/sieve.c
index 179c596..b918fe3 100644
--- a/sieve/sieve.c
+++ b/sieve/sieve.c
@@ -526,7 +526,7 @@ main (int argc, char *argv[])
   if (rc)
     return EX_CONFIG;
 
-  /* We can finish if its only a compilation check. */
+  /* We can finish if it's only a compilation check. */
   if (compile_only)
     {
       if (compile_only == 2)


hooks/post-receive
-- 
GNU Mailutils



reply via email to

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