summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2016-10-11 17:20:38 +0300
committerSergey Poznyakoff <gray@gnu.org>2016-10-11 17:36:10 +0300
commitbc73fc65600b6021dfe7a9fa1fba7e9b823993e2 (patch)
tree934b239ddd68b1bc91a42b66ddccfe3bcf01accf
parent6e8147334cf9ffe36367760c06002a1e5b7ae0d5 (diff)
downloadmailutils-bc73fc65600b6021dfe7a9fa1fba7e9b823993e2.tar.gz
mailutils-bc73fc65600b6021dfe7a9fa1fba7e9b823993e2.tar.bz2
Introduce new CLI/configuration code for mailutils applications.
The new API is to replace libmu_cfg and libmu_argp. A smooth transition is scheduled, during which the two APIs will coexist, * configure.ac: Build libmailutils/cli/Makefile * include/mailutils/cli.h: New file. * include/mailutils/Makefile.am: Add cli.h * libmailutils/cli/Makefile.am: New file. * libmailutils/cli/capa.c: New file. * libmailutils/cli/cli.c: New file. * libmailutils/cli/stdcapa.c: New file. * libmailutils/Makefile.am (SUBDIRS): Add cli. * include/mailutils/cfg.h (mu_cfg_parse_hints): New members: append_tree and data. (MU_PARSE_CONFIG_LINT): New flag. * include/mailutils/diag.h (mu_program_name) (mu_full_program_name): Remove const qualifier. * include/mailutils/locker.h (mu_locker_set_default_external_program): Argument is const. * libmailutils/base/locker.c: Likewise. * include/mailutils/opt.h (mu_progname, mu_absprogname): Replace with mu_program_name and mu_full_program_name. (mu_set_progname): Rename to mu_set_program_name. (mu_parseopt) <po_data>: Change type to void *. (po_help_hook, po_version_hook): Change signatures. (mu_parseopt_error): New function. * libmailutils/opt/progname.c (mu_progname, mu_absprogname): Replace with mu_program_name and mu_full_program_name. (mu_set_progname): Rename to mu_set_program_name. * libmailutils/opt/help.c: Minor changes * libmailutils/opt/opt.c (parse_error): Rename to mu_parse_error (extern). (next_opt): Fix permutations. * libmailutils/tests/parseopt.c: Reflect changes. * libmailutils/tests/parseopt17.at: Improve test case * libmailutils/tests/parseopt_help05.at: Reflect changes. * libmailutils/tests/parseopt_help07.at: Reflect changes. * include/mailutils/stdstream.h (mu_program_name): Remove qualifier. * libmailutils/cfg/driver.c (mu_cfg_tree_reduce): Remove useless condition * libmailutils/cfg/lexer.l (mu_cfg_parse_file): Additional info messages. * libmailutils/cfg/parser.y (mu_cfg_parse_config): Join in the append_tree. * libmailutils/diag/diag.c (mu_program_name, mu_full_program_name) (mu_set_program_name): Remove. Declared elsewhere. * libmu_sieve/conf.c: Add new configuration code. Mark old text for removal. * libmailutils/tests/tcli.c: New program. * libmailutils/tests/Makefile.am: Add tcli.c
-rw-r--r--configure.ac1
-rw-r--r--include/mailutils/Makefile.am1
-rw-r--r--include/mailutils/cfg.h5
-rw-r--r--include/mailutils/cli.h55
-rw-r--r--include/mailutils/diag.h4
-rw-r--r--include/mailutils/locker.h2
-rw-r--r--include/mailutils/opt.h16
-rw-r--r--include/mailutils/stdstream.h2
-rw-r--r--libmailutils/Makefile.am3
-rw-r--r--libmailutils/base/locker.c2
-rw-r--r--libmailutils/cfg/driver.c12
-rw-r--r--libmailutils/cfg/lexer.l6
-rw-r--r--libmailutils/cfg/parser.y5
-rw-r--r--libmailutils/cli/Makefile.am26
-rw-r--r--libmailutils/cli/capa.c96
-rw-r--r--libmailutils/cli/cli.c420
-rw-r--r--libmailutils/cli/stdcapa.c466
-rw-r--r--libmailutils/diag/diag.c26
-rw-r--r--libmailutils/opt/help.c8
-rw-r--r--libmailutils/opt/opt.c24
-rw-r--r--libmailutils/opt/progname.c14
-rw-r--r--libmailutils/tests/.gitignore1
-rw-r--r--libmailutils/tests/Makefile.am1
-rw-r--r--libmailutils/tests/parseopt.c4
-rw-r--r--libmailutils/tests/parseopt17.at20
-rw-r--r--libmailutils/tests/parseopt_help05.at2
-rw-r--r--libmailutils/tests/parseopt_help07.at2
-rw-r--r--libmailutils/tests/tcli.c75
-rw-r--r--libmu_sieve/conf.c171
29 files changed, 1390 insertions, 80 deletions
diff --git a/configure.ac b/configure.ac
index dc244dea5..d729747cf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1503,12 +1503,13 @@ AC_CONFIG_FILES([
mail/testsuite/Makefile
libmailutils/auth/Makefile
libmailutils/base/Makefile
libmailutils/address/Makefile
libmailutils/sockaddr/Makefile
libmailutils/cidr/Makefile
+ libmailutils/cli/Makefile
libmailutils/cfg/Makefile
libmailutils/datetime/Makefile
libmailutils/diag/Makefile
libmailutils/filter/Makefile
libmailutils/imapio/Makefile
libmailutils/list/Makefile
diff --git a/include/mailutils/Makefile.am b/include/mailutils/Makefile.am
index ba87486ce..9ae3929af 100644
--- a/include/mailutils/Makefile.am
+++ b/include/mailutils/Makefile.am
@@ -33,12 +33,13 @@ pkginclude_HEADERS = \
attribute.h\
auth.h\
body.h\
cctype.h\
cfg.h\
cidr.h\
+ cli.h\
cstr.h\
datetime.h\
daemon.h\
dbm.h\
debug.h\
diag.h\
diff --git a/include/mailutils/cfg.h b/include/mailutils/cfg.h
index 7ea8e080b..e9f3587ef 100644
--- a/include/mailutils/cfg.h
+++ b/include/mailutils/cfg.h
@@ -76,12 +76,14 @@ struct mu_cfg_node
struct mu_cfg_parse_hints
{
int flags;
char *site_rcfile;
char *custom_rcfile;
char *program;
+ struct mu_cfg_tree *append_tree;
+ void *data;
};
struct mu_cfg_tree
{
mu_list_t nodes; /* a list of mu_cfg_node_t */
mu_opool_t pool;
@@ -235,13 +237,14 @@ int mu_config_register_plain_section (const char *parent_path,
#define MU_CFG_PARSE_SITE_RCFILE 0x010
#define MU_CFG_PARSE_CUSTOM_RCFILE 0x020
#define MU_CFG_PARSE_PROGRAM 0x040
#define MU_CFG_FMT_LOCUS 0x080
#define MU_CFG_FMT_VALUE_ONLY 0x100
#define MU_CFG_FMT_PARAM_PATH 0x200
-
+#define MU_PARSE_CONFIG_LINT 0x400
+
#ifdef MU_CFG_COMPATIBILITY
# define MU_CFG_DEPRECATED
#else
# define MU_CFG_DEPRECATED MU_DEPRECATED
#endif
diff --git a/include/mailutils/cli.h b/include/mailutils/cli.h
new file mode 100644
index 000000000..2943bc469
--- /dev/null
+++ b/include/mailutils/cli.h
@@ -0,0 +1,55 @@
+/* opt.h -- general-purpose command line option parser
+ 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/>.
+*/
+
+#ifndef _MAILUTILS_CLI_H
+#define _MAILUTILS_CLI_H
+#include <stdio.h>
+#include <mailutils/types.h>
+#include <mailutils/cfg.h>
+#include <mailutils/opt.h>
+
+typedef void (*mu_cli_capa_commit_fp) (void *);
+
+struct mu_cli_capa
+{
+ char *name;
+ struct mu_option *opt;
+ struct mu_cfg_param *cfg;
+ mu_cfg_section_fp parser;
+ mu_cli_capa_commit_fp commit;
+};
+
+void mu_cli_capa_init (void);
+void mu_cli_capa_register (struct mu_cli_capa *capa);
+void mu_cli_capa_apply (char const *name, mu_list_t opts, mu_list_t commits);
+
+struct mu_cli_setup
+{
+ struct mu_option **optv;
+ struct mu_cfg_param *cfg;
+ char *prog_doc;
+ char *prog_args;
+};
+
+void mu_version_func (struct mu_parseopt *po, FILE *stream);
+void mu_cli (int argc, char **argv, struct mu_cli_setup *setup,
+ char **capa, void *data,
+ int *ret_argc, char ***ret_argv);
+
+char *mu_site_config_file (void);
+
+#endif
diff --git a/include/mailutils/diag.h b/include/mailutils/diag.h
index 3e2bc5188..0a5ebd2de 100644
--- a/include/mailutils/diag.h
+++ b/include/mailutils/diag.h
@@ -26,14 +26,14 @@
#include <mailutils/debug.h>
#ifdef __cplusplus
extern "C" {
#endif
-extern const char *mu_program_name;
-extern const char *mu_full_program_name;
+extern char *mu_program_name;
+extern char *mu_full_program_name;
#define MU_DIAG_EMERG MU_LOG_EMERG
#define MU_DIAG_ALERT MU_LOG_ALERT
#define MU_DIAG_CRIT MU_LOG_CRIT
#define MU_DIAG_ERROR MU_LOG_ERROR
#define MU_DIAG_ERR MU_DIAG_ERROR
diff --git a/include/mailutils/locker.h b/include/mailutils/locker.h
index b8c4a93c5..718338f72 100644
--- a/include/mailutils/locker.h
+++ b/include/mailutils/locker.h
@@ -100,13 +100,13 @@ enum mu_locker_set_mode
* the default.
*/
extern int mu_locker_set_default_flags (int flags, enum mu_locker_set_mode mode);
extern void mu_locker_set_default_retry_timeout (time_t to);
extern void mu_locker_set_default_retry_count (size_t n);
extern void mu_locker_set_default_expire_timeout (time_t t);
-extern int mu_locker_set_default_external_program (char *path);
+extern int mu_locker_set_default_external_program (char const *path);
/* A flags of 0 means that the default will be used. */
extern int mu_locker_create (mu_locker_t *, const char *filename, int flags);
extern void mu_locker_destroy (mu_locker_t *);
/* Time is measured in seconds. */
diff --git a/include/mailutils/opt.h b/include/mailutils/opt.h
index 8e3b03b5d..cc5634211 100644
--- a/include/mailutils/opt.h
+++ b/include/mailutils/opt.h
@@ -20,16 +20,16 @@
#include <stdio.h>
#include <mailutils/types.h>
#include <mailutils/list.h>
#include <mailutils/util.h>
#include <mailutils/cctype.h>
-extern char *mu_progname;
-extern char *mu_absprogname;
+extern char *mu_program_name;
+extern char *mu_full_program_name;
-void mu_set_progname (char const *arg);
+void mu_set_program_name (char const *arg);
#define MU_OPTION_DEFAULT 0
#define MU_OPTION_ARG_OPTIONAL 0x01
#define MU_OPTION_HIDDEN 0x02
#define MU_OPTION_ALIAS 0x04
#define MU_OPTION_IMMEDIATE 0x08
@@ -115,27 +115,28 @@ struct mu_parseopt
int po_argc; /* Number of argiments */
char **po_argv; /* Array of arguments */
size_t po_optc; /* Number of elements in optv */
struct mu_option **po_optv; /* Array of ptrs to option structures */
int po_flags;
- char *po_data; /* Call-specific data */
+ void *po_data; /* Call-specific data */
int po_exit_error; /* Exit on error with this code */
/* Informational: */
char const *po_prog_name;
char const *po_prog_doc;
char const *po_prog_args;
char const *po_bug_address;
char const *po_package_name;
char const *po_package_url;
char const *po_extra_info;
-
- void (*po_help_hook) (FILE *stream); /* FIXME: should take mu_stream_t ?*/
- void (*po_version_hook) (FILE *stream);
+
+ /* FIXME: should these take mu_stream_t ?*/
+ void (*po_help_hook) (struct mu_parseopt *po, FILE *stream);
+ void (*po_version_hook) (struct mu_parseopt *po, FILE *stream);
/* Output data */
int po_ind; /* Index of the next option */
int po_opterr; /* Index of the element in po_argv that
caused last error, or -1 if no errors */
mu_list_t po_optlist;
@@ -159,12 +160,13 @@ struct mu_parseopt
unsigned po_permuted:1; /* Whether the arguments were permuted */
};
int mu_parseopt (struct mu_parseopt *p,
int argc, char **argv, struct mu_option **optv,
int flags);
+void mu_parseopt_error (struct mu_parseopt *po, char const *fmt, ...);
int mu_parseopt_apply (struct mu_parseopt *p);
void mu_parseopt_free (struct mu_parseopt *p);
void mu_option_describe_options (struct mu_option **optbuf, size_t optcnt);
void mu_program_help (struct mu_parseopt *p);
diff --git a/include/mailutils/stdstream.h b/include/mailutils/stdstream.h
index ac35ff78d..97718811d 100644
--- a/include/mailutils/stdstream.h
+++ b/include/mailutils/stdstream.h
@@ -25,13 +25,13 @@ extern "C" {
#endif
extern mu_stream_t mu_strin;
extern mu_stream_t mu_strout;
extern mu_stream_t mu_strerr;
-extern const char *mu_program_name;
+extern char *mu_program_name;
#define MU_STRERR_STDERR 0
#define MU_STRERR_SYSLOG 1
/* #define MU_STRERR_FILE 2 */
#define MU_STDSTREAM_RESET_STRIN 0x01
diff --git a/libmailutils/Makefile.am b/libmailutils/Makefile.am
index 7a5270c4c..82550c23f 100644
--- a/libmailutils/Makefile.am
+++ b/libmailutils/Makefile.am
@@ -14,13 +14,13 @@
#
# 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/>.
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
lib_LTLIBRARIES = libmailutils.la
libmailutils_la_SOURCES =
@@ -30,12 +30,13 @@ libmailutils_la_LIBADD = \
auth/libauth.la\
base/libbase.la\
address/libaddress.la\
sockaddr/libsockaddr.la\
cidr/libcidr.la\
cfg/libcfg.la\
+ cli/libcli.la\
datetime/libdatetime.la\
diag/libdiag.la\
filter/libfilter.la\
imapio/libimapio.la\
list/liblist.la\
mailbox/libmailbox.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
@@ -239,13 +239,13 @@ void
mu_locker_set_default_expire_timeout (time_t t)
{
mu_locker_expire_timeout = 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)
return ENOMEM;
free (mu_locker_external_program);
mu_locker_external_program = 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
@@ -460,13 +460,13 @@ int
mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree,
struct mu_cfg_parse_hints *hints,
struct mu_cfg_param *progparam,
void *target_ptr)
{
int rc = 0;
-
+ struct mu_cfg_cont *cont;
if (!parse_tree)
return 0;
if (hints && (hints->flags & MU_PARSE_CONFIG_DUMP))
{
int yes = 1;
mu_stream_t stream;
@@ -474,19 +474,15 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree,
mu_stdio_stream_create (&stream, MU_STDERR_FD, 0);
mu_stream_ioctl (stream, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
mu_cfg_format_parse_tree (stream, parse_tree, MU_CFG_FMT_LOCUS);
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;
}
void
mu_format_config_tree (mu_stream_t stream, struct mu_cfg_param *progparam)
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
@@ -327,16 +327,22 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags)
{
struct stat st;
FILE *fp;
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;
}
else if (!S_ISREG (st.st_mode))
{
if (flags & MU_PARSE_CONFIG_VERBOSE)
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
@@ -1586,13 +1586,16 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints)
else
{
mu_cfg_tree_postprocess (tmp, 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-c