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.
Showing
22 changed files
with
464 additions
and
188 deletions
1 | GNU mailutils TODO list. 2010-12-01 | 1 | GNU mailutils TODO list. 2010-12-02 |
2 | Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 Free | 2 | Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 Free |
3 | Software Foundation, Inc. | 3 | Software Foundation, Inc. |
4 | 4 | ||
... | @@ -12,7 +12,9 @@ Software Foundation, Inc. | ... | @@ -12,7 +12,9 @@ Software Foundation, Inc. |
12 | 12 | ||
13 | * use the above in message_stream. | 13 | * use the above in message_stream. |
14 | 14 | ||
15 | * eliminate uses of strtok(_r) | 15 | * envelope: date returned by mu_envelope_?get_date must not end with a \n |
16 | |||
17 | See also mu_rfc2822_in_reply_to. | ||
16 | 18 | ||
17 | * mail: rewrite I/O support using streams. | 19 | * mail: rewrite I/O support using streams. |
18 | 20 | ||
... | @@ -51,6 +53,10 @@ See guimb/scm/Makefile.am for a discussion. | ... | @@ -51,6 +53,10 @@ See guimb/scm/Makefile.am for a discussion. |
51 | 53 | ||
52 | * lib/mailcap.c: rewrite using streams | 54 | * lib/mailcap.c: rewrite using streams |
53 | 55 | ||
56 | * sieve: needs an option to add directory at the head of the search path | ||
57 | |||
58 | * sieve: extension tests | ||
59 | |||
54 | * mu_address_createv: pass hints as in mu_address_create_hint? | 60 | * mu_address_createv: pass hints as in mu_address_create_hint? |
55 | 61 | ||
56 | * fix Python support | 62 | * fix Python support | ... | ... |
... | @@ -63,10 +63,6 @@ get_charset () | ... | @@ -63,10 +63,6 @@ get_charset () |
63 | if (!output_charset) | 63 | if (!output_charset) |
64 | { | 64 | { |
65 | char *tmp; | 65 | char *tmp; |
66 | const char *str = NULL; | ||
67 | char locale[32]; | ||
68 | |||
69 | memset (locale, 0, sizeof (locale)); | ||
70 | 66 | ||
71 | /* Try to deduce the charset from LC_ALL or LANG variables */ | 67 | /* Try to deduce the charset from LC_ALL or LANG variables */ |
72 | 68 | ||
... | @@ -76,24 +72,14 @@ get_charset () | ... | @@ -76,24 +72,14 @@ get_charset () |
76 | 72 | ||
77 | if (tmp) | 73 | if (tmp) |
78 | { | 74 | { |
79 | char *sp = NULL; | 75 | struct mu_lc_all lc_all; |
80 | char *lang; | ||
81 | char *terr; | ||
82 | |||
83 | strncpy (locale, tmp, sizeof (locale) - 1); | ||
84 | 76 | ||
85 | lang = strtok_r (locale, "_", &sp); | 77 | if (mu_parse_lc_all (tmp, &lc_all, MU_LC_CSET) == 0) |
86 | terr = strtok_r (NULL, ".", &sp); | 78 | output_charset = lc_all.charset; |
87 | str = strtok_r (NULL, "@", &sp); | ||
88 | |||
89 | if (!str) | ||
90 | str = mu_charset_lookup (lang, terr); | ||
91 | } | 79 | } |
92 | 80 | ||
93 | if (!str) | 81 | if (!output_charset) |
94 | str = "ASCII"; | 82 | output_charset = xstrdup ("ASCII"); |
95 | |||
96 | output_charset = xstrdup (str); | ||
97 | } | 83 | } |
98 | return output_charset; | 84 | return output_charset; |
99 | } | 85 | } | ... | ... |
... | @@ -181,21 +181,37 @@ static void | ... | @@ -181,21 +181,37 @@ static void |
181 | auth_gsasl_capa_init (int disable) | 181 | auth_gsasl_capa_init (int disable) |
182 | { | 182 | { |
183 | int rc; | 183 | int rc; |
184 | char *listmech, *name, *s; | 184 | char *listmech; |
185 | 185 | struct mu_wordsplit ws; | |
186 | |||
186 | rc = gsasl_server_mechlist (ctx, &listmech); | 187 | rc = gsasl_server_mechlist (ctx, &listmech); |
187 | if (rc != GSASL_OK) | 188 | if (rc != GSASL_OK) |
188 | return; | 189 | return; |
189 | 190 | ||
190 | for (name = strtok_r (listmech, " ", &s); name; | 191 | ws.ws_delim = " "; |
191 | name = strtok_r (NULL, " ", &s)) | 192 | if (mu_wordsplit (listmech, &ws, |
193 | MU_WRDSF_DELIM|MU_WRDSF_SQUEEZE_DELIMS| | ||
194 | MU_WRDSF_NOVAR|MU_WRDSF_NOCMD)) | ||
192 | { | 195 | { |
193 | if (disable) | 196 | mu_error (_("cannot split line `%s': %s"), listmech, |
194 | auth_remove (name); | 197 | mu_wordsplit_strerror (&ws)); |
195 | else | 198 | } |
196 | auth_add (strdup (name), auth_gsasl); | 199 | else |
200 | { | ||
201 | size_t i; | ||
202 | |||
203 | for (i = 0; i < ws.ws_wordc; i++) | ||
204 | { | ||
205 | if (disable) | ||
206 | auth_remove (ws.ws_wordv[i]); | ||
207 | else | ||
208 | { | ||
209 | auth_add (ws.ws_wordv[i], auth_gsasl); | ||
210 | ws.ws_wordv[i] = NULL; | ||
211 | } | ||
212 | } | ||
213 | mu_wordsplit_free (&ws); | ||
197 | } | 214 | } |
198 | |||
199 | free (listmech); | 215 | free (listmech); |
200 | } | 216 | } |
201 | 217 | ... | ... |
... | @@ -201,10 +201,6 @@ extern mu_list_t imap4d_id_list; | ... | @@ -201,10 +201,6 @@ extern mu_list_t imap4d_id_list; |
201 | extern int imap4d_argc; | 201 | extern int imap4d_argc; |
202 | extern char **imap4d_argv; | 202 | extern char **imap4d_argv; |
203 | 203 | ||
204 | #ifndef HAVE_STRTOK_R | ||
205 | extern char *strtok_r (char *s, const char *delim, char **save_ptr); | ||
206 | #endif | ||
207 | |||
208 | /* Input functions */ | 204 | /* Input functions */ |
209 | extern mu_stream_t iostream; | 205 | extern mu_stream_t iostream; |
210 | extern int io_untagged_response (int, const char *, ...) MU_PRINTFLIKE(2,3); | 206 | extern int io_untagged_response (int, const char *, ...) MU_PRINTFLIKE(2,3); | ... | ... |
... | @@ -22,6 +22,8 @@ | ... | @@ -22,6 +22,8 @@ |
22 | extern "C" { | 22 | extern "C" { |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | # include <mailutils/types.h> | ||
26 | |||
25 | int mu_strlower (char *); | 27 | int mu_strlower (char *); |
26 | int mu_strupper (char *); | 28 | int mu_strupper (char *); |
27 | 29 | ||
... | @@ -41,6 +43,8 @@ char *mu_str_skip_class_comp (const char *str, int __class); | ... | @@ -41,6 +43,8 @@ char *mu_str_skip_class_comp (const char *str, int __class); |
41 | char *mu_str_skip_cset_comp (const char *str, const char *cset); | 43 | char *mu_str_skip_cset_comp (const char *str, const char *cset); |
42 | 44 | ||
43 | char *mu_str_stripws (char *string); | 45 | char *mu_str_stripws (char *string); |
46 | |||
47 | int mu_string_split (const char *string, char *delim, mu_list_t list); | ||
44 | 48 | ||
45 | #ifdef __cplusplus | 49 | #ifdef __cplusplus |
46 | } | 50 | } | ... | ... |
... | @@ -46,6 +46,24 @@ extern void mu_init_nls (void); | ... | @@ -46,6 +46,24 @@ extern void mu_init_nls (void); |
46 | extern char *mu_set_locale (const char *locale); | 46 | extern char *mu_set_locale (const char *locale); |
47 | void mu_restore_locale (void); | 47 | void mu_restore_locale (void); |
48 | 48 | ||
49 | #define MU_LC_LANG 0x01 | ||
50 | #define MU_LC_TERR 0x02 | ||
51 | #define MU_LC_CSET 0x04 | ||
52 | #define MU_LC_MOD 0x08 | ||
53 | |||
54 | struct mu_lc_all | ||
55 | { | ||
56 | int flags; | ||
57 | char *language; | ||
58 | char *territory; | ||
59 | char *charset; | ||
60 | char *modifier; | ||
61 | }; | ||
62 | |||
63 | int mu_parse_lc_all (const char *arg, struct mu_lc_all *str, int flags); | ||
64 | void mu_lc_all_free (struct mu_lc_all *str); | ||
65 | const char *mu_charset_lookup (char *lang, char *terr); | ||
66 | |||
49 | #ifdef __cplusplus | 67 | #ifdef __cplusplus |
50 | } | 68 | } |
51 | #endif | 69 | #endif | ... | ... |
... | @@ -176,7 +176,6 @@ int mu_getpass (mu_stream_t in, mu_stream_t out, const char *prompt, | ... | @@ -176,7 +176,6 @@ int mu_getpass (mu_stream_t in, mu_stream_t out, const char *prompt, |
176 | /* Get the host name, doing a gethostbyname() if possible. */ | 176 | /* Get the host name, doing a gethostbyname() if possible. */ |
177 | int mu_get_host_name (char **host); | 177 | int mu_get_host_name (char **host); |
178 | int mu_spawnvp(const char *prog, char *av[], int *stat); | 178 | int mu_spawnvp(const char *prog, char *av[], int *stat); |
179 | const char *mu_charset_lookup (char *lang, char *terr); | ||
180 | int mu_scheme_autodetect_p (mu_url_t); | 179 | int mu_scheme_autodetect_p (mu_url_t); |
181 | 180 | ||
182 | struct timeval; | 181 | struct timeval; | ... | ... |
... | @@ -53,7 +53,6 @@ struct mime_context | ... | @@ -53,7 +53,6 @@ struct mime_context |
53 | char *temp_file; | 53 | char *temp_file; |
54 | int unlink_temp_file; | 54 | int unlink_temp_file; |
55 | 55 | ||
56 | char *no_ask_str; | ||
57 | mu_list_t no_ask_types; | 56 | mu_list_t no_ask_types; |
58 | int debug_level; | 57 | int debug_level; |
59 | int flags; | 58 | int flags; |
... | @@ -66,15 +65,28 @@ mime_context_fill (struct mime_context *ctx, const char *file, | ... | @@ -66,15 +65,28 @@ mime_context_fill (struct mime_context *ctx, const char *file, |
66 | mu_stream_t input, mu_header_t hdr, const char *no_ask, | 65 | mu_stream_t input, mu_header_t hdr, const char *no_ask, |
67 | int interactive, int dry_run, int debug_level) | 66 | int interactive, int dry_run, int debug_level) |
68 | { | 67 | { |
69 | char *p, *sp; | 68 | struct mu_wordsplit ws; |
70 | 69 | size_t i; | |
70 | |||
71 | memset (ctx, 0, sizeof *ctx); | 71 | memset (ctx, 0, sizeof *ctx); |
72 | ctx->input = input; | 72 | ctx->input = input; |
73 | ctx->hdr = hdr; | 73 | ctx->hdr = hdr; |
74 | if (mu_header_aget_value (hdr, MU_HEADER_CONTENT_TYPE, | 74 | if (mu_header_aget_value (hdr, MU_HEADER_CONTENT_TYPE, |
75 | &ctx->content_type_buffer)) | 75 | &ctx->content_type_buffer)) |
76 | return 1; | 76 | return 1; |
77 | ctx->content_type = strtok_r (ctx->content_type_buffer, ";", &sp); | 77 | ws.ws_delim = ";"; |
78 | if (mu_wordsplit (ctx->content_type_buffer, &ws, | ||
79 | MU_WRDSF_DELIM|MU_WRDSF_SQUEEZE_DELIMS|MU_WRDSF_WS| | ||
80 | MU_WRDSF_NOVAR|MU_WRDSF_NOCMD)) | ||
81 | { | ||
82 | mu_error (_("cannot split line `%s': %s"), | ||
83 | ctx->content_type_buffer, | ||
84 | mu_wordsplit_strerror (&ws)); | ||
85 | return 1; | ||
86 | } | ||
87 | |||
88 | ctx->content_type = ws.ws_wordv[0]; | ||
89 | ws.ws_wordv[0] = NULL; | ||
78 | ctx->temp_file = file ? strdup (file) : NULL; | 90 | ctx->temp_file = file ? strdup (file) : NULL; |
79 | ctx->unlink_temp_file = 0; | 91 | ctx->unlink_temp_file = 0; |
80 | 92 | ||
... | @@ -85,24 +97,20 @@ mime_context_fill (struct mime_context *ctx, const char *file, | ... | @@ -85,24 +97,20 @@ mime_context_fill (struct mime_context *ctx, const char *file, |
85 | ctx->debug_level = debug_level; | 97 | ctx->debug_level = debug_level; |
86 | 98 | ||
87 | mu_list_create (&ctx->values); | 99 | mu_list_create (&ctx->values); |
88 | while ((p = strtok_r (NULL, ";", &sp))) | 100 | |
101 | for (i = 1; i < ws.ws_wordc; i++) | ||
89 | { | 102 | { |
90 | while (*p && isspace (*p)) | 103 | mu_list_append (ctx->values, ws.ws_wordv[i]); |
91 | p++; | 104 | ws.ws_wordv[i] = NULL; |
92 | mu_list_append (ctx->values, p); | ||
93 | } | 105 | } |
106 | mu_wordsplit_free (&ws); | ||
94 | 107 | ||
95 | if (no_ask) | 108 | if (no_ask) |
96 | { | 109 | { |
97 | ctx->no_ask_str = xstrdup (no_ask); | ||
98 | mu_list_create (&ctx->no_ask_types); | 110 | mu_list_create (&ctx->no_ask_types); |
99 | for (p = strtok_r (ctx->no_ask_str, ",", &sp); p; | 111 | mu_list_set_destroy_item (ctx->no_ask_types, mu_list_free_item); |
100 | p = strtok_r (NULL, ",", &sp)) | 112 | if (mu_string_split (no_ask, ",", ctx->no_ask_types)) |
101 | { | 113 | return 1; |
102 | while (*p && isspace (*p)) | ||
103 | p++; | ||
104 | mu_list_append (ctx->no_ask_types, p); | ||
105 | } | ||
106 | } | 114 | } |
107 | return 0; | 115 | return 0; |
108 | } | 116 | } |
... | @@ -115,7 +123,6 @@ mime_context_release (struct mime_context *ctx) | ... | @@ -115,7 +123,6 @@ mime_context_release (struct mime_context *ctx) |
115 | unlink (ctx->temp_file); | 123 | unlink (ctx->temp_file); |
116 | free (ctx->temp_file); | 124 | free (ctx->temp_file); |
117 | mu_list_destroy (&ctx->values); | 125 | mu_list_destroy (&ctx->values); |
118 | free (ctx->no_ask_str); | ||
119 | mu_list_destroy (&ctx->no_ask_types); | 126 | mu_list_destroy (&ctx->no_ask_types); |
120 | } | 127 | } |
121 | 128 | ||
... | @@ -208,8 +215,11 @@ mime_context_write_input (struct mime_context *ctx, int fd) | ... | @@ -208,8 +215,11 @@ mime_context_write_input (struct mime_context *ctx, int fd) |
208 | 215 | ||
209 | mime_context_get_input (ctx, &input); | 216 | mime_context_get_input (ctx, &input); |
210 | status = mu_stream_seek (input, 0, SEEK_SET, NULL); | 217 | status = mu_stream_seek (input, 0, SEEK_SET, NULL); |
211 | if (status) | 218 | if (status && status != ENOSYS) |
212 | abort (); /* FIXME */ | 219 | { |
220 | mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_seek", NULL, status); | ||
221 | abort (); /* FIXME */ | ||
222 | } | ||
213 | while ((status = mu_stream_read (input, buf, sizeof buf, &n)) == 0 | 223 | while ((status = mu_stream_read (input, buf, sizeof buf, &n)) == 0 |
214 | && n) | 224 | && n) |
215 | write (fd, buf, n); | 225 | write (fd, buf, n); |
... | @@ -661,8 +671,8 @@ display_stream_mailcap (const char *ident, mu_stream_t stream, mu_header_t hdr, | ... | @@ -661,8 +671,8 @@ display_stream_mailcap (const char *ident, mu_stream_t stream, mu_header_t hdr, |
661 | const char *no_ask, int interactive, int dry_run, | 671 | const char *no_ask, int interactive, int dry_run, |
662 | int debug_level) | 672 | int debug_level) |
663 | { | 673 | { |
664 | char *p, *sp; | 674 | char *mailcap_path, *mailcap_path_tmp = NULL; |
665 | char *mailcap_path; | 675 | struct mu_wordsplit ws; |
666 | struct mime_context ctx; | 676 | struct mime_context ctx; |
667 | int rc = 1; | 677 | int rc = 1; |
668 | 678 | ||
... | @@ -673,24 +683,37 @@ display_stream_mailcap (const char *ident, mu_stream_t stream, mu_header_t hdr, | ... | @@ -673,24 +683,37 @@ display_stream_mailcap (const char *ident, mu_stream_t stream, mu_header_t hdr, |
673 | if (!mailcap_path) | 683 | if (!mailcap_path) |
674 | { | 684 | { |
675 | char *home = mu_get_homedir (); | 685 | char *home = mu_get_homedir (); |
676 | mu_asprintf (&mailcap_path, "%s/.mailcap:%s", home, DEFAULT_MAILCAP); | 686 | mailcap_path_tmp = mu_make_file_name_suf (home, ".mailcap:", |
687 | DEFAULT_MAILCAP); | ||
677 | free (home); | 688 | free (home); |
678 | if (!mailcap_path) | 689 | if (!mailcap_path_tmp) |
679 | return 1; | 690 | return 1; |
691 | mailcap_path = mailcap_path_tmp; | ||
680 | } | 692 | } |
681 | else | ||
682 | mailcap_path = strdup (mailcap_path); | ||
683 | 693 | ||
684 | obstack_init (&expand_stack); | 694 | obstack_init (&expand_stack); |
685 | 695 | ||
686 | for (p = strtok_r (mailcap_path, ":", &sp); p; p = strtok_r (NULL, ":", &sp)) | 696 | ws.ws_delim = ":"; |
697 | if (mu_wordsplit (mailcap_path, &ws, | ||
698 | MU_WRDSF_DELIM|MU_WRDSF_SQUEEZE_DELIMS| | ||
699 | MU_WRDSF_NOVAR|MU_WRDSF_NOCMD)) | ||
687 | { | 700 | { |
688 | if ((rc = find_entry (p, &ctx)) == 0) | 701 | mu_error (_("cannot split line `%s': %s"), mailcap_path, |
689 | break; | 702 | mu_wordsplit_strerror (&ws)); |
690 | } | 703 | } |
704 | else | ||
705 | { | ||
706 | size_t i; | ||
691 | 707 | ||
708 | for (i = 0; i < ws.ws_wordc; i++) | ||
709 | { | ||
710 | if ((rc = find_entry (ws.ws_wordv[i], &ctx)) == 0) | ||
711 | break; | ||
712 | } | ||
713 | mu_wordsplit_free (&ws); | ||
714 | } | ||
692 | obstack_free (&expand_stack, NULL); | 715 | obstack_free (&expand_stack, NULL); |
693 | free (mailcap_path); | 716 | free (mailcap_path_tmp); |
694 | mime_context_release (&ctx); | 717 | mime_context_release (&ctx); |
695 | return rc; | 718 | return rc; |
696 | } | 719 | } | ... | ... |
libmailutils/base/lcall.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2003, 2009, 2010 Free Software Foundation, Inc. | ||
3 | |||
4 | This library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Lesser General Public | ||
6 | License as published by the Free Software Foundation; either | ||
7 | version 3 of the License, or (at your option) any later version. | ||
8 | |||
9 | This library is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | Lesser General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Lesser General | ||
15 | Public License along with this library. If not, see | ||
16 | <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | |||
22 | #include <stdlib.h> | ||
23 | #include <string.h> | ||
24 | #include <errno.h> | ||
25 | #include <mailutils/nls.h> | ||
26 | |||
27 | static int | ||
28 | _parse_lc_all (const char *arg, struct mu_lc_all *str, int flags) | ||
29 | { | ||
30 | char *s; | ||
31 | size_t n; | ||
32 | |||
33 | n = strcspn (arg, "_.@"); | ||
34 | if (flags & MU_LC_LANG) | ||
35 | { | ||
36 | s = malloc (n + 1); | ||
37 | if (!s) | ||
38 | return ENOMEM; | ||
39 | memcpy (s, arg, n); | ||
40 | s[n] = 0; | ||
41 | str->language = s; | ||
42 | str->flags |= MU_LC_LANG; | ||
43 | } | ||
44 | else | ||
45 | str->language = NULL; | ||
46 | arg += n; | ||
47 | |||
48 | if (arg[0] == '_') | ||
49 | { | ||
50 | arg++; | ||
51 | |||
52 | n = strcspn (arg, ".@"); | ||
53 | if (flags & MU_LC_TERR) | ||
54 | { | ||
55 | s = malloc (n + 1); | ||
56 | if (!s) | ||
57 | return ENOMEM; | ||
58 | memcpy (s, arg, n); | ||
59 | s[n] = 0; | ||
60 | str->territory = s; | ||
61 | str->flags |= MU_LC_TERR; | ||
62 | } | ||
63 | else | ||
64 | str->territory = NULL; | ||
65 | arg += n; | ||
66 | } | ||
67 | |||
68 | if (arg[0] == '.') | ||
69 | { | ||
70 | arg++; | ||
71 | |||
72 | n = strcspn (arg, "@"); | ||
73 | if (flags & MU_LC_CSET) | ||
74 | { | ||
75 | s = malloc (n + 1); | ||
76 | if (!s) | ||
77 | return ENOMEM; | ||
78 | memcpy (s, arg, n); | ||
79 | s[n] = 0; | ||
80 | str->charset = s; | ||
81 | str->flags |= MU_LC_CSET; | ||
82 | } | ||
83 | else | ||
84 | str->charset = NULL; | ||
85 | arg += n; | ||
86 | } | ||
87 | |||
88 | if (arg[0]) | ||
89 | { | ||
90 | arg++; | ||
91 | if (flags & MU_LC_MOD) | ||
92 | { | ||
93 | str->modifier = strdup (arg); | ||
94 | if (!str->modifier) | ||
95 | return ENOMEM; | ||
96 | str->flags |= MU_LC_MOD; | ||
97 | } | ||
98 | } | ||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | void | ||
103 | mu_lc_all_free (struct mu_lc_all *str) | ||
104 | { | ||
105 | free (str->language); | ||
106 | free (str->territory); | ||
107 | free (str->charset); | ||
108 | free (str->modifier); | ||
109 | } | ||
110 | |||
111 | int | ||
112 | mu_parse_lc_all (const char *arg, struct mu_lc_all *str, int flags) | ||
113 | { | ||
114 | int rc; | ||
115 | |||
116 | memset (str, 0, sizeof (str[0])); | ||
117 | rc = _parse_lc_all (arg, str, flags); | ||
118 | if (rc == 0 && !str->charset) | ||
119 | { | ||
120 | const char *charset = mu_charset_lookup (str->language, str->territory); | ||
121 | if (charset) | ||
122 | { | ||
123 | str->charset = strdup (charset); | ||
124 | if (!str->charset) | ||
125 | rc = ENOMEM; | ||
126 | } | ||
127 | } | ||
128 | if (rc) | ||
129 | mu_lc_all_free (str); | ||
130 | return rc; | ||
131 | } |
... | @@ -220,7 +220,7 @@ mu_tempname (const char *tmpdir) | ... | @@ -220,7 +220,7 @@ mu_tempname (const char *tmpdir) |
220 | struct mu_tempfile_hints hints; | 220 | struct mu_tempfile_hints hints; |
221 | char *filename = NULL; | 221 | char *filename = NULL; |
222 | int fd; | 222 | int fd; |
223 | hints.tmpdir = tmpdir; | 223 | hints.tmpdir = (char*)tmpdir; |
224 | if (mu_tempfile (&hints, MU_TEMPFILE_TMPDIR, &fd, &filename)) | 224 | if (mu_tempfile (&hints, MU_TEMPFILE_TMPDIR, &fd, &filename)) |
225 | return NULL; | 225 | return NULL; |
226 | close (fd); | 226 | close (fd); | ... | ... |
... | @@ -118,15 +118,25 @@ mu_debug_level_from_string (const char *string, mu_log_level_t *plev, | ... | @@ -118,15 +118,25 @@ mu_debug_level_from_string (const char *string, mu_log_level_t *plev, |
118 | } | 118 | } |
119 | else | 119 | else |
120 | { | 120 | { |
121 | char *p = strdup (string); | 121 | size_t i; |
122 | size_t len = strlen (p); | 122 | struct mu_wordsplit ws; |
123 | if (len > 0 && p[len-1] == '\n') | 123 | |
124 | p[len-1] = 0; | 124 | if (mu_wordsplit (string, &ws, |
125 | for (q = strtok (p, ","); q; q = strtok (NULL, ",")) | 125 | MU_WRDSF_DELIM|MU_WRDSF_SQUEEZE_DELIMS| |
126 | MU_WRDSF_WS| | ||
127 | MU_WRDSF_NOVAR|MU_WRDSF_NOCMD)) | ||
128 | { | ||
129 | mu_error (_("cannot split line `%s': %s"), string, | ||
130 | mu_wordsplit_strerror (&ws)); | ||
131 | return MU_ERR_FAILURE; | ||
132 | } | ||
133 | |||
134 | for (i = 0; i < ws.ws_wordc; i++) | ||
126 | { | 135 | { |
127 | int flag; | 136 | int flag; |
128 | int revert = 0; | 137 | int revert = 0; |
129 | int upto = 0; | 138 | int upto = 0; |
139 | const char *q = ws.ws_wordv[i]; | ||
130 | 140 | ||
131 | if (*q == '!') | 141 | if (*q == '!') |
132 | { | 142 | { |
... | @@ -158,7 +168,7 @@ mu_debug_level_from_string (const char *string, mu_log_level_t *plev, | ... | @@ -158,7 +168,7 @@ mu_debug_level_from_string (const char *string, mu_log_level_t *plev, |
158 | level |= MU_DEBUG_LEVEL_MASK (flag); | 168 | level |= MU_DEBUG_LEVEL_MASK (flag); |
159 | } | 169 | } |
160 | } | 170 | } |
161 | free (p); | 171 | mu_wordsplit_free (&ws); |
162 | } | 172 | } |
163 | *plev = level; | 173 | *plev = level; |
164 | return 0; | 174 | return 0; |
... | @@ -207,12 +217,24 @@ mu_global_debug_from_string (const char *string, const char *errpfx) | ... | @@ -207,12 +217,24 @@ mu_global_debug_from_string (const char *string, const char *errpfx) |
207 | } | 217 | } |
208 | else | 218 | else |
209 | { | 219 | { |
210 | char *q; | 220 | size_t j; |
211 | for (q = strtok (p, ","); q; q = strtok (NULL, ",")) | 221 | struct mu_wordsplit ws1; |
222 | |||
223 | ws.ws_delim = ","; | ||
224 | if (mu_wordsplit (p, &ws1, | ||
225 | MU_WRDSF_DELIM|MU_WRDSF_NOVAR|MU_WRDSF_NOCMD)) | ||
226 | { | ||
227 | mu_error (_("cannot split line `%s': %s"), p, | ||
228 | mu_wordsplit_strerror (&ws)); | ||
229 | return MU_ERR_FAILURE; | ||
230 | } | ||
231 | |||
232 | for (j = 0; j < ws1.ws_wordc; j++) | ||
212 | { | 233 | { |
213 | int flag; | 234 | int flag; |
214 | int revert = 0; | 235 | int revert = 0; |
215 | int upto = 0; | 236 | int upto = 0; |
237 | const char *q = ws1.ws_wordv[j]; | ||
216 | 238 | ||
217 | if (*q == '!') | 239 | if (*q == '!') |
218 | { | 240 | { |
... | @@ -243,6 +265,7 @@ mu_global_debug_from_string (const char *string, const char *errpfx) | ... | @@ -243,6 +265,7 @@ mu_global_debug_from_string (const char *string, const char *errpfx) |
243 | level |= MU_DEBUG_LEVEL_MASK (flag); | 265 | level |= MU_DEBUG_LEVEL_MASK (flag); |
244 | } | 266 | } |
245 | } | 267 | } |
268 | mu_wordsplit_free (&ws1); | ||
246 | } | 269 | } |
247 | } | 270 | } |
248 | else | 271 | else | ... | ... |
... | @@ -267,7 +267,7 @@ mu_streamref_create_abridged (mu_stream_t *pref, mu_stream_t str, | ... | @@ -267,7 +267,7 @@ mu_streamref_create_abridged (mu_stream_t *pref, mu_stream_t str, |
267 | int flags; | 267 | int flags; |
268 | struct _mu_streamref *sp; | 268 | struct _mu_streamref *sp; |
269 | 269 | ||
270 | rc = mu_stream_seek (str, 0, MU_SEEK_SET, &off); | 270 | rc = mu_stream_seek (str, 0, MU_SEEK_SET, &off);//FIXME: SEEK_CUR? |
271 | if (rc) | 271 | if (rc) |
272 | return rc; | 272 | return rc; |
273 | mu_stream_get_flags (str, &flags); | 273 | mu_stream_get_flags (str, &flags); | ... | ... |
libmailutils/string/strlst.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009, | ||
3 | 2010 Free Software Foundation, Inc. | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 3 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General | ||
16 | Public License along with this library. If not, see | ||
17 | <http://www.gnu.org/licenses/>. */ | ||
18 | #if HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | |||
22 | #include <errno.h> | ||
23 | #include <mailutils/errno.h> | ||
24 | #include <mailutils/list.h> | ||
25 | #include <mailutils/wordsplit.h> | ||
26 | #include <mailutils/cstr.h> | ||
27 | |||
28 | int | ||
29 | mu_string_split (const char *string, char *delim, mu_list_t list) | ||
30 | { | ||
31 | size_t i; | ||
32 | struct mu_wordsplit ws; | ||
33 | int rc = 0; | ||
34 | |||
35 | if (!string || !delim || !list) | ||
36 | return EINVAL; | ||
37 | |||
38 | /* Split the string */ | ||
39 | ws.ws_delim = delim; | ||
40 | if (mu_wordsplit (string, &ws, | ||
41 | MU_WRDSF_DELIM|MU_WRDSF_SQUEEZE_DELIMS| | ||
42 | MU_WRDSF_NOVAR|MU_WRDSF_NOCMD)) | ||
43 | return errno; | ||
44 | |||
45 | for (i = 0; i < ws.ws_wordc; i++) | ||
46 | { | ||
47 | rc = mu_list_append (list, ws.ws_wordv[i]); | ||
48 | if (rc) | ||
49 | break; | ||
50 | } | ||
51 | |||
52 | if (rc) | ||
53 | { | ||
54 | /* If failed, restore LIST to the state before entering this | ||
55 | function. */ | ||
56 | size_t j; | ||
57 | mu_list_comparator_t cptr = | ||
58 | mu_list_set_comparator (list, NULL); | ||
59 | mu_list_destroy_item_t dptr = | ||
60 | mu_list_set_destroy_item (list, NULL); | ||
61 | |||
62 | for (j = 0; j < i; j++) | ||
63 | mu_list_remove (list, ws.ws_wordv[j]); | ||
64 | mu_list_set_destroy_item (list, dptr); | ||
65 | mu_list_set_comparator (list, cptr); | ||
66 | } | ||
67 | else | ||
68 | /* Make sure ws.ws_wordv[x] are not freed */ | ||
69 | ws.ws_wordc = 0; | ||
70 | mu_wordsplit_free (&ws); | ||
71 | return rc; | ||
72 | } |
... | @@ -61,7 +61,6 @@ cb_clear_include_path (mu_debug_t debug, void *data, mu_config_value_t *val) | ... | @@ -61,7 +61,6 @@ cb_clear_include_path (mu_debug_t debug, void *data, mu_config_value_t *val) |
61 | static int | 61 | static int |
62 | _add_path (mu_debug_t debug, const char *arg, void *data) | 62 | _add_path (mu_debug_t debug, const char *arg, void *data) |
63 | { | 63 | { |
64 | char *p, *tmp; | ||
65 | mu_list_t *plist = data; | 64 | mu_list_t *plist = data; |
66 | 65 | ||
67 | if (!*plist) | 66 | if (!*plist) |
... | @@ -75,12 +74,7 @@ _add_path (mu_debug_t debug, const char *arg, void *data) | ... | @@ -75,12 +74,7 @@ _add_path (mu_debug_t debug, const char *arg, void *data) |
75 | } | 74 | } |
76 | mu_list_set_destroy_item (*plist, mu_list_free_item); | 75 | mu_list_set_destroy_item (*plist, mu_list_free_item); |
77 | } | 76 | } |
78 | /* FIXME: Use mu_argcv */ | 77 | return mu_string_split (arg, ":", *plist); |
79 | tmp = strdup (arg); | ||
80 | for (p = strtok (tmp, ":"); p; p = strtok (NULL, ":")) | ||
81 | mu_list_append (*plist, strdup (p)); | ||
82 | free (tmp); | ||
83 | return 0; | ||
84 | } | 78 | } |
85 | 79 | ||
86 | static int | 80 | static int | ... | ... |
... | @@ -31,41 +31,63 @@ | ... | @@ -31,41 +31,63 @@ |
31 | 31 | ||
32 | 32 | ||
33 | /* Auxiliary functions */ | 33 | /* Auxiliary functions */ |
34 | struct header_closure { | 34 | struct header_closure |
35 | mu_header_t header; /* Message header */ | 35 | { |
36 | mu_header_t header; /* Message header */ | ||
36 | int index; /* Header index */ | 37 | int index; /* Header index */ |
37 | char *delim; /* List delimiter */ | 38 | char *delim; /* List delimiter */ |
38 | char *value; /* Retrieved header value */ | 39 | char **valv; /* Retrieved and split-out header values */ |
39 | char *save; /* Save pointer for strtok_r */ | 40 | size_t valc; /* Number of values in valv */ |
41 | size_t vali; /* Current index in valv */ | ||
40 | }; | 42 | }; |
41 | 43 | ||
42 | static void | 44 | static void |
43 | cleanup (struct header_closure *hc) | 45 | cleanup (struct header_closure *hc) |
44 | { | 46 | { |
45 | free (hc->value); | 47 | mu_argcv_free (hc->valc, hc->valv); |
46 | hc->value = hc->save = NULL; | 48 | hc->valv = NULL; |
49 | hc->valc = hc->vali = 0; | ||
47 | } | 50 | } |
48 | 51 | ||
49 | static int | 52 | static int |
50 | retrieve_next_header (struct header_closure *hc, char *name, char **pval) | 53 | retrieve_next_header (struct header_closure *hc, char *name, char **pval) |
51 | { | 54 | { |
52 | char buf[512]; | 55 | const char *buf; |
53 | size_t n; | ||
54 | 56 | ||
55 | cleanup (hc); | 57 | cleanup (hc); |
56 | while (!mu_header_get_field_name (hc->header, hc->index, buf, sizeof(buf), &n)) | 58 | while (!mu_header_sget_field_name (hc->header, hc->index, &buf)) |
57 | { | 59 | { |
58 | int i = hc->index++; | 60 | int i = hc->index++; |
59 | if (mu_c_strcasecmp (buf, name) == 0) | 61 | if (mu_c_strcasecmp (buf, name) == 0) |
60 | { | 62 | { |
61 | if (mu_header_aget_field_value (hc->header, i, &hc->value)) | 63 | const char *value; |
64 | struct mu_wordsplit ws; | ||
65 | |||
66 | if (mu_header_sget_field_value (hc->header, i, &value)) | ||
62 | return 1; | 67 | return 1; |
63 | *pval = strtok_r (hc->value, hc->delim, &hc->save); | 68 | ws.ws_delim = hc->delim; |
64 | if (*pval == NULL) | 69 | if (mu_wordsplit (value, &ws, |
70 | MU_WRDSF_DELIM|MU_WRDSF_SQUEEZE_DELIMS| | ||
71 | MU_WRDSF_WS| | ||
72 | MU_WRDSF_NOVAR|MU_WRDSF_NOCMD)) | ||
73 | { | ||
74 | mu_error (_("cannot split line `%s': %s"), value, | ||
75 | mu_wordsplit_strerror (&ws)); | ||
76 | return 1; | ||
77 | } | ||
78 | if (ws.ws_wordc == 0) | ||
65 | { | 79 | { |
66 | cleanup (hc); | 80 | cleanup (hc); |
81 | mu_wordsplit_free (&ws); | ||
67 | return 1; | 82 | return 1; |
68 | } | 83 | } |
84 | hc->valv = ws.ws_wordv; | ||
85 | hc->valc = ws.ws_wordc; | ||
86 | hc->vali = 0; | ||
87 | ws.ws_wordv = NULL; | ||
88 | ws.ws_wordc = 0; | ||
89 | mu_wordsplit_free (&ws); | ||
90 | *pval = hc->valv[hc->vali++]; | ||
69 | return 0; | 91 | return 0; |
70 | } | 92 | } |
71 | } | 93 | } |
... | @@ -84,20 +106,18 @@ list_retrieve_header (void *item, void *data, int idx, char **pval) | ... | @@ -84,20 +106,18 @@ list_retrieve_header (void *item, void *data, int idx, char **pval) |
84 | 106 | ||
85 | while (1) | 107 | while (1) |
86 | { | 108 | { |
87 | if (!hc->value) | 109 | if (!hc->valv) |
88 | { | 110 | { |
89 | if (retrieve_next_header (hc, (char*) item, &p)) | 111 | if (retrieve_next_header (hc, (char*) item, &p)) |
90 | return 1; | 112 | return 1; |
91 | } | 113 | } |
92 | else | 114 | else if (hc->vali == hc->valc) |
93 | { | 115 | { |
94 | p = strtok_r (NULL, hc->delim, &hc->save); | 116 | cleanup (hc); |
95 | if (!p) | 117 | continue; |
96 | { | 118 | } |
97 | cleanup (hc); | 119 | else |
98 | continue; | 120 | p = hc->valv[hc->vali++]; |
99 | } | ||
100 | } | ||
101 | 121 | ||
102 | *pval = strdup (p); | 122 | *pval = strdup (p); |
103 | return 0; | 123 | return 0; |
... | @@ -163,9 +183,10 @@ list_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) | ... | @@ -163,9 +183,10 @@ list_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) |
163 | } | 183 | } |
164 | 184 | ||
165 | mu_message_get_header (mu_sieve_get_message (mach), &clos.header); | 185 | mu_message_get_header (mu_sieve_get_message (mach), &clos.header); |
166 | result = mu_sieve_vlist_compare (h, v, comp, mu_sieve_get_relcmp (mach, tags), | 186 | result = mu_sieve_vlist_compare (h, v, comp, |
167 | list_retrieve_header, | 187 | mu_sieve_get_relcmp (mach, tags), |
168 | &clos, NULL) > 0; | 188 | list_retrieve_header, |
189 | &clos, NULL) > 0; | ||
169 | cleanup (&clos); | 190 | cleanup (&clos); |
170 | return result; | 191 | return result; |
171 | } | 192 | } | ... | ... |
... | @@ -443,7 +443,8 @@ quote0 (msgset_t *mspec, mu_message_t mesg, void *data) | ... | @@ -443,7 +443,8 @@ quote0 (msgset_t *mspec, mu_message_t mesg, void *data) |
443 | mu_header_t hdr; | 443 | mu_header_t hdr; |
444 | mu_body_t body; | 444 | mu_body_t body; |
445 | mu_stream_t stream; | 445 | mu_stream_t stream; |
446 | char buffer[512]; | 446 | char *buffer = NULL; |
447 | size_t size = 0; | ||
447 | size_t n = 0; | 448 | size_t n = 0; |
448 | char *prefix = "\t"; | 449 | char *prefix = "\t"; |
449 | 450 | ||
... | @@ -465,22 +466,18 @@ quote0 (msgset_t *mspec, mu_message_t mesg, void *data) | ... | @@ -465,22 +466,18 @@ quote0 (msgset_t *mspec, mu_message_t mesg, void *data) |
465 | mu_header_sget_field_name (hdr, i, &sptr); | 466 | mu_header_sget_field_name (hdr, i, &sptr); |
466 | if (mail_header_is_visible (sptr)) | 467 | if (mail_header_is_visible (sptr)) |
467 | { | 468 | { |
468 | char *value; | 469 | const char *value; |
469 | 470 | ||
470 | fprintf (ofile, "%s%s: ", prefix, sptr); | 471 | fprintf (ofile, "%s%s: ", prefix, sptr); |
471 | if (mu_header_aget_value (hdr, sptr, &value) == 0) | 472 | if (mu_header_sget_value (hdr, sptr, &value) == 0) |
472 | { | 473 | { |
473 | int i; | 474 | for (; *value; value++) |
474 | char *p, *s; | ||
475 | |||
476 | for (i = 0, p = strtok_r (value, "\n", &s); p; | ||
477 | p = strtok_r (NULL, "\n", &s), i++) | ||
478 | { | 475 | { |
479 | if (i) | 476 | fputc (*value, ofile); |
477 | if (*value == '\n') | ||
480 | fprintf (ofile, "%s", prefix); | 478 | fprintf (ofile, "%s", prefix); |
481 | fprintf (ofile, "%s\n", p); | ||
482 | } | 479 | } |
483 | free (value); | 480 | fputc ('\n', ofile); |
484 | } | 481 | } |
485 | } | 482 | } |
486 | } | 483 | } |
... | @@ -498,12 +495,9 @@ quote0 (msgset_t *mspec, mu_message_t mesg, void *data) | ... | @@ -498,12 +495,9 @@ quote0 (msgset_t *mspec, mu_message_t mesg, void *data) |
498 | } | 495 | } |
499 | 496 | ||
500 | /* FIXME: Use mu_stream_copy? */ | 497 | /* FIXME: Use mu_stream_copy? */ |
501 | while (mu_stream_readline (stream, buffer, sizeof buffer - 1, &n) == 0 | 498 | while (mu_stream_getline (stream, &buffer, &size, &n) == 0 && n != 0) |
502 | && n != 0) | 499 | fprintf (ofile, "%s%s", prefix, buffer); |
503 | { | 500 | free (buffer); |
504 | buffer[n] = '\0'; | ||
505 | fprintf (ofile, "%s%s", prefix, buffer); | ||
506 | } | ||
507 | mu_stream_destroy (&stream); | 501 | mu_stream_destroy (&stream); |
508 | return 0; | 502 | return 0; |
509 | } | 503 | } | ... | ... |
... | @@ -935,36 +935,45 @@ util_header_expand (mu_header_t *phdr) | ... | @@ -935,36 +935,45 @@ util_header_expand (mu_header_t *phdr) |
935 | mu_header_get_field_count (*phdr, &nfields); | 935 | mu_header_get_field_count (*phdr, &nfields); |
936 | for (i = 1; i <= nfields; i++) | 936 | for (i = 1; i <= nfields; i++) |
937 | { | 937 | { |
938 | char *name, *value; | 938 | const char *name, *value; |
939 | 939 | ||
940 | if (mu_header_aget_field_name (*phdr, i, &name)) | 940 | if (mu_header_sget_field_name (*phdr, i, &name)) |
941 | continue; | 941 | continue; |
942 | 942 | ||
943 | if (mu_header_aget_field_value (*phdr, i, &value)) | 943 | if (mu_header_sget_field_value (*phdr, i, &value)) |
944 | { | 944 | continue; |
945 | free (name); | ||
946 | continue; | ||
947 | } | ||
948 | 945 | ||
949 | if (is_address_field (name)) | 946 | if (is_address_field (name)) |
950 | { | 947 | { |
951 | char *p, *s, *exp = NULL; | 948 | const char *s; |
952 | mu_address_t addr = NULL; | 949 | mu_address_t addr = NULL; |
953 | 950 | struct mu_wordsplit ws; | |
954 | if (mu_header_aget_value (hdr, name, &exp) == 0) | 951 | size_t j; |
952 | |||
953 | if (mu_header_sget_value (hdr, name, &s) == 0) | ||
954 | mu_address_create (&addr, s); | ||
955 | |||
956 | ws.ws_delim = ","; | ||
957 | if (mu_wordsplit (value, &ws, | ||
958 | MU_WRDSF_DELIM|MU_WRDSF_SQUEEZE_DELIMS| | ||
959 | MU_WRDSF_WS| | ||
960 | MU_WRDSF_NOVAR|MU_WRDSF_NOCMD)) | ||
955 | { | 961 | { |
956 | mu_address_create (&addr, exp); | 962 | errcnt++; |
957 | free (exp); | 963 | mu_error (_("cannot split line `%s': %s"), value, |
964 | mu_wordsplit_strerror (&ws)); | ||
965 | break; | ||
958 | } | 966 | } |
959 | 967 | ||
960 | for (p = strtok_r (value, ",", &s); p; p = strtok_r (NULL, ",", &s)) | 968 | for (j = 0; j < ws.ws_wordc; j++) |
961 | { | 969 | { |
970 | const char *exp; | ||
962 | mu_address_t new_addr; | 971 | mu_address_t new_addr; |
972 | char *p = ws.ws_wordv[j]; | ||
963 | 973 | ||
964 | while (*p && mu_isspace (*p)) | ||
965 | p++; | ||
966 | /* If inplacealiases was set, the value was already expanded */ | 974 | /* If inplacealiases was set, the value was already expanded */ |
967 | if (mailvar_get (NULL, "inplacealiases", mailvar_type_boolean, 0)) | 975 | if (mailvar_get (NULL, "inplacealiases", |
976 | mailvar_type_boolean, 0)) | ||
968 | exp = alias_expand (p); | 977 | exp = alias_expand (p); |
969 | rc = mu_address_create (&new_addr, exp ? exp : p); | 978 | rc = mu_address_create (&new_addr, exp ? exp : p); |
970 | if (rc) | 979 | if (rc) |
... | @@ -978,28 +987,25 @@ util_header_expand (mu_header_t *phdr) | ... | @@ -978,28 +987,25 @@ util_header_expand (mu_header_t *phdr) |
978 | p, mu_strerror (rc)); | 987 | p, mu_strerror (rc)); |
979 | } | 988 | } |
980 | 989 | ||
981 | free (exp); | ||
982 | mu_address_union (&addr, new_addr); | 990 | mu_address_union (&addr, new_addr); |
983 | mu_address_destroy (&new_addr); | 991 | mu_address_destroy (&new_addr); |
984 | } | 992 | } |
985 | 993 | ||
986 | if (addr) | 994 | if (addr) |
987 | { | 995 | { |
996 | char *newvalue; | ||
988 | size_t n = 0; | 997 | size_t n = 0; |
989 | 998 | ||
990 | free (value); | ||
991 | mu_address_to_string (addr, NULL, 0, &n); | 999 | mu_address_to_string (addr, NULL, 0, &n); |
992 | value = xmalloc (n + 1); | 1000 | newvalue = xmalloc (n + 1); |
993 | mu_address_to_string (addr, value, n + 1, NULL); | 1001 | mu_address_to_string (addr, newvalue, n + 1, NULL); |
994 | mu_address_destroy (&addr); | 1002 | mu_address_destroy (&addr); |
995 | mu_header_set_value (hdr, name, value, 1); | 1003 | mu_header_set_value (hdr, name, newvalue, 1); |
1004 | free (newvalue); | ||
996 | } | 1005 | } |
997 | } | 1006 | } |
998 | else | 1007 | else |
999 | mu_header_set_value (hdr, name, value, 0); | 1008 | mu_header_set_value (hdr, name, value, 0); |
1000 | |||
1001 | free (value); | ||
1002 | free (name); | ||
1003 | } | 1009 | } |
1004 | 1010 | ||
1005 | if (errcnt == 0) | 1011 | if (errcnt == 0) |
... | @@ -1083,8 +1089,7 @@ util_run_cached_commands (mu_list_t *list) | ... | @@ -1083,8 +1089,7 @@ util_run_cached_commands (mu_list_t *list) |
1083 | void | 1089 | void |
1084 | util_rfc2047_decode (char **value) | 1090 | util_rfc2047_decode (char **value) |
1085 | { | 1091 | { |
1086 | char locale[32]; | 1092 | char *charset = NULL; |
1087 | const char *charset = NULL; | ||
1088 | char *tmp; | 1093 | char *tmp; |
1089 | int rc; | 1094 | int rc; |
1090 | 1095 | ||
... | @@ -1093,29 +1098,25 @@ util_rfc2047_decode (char **value) | ... | @@ -1093,29 +1098,25 @@ util_rfc2047_decode (char **value) |
1093 | 1098 | ||
1094 | if (mu_c_strcasecmp (charset, "auto") == 0) | 1099 | if (mu_c_strcasecmp (charset, "auto") == 0) |
1095 | { | 1100 | { |
1096 | memset (locale, 0, sizeof (locale)); | 1101 | static char *saved_charset; |
1097 | |||
1098 | /* Try to deduce the charset from LC_ALL or LANG variables */ | ||
1099 | 1102 | ||
1100 | tmp = getenv ("LC_ALL"); | 1103 | if (!saved_charset) |
1101 | if (!tmp) | ||
1102 | tmp = getenv ("LANG"); | ||
1103 | |||
1104 | if (tmp) | ||
1105 | { | 1104 | { |
1106 | char *sp; | 1105 | /* Try to deduce the charset from LC_ALL or LANG variables */ |
1107 | char *lang; | ||
1108 | char *terr; | ||
1109 | |||
1110 | strncpy (locale, tmp, sizeof (locale) - 1); | ||
1111 | 1106 | ||
1112 | lang = strtok_r (locale, "_", &sp); | 1107 | tmp = getenv ("LC_ALL"); |
1113 | terr = strtok_r (NULL, ".", &sp); | 1108 | if (!tmp) |
1114 | charset = strtok_r (NULL, "@", &sp); | 1109 | tmp = getenv ("LANG"); |
1115 | 1110 | ||
1116 | if (!charset) | 1111 | if (tmp) |
1117 | charset = mu_charset_lookup (lang, terr); | 1112 | { |
1113 | struct mu_lc_all lc_all; | ||
1114 | |||
1115 | if (mu_parse_lc_all (tmp, &lc_all, MU_LC_CSET) == 0) | ||
1116 | saved_charset = lc_all.charset; | ||
1117 | } | ||
1118 | } | 1118 | } |
1119 | charset = saved_charset; /* NOTE: a minor memory leak */ | ||
1119 | } | 1120 | } |
1120 | 1121 | ||
1121 | if (!charset) | 1122 | if (!charset) | ... | ... |
... | @@ -930,25 +930,16 @@ mh_charset (const char *dfl) | ... | @@ -930,25 +930,16 @@ mh_charset (const char *dfl) |
930 | return NULL; | 930 | return NULL; |
931 | if (mu_c_strcasecmp (charset, "auto") == 0) | 931 | if (mu_c_strcasecmp (charset, "auto") == 0) |
932 | { | 932 | { |
933 | /* Try to deduce the charset from LC_ALL variable */ | 933 | static char *saved_charset; |
934 | |||
935 | char *lc_all = getenv ("LC_ALL"); | ||
936 | if (lc_all) | ||
937 | { | ||
938 | char *sp; | ||
939 | char *lang; | ||
940 | char *terr; | ||
941 | |||
942 | char *tmp = strdup (lc_all); | ||
943 | lang = strtok_r (tmp, "_", &sp); | ||
944 | terr = strtok_r (NULL, ".", &sp); | ||
945 | charset = strtok_r (NULL, "@", &sp); | ||
946 | 934 | ||
947 | if (!charset) | 935 | if (!saved_charset) |
948 | charset = mu_charset_lookup (lang, terr); | 936 | { |
949 | 937 | /* Try to deduce the charset from LC_ALL variable */ | |
950 | free (tmp); | 938 | struct mu_lc_all lc_all; |
939 | if (mu_parse_lc_all (getenv ("LC_ALL"), &lc_all, MU_LC_CSET) == 0) | ||
940 | saved_charset = lc_all.charset; /* FIXME: Memory leak */ | ||
951 | } | 941 | } |
942 | charset = saved_charset; | ||
952 | } | 943 | } |
953 | return charset; | 944 | return charset; |
954 | } | 945 | } | ... | ... |
... | @@ -526,7 +526,7 @@ main (int argc, char *argv[]) | ... | @@ -526,7 +526,7 @@ main (int argc, char *argv[]) |
526 | if (rc) | 526 | if (rc) |
527 | return EX_CONFIG; | 527 | return EX_CONFIG; |
528 | 528 | ||
529 | /* We can finish if its only a compilation check. */ | 529 | /* We can finish if it's only a compilation check. */ |
530 | if (compile_only) | 530 | if (compile_only) |
531 | { | 531 | { |
532 | if (compile_only == 2) | 532 | if (compile_only == 2) | ... | ... |
-
Please register or sign in to post a comment