diff options
Diffstat (limited to 'libmailutils')
-rw-r--r-- | libmailutils/Makefile.am | 3 | ||||
-rw-r--r-- | libmailutils/base/locker.c | 2 | ||||
-rw-r--r-- | libmailutils/cfg/driver.c | 12 | ||||
-rw-r--r-- | libmailutils/cfg/lexer.l | 6 | ||||
-rw-r--r-- | libmailutils/cfg/parser.y | 5 | ||||
-rw-r--r-- | libmailutils/cli/Makefile.am | 26 | ||||
-rw-r--r-- | libmailutils/cli/capa.c | 96 | ||||
-rw-r--r-- | libmailutils/cli/cli.c | 420 | ||||
-rw-r--r-- | libmailutils/cli/stdcapa.c | 466 | ||||
-rw-r--r-- | libmailutils/diag/diag.c | 26 | ||||
-rw-r--r-- | libmailutils/opt/help.c | 8 | ||||
-rw-r--r-- | libmailutils/opt/opt.c | 24 | ||||
-rw-r--r-- | libmailutils/opt/progname.c | 14 | ||||
-rw-r--r-- | libmailutils/tests/.gitignore | 1 | ||||
-rw-r--r-- | libmailutils/tests/Makefile.am | 1 | ||||
-rw-r--r-- | libmailutils/tests/parseopt.c | 4 | ||||
-rw-r--r-- | libmailutils/tests/parseopt17.at | 20 | ||||
-rw-r--r-- | libmailutils/tests/parseopt_help05.at | 2 | ||||
-rw-r--r-- | libmailutils/tests/parseopt_help07.at | 2 | ||||
-rw-r--r-- | libmailutils/tests/tcli.c | 75 |
20 files changed, 1149 insertions, 64 deletions
diff --git a/libmailutils/Makefile.am b/libmailutils/Makefile.am index 7a5270c4c..82550c23f 100644 --- a/libmailutils/Makefile.am +++ b/libmailutils/Makefile.am @@ -17,7 +17,7 @@ # <http://www.gnu.org/licenses/>. SUBDIRS = \ - auth base address list sockaddr cidr cfg diag\ + auth base address list sockaddr cidr cfg cli diag\ filter mailbox mailer mime msgset opt server string stream stdstream\ property url imapio datetime . tests @@ -33,6 +33,7 @@ libmailutils_la_LIBADD = \ sockaddr/libsockaddr.la\ cidr/libcidr.la\ cfg/libcfg.la\ + cli/libcli.la\ datetime/libdatetime.la\ diag/libdiag.la\ filter/libfilter.la\ diff --git a/libmailutils/base/locker.c b/libmailutils/base/locker.c index b4663b948..c4fe993bf 100644 --- a/libmailutils/base/locker.c +++ b/libmailutils/base/locker.c @@ -242,7 +242,7 @@ mu_locker_set_default_expire_timeout (time_t t) } int -mu_locker_set_default_external_program (char *path) +mu_locker_set_default_external_program (char const *path) { char *p = strdup (path); if (!p) diff --git a/libmailutils/cfg/driver.c b/libmailutils/cfg/driver.c index c0cd2d5d9..f2a43a367 100644 --- a/libmailutils/cfg/driver.c +++ b/libmailutils/cfg/driver.c @@ -463,7 +463,7 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree, void *target_ptr) { int rc = 0; - + struct mu_cfg_cont *cont; if (!parse_tree) return 0; if (hints && (hints->flags & MU_PARSE_CONFIG_DUMP)) @@ -477,13 +477,9 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree, mu_stream_destroy (&stream); } - if (root_container) - { - struct mu_cfg_cont *cont = mu_build_container (progparam); - rc = mu_cfg_scan_tree (parse_tree, &cont->v.section, target_ptr, - NULL); - mu_config_destroy_container (&cont); - } + cont = mu_build_container (progparam); + rc = mu_cfg_scan_tree (parse_tree, &cont->v.section, target_ptr, NULL); + mu_config_destroy_container (&cont); return rc; } diff --git a/libmailutils/cfg/lexer.l b/libmailutils/cfg/lexer.l index 40598a1a2..b6c49ecc1 100644 --- a/libmailutils/cfg/lexer.l +++ b/libmailutils/cfg/lexer.l @@ -330,10 +330,16 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags) int rc; char *full_name = mu_tilde_expansion (file, MU_HIERARCHY_DELIMITER, NULL); + if (flags & MU_PARSE_CONFIG_VERBOSE) + mu_diag_output (MU_DIAG_INFO, _("opening configuration file %s"), + full_name); if (stat (full_name, &st)) { if (errno != ENOENT) mu_error (_("cannot stat `%s': %s"), full_name, mu_strerror (errno)); + else if (flags & MU_PARSE_CONFIG_VERBOSE) + mu_diag_output (MU_DIAG_INFO, _("configuration file %s doesn't exist"), + full_name); free (full_name); return ENOENT; } diff --git a/libmailutils/cfg/parser.y b/libmailutils/cfg/parser.y index e36b513b0..043f7e0c7 100644 --- a/libmailutils/cfg/parser.y +++ b/libmailutils/cfg/parser.y @@ -1589,7 +1589,10 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints) mu_cfg_tree_union (&tree, &tmp); } } - + + if (hints->append_tree) + mu_cfg_tree_union (&tree, &hints->append_tree); + *ptree = tree; return rc; } diff --git a/libmailutils/cli/Makefile.am b/libmailutils/cli/Makefile.am new file mode 100644 index 000000000..48770e844 --- /dev/null +++ b/libmailutils/cli/Makefile.am @@ -0,0 +1,26 @@ +# GNU Mailutils -- a suite of utilities for electronic mail +# Copyright (C) 2016 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/>. + +noinst_LTLIBRARIES = libcli.la + +libcli_la_SOURCES = \ + capa.c\ + cli.c\ + stdcapa.c + +AM_CPPFLAGS = \ + @MU_LIB_COMMON_INCLUDES@ -I/libmailutils diff --git a/libmailutils/cli/capa.c b/libmailutils/cli/capa.c new file mode 100644 index 000000000..bd5c557e9 --- /dev/null +++ b/libmailutils/cli/capa.c @@ -0,0 +1,96 @@ +/* capa.c -- CLI capabilities for GNU Mailutils + Copyright (C) 2016 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 + published by the Free Software Foundation; either version 3, or (at + your option) any later version. + + GNU Mailutils 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. +*/ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <stdlib.h> +#include <string.h> +#include <mailutils/cli.h> +#include <mailutils/list.h> +#include <mailutils/alloc.h> +#include <mailutils/nls.h> + +static mu_list_t capa_list; + +static void +capa_free (void *ptr) +{ + struct mu_cli_capa *cp = ptr; + free (cp->name); + free (cp); +} + +void +mu_cli_capa_register (struct mu_cli_capa *capa) +{ + struct mu_cli_capa *cp = mu_alloc (sizeof (*cp)); + cp->name = mu_strdup (capa->name); + cp->opt = capa->opt; + cp->cfg = capa->cfg; + cp->parser = capa->parser; + cp->commit = capa->commit; + if (!capa_list) + { + mu_list_create (&capa_list); + mu_list_set_destroy_item (capa_list, capa_free); + } + mu_list_append (capa_list, cp); +} + +struct capa_apply +{ + char const *name; + mu_list_t opts; + mu_list_t commits; + int found; +}; + +static int +capa_apply (void *item, void *data) +{ + struct mu_cli_capa *cp = item; + struct capa_apply *ap = data; + + if (strcmp (cp->name, ap->name) == 0) + { + ap->found = 1; + if (cp->opt) + mu_list_append (ap->opts, cp->opt); + if (cp->commit) + mu_list_append (ap->commits, cp->commit); + if (cp->parser || cp->cfg) + mu_config_root_register_section (NULL, cp->name, NULL, + cp->parser, cp->cfg); + } + return 0; +} + +void +mu_cli_capa_apply (char const *name, mu_list_t opts, mu_list_t commits) +{ + struct capa_apply app; + app.name = name; + app.opts = opts; + app.commits = commits; + app.found = 0; + mu_list_foreach (capa_list, capa_apply, &app); + if (!app.found) + mu_error (_("INTERNAL ERROR at %s:%d: unknown standard capability `%s'"), + __FILE__, __LINE__, name); +} + + diff --git a/libmailutils/cli/cli.c b/libmailutils/cli/cli.c new file mode 100644 index 000000000..2be1af833 --- /dev/null +++ b/libmailutils/cli/cli.c @@ -0,0 +1,420 @@ +/* cli.c -- Command line interface for GNU Mailutils + Copyright (C) 2016 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 + published by the Free Software Foundation; either version 3, or (at + your option) any later version. + + GNU Mailutils 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. +*/ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <stdlib.h> +#include <sysexits.h> +#include <mailutils/cfg.h> +#include <mailutils/opt.h> +#include <mailutils/cli.h> +#include <mailutils/list.h> +#include <mailutils/alloc.h> +#include <mailutils/nls.h> +#include <mailutils/errno.h> +#include <mailutils/version.h> +#include <mailutils/stream.h> +#include <mailutils/stdstream.h> +#include <mailutils/io.h> +#include <mailutils/syslog.h> + +#ifndef MU_SITE_CONFIG_FILE +# define MU_SITE_CONFIG_FILE SYSCONFDIR "/mailutils.rc" +#endif + +char * +mu_site_config_file (void) +{ + char *p = getenv ("MU_SITE_CONFIG_FILE"); + if (p) + return p; + return MU_SITE_CONFIG_FILE; +} + + +const char mu_version_copyright[] = + /* Do *not* mark this string for translation. %s is a copyright + symbol suitable for this locale, and %d is the copyright + year. */ + "Copyright %s 2007-2016 Free Software Foundation, inc."; + +void +mu_version_func (struct mu_parseopt *po, FILE *stream) +{ +#ifdef GIT_DESCRIBE + fprintf (stream, "%s (%s) %s [%s]\n", + mu_program_name, PACKAGE_NAME, PACKAGE_VERSION, GIT_DESCRIBE); +#else + fprintf (stream, "%s (%s) %s\n", mu_program_name, + PACKAGE_NAME, PACKAGE_VERSION); +#endif + /* TRANSLATORS: Translate "(C)" to the copyright symbol + (C-in-a-circle), if this symbol is available in the user's + locale. Otherwise, do not translate "(C)"; leave it as-is. */ + fprintf (stream, mu_version_copyright, _("(C)")); + fputs (_("\ +\n\ +License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\n\ +There is NO WARRANTY, to the extent permitted by law.\n\ +\n\ +"), + stream); +} + +static char gnu_general_help_url[] = + N_("General help using GNU software: <http://www.gnu.org/gethelp/>"); + + +static void +change_progname (struct mu_parseopt *po, struct mu_option *opt, + char const *arg) +{ + po->po_prog_name = mu_strdup (arg); +} + +static void +no_user_config (struct mu_parseopt *po, struct mu_option *opt, + char const *arg) +{ + struct mu_cfg_parse_hints *hints = po->po_data; + hints->flags &= ~MU_CFG_PARSE_PROGRAM; +} + +static void +no_site_config (struct mu_parseopt *po, struct mu_option *opt, + char const *arg) +{ + struct mu_cfg_parse_hints *hints = po->po_data; + hints->flags &= ~MU_CFG_PARSE_SITE_RCFILE; +} + +static void +config_file (struct mu_parseopt *po, struct mu_option *opt, + char const *arg) +{ + struct mu_cfg_parse_hints *hints = po->po_data; + hints->flags |= MU_CFG_PARSE_CUSTOM_RCFILE; + hints->custom_rcfile = mu_strdup (arg); +} + +static void +config_verbose (struct mu_parseopt *po, struct mu_option *opt, + char const *arg) +{ + struct mu_cfg_parse_hints *hints = po->po_data; + if (hints->flags & MU_PARSE_CONFIG_VERBOSE) + hints->flags |= MU_PARSE_CONFIG_DUMP; + else + hints->flags |= MU_PARSE_CONFIG_VERBOSE; +} + +static void +config_lint (struct mu_parseopt *po, struct mu_option *opt, + char const *arg) +{ + struct mu_cfg_parse_hints *hints = po->po_data; + hints->flags |= MU_PARSE_CONFIG_VERBOSE|MU_PARSE_CONFIG_LINT; +} + +static void +param_set (struct mu_parseopt *po, struct mu_option *opt, char const *arg) +{ + struct mu_cfg_parse_hints *hints = po->po_data; + mu_cfg_node_t *node; + int rc = mu_cfg_create_subtree (arg, &node); + if (rc) + mu_parseopt_error (po, "%s: cannot create node: %s", + arg, mu_strerror (rc)); + if (!hints->append_tree) + mu_cfg_tree_create (&hints->append_tree); + mu_cfg_tree_add_node (hints->append_tree, node); +} + +struct mu_option mu_common_options[] = { + MU_OPTION_GROUP(N_("Common options")), + { "program-name", 0, N_("NAME"), MU_OPTION_IMMEDIATE|MU_OPTION_HIDDEN, + N_("set program name"), + mu_c_string, NULL, change_progname }, + + { "no-user-config", 0, NULL, MU_OPTION_IMMEDIATE, + N_("do not load user configuration file"), + mu_c_string, NULL, no_user_config }, + { "no-user-rcfile", 0, NULL, MU_OPTION_ALIAS }, + + { "no-site-config", 0, NULL, MU_OPTION_IMMEDIATE, + N_("do not load user configuration file"), + mu_c_string, NULL, no_site_config }, + { "no-site-rcfile", 0, NULL, MU_OPTION_ALIAS }, + + { "config-file", 0, N_("FILE"), MU_OPTION_IMMEDIATE, + N_("load this configuration file"), + mu_c_string, NULL, config_file }, + { "rcfile", 0, NULL, MU_OPTION_ALIAS }, + + { "config-verbose", 0, NULL, MU_OPTION_IMMEDIATE, + N_("verbosely log parsing of the configuration files"), + mu_c_string, NULL, config_verbose }, + { "rcfile-verbose", 0, NULL, MU_OPTION_ALIAS }, + + { "config-lint", 0, NULL, MU_OPTION_IMMEDIATE, + N_("check configuration file syntax and exit"), + mu_c_string, NULL, config_lint }, + { "rcfile-lint", 0, NULL, MU_OPTION_ALIAS }, + + { "set", 0, N_("PARAM=VALUE"), MU_OPTION_IMMEDIATE, + N_("set configuration parameter"), + mu_c_string, NULL, param_set }, + + MU_OPTION_END +}; + +static void +show_comp_defaults (struct mu_parseopt *po, struct mu_option *opt, + char const *unused) +{ + mu_print_options (); + exit (0); +} + +static void +show_config_help (struct mu_parseopt *po, struct mu_option *opt, + char const *unused) +{ + struct mu_cfg_parse_hints *hints = po->po_data; + + char *comment; + mu_stream_t stream; + struct mu_cfg_cont *cont; + static struct mu_cfg_param dummy_include_param[] = { + { "include", mu_c_string, NULL, 0, NULL, + 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."), + N_("file-or-directory") }, + { NULL } + }; + + mu_stdio_stream_create (&stream, MU_STDOUT_FD, 0); + + mu_asprintf (&comment, + "Configuration file structure for %s utility.", + po->po_prog_name); + mu_cfg_format_docstring (stream, comment, 0); + free (comment); + + mu_asprintf (&comment, + "For use in global configuration file (%s), enclose it " + "in `program %s { ... };", + mu_site_config_file (), + po->po_prog_name); + mu_cfg_format_docstring (stream, comment, 0); + free (comment); + + /* FIXME: %s should be replaced by the canonical utility name */ + mu_asprintf (&comment, "For more information, use `info %s'.", + po->po_prog_name); + mu_cfg_format_docstring (stream, comment, 0); + free (comment); + + cont = mu_config_clone_root_container (); + mu_config_container_register_section (&cont, NULL, NULL, NULL, NULL, + dummy_include_param, NULL); + if (hints->data) + mu_config_container_register_section (&cont, NULL, NULL, NULL, NULL, + hints->data, NULL); + mu_cfg_format_container (stream, cont); + mu_config_destroy_container (&cont); + + mu_stream_destroy (&stream); + exit (0); +} + +struct mu_option mu_extra_help_options[] = { + MU_OPTION_GROUP (N_("Informational options")), + { "show-config-options", 0, NULL, MU_OPTION_IMMEDIATE, + N_("show compilation options"), + mu_c_string, NULL, show_comp_defaults }, + { "config-help", 0, NULL, MU_OPTION_IMMEDIATE, + N_("show configuration file summary"), + mu_c_string, NULL, show_config_help }, + MU_OPTION_END +}; + + +static int +add_opt_group (void *item, void *data) +{ + struct mu_parseopt *po = data; + struct mu_option *opt = item; + po->po_optv[po->po_optc++] = opt; + return 0; +} + +/* Build the list of option groups and configuration sections */ +static struct mu_option ** +init_options (char **capa, struct mu_cli_setup *setup, + mu_list_t *ret_comlist) +{ + size_t i, s; + mu_list_t oplist; + struct mu_parseopt po; + + mu_list_create (&oplist); + if (setup->optv) + { + for (i = 0; setup->optv[i]; i++) + mu_list_append (oplist, setup->optv[i]); + } + if (capa) + { + mu_list_t comlist; + mu_list_create (&comlist); + for (i = 0; capa[i]; i++) + mu_cli_capa_apply (capa[i], oplist, comlist); + *ret_comlist = comlist; + } + else + *ret_comlist = NULL; + + mu_list_append (oplist, mu_common_options); + mu_list_append (oplist, mu_extra_help_options); + + mu_list_count (oplist, &s); + + po.po_optv = mu_calloc (s + 1, sizeof (po.po_optv[0])); + po.po_optc = 0; + mu_list_foreach (oplist, add_opt_group, &po); + if (po.po_optc != s) + abort (); + po.po_optv[po.po_optc] = NULL; + mu_list_destroy (&oplist); + return po.po_optv; +} + +static int +run_commit (void *item, void *data) +{ + mu_cli_capa_commit_fp commit = item; + commit (data); + return 0; +} + +void +mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, + void *data, + int *ret_argc, char ***ret_argv) +{ + struct mu_parseopt po; + int flags = 0; + struct mu_cfg_tree *parse_tree = NULL; + struct mu_cfg_parse_hints hints; + struct mu_option **optv; + mu_list_t com_list; + + /* Set program name */ + mu_set_program_name (argv[0]); + + if (!mu_log_tag) + mu_log_tag = (char*)mu_program_name; + + /* Initialize standard streams */ + mu_stdstream_setup (MU_STDSTREAM_RESET_NONE); + + /* Initialize standard capabilities */ + mu_cli_capa_init (); + + /* Initialize hints */ + memset (&hints, 0, sizeof (hints)); + hints.flags |= MU_CFG_PARSE_SITE_RCFILE; + hints.site_rcfile = mu_site_config_file (); + + hints.flags |= MU_CFG_PARSE_PROGRAM; + hints.program = (char*) mu_program_name; + + hints.data = setup->cfg; + + /* Initialize po */ + if (setup->prog_doc) + { + po.po_prog_doc = setup->prog_doc; + flags |= MU_PARSEOPT_PROG_DOC; + } + + if (setup->prog_args) + { + po.po_prog_args = setup->prog_args; + flags |= MU_PARSEOPT_PROG_ARGS; + } + + po.po_package_name = PACKAGE_NAME; + flags |= MU_PARSEOPT_PACKAGE_NAME; + + po.po_package_url = PACKAGE_URL; + flags |= MU_PARSEOPT_PACKAGE_URL; + + po.po_bug_address = PACKAGE_BUGREPORT; + flags |= MU_PARSEOPT_BUG_ADDRESS; + + po.po_extra_info = gnu_general_help_url; + flags |= MU_PARSEOPT_EXTRA_INFO; + + po.po_version_hook = mu_version_func; + flags |= MU_PARSEOPT_VERSION_HOOK; + + po.po_data = &hints; + flags |= MU_PARSEOPT_DATA; + + po.po_exit_error = EX_USAGE; + + optv = init_options (capa, setup, &com_list); + + if (mu_parseopt (&po, argc, argv, optv, flags)) + exit (EX_USAGE); + + argc -= po.po_arg_start; + argv += po.po_arg_start; + + if (ret_argc) + { + *ret_argc = argc; + *ret_argv = argv; + } + else if (argc) + mu_parseopt_error (&po, "%s", _("unexpected arguments")); + + if (mu_cfg_parse_config (&parse_tree, &hints)) + exit (EX_CONFIG); + + if (mu_cfg_tree_reduce (parse_tree, &hints, setup->cfg, data)) + exit (EX_CONFIG); + + if (mu_cfg_error_count) //FIXME + exit (EX_CONFIG); + + mu_parseopt_apply (&po); + + mu_list_foreach (com_list, run_commit, NULL); + mu_list_destroy (&com_list); + + if (hints.flags & MU_PARSE_CONFIG_LINT) + exit (0); + + mu_cfg_destroy_tree (&parse_tree); + free (optv); + mu_parseopt_free (&po); +} diff --git a/libmailutils/cli/stdcapa.c b/libmailutils/cli/stdcapa.c new file mode 100644 index 000000000..3b1cabe54 --- /dev/null +++ b/libmailutils/cli/stdcapa.c @@ -0,0 +1,466 @@ +/* stdcapa.c -- Standard CLI capabilities for GNU Mailutils + Copyright (C) 2016 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 + published by the Free Software Foundation; either version 3, or (at + your option) any later version. + + GNU Mailutils 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. +*/ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <stdlib.h> +#include <mailutils/cli.h> +#include <mailutils/cfg.h> +#include <mailutils/nls.h> +#include <mailutils/syslog.h> +#include <mailutils/stdstream.h> +#include <mailutils/mailer.h> +#include <mailutils/errno.h> +#include <mailutils/mailbox.h> +#include <mailutils/registrar.h> +#include <mailutils/locker.h> + +/* ************************************************************************* + * Logging section + * ************************************************************************* */ +static void +cli_log_facility (struct mu_parseopt *po, struct mu_option *opt, + char const *arg) +{ + if (mu_string_to_syslog_facility (arg, &mu_log_facility)) + mu_parseopt_error (po, _("unknown syslog facility `%s'"), arg); +} + +static int +cb_facility (void *data, mu_config_value_t *val) +{ + if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) + return 1; + + if (mu_string_to_syslog_facility (val->v.string, &mu_log_facility)) + { + mu_error (_("unknown syslog facility `%s'"), val->v.string); + return 1; + } + return 0; +} + +static int +cb_severity (void *data, mu_config_value_t *val) +{ + unsigned n; + + if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) + return 1; + if (mu_severity_from_string (val->v.string, &n)) + { + mu_error (_("unknown severity `%s'"), val->v.string); + return 1; + } + mu_log_severity_threshold = n; + return 0; +} + +static struct mu_cfg_param logging_cfg[] = { + { "syslog", mu_c_bool, &mu_log_syslog, 0, NULL, + N_("Send diagnostics to syslog.") }, + { "print-severity", mu_c_bool, &mu_log_print_severity, 0, NULL, + N_("Print message severity levels.") }, + { "severity", mu_cfg_callback, NULL, 0, cb_severity, + N_("Output only messages with a severity equal to or greater than " + "this one."), + N_("arg: string")}, + { "facility", mu_cfg_callback, NULL, 0, cb_facility, + N_("Set syslog facility. Arg is one of the following: user, daemon, " + "auth, authpriv, mail, cron, local0 through local7 (case-insensitive), " + "or a facility number."), + N_("arg: string") }, + { "session-id", mu_c_bool, &mu_log_session_id, 0, NULL, + N_("Log session ID") }, + { "tag", mu_c_string, &mu_log_tag, 0, NULL, + N_("Tag syslog messages with this string.") }, + { NULL } +}; + +static struct mu_option logging_option[] = { + { "log-facility", 0, N_("FACILITY"), MU_OPTION_DEFAULT, + N_("output logs to syslog FACILITY"), + mu_c_int, &mu_log_facility, cli_log_facility }, + MU_OPTION_END +}; + +static void +logging_commit (void *unused) +{ + if (mu_log_syslog >= 0) + mu_stdstream_strerr_setup (mu_log_syslog ? + MU_STRERR_SYSLOG : MU_STRERR_STDERR); +} + +/* ************************************************************************* + * Mailer + * ************************************************************************* */ +static void +cli_mailer (struct mu_parseopt *po, struct mu_option *opt, char const *arg) +{ + int rc = mu_mailer_set_url_default (arg); + if (rc != 0) + mu_parseopt_error (po, _("invalid mailer URL `%s': %s"), + arg, mu_strerror (rc)); +} + +static struct mu_option mailer_option[] = { + { "mailer", 'M', N_("MAILER"), MU_OPTION_DEFAULT, + N_("use specified URL as the default mailer"), + mu_c_string, NULL, cli_mailer }, + MU_OPTION_END +}; + +static int +cb_mailer (void *data, mu_config_value_t *val) +{ + int rc; + + if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) + return 1; + rc = mu_mailer_set_url_default (val->v.string); + if (rc != 0) + mu_error (_("%s: invalid mailer URL: %s"), + val->v.string, mu_strerror (rc)); + return rc; +} + +static struct mu_cfg_param mailer_cfg[] = { + { "url", mu_cfg_callback, NULL, 0, cb_mailer, + N_("Use this URL as the default mailer"), + N_("url: string") }, + { NULL } +}; + +/* ************************************************************************* + * Debugging + * ************************************************************************* */ +static void +cli_debug_level (struct mu_parseopt *po, struct mu_option *opt, + char const *arg) +{ + mu_debug_clear_all (); + mu_debug_parse_spec (arg); + /* FIXME: Error handling */ +} + +static struct mu_option debug_option[] = { + MU_OPTION_GROUP (N_("Global debugging settings")), + { "debug-level", 0, N_("LEVEL"), MU_OPTION_DEFAULT, + N_("set Mailutils debugging level"), + mu_c_string, NULL, cli_debug_level }, + { "debug-line-info", 0, NULL, MU_OPTION_DEFAULT, + N_("show source info with debugging messages"), + mu_c_bool, &mu_debug_line_info }, + MU_OPTION_END +}; + +static int +cb_debug_level (void *data, mu_config_value_t *val) +{ + if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) + return 1; + mu_debug_parse_spec (val->v.string); + return 0; +} + +static struct mu_cfg_param debug_cfg[] = { + { "level", mu_cfg_callback, NULL, 0, &cb_debug_level, + N_("Set Mailutils debugging level. Argument is a colon-separated list " + "of debugging specifications in the form:\n" + " <object: string>[[:]=<level: number>]."), + N_("arg: string") }, + { "line-info", mu_c_bool, &mu_debug_line_info, 0, NULL, + N_("Prefix debug messages with Mailutils source locations.") }, + { NULL } +}; + +/* ************************************************************************* * + * Mailbox * + * ************************************************************************* */ + +static int +cb_mail_spool (void *data, mu_config_value_t *val) +{ + int rc; + if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) + return 1; + rc = mu_set_mail_directory (val->v.string); + if (rc) + mu_error (_("cannot set mail directory name to `%s': %s"), + val->v.string, mu_strerror (rc)); + return rc; +} + +static int +cb_mailbox_pattern (void *data, mu_config_value_t *val) +{ + int rc; + if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) + return 1; + + rc = mu_set_mailbox_pattern (val->v.string); + if (rc) + mu_error (_("cannot set mailbox pattern to `%s': %s"), + val->v.string, mu_strerror (rc)); + return rc; +} + +static int +cb_mailbox_type (void *data, mu_config_value_t *val) +{ + if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) + return 1; + if (mu_registrar_set_default_scheme (val->v.string)) + mu_error (_("invalid mailbox type: %s"), val->v.string); + return 0; +} + +static int +cb_folder (void *data, mu_config_value_t *val) +{ + if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) + return 1; + mu_set_folder_directory (val->v.string); + return 0; +} + +static struct mu_cfg_param mailbox_cfg[] = { + { "mail-spool", mu_cfg_callback, NULL, 0, cb_mail_spool, + N_("Use specified URL as a mailspool directory."), + N_("url: string") }, + { "mailbox-pattern", mu_cfg_callback, NULL, 0, cb_mailbox_pattern, + N_("Create mailbox URL using <pattern>."), + N_("pattern: string") }, + { "mailbox-type", mu_cfg_callback, NULL, 0, cb_mailbox_type, + N_("Default mailbox type."), + N_("protocol: string") }, + { "folder", mu_cfg_callback, NULL, 0, cb_folder, + N_("Default user mail folder"), + N_("dir: string") }, + { NULL } +}; + +/* ************************************************************************* * + * Locking * + * ************************************************************************* */ +static int +cb_locker_flags (void *data, mu_config_value_t *val) +{ + int flags = 0; + char const *s; + + if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) + return 1; + + for (s = val->v.string; *s; s++) + { + switch (*s) + { + case 'E': + flags |= MU_LOCKER_EXTERNAL; + break; + + case 'R': + flags |= MU_LOCKER_RETRY; + break;< |