Commit d39f4c2d d39f4c2db3ea8bc387cde7dcc2825598aa166ff6 by Sergey Poznyakoff

Improve configuration parsing (step 1).

Remove obsolete options (these have been made hidden in
v. 2.0).  Handle "include" and "program" after parsing
the sources, not while reducing the tree, as was
previously.  Retain, however, old functions for compatibility,
making them deprecated.  Add "query" mode to mailutils-config.

* include/mailutils/cfg.h (mu_cfg_node_tag): Remove
(mu_cfg_statement): Rename to mu_cfg_node_statement.
(mu_cfg_tree): New member: tail.
(mu_cfg_perror): Change signature.
(mu_cfg_vperror, mu_cfg_parse_error): New protos.
(MU_CFG_PATH_DELIM, MU_CFG_PATH_DELIM_STR): New defines.
(MU_PARSE_CONFIG_PLAIN,MU_CFG_FMT_LOCUS): New constant.
(MU_CFG_DEPRECATED): New macro.
(mu_parse_config,mu_get_config): Deprecated.
(mu_cfg_format_parse_tree): Change signature.
(mu_cfg_format_node, mu_cfg_parse_file): New protos.
(mu_cfg_tree_free): Remove stale proto.
(mu_cfg_find_node, mu_cfg_create_subtree): New protos.
* include/mailutils/libcfg.h (mu_libcfg_parse_config): New proto.
(mu_parse_config_files): Deprecated.

* include/mailutils/mutil.h (mu_make_file_name): New proto.
(mu_retrieve_fp, mu_register_retriever)
(mu_retrieve): Remove unused prototypes.
* include/mailutils/opool.h (mu_opool_union): New proto.

* libmu_argp/Makefile.am (libmu_argp_a_SOURCES): Remove
sources (see below):
* po/POTFILES.in: Likewise.
* libmu_argp/gsasl.c: Remove.
* libmu_argp/pam.c: Remove.
* libmu_argp/radius.c: Remove.
* libmu_argp/sql.c: Remove.
* libmu_argp/tls.c: Remove.
* libmu_argp/virtdomain.c: Remove.

* config/mailutils-config.c: New option --query (-q)
(main): Handle query mode.

* comsat/comsat.c: Define MU_CFG_COMPATIBILITY to suppress
deprecation warnings.

* bootstrap.conf (XGETTEXT_OPTIONS): Add mu_cfg
error reporting functions.

* mailbox/Makefile.am (libmailutils_la_SOURCES): Add
mkfilename.c
* mailbox/mkfilename.c: New file.

* imap4d/imap4d.c: Remove obsolete option (hidden since 2.0)
* libmu_argp/auth.c: Likewise.
* libmu_argp/cmdline.c: Likewise.
* libmu_argp/tls.c: Likewise.
* pop3d/pop3d.c: Likewise.
* libmu_argp/common.c: Likewise.
(mu_common_argp_options): New option --set.

* libmu_argp/muinit.c (mu_app_init): Rewrite using parse
tree as a principal entity.
* libmu_cfg/init.c (mu_libcfg_parse_config): New function.
* mailbox/cfg_driver.c (make_file_name): Remove.
(_cb_include): Use mu_make_file_name.
(mu_build_container): Use deprecated code only unless MU_PARSE_CONFIG_PLAIN
flag is set.
(mu_cfg_tree_reduce): Do nothing if the tree is NULL.
* mailbox/cfg_format.c (format_node): Print locus optionally.
(mu_cfg_format_parse_tree): Take additional argument.
(mu_cfg_format_node): New function.
* mailbox/cfg_lexer.l: Update calls to diagnostic functions.
(mu_cfg_parse_file): New function.
(mu_get_config): Rewrite.
* mailbox/cfg_parser.y (parse_tree): Replace with
parse_head, parse_tail. All usages updated.
(mu_cfg_free_node): New function.
(mu_cfg_vperror): New function.
(mu_cfg_perror,mu_cfg_parse_error): New function.
(mu_cfg_tree_union): New function.
(mu_cfg_tree_postprocess): New function.
(mu_cfg_find_section): Use MU_CFG_PATH_DELIM instead
of hardcoded slash.
(mu_cfg_value_eq): New function.
(mu_cfg_find_node): New function. Redesign of an old idea.
(mu_cfg_create_subtree): New function.
* mailbox/opool.c (mu_opool_union): New function.

* frm/testsuite/frm/test.exp: use --set option instead of
the obsolete --mail-folder.
* messages/testsuite/messages/test.exp: Likewise.
* sieve/testsuite/sieve/action.exp: Likewise.
* mail/testsuite/lib/mail.exp: use --set option instead of
the obsolete --mail-spool.
* mailbox/testsuite/lib/mailbox.exp: Likewise.
* testsuite/lib/mailutils.exp: Likewise.
* mailbox/mutil.c (mu_register_retriever)
(mu_retrieve): Remove unused functions.

Minor fix:

