Commit 7c8e01ff 7c8e01ff3f278a56067353b8dd7030e3cfc47495 by Sergey Poznyakoff

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.
1 parent e1db594c
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\
......
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);
......
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
......
...@@ -11,5 +11,6 @@ mailutils-config ...@@ -11,5 +11,6 @@ mailutils-config
11 parsedate.c 11 parsedate.c
12 *y.output 12 *y.output
13 muerrno.c 13 muerrno.c
14 cfg_lexer.c
14 cfg_parser.c 15 cfg_parser.c
15 cfg_parser.h 16 cfg_parser.h
......
...@@ -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
......
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, &quote); 52 size = mu_argcv_quoted_length (str, &quote);
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,
......
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
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 }
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;
......
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 }
......