Commit 38d688c1 38d688c17f9545c032e22f117189b970e858697d by Sergey Poznyakoff

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.
1 parent 0fac46ab
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
......
......@@ -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;
}
......
......@@ -21,5 +21,4 @@ obstack
realloc
setenv
stdint
strtok_r
xalloc
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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
}
......
......@@ -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
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -36,6 +36,7 @@ libbase_la_SOURCES = \
hostname.c\
iterator.c\
kwd.c\
lcall.c\
list.c\
listlist.c\
locale.c\
......
/* 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;
}
......@@ -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);
......
......@@ -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
......
......@@ -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);
......
......@@ -27,6 +27,7 @@ libstring_la_SOURCES = \
strltrim.c\
strskip.c\
stripws.c\
strlst.c\
strrtrim.c\
trueans.c\
unfold.c\
......
/* 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;
}
......@@ -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
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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)
......
......@@ -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;
}
......
......@@ -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)
......