* frm/common.c (frm_abort): Initialize URL
before usage.
(frm_scan): Don't call frm_abort on a mailbox
that was not opened successfully.
1 parent 6dad17fe
......@@ -53,6 +53,9 @@ XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\
--flag=mh_getyn:1:c-format\\\
--flag=mh_getyn_interactive:1:c-format\\\
--flag=mh_error:1:c-format\\\
--flag=mu_cfg_perror:3:c-format\\\
--flag=mu_cfg_parse_error:1:c-format\\\
--flag=mu_cfg_format_error:3:c-format\\\
--flag=ali_parse_error:1:c-format\\\
--flag=asnprintf:3:c-format --flag=vasnprintf:3:c-format\\\
--flag=argp_error:2:c-format\\\
......
......@@ -18,6 +18,8 @@
MA 02110-1301 USA */
#include "comsat.h"
#define MU_CFG_COMPATIBILITY /* This source uses deprecated cfg interfaces */
#include "mailutils/libcfg.h"
#include "mailutils/libargp.h"
#ifndef PATH_DEV
......
......@@ -39,6 +39,9 @@ static struct argp_option options[] = {
N_("print a list of configuration options used to build mailutils; "
"optional arguments are interpreted as a list of configuration "
"options to check for"), 0},
{"query", 'q', N_("FILE"), OPTION_ARG_OPTIONAL,
N_("query configuration values from FILE (default mailutils.rc)"),
0 },
{"verbose", 'v', NULL, 0,
N_("increase output verbosity"), 0},
{0, 0, 0, 0}
......@@ -48,11 +51,13 @@ enum config_mode {
MODE_VOID,
MODE_COMPILE,
MODE_LINK,
MODE_INFO
MODE_INFO,
MODE_QUERY
};
enum config_mode mode;
int verbose;
char *query_config_file;
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
......@@ -71,6 +76,12 @@ parse_opt (int key, char *arg, struct argp_state *state)
mode = MODE_INFO;
break;
case 'q':
if (arg)
query_config_file = arg;
mode = MODE_QUERY;
break;
case 'v':
verbose++;
break;
......@@ -170,13 +181,28 @@ int
main (int argc, char **argv)
{
int index;
int i, rc;
struct argp *myargp;
char **excapa;
mu_cfg_tree_t *tree = NULL;
mu_stream_t stream;
int fmtflags = 0;
mu_argp_init (program_version, NULL);
if (mu_app_init (&argp, argp_capa, NULL, argc, argv, 0, &index, NULL))
mu_set_program_name (argv[0]);
mu_libargp_init ();
for (i = 0; argp_capa[i]; i++)
mu_gocs_register_std (argp_capa[i]); /*FIXME*/
myargp = mu_argp_build (&argp, &excapa);
if (argp_parse (myargp, argc, argv, 0, &index, NULL))
{
argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
argp_help (myargp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
return 1;
}
mu_argp_done (myargp);
mu_set_program_name (program_invocation_name);
argc -= index;
argv += index;
......@@ -298,6 +324,44 @@ main (int argc, char **argv)
return found == argc ? 0 : 1;
}
return 0;
case MODE_QUERY:
if (argc == 0)
{
mu_error (_("not enough arguments"));
return 1;
}
if (query_config_file)
{
mu_load_site_rcfile = 0;
mu_load_user_rcfile = 0;
mu_load_rcfile = query_config_file;
}
if (mu_libcfg_parse_config (&tree))
exit (1);
if (!tree)
exit (0);
rc = mu_stdio_stream_create (&stream, stdout, 0);
if (rc)
{
mu_error ("mu_stdio_stream_create: %s", mu_strerror (rc));
exit (1);
}
if (verbose)
fmtflags = MU_CFG_FMT_LOCUS;
for ( ; argc > 0; argc--, argv++)
{
char *path = *argv;
mu_cfg_node_t *node;
if (mu_cfg_find_node (tree->head, path, &node) == 0)
{
mu_cfg_format_node (stream, node, fmtflags);
}
}
exit (0);
}
argp_help (&argp, stdout, ARGP_HELP_USAGE, program_invocation_short_name);
......
......@@ -527,7 +527,7 @@ frm_abort (mu_mailbox_t *mbox)
if ((status = mu_mailbox_close (*mbox)) != 0)
{
mu_url_t url;
mu_mailbox_get_url (*mbox, &url);
mu_error (_("could not close mailbox `%s': %s"),
mu_url_to_string (url), mu_strerror (status));
exit (3);
......@@ -580,7 +580,8 @@ frm_scan (char *mailbox_name, frm_select_t fun, size_t *total)
{
mu_error (_("could not open mailbox `%s': %s"),
mu_url_to_string (url), mu_strerror (status));
frm_abort (&mbox);
mu_mailbox_destroy (&mbox);
exit (3);
}
else
{
......
# -*- tcl -*-
# This file is part of Mailutils testsuite.
# Copyright (C) 2002, 2007 Free Software Foundation
# Copyright (C) 2002, 2007, 2009 Free Software Foundation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -51,7 +51,7 @@ mu_exec -retcode 1 -message "frm -qS" -arg -qS \
mu_exec -retcode 1 -arg -q -message "frm -q" \
"There are messages in that folder."
mu_exec -retcode 1 -arg "--mail-folder=$MU_SPOOL_DIR" -arg +mbox -message "frm +mbox" \
mu_exec -retcode 1 -arg "--set mailbox.folder=$MU_SPOOL_DIR" -arg +mbox -message "frm +mbox" \
"Sergey Poznyakoff\tMBOX"
mu_exec -arg -q -arg %nonexistent -retcode 2 -message "frm -q %nonexistent" \
......
......@@ -57,9 +57,6 @@ int ident_encrypt_only;
const char *program_version = "imap4d (" PACKAGE_STRING ")";
static char doc[] = N_("GNU imap4d -- the IMAP4D daemon.");
#define OPT_LOGIN_DISABLED 256
#define OPT_TLS_REQUIRED 257
#define OPT_CREATE_HOME_DIR 258
#define OPT_PREAUTH 259
#define OPT_FOREGROUND 260
......@@ -69,21 +66,9 @@ static struct argp_option options[] = {
{ "daemon", 'd', N_("NUMBER"), OPTION_ARG_OPTIONAL,
N_("runs in daemon mode with a maximum of NUMBER children"), 0 },
{"other-namespace", 'O', N_("PATHLIST"), OPTION_HIDDEN,
N_("set the `other' namespace"), 0},
{"shared-namespace", 'S', N_("PATHLIST"), OPTION_HIDDEN,
N_("set the `shared' namespace"), 0},
{"login-disabled", OPT_LOGIN_DISABLED, NULL, OPTION_HIDDEN,
N_("disable LOGIN command")},
{"create-home-dir", OPT_CREATE_HOME_DIR, N_("MODE"),
OPTION_ARG_OPTIONAL|OPTION_HIDDEN,
N_("create home directory, if it does not exist")},
{"preauth", OPT_PREAUTH, NULL, 0,
N_("start in preauth mode") },
#ifdef WITH_TLS
{"tls-required", OPT_TLS_REQUIRED, NULL, OPTION_HIDDEN,
N_("always require STARTTLS before entering authentication phase")},
#endif
{NULL, 0, NULL, 0, NULL, 0}
};
......@@ -134,30 +119,6 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state)
mu_argp_node_list_new (&lst, "foreground", "yes");
break;
case 'O':
mu_argp_node_list_new (&lst, "other-namespace", arg);
break;
case 'S':
mu_argp_node_list_new (&lst, "shared-namespace", arg);
break;
case OPT_LOGIN_DISABLED:
mu_argp_node_list_new (&lst, "login-disabled", "yes");
break;
case OPT_CREATE_HOME_DIR:
mu_argp_node_list_new (&lst, "create-home-dir", "yes");
if (arg)
mu_argp_node_list_new (&lst, "home-dir-mode", arg);
break;
#ifdef WITH_TLS
case OPT_TLS_REQUIRED:
mu_argp_node_list_new (&lst, "tls-required", "yes");
break;
#endif
case OPT_PREAUTH:
preauth_mode = preauth_stdio;
break;
......
/* cfg.h -- general-purpose configuration file parser
Copyright (C) 2007, 2008 Free Software Foundation, Inc.
Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
......@@ -58,8 +58,7 @@ struct mu_config_value
enum mu_cfg_node_type
{
mu_cfg_node_undefined,
mu_cfg_statement,
mu_cfg_node_tag=mu_cfg_statement, /* FIXME: remove */
mu_cfg_node_statement,
mu_cfg_node_param
};
......@@ -81,19 +80,24 @@ struct mu_cfg_node
struct mu_cfg_tree
{
mu_cfg_node_t *node;
mu_cfg_node_t *head, *tail;
mu_debug_t debug;
mu_opool_t pool;
};
int mu_cfg_parse (mu_cfg_tree_t **ptree);
int mu_cfg_tree_union (mu_cfg_tree_t **pa, mu_cfg_tree_t **pb);
int mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, int flags);
extern mu_cfg_locus_t mu_cfg_locus;
mu_opool_t mu_cfg_lexer_pool (void);
void mu_cfg_perror (const mu_cfg_locus_t *, const char *, ...)
MU_PRINTFLIKE(2,3);
void mu_cfg_vperror (mu_debug_t, const mu_cfg_locus_t *,
const char *fmt, va_list ap);
void mu_cfg_perror (mu_debug_t debug, const mu_cfg_locus_t *,
const char *, ...) MU_PRINTFLIKE(3,4);
void mu_cfg_parse_error (const char *, ...) MU_PRINTFLIKE(1,2);
void mu_cfg_format_error (mu_debug_t debug, size_t, const char *fmt, ...)
MU_PRINTFLIKE(3,4);
......@@ -205,6 +209,9 @@ struct mu_cfg_cidr
unsigned long mask;
};
#define MU_CFG_PATH_DELIM '.'
#define MU_CFG_PATH_DELIM_STR "."
int mu_config_create_container (struct mu_cfg_cont **pcont,
enum mu_cfg_cont_type type);
int mu_config_clone_container (struct mu_cfg_cont *cont);
......@@ -240,19 +247,32 @@ mu_debug_t mu_cfg_get_debug (void);
#define MU_PARSE_CONFIG_GLOBAL 0x1
#define MU_PARSE_CONFIG_VERBOSE 0x2
#define MU_PARSE_CONFIG_DUMP 0x4
#define MU_PARSE_CONFIG_PLAIN 0x8
#ifdef MU_CFG_COMPATIBILITY
# define MU_CFG_DEPRECATED
#else
# define MU_CFG_DEPRECATED __attribute__ ((deprecated))
#endif
int mu_parse_config (const char *file, const char *progname,
struct mu_cfg_param *progparam, int flags,
void *target_ptr);
void *target_ptr) MU_CFG_DEPRECATED;
int mu_cfg_parse_boolean (const char *str, int *res);
extern int mu_cfg_parser_verbose;
extern size_t mu_cfg_error_count;
#define MU_CFG_FMT_LOCUS 0x01
void mu_cfg_format_docstring (mu_stream_t stream, const char *docstring,
int level);
void mu_cfg_format_parse_tree (mu_stream_t stream, struct mu_cfg_tree *tree);
void mu_cfg_format_parse_tree (mu_stream_t stream, struct mu_cfg_tree *tree,
int flags);
void mu_cfg_format_node (mu_stream_t stream, const mu_cfg_node_t *node,
int flags);
void mu_cfg_format_container (mu_stream_t stream, struct mu_cfg_cont *cont);
void mu_format_config_tree (mu_stream_t stream, const char *progname,
struct mu_cfg_param *progparam, int flags);
......@@ -265,14 +285,16 @@ int mu_cfg_string_value_cb (mu_debug_t debug, mu_config_value_t *val,
int (*fun) (mu_debug_t, const char *, void *),
void *data);
int mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file,
int flags);
int mu_get_config (const char *file, const char *progname,
struct mu_cfg_param *progparam, int flags,
void *target_ptr);
void *target_ptr) MU_CFG_DEPRECATED;
int mu_cfg_tree_create (struct mu_cfg_tree **ptree);
void mu_cfg_tree_set_debug (struct mu_cfg_tree *tree, mu_debug_t debug);
void mu_cfg_tree_free (struct mu_cfg_tree *tree, void *mem);
mu_cfg_node_t *mu_cfg_tree_create_node (struct mu_cfg_tree *tree,
enum mu_cfg_node_type type,
const mu_cfg_locus_t *loc,
......@@ -281,6 +303,10 @@ mu_cfg_node_t *mu_cfg_tree_create_node (struct mu_cfg_tree *tree,
mu_cfg_node_t *node);
void mu_cfg_tree_add_node (mu_cfg_tree_t *tree, mu_cfg_node_t *node);
int mu_cfg_find_node (mu_cfg_node_t *tree, const char *path,
mu_cfg_node_t **pnode);
int mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode);
#ifdef __cplusplus
}
#endif
......
......@@ -50,7 +50,9 @@ extern int mu_register_cfg_capa (const char *name,
extern void mu_libcfg_init (char **cnames);
extern int mu_parse_config_files (struct mu_cfg_param *param,
void *target_ptr);
void *target_ptr) MU_CFG_DEPRECATED;
int mu_libcfg_parse_config (mu_cfg_tree_t **ptree);
extern void mu_acl_cfg_init (void);
#define __mu_common_cat2__(a,b) a ## b
......
......@@ -99,6 +99,7 @@ extern int mu_aget_user_email_domain (char **pdomain);
*/
extern char *mu_get_user_email (const char *name);
extern char *mu_make_file_name (const char *dir, const char *file);
extern char *mu_normalize_path (char *path);
extern int mu_tempfile (const char *tmpdir, char **namep);
extern char *mu_tempname (const char *tmpdir);
......@@ -108,10 +109,6 @@ extern char * mu_getcwd (void);
extern int mu_spawnvp(const char *prog, char *av[], int *stat);
typedef void *(*mu_retrieve_fp) (void *);
extern void mu_register_retriever (mu_list_t *pflist, mu_retrieve_fp fun);
extern void * mu_retrieve (mu_list_t flist, void *data);
extern int mu_unroll_symlink (char *out, size_t outsz, const char *in);
extern char * mu_expand_path_pattern (const char *pattern, const char *username);
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2008 Free Software Foundation, Inc.
Copyright (C) 2008, 2009 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
......@@ -32,6 +32,10 @@ int mu_opool_create (mu_opool_t *pret, int memerr);
int mu_opool_set_bucket_size (mu_opool_t opool, size_t size);
int mu_opool_get_bucket_size (mu_opool_t opool, size_t *psize);
/* Merge all data from *SRC into *DST. If the latter is NULL, create
it. On success, free *SRC and initialize it with NULL. */
int mu_opool_union (mu_opool_t *dst, mu_opool_t *src);
/* Clear all data from the pool, so next mu_opool_append* call will
begin a new object. */
void mu_opool_clear (mu_opool_t opool);
......
......@@ -32,14 +32,9 @@ libmu_argp_a_SOURCES =\
cmdline.h\
common.c\
compat.c\
gsasl.c\
mu_argp.h\
mu_argp.c\
muinit.c\
pam.c\
radius.c\
sieve.c\
sql.c\
tls.c\
virtdomain.c
tls.c
......
......@@ -28,11 +28,7 @@
/* ************************************************************************* */
enum {
OPT_AUTHORIZATION=256,
OPT_AUTHENTICATION,
OPT_CLEAR_AUTHORIZATION,
OPT_CLEAR_AUTHENTICATION,
OPT_DEBUG_AUTH
OPT_DEBUG_AUTH=256
};
static error_t mu_auth_argp_parser (int key, char *arg,
......@@ -40,14 +36,6 @@ static error_t mu_auth_argp_parser (int key, char *arg,
/* Options used by programs that use extended authentication mechanisms. */
static struct argp_option mu_auth_argp_option[] = {
{ "authentication", OPT_AUTHENTICATION, N_("MODLIST"), OPTION_HIDDEN,
N_("set the list of modules to be used for authentication"), 0 },
{ "authorization", OPT_AUTHORIZATION, N_("MODLIST"), OPTION_HIDDEN,
N_("set list of modules to be used for authorization"), 0 },
{ "clear-authorization", OPT_CLEAR_AUTHORIZATION, NULL, OPTION_HIDDEN,
N_("clear the list of authorization modules"), 0 },
{ "clear-authentication", OPT_CLEAR_AUTHENTICATION, NULL, OPTION_HIDDEN,
N_("clear the list of authentication modules"), 0 },
{ "debug-auth", OPT_DEBUG_AUTH, NULL, 0,
N_("debug authentication functions") },
{ NULL, 0, NULL, 0, NULL, 0 }
......@@ -92,22 +80,6 @@ mu_auth_argp_parser (int key, char *arg, struct argp_state *state)
mu_argp_node_list_finish (&lst, "auth", NULL);
break;
case OPT_AUTHORIZATION:
mu_argp_node_list_new (&lst, "authorization", arg);
break;
case OPT_AUTHENTICATION:
mu_argp_node_list_new (&lst, "authentication", arg);
break;
case OPT_CLEAR_AUTHENTICATION:
mu_argp_node_list_new (&lst, "authentication", "clear");
break;
case OPT_CLEAR_AUTHORIZATION:
mu_argp_node_list_new (&lst, "authorization", "clear");
break;
case OPT_DEBUG_AUTH:
auth_set_debug ();
break;
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2007, 2008 Free Software Foundation, Inc.
Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
......@@ -26,17 +26,9 @@ static struct mu_cmdline_capa *all_cmdline_capa[] = {
&mu_common_cmdline,
&mu_logging_cmdline,
&mu_license_cmdline,
&mu_mailbox_cmdline,
&mu_locking_cmdline,
&mu_address_cmdline,
&mu_mailer_cmdline,
&mu_debug_cmdline,
&mu_pam_cmdline,
&mu_gsasl_cmdline,
&mu_tls_cmdline,
&mu_radius_cmdline,
&mu_sql_cmdline,
&mu_virtdomain_cmdline,
&mu_auth_cmdline,
&mu_sieve_cmdline,
NULL
......@@ -104,7 +96,7 @@ mu_argp_node_list_finish (struct mu_argp_node_list *lst, char *tag,
return;
if (tag)
node = mu_cfg_tree_create_node (mu_argp_tree,
mu_cfg_node_tag,
mu_cfg_node_statement,
NULL,
tag, label,
lst->head);
......@@ -113,3 +105,4 @@ mu_argp_node_list_finish (struct mu_argp_node_list *lst, char *tag,
mu_cfg_tree_add_node (mu_argp_tree, node);
mu_argp_node_list_init (lst);
}
......
......@@ -38,18 +38,11 @@ enum {
OPT_RCFILE_LINT,
OPT_RCFILE_VERBOSE,
OPT_LOG_FACILITY,
OPT_LOCK_FLAGS,
OPT_LOCK_RETRY_COUNT,
OPT_LOCK_RETRY_TIMEOUT,
OPT_LOCK_EXPIRE_TIMEOUT,
OPT_LOCK_EXTERNAL_PROGRAM,
OPT_LICENSE,
OPT_MAILBOX_PATTERN,
OPT_MAILBOX_TYPE,
OPT_MAIL_FOLDER,
OPT_DEBUG_LEVEL,
OPT_LINE_INFO,
OPT_HELP_CONFIG
OPT_HELP_CONFIG,
OPT_SET
};
static struct argp_option mu_common_argp_options[] =
......@@ -74,9 +67,21 @@ static struct argp_option mu_common_argp_options[] =
{ "config-lint", OPT_RCFILE_LINT, NULL, 0,
N_("check configuration file syntax and exit"), 0 },
{ "rcfile-lint", 0, NULL, OPTION_ALIAS, NULL },
{ "set", OPT_SET, N_("PARAM=VALUE"), 0,
N_("set configuration parameter"), 0 },
{ NULL, 0, NULL, 0, NULL, 0 }
};
static void
set_config_param (const char *path, struct argp_state *state)
{
mu_cfg_node_t *node;
int rc = mu_cfg_create_subtree (path, &node);
if (rc)
argp_error (state, "cannot create node: %s", mu_strerror (rc));
mu_cfg_tree_add_node (mu_argp_tree, node);
}
static error_t
mu_common_argp_parser (int key, char *arg, struct argp_state *state)
{
......@@ -111,6 +116,10 @@ mu_common_argp_parser (int key, char *arg, struct argp_state *state)
mu_help_config_mode = 1;
break;
case OPT_SET:
set_config_param (arg, state);
break;
default:
return ARGP_ERR_UNKNOWN;
}
......@@ -231,215 +240,6 @@ struct mu_cmdline_capa mu_license_cmdline = {
/* ************************************************************************* */
/* Mailbox */
/* ************************************************************************* */
/* Options used by programs that access mailboxes. */
static struct argp_option mu_mailbox_argp_option[] = {
{ "mail-spool", 'm', N_("URL"), OPTION_HIDDEN,
N_("use specified URL as a mailspool directory"), 0 },
{ "mailbox-pattern", OPT_MAILBOX_PATTERN, N_("pat"), OPTION_HIDDEN,
"", 0 },
{ "mailbox-type", OPT_MAILBOX_TYPE, N_("PROTO"), OPTION_HIDDEN,
N_("default mailbox type to use"), 0 },
{ "mail-folder", OPT_MAIL_FOLDER, N_("DIR"), OPTION_HIDDEN,
N_("default user mail folder"), 0 },
{ NULL }
};
static error_t
mu_mailbox_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
/* mailbox */
case 'm':
mu_argp_node_list_new (&lst, "mail-spool", arg);
break;
case OPT_MAILBOX_PATTERN:
mu_argp_node_list_new (&lst, "mailbox-pattern", arg);
break;
case OPT_MAILBOX_TYPE:
mu_argp_node_list_new (&lst, "mailbox-type", arg);
break;
case OPT_MAIL_FOLDER:
mu_argp_node_list_new (&lst, "folder", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, "mailbox", NULL);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
struct argp mu_mailbox_argp = {
mu_mailbox_argp_option,
mu_mailbox_argp_parser,
};
struct argp_child mu_mailbox_argp_child = {
&mu_mailbox_argp,
0,
NULL,
0
};
struct mu_cmdline_capa mu_mailbox_cmdline = {
"mailbox", &mu_mailbox_argp_child
};
/* ************************************************************************* */
/* Locking */
/* ************************************************************************* */
/* Options used by programs that access mailboxes. */
static struct argp_option mu_locking_argp_option[] = {
{"lock-flags", OPT_LOCK_FLAGS, N_("FLAGS"), OPTION_HIDDEN,
N_("default locker flags (E=external, R=retry, T=time, P=pid)"), 0},
{"lock-retry-timeout", OPT_LOCK_RETRY_TIMEOUT, N_("SECONDS"), OPTION_HIDDEN,
N_("set timeout for acquiring the lockfile") },
{"lock-retry-count", OPT_LOCK_RETRY_COUNT, N_("NUMBER"), OPTION_HIDDEN,
N_("set the maximum number of times to retry acquiring the lockfile") },
{"lock-expire-timeout", OPT_LOCK_EXPIRE_TIMEOUT, N_("SECONDS"),
OPTION_HIDDEN,
N_("number of seconds after which the lock expires"), },
{"external-locker", OPT_LOCK_EXTERNAL_PROGRAM, N_("PATH"), OPTION_HIDDEN,
N_("set full path to the external locker program") },
{ NULL, 0, NULL, 0, NULL, 0 }
};
static error_t
mu_locking_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case OPT_LOCK_FLAGS:
mu_argp_node_list_new (&lst, "flags", arg);
break;
case OPT_LOCK_RETRY_COUNT:
mu_argp_node_list_new (&lst, "retry-count", arg);
break;
case OPT_LOCK_RETRY_TIMEOUT:
mu_argp_node_list_new (&lst, "retry-timeout", arg);
break;
case OPT_LOCK_EXPIRE_TIMEOUT:
mu_argp_node_list_new (&lst, "expire-timeout", arg);
break;
case OPT_LOCK_EXTERNAL_PROGRAM:
mu_argp_node_list_new (&lst, "external-locker", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, "locking", NULL);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
struct argp mu_locking_argp = {
mu_locking_argp_option,
mu_locking_argp_parser,
};
struct argp_child mu_locking_argp_child = {
&mu_locking_argp,
0,
NULL,
0
};
struct mu_cmdline_capa mu_locking_cmdline = {
"locking", &mu_locking_argp_child
};
/* ************************************************************************* */
/* Address */
/* ************************************************************************* */
/* Options used by programs that do address mapping. */
static struct argp_option mu_address_argp_option[] = {
{"email-addr", 'E', N_("EMAIL"), OPTION_HIDDEN,
N_("set current user's email address (default is loginname@defaultdomain)"), 0},
{"email-domain", 'D', N_("DOMAIN"), OPTION_HIDDEN,
N_("set domain for unqualified user names (default is this host)"), 0},
{ NULL, 0, NULL, 0, NULL, 0 }
};
static error_t
mu_address_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case 'E':
mu_argp_node_list_new (&lst, "email-addr", arg);
break;
case 'D':
mu_argp_node_list_new (&lst, "email-domain", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, "address", NULL);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
struct argp mu_address_argp = {
mu_address_argp_option,
mu_address_argp_parser,
};
struct argp_child mu_address_argp_child = {
&mu_address_argp,
0,
NULL,
0
};
struct mu_cmdline_capa mu_address_cmdline = {
"address", &mu_address_argp_child
};
/* ************************************************************************* */
/* Mailer */
/* ************************************************************************* */
......@@ -511,7 +311,7 @@ mu_debug_argp_parser (int key, char *arg, struct argp_state *state)
{
case OPT_DEBUG_LEVEL:
mu_global_debug_from_string (arg, "command line");
//mu_argp_node_list_new (&lst, "level", arg);
/*mu_argp_node_list_new (&lst, "level", arg);*/
break;
case OPT_LINE_INFO:
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2007, 2009 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "cmdline.h"
#include <mailutils/gsasl.h>
#define OPT_CRAM_PASSWD 256
static struct argp_option _gsasl_argp_options[] = {
{"cram-passwd", OPT_CRAM_PASSWD, N_("FILE"), OPTION_HIDDEN,
N_("specify password file for CRAM-MD5 authentication"), 0},
{ NULL, 0, NULL, 0, NULL, 0 }
};
static error_t
_gsasl_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case OPT_CRAM_PASSWD:
mu_argp_node_list_new (&lst, "cram-passwd", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, "gsasl", NULL);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp _gsasl_argp = {
_gsasl_argp_options,
_gsasl_argp_parser
};
struct argp_child mu_gsasl_argp_child = {
&_gsasl_argp,
0,
NULL,
0
};
struct mu_cmdline_capa mu_gsasl_cmdline = {
"gsasl", &mu_gsasl_argp_child
};
......@@ -66,7 +66,7 @@ mu_app_init (struct argp *myargp, const char **capa,
struct argp *argp;
struct argp argpnull = { 0 };
char **excapa;
int cfgflags = 0;
struct mu_cfg_tree *parse_tree = NULL;
mu_set_program_name (argv[0]);
mu_libargp_init ();
......@@ -119,15 +119,21 @@ mu_app_init (struct argp *myargp, const char **capa,
mu_stream_destroy (&stream, NULL);
exit (0);
}
else
mu_parse_config_files (cfg_param, data);
rc = mu_libcfg_parse_config (&parse_tree);
if (rc == 0)
{
int cfgflags = MU_PARSE_CONFIG_PLAIN;
if (mu_cfg_parser_verbose)
cfgflags |= MU_PARSE_CONFIG_VERBOSE;
if (mu_cfg_parser_verbose > 1)
cfgflags |= MU_PARSE_CONFIG_DUMP;
rc = mu_cfg_tree_reduce (mu_argp_tree, mu_program_name, cfg_param,
mu_cfg_tree_postprocess (mu_argp_tree, cfgflags);
mu_cfg_tree_union (&parse_tree, &mu_argp_tree);
rc = mu_cfg_tree_reduce (parse_tree, mu_program_name, cfg_param,
cfgflags, data);
}
if (mu_rcfile_lint)
{
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2007, 2009 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "cmdline.h"
#include <mailutils/pam.h>
#define OPT_PAM_SERVICE 256
static error_t
mu_pam_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case OPT_PAM_SERVICE:
mu_argp_node_list_new (&lst, "service", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, "pam", NULL);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp_option mu_pam_argp_option[] = {
{ "pam-service", OPT_PAM_SERVICE, N_("STRING"), OPTION_HIDDEN,
N_("use STRING as PAM service name"), 0},
{ NULL, 0, NULL, 0, NULL, 0 }
};
static struct argp mu_pam_argp = {
mu_pam_argp_option,
mu_pam_argp_parser,
};
struct argp_child mu_pam_argp_child = {
&mu_pam_argp,
0,
NULL,
0
};
struct mu_cmdline_capa mu_pam_cmdline = {
"pam", &mu_pam_argp_child
};
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2007, 2009 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "cmdline.h"
#include <mailutils/radius.h>
enum {
OPT_AUTH_REQUEST = 256,
OPT_GETPWNAM_REQUEST,
OPT_GETPWUID_REQUEST,
OPT_RADIUS_DIR
};
static struct argp_option mu_radius_argp_option[] = {
{ "radius-auth-request", OPT_AUTH_REQUEST, N_("REQUEST"), OPTION_HIDDEN,
N_("radius request to authenticate the user"), 0 },
{ "radius-getpwnam-request", OPT_GETPWNAM_REQUEST, N_("REQUEST"), OPTION_HIDDEN,
N_("radius request to retrieve a passwd entry based on username"), 0 },
{ "radius-getpwuid-request", OPT_GETPWUID_REQUEST, N_("REQUEST"), OPTION_HIDDEN,
N_("radius request to retrieve a passwd entry based on UID"), 0 },
{ "radius-directory", OPT_RADIUS_DIR, N_("DIR"), OPTION_HIDDEN,
N_("set name of the radius configuration directory"), 0 },
{ NULL }
};
static error_t
mu_radius_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case OPT_AUTH_REQUEST:
mu_argp_node_list_new (&lst, "auth-request", arg);
break;
case OPT_GETPWNAM_REQUEST:
mu_argp_node_list_new (&lst, "getwnam-request", arg);
break;
case OPT_GETPWUID_REQUEST:
mu_argp_node_list_new (&lst, "getwuid-request", arg);
break;
case OPT_RADIUS_DIR:
mu_argp_node_list_new (&lst, "directory", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, "radius", NULL);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp mu_radius_argp = {
mu_radius_argp_option,
mu_radius_argp_parser,
};
struct argp_child mu_radius_argp_child = {
&mu_radius_argp,
0,
NULL,
0
};
struct mu_cmdline_capa mu_radius_cmdline = {
"radius", &mu_radius_argp_child
};
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2007, 2009 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "cmdline.h"
enum {
OPT_SQL_INTERFACE = 256,
OPT_SQL_GETPWNAM,
OPT_SQL_GETPWUID,
OPT_SQL_GETPASS,
OPT_SQL_HOST,
OPT_SQL_USER,
OPT_SQL_PASSWD,
OPT_SQL_DB,
OPT_SQL_PORT,
OPT_SQL_MU_PASSWORD_TYPE,
OPT_SQL_FIELD_MAP,
};
static struct argp_option mu_sql_argp_option[] = {
{"sql-interface", OPT_SQL_INTERFACE, N_("NAME"), OPTION_HIDDEN,
N_("type of SQL interface to use"), },
{"sql-getpwnam", OPT_SQL_GETPWNAM, N_("QUERY"), OPTION_HIDDEN,
N_("SQL query to retrieve a passwd entry based on username"), 0},
{"sql-getpwuid", OPT_SQL_GETPWUID, N_("QUERY"), OPTION_HIDDEN,
N_("SQL query to retrieve a passwd entry based on UID"), 0},
{"sql-getpass", OPT_SQL_GETPASS, N_("QUERY"), OPTION_HIDDEN,
N_("SQL query to retrieve a password from the database"), 0},
{"sql-host", OPT_SQL_HOST, N_("HOSTNAME"), OPTION_HIDDEN,
N_("name or IP of MySQL server to connect to"), 0},
{"sql-user", OPT_SQL_USER, N_("NAME"), OPTION_HIDDEN,
N_("SQL user name"), 0},
{"sql-passwd", OPT_SQL_PASSWD, N_("STRING"), OPTION_HIDDEN,
N_("SQL connection password"), 0},
{"sql-db", OPT_SQL_DB, N_("STRING"), OPTION_HIDDEN,
N_("name of the database to connect to"), 0},
{"sql-port", OPT_SQL_PORT, N_("NUMBER"), OPTION_HIDDEN,
N_("port to use"), 0},
{"sql-password-type", OPT_SQL_MU_PASSWORD_TYPE, N_("STRING"), OPTION_HIDDEN,
N_("type of password returned by --sql-getpass query. STRING is one of: plain, hash, scrambled"), 0},
{"sql-field-map", OPT_SQL_FIELD_MAP, N_("MAP"), OPTION_HIDDEN,
N_("declare a name translation map for SQL fields in results of sql-getpwnam and "
"sql-getpwuid queries"), 0},
{ NULL, 0, NULL, 0, NULL, 0 }
};
static error_t
mu_sql_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case OPT_SQL_INTERFACE:
mu_argp_node_list_new (&lst, "interface", arg);
break;
case OPT_SQL_GETPWNAM:
mu_argp_node_list_new (&lst, "getpwnam", arg);
break;
case OPT_SQL_GETPWUID:
mu_argp_node_list_new (&lst, "getpwuid", arg);
break;
case OPT_SQL_GETPASS:
mu_argp_node_list_new (&lst, "getpass", arg);
break;
case OPT_SQL_HOST:
mu_argp_node_list_new (&lst, "host", arg);
break;
case OPT_SQL_USER:
mu_argp_node_list_new (&lst, "user", arg);
break;
case OPT_SQL_PASSWD:
mu_argp_node_list_new (&lst, "passwd", arg);
break;
case OPT_SQL_DB:
mu_argp_node_list_new (&lst, "db", arg);
break;
case OPT_SQL_PORT:
mu_argp_node_list_new (&lst, "port", arg);
break;
case OPT_SQL_MU_PASSWORD_TYPE:
mu_argp_node_list_new (&lst, "password-type", arg);
break;
case OPT_SQL_FIELD_MAP:
mu_argp_node_list_new (&lst, "field-map", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, "sql", NULL);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp mu_sql_argp = {
mu_sql_argp_option,
mu_sql_argp_parser,
};
struct argp_child mu_sql_argp_child = {
&mu_sql_argp,
0,
NULL,
0
};
struct mu_cmdline_capa mu_sql_cmdline = {
"sql", &mu_sql_argp_child
};
......@@ -24,18 +24,9 @@
enum {
OPT_TLS = 256,
OPT_SSL_CERT,
OPT_SSL_KEY,
OPT_SSL_CAFILE
};
static struct argp_option _tls_argp_options[] = {
{"ssl-cert", OPT_SSL_CERT, N_("FILE"), OPTION_HIDDEN,
N_("specify SSL certificate file"), 0},
{"ssl-key", OPT_SSL_KEY, N_("FILE"), OPTION_HIDDEN,
N_("specify SSL certificate key"), },
{"ssl-cafile", OPT_SSL_CAFILE, N_("FILE"), OPTION_HIDDEN,
N_("specify trusted CAs file"), 0},
{"tls", OPT_TLS, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("enable TLS support") },
{NULL, 0, NULL, 0, NULL, 0}
......@@ -52,18 +43,6 @@ _tls_argp_parser (int key, char *arg, struct argp_state *state)
mu_argp_node_list_new (&lst, "enable", arg ? arg : "yes");
break;
case OPT_SSL_CERT:
mu_argp_node_list_new (&lst, "ssl-cert", arg);
break;
case OPT_SSL_KEY:
mu_argp_node_list_new (&lst, "ssl-key", arg);
break;
case OPT_SSL_CAFILE:
mu_argp_node_list_new (&lst, "ssl-cafile", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2007, 2009 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "cmdline.h"
#define OPT_PWDDIR 256
static error_t
mu_virt_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case OPT_PWDDIR:
mu_argp_node_list_new (&lst, "passwd-dir", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, "virtdomain", NULL);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp_option mu_virt_argp_option[] = {
{ "virtual-passwd-dir", OPT_PWDDIR, N_("DIR"), OPTION_HIDDEN,
N_("search for virtual passwd file in DIR"), 0},
{ NULL, 0, NULL, 0, NULL, 0 }
};
static struct argp mu_virt_argp = {
mu_virt_argp_option,
mu_virt_argp_parser,
};
struct argp_child mu_virt_argp_child = {
&mu_virt_argp,
0,
NULL,
0
};
struct mu_cmdline_capa mu_virtdomain_cmdline = {
"virtdomain", &mu_virt_argp_child
};
......@@ -18,6 +18,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#define MU_CFG_COMPATIBILITY /* This source uses deprecated cfg interfaces */
#include "mailutils/libcfg.h"
#include <string.h>
#include <stdlib.h>
......@@ -84,6 +85,83 @@ mu_libcfg_init (char **cnames)
}
int
mu_libcfg_parse_config (mu_cfg_tree_t **ptree)
{
int flags = 0;
int rc = 0;
mu_cfg_tree_t *tree = NULL, *tmp;
if (mu_cfg_parser_verbose)
flags |= MU_PARSE_CONFIG_VERBOSE;
if (mu_cfg_parser_verbose > 1)
flags |= MU_PARSE_CONFIG_DUMP;
if (mu_load_site_rcfile)
{
rc = mu_cfg_parse_file (&tmp, MU_CONFIG_FILE, flags);
if (rc == ENOMEM)
{
mu_error ("%s", mu_strerror (rc));
return rc;
}
else if (rc == 0)
{
mu_cfg_tree_postprocess (tmp, flags | MU_PARSE_CONFIG_GLOBAL);
mu_cfg_tree_union (&tree, &tmp);
}
}
if (mu_load_user_rcfile && mu_program_name)
{
size_t size = 3 + strlen (mu_program_name) + 1;
char *file_name = malloc (size);
if (file_name)
{
strcpy (file_name, "~/.");
strcat (file_name, mu_program_name);
rc = mu_cfg_parse_file (&tmp, file_name, flags);
if (rc == ENOMEM)
{
mu_error ("%s", mu_strerror (rc));
mu_cfg_destroy_tree (&tree);
return rc;
}
else if (rc == 0)
{
mu_cfg_tree_postprocess (tmp, flags);
mu_cfg_tree_union (&tree, &tmp);
}
free (file_name);
}
}
if (mu_load_rcfile)
{
rc = mu_cfg_parse_file (&tmp, mu_load_rcfile, flags);
if (rc)
{
mu_error (_("errors parsing file %s: %s"), mu_load_rcfile,
mu_strerror (rc));
mu_cfg_destroy_tree (&tree);
return rc;
}
else
{
mu_cfg_tree_postprocess (tmp, flags);
mu_cfg_tree_union (&tree, &tmp);
}
}
*ptree = tree;
return rc;
}
/* FIXME: Deprecated */
int
mu_parse_config_files (struct mu_cfg_param *param, void *target)
{
int flags = 0;
......
# -*- tcl -*-
# This file is part of Mailutils testsuite.
# Copyright (C) 2002, 2007 Free Software Foundation
# Copyright (C) 2002, 2007, 2009 Free Software Foundation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -64,7 +64,7 @@ proc default_mail_start {args} {
if [info exists host_board] {
if [board_info $host_board exists top_srcdir] {
append sw " --mail-spool [board_info $host_board top_srcdir]/mail/testsuite/spool"
append sw " --set mailbox.mail-spool=[board_info $host_board top_srcdir]/mail/testsuite/spool"
}
}
......
......@@ -98,6 +98,7 @@ libmailutils_la_SOURCES = \
memory_stream.c\
message_stream.c\
mime.c\
mkfilename.c\
monitor.c\
msrv.c\
mu_auth.c\
......
/* cfg_driver.c -- Main driver for Mailutils configuration files
Copyright (C) 2007, 2008 Free Software Foundation, Inc.
Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
......@@ -27,6 +27,7 @@
#include <ctype.h>
#include <mailutils/argcv.h>
#include <mailutils/nls.h>
#define MU_CFG_COMPATIBILITY /* This source uses deprecated cfg interfaces */
#include <mailutils/cfg.h>
#include <mailutils/errno.h>
#include <mailutils/error.h>
......@@ -453,23 +454,6 @@ prog_parser (enum mu_cfg_section_stage stage,
return 0;
}
static char *
make_file_name (const char *dir, const char *file)
{
char *tmp;
size_t len = strlen (dir) + 1 + strlen (file);
tmp = malloc (len + 1);
if (!tmp)
{
mu_error ("%s", mu_strerror (errno));
exit (1);
}
strcpy (tmp, dir);
strcat (tmp, "/");
strcat (tmp, file);
return tmp;
}
struct include_data
{
const char *progname;
......@@ -492,13 +476,20 @@ _cb_include (mu_debug_t debug, void *data, mu_config_value_t *val)
dirname = val->v.string;
if (dirname[0] != '/')
dirname = tmp = make_file_name (SYSCONFDIR, dirname);
{
dirname = tmp = mu_make_file_name (SYSCONFDIR, dirname);
if (!dirname)
{
mu_error ("%s", mu_strerror (errno));
return 1;
}
}
if (stat (dirname, &sb) == 0)
{
if (S_ISDIR (sb.st_mode))
{
char *file = make_file_name (dirname, idp->progname);
char *file = mu_make_file_name (dirname, idp->progname);
ret = mu_get_config (file, idp->progname, idp->progparam,
idp->flags & ~MU_PARSE_CONFIG_GLOBAL,
idp->target);
......@@ -528,20 +519,25 @@ struct mu_cfg_cont *
mu_build_container (const char *progname, struct include_data *idp)
{
struct mu_cfg_cont *cont = root_container;
mu_config_clone_container (cont);
if (idp->flags & MU_PARSE_CONFIG_PLAIN)
{
struct mu_cfg_param mu_include_param[] = {
{ "include", mu_cfg_callback, NULL, 0, _cb_include,
N_("Include contents of the given file. If a directory is given, "
"include contents of the file <file>/<program>, where <program> is "
"the name of the program. This latter form is allowed only in "
"the site-wide configuration file."),
"include contents of the file <file>/<program>, where "
"<program> is the name of the program. This latter form is "
"allowed only in the site-wide configuration file."),
N_("file-or-directory") },
{ NULL }
};
mu_include_param[0].data = idp;
mu_config_clone_container (cont);
_mu_config_register_section (&cont, NULL, NULL, NULL,
(void*) progname, mu_include_param, NULL);
if (idp->flags & MU_PARSE_CONFIG_GLOBAL)
{
mu_iterator_t iter;
......@@ -573,6 +569,11 @@ mu_build_container (const char *progname, struct include_data *idp)
else if (idp->progparam)
_mu_config_register_section (&cont, NULL, NULL, NULL, NULL,
idp->progparam, NULL);
}
else if (idp->progparam)
_mu_config_register_section (&cont, NULL, NULL, NULL, NULL,
idp->progparam, NULL);
return cont;
}
......@@ -583,13 +584,15 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree, const char *progname,
{
int rc = 0;
if (!parse_tree)
return 0;
if (flags & MU_PARSE_CONFIG_DUMP)
{
mu_stream_t stream;
mu_stdio_stream_create (&stream, stderr,
MU_STREAM_NO_CHECK|MU_STREAM_NO_CLOSE);
mu_stream_open (stream);
mu_cfg_format_parse_tree (stream, parse_tree);
mu_cfg_format_parse_tree (stream, parse_tree, MU_CFG_FMT_LOCUS);
mu_stream_destroy (&stream, NULL);
}
......
......@@ -29,6 +29,7 @@
struct tree_print
{
int flags;
unsigned level;
mu_stream_t stream;
char *buf;
......@@ -131,7 +132,7 @@ format_node (const mu_cfg_node_t *node, void *data)
{
struct tree_print *tp = data;
if (node->locus.file)
if ((tp->flags & MU_CFG_FMT_LOCUS) && node->locus.file)
mu_stream_sequential_printf (tp->stream, "# %lu \"%s\"\n",
(unsigned long) node->locus.line,
node->locus.file);
......@@ -143,7 +144,7 @@ format_node (const mu_cfg_node_t *node, void *data)
_("ERROR: undefined statement"));
break;
case mu_cfg_node_tag:
case mu_cfg_node_statement:
{
mu_stream_sequential_write (tp->stream, node->tag,
strlen (node->tag));
......@@ -183,17 +184,36 @@ format_node_end (const mu_cfg_node_t *node, void *data)
}
void
mu_cfg_format_parse_tree (mu_stream_t stream, mu_cfg_tree_t *tree)
mu_cfg_format_parse_tree (mu_stream_t stream, mu_cfg_tree_t *tree, int flags)
{
struct tree_print t;
t.flags = flags;
t.level = 0;
t.stream = stream;
t.buf = NULL;
t.bufsize = 0;
mu_cfg_preorder (tree->node, format_node, format_node_end, &t);
mu_cfg_preorder (tree->head, format_node, format_node_end, &t);
free (t.buf);
}
void
mu_cfg_format_node (mu_stream_t stream, const mu_cfg_node_t *node, int flags)
{
struct tree_print t;
t.flags = flags;
t.level = 0;
t.stream = stream;
t.buf = NULL;
t.bufsize = 0;
format_node (node, &t);
if (node->type == mu_cfg_node_statement)
{
mu_cfg_preorder (node->node, format_node, format_node_end, &t);
format_node_end (node, &t);
}
}
const char *
mu_cfg_data_type_string (enum mu_cfg_param_data_type type)
......
......@@ -150,11 +150,9 @@ P [1-9][0-9]*
\n { mu_cfg_locus.line++; }
[,;{}()] return yytext[0];
. { if (mu_isprint (yytext[0]))
mu_cfg_perror (&mu_cfg_locus,
_("stray character %c"), yytext[0]);
mu_cfg_parse_error (_("stray character %c"), yytext[0]);
else
mu_cfg_perror (&mu_cfg_locus,
_("stray character \\%03o"),
mu_cfg_parse_error (_("stray character \\%03o"),
(unsigned char) yytext[0]);
}
%%
......@@ -172,7 +170,7 @@ unescape_to_line (int c)
{
char t = mu_argcv_unquote_char (c);
if (t == c && t != '\\' && t != '\"')
mu_cfg_perror (&mu_cfg_locus, _("unknown escape sequence '\\%c'"), c);
mu_cfg_parse_error (_("unknown escape sequence '\\%c'"), c);
mu_opool_append_char (pool, t);
}
}
......@@ -317,13 +315,11 @@ multiline_finish ()
int
mu_get_config (const char *file, const char *progname,
struct mu_cfg_param *progparam, int flags, void *target_ptr)
mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags)
{
struct stat st;
FILE *fp;
int rc;
mu_cfg_tree_t *parse_tree;
if (stat (file, &st))
{
......@@ -348,20 +344,30 @@ mu_get_config (const char *file, const char *progname,
mu_cfg_locus.file = (char*) file;
mu_cfg_locus.line = 1;
yyrestart (fp);
rc = mu_cfg_parse (&parse_tree);
rc = mu_cfg_parse (return_tree);
fclose (fp);
if (flags & MU_PARSE_CONFIG_VERBOSE)
mu_diag_output (MU_DIAG_INFO, _("finished parsing file `%s'"), file);
return rc == 0 ? 0 : MU_ERR_FAILURE;
}
/* FIXME: Deprecated interface */
int
mu_get_config (const char *file, const char *progname,
struct mu_cfg_param *progparam, int flags, void *target_ptr)
{
mu_cfg_tree_t *parse_tree;
int rc = mu_cfg_parse_file (&parse_tree, file, flags);
if (rc == 0)
rc = mu_cfg_tree_reduce (parse_tree, progname, progparam, flags,
target_ptr);
mu_cfg_destroy_tree (&parse_tree);
if (flags & MU_PARSE_CONFIG_VERBOSE)
mu_diag_output (MU_DIAG_INFO, _("finished parsing file `%s'"), file);
return rc == 0 ? 0 : MU_ERR_FAILURE;
}
mu_opool_t
mu_cfg_lexer_pool ()
{
......
......@@ -18,12 +18,15 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <netdb.h>
#include "intprops.h"
#include <mailutils/argcv.h>
#include <mailutils/nls.h>
#include <mailutils/cfg.h>
#include <mailutils/alloc.h>
......@@ -32,9 +35,10 @@
#include <mailutils/list.h>
#include <mailutils/iterator.h>
#include <mailutils/debug.h>
#include <mailutils/mutil.h>
int mu_cfg_parser_verbose;
static mu_cfg_node_t *parse_tree;
static mu_cfg_node_t *parse_head, *parse_tail;
mu_cfg_locus_t mu_cfg_locus;
size_t mu_cfg_error_count;
......@@ -50,7 +54,7 @@ char *_mu_line_finish (void);
static int
yyerror (char *s)
{
mu_cfg_perror (&mu_cfg_locus, "%s", s);
mu_cfg_parse_error ("%s", s);
return 0;
}
......@@ -89,6 +93,13 @@ mu_cfg_alloc_node (enum mu_cfg_node_type type, mu_cfg_locus_t *loc,
}
void
mu_cfg_free_node (mu_cfg_node_t *node)
{
free (node->label);
free (node);
}
void
mu_cfg_format_error (mu_debug_t debug, size_t level, const char *fmt, ...)
{
va_list ap;
......@@ -110,8 +121,8 @@ _mu_cfg_debug_set_locus (mu_debug_t debug, const mu_cfg_locus_t *loc)
loc->line);
}
static void
_mu_cfg_vperror (mu_debug_t debug, const mu_cfg_locus_t *loc,
void
mu_cfg_vperror (mu_debug_t debug, const mu_cfg_locus_t *loc,
const char *fmt, va_list ap)
{
if (!debug)
......@@ -123,28 +134,28 @@ _mu_cfg_vperror (mu_debug_t debug, const mu_cfg_locus_t *loc,
mu_cfg_error_count++;
}
static void
_mu_cfg_perror (mu_debug_t debug, const mu_cfg_locus_t *loc,
void
mu_cfg_perror (mu_debug_t debug, const mu_cfg_locus_t *loc,
const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
_mu_cfg_vperror (debug, loc, fmt, ap);
mu_cfg_vperror (debug, loc, fmt, ap);
va_end (ap);
}
void
mu_cfg_perror (const mu_cfg_locus_t *loc, const char *fmt, ...)
mu_cfg_parse_error (const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
_mu_cfg_vperror (_mu_cfg_debug, loc, fmt, ap);
mu_cfg_vperror (_mu_cfg_debug, &mu_cfg_locus, fmt, ap);
va_end (ap);
}
#define node_type_str(t) (((t) == mu_cfg_node_tag) ? "tag" : "param")
#define node_type_str(t) (((t) == mu_cfg_node_statement) ? "stmt" : "param")
static void
debug_print_node (mu_cfg_node_t *node)
......@@ -194,7 +205,8 @@ debug_print_node (mu_cfg_node_t *node)
input : stmtlist
{
parse_tree = $1.head;
parse_head = $1.head;
parse_tail = $1.tail;
}
;
......@@ -226,14 +238,14 @@ simple : ident vallist ';'
block : ident tag '{' '}' opt_sc
{
$$ = mu_cfg_alloc_node (mu_cfg_node_tag, &$1.locus,
$$ = mu_cfg_alloc_node (mu_cfg_node_statement, &$1.locus,
$1.name, $2,
NULL);
}
| ident tag '{' stmtlist '}' opt_sc
{
$$ = mu_cfg_alloc_node (mu_cfg_node_tag, &$1.locus,
$$ = mu_cfg_alloc_node (mu_cfg_node_statement, &$1.locus,
$1.name, $2,
$4.head);
......@@ -273,7 +285,7 @@ vallist : vlist
val.v.arg.v = mu_alloc (n * sizeof (val.v.arg.v[0]));
if (!val.v.arg.v)
{
mu_cfg_perror (&mu_cfg_locus, _("not enough memory"));
mu_cfg_parse_error (_("not enough memory"));
abort();
}
......@@ -294,7 +306,7 @@ vlist : value
int rc = mu_list_create (&$$);
if (rc)
{
mu_cfg_perror (&mu_cfg_locus, _("cannot create list: %s"),
mu_cfg_parse_error (_("cannot create list: %s"),
mu_strerror (rc));
abort ();
}
......@@ -430,13 +442,184 @@ mu_cfg_parse (mu_cfg_tree_t **ptree)
tree = mu_alloc (sizeof (*tree));
tree->debug = _mu_cfg_debug;
tree->node = parse_tree;
tree->head = parse_head;
tree->tail = parse_tail;
tree->pool = mu_cfg_lexer_pool ();
parse_tree = NULL;
parse_head = parse_tail = NULL;
*ptree = tree;
return rc;
}
int
mu_cfg_tree_union (mu_cfg_tree_t **pa, mu_cfg_tree_t **pb)
{
mu_cfg_tree_t *a, *b;
int rc;
if (!pb)
return EINVAL;
if (!*pb)
return 0;
b = *pb;
if (!pa)
return EINVAL;
if (!*pa)
{
*pa = b;
*pb = NULL;
return 0;
}
else
a = *pa;
/* Merge opools */
rc = mu_opool_union (&b->pool, &a->pool);
if (rc)
return rc;
/* Link node lists */
if (a->tail)
a->tail->next = b->head;
else
a->head = b->head;
a->tail = b->tail;
mu_debug_destroy (&b->debug, mu_debug_get_owner (b->debug));
free (b);
*pb = NULL;
return 0;
}
static mu_cfg_tree_t *
do_include (const char *name, int flags, mu_cfg_locus_t *loc)
{
struct stat sb;
char *tmpname = NULL;
mu_cfg_tree_t *tree = NULL;
if (name[0] != '/')
{
name = tmpname = mu_make_file_name (SYSCONFDIR, name);
if (!name)
{
mu_error ("%s", mu_strerror (errno));
return NULL;
}
}
if (stat (name, &sb) == 0)
{
int rc = 0;
if (S_ISDIR (sb.st_mode))
{
if (flags & MU_PARSE_CONFIG_GLOBAL)
{
char *file = mu_make_file_name (name, mu_program_name);
rc = mu_cfg_parse_file (&tree, file, flags);
}
}
else
rc = mu_cfg_parse_file (&tree, name, flags);
if (rc == 0 && tree)
mu_cfg_tree_postprocess (tree, flags & ~MU_PARSE_CONFIG_GLOBAL);
}
else if (errno == ENOENT)
mu_cfg_perror (tree->debug, loc,
_("include file or directory does not exist"));
else
mu_cfg_perror (tree->debug, loc,
_("cannot stat include file or directory: %s"),
mu_strerror (errno));
free (tmpname);
return tree;
}
int
mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, int flags)
{
mu_cfg_node_t *prev, *node;
for (prev = NULL, node = tree->head; node; )
{
mu_cfg_node_t *next = node->next;
if (node->type == mu_cfg_node_statement)
{
if ((flags & MU_PARSE_CONFIG_GLOBAL) &&
strcmp (node->tag, "program") == 0)
{
if (node->label->type == MU_CFG_STRING)
{
if (strcmp (node->label->v.string, mu_program_name) == 0)
{
mu_cfg_node_t *p;
/* Move all nodes from this block to the topmost
level */
if (prev)
prev->next = node->node;
else
tree->head = node->node;
p = node->node;
mu_cfg_free_node (node);
for (node = prev->next; node->next; node = node->next)
;
node->next = next;
}
}
else
{
mu_cfg_perror (tree->debug, &node->locus,
_("argument to `program' is not a string"));
if (prev)
prev->next = next;
else
tree->head = next;
mu_cfg_free_node (node);
}
}
}
else if (node->type == mu_cfg_node_param &&
strcmp (node->tag, "include") == 0)
{
/* Remove node from the list */
if (prev)
prev->next = next;
else
tree->head = next;
if (node->label->type == MU_CFG_STRING)
{
mu_cfg_tree_t *t = do_include (node->label->v.string, flags,
&node->locus);
if (t)
{
if (prev)
prev->next = t->head;
else
tree->head = t->head;
t->tail->next = next;
/* FIXME: check return value */
mu_opool_union (&tree->pool, &t->pool);
mu_debug_destroy (&t->debug, NULL);
free (t);
}
}
else
mu_cfg_perror (tree->debug, &node->locus,
_("argument to `include' is not a string"));
mu_cfg_free_node (node);
}
prev = node;
node = next;
}
return 0;
}
static int
_mu_cfg_preorder_recursive (mu_cfg_node_t *node,
mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end,
......@@ -447,7 +630,7 @@ _mu_cfg_preorder_recursive (mu_cfg_node_t *node,
case mu_cfg_node_undefined:
abort ();
case mu_cfg_node_tag:
case mu_cfg_node_statement:
switch (beg (node, data))
{
case MU_CFG_ITER_OK:
......@@ -491,7 +674,7 @@ _mu_cfg_postorder_recursive(mu_cfg_node_t *node,
case mu_cfg_node_undefined:
abort ();
case mu_cfg_node_tag:
case mu_cfg_node_statement:
switch (beg (node, data))
{
case MU_CFG_ITER_OK:
......@@ -532,7 +715,7 @@ mu_cfg_postorder (mu_cfg_node_t *node,
static int
free_section (const mu_cfg_node_t *node, void *data)
{
if (node->type == mu_cfg_node_tag)
if (node->type == mu_cfg_node_statement)
free ((void *) node);
return MU_CFG_ITER_OK;
}
......@@ -551,7 +734,7 @@ mu_cfg_destroy_tree (mu_cfg_tree_t **ptree)
if (ptree && *ptree)
{
mu_cfg_tree_t *tree = *ptree;
mu_cfg_postorder (tree->node, free_param, free_section, NULL);
mu_cfg_postorder (tree->head, free_param, free_section, NULL);
mu_opool_destroy (&tree->pool);
*ptree = NULL;
}
......@@ -643,7 +826,7 @@ push_section (struct scan_tree_data *dat, struct mu_cfg_section *sec)
struct mu_cfg_section_list *p = mu_alloc (sizeof *p);
if (!p)
{
_mu_cfg_perror (dat->tree->debug, NULL, _("not enough memory"));
mu_cfg_perror (dat->tree->debug, NULL, _("not enough memory"));
return 1;
}
p->sec = sec;
......@@ -680,12 +863,12 @@ pop_section (struct scan_tree_data *dat)
break; \
if (x <= sum) \
{ \
_mu_cfg_perror (d, loc, _("numeric overflow")); \
mu_cfg_perror (d, loc, _("numeric overflow")); \
return 1; \
} \
else if (limit && x > limit) \
{ \
_mu_cfg_perror (d, loc, \
mu_cfg_perror (d, loc, \
_("value out of allowed range")); \
return 1; \
} \
......@@ -721,7 +904,7 @@ pop_section (struct scan_tree_data *dat)
STRxTONUM (s, type, tmpres, 0, d, loc); \
if (*s) \
{ \
_mu_cfg_perror (d, loc, \
mu_cfg_perror (d, loc, \
_("not a number (stopped near `%s')"), \
s); \
return 1; \
......@@ -752,7 +935,7 @@ pop_section (struct scan_tree_data *dat)
STRxTONUM (s, unsigned type, tmpres, limit, d, loc); \
if (*s) \
{ \
_mu_cfg_perror (d, loc, \
mu_cfg_perror (d, loc, \
_("not a number (stopped near `%s')"), \
s); \
return 1; \
......@@ -767,7 +950,7 @@ parse_ipv4 (struct scan_tree_data *sdata, const mu_cfg_locus_t *locus,
struct in_addr addr;
if (inet_aton (str, &addr) == 0)
{
_mu_cfg_perror (sdata->tree->debug, locus, _("not an IPv4"));
mu_cfg_perror (sdata->tree->debug, locus, _("not an IPv4"));
return 1;
}
addr.s_addr = ntohl (addr.s_addr);
......@@ -787,7 +970,7 @@ parse_host (struct scan_tree_data *sdata, const mu_cfg_locus_t *locus,
}
else if (inet_aton (str, &addr) == 0)
{
_mu_cfg_perror (sdata->tree->debug, locus,
mu_cfg_perror (sdata->tree->debug, locus,
_("cannot resolve hostname `%s'"),
str);
return 1;
......@@ -811,7 +994,7 @@ parse_cidr (struct scan_tree_data *sdata, const mu_cfg_locus_t *locus,
{
int len = p - str;
if (len > sizeof astr - 1) {
_mu_cfg_perror (sdata->tree->debug, locus,
mu_cfg_perror (sdata->tree->debug, locus,
_("not a valid IPv4 address in CIDR"));
return 1;
}
......@@ -819,7 +1002,7 @@ parse_cidr (struct scan_tree_data *sdata, const mu_cfg_locus_t *locus,
astr[len] = 0;
if (inet_aton (astr, &addr) == 0)
{
_mu_cfg_perror (sdata->tree->debug, locus,
mu_cfg_perror (sdata->tree->debug, locus,
_("not a valid IPv4 address in CIDR"));
return 1;
}
......@@ -833,7 +1016,7 @@ parse_cidr (struct scan_tree_data *sdata, const mu_cfg_locus_t *locus,
struct in_addr a;
if (inet_aton (p, &a) == 0)
{
_mu_cfg_perror (sdata->tree->debug, locus,
mu_cfg_perror (sdata->tree->debug, locus,
_("not a valid network in CIDR"));
return 1;
}
......@@ -847,7 +1030,7 @@ parse_cidr (struct scan_tree_data *sdata, const mu_cfg_locus_t *locus,
}
else if (mask > 32)
{
_mu_cfg_perror (sdata->tree->debug, locus,
mu_cfg_perror (sdata->tree->debug, locus,
_("not a valid network mask in CIDR"));
return 1;
}
......@@ -869,7 +1052,7 @@ parse_cidr (struct scan_tree_data *sdata, const mu_cfg_locus_t *locus,
if (*p)
{
_mu_cfg_perror (sdata->tree->debug, locus,
mu_cfg_perror (sdata->tree->debug, locus,
_("not a CIDR (stopped near `%s')"),
p);
return 1;
......@@ -911,7 +1094,7 @@ parse_bool (struct scan_tree_data *sdata, const mu_cfg_locus_t *locus,
{
if (mu_cfg_parse_boolean (str, res))
{
_mu_cfg_perror (sdata->tree->debug, locus, _("not a boolean"));
mu_cfg_perror (sdata->tree->debug, locus, _("not a boolean"));
return 1;
}
return 0;
......@@ -924,8 +1107,7 @@ valcvt (struct scan_tree_data *sdata, const mu_cfg_locus_t *locus,
{
if (val->type != MU_CFG_STRING)
{
_mu_cfg_perror (sdata->tree->debug, locus,
_("expected string value"));
mu_cfg_perror (sdata->tree->debug, locus, _("expected string value"));
return 1;
}
switch (type)
......@@ -972,8 +1154,7 @@ valcvt (struct scan_tree_data *sdata, const mu_cfg_locus_t *locus,
break;
case mu_cfg_off:
_mu_cfg_perror (sdata->tree->debug, locus,
_("not implemented yet"));
mu_cfg_perror (sdata->tree->debug, locus, _("not implemented yet"));
/* GETSNUM(node->tag_label, off_t, *(off_t*)tgt); */
return 1;
......@@ -1046,7 +1227,7 @@ _set_fun (void *item, void *data)
if (clos->type >= MU_ARRAY_SIZE(config_type_size)
|| (size = config_type_size[clos->type]) == 0)
{
_mu_cfg_perror (clos->sdata->tree->debug, clos->locus,
mu_cfg_perror (clos->sdata->tree->debug, clos->locus,
_("INTERNAL ERROR at %s:%d: unhandled data type %d"),
__FILE__, __LINE__, clos->type);
return 1;
......@@ -1055,7 +1236,7 @@ _set_fun (void *item, void *data)
tgt = mu_alloc (size);
if (!tgt)
{
_mu_cfg_perror (clos->sdata->tree->debug, clos->locus,
mu_cfg_perror (clos->sdata->tree->debug, clos->locus,
_("not enough memory"));
return 1;
}
......@@ -1075,7 +1256,7 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
if (!param)
{
_mu_cfg_perror (sdata->tree->debug, &node->locus,
mu_cfg_perror (sdata->tree->debug, &node->locus,
_("unknown keyword `%s'"),
node->tag);
return 1;
......@@ -1091,7 +1272,7 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
tgt = NULL;
else
{
_mu_cfg_perror (sdata->tree->debug, &node->locus,
mu_cfg_perror (sdata->tree->debug, &node->locus,
_("INTERNAL ERROR: cannot determine target offset for "
"%s"), param->ident);
abort ();
......@@ -1119,7 +1300,7 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
break;
case MU_CFG_ARRAY:
_mu_cfg_perror (sdata->tree->debug, &node->locus,
mu_cfg_perror (sdata->tree->debug, &node->locus,
_("expected list, but found array"));
return 1;
}
......@@ -1134,7 +1315,7 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
node->locus.line);
if (!param->callback)
{
_mu_cfg_perror (sdata->tree->debug, &node->locus,
mu_cfg_perror (sdata->tree->debug, &node->locus,
_("INTERNAL ERROR: %s: callback not defined"),
node->tag);
abort ();
......@@ -1161,7 +1342,7 @@ _scan_tree_helper (const mu_cfg_node_t *node, void *data)
case mu_cfg_node_undefined:
abort ();
case mu_cfg_node_tag:
case mu_cfg_node_statement:
sec = find_subsection (sdata->list->sec, node->tag, 0);
if (!sec)
{
......@@ -1219,7 +1400,7 @@ _scan_tree_end_helper (const mu_cfg_node_t *node, void *data)
default:
abort ();
case mu_cfg_node_tag:
case mu_cfg_node_statement:
sec = pop_section (sdata);
if (sec && sec->parser)
{
......@@ -1253,7 +1434,7 @@ mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections,
}
if (push_section (&dat, sections))
return 1;
mu_cfg_preorder (tree->node, _scan_tree_helper, _scan_tree_end_helper, &dat);
mu_cfg_preorder (tree->head, _scan_tree_helper, _scan_tree_end_helper, &dat);
if (debug)
{
mu_debug_set_locus (debug, NULL, 0);
......@@ -1273,13 +1454,13 @@ mu_cfg_find_section (struct mu_cfg_section *root_sec,
size_t len;
const char *p;
while (*path == '/')
while (*path == MU_CFG_PATH_DELIM)
path++;
if (*path == 0)
return MU_ERR_NOENT;
p = strchr (path, '/');
p = strchr (path, MU_CFG_PATH_DELIM);
if (p)
len = p - path;
else
......@@ -1354,13 +1535,275 @@ mu_cfg_tree_create_node (struct mu_cfg_tree *tree,
void
mu_cfg_tree_add_node (mu_cfg_tree_t *tree, mu_cfg_node_t *node)
{
if (!tree->node)
tree->node = node;
if (!tree->head)
tree->head = node;
else
{
mu_cfg_node_t *p;
for (p = tree->node; p->next; p = p->next)
for (p = tree->head; p->next; p = p->next)
;
p->next = node;
}
}
/* Return 1 if configuration value A equals B */
int
mu_cfg_value_eq (mu_config_value_t *a, mu_config_value_t *b)
{
if (a->type != b->type)
return 0;
switch (a->type)
{
case MU_CFG_STRING:
if (a->v.string == NULL)
return b->v.string == NULL;
return strcmp (a->v.string, b->v.string) == 0;
case MU_CFG_LIST:
{
int ret = 1;
size_t cnt;
size_t i;
mu_iterator_t aitr, bitr;
mu_list_count (a->v.list, &cnt);
mu_list_count (b->v.list, &i);
if (i != cnt)
return 1;
mu_list_get_iterator (a->v.list, &aitr);
mu_list_get_iterator (b->v.list, &bitr);
for (i = 0,
mu_iterator_first (aitr),
mu_iterator_first (bitr);
!mu_iterator_is_done (aitr) && !mu_iterator_is_done (bitr);
mu_iterator_next (aitr),
mu_iterator_next (bitr),
i++)
{
mu_config_value_t *ap, *bp;
mu_iterator_current (aitr, (void**)&ap);
mu_iterator_current (bitr, (void**)&bp);
ret = mu_cfg_value_eq (ap, bp);
if (!ret)
break;
}
mu_iterator_destroy (&aitr);
mu_iterator_destroy (&bitr);
return ret && i == cnt;
}
case MU_CFG_ARRAY:
if (a->v.arg.c == b->v.arg.c)
{
size_t i;
for (i = 0; i < a->v.arg.c; i++)
if (!mu_cfg_value_eq (&a->v.arg.v[i], &b->v.arg.v[i]))
return 0;
return 1;
}
}
return 0;
}
struct find_data
{
int argc;
char **argv;
int tag;
mu_config_value_t *label;
const mu_cfg_node_t *node;
};
static void
free_value_mem (mu_config_value_t *p)
{
switch (p->type)
{
case MU_CFG_STRING:
free ((char*)p->v.string);
break;
case MU_CFG_LIST:
/* FIXME */
break;
case MU_CFG_ARRAY:
{
size_t i;
for (i = 0; i < p->v.arg.c; i++)
free_value_mem (&p->v.arg.v[i]);
}
}
}
static void
destroy_value (void *p)
{
mu_config_value_t *val = p;
if (val)
{
free_value_mem (val);
free (val);
}
}
static mu_config_value_t *
parse_label (const char *str)
{
mu_config_value_t *val = NULL;
int count, i;
char **vect;
size_t len = strlen (str);
if (len > 1 && str[0] == '(' && str[len-1] == ')')
{
mu_list_t lst;
mu_argcv_get_np (str + 1, len - 2,
", \t", NULL,
0,
&count, &vect, NULL);
mu_list_create (&lst);
mu_list_set_destroy_item (lst, destroy_value);
for (i = 0; i < count; i++)
{
mu_config_value_t *p = mu_alloc (sizeof (*p));
p->type = MU_CFG_STRING;
p->v.string = vect[i];
mu_list_append (lst, p);
}
free (vect);
val = mu_alloc (sizeof (*val));
val->type = MU_CFG_LIST;
val->v.list = lst;
}
else
{
mu_argcv_get (str, NULL, NULL, &count, &vect);
val = mu_alloc (sizeof (*val));
if (count == 1)
{
val->type = MU_CFG_STRING;
val->v.string = vect[0];
free (vect);
}
else
{
val->type = MU_CFG_ARRAY;
val->v.arg.c = count;
val->v.arg.v = mu_alloc (count * sizeof (val->v.arg.v[0]));
for (i = 0; i < count; i++)
{
val->v.arg.v[i].type = MU_CFG_STRING;
val->v.arg.v[i].v.string = vect[i];
}
free (vect);
}
}
return val;
}
static void
parse_tag (struct find_data *fptr)
{
char *p = strchr (fptr->argv[fptr->tag], '=');
if (p)
{
*p++ = 0;
fptr->label = parse_label (p);
}
else
fptr->label = NULL;
}
static int
node_finder (const mu_cfg_node_t *node, void *data)
{
struct find_data *fdptr = data;
if (strcmp (fdptr->argv[fdptr->tag], node->tag) == 0
&& (!fdptr->label || mu_cfg_value_eq (fdptr->label, node->label)))
{
fdptr->tag++;
if (fdptr->tag == fdptr->argc)
{
fdptr->node = node;
return MU_CFG_ITER_STOP;
}
parse_tag (fdptr);
return MU_CFG_ITER_OK;
}
return node->type == mu_cfg_node_statement ?
MU_CFG_ITER_SKIP : MU_CFG_ITER_OK;
}
int
mu_cfg_find_node (mu_cfg_node_t *tree, const char *path, mu_cfg_node_t **pval)
{
int rc;
struct find_data data;
rc = mu_argcv_get_np (path, strlen (path),
MU_CFG_PATH_DELIM_STR, NULL,
0, &data.argc, &data.argv, NULL);
if (rc)
return rc;
data.tag = 0;
parse_tag (&data);
rc = mu_cfg_preorder (tree, node_finder, NULL, &data);
destroy_value (data.label);
if (rc)
{
*pval = (mu_cfg_node_t *) data.node;
return 0;
}
return MU_ERR_NOENT;
}
int
mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode)
{
int rc;
int argc, i;
char **argv;
mu_cfg_locus_t locus;
enum mu_cfg_node_type type;
mu_cfg_node_t *node = NULL;
locus.file = "<int>";
locus.line = 0;
rc = mu_argcv_get_np (path, strlen (path), MU_CFG_PATH_DELIM_STR, NULL, 0,
&argc, &argv, NULL);
if (rc)
return rc;
for (i = argc - 1; i >= 0; i--)
{
char *p = strrchr (argv[i], '=');
mu_config_value_t *label = NULL;
type = mu_cfg_node_statement;
if (p)
{
*p++ = 0;
label = parse_label (p);
if (i == argc - 1)
type = mu_cfg_node_param;
}
node = mu_cfg_alloc_node (type, &locus, argv[i], label, node);
}
mu_argcv_free (argc, argv);
*pnode = node;
return 0;
}
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2009 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library. If not,
see <http://www.gnu.org/licenses/>. */
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mailutils/alloc.h>
#include <mailutils/mutil.h>
char *
mu_make_file_name (const char *dir, const char *file)
{
char *tmp;
size_t dirlen = strlen (dir);
size_t len;
while (dirlen > 0 && dir[dirlen-1] == '/')
dirlen--;
len = dirlen + 1 + strlen (file);
tmp = mu_alloc (len + 1);
if (tmp)
{
memcpy (tmp, dir, dirlen);
tmp[dirlen++] = '/';
strcpy (tmp + dirlen, file);
}
return tmp;
}
......@@ -291,37 +291,6 @@ mu_cpystr (char *dst, const char *src, size_t size)
return len;
}
/* General retrieve stack support: */
void
mu_register_retriever (mu_list_t *pflist, mu_retrieve_fp fun)
{
if (!*pflist && mu_list_create (pflist))
return;
mu_list_append (*pflist, fun);
}
void *
mu_retrieve (mu_list_t flist, void *data)
{
void *p = NULL;
mu_iterator_t itr;
if (mu_list_get_iterator (flist, &itr) == 0)
{
mu_retrieve_fp fun;
for (mu_iterator_first (itr); !p && !mu_iterator_is_done (itr);
mu_iterator_next (itr))
{
mu_iterator_current (itr, (void **)&fun);
p = (*fun) (data);
}
mu_iterator_destroy (&itr);
}
return p;
}
int
mu_get_host_name (char **host)
{
......
/* String-list functions for GNU Mailutils.
Copyright (C) 2007, 2008 Free Software Foundation, Inc.
Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
Based on slist module from GNU Radius. Written by Sergey Poznyakoff.
......@@ -255,6 +255,49 @@ mu_opool_finish (mu_opool_t opool, size_t *psize)
return opool->free->buf;
}
int
mu_opool_union (mu_opool_t *pdst, mu_opool_t *psrc)
{
mu_opool_t src, dst;
if (!psrc)
return EINVAL;
if (!*psrc)
return 0;
src = *psrc;
if (!pdst)
return EINVAL;
if (!*pdst)
{
*pdst = src;
*psrc = NULL;
return 0;
}
else
dst = *pdst;
if (dst->tail)
dst->tail->next = src->head;
else
dst->head = src->head;
dst->tail = src->tail;
if (src->free)
{
struct mu_opool_bucket *p;
for (p = src->free; p->next; p = p->next)
;
p->next = dst->free;
dst->free = src->free;
}
free (src);
*psrc = NULL;
return 0;
}
/* Iterator support */
struct opool_iterator
......
# -*- tcl -*-
# This file is part of Mailutils testsuite.
# Copyright (C) 2002, 2007 Free Software Foundation
# Copyright (C) 2002, 2007, 2009 Free Software Foundation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -31,7 +31,7 @@ proc mailbox_run {args} {
if {"$a" == "-mail-spool"} {
if [info exists host_board] {
if [board_info $host_board exists top_srcdir] {
append sw "--mail-spool [board_info $host_board top_srcdir]/mail/testsuite/spool"
append sw "--set mailbox.mail-spool=[board_info $host_board top_srcdir]/mail/testsuite/spool"
}
}
if {![info exists init_spool]} {
......
# -*- tcl -*-
# This file is part of Mailutils testsuite.
# Copyright (C) 2002, 2007 Free Software Foundation
# Copyright (C) 2002, 2007, 2009 Free Software Foundation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -31,7 +31,7 @@ mu_exec -message "messages" \
mu_exec -message "messages -q" -arg -q "5"
mu_exec -message "messages +teaparty.mbox" \
-arg "--mail-folder=$MU_SPOOL_DIR" -arg +teaparty.mbox \
-arg "--set mailbox.folder=$MU_SPOOL_DIR" -arg +teaparty.mbox \
"Number of messages in $MU_SPOOL_DIR/teaparty.mbox: 95"
#end of test.exp
......
......@@ -43,14 +43,9 @@ libmu_argp/auth.c
libmu_argp/cmdline.c
libmu_argp/common.c
libmu_argp/compat.c
libmu_argp/gsasl.c
libmu_argp/mu_argp.c
libmu_argp/pam.c
libmu_argp/radius.c
libmu_argp/sieve.c
libmu_argp/sql.c
libmu_argp/tls.c
libmu_argp/virtdomain.c
libmu_auth/ldap.c
libmu_auth/radius.c
......
......@@ -56,14 +56,7 @@ static error_t pop3d_parse_opt (int key, char *arg, struct argp_state *astate);
const char *program_version = "pop3d (" PACKAGE_STRING ")";
static char doc[] = N_("GNU pop3d -- the POP3 daemon.");
#define OPT_LOGIN_DELAY 257
#define OPT_STAT_FILE 258
#define OPT_EXPIRE 259
#define OPT_EXPIRE_ON_EXIT 260
#define OPT_TLS_REQUIRED 261
#define OPT_BULLETIN_SOURCE 262
#define OPT_BULLETIN_DB 263
#define OPT_FOREGROUND 264
#define OPT_FOREGROUND 256
static struct argp_option options[] = {
#define GRP 0
......@@ -73,38 +66,6 @@ static struct argp_option options[] = {
N_("runs in daemon mode with a maximum of NUMBER children"), GRP+1 },
#undef GRP
#define GRP 5
{"undelete", 'u', NULL, OPTION_HIDDEN,
N_("undelete all messages on startup"), GRP+1},
{"expire", OPT_EXPIRE, N_("DAYS"), OPTION_HIDDEN,
N_("expire read messages after the given number of days"), GRP+1},
{"delete-expired", OPT_EXPIRE_ON_EXIT, NULL, OPTION_HIDDEN,
N_("delete expired messages upon closing the mailbox"), GRP+1},
#ifdef WITH_TLS
{"tls-required", OPT_TLS_REQUIRED, NULL, OPTION_HIDDEN,
N_("always require STLS before entering authentication phase")},
#endif
#undef GRP
#define GRP 10
#ifdef ENABLE_LOGIN_DELAY
{"login-delay", OPT_LOGIN_DELAY, N_("SECONDS"), OPTION_HIDDEN,
N_("allowed delay between two successive logins"), GRP+1},
{"stat-file", OPT_STAT_FILE, N_("FILENAME"), OPTION_HIDDEN,
N_("name of login statistics file"), GRP+1},
#endif
#undef GRP
#define GRP 20
{ "bulletin-source", OPT_BULLETIN_SOURCE, N_("MBOX"), OPTION_HIDDEN,
N_("set source mailbox to get bulletins from"), GRP+1 },
#ifdef USE_DBM
{ "bulletin-db", OPT_BULLETIN_DB, N_("FILE"), OPTION_HIDDEN,
N_("set the bulletin database file name"), GRP+1 },
#endif
#undef GRP
{NULL, 0, NULL, 0, NULL, 0}
};
......@@ -203,44 +164,6 @@ pop3d_parse_opt (int key, char *arg, struct argp_state *astate)
mu_argp_node_list_new (&lst, "foreground", "yes");
break;
case 'u':
mu_argp_node_list_new (&lst, "undelete", "yes");
break;
#ifdef ENABLE_LOGIN_DELAY
case OPT_LOGIN_DELAY:
mu_argp_node_list_new (&lst, "login-delay", arg);
break;
case OPT_STAT_FILE:
mu_argp_node_list_new (&lst, "stat-file", arg);
break;
#endif
case OPT_EXPIRE:
mu_argp_node_list_new (&lst, "expire", arg);
break;
case OPT_EXPIRE_ON_EXIT:
mu_argp_node_list_new (&lst, "delete-expired", "yes");
break;
#ifdef WITH_TLS
case OPT_TLS_REQUIRED:
mu_argp_node_list_new (&lst, "tls-required", "yes");
break;
#endif
case OPT_BULLETIN_SOURCE:
mu_argp_node_list_new (&lst, "bulletin-source", arg);
break;
#ifdef USE_DBM
case OPT_BULLETIN_DB:
mu_argp_node_list_new (&lst, "bulletin-db", arg);
break;
#endif
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
......
# -*- tcl -*-
# This file is part of Mailutils testsuite.
# Copyright (C) 2002, 2007 Free Software Foundation
# Copyright (C) 2002, 2007, 2009 Free Software Foundation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -37,7 +37,7 @@ sieve_test discard.sv -pattern\
"DISCARD on msg uid 2: marking as deleted"\
"DISCARD on msg uid 3: marking as deleted"
sieve_test --mail-folder='$MU_SPOOL_DIR' fileinto.sv -pattern\
sieve_test --set "mailbox.folder='$MU_SPOOL_DIR'" fileinto.sv -pattern\
"FILEINTO on msg uid 1: delivering into +file"\
"FILEINTO on msg uid 2: delivering into +file"\
"FILEINTO on msg uid 3: delivering into +file"
......
# -*- tcl -*-
# This file is part of Mailutils testsuite.
# Copyright (C) 2002, 2005, 2007, 2008 Free Software Foundation
# Copyright (C) 2002, 2005, 2007, 2008, 2009 Free Software Foundation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -152,7 +152,7 @@ proc mu_init {args} {
if {[llength $args] == 1 && [lindex $args 0] == "-noflags"} {
set MU_TOOL_FLAGS "--no-site-rcfile --no-user-rcfile"
} else {
set MU_TOOL_FLAGS "--mail-spool $MU_SPOOL_DIR --no-site-rcfile --no-user-rcfile"
set MU_TOOL_FLAGS "--set mailbox.mail-spool=$MU_SPOOL_DIR --no-site-rcfile --no-user-rcfile"
for {set i 0} {$i < [llength $args]} {incr i} {
append MU_TOOL_FLAGS " [lindex $args $i]"
}
......@@ -181,7 +181,7 @@ proc mu_start {args} {
if [info exists host_board] {
if [board_info $host_board exists top_srcdir] {
append sw " --mail-spool [board_info $host_board top_srcdir]/mail/testsuite/spool"
append sw " --set mailbox.mail-spool=[board_info $host_board top_srcdir]/mail/testsuite/spool"
}
}
......@@ -263,7 +263,7 @@ proc mu_exec {args} {
if [info exists host_board] {
if [board_info $host_board exists top_srcdir] {
append sw " --mail-spool [board_info $host_board top_srcdir]/mail/testsuite/spool"
append sw " --set mailbox.mail-spool=[board_info $host_board top_srcdir]/mail/testsuite/spool"
}
}
......