Change configuration file parser based on the lexer/parser from GNU Dico.
* auth/gsasl.c: Remove deprecated data types. * imap4d/auth_gsasl.c (retrieve_password): Minor fix. * imap4d/imap4d.c, imap4d/imap4d.h, imap4d/namespace.c, lib/tcpwrap.c, libcfg/acl.c, libcfg/auth.c, libcfg/common.c, libcfg/ldap.c, libcfg/sieve.c, libcfg/sql.c, maidag/maidag.c, mail.local/main.c, mailbox/gdebug.c, mailbox/msrv.c, mimeview/mimeview.c, pop3d/bulletin.c, pop3d/pop3d.c, pop3d/pop3d.h, sieve/sieve.c: Reflect changes to the configuration system. * mailbox/Makefile.am (AM_LFLAGS): New variable. (EXTRA_DIST) Add cfg_lexer.l. (libmailutils_la_SOURCES): Add alloc.c and opool.c (BUILT_SOURCES): Add cfg_lexer.c. (cfg_lexer.c): New goal. * mailbox/alloc.c, mailbox/opool.c: New files. * mailbox/cfg_lexer.c: Remove. * mailbox/cfg_lexer.l: New file. * mailbox/.cvsignore: Add cfg_lexer.c. * include/mailutils/Makefile.am: Add alloc.h and opool.h * include/mailutils/alloc.h: New file. * include/mailutils/opool.h: New file. * include/mailutils/cfg.h (mu_cfg_lexer_t,mu_cfg_alloc_t) (mu_cfg_free_t): Remove types. (MU_CFG_STRING, MU_CFG_LIST, MU_CFG_ARRAY): New defines. (mu_config_value_t): New data type. (struct mu_cfg_node): Change type of `label'. (struct mu_cfg_tree): Remove `alloc', `free'. New member `pool'. (mu_cfg_parse): Simplify the signature by removing superfluous arguments. (mu_cfg_tie_in): Remove. (mu_cfg_lexer_pool): New function. (mu_cfg_find_node, mu_cfg_find_node_label): Remove. (mu_cfg_callback_t): Change signature. (MU_CFG_LIST_MASK): New define. (MU_CFG_LIST_OF, MU_CFG_TYPE, MU_CFG_IS_LIST): New defines. (mu_cfg_get_debug): New function. (mu_cfg_assert_value_type, mu_cfg_string_value_cb): New functions. (mu_cfg_tree_set_alloc, mu_cfg_tree_alloc): Remove. * mailbox/cfg_driver.c: Adapt for new node structure. (mu_cfg_assert_value_type, mu_cfg_string_value_cb): New function. * mailbox/cfg_format.c: Adapt for new node structure. * mailbox/cfg_parser.y: Adapt for changes in cfg data types and lexer. * include/mailutils/mailutils.h: Include alloc.h and opool.h * include/mailutils/mu_auth.h (mu_authorization_add_module) (mu_authentication_add_module): New prototypes. * include/mailutils/syslog.h (mu_string_to_syslog_facility) (mu_string_to_syslog_priority): First argument is const char *. * mailbox/syslog.c: Likewise. * include/mailutils/types.hin (mu_opool_t): New type. * mailbox/list.c (mu_list_get_comparator): Add missing return statement.
Showing
41 changed files
with
1424 additions
and
725 deletions
1 | 2008-08-19 Sergey Poznyakoff <gray@gnu.org.ua> | ||
2 | |||
3 | Change configuration file parser based on the lexer/parser from | ||
4 | GNU Dico. | ||
5 | |||
6 | * auth/gsasl.c: Remove deprecated data types. | ||
7 | * imap4d/auth_gsasl.c (retrieve_password): Minor fix. | ||
8 | |||
9 | * imap4d/imap4d.c, imap4d/imap4d.h, imap4d/namespace.c, | ||
10 | lib/tcpwrap.c, libcfg/acl.c, libcfg/auth.c, libcfg/common.c, | ||
11 | libcfg/ldap.c, libcfg/sieve.c, libcfg/sql.c, maidag/maidag.c, | ||
12 | mail.local/main.c, mailbox/gdebug.c, mailbox/msrv.c, | ||
13 | mimeview/mimeview.c, pop3d/bulletin.c, pop3d/pop3d.c, | ||
14 | pop3d/pop3d.h, sieve/sieve.c: Reflect changes to the configuration | ||
15 | system. | ||
16 | |||
17 | * mailbox/Makefile.am (AM_LFLAGS): New variable. | ||
18 | (EXTRA_DIST) Add cfg_lexer.l. | ||
19 | (libmailutils_la_SOURCES): Add alloc.c and opool.c | ||
20 | (BUILT_SOURCES): Add cfg_lexer.c. | ||
21 | (cfg_lexer.c): New goal. | ||
22 | * mailbox/alloc.c, mailbox/opool.c: New files. | ||
23 | * mailbox/cfg_lexer.c: Remove. | ||
24 | * mailbox/cfg_lexer.l: New file. | ||
25 | * mailbox/.cvsignore: Add cfg_lexer.c. | ||
26 | |||
27 | * include/mailutils/Makefile.am: Add alloc.h and opool.h | ||
28 | * include/mailutils/alloc.h: New file. | ||
29 | * include/mailutils/opool.h: New file. | ||
30 | |||
31 | * include/mailutils/cfg.h (mu_cfg_lexer_t,mu_cfg_alloc_t) | ||
32 | (mu_cfg_free_t): Remove types. | ||
33 | (MU_CFG_STRING, MU_CFG_LIST, MU_CFG_ARRAY): New defines. | ||
34 | (mu_config_value_t): New data type. | ||
35 | (struct mu_cfg_node): Change type of `label'. | ||
36 | (struct mu_cfg_tree): Remove `alloc', `free'. | ||
37 | New member `pool'. | ||
38 | (mu_cfg_parse): Simplify the signature by removing superfluous | ||
39 | arguments. | ||
40 | (mu_cfg_tie_in): Remove. | ||
41 | (mu_cfg_lexer_pool): New function. | ||
42 | (mu_cfg_find_node, mu_cfg_find_node_label): Remove. | ||
43 | (mu_cfg_callback_t): Change signature. | ||
44 | (MU_CFG_LIST_MASK): New define. | ||
45 | (MU_CFG_LIST_OF, MU_CFG_TYPE, MU_CFG_IS_LIST): New defines. | ||
46 | (mu_cfg_get_debug): New function. | ||
47 | (mu_cfg_assert_value_type, mu_cfg_string_value_cb): New functions. | ||
48 | (mu_cfg_tree_set_alloc, mu_cfg_tree_alloc): Remove. | ||
49 | * mailbox/cfg_driver.c: Adapt for new node structure. | ||
50 | (mu_cfg_assert_value_type, mu_cfg_string_value_cb): New function. | ||
51 | * mailbox/cfg_format.c: Adapt for new node structure. | ||
52 | * mailbox/cfg_parser.y: Adapt for changes in cfg data types and | ||
53 | lexer. | ||
54 | |||
55 | * include/mailutils/mailutils.h: Include alloc.h and opool.h | ||
56 | * include/mailutils/mu_auth.h (mu_authorization_add_module) | ||
57 | (mu_authentication_add_module): New prototypes. | ||
58 | |||
59 | * include/mailutils/syslog.h (mu_string_to_syslog_facility) | ||
60 | (mu_string_to_syslog_priority): First argument is const char *. | ||
61 | * mailbox/syslog.c: Likewise. | ||
62 | |||
63 | * include/mailutils/types.hin (mu_opool_t): New type. | ||
64 | * mailbox/list.c (mu_list_get_comparator): Add missing return | ||
65 | statement. | ||
66 | |||
1 | 2008-08-18 Sergey Poznyakoff <gray@gnu.org.ua> | 67 | 2008-08-18 Sergey Poznyakoff <gray@gnu.org.ua> |
2 | 68 | ||
3 | Autobuild setup. | 69 | Autobuild setup. | ... | ... |
... | @@ -52,7 +52,7 @@ mu_gsasl_module_init (void *data) | ... | @@ -52,7 +52,7 @@ mu_gsasl_module_init (void *data) |
52 | } | 52 | } |
53 | 53 | ||
54 | struct _gsasl_stream { | 54 | struct _gsasl_stream { |
55 | Gsasl_session_ctx *sess_ctx; /* Context */ | 55 | Gsasl_session *sess_ctx; /* Context */ |
56 | int last_err; /* Last Gsasl error code */ | 56 | int last_err; /* Last Gsasl error code */ |
57 | 57 | ||
58 | mu_stream_t stream; /* I/O stream */ | 58 | mu_stream_t stream; /* I/O stream */ |
... | @@ -238,7 +238,7 @@ _gsasl_wait (mu_stream_t stream, int *pflags, struct timeval *tvp) | ... | @@ -238,7 +238,7 @@ _gsasl_wait (mu_stream_t stream, int *pflags, struct timeval *tvp) |
238 | 238 | ||
239 | int | 239 | int |
240 | mu_gsasl_stream_create (mu_stream_t *stream, mu_stream_t transport, | 240 | mu_gsasl_stream_create (mu_stream_t *stream, mu_stream_t transport, |
241 | Gsasl_session_ctx *ctx, int flags) | 241 | Gsasl_session *ctx, int flags) |
242 | { | 242 | { |
243 | struct _gsasl_stream *s; | 243 | struct _gsasl_stream *s; |
244 | int rc; | 244 | int rc; | ... | ... |
... | @@ -175,7 +175,7 @@ static int | ... | @@ -175,7 +175,7 @@ static int |
175 | retrieve_password (Gsasl *ctx, Gsasl_session *sctx) | 175 | retrieve_password (Gsasl *ctx, Gsasl_session *sctx) |
176 | { | 176 | { |
177 | char **username = gsasl_callback_hook_get (ctx); | 177 | char **username = gsasl_callback_hook_get (ctx); |
178 | char *authid = gsasl_property_get (sctx, GSASL_AUTHID); | 178 | const char *authid = gsasl_property_get (sctx, GSASL_AUTHID); |
179 | 179 | ||
180 | if (username && *username == 0) | 180 | if (username && *username == 0) |
181 | *username = strdup (authid); | 181 | *username = strdup (authid); | ... | ... |
... | @@ -169,27 +169,37 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -169,27 +169,37 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) |
169 | } | 169 | } |
170 | 170 | ||
171 | static int | 171 | static int |
172 | cb_other (mu_debug_t debug, void *data, char *arg) | 172 | cb2_namespace (mu_debug_t debug, const char *arg, void *data) |
173 | { | 173 | { |
174 | set_namespace (NS_OTHER, arg); | 174 | int what = (int) data; |
175 | set_namespace (what, arg); | ||
175 | return 0; | 176 | return 0; |
176 | } | 177 | } |
177 | 178 | ||
178 | static int | 179 | static int |
179 | cb_shared (mu_debug_t debug, void *data, char *arg) | 180 | cb_other (mu_debug_t debug, void *data, mu_config_value_t *val) |
180 | { | 181 | { |
181 | set_namespace (NS_SHARED, arg); | 182 | return mu_cfg_string_value_cb (debug, val, cb2_namespace, (void*)NS_OTHER); |
183 | } | ||
184 | |||
185 | static int | ||
186 | cb_shared (mu_debug_t debug, void *data, mu_config_value_t *val) | ||
187 | { | ||
188 | return mu_cfg_string_value_cb (debug, val, cb2_namespace, (void*)NS_SHARED); | ||
182 | return 0; | 189 | return 0; |
183 | } | 190 | } |
184 | 191 | ||
185 | static int | 192 | static int |
186 | cb_mode (mu_debug_t debug, void *data, char *arg) | 193 | cb_mode (mu_debug_t debug, void *data, mu_config_value_t *val) |
187 | { | 194 | { |
188 | char *p; | 195 | char *p; |
189 | home_dir_mode = strtoul (arg, &p, 8); | 196 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) |
197 | return 1; | ||
198 | home_dir_mode = strtoul (val->v.string, &p, 8); | ||
190 | if (p[0] || (home_dir_mode & ~0777)) | 199 | if (p[0] || (home_dir_mode & ~0777)) |
191 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, | 200 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, |
192 | _("Invalid mode specification: %s"), arg); | 201 | _("Invalid mode specification: %s"), |
202 | val->v.string); | ||
193 | return 0; | 203 | return 0; |
194 | } | 204 | } |
195 | 205 | ||
... | @@ -239,22 +249,24 @@ parse_preauth_scheme (mu_debug_t debug, const char *scheme, mu_url_t url) | ... | @@ -239,22 +249,24 @@ parse_preauth_scheme (mu_debug_t debug, const char *scheme, mu_url_t url) |
239 | preauth stdio | 249 | preauth stdio |
240 | */ | 250 | */ |
241 | static int | 251 | static int |
242 | cb_preauth (mu_debug_t debug, void *data, char *arg) | 252 | cb_preauth (mu_debug_t debug, void *data, mu_config_value_t *val) |
243 | { | 253 | { |
244 | if (strcmp (arg, "stdio") == 0) | 254 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) |
255 | return 1; | ||
256 | if (strcmp (val->v.string, "stdio") == 0) | ||
245 | preauth_mode = preauth_stdio; | 257 | preauth_mode = preauth_stdio; |
246 | else if (strcmp (arg, "ident") == 0) | 258 | else if (strcmp (val->v.string, "ident") == 0) |
247 | return parse_preauth_scheme (debug, arg, NULL); | 259 | return parse_preauth_scheme (debug, val->v.string, NULL); |
248 | else if (arg[0] == '/') | 260 | else if (val->v.string[0] == '/') |
249 | { | 261 | { |
250 | preauth_program = xstrdup (arg); | 262 | preauth_program = xstrdup (val->v.string); |
251 | preauth_mode = preauth_prog; | 263 | preauth_mode = preauth_prog; |
252 | } | 264 | } |
253 | else | 265 | else |
254 | { | 266 | { |
255 | mu_url_t url; | 267 | mu_url_t url; |
256 | char *scheme; | 268 | char *scheme; |
257 | int rc = mu_url_create (&url, arg); | 269 | int rc = mu_url_create (&url, val->v.string); |
258 | 270 | ||
259 | if (rc) | 271 | if (rc) |
260 | { | 272 | { |
... | @@ -266,7 +278,7 @@ cb_preauth (mu_debug_t debug, void *data, char *arg) | ... | @@ -266,7 +278,7 @@ cb_preauth (mu_debug_t debug, void *data, char *arg) |
266 | if (rc) | 278 | if (rc) |
267 | { | 279 | { |
268 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, | 280 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, |
269 | "%s: %s", arg, mu_strerror (rc)); | 281 | "%s: %s", val->v.string, mu_strerror (rc)); |
270 | return 1; | 282 | return 1; |
271 | } | 283 | } |
272 | 284 | ||
... | @@ -301,7 +313,7 @@ static struct mu_cfg_param imap4d_cfg_param[] = { | ... | @@ -301,7 +313,7 @@ static struct mu_cfg_param imap4d_cfg_param[] = { |
301 | { "home-dir-mode", mu_cfg_callback, NULL, 0, cb_mode, | 313 | { "home-dir-mode", mu_cfg_callback, NULL, 0, cb_mode, |
302 | N_("File mode for creating user home directories (octal)."), | 314 | N_("File mode for creating user home directories (octal)."), |
303 | N_("mode") }, | 315 | N_("mode") }, |
304 | { "tls-required", mu_cfg_int, &tls_required, 0, NULL, | 316 | { "tls-required", mu_cfg_bool, &tls_required, 0, NULL, |
305 | N_("Always require STARTTLS before entering authentication phase.") }, | 317 | N_("Always require STARTTLS before entering authentication phase.") }, |
306 | { "preauth", mu_cfg_callback, NULL, 0, cb_preauth, | 318 | { "preauth", mu_cfg_callback, NULL, 0, cb_preauth, |
307 | N_("Configure PREAUTH mode. MODE is one of:\n" | 319 | N_("Configure PREAUTH mode. MODE is one of:\n" | ... | ... |
... | @@ -100,6 +100,8 @@ | ... | @@ -100,6 +100,8 @@ |
100 | #include <mailutils/pam.h> | 100 | #include <mailutils/pam.h> |
101 | #include <mailutils/acl.h> | 101 | #include <mailutils/acl.h> |
102 | #include <mailutils/server.h> | 102 | #include <mailutils/server.h> |
103 | #include <mailutils/argcv.h> | ||
104 | #include <mailutils/alloc.h> | ||
103 | 105 | ||
104 | #include <mu_asprintf.h> | 106 | #include <mu_asprintf.h> |
105 | #include <mu_umaxtostr.h> | 107 | #include <mu_umaxtostr.h> |
... | @@ -271,7 +273,7 @@ extern int imap4d_bye (int); | ... | @@ -271,7 +273,7 @@ extern int imap4d_bye (int); |
271 | extern int imap4d_bye0 (int reason, struct imap4d_command *command); | 273 | extern int imap4d_bye0 (int reason, struct imap4d_command *command); |
272 | 274 | ||
273 | /* Namespace functions */ | 275 | /* Namespace functions */ |
274 | extern int set_namespace (int i, char *str); | 276 | extern int set_namespace (int i, const char *str); |
275 | extern int namespace_init (char *path); | 277 | extern int namespace_init (char *path); |
276 | extern char * namespace_getfullpath (char *name, const char *delim); | 278 | extern char * namespace_getfullpath (char *name, const char *delim); |
277 | extern char * namespace_checkfullpath (char *name, const char *pattern, | 279 | extern char * namespace_checkfullpath (char *name, const char *pattern, | ... | ... |
... | @@ -18,6 +18,8 @@ | ... | @@ -18,6 +18,8 @@ |
18 | 18 | ||
19 | #include "imap4d.h" | 19 | #include "imap4d.h" |
20 | 20 | ||
21 | /* FIXME: Rewrite using mu_list_t */ | ||
22 | |||
21 | /*FIXME: should be global? */ | 23 | /*FIXME: should be global? */ |
22 | typedef int (*nsfp_t) (void *closure, int ns, char *path, int delim); | 24 | typedef int (*nsfp_t) (void *closure, int ns, char *path, int delim); |
23 | 25 | ||
... | @@ -31,34 +33,20 @@ struct namespace_t namespace[NS_MAX]; | ... | @@ -31,34 +33,20 @@ struct namespace_t namespace[NS_MAX]; |
31 | 33 | ||
32 | /* Note: str is not supposed to be NULL */ | 34 | /* Note: str is not supposed to be NULL */ |
33 | int | 35 | int |
34 | set_namespace (int i, char *str) | 36 | set_namespace (int i, const char *str) |
35 | { | 37 | { |
36 | char *p, *save; | 38 | struct namespace_t *ns = namespace + i; |
37 | struct namespace_t ns; | 39 | int argc; |
38 | 40 | char **argv; | |
39 | /* first, estimate the number of items in subdir_v array: */ | 41 | |
40 | ns.subdir_c = 1; | 42 | mu_argcv_get (str, ":", NULL, &argc, &argv); |
41 | for (p = strchr (str, ':'); p && *p; p = strchr (p + 1, ':')) | 43 | |
42 | ns.subdir_c++; | 44 | ns->subdir_v = mu_realloc (ns->subdir_v, |
43 | 45 | (ns->subdir_c + argc) * sizeof (ns->subdir_v[0])); | |
44 | /* Now allocate the memory */ | 46 | for (i = 0; i < argc; i++) |
45 | ns.subdir_v = calloc (ns.subdir_c, sizeof (ns.subdir_v[0])); | 47 | ns->subdir_v[ns->subdir_c++] = mu_normalize_path (argv[i], "/"); |
46 | 48 | /* Free only argv, not its members */ | |
47 | /* Fill in the array */ | 49 | free (argv); |
48 | if (ns.subdir_c == 1) | ||
49 | { | ||
50 | ns.subdir_v[0] = mu_normalize_path (strdup (str), "/"); | ||
51 | } | ||
52 | else | ||
53 | { | ||
54 | ns.subdir_c = 0; | ||
55 | for (p = strtok_r (str, ":", &save); p; p = strtok_r (NULL, ":", &save)) | ||
56 | { | ||
57 | ns.subdir_v[ns.subdir_c++] = mu_normalize_path (strdup (p), "/"); | ||
58 | } | ||
59 | } | ||
60 | |||
61 | namespace[i] = ns; | ||
62 | 50 | ||
63 | return 0; | 51 | return 0; |
64 | } | 52 | } | ... | ... |
1 | ## Process this file with GNU Automake to create Makefile.in | 1 | ## Process this file with GNU Automake to create Makefile.in |
2 | 2 | ||
3 | ## Copyright (C) 2000, 2001, 2002, 2003, | 3 | ## Copyright (C) 2000, 2001, 2002, 2003, |
4 | ## 2004, 2005, 2007 Free Software Foundation, Inc. | 4 | ## 2004, 2005, 2007, 2008 Free Software Foundation, Inc. |
5 | ## | 5 | ## |
6 | ## GNU Mailutils is free software; you can redistribute it and/or | 6 | ## GNU Mailutils is free software; you can redistribute it and/or |
7 | ## modify it under the terms of the GNU General Public License as | 7 | ## modify it under the terms of the GNU General Public License as |
... | @@ -34,6 +34,7 @@ pkginclude_DATA = types.h | ... | @@ -34,6 +34,7 @@ pkginclude_DATA = types.h |
34 | pkginclude_HEADERS = \ | 34 | pkginclude_HEADERS = \ |
35 | acl.h\ | 35 | acl.h\ |
36 | address.h\ | 36 | address.h\ |
37 | alloc.h\ | ||
37 | argcv.h\ | 38 | argcv.h\ |
38 | assoc.h\ | 39 | assoc.h\ |
39 | attribute.h\ | 40 | attribute.h\ |
... | @@ -73,6 +74,7 @@ pkginclude_HEADERS = \ | ... | @@ -73,6 +74,7 @@ pkginclude_HEADERS = \ |
73 | nls.h\ | 74 | nls.h\ |
74 | nntp.h\ | 75 | nntp.h\ |
75 | observer.h\ | 76 | observer.h\ |
77 | opool.h\ | ||
76 | pam.h\ | 78 | pam.h\ |
77 | parse822.h\ | 79 | parse822.h\ |
78 | pop3.h\ | 80 | pop3.h\ | ... | ... |
include/mailutils/alloc.h
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2008 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, write to the | ||
16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
17 | Boston, MA 02110-1301 USA */ | ||
18 | |||
19 | #ifndef _MAILUTILS_ALLOC_H | ||
20 | #define _MAILUTILS_ALLOC_H | ||
21 | |||
22 | #include <mailutils/types.h> | ||
23 | |||
24 | # ifndef MU_ATTRIBUTE_NORETURN | ||
25 | # define MU_ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) | ||
26 | # endif | ||
27 | |||
28 | extern void (*mu_alloc_die_hook) (void); | ||
29 | void mu_alloc_die (void) MU_ATTRIBUTE_NORETURN; | ||
30 | void *mu_alloc (size_t); | ||
31 | void *mu_calloc (size_t, size_t); | ||
32 | void *mu_zalloc (size_t size); | ||
33 | void *mu_realloc (void *, size_t); | ||
34 | char *mu_strdup (const char *); | ||
35 | void *mu_2nrealloc (void *, size_t *, size_t); | ||
36 | |||
37 | #endif |
... | @@ -20,6 +20,7 @@ | ... | @@ -20,6 +20,7 @@ |
20 | 20 | ||
21 | #include <mailutils/list.h> | 21 | #include <mailutils/list.h> |
22 | #include <mailutils/debug.h> | 22 | #include <mailutils/debug.h> |
23 | #include <mailutils/opool.h> | ||
23 | #include <sys/socket.h> | 24 | #include <sys/socket.h> |
24 | #include <netinet/in.h> | 25 | #include <netinet/in.h> |
25 | #include <arpa/inet.h> | 26 | #include <arpa/inet.h> |
... | @@ -33,14 +34,32 @@ typedef struct mu_cfg_node mu_cfg_node_t; | ... | @@ -33,14 +34,32 @@ typedef struct mu_cfg_node mu_cfg_node_t; |
33 | typedef struct mu_cfg_locus mu_cfg_locus_t; | 34 | typedef struct mu_cfg_locus mu_cfg_locus_t; |
34 | typedef struct mu_cfg_tree mu_cfg_tree_t; | 35 | typedef struct mu_cfg_tree mu_cfg_tree_t; |
35 | 36 | ||
36 | typedef int (*mu_cfg_lexer_t) (void *ptr, mu_debug_t dbg); | 37 | #define MU_CFG_STRING 0 |
37 | typedef void *(*mu_cfg_alloc_t) (size_t size); | 38 | #define MU_CFG_LIST 1 |
38 | typedef void (*mu_cfg_free_t) (void *ptr); | 39 | #define MU_CFG_ARRAY 2 |
39 | 40 | ||
41 | typedef struct mu_config_value mu_config_value_t; | ||
42 | |||
43 | struct mu_config_value | ||
44 | { | ||
45 | int type; | ||
46 | union | ||
47 | { | ||
48 | mu_list_t list; | ||
49 | const char *string; | ||
50 | struct | ||
51 | { | ||
52 | size_t c; | ||
53 | mu_config_value_t *v; | ||
54 | } arg; | ||
55 | } v; | ||
56 | }; | ||
57 | |||
40 | enum mu_cfg_node_type | 58 | enum mu_cfg_node_type |
41 | { | 59 | { |
42 | mu_cfg_node_undefined, | 60 | mu_cfg_node_undefined, |
43 | mu_cfg_node_tag, | 61 | mu_cfg_statement, |
62 | mu_cfg_node_tag=mu_cfg_statement, /* FIXME: remove */ | ||
44 | mu_cfg_node_param | 63 | mu_cfg_node_param |
45 | }; | 64 | }; |
46 | 65 | ||
... | @@ -55,8 +74,8 @@ struct mu_cfg_node | ... | @@ -55,8 +74,8 @@ struct mu_cfg_node |
55 | mu_cfg_node_t *next; | 74 | mu_cfg_node_t *next; |
56 | mu_cfg_locus_t locus; | 75 | mu_cfg_locus_t locus; |
57 | enum mu_cfg_node_type type; | 76 | enum mu_cfg_node_type type; |
58 | char *tag_name; | 77 | char *tag; |
59 | char *tag_label; | 78 | mu_config_value_t *label; |
60 | mu_cfg_node_t *node; | 79 | mu_cfg_node_t *node; |
61 | }; | 80 | }; |
62 | 81 | ||
... | @@ -64,19 +83,14 @@ struct mu_cfg_tree | ... | @@ -64,19 +83,14 @@ struct mu_cfg_tree |
64 | { | 83 | { |
65 | mu_cfg_node_t *node; | 84 | mu_cfg_node_t *node; |
66 | mu_debug_t debug; | 85 | mu_debug_t debug; |
67 | mu_cfg_alloc_t alloc; | 86 | mu_opool_t pool; |
68 | mu_cfg_free_t free; | ||
69 | }; | 87 | }; |
70 | 88 | ||
71 | int mu_cfg_parse (mu_cfg_tree_t **ptree, | 89 | int mu_cfg_parse (mu_cfg_tree_t **ptree); |
72 | void *data, | ||
73 | mu_cfg_lexer_t lexer, | ||
74 | mu_debug_t debug, | ||
75 | mu_cfg_alloc_t alloc, | ||
76 | mu_cfg_free_t free); | ||
77 | 90 | ||
78 | extern mu_cfg_locus_t mu_cfg_locus; | 91 | extern mu_cfg_locus_t mu_cfg_locus; |
79 | extern int mu_cfg_tie_in; | 92 | |
93 | mu_opool_t mu_cfg_lexer_pool (void); | ||
80 | 94 | ||
81 | void mu_cfg_perror (const mu_cfg_locus_t *, const char *, ...); | 95 | void mu_cfg_perror (const mu_cfg_locus_t *, const char *, ...); |
82 | void mu_cfg_format_error (mu_debug_t debug, size_t, const char *fmt, ...); | 96 | void mu_cfg_format_error (mu_debug_t debug, size_t, const char *fmt, ...); |
... | @@ -96,10 +110,6 @@ int mu_cfg_postorder (mu_cfg_node_t *node, | ... | @@ -96,10 +110,6 @@ int mu_cfg_postorder (mu_cfg_node_t *node, |
96 | mu_cfg_iter_func_t fun, mu_cfg_iter_func_t endfun, | 110 | mu_cfg_iter_func_t fun, mu_cfg_iter_func_t endfun, |
97 | void *data); | 111 | void *data); |
98 | 112 | ||
99 | int mu_cfg_find_node (mu_cfg_node_t *tree, const char *path, | ||
100 | mu_cfg_node_t **pval); | ||
101 | int mu_cfg_find_node_label (mu_cfg_node_t *tree, const char *path, | ||
102 | const char **pval); | ||
103 | 113 | ||
104 | /* Table-driven parsing */ | 114 | /* Table-driven parsing */ |
105 | enum mu_cfg_param_data_type | 115 | enum mu_cfg_param_data_type |
... | @@ -122,7 +132,12 @@ enum mu_cfg_param_data_type | ... | @@ -122,7 +132,12 @@ enum mu_cfg_param_data_type |
122 | mu_cfg_section | 132 | mu_cfg_section |
123 | }; | 133 | }; |
124 | 134 | ||
125 | typedef int (*mu_cfg_callback_t) (mu_debug_t, void *, char *); | 135 | #define MU_CFG_LIST_MASK 0x8000 |
136 | #define MU_CFG_LIST_OF(t) ((t) | MU_CFG_LIST_MASK) | ||
137 | #define MU_CFG_TYPE(t) ((t) & ~MU_CFG_LIST_MASK) | ||
138 | #define MU_CFG_IS_LIST(t) ((t) & MU_CFG_LIST_MASK) | ||
139 | |||
140 | typedef int (*mu_cfg_callback_t) (mu_debug_t, void *, mu_config_value_t *); | ||
126 | 141 | ||
127 | struct mu_cfg_param | 142 | struct mu_cfg_param |
128 | { | 143 | { |
... | @@ -218,6 +233,8 @@ int mu_config_register_plain_section (const char *parent_path, | ... | @@ -218,6 +233,8 @@ int mu_config_register_plain_section (const char *parent_path, |
218 | const char *ident, | 233 | const char *ident, |
219 | struct mu_cfg_param *params); | 234 | struct mu_cfg_param *params); |
220 | 235 | ||
236 | mu_debug_t mu_cfg_get_debug (void); | ||
237 | |||
221 | #define MU_PARSE_CONFIG_GLOBAL 0x1 | 238 | #define MU_PARSE_CONFIG_GLOBAL 0x1 |
222 | #define MU_PARSE_CONFIG_VERBOSE 0x2 | 239 | #define MU_PARSE_CONFIG_VERBOSE 0x2 |
223 | #define MU_PARSE_CONFIG_DUMP 0x4 | 240 | #define MU_PARSE_CONFIG_DUMP 0x4 |
... | @@ -240,6 +257,11 @@ void mu_format_config_tree (mu_stream_t stream, const char *progname, | ... | @@ -240,6 +257,11 @@ void mu_format_config_tree (mu_stream_t stream, const char *progname, |
240 | int mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree, const char *progname, | 257 | int mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree, const char *progname, |
241 | struct mu_cfg_param *progparam, | 258 | struct mu_cfg_param *progparam, |
242 | int flags, void *target_ptr); | 259 | int flags, void *target_ptr); |
260 | int mu_cfg_assert_value_type (mu_config_value_t *val, int type, | ||
261 | mu_debug_t debug); | ||
262 | int mu_cfg_string_value_cb (mu_debug_t debug, mu_config_value_t *val, | ||
263 | int (*fun) (mu_debug_t, const char *, void *), | ||
264 | void *data); | ||
243 | 265 | ||
244 | int mu_get_config (const char *file, const char *progname, | 266 | int mu_get_config (const char *file, const char *progname, |
245 | struct mu_cfg_param *progparam, int flags, | 267 | struct mu_cfg_param *progparam, int flags, |
... | @@ -248,14 +270,12 @@ int mu_get_config (const char *file, const char *progname, | ... | @@ -248,14 +270,12 @@ int mu_get_config (const char *file, const char *progname, |
248 | 270 | ||
249 | int mu_cfg_tree_create (struct mu_cfg_tree **ptree); | 271 | int mu_cfg_tree_create (struct mu_cfg_tree **ptree); |
250 | void mu_cfg_tree_set_debug (struct mu_cfg_tree *tree, mu_debug_t debug); | 272 | void mu_cfg_tree_set_debug (struct mu_cfg_tree *tree, mu_debug_t debug); |
251 | void mu_cfg_tree_set_alloc (struct mu_cfg_tree *tree, | ||
252 | mu_cfg_alloc_t alloc, mu_cfg_free_t free); | ||
253 | void *mu_cfg_tree_alloc (struct mu_cfg_tree *tree, size_t size); | ||
254 | void mu_cfg_tree_free (struct mu_cfg_tree *tree, void *mem); | 273 | void mu_cfg_tree_free (struct mu_cfg_tree *tree, void *mem); |
255 | mu_cfg_node_t *mu_cfg_tree_create_node (struct mu_cfg_tree *tree, | 274 | mu_cfg_node_t *mu_cfg_tree_create_node (struct mu_cfg_tree *tree, |
256 | enum mu_cfg_node_type type, | 275 | enum mu_cfg_node_type type, |
257 | const mu_cfg_locus_t *loc, | 276 | const mu_cfg_locus_t *loc, |
258 | const char *tag, const char *label, | 277 | const char *tag, |
278 | const char *label, | ||
259 | mu_cfg_node_t *node); | 279 | mu_cfg_node_t *node); |
260 | void mu_cfg_tree_add_node (mu_cfg_tree_t *tree, mu_cfg_node_t *node); | 280 | void mu_cfg_tree_add_node (mu_cfg_tree_t *tree, mu_cfg_node_t *node); |
261 | 281 | ... | ... |
... | @@ -19,6 +19,7 @@ | ... | @@ -19,6 +19,7 @@ |
19 | 19 | ||
20 | #include <mailutils/acl.h> | 20 | #include <mailutils/acl.h> |
21 | #include <mailutils/address.h> | 21 | #include <mailutils/address.h> |
22 | #include <mailutils/alloc.h> | ||
22 | #include <mailutils/assoc.h> | 23 | #include <mailutils/assoc.h> |
23 | #include <mailutils/argcv.h> | 24 | #include <mailutils/argcv.h> |
24 | #include <mailutils/attribute.h> | 25 | #include <mailutils/attribute.h> | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 2002, 2005, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 2002, 2005, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | This library is free software; you can redistribute it and/or | 4 | This library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Lesser General Public | 5 | modify it under the terms of the GNU Lesser General Public |
... | @@ -109,7 +109,9 @@ extern int mu_auth_nosupport (struct mu_auth_data **return_data, | ... | @@ -109,7 +109,9 @@ extern int mu_auth_nosupport (struct mu_auth_data **return_data, |
109 | 109 | ||
110 | extern void mu_auth_register_module (struct mu_auth_module *mod); | 110 | extern void mu_auth_register_module (struct mu_auth_module *mod); |
111 | 111 | ||
112 | extern int mu_authorization_add_module (const char *modname); | ||
112 | extern void mu_authorization_add_module_list (const char *modlist); | 113 | extern void mu_authorization_add_module_list (const char *modlist); |
114 | extern int mu_authentication_add_module (const char *modname); | ||
113 | extern void mu_authentication_add_module_list (const char *modlist); | 115 | extern void mu_authentication_add_module_list (const char *modlist); |
114 | extern void mu_authentication_clear_list (void); | 116 | extern void mu_authentication_clear_list (void); |
115 | extern void mu_authorization_clear_list (void); | 117 | extern void mu_authorization_clear_list (void); | ... | ... |
include/mailutils/opool.h
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2008 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, write to the | ||
16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
17 | Boston, MA 02110-1301 USA */ | ||
18 | |||
19 | #ifndef _MAILUTILS_OPOOL_H | ||
20 | #define _MAILUTILS_OPOOL_H | ||
21 | |||
22 | #include <mailutils/types.h> | ||
23 | |||
24 | #ifndef MU_OPOOL_BUCKET_SIZE | ||
25 | # define MU_OPOOL_BUCKET_SIZE 1024 | ||
26 | #endif | ||
27 | |||
28 | /* Create an object pool. If MEMERR is not 0, any operation of the | ||
29 | resulting pool (including mu_opool_create itself) will abort on | ||
30 | not enough memory condition, using mu_alloc_die. */ | ||
31 | int mu_opool_create (mu_opool_t *pret, int memerr); | ||
32 | |||
33 | /* Clear all data from the pool, so next mu_opool_append* call will | ||
34 | begin a new object. */ | ||
35 | void mu_opool_clear (mu_opool_t opool); | ||
36 | |||
37 | /* Destroy the pool, reclaim any memory associated with it. */ | ||
38 | void mu_opool_destroy (mu_opool_t *popool); | ||
39 | |||
40 | /* Append to the current object N bytes pointed to by STR. */ | ||
41 | int mu_opool_append (mu_opool_t opool, const void *str, size_t n); | ||
42 | |||
43 | /* Append to the current object a nul-terminated string STR. */ | ||
44 | int mu_opool_appendz (mu_opool_t opool, const char *str); | ||
45 | |||
46 | /* Append a single byte C to the current object. */ | ||
47 | int mu_opool_append_char (mu_opool_t opool, char c); | ||
48 | |||
49 | /* Return size of the current object in the pool. */ | ||
50 | size_t mu_opool_size (mu_opool_t opool); | ||
51 | |||
52 | /* Coalesce all data collected so far (by using mu_opool_append* calls) | ||
53 | into a single contiguous memory chunk. Return the size of the resulting | ||
54 | object in *PSIZE, unless PSIZE==NULL. Return 0 on success, error code on | ||
55 | failure (unless the pool was created with `memerr' option, see | ||
56 | mu_opool_create, above). */ | ||
57 | int mu_opool_coalesce (mu_opool_t opool, size_t *psize); | ||
58 | |||
59 | /* Return the pointer to the current object head chunk. If mu_opool_coalesce | ||
60 | was called before, the returned value points to the entire object. | ||
61 | If PSIZE is not NULL, store the size of the head chunk to *PSIZE. */ | ||
62 | void *mu_opool_head (mu_opool_t opool, size_t *psize); | ||
63 | |||
64 | /* Finish building the object. Equivalent to: | ||
65 | mu_opool_coalesce (opool, NULL); | ||
66 | p = mu_opool_head (opool, psize); | ||
67 | mu_opool_clear (opool); | ||
68 | return p; */ | ||
69 | void *mu_opool_finish (mu_opool_t opool, size_t *psize); | ||
70 | |||
71 | #endif |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | This library is free software; you can redistribute it and/or | 4 | This library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Lesser General Public | 5 | modify it under the terms of the GNU Lesser General Public |
... | @@ -29,9 +29,9 @@ extern int mu_log_facility; | ... | @@ -29,9 +29,9 @@ extern int mu_log_facility; |
29 | extern char *mu_log_tag; | 29 | extern char *mu_log_tag; |
30 | #define MU_LOG_TAG() (mu_log_tag ? mu_log_tag : mu_program_name) | 30 | #define MU_LOG_TAG() (mu_log_tag ? mu_log_tag : mu_program_name) |
31 | 31 | ||
32 | int mu_string_to_syslog_facility (char *str, int *pfacility); | 32 | int mu_string_to_syslog_facility (const char *str, int *pfacility); |
33 | const char *mu_syslog_facility_to_string (int n); | 33 | const char *mu_syslog_facility_to_string (int n); |
34 | int mu_string_to_syslog_priority (char *str, int *pprio); | 34 | int mu_string_to_syslog_priority (const char *str, int *pprio); |
35 | const char *mu_syslog_priority_to_string (int n); | 35 | const char *mu_syslog_priority_to_string (int n); |
36 | 36 | ||
37 | #ifdef __cplusplus | 37 | #ifdef __cplusplus | ... | ... |
... | @@ -110,7 +110,8 @@ typedef struct _mu_acl *mu_acl_t; | ... | @@ -110,7 +110,8 @@ typedef struct _mu_acl *mu_acl_t; |
110 | typedef struct _mu_server *mu_server_t; | 110 | typedef struct _mu_server *mu_server_t; |
111 | typedef struct _mu_ip_server *mu_ip_server_t; | 111 | typedef struct _mu_ip_server *mu_ip_server_t; |
112 | typedef struct _mu_m_server *mu_m_server_t; | 112 | typedef struct _mu_m_server *mu_m_server_t; |
113 | 113 | typedef struct _mu_opool *mu_opool_t; | |
114 | |||
114 | #define MU_FOLDER_ATTRIBUTE_DIRECTORY 0x001 | 115 | #define MU_FOLDER_ATTRIBUTE_DIRECTORY 0x001 |
115 | #define MU_FOLDER_ATTRIBUTE_FILE 0x002 | 116 | #define MU_FOLDER_ATTRIBUTE_FILE 0x002 |
116 | 117 | ... | ... |
... | @@ -39,37 +39,28 @@ int deny_severity = LOG_INFO; | ... | @@ -39,37 +39,28 @@ int deny_severity = LOG_INFO; |
39 | int allow_severity = LOG_INFO; | 39 | int allow_severity = LOG_INFO; |
40 | 40 | ||
41 | int | 41 | int |
42 | mu_tcp_wrapper_cb_hosts_allow (mu_debug_t debug, void *data, char *arg) | ||
43 | { | ||
44 | hosts_allow_table = strdup (arg); | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | int | ||
49 | mu_tcp_wrapper_cb_hosts_deny (mu_debug_t debug, void *data, char *arg) | ||
50 | { | ||
51 | hosts_deny_table = strdup (arg); | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | int | ||
56 | mu_tcp_wrapper_cb_hosts_allow_syslog (mu_debug_t debug, void *data, | 42 | mu_tcp_wrapper_cb_hosts_allow_syslog (mu_debug_t debug, void *data, |
57 | char *arg) | 43 | mu_config_value_t *val) |
58 | { | 44 | { |
59 | if (mu_string_to_syslog_priority (arg, &allow_severity)) | 45 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) |
46 | return 1; | ||
47 | if (mu_string_to_syslog_priority (val->v.string, &allow_severity)) | ||
60 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, | 48 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, |
61 | _("Unknown syslog priority `%s'"), | 49 | _("Unknown syslog priority `%s'"), |
62 | arg); | 50 | val->v.string); |
63 | return 0; | 51 | return 0; |
64 | } | 52 | } |
65 | 53 | ||
66 | int | 54 | int |
67 | mu_tcp_wrapper_cb_hosts_deny_syslog (mu_debug_t debug, void *data, char *arg) | 55 | mu_tcp_wrapper_cb_hosts_deny_syslog (mu_debug_t debug, void *data, |
56 | mu_config_value_t *val) | ||
68 | { | 57 | { |
69 | if (mu_string_to_syslog_priority (arg, &deny_severity)) | 58 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) |
59 | return 1; | ||
60 | if (mu_string_to_syslog_priority (val->v.string, &deny_severity)) | ||
70 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, | 61 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, |
71 | _("Unknown syslog priority `%s'"), | 62 | _("Unknown syslog priority `%s'"), |
72 | arg); | 63 | val->v.string); |
73 | return 0; | 64 | return 0; |
74 | } | 65 | } |
75 | 66 | ||
... | @@ -95,13 +86,13 @@ struct mu_cfg_param tcpwrapper_param[] = { | ... | @@ -95,13 +86,13 @@ struct mu_cfg_param tcpwrapper_param[] = { |
95 | { "daemon", mu_cfg_string, &mu_tcp_wrapper_daemon, 0, NULL, | 86 | { "daemon", mu_cfg_string, &mu_tcp_wrapper_daemon, 0, NULL, |
96 | N_("Set daemon name for TCP wrapper lookups. Default is program name."), | 87 | N_("Set daemon name for TCP wrapper lookups. Default is program name."), |
97 | N_("name") }, | 88 | N_("name") }, |
98 | { "allow-table", mu_cfg_callback, NULL, 0, | 89 | { "allow-table", mu_cfg_string, &hosts_allow_table, |
99 | mu_tcp_wrapper_cb_hosts_allow, | 90 | 0, NULL, |
100 | N_("Use file for positive client address access control " | 91 | N_("Use file for positive client address access control " |
101 | "(default: /etc/hosts.allow)."), | 92 | "(default: /etc/hosts.allow)."), |
102 | N_("file") }, | 93 | N_("file") }, |
103 | { "deny-table", mu_cfg_callback, NULL, 0, | 94 | { "deny-table", mu_cfg_string, &hosts_deny_table, |
104 | mu_tcp_wrapper_cb_hosts_deny, | 95 | 0, NULL, |
105 | N_("Use file for negative client address access control " | 96 | N_("Use file for negative client address access control " |
106 | "(default: /etc/hosts.deny)."), | 97 | "(default: /etc/hosts.deny)."), |
107 | N_("file") }, | 98 | N_("file") }, | ... | ... |
1 | /* This file is part of GNU Mailutils | 1 | /* This file is part of GNU Mailutils |
2 | Copyright (C) 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or | 4 | GNU Mailutils is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU General Public License as | 5 | modify it under the terms of the GNU General Public License as |
... | @@ -35,23 +35,21 @@ | ... | @@ -35,23 +35,21 @@ |
35 | 35 | ||
36 | #define SKIPWS(p) while (*(p) && ISSPACE (*(p))) (p)++; | 36 | #define SKIPWS(p) while (*(p) && ISSPACE (*(p))) (p)++; |
37 | 37 | ||
38 | static char * | 38 | static const char * |
39 | getword (char **parg) | 39 | getword (mu_config_value_t *val, int *pn, mu_debug_t err) |
40 | { | 40 | { |
41 | char *arg = *parg; | 41 | int n = (*pn)++; |
42 | char *word; | 42 | mu_config_value_t *v; |
43 | 43 | ||
44 | SKIPWS (arg); | 44 | if (n >= val->v.arg.c) |
45 | word = arg; | ||
46 | if (*arg) | ||
47 | { | 45 | { |
48 | while (*arg && !ISSPACE (*arg)) | 46 | mu_cfg_format_error (err, MU_DEBUG_ERROR, _("not enough arguments")); |
49 | arg++; | 47 | return NULL; |
50 | if (*arg) | ||
51 | *arg++ = 0; | ||
52 | } | 48 | } |
53 | *parg = arg; | 49 | v = &val->v.arg.v[n]; |
54 | return word; | 50 | if (mu_cfg_assert_value_type (v, MU_CFG_STRING, err)) |
51 | return NULL; | ||
52 | return v->v.string; | ||
55 | } | 53 | } |
56 | 54 | ||
57 | struct netdef | 55 | struct netdef |
... | @@ -66,7 +64,7 @@ struct netdef | ... | @@ -66,7 +64,7 @@ struct netdef |
66 | #endif | 64 | #endif |
67 | 65 | ||
68 | int | 66 | int |
69 | parse_address (mu_debug_t err, char *str, struct netdef *nd) | 67 | parse_address (mu_debug_t err, const char *str, struct netdef *nd) |
70 | { | 68 | { |
71 | struct sockaddr_in in; | 69 | struct sockaddr_in in; |
72 | 70 | ||
... | @@ -94,21 +92,33 @@ parse_address (mu_debug_t err, char *str, struct netdef *nd) | ... | @@ -94,21 +92,33 @@ parse_address (mu_debug_t err, char *str, struct netdef *nd) |
94 | } | 92 | } |
95 | 93 | ||
96 | static int | 94 | static int |
97 | parsearg (mu_debug_t err, char *arg, struct netdef *pnd, char **prest) | 95 | parsearg (mu_debug_t err, mu_config_value_t *val, struct netdef *pnd, |
96 | char **prest) | ||
98 | { | 97 | { |
99 | char *w, *p; | 98 | const char *w; |
99 | char *p; | ||
100 | unsigned long netmask; | 100 | unsigned long netmask; |
101 | 101 | int n = 0; | |
102 | w = getword (&arg); | ||
103 | if (strcmp (w, "from") == 0) | ||
104 | w = getword (&arg); | ||
105 | 102 | ||
103 | if (mu_cfg_assert_value_type (val, MU_CFG_ARRAY, err)) | ||
104 | return 1; | ||
105 | |||
106 | w = getword (val, &n, err); | ||
107 | if (!w) | ||
108 | return 1; | ||
109 | if (strcmp (w, "from") == 0) { | ||
110 | w = getword (val, &n, err); | ||
111 | if (!w) | ||
112 | return 1; | ||
113 | } | ||
114 | |||
106 | p = strchr (w, '/'); | 115 | p = strchr (w, '/'); |
107 | if (p) | 116 | if (p) |
108 | { | 117 | { |
109 | char *q; | 118 | char *q; |
110 | unsigned netlen; | 119 | unsigned netlen; |
111 | 120 | ||
121 | /* FIXME: This modifies a const char! */ | ||
112 | *p++ = 0; | 122 | *p++ = 0; |
113 | netlen = strtoul (p, &q, 10); | 123 | netlen = strtoul (p, &q, 10); |
114 | if (*q == 0) | 124 | if (*q == 0) |
... | @@ -146,28 +156,44 @@ parsearg (mu_debug_t err, char *arg, struct netdef *pnd, char **prest) | ... | @@ -146,28 +156,44 @@ parsearg (mu_debug_t err, char *arg, struct netdef *pnd, char **prest) |
146 | if (parse_address (err, w, pnd)) | 156 | if (parse_address (err, w, pnd)) |
147 | return 1; | 157 | return 1; |
148 | 158 | ||
149 | SKIPWS (arg); | ||
150 | if (prest) | 159 | if (prest) |
151 | { | 160 | { |
152 | if (*arg == 0) | 161 | if (n == val->v.arg.c) |
153 | *prest = NULL; | 162 | *prest = NULL; |
154 | else | 163 | else |
155 | { | 164 | { |
156 | int len = strlen (arg); | 165 | size_t size; |
157 | *prest = malloc (len); | 166 | int i; |
158 | if (!prest) | 167 | char *buf; |
168 | |||
169 | for (i = n; i < val->v.arg.c; i++) | ||
170 | { | ||
171 | if (mu_cfg_assert_value_type (&val->v.arg.v[i], MU_CFG_STRING, | ||
172 | err)) | ||
173 | return 1; | ||
174 | size += strlen (val->v.arg.v[i].v.string) + 1; | ||
175 | } | ||
176 | |||
177 | buf = malloc (size); | ||
178 | if (!buf) | ||
159 | { | 179 | { |
160 | mu_cfg_format_error (err, MU_DEBUG_ERROR, | 180 | mu_cfg_format_error (err, MU_DEBUG_ERROR, |
161 | "%s", mu_strerror (errno)); | 181 | "%s", mu_strerror (errno)); |
162 | return 1; | 182 | return 1; |
183 | } | ||
184 | |||
185 | *prest = buf; | ||
186 | for (i = n; i < val->v.arg.c; i++) | ||
187 | { | ||
188 | if (i > n) | ||
189 | *buf++ = ' '; | ||
190 | strcpy (buf, val->v.arg.v[i].v.string); | ||
191 | buf += strlen (buf); | ||
163 | } | 192 | } |
164 | if (arg[0] == '"' || arg[0] == '\'') | 193 | *buf = 0; |
165 | mu_argcv_unquote_copy (*prest, arg, len); | ||
166 | else | ||
167 | strcpy (*prest, arg); | ||
168 | } | 194 | } |
169 | } | 195 | } |
170 | else if (*arg != 0) | 196 | else if (n != val->v.arg.c) |
171 | { | 197 | { |
172 | mu_cfg_format_error (err, MU_DEBUG_ERROR, _("junk after IP address")); | 198 | mu_cfg_format_error (err, MU_DEBUG_ERROR, _("junk after IP address")); |
173 | return 1; | 199 | return 1; |
... | @@ -176,13 +202,13 @@ parsearg (mu_debug_t err, char *arg, struct netdef *pnd, char **prest) | ... | @@ -176,13 +202,13 @@ parsearg (mu_debug_t err, char *arg, struct netdef *pnd, char **prest) |
176 | } | 202 | } |
177 | 203 | ||
178 | static int | 204 | static int |
179 | cb_allow (mu_debug_t err, void *data, char *arg) | 205 | cb_allow (mu_debug_t err, void *data, mu_config_value_t *val) |
180 | { | 206 | { |
181 | int rc; | 207 | int rc; |
182 | mu_acl_t acl = *(mu_acl_t*)data; | 208 | mu_acl_t acl = *(mu_acl_t*)data; |
183 | struct netdef ndef; | 209 | struct netdef ndef; |
184 | 210 | ||
185 | if (parsearg (err, arg, &ndef, NULL)) | 211 | if (parsearg (err, val, &ndef, NULL)) |
186 | return 1; | 212 | return 1; |
187 | rc = mu_acl_append (acl, mu_acl_accept, NULL, ndef.sa, ndef.len, | 213 | rc = mu_acl_append (acl, mu_acl_accept, NULL, ndef.sa, ndef.len, |
188 | ndef.netmask); | 214 | ndef.netmask); |
... | @@ -195,13 +221,13 @@ cb_allow (mu_debug_t err, void *data, char *arg) | ... | @@ -195,13 +221,13 @@ cb_allow (mu_debug_t err, void *data, char *arg) |
195 | } | 221 | } |
196 | 222 | ||
197 | static int | 223 | static int |
198 | cb_deny (mu_debug_t err, void *data, char *arg) | 224 | cb_deny (mu_debug_t err, void *data, mu_config_value_t *val) |
199 | { | 225 | { |
200 | int rc; | 226 | int rc; |
201 | mu_acl_t acl = *(mu_acl_t*)data; | 227 | mu_acl_t acl = *(mu_acl_t*)data; |
202 | struct netdef ndef; | 228 | struct netdef ndef; |
203 | 229 | ||
204 | if (parsearg (err, arg, &ndef, NULL)) | 230 | if (parsearg (err, val, &ndef, NULL)) |
205 | return 1; | 231 | return 1; |
206 | rc = mu_acl_append (acl, mu_acl_deny, NULL, ndef.sa, ndef.len, | 232 | rc = mu_acl_append (acl, mu_acl_deny, NULL, ndef.sa, ndef.len, |
207 | ndef.netmask); | 233 | ndef.netmask); |
... | @@ -214,14 +240,14 @@ cb_deny (mu_debug_t err, void *data, char *arg) | ... | @@ -214,14 +240,14 @@ cb_deny (mu_debug_t err, void *data, char *arg) |
214 | } | 240 | } |
215 | 241 | ||
216 | static int | 242 | static int |
217 | cb_log (mu_debug_t err, void *data, char *arg) | 243 | cb_log (mu_debug_t err, void *data, mu_config_value_t *val) |
218 | { | 244 | { |
219 | int rc; | 245 | int rc; |
220 | mu_acl_t acl = *(mu_acl_t*)data; | 246 | mu_acl_t acl = *(mu_acl_t*)data; |
221 | struct netdef ndef; | 247 | struct netdef ndef; |
222 | char *rest; | 248 | char *rest; |
223 | 249 | ||
224 | if (parsearg (err, arg, &ndef, &rest)) | 250 | if (parsearg (err, val, &ndef, &rest)) |
225 | return 1; | 251 | return 1; |
226 | rc = mu_acl_append (acl, mu_acl_log, rest, ndef.sa, ndef.len, | 252 | rc = mu_acl_append (acl, mu_acl_log, rest, ndef.sa, ndef.len, |
227 | ndef.netmask); | 253 | ndef.netmask); |
... | @@ -234,14 +260,14 @@ cb_log (mu_debug_t err, void *data, char *arg) | ... | @@ -234,14 +260,14 @@ cb_log (mu_debug_t err, void *data, char *arg) |
234 | } | 260 | } |
235 | 261 | ||
236 | static int | 262 | static int |
237 | cb_exec (mu_debug_t err, void *data, char *arg) | 263 | cb_exec (mu_debug_t err, void *data, mu_config_value_t *val) |
238 | { | 264 | { |
239 | int rc; | 265 | int rc; |
240 | mu_acl_t acl = *(mu_acl_t*)data; | 266 | mu_acl_t acl = *(mu_acl_t*)data; |
241 | struct netdef ndef; | 267 | struct netdef ndef; |
242 | char *rest; | 268 | char *rest; |
243 | 269 | ||
244 | if (parsearg (err, arg, &ndef, &rest)) | 270 | if (parsearg (err, val, &ndef, &rest)) |
245 | return 1; | 271 | return 1; |
246 | rc = mu_acl_append (acl, mu_acl_exec, rest, ndef.sa, ndef.len, | 272 | rc = mu_acl_append (acl, mu_acl_exec, rest, ndef.sa, ndef.len, |
247 | ndef.netmask); | 273 | ndef.netmask); |
... | @@ -254,14 +280,14 @@ cb_exec (mu_debug_t err, void *data, char *arg) | ... | @@ -254,14 +280,14 @@ cb_exec (mu_debug_t err, void *data, char *arg) |
254 | } | 280 | } |
255 | 281 | ||
256 | static int | 282 | static int |
257 | cb_ifexec (mu_debug_t err, void *data, char *arg) | 283 | cb_ifexec (mu_debug_t err, void *data, mu_config_value_t *val) |
258 | { | 284 | { |
259 | int rc; | 285 | int rc; |
260 | mu_acl_t acl = *(mu_acl_t*)data; | 286 | mu_acl_t acl = *(mu_acl_t*)data; |
261 | struct netdef ndef; | 287 | struct netdef ndef; |
262 | char *rest; | 288 | char *rest; |
263 | 289 | ||
264 | if (parsearg (err, arg, &ndef, &rest)) | 290 | if (parsearg (err, val, &ndef, &rest)) |
265 | return 1; | 291 | return 1; |
266 | rc = mu_acl_append (acl, mu_acl_ifexec, rest, ndef.sa, ndef.len, | 292 | rc = mu_acl_append (acl, mu_acl_ifexec, rest, ndef.sa, ndef.len, |
267 | ndef.netmask); | 293 | ndef.netmask); | ... | ... |
1 | /* This file is part of GNU Mailutils | 1 | /* This file is part of GNU Mailutils |
2 | Copyright (C) 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or | 4 | GNU Mailutils is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU General Public License as | 5 | modify it under the terms of the GNU General Public License as |
... | @@ -29,28 +29,73 @@ | ... | @@ -29,28 +29,73 @@ |
29 | /* Resource-style configuration */ | 29 | /* Resource-style configuration */ |
30 | /* ************************************************************************* */ | 30 | /* ************************************************************************* */ |
31 | static int | 31 | static int |
32 | cb_authentication (mu_debug_t err, void *data, char *arg) | 32 | cb_authentication (mu_debug_t err, void *data, mu_config_value_t *val) |
33 | { | 33 | { |
34 | if (strcmp (arg, "clear") == 0) | 34 | if (val->type == MU_CFG_STRING) |
35 | mu_authentication_clear_list (); | 35 | { |
36 | if (strcmp (val->v.string, "clear") == 0) | ||
37 | mu_authentication_clear_list (); | ||
38 | else | ||
39 | /*FIXME: use err for error reporting*/ | ||
40 | mu_authentication_add_module_list (val->v.string); | ||
41 | } | ||
42 | else if (val->type == MU_CFG_LIST) | ||
43 | { | ||
44 | int i; | ||
45 | for (i = 0; i < val->v.arg.c; i++) | ||
46 | { | ||
47 | if (mu_cfg_assert_value_type (&val->v.arg.v[i], MU_CFG_STRING, err)) | ||
48 | return 1; | ||
49 | if (strcmp (val->v.arg.v[i].v.string, "clear") == 0) | ||
50 | mu_authentication_clear_list (); | ||
51 | else | ||
52 | mu_authentication_add_module (val->v.arg.v[i].v.string); | ||
53 | } | ||
54 | } | ||
36 | else | 55 | else |
37 | mu_authentication_add_module_list (arg);/*FIXME: use err for error | 56 | { |
38 | reporting*/ | 57 | mu_cfg_format_error (err, MU_DEBUG_ERROR, _("expected string value")); |
58 | return 1; | ||
59 | } | ||
39 | return 0; | 60 | return 0; |
40 | } | 61 | } |
41 | 62 | ||
42 | static int | 63 | static int |
43 | cb_authorization (mu_debug_t err, void *data, char *arg) | 64 | cb_authorization (mu_debug_t err, void *data, mu_config_value_t *val) |
44 | { | 65 | { |
45 | if (strcmp (arg, "clear") == 0) | 66 | if (val->type == MU_CFG_STRING) |
46 | mu_authorization_clear_list (); | 67 | { |
68 | if (strcmp (val->v.string, "clear") == 0) | ||
69 | mu_authorization_clear_list (); | ||
70 | else | ||
71 | /*FIXME: use err for error reporting*/ | ||
72 | mu_authorization_add_module_list (val->v.string); | ||
73 | } | ||
74 | else if (val->type == MU_CFG_LIST) | ||
75 | { | ||
76 | int i; | ||
77 | for (i = 0; i < val->v.arg.c; i++) | ||
78 | { | ||
79 | if (mu_cfg_assert_value_type (&val->v.arg.v[i], MU_CFG_STRING, err)) | ||
80 | return 1; | ||
81 | if (strcmp (val->v.arg.v[i].v.string, "clear") == 0) | ||
82 | mu_authorization_clear_list (); | ||
83 | else | ||
84 | mu_authorization_add_module (val->v.arg.v[i].v.string); | ||
85 | } | ||
86 | } | ||
47 | else | 87 | else |
48 | mu_authorization_add_module_list (arg);/* FIXME: see above */ | 88 | { |
89 | mu_cfg_format_error (err, MU_DEBUG_ERROR, _("expected string value")); | ||
90 | return 1; | ||
91 | } | ||
49 | return 0; | 92 | return 0; |
50 | } | 93 | } |
51 | 94 | ||
52 | static struct mu_cfg_param mu_auth_param[] = { | 95 | static struct mu_cfg_param mu_auth_param[] = { |
53 | { "authentication", mu_cfg_callback, NULL, 0, cb_authentication, | 96 | { "authentication", mu_cfg_callback, NULL, 0, cb_authentication, |
97 | /* FIXME: The description is incomplete. MU-list is also allowed as | ||
98 | argument */ | ||
54 | N_("Set a list of modules for authentication. Modlist is a " | 99 | N_("Set a list of modules for authentication. Modlist is a " |
55 | "colon-separated list of module names or a word `clear' to " | 100 | "colon-separated list of module names or a word `clear' to " |
56 | "clear the previously set up values."), | 101 | "clear the previously set up values."), | ... | ... |
... | @@ -39,9 +39,11 @@ static struct mu_gocs_debug debug_settings; | ... | @@ -39,9 +39,11 @@ static struct mu_gocs_debug debug_settings; |
39 | /* ************************************************************************* */ | 39 | /* ************************************************************************* */ |
40 | 40 | ||
41 | static int | 41 | static int |
42 | _cb_folder (mu_debug_t debug, void *data, char *arg) | 42 | _cb_folder (mu_debug_t debug, void *data, mu_config_value_t *val) |
43 | { | 43 | { |
44 | mu_set_folder_directory (arg); | 44 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) |
45 | return 1; | ||
46 | mu_set_folder_directory (val->v.string); | ||
45 | return 0; | 47 | return 0; |
46 | } | 48 | } |
47 | 49 | ||
... | @@ -127,13 +129,16 @@ DCL_CFG_CAPA (mailer); | ... | @@ -127,13 +129,16 @@ DCL_CFG_CAPA (mailer); |
127 | /* ************************************************************************* */ | 129 | /* ************************************************************************* */ |
128 | 130 | ||
129 | int | 131 | int |
130 | cb_facility (mu_debug_t debug, void *data, char *arg) | 132 | cb_facility (mu_debug_t debug, void *data, mu_config_value_t *val) |
131 | { | 133 | { |
132 | if (mu_string_to_syslog_facility (arg, &logging_settings.facility)) | 134 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) |
135 | return 1; | ||
136 | |||
137 | if (mu_string_to_syslog_facility (val->v.string, &logging_settings.facility)) | ||
133 | { | 138 | { |
134 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, | 139 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, |
135 | _("Unknown syslog facility `%s'"), | 140 | _("Unknown syslog facility `%s'"), |
136 | arg); | 141 | val->v.string); |
137 | return 1; | 142 | return 1; |
138 | } | 143 | } |
139 | return 0; | 144 | return 0; |
... | @@ -157,7 +162,7 @@ DCL_CFG_CAPA (logging); | ... | @@ -157,7 +162,7 @@ DCL_CFG_CAPA (logging); |
157 | /* ************************************************************************* */ | 162 | /* ************************************************************************* */ |
158 | 163 | ||
159 | static int | 164 | static int |
160 | cb_debug_level (mu_debug_t debug, void *data, char *arg) | 165 | _cb2_debug_level (mu_debug_t debug, const char *arg, void *data MU_ARG_UNUSED) |
161 | { | 166 | { |
162 | char buf[UINTMAX_STRSIZE_BOUND]; | 167 | char buf[UINTMAX_STRSIZE_BOUND]; |
163 | char *p; | 168 | char *p; |
... | @@ -185,7 +190,8 @@ cb_debug_level (mu_debug_t debug, void *data, char *arg) | ... | @@ -185,7 +190,8 @@ cb_debug_level (mu_debug_t debug, void *data, char *arg) |
185 | } | 190 | } |
186 | else | 191 | else |
187 | pfx = strdup ("command line");/*FIXME*/ | 192 | pfx = strdup ("command line");/*FIXME*/ |
188 | /*FIXME:*/ | 193 | /*FIXME: this is suboptimal, there's no use parsing 1st arg in |
194 | mu_global_debug_from_string */ | ||
189 | mu_global_debug_from_string (debug_settings.string, pfx); | 195 | mu_global_debug_from_string (debug_settings.string, pfx); |
190 | free (debug_settings.string); | 196 | free (debug_settings.string); |
191 | free (debug_settings.errpfx); | 197 | free (debug_settings.errpfx); |
... | @@ -193,6 +199,12 @@ cb_debug_level (mu_debug_t debug, void *data, char *arg) | ... | @@ -193,6 +199,12 @@ cb_debug_level (mu_debug_t debug, void *data, char *arg) |
193 | return 0; | 199 | return 0; |
194 | } | 200 | } |
195 | 201 | ||
202 | static int | ||
203 | cb_debug_level (mu_debug_t debug, void *data, mu_config_value_t *val) | ||
204 | { | ||
205 | return mu_cfg_string_value_cb (debug, val, _cb2_debug_level, NULL); | ||
206 | } | ||
207 | |||
196 | static struct mu_cfg_param mu_debug_param[] = { | 208 | static struct mu_cfg_param mu_debug_param[] = { |
197 | { "level", mu_cfg_callback, NULL, 0, &cb_debug_level, | 209 | { "level", mu_cfg_callback, NULL, 0, &cb_debug_level, |
198 | N_("Set Mailutils debugging level. Argument is a colon-separated list " | 210 | N_("Set Mailutils debugging level. Argument is a colon-separated list " | ... | ... |
1 | /* This file is part of GNU Mailutils | 1 | /* This file is part of GNU Mailutils |
2 | Copyright (C) 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or | 4 | GNU Mailutils is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU General Public License as | 5 | modify it under the terms of the GNU General Public License as |
... | @@ -26,16 +26,23 @@ | ... | @@ -26,16 +26,23 @@ |
26 | static struct mu_ldap_module_config ldap_settings; | 26 | static struct mu_ldap_module_config ldap_settings; |
27 | 27 | ||
28 | static int | 28 | static int |
29 | cb_field_map (mu_debug_t debug, void *data, char *arg) | 29 | _cb2_field_map (mu_debug_t debug, const char *arg, void *data) |
30 | { | 30 | { |
31 | int err; | 31 | int err; |
32 | int rc = mutil_parse_field_map (arg, &ldap_settings.field_map, &err); | 32 | int rc = mutil_parse_field_map (arg, &ldap_settings.field_map, &err); |
33 | if (rc) | 33 | if (rc) |
34 | /* FIXME: this message may be misleading */ | ||
34 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("Error near element %d: %s"), | 35 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("Error near element %d: %s"), |
35 | err, mu_strerror (rc)); | 36 | err, mu_strerror (rc)); |
36 | return 0; | 37 | return 0; |
37 | } | 38 | } |
38 | 39 | ||
40 | static int | ||
41 | cb_field_map (mu_debug_t debug, void *data, mu_config_value_t *val) | ||
42 | { | ||
43 | return mu_cfg_string_value_cb (debug, val, _cb2_field_map, NULL); | ||
44 | } | ||
45 | |||
39 | static struct mu_cfg_param mu_ldap_param[] = { | 46 | static struct mu_cfg_param mu_ldap_param[] = { |
40 | { "enable", mu_cfg_bool, &ldap_settings.enable, 0, NULL, | 47 | { "enable", mu_cfg_bool, &ldap_settings.enable, 0, NULL, |
41 | N_("Enable LDAP lookups.") }, | 48 | N_("Enable LDAP lookups.") }, | ... | ... |
1 | /* This file is part of GNU Mailutils | 1 | /* This file is part of GNU Mailutils |
2 | Copyright (C) 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or | 4 | GNU Mailutils is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU General Public License as | 5 | modify it under the terms of the GNU General Public License as |
... | @@ -25,10 +25,13 @@ | ... | @@ -25,10 +25,13 @@ |
25 | static struct mu_gocs_sieve sieve_settings; | 25 | static struct mu_gocs_sieve sieve_settings; |
26 | 26 | ||
27 | static int | 27 | static int |
28 | cb_clear_library_path (mu_debug_t debug, void *data, char *arg) | 28 | cb_clear_library_path (mu_debug_t debug, void *data, mu_config_value_t *val) |
29 | { | 29 | { |
30 | int flag; | 30 | int flag; |
31 | if (mu_cfg_parse_boolean (arg, &flag)) | 31 | |
32 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) | ||
33 | return 1; | ||
34 | if (mu_cfg_parse_boolean (val->v.string, &flag)) | ||
32 | { | 35 | { |
33 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("not a boolean")); | 36 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("not a boolean")); |
34 | return 1; | 37 | return 1; |
... | @@ -39,10 +42,13 @@ cb_clear_library_path (mu_debug_t debug, void *data, char *arg) | ... | @@ -39,10 +42,13 @@ cb_clear_library_path (mu_debug_t debug, void *data, char *arg) |
39 | } | 42 | } |
40 | 43 | ||
41 | static int | 44 | static int |
42 | cb_clear_include_path (mu_debug_t debug, void *data, char *arg) | 45 | cb_clear_include_path (mu_debug_t debug, void *data, mu_config_value_t *val) |
43 | { | 46 | { |
44 | int flag; | 47 | int flag; |
45 | if (mu_cfg_parse_boolean (arg, &flag)) | 48 | |
49 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) | ||
50 | return 1; | ||
51 | if (mu_cfg_parse_boolean (val->v.string, &flag)) | ||
46 | { | 52 | { |
47 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("not a boolean")); | 53 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("not a boolean")); |
48 | return 1; | 54 | return 1; |
... | @@ -59,10 +65,11 @@ destroy_string (void *str) | ... | @@ -59,10 +65,11 @@ destroy_string (void *str) |
59 | } | 65 | } |
60 | 66 | ||
61 | static int | 67 | static int |
62 | _add_path (mu_list_t *plist, mu_debug_t debug, void *data, char *arg) | 68 | _add_path (mu_debug_t debug, const char *arg, void *data) |
63 | { | 69 | { |
64 | char *p; | 70 | char *p, *tmp; |
65 | 71 | mu_list_t *plist = data; | |
72 | |||
66 | if (!*plist) | 73 | if (!*plist) |
67 | { | 74 | { |
68 | int rc = mu_list_create (plist); | 75 | int rc = mu_list_create (plist); |
... | @@ -74,21 +81,26 @@ _add_path (mu_list_t *plist, mu_debug_t debug, void *data, char *arg) | ... | @@ -74,21 +81,26 @@ _add_path (mu_list_t *plist, mu_debug_t debug, void *data, char *arg) |
74 | } | 81 | } |
75 | mu_list_set_destroy_item (*plist, destroy_string); | 82 | mu_list_set_destroy_item (*plist, destroy_string); |
76 | } | 83 | } |
77 | for (p = strtok (arg, ":"); p; p = strtok (NULL, ":")) | 84 | /* FIXME: Use mu_argcv */ |
85 | tmp = strdup (arg); | ||
86 | for (p = strtok (tmp, ":"); p; p = strtok (NULL, ":")) | ||
78 | mu_list_append (*plist, strdup (p)); | 87 | mu_list_append (*plist, strdup (p)); |
88 | free (tmp); | ||
79 | return 0; | 89 | return 0; |
80 | } | 90 | } |
81 | 91 | ||
82 | static int | 92 | static int |
83 | cb_include_path (mu_debug_t debug, void *data, char *arg) | 93 | cb_include_path (mu_debug_t debug, void *data, mu_config_value_t *val) |
84 | { | 94 | { |
85 | return _add_path (&sieve_settings.include_path, debug, data, arg); | 95 | return mu_cfg_string_value_cb (debug, val, _add_path, |
86 | } | 96 | &sieve_settings.include_path); |
97 | } | ||
87 | 98 | ||
88 | static int | 99 | static int |
89 | cb_library_path (mu_debug_t debug, void *data, char *arg) | 100 | cb_library_path (mu_debug_t debug, void *data, mu_config_value_t *val) |
90 | { | 101 | { |
91 | return _add_path (&sieve_settings.library_path, debug, data, arg); | 102 | return mu_cfg_string_value_cb (debug, val, _add_path, |
103 | &sieve_settings.library_path); | ||
92 | } | 104 | } |
93 | 105 | ||
94 | static struct mu_cfg_param mu_sieve_param[] = { | 106 | static struct mu_cfg_param mu_sieve_param[] = { | ... | ... |
... | @@ -29,26 +29,36 @@ static struct mu_sql_module_config sql_settings; | ... | @@ -29,26 +29,36 @@ static struct mu_sql_module_config sql_settings; |
29 | 29 | ||
30 | /* Resource file configuration */ | 30 | /* Resource file configuration */ |
31 | static int | 31 | static int |
32 | cb_password_type (mu_debug_t debug, void *data, char *arg) | 32 | cb_password_type (mu_debug_t debug, void *data, mu_config_value_t *val) |
33 | { | 33 | { |
34 | if (mu_sql_decode_password_type (arg, &sql_settings.password_type)) | 34 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) |
35 | return 1; | ||
36 | |||
37 | if (mu_sql_decode_password_type (val->v.string, &sql_settings.password_type)) | ||
35 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, | 38 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, |
36 | _("Unknown password type `%s'"), | 39 | _("Unknown password type `%s'"), |
37 | arg); | 40 | val->v.string); |
38 | return 0; | 41 | return 0; |
39 | } | 42 | } |
40 | 43 | ||
41 | static int | 44 | static int |
42 | cb_field_map (mu_debug_t debug, void *data, char *arg) | 45 | _cb2_field_map (mu_debug_t debug, const char *arg, void *data) |
43 | { | 46 | { |
44 | int err; | 47 | int err; |
45 | int rc = mutil_parse_field_map (arg, &sql_settings.field_map, &err); | 48 | int rc = mutil_parse_field_map (arg, &sql_settings.field_map, &err); |
46 | if (rc) | 49 | if (rc) |
50 | /* FIXME: this message may be misleading */ | ||
47 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("Error near element %d: %s"), | 51 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("Error near element %d: %s"), |
48 | err, mu_strerror (rc)); | 52 | err, mu_strerror (rc)); |
49 | return 0; | 53 | return 0; |
50 | } | 54 | } |
51 | 55 | ||
56 | static int | ||
57 | cb_field_map (mu_debug_t debug, void *data, mu_config_value_t *val) | ||
58 | { | ||
59 | return mu_cfg_string_value_cb (debug, val, _cb2_field_map, NULL); | ||
60 | } | ||
61 | |||
52 | static struct mu_cfg_param mu_sql_param[] = { | 62 | static struct mu_cfg_param mu_sql_param[] = { |
53 | { "interface", mu_cfg_string, &sql_settings.interface, 0, NULL, | 63 | { "interface", mu_cfg_string, &sql_settings.interface, 0, NULL, |
54 | N_("Set SQL interface to use (one of: mysql, odbc, or postgres).") }, | 64 | N_("Set SQL interface to use (one of: mysql, odbc, or postgres).") }, | ... | ... |
... | @@ -242,9 +242,11 @@ parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -242,9 +242,11 @@ parse_opt (int key, char *arg, struct argp_state *state) |
242 | 242 | ||
243 | 243 | ||
244 | static int | 244 | static int |
245 | cb_debug (mu_debug_t debug, void *data, char *arg) | 245 | cb_debug (mu_debug_t debug, void *data, mu_config_value_t *val) |
246 | { | 246 | { |
247 | set_debug_flags (debug, arg); | 247 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) |
248 | return 1; | ||
249 | set_debug_flags (debug, val->v.string); | ||
248 | return 0; | 250 | return 0; |
249 | } | 251 | } |
250 | 252 | ... | ... |
... | @@ -249,9 +249,11 @@ parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -249,9 +249,11 @@ parse_opt (int key, char *arg, struct argp_state *state) |
249 | 249 | ||
250 | 250 | ||
251 | static int | 251 | static int |
252 | cb_debug (mu_debug_t debug, void *data, char *arg) | 252 | cb_debug (mu_debug_t debug, void *data, mu_config_value_t *val) |
253 | { | 253 | { |
254 | set_debug_flags (debug, arg); | 254 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) |
255 | return 1; | ||
256 | set_debug_flags (debug, val->v.string); | ||
255 | return 0; | 257 | return 0; |
256 | } | 258 | } |
257 | 259 | ... | ... |
... | @@ -22,6 +22,7 @@ INCLUDES = @MU_COMMON_INCLUDES@ -I${top_srcdir}/libproto/include | ... | @@ -22,6 +22,7 @@ INCLUDES = @MU_COMMON_INCLUDES@ -I${top_srcdir}/libproto/include |
22 | 22 | ||
23 | YLWRAP = $(SHELL) $(top_srcdir)/scripts/gylwrap | 23 | YLWRAP = $(SHELL) $(top_srcdir)/scripts/gylwrap |
24 | AM_YFLAGS=-vt | 24 | AM_YFLAGS=-vt |
25 | AM_LFLAGS=-dvp | ||
25 | 26 | ||
26 | SUBDIRS = testsuite | 27 | SUBDIRS = testsuite |
27 | 28 | ||
... | @@ -33,11 +34,21 @@ AM_CPPFLAGS = \ | ... | @@ -33,11 +34,21 @@ AM_CPPFLAGS = \ |
33 | -DSITE_VIRTUAL_PWDDIR=\"@SITE_VIRTUAL_PWDDIR@\"\ | 34 | -DSITE_VIRTUAL_PWDDIR=\"@SITE_VIRTUAL_PWDDIR@\"\ |
34 | -DLOCALEDIR=\"$(localedir)\" | 35 | -DLOCALEDIR=\"$(localedir)\" |
35 | 36 | ||
36 | EXTRA_DIST = errors muerrno.cin parsedate.y fgetpwent.c cfg_parser.y cfg_parser.h inttostr.c inttostr.h | 37 | EXTRA_DIST = \ |
38 | errors\ | ||
39 | muerrno.cin\ | ||
40 | parsedate.y\ | ||
41 | fgetpwent.c\ | ||
42 | cfg_lexer.l\ | ||
43 | cfg_parser.y\ | ||
44 | cfg_parser.h\ | ||
45 | inttostr.c\ | ||
46 | inttostr.h | ||
37 | 47 | ||
38 | libmailutils_la_SOURCES = \ | 48 | libmailutils_la_SOURCES = \ |
39 | acl.c\ | 49 | acl.c\ |
40 | address.c\ | 50 | address.c\ |
51 | alloc.c\ | ||
41 | amd.c\ | 52 | amd.c\ |
42 | argcv.c\ | 53 | argcv.c\ |
43 | assoc.c\ | 54 | assoc.c\ |
... | @@ -94,6 +105,7 @@ libmailutils_la_SOURCES = \ | ... | @@ -94,6 +105,7 @@ libmailutils_la_SOURCES = \ |
94 | muerrno.c\ | 105 | muerrno.c\ |
95 | nls.c\ | 106 | nls.c\ |
96 | observer.c\ | 107 | observer.c\ |
108 | opool.c\ | ||
97 | parse822.c\ | 109 | parse822.c\ |
98 | parsedate.c\ | 110 | parsedate.c\ |
99 | property.c\ | 111 | property.c\ |
... | @@ -114,7 +126,7 @@ libmailutils_la_SOURCES = \ | ... | @@ -114,7 +126,7 @@ libmailutils_la_SOURCES = \ |
114 | wicket.c\ | 126 | wicket.c\ |
115 | imaxtostr.c offtostr.c umaxtostr.c intprops.h | 127 | imaxtostr.c offtostr.c umaxtostr.c intprops.h |
116 | 128 | ||
117 | BUILT_SOURCES = parsedate.c muerrno.c cfg_parser.c cfg_parser.h | 129 | BUILT_SOURCES = parsedate.c muerrno.c cfg_parser.c cfg_parser.h cfg_lexer.c |
118 | MOSTLYCLEANFILES= | 130 | MOSTLYCLEANFILES= |
119 | 131 | ||
120 | parsedate.c: $(srcdir)/parsedate.y | 132 | parsedate.c: $(srcdir)/parsedate.y |
... | @@ -128,6 +140,11 @@ cfg_parser.c cfg_parser.h: $(srcdir)/cfg_parser.y | ... | @@ -128,6 +140,11 @@ cfg_parser.c cfg_parser.h: $(srcdir)/cfg_parser.y |
128 | y.output cfg_parser.y.output \ | 140 | y.output cfg_parser.y.output \ |
129 | -- -yy mu_cfg_yy | 141 | -- -yy mu_cfg_yy |
130 | 142 | ||
143 | cfg_lexer.c: $(srcdir)/cfg_lexer.l cfg_parser.h | ||
144 | $(YLWRAP) "$(LEX) $(AM_LFLAGS) $(LFLAGS)" \ | ||
145 | $(srcdir)/cfg_lexer.l lex.yy.c cfg_lexer.c \ | ||
146 | -- -yy mu_cfg_yy | ||
147 | |||
131 | muerrno.c: errors muerrno.cin | 148 | muerrno.c: errors muerrno.cin |
132 | $(AWK) -f $(top_srcdir)/scripts/generr.awk $^ > $@ | 149 | $(AWK) -f $(top_srcdir)/scripts/generr.awk $^ > $@ |
133 | 150 | ... | ... |
mailbox/alloc.c
0 → 100644
1 | /* Error-proof memory allocation functions. | ||
2 | Copyright (C) 2008 Free Software Foundation, Inc. | ||
3 | |||
4 | GNU Mailutils is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU General Public License as | ||
6 | published by the Free Software Foundation; either version 3, or (at | ||
7 | your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, but | ||
10 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | #ifdef HAVE_CONFIG_H | ||
18 | # include <config.h> | ||
19 | #endif | ||
20 | #include <stdio.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <string.h> | ||
23 | #include <mailutils/error.h> | ||
24 | #include <mailutils/nls.h> | ||
25 | #include <mailutils/alloc.h> | ||
26 | |||
27 | void (*mu_alloc_die_hook) (void) = NULL; | ||
28 | |||
29 | void | ||
30 | mu_alloc_die () | ||
31 | { | ||
32 | if (mu_alloc_die_hook) | ||
33 | mu_alloc_die_hook (); | ||
34 | mu_error (_("Not enough memory")); | ||
35 | abort (); | ||
36 | } | ||
37 | |||
38 | void * | ||
39 | mu_alloc (size_t size) | ||
40 | { | ||
41 | void *p = malloc (size); | ||
42 | if (!p) | ||
43 | mu_alloc_die (); | ||
44 | return p; | ||
45 | } | ||
46 | |||
47 | void * | ||
48 | mu_calloc (size_t nmemb, size_t size) | ||
49 | { | ||
50 | void *p = calloc (nmemb, size); | ||
51 | if (!p) | ||
52 | mu_alloc_die (); | ||
53 | return p; | ||
54 | } | ||
55 | |||
56 | void * | ||
57 | mu_zalloc (size_t size) | ||
58 | { | ||
59 | void *p = mu_alloc (size); | ||
60 | memset (p, 0, size); | ||
61 | return p; | ||
62 | } | ||
63 | |||
64 | void * | ||
65 | mu_realloc (void *p, size_t size) | ||
66 | { | ||
67 | void *newp = realloc (p, size); | ||
68 | if (!newp) | ||
69 | mu_alloc_die (); | ||
70 | return newp; | ||
71 | } | ||
72 | |||
73 | char * | ||
74 | mu_strdup (const char *s) | ||
75 | { | ||
76 | char *news = strdup (s); | ||
77 | if (!news) | ||
78 | mu_alloc_die (); | ||
79 | return news; | ||
80 | } | ||
81 | |||
82 | /* Copied from gnulib */ | ||
83 | void * | ||
84 | mu_2nrealloc (void *p, size_t *pn, size_t s) | ||
85 | { | ||
86 | size_t n = *pn; | ||
87 | |||
88 | if (!p) | ||
89 | { | ||
90 | if (!n) | ||
91 | { | ||
92 | /* The approximate size to use for initial small allocation | ||
93 | requests, when the invoking code specifies an old size of | ||
94 | zero. 64 bytes is the largest "small" request for the | ||
95 | GNU C library malloc. */ | ||
96 | enum { DEFAULT_MXFAST = 64 }; | ||
97 | |||
98 | n = DEFAULT_MXFAST / s; | ||
99 | n += !n; | ||
100 | } | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | /* Set N = ceil (1.5 * N) so that progress is made if N == 1. | ||
105 | Check for overflow, so that N * S stays in size_t range. | ||
106 | The check is slightly conservative, but an exact check isn't | ||
107 | worth the trouble. */ | ||
108 | if ((size_t) -1 / 3 * 2 / s <= n) | ||
109 | mu_alloc_die (); | ||
110 | n += (n + 1) / 2; | ||
111 | } | ||
112 | |||
113 | *pn = n; | ||
114 | return mu_realloc (p, n * s); | ||
115 | } | ||
116 |
... | @@ -442,8 +442,11 @@ prog_parser (enum mu_cfg_section_stage stage, | ... | @@ -442,8 +442,11 @@ prog_parser (enum mu_cfg_section_stage stage, |
442 | mu_cfg_tree_t *tree) | 442 | mu_cfg_tree_t *tree) |
443 | { | 443 | { |
444 | if (stage == mu_cfg_section_start) | 444 | if (stage == mu_cfg_section_start) |
445 | return strcmp (node->tag_label, label); | 445 | { |
446 | 446 | return node->label->type == MU_CFG_STRING | |
447 | && strcmp (node->label->v.string, label); | ||
448 | } | ||
449 | |||
447 | return 0; | 450 | return 0; |
448 | } | 451 | } |
449 | 452 | ||
... | @@ -473,14 +476,18 @@ struct include_data | ... | @@ -473,14 +476,18 @@ struct include_data |
473 | }; | 476 | }; |
474 | 477 | ||
475 | static int | 478 | static int |
476 | _cb_include (mu_debug_t debug, void *data, char *arg) | 479 | _cb_include (mu_debug_t debug, void *data, mu_config_value_t *val) |
477 | { | 480 | { |
478 | int ret = 0; | 481 | int ret = 0; |
479 | struct stat sb; | 482 | struct stat sb; |
480 | char *dirname = arg; | 483 | const char *dirname; |
481 | struct include_data *idp = data; | 484 | struct include_data *idp = data; |
482 | char *tmp = NULL; | 485 | char *tmp = NULL; |
483 | 486 | ||
487 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) | ||
488 | return 1; | ||
489 | |||
490 | dirname = val->v.string; | ||
484 | if (dirname[0] != '/') | 491 | if (dirname[0] != '/') |
485 | dirname = tmp = make_file_name (SYSCONFDIR, dirname); | 492 | dirname = tmp = make_file_name (SYSCONFDIR, dirname); |
486 | 493 | ||
... | @@ -641,3 +648,59 @@ mu_parse_config (const char *file, const char *progname, | ... | @@ -641,3 +648,59 @@ mu_parse_config (const char *file, const char *progname, |
641 | rc = ENOMEM; | 648 | rc = ENOMEM; |
642 | return rc; | 649 | return rc; |
643 | } | 650 | } |
651 | |||
652 | int | ||
653 | mu_cfg_assert_value_type (mu_config_value_t *val, int type, mu_debug_t debug) | ||
654 | { | ||
655 | if (val->type != MU_CFG_STRING) | ||
656 | { | ||
657 | /* FIXME */ | ||
658 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, | ||
659 | _("expected string value")); | ||
660 | return 1; | ||
661 | } | ||
662 | return 0; | ||
663 | } | ||
664 | |||
665 | int | ||
666 | mu_cfg_string_value_cb (mu_debug_t debug, mu_config_value_t *val, | ||
667 | int (*fun) (mu_debug_t, const char *, void *), | ||
668 | void *data) | ||
669 | { | ||
670 | switch (val->type) | ||
671 | { | ||
672 | case MU_CFG_STRING: | ||
673 | return fun (debug, val->v.string, data); | ||
674 | break; | ||
675 | |||
676 | case MU_CFG_ARRAY: | ||
677 | { | ||
678 | int i; | ||
679 | |||
680 | for (i = 0; i < val->v.arg.c; i++) | ||
681 | { | ||
682 | if (mu_cfg_assert_value_type (&val->v.arg.v[i], | ||
683 | MU_CFG_STRING, debug)) | ||
684 | return 1; | ||
685 | fun (debug, val->v.arg.v[i].v.string, data); | ||
686 | } | ||
687 | } | ||
688 | break; | ||
689 | |||
690 | case MU_CFG_LIST: | ||
691 | { | ||
692 | mu_iterator_t itr; | ||
693 | mu_list_get_iterator (val->v.list, &itr); | ||
694 | for (mu_iterator_first (itr); | ||
695 | !mu_iterator_is_done (itr); mu_iterator_next (itr)) | ||
696 | { | ||
697 | mu_config_value_t *pval; | ||
698 | mu_iterator_current (itr, (void*) &pval); | ||
699 | if (mu_cfg_assert_value_type (pval, MU_CFG_STRING, debug)) | ||
700 | fun (debug, pval->v.string, data); | ||
701 | } | ||
702 | mu_iterator_destroy (&itr); | ||
703 | } | ||
704 | } | ||
705 | return 0; | ||
706 | } | ... | ... |
1 | /* cfg_print.c -- convert configuration parse tree to human-readable format. | 1 | /* cfg_print.c -- convert configuration parse tree to human-readable format. |
2 | Copyright (C) 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or | 4 | GNU Mailutils is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU General Public License as | 5 | modify it under the terms of the GNU General Public License as |
... | @@ -18,11 +18,13 @@ | ... | @@ -18,11 +18,13 @@ |
18 | #ifdef HAVE_CONFIG_H | 18 | #ifdef HAVE_CONFIG_H |
19 | # include <config.h> | 19 | # include <config.h> |
20 | #endif | 20 | #endif |
21 | #include <mailutils/alloc.h> | ||
21 | #include <mailutils/stream.h> | 22 | #include <mailutils/stream.h> |
22 | #include <mailutils/error.h> | 23 | #include <mailutils/error.h> |
23 | #include <mailutils/cfg.h> | 24 | #include <mailutils/cfg.h> |
24 | #include <mailutils/argcv.h> | 25 | #include <mailutils/argcv.h> |
25 | #include <mailutils/nls.h> | 26 | #include <mailutils/nls.h> |
27 | #include <mailutils/iterator.h> | ||
26 | #include <ctype.h> | 28 | #include <ctype.h> |
27 | 29 | ||
28 | struct tree_print | 30 | struct tree_print |
... | @@ -41,25 +43,19 @@ format_level (mu_stream_t stream, int level) | ... | @@ -41,25 +43,19 @@ format_level (mu_stream_t stream, int level) |
41 | } | 43 | } |
42 | 44 | ||
43 | static void | 45 | static void |
44 | format_label (struct tree_print *tp, const char *label) | 46 | format_string_value (struct tree_print *tp, const char *str) |
45 | { | 47 | { |
46 | size_t size; | 48 | size_t size; |
47 | int quote; | 49 | int quote; |
48 | char *p; | 50 | char *p; |
49 | 51 | ||
50 | size = mu_argcv_quoted_length (label, "e); | 52 | size = mu_argcv_quoted_length (str, "e); |
51 | if (quote) | 53 | if (quote) |
52 | size += 2; | 54 | size += 2; |
53 | size++; | 55 | size++; |
54 | if (size > tp->bufsize) | 56 | if (size > tp->bufsize) |
55 | { | 57 | { |
56 | p = realloc (tp->buf, size); | 58 | p = mu_realloc (tp->buf, size); |
57 | if (!p) | ||
58 | { | ||
59 | mu_stream_sequential_printf (tp->stream, "%s\n", | ||
60 | _("ERROR: not enough memory")); | ||
61 | return; | ||
62 | } | ||
63 | tp->bufsize = size; | 59 | tp->bufsize = size; |
64 | tp->buf = p; | 60 | tp->buf = p; |
65 | } | 61 | } |
... | @@ -72,10 +68,64 @@ format_label (struct tree_print *tp, const char *label) | ... | @@ -72,10 +68,64 @@ format_label (struct tree_print *tp, const char *label) |
72 | p++; | 68 | p++; |
73 | } | 69 | } |
74 | tp->buf[size-1] = 0; | 70 | tp->buf[size-1] = 0; |
75 | mu_argcv_quote_copy (p, label); | 71 | mu_argcv_quote_copy (p, str); |
76 | mu_stream_sequential_write (tp->stream, tp->buf, size - 1); | 72 | mu_stream_sequential_write (tp->stream, tp->buf, size - 1); |
77 | } | 73 | } |
78 | 74 | ||
75 | static void format_value (struct tree_print *tp, mu_config_value_t *val); | ||
76 | |||
77 | static void | ||
78 | format_list_value (struct tree_print *tp, mu_config_value_t *val) | ||
79 | { | ||
80 | int i; | ||
81 | mu_iterator_t itr; | ||
82 | mu_stream_sequential_write (tp->stream, "(", 1); | ||
83 | mu_list_get_iterator (val->v.list, &itr); | ||
84 | |||
85 | for (mu_iterator_first (itr), i = 0; | ||
86 | !mu_iterator_is_done (itr); mu_iterator_next (itr), i++) | ||
87 | { | ||
88 | mu_config_value_t *p; | ||
89 | mu_iterator_current (itr, (void**)&p); | ||
90 | if (i) | ||
91 | mu_stream_sequential_write (tp->stream, ", ", 2); | ||
92 | format_value (tp, p); | ||
93 | } | ||
94 | mu_iterator_destroy (&itr); | ||
95 | mu_stream_sequential_write (tp->stream, ")", 1); | ||
96 | } | ||
97 | |||
98 | static void | ||
99 | format_array_value (struct tree_print *tp, mu_config_value_t *val) | ||
100 | { | ||
101 | int i; | ||
102 | |||
103 | for (i = 0; i < val->v.arg.c; i++) | ||
104 | { | ||
105 | if (i) | ||
106 | mu_stream_sequential_write (tp->stream, " ", 1); | ||
107 | format_value (tp, &val->v.arg.v[i]); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | static void | ||
112 | format_value (struct tree_print *tp, mu_config_value_t *val) | ||
113 | { | ||
114 | switch (val->type) | ||
115 | { | ||
116 | case MU_CFG_STRING: | ||
117 | format_string_value (tp, val->v.string); | ||
118 | break; | ||
119 | |||
120 | case MU_CFG_LIST: | ||
121 | format_list_value (tp, val); | ||
122 | break; | ||
123 | |||
124 | case MU_CFG_ARRAY: | ||
125 | format_array_value (tp, val); | ||
126 | } | ||
127 | } | ||
128 | |||
79 | static int | 129 | static int |
80 | format_node (const mu_cfg_node_t *node, void *data) | 130 | format_node (const mu_cfg_node_t *node, void *data) |
81 | { | 131 | { |
... | @@ -94,12 +144,12 @@ format_node (const mu_cfg_node_t *node, void *data) | ... | @@ -94,12 +144,12 @@ format_node (const mu_cfg_node_t *node, void *data) |
94 | 144 | ||
95 | case mu_cfg_node_tag: | 145 | case mu_cfg_node_tag: |
96 | { | 146 | { |
97 | mu_stream_sequential_write (tp->stream, node->tag_name, | 147 | mu_stream_sequential_write (tp->stream, node->tag, |
98 | strlen (node->tag_name)); | 148 | strlen (node->tag)); |
99 | if (node->tag_label) | 149 | if (node->label) |
100 | { | 150 | { |
101 | mu_stream_sequential_write (tp->stream, " ", 1); | 151 | mu_stream_sequential_write (tp->stream, " ", 1); |
102 | format_label (tp, node->tag_label); | 152 | format_value (tp, node->label); |
103 | } | 153 | } |
104 | mu_stream_sequential_write (tp->stream, " {", 2); | 154 | mu_stream_sequential_write (tp->stream, " {", 2); |
105 | tp->level++; | 155 | tp->level++; |
... | @@ -107,12 +157,12 @@ format_node (const mu_cfg_node_t *node, void *data) | ... | @@ -107,12 +157,12 @@ format_node (const mu_cfg_node_t *node, void *data) |
107 | break; | 157 | break; |
108 | 158 | ||
109 | case mu_cfg_node_param: | 159 | case mu_cfg_node_param: |
110 | mu_stream_sequential_write (tp->stream, node->tag_name, | 160 | mu_stream_sequential_write (tp->stream, node->tag, |
111 | strlen (node->tag_name)); | 161 | strlen (node->tag)); |
112 | if (node->tag_label) | 162 | if (node->label) |
113 | { | 163 | { |
114 | mu_stream_sequential_write (tp->stream, " ", 1); | 164 | mu_stream_sequential_write (tp->stream, " ", 1); |
115 | format_label (tp, node->tag_label); | 165 | format_value (tp, node->label); |
116 | mu_stream_sequential_write (tp->stream, ";", 1); | 166 | mu_stream_sequential_write (tp->stream, ";", 1); |
117 | } | 167 | } |
118 | break; | 168 | break; |
... | @@ -238,12 +288,20 @@ format_param (mu_stream_t stream, struct mu_cfg_param *param, int level) | ... | @@ -238,12 +288,20 @@ format_param (mu_stream_t stream, struct mu_cfg_param *param, int level) |
238 | mu_stream_sequential_printf (stream, "%s <%s>;\n", | 288 | mu_stream_sequential_printf (stream, "%s <%s>;\n", |
239 | param->ident, | 289 | param->ident, |
240 | gettext (param->argname)); | 290 | gettext (param->argname)); |
291 | else if (MU_CFG_IS_LIST (param->type)) | ||
292 | mu_stream_sequential_printf | ||
293 | (stream, "%s <%s: list of %s>;\n", | ||
294 | param->ident, | ||
295 | gettext (param->argname ? | ||
296 | param->argname : N_("arg")), | ||
297 | gettext (mu_cfg_data_type_string (MU_CFG_TYPE (param->type)))); | ||
241 | else | 298 | else |
242 | mu_stream_sequential_printf (stream, "%s <%s: %s>;\n", | 299 | mu_stream_sequential_printf |
243 | param->ident, | 300 | (stream, "%s <%s: %s>;\n", |
244 | gettext (param->argname ? | 301 | param->ident, |
245 | param->argname : N_("arg")), | 302 | gettext (param->argname ? |
246 | gettext (mu_cfg_data_type_string (param->type))); | 303 | param->argname : N_("arg")), |
304 | gettext (mu_cfg_data_type_string (param->type))); | ||
247 | } | 305 | } |
248 | 306 | ||
249 | static void format_container (mu_stream_t stream, struct mu_cfg_cont *cont, | 307 | static void format_container (mu_stream_t stream, struct mu_cfg_cont *cont, | ... | ... |
mailbox/cfg_lexer.c
deleted
100644 → 0
1 | /* cfg_lexer.c -- default lexer for Mailutils configuration files | ||
2 | Copyright (C) 2007, 2008 Free Software Foundation, Inc. | ||
3 | |||
4 | GNU Mailutils is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU General Public License as | ||
6 | published by the Free Software Foundation; either version 3, or (at | ||
7 | your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, but | ||
10 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | #ifdef HAVE_CONFIG_H | ||
18 | # include <config.h> | ||
19 | #endif | ||
20 | #include <stdio.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <sys/types.h> | ||
23 | #include <sys/stat.h> | ||
24 | #include <fcntl.h> | ||
25 | #include <errno.h> | ||
26 | #include <unistd.h> | ||
27 | #include <ctype.h> | ||
28 | #include <mailutils/errno.h> | ||
29 | #include <mailutils/error.h> | ||
30 | #include <mailutils/argcv.h> | ||
31 | #include <mailutils/nls.h> | ||
32 | #include <mailutils/cfg.h> | ||
33 | #include <mailutils/list.h> | ||
34 | |||
35 | #include "cfg_parser.h" | ||
36 | |||
37 | struct lexer_data | ||
38 | { | ||
39 | char *buffer; | ||
40 | char *curp; | ||
41 | mu_list_t mpool; | ||
42 | char *cbuf; | ||
43 | size_t cbufsize; | ||
44 | size_t cbuflevel; | ||
45 | }; | ||
46 | |||
47 | #define CBUFINCR 256 | ||
48 | |||
49 | static void | ||
50 | cbuf_grow (struct lexer_data *datp, const char *str, size_t len) | ||
51 | { | ||
52 | if (datp->cbufsize - datp->cbuflevel < len) | ||
53 | { | ||
54 | size_t n = ((datp->cbuflevel + len + CBUFINCR - 1) / CBUFINCR); | ||
55 | datp->cbufsize = n * CBUFINCR; | ||
56 | datp->cbuf = realloc (datp->cbuf, datp->cbufsize); | ||
57 | if (!datp->cbuf) | ||
58 | { | ||
59 | mu_error ("%s", mu_strerror (ENOMEM)); | ||
60 | abort (); | ||
61 | } | ||
62 | } | ||
63 | memcpy (datp->cbuf + datp->cbuflevel, str, len); | ||
64 | datp->cbuflevel += len; | ||
65 | } | ||
66 | |||
67 | static void | ||
68 | cbuf_1grow (struct lexer_data *datp, char c) | ||
69 | { | ||
70 | cbuf_grow (datp, &c, 1); | ||
71 | } | ||
72 | |||
73 | static void | ||
74 | _mpool_destroy_item (void *p) | ||
75 | { | ||
76 | free (p); | ||
77 | } | ||
78 | |||
79 | static char * | ||
80 | cbuf_finish (struct lexer_data *datp) | ||
81 | { | ||
82 | char *p = malloc (datp->cbuflevel); | ||
83 | if (!p) | ||
84 | { | ||
85 | mu_error ("%s", mu_strerror (ENOMEM)); | ||
86 | abort (); | ||
87 | } | ||
88 | memcpy (p, datp->cbuf, datp->cbuflevel); | ||
89 | datp->cbuflevel = 0; | ||
90 | if (!datp->mpool) | ||
91 | { | ||
92 | mu_list_create (&datp->mpool); | ||
93 | mu_list_set_destroy_item (datp->mpool, _mpool_destroy_item); | ||
94 | } | ||
95 | mu_list_append (datp->mpool, p); | ||
96 | return p; | ||
97 | } | ||
98 | |||
99 | static void | ||
100 | skipws (struct lexer_data *p) | ||
101 | { | ||
102 | while (*p->curp && isspace (*p->curp)) | ||
103 | { | ||
104 | if (*p->curp == '\n') | ||
105 | mu_cfg_locus.line++; | ||
106 | p->curp++; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | static void | ||
111 | skipline (struct lexer_data *p) | ||
112 | { | ||
113 | while (*p->curp && *p->curp != '\n') | ||
114 | p->curp++; | ||
115 | } | ||
116 | |||
117 | static int | ||
118 | continuation_line_p (struct lexer_data *p, int quote) | ||
119 | { | ||
120 | skipws (p); | ||
121 | return *p->curp == quote; | ||
122 | } | ||
123 | |||
124 | static void | ||
125 | copy_string0 (struct lexer_data *p, int unquote) | ||
126 | { | ||
127 | int quote; | ||
128 | do | ||
129 | { | ||
130 | quote = *p->curp++; | ||
131 | |||
132 | while (*p->curp) | ||
133 | { | ||
134 | if (*p->curp == '\\') | ||
135 | { | ||
136 | char c; | ||
137 | if (*++p->curp == 0) | ||
138 | { | ||
139 | cbuf_1grow (p, '\\'); | ||
140 | break; | ||
141 | } | ||
142 | if (*p->curp == '\n') | ||
143 | { | ||
144 | p->curp++; | ||
145 | continue; | ||
146 | } | ||
147 | if (!unquote) | ||
148 | c = *p->curp; | ||
149 | else | ||
150 | c = mu_argcv_unquote_char (*p->curp); | ||
151 | cbuf_1grow (p, c); | ||
152 | p->curp++; | ||
153 | } | ||
154 | else if (*p->curp == quote) | ||
155 | { | ||
156 | p->curp++; | ||
157 | break; | ||
158 | } | ||
159 | else | ||
160 | { | ||
161 | cbuf_1grow (p, *p->curp); | ||
162 | p->curp++; | ||
163 | } | ||
164 | } | ||
165 | } | ||
166 | while (continuation_line_p (p, quote)); | ||
167 | } | ||
168 | |||
169 | static char * | ||
170 | copy_string (struct lexer_data *p) | ||
171 | { | ||
172 | copy_string0 (p, 1); | ||
173 | cbuf_1grow (p, 0); | ||
174 | return cbuf_finish (p); | ||
175 | } | ||
176 | |||
177 | static char * | ||
178 | copy_to (struct lexer_data *p, const char *delim) | ||
179 | { | ||
180 | while (*p->curp) | ||
181 | { | ||
182 | if (*p->curp == '"' || *p->curp == '\'') | ||
183 | { | ||
184 | int quote = *p->curp; | ||
185 | cbuf_1grow (p, quote); | ||
186 | copy_string0 (p, 0); | ||
187 | cbuf_1grow (p, quote); | ||
188 | continue; | ||
189 | } | ||
190 | |||
191 | if (strchr (delim, *p->curp)) | ||
192 | break; | ||
193 | if (*p->curp == '\n') | ||
194 | mu_cfg_locus.line++; | ||
195 | cbuf_1grow (p, *p->curp); | ||
196 | p->curp++; | ||
197 | } | ||
198 | cbuf_1grow (p, 0); | ||
199 | return cbuf_finish (p); | ||
200 | } | ||
201 | |||
202 | static int | ||
203 | isword (int c) | ||
204 | { | ||
205 | if (mu_cfg_tie_in) | ||
206 | return c && c != ';' && c != '{'; | ||
207 | |||
208 | return isalnum (c) || c == '_' || c == '-' || c == '.'; | ||
209 | } | ||
210 | |||
211 | static char * | ||
212 | copy_alpha (struct lexer_data *p) | ||
213 | { | ||
214 | do | ||
215 | { | ||
216 | if (mu_cfg_tie_in && (*p->curp == '"' || *p->curp == '\'')) | ||
217 | { | ||
218 | int quote = *p->curp; | ||
219 | cbuf_1grow (p, quote); | ||
220 | copy_string0 (p, 0); | ||
221 | cbuf_1grow (p, quote); | ||
222 | continue; | ||
223 | } | ||
224 | |||
225 | if (*p->curp == '\n') | ||
226 | mu_cfg_locus.line++; | ||
227 | cbuf_1grow (p, *p->curp); | ||
228 | p->curp++; | ||
229 | } while (*p->curp && isword (*p->curp)); | ||
230 | cbuf_1grow (p, 0); | ||
231 | return cbuf_finish (p); | ||
232 | } | ||
233 | |||
234 | #define LEX_DEBUG(tok, arg1, arg2) \ | ||
235 | do \ | ||
236 | { \ | ||
237 | if (mu_debug_check_level (dbg, MU_DEBUG_TRACE2)) \ | ||
238 | { \ | ||
239 | mu_debug_set_locus (dbg, \ | ||
240 | mu_cfg_locus.file, mu_cfg_locus.line); \ | ||
241 | mu_cfg_format_error (dbg, MU_DEBUG_TRACE2, "TOKEN %s \"%s\" \"%s\"", \ | ||
242 | tok, \ | ||
243 | arg1 ? arg1 : "", \ | ||
244 | arg2 ? arg2 : ""); \ | ||
245 | } \ | ||
246 | } \ | ||
247 | while (0) | ||
248 | |||
249 | static void | ||
250 | rtrim (char *arg) | ||
251 | { | ||
252 | int len = strlen (arg); | ||
253 | while (len > 0 && strchr (" \t\n\r", arg[len-1])) | ||
254 | len--; | ||
255 | arg[len] = 0; | ||
256 | } | ||
257 | |||
258 | int | ||
259 | default_lexer (void *dp, mu_debug_t dbg) | ||
260 | { | ||
261 | struct lexer_data *p = dp; | ||
262 | char *save_start; | ||
263 | char *tag, *label; | ||
264 | extern int mu_cfg_yydebug; | ||
265 | |||
266 | again: | ||
267 | skipws (p); | ||
268 | |||
269 | if (*p->curp == '#') | ||
270 | { | ||
271 | const char *start = ++p->curp; | ||
272 | skipline (p); | ||
273 | if (strncmp (start, "debug=", 6) == 0) | ||
274 | { | ||
275 | mu_log_level_t lev; | ||
276 | if (p->curp[0] == '\n') | ||
277 | { | ||
278 | mu_cfg_locus.line++; | ||
279 | *p->curp++ = 0; | ||
280 | } | ||
281 | if (mu_debug_level_from_string (start + 6, &lev, dbg) == 0) | ||
282 | { | ||
283 | mu_debug_set_level (dbg, lev); | ||
284 | mu_cfg_yydebug = lev & MU_DEBUG_LEVEL_MASK (MU_DEBUG_TRACE1); | ||
285 | } | ||
286 | } | ||
287 | goto again; | ||
288 | } | ||
289 | |||
290 | if (*p->curp == '/' && p->curp[1] == '/') | ||
291 | { | ||
292 | skipline (p); | ||
293 | goto again; | ||
294 | } | ||
295 | |||
296 | if (*p->curp == '/' && p->curp[1] == '*') | ||
297 | { | ||
298 | int keep_line = mu_cfg_locus.line; | ||
299 | |||
300 | p->curp += 2; | ||
301 | do | ||
302 | { | ||
303 | while (*p->curp != '*') | ||
304 | { | ||
305 | if (*p->curp == 0) | ||
306 | { | ||
307 | mu_cfg_perror (&mu_cfg_locus, | ||
308 | _("unexpected EOF in comment started at line %d"), | ||
309 | keep_line); | ||
310 | return 0; | ||
311 | } | ||
312 | else if (*p->curp == '\n') | ||
313 | mu_cfg_locus.line++; | ||
314 | ++p->curp; | ||
315 | } | ||
316 | } while (*++p->curp != '/'); | ||
317 | ++p->curp; | ||
318 | goto again; | ||
319 | } | ||
320 | |||
321 | if (*p->curp == 0) | ||
322 | { | ||
323 | LEX_DEBUG ("EOF", NULL, NULL); | ||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | if (*p->curp == '"' || *p->curp == '\'') | ||
328 | { | ||
329 | mu_cfg_yylval.string = copy_string (p); | ||
330 | LEX_DEBUG ("STRING", mu_cfg_yylval.string, NULL); | ||
331 | return MU_CFG_STRING_TOKEN; | ||
332 | } | ||
333 | |||
334 | if (mu_cfg_tie_in) | ||
335 | { | ||
336 | mu_cfg_yylval.string = copy_alpha (p); | ||
337 | LEX_DEBUG ("STRING", mu_cfg_yylval.string, NULL); | ||
338 | return MU_CFG_STRING_TOKEN; | ||
339 | } | ||
340 | |||
341 | if (*p->curp == '}') | ||
342 | { | ||
343 | p->curp++; | ||
344 | memset (&mu_cfg_yylval.node, 0, sizeof mu_cfg_yylval.node); | ||
345 | mu_cfg_yylval.node.locus = mu_cfg_locus; | ||
346 | LEX_DEBUG ("END", NULL, NULL); | ||
347 | return MU_CFG_END_TOKEN; | ||
348 | } | ||
349 | |||
350 | if (*p->curp == ';') | ||
351 | { | ||
352 | p->curp++; | ||
353 | LEX_DEBUG ("EOL", NULL, NULL); | ||
354 | return MU_CFG_EOL_TOKEN; | ||
355 | } | ||
356 | |||
357 | tag = copy_alpha (p); | ||
358 | skipws (p); | ||
359 | |||
360 | if (*tag == '"') | ||
361 | { | ||
362 | mu_cfg_yylval.string = tag; | ||
363 | LEX_DEBUG ("STRING", mu_cfg_yylval.string, NULL); | ||
364 | return MU_CFG_STRING_TOKEN; | ||
365 | } | ||
366 | |||
367 | save_start = p->curp; | ||
368 | if (*p->curp != '{') | ||
369 | { | ||
370 | label = copy_to (p, ";{"); | ||
371 | rtrim (label); | ||
372 | } | ||
373 | else | ||
374 | label = NULL; | ||
375 | if (*p->curp == '{') | ||
376 | { | ||
377 | p->curp++; | ||
378 | mu_cfg_yylval.node.tag_name = tag; | ||
379 | mu_cfg_yylval.node.locus = mu_cfg_locus; | ||
380 | mu_cfg_yylval.node.tag_label = label; | ||
381 | LEX_DEBUG ("START", tag, label); | ||
382 | return MU_CFG_START_TOKEN; | ||
383 | } | ||
384 | else | ||
385 | { | ||
386 | p->curp = save_start; | ||
387 | mu_cfg_yylval.string = tag; | ||
388 | } | ||
389 | LEX_DEBUG ("STRING", mu_cfg_yylval.string, NULL); | ||
390 | return MU_CFG_STRING_TOKEN; | ||
391 | } | ||
392 | |||
393 | |||
394 | int | ||
395 | mu_get_config (const char *file, const char *progname, | ||
396 | struct mu_cfg_param *progparam, int flags, void *target_ptr) | ||
397 | { | ||
398 | struct lexer_data data; | ||
399 | struct stat st; | ||
400 | int fd; | ||
401 | int rc; | ||
402 | mu_cfg_tree_t *parse_tree; | ||
403 | |||
404 | if (stat (file, &st)) | ||
405 | { | ||
406 | if (errno != ENOENT) | ||
407 | mu_error (_("can't stat `%s': %s"), file, mu_strerror (errno)); | ||
408 | return -1; | ||
409 | } | ||
410 | fd = open (file, O_RDONLY); | ||
411 | if (fd == -1) | ||
412 | { | ||
413 | mu_error (_("cannot open config file `%s': %s"), file, | ||
414 | mu_strerror (errno)); | ||
415 | return -1; | ||
416 | } | ||
417 | |||
418 | if (flags & MU_PARSE_CONFIG_VERBOSE) | ||
419 | mu_error (_("Info: parsing file `%s'"), file); | ||
420 | |||
421 | memset (&data, 0, sizeof data); | ||
422 | data.buffer = malloc (st.st_size+1); | ||
423 | |||
424 | read (fd, data.buffer, st.st_size); | ||
425 | data.buffer[st.st_size] = 0; | ||
426 | close (fd); | ||
427 | data.curp = data.buffer; | ||
428 | |||
429 | /* Parse configuration */ | ||
430 | mu_cfg_locus.file = (char*) file; | ||
431 | mu_cfg_locus.line = 1; | ||
432 | rc = mu_cfg_parse (&parse_tree, | ||
433 | &data, | ||
434 | default_lexer, | ||
435 | NULL, | ||
436 | NULL, | ||
437 | NULL); | ||
438 | |||
439 | if (rc == 0) | ||
440 | rc = mu_cfg_tree_reduce (parse_tree, progname, progparam, flags, | ||
441 | target_ptr); | ||
442 | |||
443 | mu_cfg_destroy_tree (&parse_tree); | ||
444 | mu_list_destroy (&data.mpool); | ||
445 | free (data.cbuf); | ||
446 | free (data.buffer); | ||
447 | |||
448 | if (flags & MU_PARSE_CONFIG_VERBOSE) | ||
449 | mu_error (_("Info: finished parsing file `%s'"), file); | ||
450 | |||
451 | return rc; | ||
452 | } | ||
453 |
mailbox/cfg_lexer.l
0 → 100644
1 | %{ | ||
2 | /* cfg_lexer.l -- default lexer for Mailutils configuration files | ||
3 | Copyright (C) 2007, 2008 Free Software Foundation, Inc. | ||
4 | |||
5 | GNU Mailutils is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU General Public License as | ||
7 | published by the Free Software Foundation; either version 3, or (at | ||
8 | your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | #include <stdio.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <sys/types.h> | ||
24 | #include <sys/stat.h> | ||
25 | #include <fcntl.h> | ||
26 | #include <errno.h> | ||
27 | #include <unistd.h> | ||
28 | #include <ctype.h> | ||
29 | #include <mailutils/errno.h> | ||
30 | #include <mailutils/error.h> | ||
31 | #include <mailutils/debug.h> | ||
32 | #include <mailutils/argcv.h> | ||
33 | #include <mailutils/alloc.h> | ||
34 | #include <mailutils/nls.h> | ||
35 | #include <mailutils/cfg.h> | ||
36 | #include <mailutils/list.h> | ||
37 | |||
38 | #include "cfg_parser.h" | ||
39 | |||
40 | void _mu_line_begin (void); | ||
41 | void _mu_line_add (char *text, size_t len); | ||
42 | char *_mu_line_finish (void); | ||
43 | |||
44 | static void _mu_line_add_unescape_last (char *text, size_t len); | ||
45 | static void multiline_begin (char *p); | ||
46 | static char *multiline_strip_tabs (char *text); | ||
47 | static void multiline_add (char *s); | ||
48 | static char *multiline_finish (void); | ||
49 | |||
50 | static char *multiline_delimiter; | ||
51 | static size_t multiline_delimiter_len; | ||
52 | static int multiline_unescape; /* Unescape here-document contents */ | ||
53 | static int (*char_to_strip)(char); /* Strip matching characters of each | ||
54 | here-document line */ | ||
55 | static int isemptystr(int off); | ||
56 | |||
57 | static mu_opool_t pool; | ||
58 | |||
59 | %} | ||
60 | |||
61 | %x COMMENT ML STR | ||
62 | |||
63 | WS [ \t\f][ \t\f]* | ||
64 | ID [a-zA-Z_][a-zA-Z_0-9-]+ | ||
65 | P [1-9][0-9]* | ||
66 | |||
67 | %% | ||
68 | /* C-style comments */ | ||
69 | "/*" BEGIN(COMMENT); | ||
70 | <COMMENT>[^*\n]* /* eat anything that's not a '*' */ | ||
71 | <COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ | ||
72 | <COMMENT>\n ++mu_cfg_locus.line; | ||
73 | <COMMENT>"*"+"/" BEGIN (INITIAL); | ||
74 | /* End-of-line comments */ | ||
75 | #.*\n { mu_cfg_locus.line++; } | ||
76 | #.* /* end-of-file comment */; | ||
77 | "//".*\n { mu_cfg_locus.line++; } | ||
78 | "//".* /* end-of-file comment */; | ||
79 | /* Identifiers */ | ||
80 | <INITIAL>{ID} { | ||
81 | _mu_line_begin (); | ||
82 | _mu_line_add (yytext, yyleng); | ||
83 | yylval.string = _mu_line_finish (); | ||
84 | return MU_TOK_IDENT; } | ||
85 | /* Strings */ | ||
86 | [a-zA-Z0-9_\./:-]+ { _mu_line_begin (); | ||
87 | _mu_line_add (yytext, yyleng); | ||
88 | yylval.string = _mu_line_finish (); | ||
89 | return MU_TOK_STRING; } | ||
90 | /* Quoted strings */ | ||
91 | \"[^\\"\n]*\" { _mu_line_begin (); | ||
92 | _mu_line_add (yytext + 1, yyleng - 2); | ||
93 | yylval.string = _mu_line_finish (); | ||
94 | return MU_TOK_QSTRING; } | ||
95 | \"[^\\"\n]*\\. | | ||
96 | \"[^\\"\n]*\\\n { BEGIN (STR); | ||
97 | _mu_line_begin (); | ||
98 | _mu_line_add_unescape_last (yytext + 1, yyleng - 1); } | ||
99 | <STR>[^\\"\n]*\\. | | ||
100 | <STR>\"[^\\"\n]*\\\n { _mu_line_add_unescape_last (yytext, yyleng); } | ||
101 | <STR>[^\\"\n]*\" { BEGIN (INITIAL); | ||
102 | if (yyleng > 1) | ||
103 | _mu_line_add (yytext, yyleng - 1); | ||
104 | yylval.string = _mu_line_finish (); | ||
105 | return MU_TOK_QSTRING; } | ||
106 | /* Multiline strings */ | ||
107 | "<<"(-" "?)?\\?{ID}[ \t]*#.*\n | | ||
108 | "<<"(-" "?)?\\?{ID}[ \t]*"//".*\n | | ||
109 | "<<"(-" "?)?\\?{ID}[ \t]*\n | | ||
110 | "<<"(-" "?)?\"{ID}\"[ \t]*#.*\n | | ||
111 | "<<"(-" "?)?\"{ID}\"[ \t]*"//".*\n | | ||
112 | "<<"(-" "?)?\"{ID}\"[ \t]*\n { | ||
113 | BEGIN (ML); | ||
114 | multiline_begin (yytext+2); | ||
115 | mu_cfg_locus.line++; | ||
116 | } | ||
117 | <ML>.*\n { char *p = multiline_strip_tabs (yytext); | ||
118 | |||
119 | if (!strncmp (p, multiline_delimiter, multiline_delimiter_len) | ||
120 | && isemptystr (p + multiline_delimiter_len - yytext)) | ||
121 | { | ||
122 | free (multiline_delimiter); | ||
123 | multiline_delimiter = NULL; | ||
124 | BEGIN (INITIAL); | ||
125 | yylval.string = multiline_finish (); | ||
126 | return MU_TOK_MSTRING; | ||
127 | } | ||
128 | mu_cfg_locus.line++; | ||
129 | multiline_add (p); } | ||
130 | {WS} ; | ||
131 | /* Other tokens */ | ||
132 | \n { mu_cfg_locus.line++; } | ||
133 | [,;{}()] return yytext[0]; | ||
134 | . mu_cfg_perror (&mu_cfg_locus, _("stray character \\%03o"), yytext[0]); | ||
135 | %% | ||
136 | |||
137 | int | ||
138 | yywrap () | ||
139 | { | ||
140 | return 1; | ||
141 | } | ||
142 | |||
143 | static void | ||
144 | unescape_to_line (int c) | ||
145 | { | ||
146 | if (c != '\n') | ||
147 | { | ||
148 | char t = mu_argcv_unquote_char (c); | ||
149 | if (t == c) | ||
150 | mu_cfg_perror (&mu_cfg_locus, _("unknown escape sequence '\\%c'"), c); | ||
151 | mu_opool_append_char (pool, t); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | void | ||
156 | _mu_line_add (char *text, size_t len) | ||
157 | { | ||
158 | mu_opool_append (pool, text, len); | ||
159 | } | ||
160 | |||
161 | void | ||
162 | _mu_line_add_unescape_last (char *text, size_t len) | ||
163 | { | ||
164 | mu_opool_append (pool, text, len - 2); | ||
165 | unescape_to_line (text[len - 1]); | ||
166 | } | ||
167 | |||
168 | void | ||
169 | _mu_line_begin () | ||
170 | { | ||
171 | if (!pool) | ||
172 | mu_opool_create (&pool, 1); | ||
173 | else | ||
174 | mu_opool_clear (pool); | ||
175 | } | ||
176 | |||
177 | char * | ||
178 | _mu_line_finish () | ||
179 | { | ||
180 | mu_opool_append_char (pool, 0); | ||
181 | return mu_opool_finish (pool, NULL); | ||
182 | } | ||
183 | |||
184 | |||
185 | |||
186 | static int | ||
187 | is_tab (char c) | ||
188 | { | ||
189 | return c == '\t'; | ||
190 | } | ||
191 | |||
192 | static int | ||
193 | is_ws (char c) | ||
194 | { | ||
195 | return c == '\t' || c == ' '; | ||
196 | } | ||
197 | |||
198 | static int | ||
199 | isemptystr (int off) | ||
200 | { | ||
201 | for (; yytext[off] && isspace (yytext[off]); off++) | ||
202 | ; | ||
203 | if (yytext[off] == ';') | ||
204 | { | ||
205 | int i; | ||
206 | for (i = off + 1; yytext[i]; i++) | ||
207 | if (!isspace (yytext[i])) | ||
208 | return 0; | ||
209 | yyless (off); | ||
210 | return 1; | ||
211 | } | ||
212 | return yytext[off] == 0; | ||
213 | } | ||
214 | |||
215 | static void | ||
216 | multiline_begin (char *p) | ||
217 | { | ||
218 | if (*p == '-') | ||
219 | { | ||
220 | if (*++p == ' ') | ||
221 | { | ||
222 | char_to_strip = is_ws; | ||
223 | p++; | ||
224 | } | ||
225 | else | ||
226 | char_to_strip = is_tab; | ||
227 | } | ||
228 | else | ||
229 | char_to_strip = NULL; | ||
230 | if (*p == '\\') | ||
231 | { | ||
232 | p++; | ||
233 | multiline_unescape = 0; | ||
234 | } | ||
235 | else if (*p == '"') | ||
236 | { | ||
237 | char *q; | ||
238 | |||
239 | p++; | ||
240 | multiline_unescape = 0; | ||
241 | q = strchr (p, '"'); | ||
242 | multiline_delimiter_len = q - p; | ||
243 | } | ||
244 | else | ||
245 | { | ||
246 | multiline_delimiter_len = strcspn (p, " \t"); | ||
247 | multiline_unescape = 1; | ||
248 | } | ||
249 | |||
250 | /* Remove trailing newline */ | ||
251 | multiline_delimiter_len--; | ||
252 | multiline_delimiter = mu_alloc (multiline_delimiter_len + 1); | ||
253 | memcpy (multiline_delimiter, p, multiline_delimiter_len); | ||
254 | multiline_delimiter[multiline_delimiter_len] = 0; | ||
255 | _mu_line_begin (); | ||
256 | } | ||
257 | |||
258 | static char * | ||
259 | multiline_strip_tabs (char *text) | ||
260 | { | ||
261 | if (char_to_strip) | ||
262 | for (; *text && char_to_strip (*text); text++) | ||
263 | ; | ||
264 | return text; | ||
265 | } | ||
266 | |||
267 | static void | ||
268 | multiline_add (char *s) | ||
269 | { | ||
270 | if (multiline_unescape) | ||
271 | { | ||
272 | for (; *s; s++) | ||
273 | { | ||
274 | if (*s == '\\') | ||
275 | { | ||
276 | unescape_to_line (s[1]); | ||
277 | ++s; | ||
278 | } | ||
279 | else | ||
280 | _mu_line_add (s, 1); | ||
281 | } | ||
282 | } | ||
283 | else | ||
284 | _mu_line_add (s, strlen (s)); | ||
285 | } | ||
286 | |||
287 | static char * | ||
288 | multiline_finish () | ||
289 | { | ||
290 | return _mu_line_finish (); | ||
291 | } | ||
292 | |||
293 | |||
294 | int | ||
295 | mu_get_config (const char *file, const char *progname, | ||
296 | struct mu_cfg_param *progparam, int flags, void *target_ptr) | ||
297 | { | ||
298 | struct stat st; | ||
299 | FILE *fp; | ||
300 | int rc; | ||
301 | mu_cfg_tree_t *parse_tree; | ||
302 | |||
303 | if (stat (file, &st)) | ||
304 | { | ||
305 | if (errno != ENOENT) | ||
306 | mu_error (_("cannot stat `%s': %s"), file, mu_strerror (errno)); | ||
307 | return -1; | ||
308 | } | ||
309 | fp = fopen (file, "r"); | ||
310 | if (!fp) | ||
311 | { | ||
312 | mu_error (_("cannot open config file `%s': %s"), file, | ||
313 | mu_strerror (errno)); | ||
314 | return -1; | ||
315 | } | ||
316 | |||
317 | if (flags & MU_PARSE_CONFIG_VERBOSE) | ||
318 | mu_error (_("Info: parsing file `%s'"), file); | ||
319 | |||
320 | yy_flex_debug = mu_debug_check_level (mu_cfg_get_debug (), MU_DEBUG_TRACE2); | ||
321 | |||
322 | /* Parse configuration */ | ||
323 | mu_cfg_locus.file = (char*) file; | ||
324 | mu_cfg_locus.line = 1; | ||
325 | yyrestart (fp); | ||
326 | rc = mu_cfg_parse (&parse_tree); | ||
327 | |||
328 | if (rc == 0) | ||
329 | rc = mu_cfg_tree_reduce (parse_tree, progname, progparam, flags, | ||
330 | target_ptr); | ||
331 | |||
332 | mu_cfg_destroy_tree (&parse_tree); | ||
333 | |||
334 | if (flags & MU_PARSE_CONFIG_VERBOSE) | ||
335 | mu_error (_("Info: finished parsing file `%s'"), file); | ||
336 | |||
337 | return rc; | ||
338 | } | ||
339 | |||
340 | mu_opool_t | ||
341 | mu_cfg_lexer_pool () | ||
342 | { | ||
343 | mu_opool_t p = pool; | ||
344 | pool = NULL; | ||
345 | return p; | ||
346 | } |
This diff is collapsed.
Click to expand it.
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2000, 2001, 2004, 2005, | 2 | Copyright (C) 1999, 2000, 2001, 2004, 2005, |
3 | 2007 Free Software Foundation, Inc. | 3 | 2007, 2008 Free Software Foundation, Inc. |
4 | 4 | ||
5 | This library is free software; you can redistribute it and/or | 5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public | 6 | modify it under the terms of the GNU Lesser General Public |
... | @@ -102,24 +102,26 @@ int | ... | @@ -102,24 +102,26 @@ int |
102 | mu_debug_level_from_string (const char *string, mu_log_level_t *plev, | 102 | mu_debug_level_from_string (const char *string, mu_log_level_t *plev, |
103 | mu_debug_t debug) | 103 | mu_debug_t debug) |
104 | { | 104 | { |
105 | char *p = string, *q; | 105 | char *q; |
106 | unsigned level = MU_DEBUG_INHERIT; | 106 | unsigned level = MU_DEBUG_INHERIT; |
107 | 107 | ||
108 | if (isdigit (*p)) | 108 | if (isdigit (*string)) |
109 | { | 109 | { |
110 | level = strtoul (p, &q, 0); | 110 | level = strtoul (string, &q, 0); |
111 | if (*q) | 111 | if (*q) |
112 | { | 112 | { |
113 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, | 113 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, |
114 | _("invalid debugging specification `%s': " | 114 | _("invalid debugging specification `%s': " |
115 | "expected levels or number after `=', " | 115 | "expected levels or number after `=', " |
116 | "but found `%s'"), | 116 | "but found `%s'"), |
117 | string, p); | 117 | string, string); |
118 | return MU_ERR_FAILURE; | 118 | return MU_ERR_FAILURE; |
119 | } | 119 | } |
120 | } | 120 | } |
121 | else | 121 | else |
122 | { | 122 | { |
123 | char *p = strdup (string); | ||
124 | |||
123 | for (q = strtok (p, ","); q; q = strtok (NULL, ",")) | 125 | for (q = strtok (p, ","); q; q = strtok (NULL, ",")) |
124 | { | 126 | { |
125 | int flag; | 127 | int flag; |
... | @@ -156,6 +158,7 @@ mu_debug_level_from_string (const char *string, mu_log_level_t *plev, | ... | @@ -156,6 +158,7 @@ mu_debug_level_from_string (const char *string, mu_log_level_t *plev, |
156 | level |= MU_DEBUG_LEVEL_MASK (flag); | 158 | level |= MU_DEBUG_LEVEL_MASK (flag); |
157 | } | 159 | } |
158 | } | 160 | } |
161 | free (p); | ||
159 | } | 162 | } |
160 | *plev = level; | 163 | *plev = level; |
161 | return 0; | 164 | return 0; | ... | ... |
... | @@ -161,6 +161,7 @@ mu_list_get_comparator (mu_list_t list, mu_list_comparator_t *comp) | ... | @@ -161,6 +161,7 @@ mu_list_get_comparator (mu_list_t list, mu_list_comparator_t *comp) |
161 | if (!list) | 161 | if (!list) |
162 | return EINVAL; | 162 | return EINVAL; |
163 | *comp = list->comp; | 163 | *comp = list->comp; |
164 | return 0; | ||
164 | } | 165 | } |
165 | 166 | ||
166 | static int | 167 | static int | ... | ... |
... | @@ -758,7 +758,7 @@ m_srv_conn (int fd, struct sockaddr *sa, int salen, | ... | @@ -758,7 +758,7 @@ m_srv_conn (int fd, struct sockaddr *sa, int salen, |
758 | 758 | ||
759 | 759 | ||
760 | unsigned short | 760 | unsigned short |
761 | get_port (mu_debug_t debug, char *p) | 761 | get_port (mu_debug_t debug, const char *p) |
762 | { | 762 | { |
763 | if (p) | 763 | if (p) |
764 | { | 764 | { |
... | @@ -787,7 +787,7 @@ get_port (mu_debug_t debug, char *p) | ... | @@ -787,7 +787,7 @@ get_port (mu_debug_t debug, char *p) |
787 | } | 787 | } |
788 | 788 | ||
789 | static int | 789 | static int |
790 | get_family (char **pstr, sa_family_t *pfamily) | 790 | get_family (const char **pstr, sa_family_t *pfamily) |
791 | { | 791 | { |
792 | static struct family_tab | 792 | static struct family_tab |
793 | { | 793 | { |
... | @@ -807,7 +807,7 @@ get_family (char **pstr, sa_family_t *pfamily) | ... | @@ -807,7 +807,7 @@ get_family (char **pstr, sa_family_t *pfamily) |
807 | }; | 807 | }; |
808 | struct family_tab *fp; | 808 | struct family_tab *fp; |
809 | 809 | ||
810 | char *str = *pstr; | 810 | const char *str = *pstr; |
811 | int len = strlen (str); | 811 | int len = strlen (str); |
812 | for (fp = ftab; fp->len; fp++) | 812 | for (fp = ftab; fp->len; fp++) |
813 | { | 813 | { |
... | @@ -847,7 +847,7 @@ is_ip_addr (const char *arg) | ... | @@ -847,7 +847,7 @@ is_ip_addr (const char *arg) |
847 | } | 847 | } |
848 | 848 | ||
849 | int | 849 | int |
850 | _mu_m_server_parse_url (mu_debug_t debug, char *arg, union m_sockaddr *s, | 850 | _mu_m_server_parse_url (mu_debug_t debug, const char *arg, union m_sockaddr *s, |
851 | int *psalen, struct sockaddr *defsa) | 851 | int *psalen, struct sockaddr *defsa) |
852 | { | 852 | { |
853 | char *p; | 853 | char *p; |
... | @@ -948,7 +948,7 @@ mu_m_server_parse_url (mu_m_server_t msrv, char *arg, | ... | @@ -948,7 +948,7 @@ mu_m_server_parse_url (mu_m_server_t msrv, char *arg, |
948 | } | 948 | } |
949 | 949 | ||
950 | static int | 950 | static int |
951 | server_block_begin (mu_debug_t debug, char *arg, mu_m_server_t msrv, | 951 | server_block_begin (mu_debug_t debug, const char *arg, mu_m_server_t msrv, |
952 | void **pdata) | 952 | void **pdata) |
953 | { | 953 | { |
954 | union m_sockaddr s; | 954 | union m_sockaddr s; |
... | @@ -970,8 +970,10 @@ server_section_parser (enum mu_cfg_section_stage stage, | ... | @@ -970,8 +970,10 @@ server_section_parser (enum mu_cfg_section_stage stage, |
970 | { | 970 | { |
971 | case mu_cfg_section_start: | 971 | case mu_cfg_section_start: |
972 | { | 972 | { |
973 | if (node->label->type != MU_CFG_STRING) | ||
974 | return 1; | ||
973 | /* FIXME: should not modify 2nd arg, or it should not be const */ | 975 | /* FIXME: should not modify 2nd arg, or it should not be const */ |
974 | return server_block_begin (tree->debug, node->tag_label, | 976 | return server_block_begin (tree->debug, node->label->v.string, |
975 | *section_data, section_data); | 977 | *section_data, section_data); |
976 | } | 978 | } |
977 | break; | 979 | break; |
... | @@ -988,14 +990,16 @@ server_section_parser (enum mu_cfg_section_stage stage, | ... | @@ -988,14 +990,16 @@ server_section_parser (enum mu_cfg_section_stage stage, |
988 | } | 990 | } |
989 | 991 | ||
990 | static int | 992 | static int |
991 | _cb_daemon_mode (mu_debug_t debug, void *data, char *arg) | 993 | _cb_daemon_mode (mu_debug_t debug, void *data, mu_config_value_t *val) |
992 | { | 994 | { |
993 | int *pmode = data; | 995 | int *pmode = data; |
994 | 996 | ||
995 | if (strcmp (arg, "inetd") == 0 | 997 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) |
996 | || strcmp (arg, "interactive") == 0) | 998 | return 1; |
999 | if (strcmp (val->v.string, "inetd") == 0 | ||
1000 | || strcmp (val->v.string, "interactive") == 0) | ||
997 | *pmode = MODE_INTERACTIVE; | 1001 | *pmode = MODE_INTERACTIVE; |
998 | else if (strcmp (arg, "daemon") == 0) | 1002 | else if (strcmp (val->v.string, "daemon") == 0) |
999 | *pmode = MODE_DAEMON; | 1003 | *pmode = MODE_DAEMON; |
1000 | else | 1004 | else |
1001 | { | 1005 | { |
... | @@ -1006,11 +1010,14 @@ _cb_daemon_mode (mu_debug_t debug, void *data, char *arg) | ... | @@ -1006,11 +1010,14 @@ _cb_daemon_mode (mu_debug_t debug, void *data, char *arg) |
1006 | } | 1010 | } |
1007 | 1011 | ||
1008 | static int | 1012 | static int |
1009 | _cb_port (mu_debug_t debug, void *data, char *arg) | 1013 | _cb_port (mu_debug_t debug, void *data, mu_config_value_t *val) |
1010 | { | 1014 | { |
1011 | struct m_default_address *ap = data; | 1015 | struct m_default_address *ap = data; |
1012 | unsigned short num = get_port (debug, arg); | 1016 | unsigned short num; |
1013 | 1017 | ||
1018 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) | ||
1019 | return 1; | ||
1020 | num = get_port (debug, val->v.string); | ||
1014 | if (!num) | 1021 | if (!num) |
1015 | return 1; | 1022 | return 1; |
1016 | ap->s.s_in.sin_family = AF_INET; | 1023 | ap->s.s_in.sin_family = AF_INET; | ... | ... |
mailbox/opool.c
0 → 100644
1 | /* String-list functions for GNU Mailutils. | ||
2 | Copyright (C) 2007, 2008 Free Software Foundation, Inc. | ||
3 | |||
4 | Based on slist module from GNU Radius. Written by Sergey Poznyakoff. | ||
5 | |||
6 | GNU Mailutils is free software; you can redistribute it and/or | ||
7 | modify it under the terms of the GNU General Public License as | ||
8 | published by the Free Software Foundation; either version 3, or (at | ||
9 | your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, but | ||
12 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #ifdef HAVE_CONFIG_H | ||
21 | # include <config.h> | ||
22 | #endif | ||
23 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <string.h> | ||
26 | #include <errno.h> | ||
27 | #include <mailutils/types.h> | ||
28 | #include <mailutils/alloc.h> | ||
29 | #include <mailutils/opool.h> | ||
30 | |||
31 | struct mu_opool_bucket | ||
32 | { | ||
33 | struct mu_opool_bucket *next; | ||
34 | char *buf; | ||
35 | size_t level; | ||
36 | size_t size; | ||
37 | }; | ||
38 | |||
39 | struct _mu_opool | ||
40 | { | ||
41 | int memerr; | ||
42 | struct mu_opool_bucket *head, *tail; | ||
43 | struct mu_opool_bucket *free; | ||
44 | }; | ||
45 | |||
46 | static struct mu_opool_bucket * | ||
47 | alloc_bucket (struct _mu_opool *opool, size_t size) | ||
48 | { | ||
49 | struct mu_opool_bucket *p = malloc (sizeof (*p) + size); | ||
50 | if (!p) | ||
51 | { | ||
52 | if (opool->memerr) | ||
53 | mu_alloc_die (); | ||
54 | } | ||
55 | else | ||
56 | { | ||
57 | p->buf = (char*)(p + 1); | ||
58 | p->level = 0; | ||
59 | p->size = size; | ||
60 | p->next = NULL; | ||
61 | } | ||
62 | return p; | ||
63 | } | ||
64 | |||
65 | static int | ||
66 | alloc_pool (mu_opool_t opool, size_t size) | ||
67 | { | ||
68 | struct mu_opool_bucket *p = alloc_bucket (opool, MU_OPOOL_BUCKET_SIZE); | ||
69 | if (!p) | ||
70 | return ENOMEM; | ||
71 | if (opool->tail) | ||
72 | opool->tail->next = p; | ||
73 | else | ||
74 | opool->head = p; | ||
75 | opool->tail = p; | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static int | ||
80 | copy_chars (mu_opool_t opool, const char *str, size_t n, size_t *psize) | ||
81 | { | ||
82 | size_t rest; | ||
83 | |||
84 | if (!opool->head || opool->tail->level == opool->tail->size) | ||
85 | if (alloc_pool (opool, MU_OPOOL_BUCKET_SIZE)) | ||
86 | return ENOMEM; | ||
87 | rest = opool->tail->size - opool->tail->level; | ||
88 | if (n > rest) | ||
89 | n = rest; | ||
90 | memcpy (opool->tail->buf + opool->tail->level, str, n); | ||
91 | opool->tail->level += n; | ||
92 | *psize = n; | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | int | ||
97 | mu_opool_create (mu_opool_t *pret, int memerr) | ||
98 | { | ||
99 | struct _mu_opool *x = malloc (sizeof (x[0])); | ||
100 | if (!x) | ||
101 | { | ||
102 | if (memerr) | ||
103 | mu_alloc_die (); | ||
104 | return ENOMEM; | ||
105 | } | ||
106 | x->memerr = memerr; | ||
107 | x->head = x->tail = x->free = 0; | ||
108 | *pret = x; | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | void | ||
113 | mu_opool_clear (mu_opool_t opool) | ||
114 | { | ||
115 | if (!opool) | ||
116 | return; | ||
117 | |||
118 | if (opool->tail) | ||
119 | { | ||
120 | opool->tail->next = opool->free; | ||
121 | opool->free = opool->head; | ||
122 | opool->head = opool->tail = NULL; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | void | ||
127 | mu_opool_destroy (mu_opool_t *popool) | ||
128 | { | ||
129 | struct mu_opool_bucket *p; | ||
130 | if (popool && *popool) | ||
131 | { | ||
132 | mu_opool_t opool = *popool; | ||
133 | mu_opool_clear (opool); | ||
134 | for (p = opool->free; p; ) | ||
135 | { | ||
136 | struct mu_opool_bucket *next = p->next; | ||
137 | free (p); | ||
138 | p = next; | ||
139 | } | ||
140 | free (opool); | ||
141 | } | ||
142 | *popool = NULL; | ||
143 | } | ||
144 | |||
145 | int | ||
146 | mu_opool_append (mu_opool_t opool, const void *str, size_t n) | ||
147 | { | ||
148 | const char *ptr = str; | ||
149 | while (n) | ||
150 | { | ||
151 | size_t s; | ||
152 | if (copy_chars (opool, ptr, n, &s)) | ||
153 | return ENOMEM; | ||
154 | ptr += s; | ||
155 | n -= s; | ||
156 | } | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | int | ||
161 | mu_opool_append_char (mu_opool_t opool, char c) | ||
162 | { | ||
163 | return mu_opool_append (opool, &c, 1); | ||
164 | } | ||
165 | |||
166 | int | ||
167 | mu_opool_appendz (mu_opool_t opool, const char *str) | ||
168 | { | ||
169 | return mu_opool_append (opool, str, strlen (str)) | ||
170 | || mu_opool_append_char (opool, 0); | ||
171 | } | ||
172 | |||
173 | size_t | ||
174 | mu_opool_size (mu_opool_t opool) | ||
175 | { | ||
176 | size_t size = 0; | ||
177 | struct mu_opool_bucket *p; | ||
178 | for (p = opool->head; p; p = p->next) | ||
179 | size += p->level; | ||
180 | return size; | ||
181 | } | ||
182 | |||
183 | int | ||
184 | mu_opool_coalesce (mu_opool_t opool, size_t *psize) | ||
185 | { | ||
186 | size_t size; | ||
187 | |||
188 | if (opool->head && opool->head->next == NULL) | ||
189 | size = opool->head->level; | ||
190 | else { | ||
191 | struct mu_opool_bucket *bucket; | ||
192 | struct mu_opool_bucket *p; | ||
193 | |||
194 | size = mu_opool_size (opool); | ||
195 | |||
196 | bucket = alloc_bucket (opool, size); | ||
197 | if (!bucket) | ||
198 | return ENOMEM; | ||
199 | for (p = opool->head; p; ) | ||
200 | { | ||
201 | struct mu_opool_bucket *next = p->next; | ||
202 | memcpy (bucket->buf + bucket->level, p->buf, p->level); | ||
203 | bucket->level += p->level; | ||
204 | free (p); | ||
205 | p = next; | ||
206 | } | ||
207 | opool->head = opool->tail = bucket; | ||
208 | } | ||
209 | if (psize) | ||
210 | *psize = size; | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | void * | ||
215 | mu_opool_head (mu_opool_t opool, size_t *psize) | ||
216 | { | ||
217 | if (*psize) | ||
218 | *psize = opool->head ? opool->head->level : 0; | ||
219 | return opool->head ? opool->head->buf : NULL; | ||
220 | } | ||
221 | |||
222 | void * | ||
223 | mu_opool_finish (mu_opool_t opool, size_t *psize) | ||
224 | { | ||
225 | if (mu_opool_coalesce (opool, psize)) | ||
226 | return NULL; | ||
227 | mu_opool_clear (opool); | ||
228 | return opool->free->buf; | ||
229 | } | ||
230 |
... | @@ -21,6 +21,7 @@ | ... | @@ -21,6 +21,7 @@ |
21 | #include <string.h> | 21 | #include <string.h> |
22 | #include <mailutils/diag.h> | 22 | #include <mailutils/diag.h> |
23 | #include <mailutils/kwd.h> | 23 | #include <mailutils/kwd.h> |
24 | #include <mailutils/syslog.h> | ||
24 | 25 | ||
25 | static mu_kwd_t kw_facility[] = { | 26 | static mu_kwd_t kw_facility[] = { |
26 | { "USER", LOG_USER }, | 27 | { "USER", LOG_USER }, |
... | @@ -41,7 +42,7 @@ static mu_kwd_t kw_facility[] = { | ... | @@ -41,7 +42,7 @@ static mu_kwd_t kw_facility[] = { |
41 | }; | 42 | }; |
42 | 43 | ||
43 | static int | 44 | static int |
44 | syslog_to_n (mu_kwd_t *kw, char *str, int *pint) | 45 | syslog_to_n (mu_kwd_t *kw, const char *str, int *pint) |
45 | { | 46 | { |
46 | if (strncasecmp (str, "LOG_", 4) == 0) | 47 | if (strncasecmp (str, "LOG_", 4) == 0) |
47 | str += 4; | 48 | str += 4; |
... | @@ -49,7 +50,7 @@ syslog_to_n (mu_kwd_t *kw, char *str, int *pint) | ... | @@ -49,7 +50,7 @@ syslog_to_n (mu_kwd_t *kw, char *str, int *pint) |
49 | } | 50 | } |
50 | 51 | ||
51 | int | 52 | int |
52 | mu_string_to_syslog_facility (char *str, int *pfacility) | 53 | mu_string_to_syslog_facility (const char *str, int *pfacility) |
53 | { | 54 | { |
54 | return syslog_to_n (kw_facility, str, pfacility); | 55 | return syslog_to_n (kw_facility, str, pfacility); |
55 | } | 56 | } |
... | @@ -75,7 +76,7 @@ static mu_kwd_t kw_prio[] = { | ... | @@ -75,7 +76,7 @@ static mu_kwd_t kw_prio[] = { |
75 | }; | 76 | }; |
76 | 77 | ||
77 | int | 78 | int |
78 | mu_string_to_syslog_priority (char *str, int *pprio) | 79 | mu_string_to_syslog_priority (const char *str, int *pprio) |
79 | { | 80 | { |
80 | return syslog_to_n (kw_prio, str, pprio); | 81 | return syslog_to_n (kw_prio, str, pprio); |
81 | } | 82 | } | ... | ... |
... | @@ -69,7 +69,7 @@ char *mimeview_file; /* Name of the file to view */ | ... | @@ -69,7 +69,7 @@ char *mimeview_file; /* Name of the file to view */ |
69 | FILE *mimeview_fp; /* Its descriptor */ | 69 | FILE *mimeview_fp; /* Its descriptor */ |
70 | 70 | ||
71 | static void | 71 | static void |
72 | set_debug_flags (mu_debug_t debug, char *arg) | 72 | set_debug_flags (mu_debug_t debug, const char *arg) |
73 | { | 73 | { |
74 | for (; *arg; arg++) | 74 | for (; *arg; arg++) |
75 | { | 75 | { |
... | @@ -152,16 +152,11 @@ static struct argp argp = { | ... | @@ -152,16 +152,11 @@ static struct argp argp = { |
152 | 152 | ||
153 | 153 | ||
154 | static int | 154 | static int |
155 | cb_debug (mu_debug_t debug, void *data, char *arg) | 155 | cb_debug (mu_debug_t debug, void *data, mu_config_value_t *val) |
156 | { | 156 | { |
157 | set_debug_flags (debug, arg); | 157 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) |
158 | return 0; | 158 | return 1; |
159 | } | 159 | set_debug_flags (debug, val->v.string); |
160 | |||
161 | static int | ||
162 | cb_metamail (mu_debug_t debug, void *data, char *arg) | ||
163 | { | ||
164 | metamail = strdup ("metamail"); | ||
165 | return 0; | 160 | return 0; |
166 | } | 161 | } |
167 | 162 | ||
... | @@ -172,7 +167,7 @@ struct mu_cfg_param mimeview_cfg_param[] = { | ... | @@ -172,7 +167,7 @@ struct mu_cfg_param mimeview_cfg_param[] = { |
172 | { "mimetypes", mu_cfg_string, &mimetypes_config, 0, NULL, | 167 | { "mimetypes", mu_cfg_string, &mimetypes_config, 0, NULL, |
173 | N_("Use this mime.types file."), | 168 | N_("Use this mime.types file."), |
174 | N_("file") }, | 169 | N_("file") }, |
175 | { "metamail", mu_cfg_string, NULL, 0, cb_metamail, | 170 | { "metamail", mu_cfg_string, &metamail, 0, NULL, |
176 | N_("Use this program to display files."), | 171 | N_("Use this program to display files."), |
177 | N_("prog") }, | 172 | N_("prog") }, |
178 | { NULL } | 173 | { NULL } | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -22,7 +22,7 @@ static char *bulletin_mbox_name; | ... | @@ -22,7 +22,7 @@ static char *bulletin_mbox_name; |
22 | static char *bulletin_db_name; | 22 | static char *bulletin_db_name; |
23 | 23 | ||
24 | void | 24 | void |
25 | set_bulletin_db (char *file) | 25 | set_bulletin_db (const char *file) |
26 | { | 26 | { |
27 | bulletin_db_name = strdup (file); | 27 | bulletin_db_name = strdup (file); |
28 | } | 28 | } |
... | @@ -65,7 +65,7 @@ open_bulletin_mailbox (mu_mailbox_t *pmbox) | ... | @@ -65,7 +65,7 @@ open_bulletin_mailbox (mu_mailbox_t *pmbox) |
65 | } | 65 | } |
66 | 66 | ||
67 | int | 67 | int |
68 | set_bulletin_source (char *source) | 68 | set_bulletin_source (const char *source) |
69 | { | 69 | { |
70 | bulletin_mbox_name = strdup (source); | 70 | bulletin_mbox_name = strdup (source); |
71 | return 0; | 71 | return 0; | ... | ... |
... | @@ -31,6 +31,7 @@ mu_m_server_t server; | ... | @@ -31,6 +31,7 @@ mu_m_server_t server; |
31 | unsigned int idle_timeout; | 31 | unsigned int idle_timeout; |
32 | int pop3d_transcript; | 32 | int pop3d_transcript; |
33 | int debug_mode; | 33 | int debug_mode; |
34 | int tls_required; | ||
34 | 35 | ||
35 | #ifdef WITH_TLS | 36 | #ifdef WITH_TLS |
36 | int tls_available; | 37 | int tls_available; |
... | @@ -107,26 +108,21 @@ static struct argp_option options[] = { | ... | @@ -107,26 +108,21 @@ static struct argp_option options[] = { |
107 | {NULL, 0, NULL, 0, NULL, 0} | 108 | {NULL, 0, NULL, 0, NULL, 0} |
108 | }; | 109 | }; |
109 | 110 | ||
110 | #ifdef WITH_TLS | ||
111 | static int | ||
112 | cb_tls_required (mu_debug_t debug, void *data, char *arg) | ||
113 | { | ||
114 | initial_state = INITIAL; | ||
115 | return 0; | ||
116 | } | ||
117 | #endif | ||
118 | |||
119 | static int | 111 | static int |
120 | cb_bulletin_source (mu_debug_t debug, void *data, char *arg) | 112 | cb_bulletin_source (mu_debug_t debug, void *data, mu_config_value_t *val) |
121 | { | 113 | { |
122 | set_bulletin_source (arg); /* FIXME: Error reporting? */ | 114 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) |
115 | return 1; | ||
116 | set_bulletin_source (val->v.string); /* FIXME: Error reporting? */ | ||
123 | return 0; | 117 | return 0; |
124 | } | 118 | } |
125 | 119 | ||
126 | static int | 120 | static int |
127 | cb_bulletin_db (mu_debug_t debug, void *data, char *arg) | 121 | cb_bulletin_db (mu_debug_t debug, void *data, mu_config_value_t *val) |
128 | { | 122 | { |
129 | set_bulletin_db (arg); /* FIXME: Error reporting? */ | 123 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) |
124 | return 1; | ||
125 | set_bulletin_db (val->v.string); /* FIXME: Error reporting? */ | ||
130 | return 0; | 126 | return 0; |
131 | } | 127 | } |
132 | 128 | ||
... | @@ -139,7 +135,7 @@ static struct mu_cfg_param pop3d_cfg_param[] = { | ... | @@ -139,7 +135,7 @@ static struct mu_cfg_param pop3d_cfg_param[] = { |
139 | { "delete-expired", mu_cfg_int, &expire_on_exit, 0, NULL, | 135 | { "delete-expired", mu_cfg_int, &expire_on_exit, 0, NULL, |
140 | N_("Delete expired messages upon closing the mailbox.") }, | 136 | N_("Delete expired messages upon closing the mailbox.") }, |
141 | #ifdef WITH_TLS | 137 | #ifdef WITH_TLS |
142 | { "tls-required", mu_cfg_callback, NULL, 0, cb_tls_required, | 138 | { "tls-required", mu_cfg_bool, &tls_required, 0, NULL, |
143 | N_("Always require STLS before entering authentication phase.") }, | 139 | N_("Always require STLS before entering authentication phase.") }, |
144 | #endif | 140 | #endif |
145 | #ifdef ENABLE_LOGIN_DELAY | 141 | #ifdef ENABLE_LOGIN_DELAY |
... | @@ -493,6 +489,9 @@ main (int argc, char **argv) | ... | @@ -493,6 +489,9 @@ main (int argc, char **argv) |
493 | argc, argv, 0, NULL, server)) | 489 | argc, argv, 0, NULL, server)) |
494 | exit (EX_CONFIG); /* FIXME: No way to discern from EX_USAGE? */ | 490 | exit (EX_CONFIG); /* FIXME: No way to discern from EX_USAGE? */ |
495 | 491 | ||
492 | if (tls_required) | ||
493 | initial_state = INITIAL; | ||
494 | |||
496 | if (expire == 0) | 495 | if (expire == 0) |
497 | expire_on_exit = 1; | 496 | expire_on_exit = 1; |
498 | 497 | ... | ... |
... | @@ -287,8 +287,8 @@ extern void pop3d_unmark_retr (mu_attribute_t attr); | ... | @@ -287,8 +287,8 @@ extern void pop3d_unmark_retr (mu_attribute_t attr); |
287 | extern void expire_mark_message (mu_message_t msg, char **value); | 287 | extern void expire_mark_message (mu_message_t msg, char **value); |
288 | 288 | ||
289 | extern void deliver_pending_bulletins (void); | 289 | extern void deliver_pending_bulletins (void); |
290 | extern void set_bulletin_db (char *file); | 290 | extern void set_bulletin_db (const char *file); |
291 | extern int set_bulletin_source (char *source); | 291 | extern int set_bulletin_source (const char *source); |
292 | extern int pop3d_begin_session (void); | 292 | extern int pop3d_begin_session (void); |
293 | 293 | ||
294 | 294 | ... | ... |
... | @@ -261,16 +261,20 @@ static struct argp argp = | ... | @@ -261,16 +261,20 @@ static struct argp argp = |
261 | 261 | ||
262 | 262 | ||
263 | static int | 263 | static int |
264 | cb_debug (mu_debug_t debug, void *data, char *arg) | 264 | cb_debug (mu_debug_t debug, void *data, mu_config_value_t *val) |
265 | { | 265 | { |
266 | set_debug_level (debug, arg); | 266 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) |
267 | return 1; | ||
268 | set_debug_level (debug, val->v.string); | ||
267 | return 0; | 269 | return 0; |
268 | } | 270 | } |
269 | 271 | ||
270 | static int | 272 | static int |
271 | cb_email (mu_debug_t debug, void *data, char *arg) | 273 | cb_email (mu_debug_t debug, void *data, mu_config_value_t *val) |
272 | { | 274 | { |
273 | int rc = mu_set_user_email (arg); | 275 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) |
276 | return 1; | ||
277 | int rc = mu_set_user_email (val->v.string); | ||
274 | if (rc) | 278 | if (rc) |
275 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("Invalid email: %s"), | 279 | mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("Invalid email: %s"), |
276 | mu_strerror (rc)); | 280 | mu_strerror (rc)); |
... | @@ -278,10 +282,12 @@ cb_email (mu_debug_t debug, void *data, char *arg) | ... | @@ -278,10 +282,12 @@ cb_email (mu_debug_t debug, void *data, char *arg) |
278 | } | 282 | } |
279 | 283 | ||
280 | static int | 284 | static int |
281 | cb_ticket (mu_debug_t debug, void *data, char *arg) | 285 | cb_ticket (mu_debug_t debug, void *data, mu_config_value_t *val) |
282 | { | 286 | { |
287 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) | ||
288 | return 1; | ||
283 | free (tickets); | 289 | free (tickets); |
284 | tickets = mu_tilde_expansion (arg, "/", NULL); | 290 | tickets = mu_tilde_expansion (val->v.string, "/", NULL); |
285 | tickets_default = 0; | 291 | tickets_default = 0; |
286 | return 0; | 292 | return 0; |
287 | } | 293 | } | ... | ... |
-
Please register or sign in to post a comment