Commit bc73fc65 bc73fc65600b6021dfe7a9fa1fba7e9b823993e2 by Sergey Poznyakoff

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
1 parent 6e814733
...@@ -1506,6 +1506,7 @@ AC_CONFIG_FILES([ ...@@ -1506,6 +1506,7 @@ AC_CONFIG_FILES([
1506 libmailutils/address/Makefile 1506 libmailutils/address/Makefile
1507 libmailutils/sockaddr/Makefile 1507 libmailutils/sockaddr/Makefile
1508 libmailutils/cidr/Makefile 1508 libmailutils/cidr/Makefile
1509 libmailutils/cli/Makefile
1509 libmailutils/cfg/Makefile 1510 libmailutils/cfg/Makefile
1510 libmailutils/datetime/Makefile 1511 libmailutils/datetime/Makefile
1511 libmailutils/diag/Makefile 1512 libmailutils/diag/Makefile
......
...@@ -36,6 +36,7 @@ pkginclude_HEADERS = \ ...@@ -36,6 +36,7 @@ pkginclude_HEADERS = \
36 cctype.h\ 36 cctype.h\
37 cfg.h\ 37 cfg.h\
38 cidr.h\ 38 cidr.h\
39 cli.h\
39 cstr.h\ 40 cstr.h\
40 datetime.h\ 41 datetime.h\
41 daemon.h\ 42 daemon.h\
......
...@@ -79,6 +79,8 @@ struct mu_cfg_parse_hints ...@@ -79,6 +79,8 @@ struct mu_cfg_parse_hints
79 char *site_rcfile; 79 char *site_rcfile;
80 char *custom_rcfile; 80 char *custom_rcfile;
81 char *program; 81 char *program;
82 struct mu_cfg_tree *append_tree;
83 void *data;
82 }; 84 };
83 85
84 struct mu_cfg_tree 86 struct mu_cfg_tree
...@@ -238,6 +240,7 @@ int mu_config_register_plain_section (const char *parent_path, ...@@ -238,6 +240,7 @@ int mu_config_register_plain_section (const char *parent_path,
238 #define MU_CFG_FMT_LOCUS 0x080 240 #define MU_CFG_FMT_LOCUS 0x080
239 #define MU_CFG_FMT_VALUE_ONLY 0x100 241 #define MU_CFG_FMT_VALUE_ONLY 0x100
240 #define MU_CFG_FMT_PARAM_PATH 0x200 242 #define MU_CFG_FMT_PARAM_PATH 0x200
243 #define MU_PARSE_CONFIG_LINT 0x400
241 244
242 #ifdef MU_CFG_COMPATIBILITY 245 #ifdef MU_CFG_COMPATIBILITY
243 # define MU_CFG_DEPRECATED 246 # define MU_CFG_DEPRECATED
......
1 /* opt.h -- general-purpose command line option parser
2 Copyright (C) 2016 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 3, or (at
7 your option) any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifndef _MAILUTILS_CLI_H
19 #define _MAILUTILS_CLI_H
20 #include <stdio.h>
21 #include <mailutils/types.h>
22 #include <mailutils/cfg.h>
23 #include <mailutils/opt.h>
24
25 typedef void (*mu_cli_capa_commit_fp) (void *);
26
27 struct mu_cli_capa
28 {
29 char *name;
30 struct mu_option *opt;
31 struct mu_cfg_param *cfg;
32 mu_cfg_section_fp parser;
33 mu_cli_capa_commit_fp commit;
34 };
35
36 void mu_cli_capa_init (void);
37 void mu_cli_capa_register (struct mu_cli_capa *capa);
38 void mu_cli_capa_apply (char const *name, mu_list_t opts, mu_list_t commits);
39
40 struct mu_cli_setup
41 {
42 struct mu_option **optv;
43 struct mu_cfg_param *cfg;
44 char *prog_doc;
45 char *prog_args;
46 };
47
48 void mu_version_func (struct mu_parseopt *po, FILE *stream);
49 void mu_cli (int argc, char **argv, struct mu_cli_setup *setup,
50 char **capa, void *data,
51 int *ret_argc, char ***ret_argv);
52
53 char *mu_site_config_file (void);
54
55 #endif
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
29 extern "C" { 29 extern "C" {
30 #endif 30 #endif
31 31
32 extern const char *mu_program_name; 32 extern char *mu_program_name;
33 extern const char *mu_full_program_name; 33 extern char *mu_full_program_name;
34 34
35 #define MU_DIAG_EMERG MU_LOG_EMERG 35 #define MU_DIAG_EMERG MU_LOG_EMERG
36 #define MU_DIAG_ALERT MU_LOG_ALERT 36 #define MU_DIAG_ALERT MU_LOG_ALERT
......
...@@ -103,7 +103,7 @@ extern int mu_locker_set_default_flags (int flags, enum mu_locker_set_mode mode) ...@@ -103,7 +103,7 @@ extern int mu_locker_set_default_flags (int flags, enum mu_locker_set_mode mode)
103 extern void mu_locker_set_default_retry_timeout (time_t to); 103 extern void mu_locker_set_default_retry_timeout (time_t to);
104 extern void mu_locker_set_default_retry_count (size_t n); 104 extern void mu_locker_set_default_retry_count (size_t n);
105 extern void mu_locker_set_default_expire_timeout (time_t t); 105 extern void mu_locker_set_default_expire_timeout (time_t t);
106 extern int mu_locker_set_default_external_program (char *path); 106 extern int mu_locker_set_default_external_program (char const *path);
107 107
108 /* A flags of 0 means that the default will be used. */ 108 /* A flags of 0 means that the default will be used. */
109 extern int mu_locker_create (mu_locker_t *, const char *filename, int flags); 109 extern int mu_locker_create (mu_locker_t *, const char *filename, int flags);
......
...@@ -23,10 +23,10 @@ ...@@ -23,10 +23,10 @@
23 #include <mailutils/util.h> 23 #include <mailutils/util.h>
24 #include <mailutils/cctype.h> 24 #include <mailutils/cctype.h>
25 25
26 extern char *mu_progname; 26 extern char *mu_program_name;
27 extern char *mu_absprogname; 27 extern char *mu_full_program_name;
28 28
29 void mu_set_progname (char const *arg); 29 void mu_set_program_name (char const *arg);
30 30
31 #define MU_OPTION_DEFAULT 0 31 #define MU_OPTION_DEFAULT 0
32 #define MU_OPTION_ARG_OPTIONAL 0x01 32 #define MU_OPTION_ARG_OPTIONAL 0x01
...@@ -118,7 +118,7 @@ struct mu_parseopt ...@@ -118,7 +118,7 @@ struct mu_parseopt
118 struct mu_option **po_optv; /* Array of ptrs to option structures */ 118 struct mu_option **po_optv; /* Array of ptrs to option structures */
119 int po_flags; 119 int po_flags;
120 120
121 char *po_data; /* Call-specific data */ 121 void *po_data; /* Call-specific data */
122 122
123 int po_exit_error; /* Exit on error with this code */ 123 int po_exit_error; /* Exit on error with this code */
124 124
...@@ -131,8 +131,9 @@ struct mu_parseopt ...@@ -131,8 +131,9 @@ struct mu_parseopt
131 char const *po_package_url; 131 char const *po_package_url;
132 char const *po_extra_info; 132 char const *po_extra_info;
133 133
134 void (*po_help_hook) (FILE *stream); /* FIXME: should take mu_stream_t ?*/ 134 /* FIXME: should these take mu_stream_t ?*/
135 void (*po_version_hook) (FILE *stream); 135 void (*po_help_hook) (struct mu_parseopt *po, FILE *stream);
136 void (*po_version_hook) (struct mu_parseopt *po, FILE *stream);
136 137
137 /* Output data */ 138 /* Output data */
138 int po_ind; /* Index of the next option */ 139 int po_ind; /* Index of the next option */
...@@ -162,6 +163,7 @@ struct mu_parseopt ...@@ -162,6 +163,7 @@ struct mu_parseopt
162 int mu_parseopt (struct mu_parseopt *p, 163 int mu_parseopt (struct mu_parseopt *p,
163 int argc, char **argv, struct mu_option **optv, 164 int argc, char **argv, struct mu_option **optv,
164 int flags); 165 int flags);
166 void mu_parseopt_error (struct mu_parseopt *po, char const *fmt, ...);
165 167
166 int mu_parseopt_apply (struct mu_parseopt *p); 168 int mu_parseopt_apply (struct mu_parseopt *p);
167 void mu_parseopt_free (struct mu_parseopt *p); 169 void mu_parseopt_free (struct mu_parseopt *p);
......
...@@ -28,7 +28,7 @@ extern mu_stream_t mu_strin; ...@@ -28,7 +28,7 @@ extern mu_stream_t mu_strin;
28 extern mu_stream_t mu_strout; 28 extern mu_stream_t mu_strout;
29 extern mu_stream_t mu_strerr; 29 extern mu_stream_t mu_strerr;
30 30
31 extern const char *mu_program_name; 31 extern char *mu_program_name;
32 32
33 #define MU_STRERR_STDERR 0 33 #define MU_STRERR_STDERR 0
34 #define MU_STRERR_SYSLOG 1 34 #define MU_STRERR_SYSLOG 1
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
17 # <http://www.gnu.org/licenses/>. 17 # <http://www.gnu.org/licenses/>.
18 18
19 SUBDIRS = \ 19 SUBDIRS = \
20 auth base address list sockaddr cidr cfg diag\ 20 auth base address list sockaddr cidr cfg cli diag\
21 filter mailbox mailer mime msgset opt server string stream stdstream\ 21 filter mailbox mailer mime msgset opt server string stream stdstream\
22 property url imapio datetime . tests 22 property url imapio datetime . tests
23 23
...@@ -33,6 +33,7 @@ libmailutils_la_LIBADD = \ ...@@ -33,6 +33,7 @@ libmailutils_la_LIBADD = \
33 sockaddr/libsockaddr.la\ 33 sockaddr/libsockaddr.la\
34 cidr/libcidr.la\ 34 cidr/libcidr.la\
35 cfg/libcfg.la\ 35 cfg/libcfg.la\
36 cli/libcli.la\
36 datetime/libdatetime.la\ 37 datetime/libdatetime.la\
37 diag/libdiag.la\ 38 diag/libdiag.la\
38 filter/libfilter.la\ 39 filter/libfilter.la\
......
...@@ -242,7 +242,7 @@ mu_locker_set_default_expire_timeout (time_t t) ...@@ -242,7 +242,7 @@ mu_locker_set_default_expire_timeout (time_t t)
242 } 242 }
243 243
244 int 244 int
245 mu_locker_set_default_external_program (char *path) 245 mu_locker_set_default_external_program (char const *path)
246 { 246 {
247 char *p = strdup (path); 247 char *p = strdup (path);
248 if (!p) 248 if (!p)
......
...@@ -463,7 +463,7 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree, ...@@ -463,7 +463,7 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree,
463 void *target_ptr) 463 void *target_ptr)
464 { 464 {
465 int rc = 0; 465 int rc = 0;
466 466 struct mu_cfg_cont *cont;
467 if (!parse_tree) 467 if (!parse_tree)
468 return 0; 468 return 0;
469 if (hints && (hints->flags & MU_PARSE_CONFIG_DUMP)) 469 if (hints && (hints->flags & MU_PARSE_CONFIG_DUMP))
...@@ -477,13 +477,9 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree, ...@@ -477,13 +477,9 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree,
477 mu_stream_destroy (&stream); 477 mu_stream_destroy (&stream);
478 } 478 }
479 479
480 if (root_container) 480 cont = mu_build_container (progparam);
481 { 481 rc = mu_cfg_scan_tree (parse_tree, &cont->v.section, target_ptr, NULL);
482 struct mu_cfg_cont *cont = mu_build_container (progparam);
483 rc = mu_cfg_scan_tree (parse_tree, &cont->v.section, target_ptr,
484 NULL);
485 mu_config_destroy_container (&cont); 482 mu_config_destroy_container (&cont);
486 }
487 483
488 return rc; 484 return rc;
489 } 485 }
......
...@@ -330,10 +330,16 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags) ...@@ -330,10 +330,16 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags)
330 int rc; 330 int rc;
331 char *full_name = mu_tilde_expansion (file, MU_HIERARCHY_DELIMITER, NULL); 331 char *full_name = mu_tilde_expansion (file, MU_HIERARCHY_DELIMITER, NULL);
332 332
333 if (flags & MU_PARSE_CONFIG_VERBOSE)
334 mu_diag_output (MU_DIAG_INFO, _("opening configuration file %s"),
335 full_name);
333 if (stat (full_name, &st)) 336 if (stat (full_name, &st))
334 { 337 {
335 if (errno != ENOENT) 338 if (errno != ENOENT)
336 mu_error (_("cannot stat `%s': %s"), full_name, mu_strerror (errno)); 339 mu_error (_("cannot stat `%s': %s"), full_name, mu_strerror (errno));
340 else if (flags & MU_PARSE_CONFIG_VERBOSE)
341 mu_diag_output (MU_DIAG_INFO, _("configuration file %s doesn't exist"),
342 full_name);
337 free (full_name); 343 free (full_name);
338 return ENOENT; 344 return ENOENT;
339 } 345 }
......
...@@ -1590,6 +1590,9 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints) ...@@ -1590,6 +1590,9 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints)
1590 } 1590 }
1591 } 1591 }
1592 1592
1593 if (hints->append_tree)
1594 mu_cfg_tree_union (&tree, &hints->append_tree);
1595
1593 *ptree = tree; 1596 *ptree = tree;
1594 return rc; 1597 return rc;
1595 } 1598 }
......
1 # GNU Mailutils -- a suite of utilities for electronic mail
2 # Copyright (C) 2016 Free Software Foundation, Inc.
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 3 of the License, or (at your option) any later version.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General
15 # Public License along with this library. If not, see
16 # <http://www.gnu.org/licenses/>.
17
18 noinst_LTLIBRARIES = libcli.la
19
20 libcli_la_SOURCES = \
21 capa.c\
22 cli.c\
23 stdcapa.c
24
25 AM_CPPFLAGS = \
26 @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
1 /* capa.c -- CLI capabilities for GNU Mailutils
2 Copyright (C) 2016 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 3, or (at
7 your option) any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
16 */
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20 #include <stdlib.h>
21 #include <string.h>
22 #include <mailutils/cli.h>
23 #include <mailutils/list.h>
24 #include <mailutils/alloc.h>
25 #include <mailutils/nls.h>
26
27 static mu_list_t capa_list;
28
29 static void
30 capa_free (void *ptr)
31 {
32 struct mu_cli_capa *cp = ptr;
33 free (cp->name);
34 free (cp);
35 }
36
37 void
38 mu_cli_capa_register (struct mu_cli_capa *capa)
39 {
40 struct mu_cli_capa *cp = mu_alloc (sizeof (*cp));
41 cp->name = mu_strdup (capa->name);
42 cp->opt = capa->opt;
43 cp->cfg = capa->cfg;
44 cp->parser = capa->parser;
45 cp->commit = capa->commit;
46 if (!capa_list)
47 {
48 mu_list_create (&capa_list);
49 mu_list_set_destroy_item (capa_list, capa_free);
50 }
51 mu_list_append (capa_list, cp);
52 }
53
54 struct capa_apply
55 {
56 char const *name;
57 mu_list_t opts;
58 mu_list_t commits;
59 int found;
60 };
61
62 static int
63 capa_apply (void *item, void *data)
64 {
65 struct mu_cli_capa *cp = item;
66 struct capa_apply *ap = data;
67
68 if (strcmp (cp->name, ap->name) == 0)
69 {
70 ap->found = 1;
71 if (cp->opt)
72 mu_list_append (ap->opts, cp->opt);
73 if (cp->commit)
74 mu_list_append (ap->commits, cp->commit);
75 if (cp->parser || cp->cfg)
76 mu_config_root_register_section (NULL, cp->name, NULL,
77 cp->parser, cp->cfg);
78 }
79 return 0;
80 }
81
82 void
83 mu_cli_capa_apply (char const *name, mu_list_t opts, mu_list_t commits)
84 {
85 struct capa_apply app;
86 app.name = name;
87 app.opts = opts;
88 app.commits = commits;
89 app.found = 0;
90 mu_list_foreach (capa_list, capa_apply, &app);
91 if (!app.found)
92 mu_error (_("INTERNAL ERROR at %s:%d: unknown standard capability `%s'"),
93 __FILE__, __LINE__, name);
94 }
95
96
1 /* cli.c -- Command line interface for GNU Mailutils
2 Copyright (C) 2016 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 3, or (at
7 your option) any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
16 */
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20 #include <stdlib.h>
21 #include <sysexits.h>
22 #include <mailutils/cfg.h>
23 #include <mailutils/opt.h>
24 #include <mailutils/cli.h>
25 #include <mailutils/list.h>
26 #include <mailutils/alloc.h>
27 #include <mailutils/nls.h>
28 #include <mailutils/errno.h>
29 #include <mailutils/version.h>
30 #include <mailutils/stream.h>
31 #include <mailutils/stdstream.h>
32 #include <mailutils/io.h>
33 #include <mailutils/syslog.h>
34
35 #ifndef MU_SITE_CONFIG_FILE
36 # define MU_SITE_CONFIG_FILE SYSCONFDIR "/mailutils.rc"
37 #endif
38
39 char *
40 mu_site_config_file (void)
41 {
42 char *p = getenv ("MU_SITE_CONFIG_FILE");
43 if (p)
44 return p;
45 return MU_SITE_CONFIG_FILE;
46 }
47
48
49 const char mu_version_copyright[] =
50 /* Do *not* mark this string for translation. %s is a copyright
51 symbol suitable for this locale, and %d is the copyright
52 year. */
53 "Copyright %s 2007-2016 Free Software Foundation, inc.";
54
55 void
56 mu_version_func (struct mu_parseopt *po, FILE *stream)
57 {
58 #ifdef GIT_DESCRIBE
59 fprintf (stream, "%s (%s) %s [%s]\n",
60 mu_program_name, PACKAGE_NAME, PACKAGE_VERSION, GIT_DESCRIBE);
61 #else
62 fprintf (stream, "%s (%s) %s\n", mu_program_name,
63 PACKAGE_NAME, PACKAGE_VERSION);
64 #endif
65 /* TRANSLATORS: Translate "(C)" to the copyright symbol
66 (C-in-a-circle), if this symbol is available in the user's
67 locale. Otherwise, do not translate "(C)"; leave it as-is. */
68 fprintf (stream, mu_version_copyright, _("(C)"));
69 fputs (_("\
70 \n\
71 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\
72 There is NO WARRANTY, to the extent permitted by law.\n\
73 \n\
74 "),
75 stream);
76 }
77
78 static char gnu_general_help_url[] =
79 N_("General help using GNU software: <http://www.gnu.org/gethelp/>");
80
81
82 static void
83 change_progname (struct mu_parseopt *po, struct mu_option *opt,
84 char const *arg)
85 {
86 po->po_prog_name = mu_strdup (arg);
87 }
88
89 static void
90 no_user_config (struct mu_parseopt *po, struct mu_option *opt,
91 char const *arg)
92 {
93 struct mu_cfg_parse_hints *hints = po->po_data;
94 hints->flags &= ~MU_CFG_PARSE_PROGRAM;
95 }
96
97 static void
98 no_site_config (struct mu_parseopt *po, struct mu_option *opt,
99 char const *arg)
100 {
101 struct mu_cfg_parse_hints *hints = po->po_data;
102 hints->flags &= ~MU_CFG_PARSE_SITE_RCFILE;
103 }
104
105 static void
106 config_file (struct mu_parseopt *po, struct mu_option *opt,
107 char const *arg)
108 {
109 struct mu_cfg_parse_hints *hints = po->po_data;
110 hints->flags |= MU_CFG_PARSE_CUSTOM_RCFILE;
111 hints->custom_rcfile = mu_strdup (arg);
112 }
113
114 static void
115 config_verbose (struct mu_parseopt *po, struct mu_option *opt,
116 char const *arg)
117 {
118 struct mu_cfg_parse_hints *hints = po->po_data;
119 if (hints->flags & MU_PARSE_CONFIG_VERBOSE)
120 hints->flags |= MU_PARSE_CONFIG_DUMP;
121 else
122 hints->flags |= MU_PARSE_CONFIG_VERBOSE;
123 }
124
125 static void
126 config_lint (struct mu_parseopt *po, struct mu_option *opt,
127 char const *arg)
128 {
129 struct mu_cfg_parse_hints *hints = po->po_data;
130 hints->flags |= MU_PARSE_CONFIG_VERBOSE|MU_PARSE_CONFIG_LINT;
131 }
132
133 static void
134 param_set (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
135 {
136 struct mu_cfg_parse_hints *hints = po->po_data;
137 mu_cfg_node_t *node;
138 int rc = mu_cfg_create_subtree (arg, &node);
139 if (rc)
140 mu_parseopt_error (po, "%s: cannot create node: %s",
141 arg, mu_strerror (rc));
142 if (!hints->append_tree)
143 mu_cfg_tree_create (&hints->append_tree);
144 mu_cfg_tree_add_node (hints->append_tree, node);
145 }
146
147 struct mu_option mu_common_options[] = {
148 MU_OPTION_GROUP(N_("Common options")),
149 { "program-name", 0, N_("NAME"), MU_OPTION_IMMEDIATE|MU_OPTION_HIDDEN,
150 N_("set program name"),
151 mu_c_string, NULL, change_progname },
152
153 { "no-user-config", 0, NULL, MU_OPTION_IMMEDIATE,
154 N_("do not load user configuration file"),
155 mu_c_string, NULL, no_user_config },
156 { "no-user-rcfile", 0, NULL, MU_OPTION_ALIAS },
157
158 { "no-site-config", 0, NULL, MU_OPTION_IMMEDIATE,
159 N_("do not load user configuration file"),
160 mu_c_string, NULL, no_site_config },
161 { "no-site-rcfile", 0, NULL, MU_OPTION_ALIAS },
162
163 { "config-file", 0, N_("FILE"), MU_OPTION_IMMEDIATE,
164 N_("load this configuration file"),
165 mu_c_string, NULL, config_file },
166 { "rcfile", 0, NULL, MU_OPTION_ALIAS },
167
168 { "config-verbose", 0, NULL, MU_OPTION_IMMEDIATE,
169 N_("verbosely log parsing of the configuration files"),
170 mu_c_string, NULL, config_verbose },
171 { "rcfile-verbose", 0, NULL, MU_OPTION_ALIAS },
172
173 { "config-lint", 0, NULL, MU_OPTION_IMMEDIATE,
174 N_("check configuration file syntax and exit"),
175 mu_c_string, NULL, config_lint },
176 { "rcfile-lint", 0, NULL, MU_OPTION_ALIAS },
177
178 { "set", 0, N_("PARAM=VALUE"), MU_OPTION_IMMEDIATE,
179 N_("set configuration parameter"),
180 mu_c_string, NULL, param_set },
181
182 MU_OPTION_END
183 };
184
185 static void
186 show_comp_defaults (struct mu_parseopt *po, struct mu_option *opt,
187 char const *unused)
188 {
189 mu_print_options ();
190 exit (0);
191 }
192
193 static void
194 show_config_help (struct mu_parseopt *po, struct mu_option *opt,
195 char const *unused)
196 {
197 struct mu_cfg_parse_hints *hints = po->po_data;
198
199 char *comment;
200 mu_stream_t stream;
201 struct mu_cfg_cont *cont;
202 static struct mu_cfg_param dummy_include_param[] = {
203 { "include", mu_c_string, NULL, 0, NULL,
204 N_("Include contents of the given file. If a directory is given, "
205 "include contents of the file <file>/<program>, where "
206 "<program> is the name of the program. This latter form is "
207 "allowed only in the site-wide configuration file."),
208 N_("file-or-directory") },
209 { NULL }
210 };
211
212 mu_stdio_stream_create (&stream, MU_STDOUT_FD, 0);
213
214 mu_asprintf (&comment,
215 "Configuration file structure for %s utility.",
216 po->po_prog_name);
217 mu_cfg_format_docstring (stream, comment, 0);
218 free (comment);
219
220 mu_asprintf (&comment,
221 "For use in global configuration file (%s), enclose it "
222 "in `program %s { ... };",
223 mu_site_config_file (),
224 po->po_prog_name);
225 mu_cfg_format_docstring (stream, comment, 0);
226 free (comment);
227
228 /* FIXME: %s should be replaced by the canonical utility name */
229 mu_asprintf (&comment, "For more information, use `info %s'.",
230 po->po_prog_name);
231 mu_cfg_format_docstring (stream, comment, 0);
232 free (comment);
233
234 cont = mu_config_clone_root_container ();
235 mu_config_container_register_section (&cont, NULL, NULL, NULL, NULL,
236 dummy_include_param, NULL);
237 if (hints->data)
238 mu_config_container_register_section (&cont, NULL, NULL, NULL, NULL,
239 hints->data, NULL);
240 mu_cfg_format_container (stream, cont);
241 mu_config_destroy_container (&cont);
242
243 mu_stream_destroy (&stream);
244 exit (0);
245 }
246
247 struct mu_option mu_extra_help_options[] = {
248 MU_OPTION_GROUP (N_("Informational options")),
249 { "show-config-options", 0, NULL, MU_OPTION_IMMEDIATE,
250 N_("show compilation options"),
251 mu_c_string, NULL, show_comp_defaults },
252 { "config-help", 0, NULL, MU_OPTION_IMMEDIATE,
253 N_("show configuration file summary"),
254 mu_c_string, NULL, show_config_help },
255 MU_OPTION_END
256 };
257
258
259 static int
260 add_opt_group (void *item, void *data)
261 {
262 struct mu_parseopt *po = data;
263 struct mu_option *opt = item;
264 po->po_optv[po->po_optc++] = opt;
265 return 0;
266 }
267
268 /* Build the list of option groups and configuration sections */
269 static struct mu_option **
270 init_options (char **capa, struct mu_cli_setup *setup,
271 mu_list_t *ret_comlist)
272 {
273 size_t i, s;
274 mu_list_t oplist;
275 struct mu_parseopt po;
276
277 mu_list_create (&oplist);
278 if (setup->optv)
279 {
280 for (i = 0; setup->optv[i]; i++)
281 mu_list_append (oplist, setup->optv[i]);
282 }
283 if (capa)
284 {
285 mu_list_t comlist;
286 mu_list_create (&comlist);
287 for (i = 0; capa[i]; i++)
288 mu_cli_capa_apply (capa[i], oplist, comlist);
289 *ret_comlist = comlist;
290 }
291 else
292 *ret_comlist = NULL;
293
294 mu_list_append (oplist, mu_common_options);
295 mu_list_append (oplist, mu_extra_help_options);
296
297 mu_list_count (oplist, &s);
298
299 po.po_optv = mu_calloc (s + 1, sizeof (po.po_optv[0]));
300 po.po_optc = 0;
301 mu_list_foreach (oplist, add_opt_group, &po);
302 if (po.po_optc != s)
303 abort ();
304 po.po_optv[po.po_optc] = NULL;
305 mu_list_destroy (&oplist);
306 return po.po_optv;
307 }
308
309 static int
310 run_commit (void *item, void *data)
311 {
312 mu_cli_capa_commit_fp commit = item;
313 commit (data);
314 return 0;
315 }
316
317 void
318 mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa,
319 void *data,
320 int *ret_argc, char ***ret_argv)
321 {
322 struct mu_parseopt po;
323 int flags = 0;
324 struct mu_cfg_tree *parse_tree = NULL;
325 struct mu_cfg_parse_hints hints;
326 struct mu_option **optv;
327 mu_list_t com_list;
328
329 /* Set program name */
330 mu_set_program_name (argv[0]);
331
332 if (!mu_log_tag)
333 mu_log_tag = (char*)mu_program_name;
334
335 /* Initialize standard streams */
336 mu_stdstream_setup (MU_STDSTREAM_RESET_NONE);
337
338 /* Initialize standard capabilities */
339 mu_cli_capa_init ();
340
341 /* Initialize hints */
342 memset (&hints, 0, sizeof (hints));
343 hints.flags |= MU_CFG_PARSE_SITE_RCFILE;
344 hints.site_rcfile = mu_site_config_file ();
345
346 hints.flags |= MU_CFG_PARSE_PROGRAM;
347 hints.program = (char*) mu_program_name;
348
349 hints.data = setup->cfg;
350
351 /* Initialize po */
352 if (setup->prog_doc)
353 {
354 po.po_prog_doc = setup->prog_doc;
355 flags |= MU_PARSEOPT_PROG_DOC;
356 }
357
358 if (setup->prog_args)
359 {
360 po.po_prog_args = setup->prog_args;
361 flags |= MU_PARSEOPT_PROG_ARGS;
362 }
363
364 po.po_package_name = PACKAGE_NAME;
365 flags |= MU_PARSEOPT_PACKAGE_NAME;
366
367 po.po_package_url = PACKAGE_URL;
368 flags |= MU_PARSEOPT_PACKAGE_URL;
369
370 po.po_bug_address = PACKAGE_BUGREPORT;
371 flags |= MU_PARSEOPT_BUG_ADDRESS;
372
373 po.po_extra_info = gnu_general_help_url;
374 flags |= MU_PARSEOPT_EXTRA_INFO;
375
376 po.po_version_hook = mu_version_func;
377 flags |= MU_PARSEOPT_VERSION_HOOK;
378
379 po.po_data = &hints;
380 flags |= MU_PARSEOPT_DATA;
381
382 po.po_exit_error = EX_USAGE;
383
384 optv = init_options (capa, setup, &com_list);
385
386 if (mu_parseopt (&po, argc, argv, optv, flags))
387 exit (EX_USAGE);
388
389 argc -= po.po_arg_start;
390 argv += po.po_arg_start;
391
392 if (ret_argc)
393 {
394 *ret_argc = argc;
395 *ret_argv = argv;
396 }
397 else if (argc)
398 mu_parseopt_error (&po, "%s", _("unexpected arguments"));
399
400 if (mu_cfg_parse_config (&parse_tree, &hints))
401 exit (EX_CONFIG);
402
403 if (mu_cfg_tree_reduce (parse_tree, &hints, setup->cfg, data))
404 exit (EX_CONFIG);
405
406 if (mu_cfg_error_count) //FIXME
407 exit (EX_CONFIG);
408
409 mu_parseopt_apply (&po);
410
411 mu_list_foreach (com_list, run_commit, NULL);
412 mu_list_destroy (&com_list);
413
414 if (hints.flags & MU_PARSE_CONFIG_LINT)
415 exit (0);
416
417 mu_cfg_destroy_tree (&parse_tree);
418 free (optv);
419 mu_parseopt_free (&po);
420 }
1 /* stdcapa.c -- Standard CLI capabilities for GNU Mailutils
2 Copyright (C) 2016 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 3, or (at
7 your option) any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
16 */
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20 #include <stdlib.h>
21 #include <mailutils/cli.h>
22 #include <mailutils/cfg.h>
23 #include <mailutils/nls.h>
24 #include <mailutils/syslog.h>
25 #include <mailutils/stdstream.h>
26 #include <mailutils/mailer.h>
27 #include <mailutils/errno.h>
28 #include <mailutils/mailbox.h>
29 #include <mailutils/registrar.h>
30 #include <mailutils/locker.h>
31
32 /* *************************************************************************
33 * Logging section
34 * ************************************************************************* */
35 static void
36 cli_log_facility (struct mu_parseopt *po, struct mu_option *opt,
37 char const *arg)
38 {
39 if (mu_string_to_syslog_facility (arg, &mu_log_facility))
40 mu_parseopt_error (po, _("unknown syslog facility `%s'"), arg);
41 }
42
43 static int
44 cb_facility (void *data, mu_config_value_t *val)
45 {
46 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
47 return 1;
48
49 if (mu_string_to_syslog_facility (val->v.string, &mu_log_facility))
50 {
51 mu_error (_("unknown syslog facility `%s'"), val->v.string);
52 return 1;
53 }
54 return 0;
55 }
56
57 static int
58 cb_severity (void *data, mu_config_value_t *val)
59 {
60 unsigned n;
61
62 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
63 return 1;
64 if (mu_severity_from_string (val->v.string, &n))
65 {
66 mu_error (_("unknown severity `%s'"), val->v.string);
67 return 1;
68 }
69 mu_log_severity_threshold = n;
70 return 0;
71 }
72
73 static struct mu_cfg_param logging_cfg[] = {
74 { "syslog", mu_c_bool, &mu_log_syslog, 0, NULL,
75 N_("Send diagnostics to syslog.") },
76 { "print-severity", mu_c_bool, &mu_log_print_severity, 0, NULL,
77 N_("Print message severity levels.") },
78 { "severity", mu_cfg_callback, NULL, 0, cb_severity,
79 N_("Output only messages with a severity equal to or greater than "
80 "this one."),
81 N_("arg: string")},
82 { "facility", mu_cfg_callback, NULL, 0, cb_facility,
83 N_("Set syslog facility. Arg is one of the following: user, daemon, "
84 "auth, authpriv, mail, cron, local0 through local7 (case-insensitive), "
85 "or a facility number."),
86 N_("arg: string") },
87 { "session-id", mu_c_bool, &mu_log_session_id, 0, NULL,
88 N_("Log session ID") },
89 { "tag", mu_c_string, &mu_log_tag, 0, NULL,
90 N_("Tag syslog messages with this string.") },
91 { NULL }
92 };
93
94 static struct mu_option logging_option[] = {
95 { "log-facility", 0, N_("FACILITY"), MU_OPTION_DEFAULT,
96 N_("output logs to syslog FACILITY"),
97 mu_c_int, &mu_log_facility, cli_log_facility },
98 MU_OPTION_END
99 };
100
101 static void
102 logging_commit (void *unused)
103 {
104 if (mu_log_syslog >= 0)
105 mu_stdstream_strerr_setup (mu_log_syslog ?
106 MU_STRERR_SYSLOG : MU_STRERR_STDERR);
107 }
108
109 /* *************************************************************************
110 * Mailer
111 * ************************************************************************* */
112 static void
113 cli_mailer (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
114 {
115 int rc = mu_mailer_set_url_default (arg);
116 if (rc != 0)
117 mu_parseopt_error (po, _("invalid mailer URL `%s': %s"),
118 arg, mu_strerror (rc));
119 }
120
121 static struct mu_option mailer_option[] = {
122 { "mailer", 'M', N_("MAILER"), MU_OPTION_DEFAULT,
123 N_("use specified URL as the default mailer"),
124 mu_c_string, NULL, cli_mailer },
125 MU_OPTION_END
126 };
127
128 static int
129 cb_mailer (void *data, mu_config_value_t *val)
130 {
131 int rc;
132
133 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
134 return 1;
135 rc = mu_mailer_set_url_default (val->v.string);
136 if (rc != 0)
137 mu_error (_("%s: invalid mailer URL: %s"),
138 val->v.string, mu_strerror (rc));
139 return rc;
140 }
141
142 static struct mu_cfg_param mailer_cfg[] = {
143 { "url", mu_cfg_callback, NULL, 0, cb_mailer,
144 N_("Use this URL as the default mailer"),
145 N_("url: string") },
146 { NULL }
147 };
148
149 /* *************************************************************************
150 * Debugging
151 * ************************************************************************* */
152 static void
153 cli_debug_level (struct mu_parseopt *po, struct mu_option *opt,
154 char const *arg)
155 {
156 mu_debug_clear_all ();
157 mu_debug_parse_spec (arg);
158 /* FIXME: Error handling */
159 }
160
161 static struct mu_option debug_option[] = {
162 MU_OPTION_GROUP (N_("Global debugging settings")),
163 { "debug-level", 0, N_("LEVEL"), MU_OPTION_DEFAULT,
164 N_("set Mailutils debugging level"),
165 mu_c_string, NULL, cli_debug_level },
166 { "debug-line-info", 0, NULL, MU_OPTION_DEFAULT,
167 N_("show source info with debugging messages"),
168 mu_c_bool, &mu_debug_line_info },
169 MU_OPTION_END
170 };
171
172 static int
173 cb_debug_level (void *data, mu_config_value_t *val)
174 {
175 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
176 return 1;
177 mu_debug_parse_spec (val->v.string);
178 return 0;
179 }
180
181 static struct mu_cfg_param debug_cfg[] = {
182 { "level", mu_cfg_callback, NULL, 0, &cb_debug_level,
183 N_("Set Mailutils debugging level. Argument is a colon-separated list "
184 "of debugging specifications in the form:\n"
185 " <object: string>[[:]=<level: number>]."),
186 N_("arg: string") },
187 { "line-info", mu_c_bool, &mu_debug_line_info, 0, NULL,
188 N_("Prefix debug messages with Mailutils source locations.") },
189 { NULL }
190 };
191
192 /* ************************************************************************* *
193 * Mailbox *
194 * ************************************************************************* */
195
196 static int
197 cb_mail_spool (void *data, mu_config_value_t *val)
198 {
199 int rc;
200 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
201 return 1;
202 rc = mu_set_mail_directory (val->v.string);
203 if (rc)
204 mu_error (_("cannot set mail directory name to `%s': %s"),
205 val->v.string, mu_strerror (rc));
206 return rc;
207 }
208
209 static int
210 cb_mailbox_pattern (void *data, mu_config_value_t *val)
211 {
212 int rc;
213 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
214 return 1;
215
216 rc = mu_set_mailbox_pattern (val->v.string);
217 if (rc)
218 mu_error (_("cannot set mailbox pattern to `%s': %s"),
219 val->v.string, mu_strerror (rc));
220 return rc;
221 }
222
223 static int
224 cb_mailbox_type (void *data, mu_config_value_t *val)
225 {
226 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
227 return 1;
228 if (mu_registrar_set_default_scheme (val->v.string))
229 mu_error (_("invalid mailbox type: %s"), val->v.string);
230 return 0;
231 }
232
233 static int
234 cb_folder (void *data, mu_config_value_t *val)
235 {
236 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
237 return 1;
238 mu_set_folder_directory (val->v.string);
239 return 0;
240 }
241
242 static struct mu_cfg_param mailbox_cfg[] = {
243 { "mail-spool", mu_cfg_callback, NULL, 0, cb_mail_spool,
244 N_("Use specified URL as a mailspool directory."),
245 N_("url: string") },
246 { "mailbox-pattern", mu_cfg_callback, NULL, 0, cb_mailbox_pattern,
247 N_("Create mailbox URL using <pattern>."),
248 N_("pattern: string") },
249 { "mailbox-type", mu_cfg_callback, NULL, 0, cb_mailbox_type,
250 N_("Default mailbox type."),
251 N_("protocol: string") },
252 { "folder", mu_cfg_callback, NULL, 0, cb_folder,
253 N_("Default user mail folder"),
254 N_("dir: string") },
255 { NULL }
256 };
257
258 /* ************************************************************************* *
259 * Locking *
260 * ************************************************************************* */
261 static int
262 cb_locker_flags (void *data, mu_config_value_t *val)
263 {
264 int flags = 0;
265 char const *s;
266
267 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
268 return 1;
269
270 for (s = val->v.string; *s; s++)
271 {
272 switch (*s)
273 {
274 case 'E':
275 flags |= MU_LOCKER_EXTERNAL;
276 break;
277
278 case 'R':
279 flags |= MU_LOCKER_RETRY;
280 break;
281
282 case 'T':
283 flags |= MU_LOCKER_TIME;
284 break;
285
286 case 'P':
287 flags |= MU_LOCKER_PID;
288 break;
289
290 default:
291 mu_error (_("invalid lock flag `%c'"), *s);
292 }
293 }
294 mu_locker_set_default_flags (flags, mu_locker_assign);
295 return 0;
296 }
297
298 static int
299 cb_locker_retry_timeout (void *data, mu_config_value_t *val)
300 {
301 int rc;
302 time_t t;
303 char *errmsg;
304
305 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
306 return 1;
307 rc = mu_str_to_c (val->v.string, mu_c_time, &t, &errmsg);
308 if (rc)
309 {
310 mu_error (_("conversion failed: %s"), errmsg ? errmsg :
311 mu_strerror (rc));
312 free (errmsg);
313 }
314 else
315 {
316 mu_locker_set_default_retry_timeout (t);
317 mu_locker_set_default_flags (MU_LOCKER_RETRY, mu_locker_set_bit);
318 }
319 return 0;
320 }
321
322 static int
323 cb_locker_retry_count (void *data, mu_config_value_t *val)
324 {
325 int rc;
326 size_t n;
327 char *errmsg;
328
329 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
330 return 1;
331 rc = mu_str_to_c (val->v.string, mu_c_size, &n, &errmsg);
332 if (rc)
333 {
334 mu_error (_("conversion failed: %s"), errmsg ? errmsg :
335 mu_strerror (rc));
336 free (errmsg);
337 }
338 else
339 {
340 mu_locker_set_default_retry_count (n);
341 mu_locker_set_default_flags (MU_LOCKER_RETRY, mu_locker_set_bit);
342 }
343 return 0;
344 }
345
346 static int
347 cb_locker_expire_timeout (void *data, mu_config_value_t *val)
348 {
349 int rc;
350 time_t t;
351 char *errmsg;
352
353 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
354 return 1;
355 rc = mu_str_to_c (val->v.string, mu_c_time, &t, &errmsg);
356 if (rc)
357 {
358 mu_error (_("conversion failed: %s"), errmsg ? errmsg :
359 mu_strerror (rc));
360 free (errmsg);
361 }
362 else
363 {
364 mu_locker_set_default_expire_timeout (t);
365 mu_locker_set_default_flags (MU_LOCKER_EXTERNAL, mu_locker_set_bit);
366 }
367 return 0;
368 }
369
370 static int
371 cb_locker_external (void *data, mu_config_value_t *val)
372 {
373 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
374 return 1;
375 mu_locker_set_default_external_program (val->v.string);
376 mu_locker_set_default_flags (MU_LOCKER_TIME, mu_locker_set_bit);
377 return 0;
378 }
379
380 static struct mu_cfg_param locking_cfg[] = {
381 /* FIXME: Flags are superfluous. */
382 { "flags", mu_cfg_callback, NULL, 0, cb_locker_flags,
383 N_("Default locker flags (E=external, R=retry, T=time, P=pid)."),
384 N_("arg: string") },
385 { "retry-timeout", mu_cfg_callback, NULL, 0, cb_locker_retry_timeout,
386 N_("Set timeout for acquiring the lock."),
387 N_("arg: interval")},
388 { "retry-count", mu_cfg_callback, NULL, 0, cb_locker_retry_count,
389 N_("Set the maximum number of times to retry acquiring the lock."),
390 N_("arg: integer") },
391 { "expire-timeout", mu_cfg_callback, NULL, 0, cb_locker_expire_timeout,
392 N_("Expire locks older than this amount of time."),
393 N_("arg: interval")},
394 { "external-locker", mu_cfg_callback, NULL, 0, cb_locker_external,
395 N_("Use external locker program."),
396 N_("prog: string") },
397 { NULL, }
398 };
399
400 /* ************************************************************************* *
401 * Address *
402 * ************************************************************************* */
403 static int
404 cb_email_addr (void *data, mu_config_value_t *val)
405 {
406 int rc;
407
408 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
409 return 1;
410
411 rc = mu_set_user_email (val->v.string);
412 if (rc)
413 mu_error (_("invalid email address `%s': %s"),
414 val->v.string, mu_strerror (rc));
415 return 0;
416 }
417
418 static int
419 cb_email_domain (void *data, mu_config_value_t *val)
420 {
421 int rc;
422
423 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
424 return 1;
425
426 rc = mu_set_user_email_domain (val->v.string);
427 if (rc)
428 mu_error (_("invalid email domain `%s': %s"),
429 val->v.string, mu_strerror (rc));
430 return 0;
431 }
432
433 static struct mu_cfg_param address_cfg[] = {
434 { "email-addr", mu_cfg_callback, NULL, 0, cb_email_addr,
435 N_("Set the current user email address (default is "
436 "loginname@defaultdomain)."),
437 N_("email: address") },
438 { "email-domain", mu_cfg_callback, NULL, 0, cb_email_domain,
439 N_("Set e-mail domain for unqualified user names (default is this host)"),
440 N_("domain: string") },
441 { NULL }
442 };
443
444
445 /* ************************************************************************* *
446 * Registry of standard mailutils' capabilities *
447 * ************************************************************************* */
448 struct mu_cli_capa mu_cli_std_capa[] = {
449 { "mailutils" }, /* Dummy */
450 { "logging", logging_option, logging_cfg, NULL, logging_commit },
451 { "mailer", mailer_option, mailer_cfg, NULL, NULL },
452 { "debug", debug_option, debug_cfg, NULL, NULL },
453 { "mailbox", NULL, mailbox_cfg, NULL, NULL },
454 { "locking", NULL, locking_cfg, NULL, NULL },
455 { "address", NULL, address_cfg, NULL, NULL },
456 { NULL }
457 };
458
459 void
460 mu_cli_capa_init (void)
461 {
462 size_t i;
463
464 for (i = 0; mu_cli_std_capa[i].name; i++)
465 mu_cli_capa_register (&mu_cli_std_capa[i]);
466 }
...@@ -30,32 +30,6 @@ ...@@ -30,32 +30,6 @@
30 #include <mailutils/stdstream.h> 30 #include <mailutils/stdstream.h>
31 #include <mailutils/stream.h> 31 #include <mailutils/stream.h>
32 32
33 const char *mu_program_name;
34 const char *mu_full_program_name;
35
36 void
37 mu_set_program_name (const char *name)
38 {
39 const char *progname;
40
41 mu_full_program_name = name;
42 if (!name)
43 progname = name;
44 else
45 {
46 progname = strrchr (name, '/');
47 if (progname)
48 progname++;
49 else
50 progname = name;
51
52 if (strlen (progname) > 3 && memcmp (progname, "lt-", 3) == 0)
53 progname += 3;
54 }
55
56 mu_program_name = progname;
57 }
58
59 void 33 void
60 mu_diag_init () 34 mu_diag_init ()
61 { 35 {
......
...@@ -155,7 +155,7 @@ init_usage_vars (struct mu_parseopt *po) ...@@ -155,7 +155,7 @@ init_usage_vars (struct mu_parseopt *po)
155 fmt = getenv ("ARGP_HELP_FMT"); 155 fmt = getenv ("ARGP_HELP_FMT");
156 if (!fmt) 156 if (!fmt)
157 return; 157 return;
158 ws.ws_delim=","; 158 ws.ws_delim = ",";
159 if (mu_wordsplit (fmt, &ws, 159 if (mu_wordsplit (fmt, &ws,
160 MU_WRDSF_DELIM | MU_WRDSF_NOVAR | MU_WRDSF_NOCMD 160 MU_WRDSF_DELIM | MU_WRDSF_NOVAR | MU_WRDSF_NOCMD
161 | MU_WRDSF_WS | MU_WRDSF_SHOWERR)) 161 | MU_WRDSF_WS | MU_WRDSF_SHOWERR))
...@@ -346,20 +346,20 @@ mu_program_help (struct mu_parseopt *po) ...@@ -346,20 +346,20 @@ mu_program_help (struct mu_parseopt *po)
346 mu_option_describe_options (po->po_optv, po->po_optc); 346 mu_option_describe_options (po->po_optv, po->po_optc);
347 347
348 if (po->po_help_hook) 348 if (po->po_help_hook)
349 po->po_help_hook (stdout); 349 po->po_help_hook (po, stdout);
350 350
351 if (po->po_bug_address) 351 if (po->po_bug_address)
352 /* TRANSLATORS: The placeholder indicates the bug-reporting address 352 /* TRANSLATORS: The placeholder indicates the bug-reporting address
353 for this package. Please add _another line_ saying 353 for this package. Please add _another line_ saying
354 "Report translation bugs to <...>\n" with the address for translation 354 "Report translation bugs to <...>\n" with the address for translation
355 bugs (typically your translation team's web or email address). */ 355 bugs (typically your translation team's web or email address). */
356 printf (_("Report bugs to %s.\n"), po->po_bug_address); 356 printf (_("Report bugs to <%s>.\n"), po->po_bug_address);
357 357
358 if (po->po_package_name && po->po_package_url) 358 if (po->po_package_name && po->po_package_url)
359 printf (_("%s home page: <%s>\n"), 359 printf (_("%s home page: <%s>\n"),
360 po->po_package_name, po->po_package_url); 360 po->po_package_name, po->po_package_url);
361 if (po->po_flags & MU_PARSEOPT_EXTRA_INFO) 361 if (po->po_flags & MU_PARSEOPT_EXTRA_INFO)
362 print_option_descr (po->po_extra_info, 0, rmargin); 362 print_option_descr (_(po->po_extra_info), 0, rmargin);
363 } 363 }
364 364
365 static struct mu_option **option_tab; 365 static struct mu_option **option_tab;
......
...@@ -85,7 +85,7 @@ fn_usage (struct mu_parseopt *po, struct mu_option *opt, char const *unused) ...@@ -85,7 +85,7 @@ fn_usage (struct mu_parseopt *po, struct mu_option *opt, char const *unused)
85 static void 85 static void
86 fn_version (struct mu_parseopt *po, struct mu_option *opt, char const *unused) 86 fn_version (struct mu_parseopt *po, struct mu_option *opt, char const *unused)
87 { 87 {
88 po->po_version_hook (stdout); 88 po->po_version_hook (po, stdout);
89 exit (EXIT_SUCCESS); 89 exit (EXIT_SUCCESS);
90 } 90 }
91 91
...@@ -107,8 +107,8 @@ struct mu_option mu_version_options[] = { ...@@ -107,8 +107,8 @@ struct mu_option mu_version_options[] = {
107 }; 107 };
108 108
109 /* Output error message */ 109 /* Output error message */
110 static void 110 void
111 parse_error (struct mu_parseopt *po, char const *fmt, ...) 111 mu_parseopt_error (struct mu_parseopt *po, char const *fmt, ...)
112 { 112 {
113 va_list ap; 113 va_list ap;
114 114
...@@ -176,7 +176,7 @@ find_short_option (struct mu_parseopt *po, int chr) ...@@ -176,7 +176,7 @@ find_short_option (struct mu_parseopt *po, int chr)
176 && po->po_optv[i]->opt_short == chr) 176 && po->po_optv[i]->opt_short == chr)
177 return option_unalias (po, i); 177 return option_unalias (po, i);
178 } 178 }
179 parse_error (po, _("unrecognized option '-%c'"), chr); 179 mu_parseopt_error (po, _("unrecognized option '-%c'"), chr);
180 return NULL; 180 return NULL;
181 } 181 }
182 182
...@@ -209,7 +209,7 @@ find_long_option (struct mu_parseopt *po, char const *optstr, ...@@ -209,7 +209,7 @@ find_long_option (struct mu_parseopt *po, char const *optstr,
209 case 1: 209 case 1:
210 if (po->po_flags & MU_PARSEOPT_IGNORE_ERRORS) 210 if (po->po_flags & MU_PARSEOPT_IGNORE_ERRORS)
211 return NULL; 211 return NULL;
212 parse_error (po, 212 mu_parseopt_error (po,
213 _("option '--%*.*s' is ambiguous; possibilities:"), 213 _("option '--%*.*s' is ambiguous; possibilities:"),
214 optlen, optlen, optstr); 214 optlen, optlen, optstr);
215 fprintf (stderr, "--%s\n", po->po_optv[ind]->opt_long); 215 fprintf (stderr, "--%s\n", po->po_optv[ind]->opt_long);
...@@ -224,7 +224,7 @@ find_long_option (struct mu_parseopt *po, char const *optstr, ...@@ -224,7 +224,7 @@ find_long_option (struct mu_parseopt *po, char const *optstr,
224 switch (found) 224 switch (found)
225 { 225 {
226 case 0: 226 case 0:
227 parse_error (po, _("unrecognized option '--%s'"), optstr); 227 mu_parseopt_error (po, _("unrecognized option '--%s'"), optstr);
228 break; 228 break;
229 229
230 case 1: 230 case 1:
...@@ -303,7 +303,7 @@ next_opt (struct mu_parseopt *po) ...@@ -303,7 +303,7 @@ next_opt (struct mu_parseopt *po)
303 break; 303 break;
304 if (!(po->po_flags & MU_PARSEOPT_IN_ORDER)) 304 if (!(po->po_flags & MU_PARSEOPT_IN_ORDER))
305 { 305 {
306 if (!po->po_permuted) 306 if (!po->po_permuted && po->po_arg_count == 0)
307 po->po_arg_start = po->po_ind - 1; 307 po->po_arg_start = po->po_ind - 1;
308 po->po_arg_count++; 308 po->po_arg_count++;
309 continue; 309 continue;
...@@ -405,11 +405,11 @@ parse (struct mu_parseopt *po) ...@@ -405,11 +405,11 @@ parse (struct mu_parseopt *po)
405 else 405 else
406 { 406 {
407 if (long_opt) 407 if (long_opt)
408 parse_error (po, 408 mu_parseopt_error (po,
409 _("option '--%s' requires an argument"), 409 _("option '--%s' requires an argument"),
410 long_opt); 410 long_opt);
411 else 411 else
412 parse_error (po, 412 mu_parseopt_error (po,
413 _("option '-%c' requires an argument"), 413 _("option '-%c' requires an argument"),
414 po->po_chr); 414 po->po_chr);
415 po->po_opterr = po->po_ind; 415 po->po_opterr = po->po_ind;
...@@ -428,7 +428,7 @@ parse (struct mu_parseopt *po) ...@@ -428,7 +428,7 @@ parse (struct mu_parseopt *po)
428 && po->po_cur[0] 428 && po->po_cur[0]
429 && !(po->po_flags & MU_OPTION_ARG_OPTIONAL)) 429 && !(po->po_flags & MU_OPTION_ARG_OPTIONAL))
430 { 430 {
431 parse_error (po, 431 mu_parseopt_error (po,
432 _("option '--%s' doesn't allow an argument"), 432 _("option '--%s' doesn't allow an argument"),
433 long_opt); 433 long_opt);
434 po->po_opterr = po->po_ind; 434 po->po_opterr = po->po_ind;
...@@ -661,9 +661,9 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt, ...@@ -661,9 +661,9 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt,
661 errtext = mu_strerror (rc); 661 errtext = mu_strerror (rc);
662 662
663 if (opt->opt_long) 663 if (opt->opt_long)
664 parse_error (po, "--%s: %s", opt->opt_long, errtext); 664 mu_parseopt_error (po, "--%s: %s", opt->opt_long, errtext);
665 else 665 else
666 parse_error (po, "-%c: %s", opt->opt_short, errtext); 666 mu_parseopt_error (po, "-%c: %s", opt->opt_short, errtext);
667 free (errmsg); 667 free (errmsg);
668 668
669 if (!(po->po_flags & MU_PARSEOPT_NO_ERREXIT)) 669 if (!(po->po_flags & MU_PARSEOPT_NO_ERREXIT))
......
...@@ -22,16 +22,16 @@ ...@@ -22,16 +22,16 @@
22 #include <mailutils/alloc.h> 22 #include <mailutils/alloc.h>
23 #include <mailutils/opt.h> 23 #include <mailutils/opt.h>
24 24
25 char *mu_progname; 25 char *mu_program_name;
26 char *mu_absprogname; 26 char *mu_full_program_name;
27 27
28 void 28 void
29 mu_set_progname (char const *arg) 29 mu_set_program_name (const char *arg)
30 { 30 {
31 char *p; 31 char *p;
32 32
33 free (mu_absprogname); 33 free (mu_full_program_name);
34 mu_absprogname = mu_strdup (arg); 34 mu_full_program_name = mu_strdup (arg);
35 35
36 p = strrchr (arg, '/'); 36 p = strrchr (arg, '/');
37 if (p) 37 if (p)
...@@ -40,6 +40,6 @@ mu_set_progname (char const *arg) ...@@ -40,6 +40,6 @@ mu_set_progname (char const *arg)
40 p = (char*) arg; 40 p = (char*) arg;
41 if (strlen (p) > 3 && memcmp (p, "lt-", 3) == 0) 41 if (strlen (p) > 3 && memcmp (p, "lt-", 3) == 0)
42 p += 3; 42 p += 3;
43 free (mu_progname); 43 free (mu_program_name);
44 mu_progname = mu_strdup (p); 44 mu_program_name = mu_strdup (p);
45 } 45 }
......
...@@ -27,6 +27,7 @@ strftime ...@@ -27,6 +27,7 @@ strftime
27 strin 27 strin
28 strout 28 strout
29 strtoc 29 strtoc
30 tcli
30 tempfile 31 tempfile
31 url-comp 32 url-comp
32 url-parse 33 url-parse
......
...@@ -64,6 +64,7 @@ noinst_PROGRAMS = \ ...@@ -64,6 +64,7 @@ noinst_PROGRAMS = \
64 strout\ 64 strout\
65 strtoc\ 65 strtoc\
66 tempfile\ 66 tempfile\
67 tcli\
67 url-comp\ 68 url-comp\
68 url-parse\ 69 url-parse\
69 wicket\ 70 wicket\
......
...@@ -64,7 +64,7 @@ struct mu_option group_b[] = { ...@@ -64,7 +64,7 @@ struct mu_option group_b[] = {
64 struct mu_option *optv[] = { group_a, group_b, NULL }; 64 struct mu_option *optv[] = { group_a, group_b, NULL };
65 65
66 static void 66 static void
67 version_func (FILE *fp) 67 version_hook (struct mu_parseopt *po, FILE *fp)
68 { 68 {
69 fputs ("version hook called\n", fp); 69 fputs ("version hook called\n", fp);
70 } 70 }
...@@ -144,7 +144,7 @@ main (int argc, char *argv[]) ...@@ -144,7 +144,7 @@ main (int argc, char *argv[])
144 } 144 }
145 } 145 }
146 if (flags & MU_PARSEOPT_VERSION_HOOK) 146 if (flags & MU_PARSEOPT_VERSION_HOOK)
147 po.po_version_hook = version_func; 147 po.po_version_hook = version_hook;
148 } 148 }
149 149
150 rc = mu_parseopt (&po, argc, argv, optv, flags); 150 rc = mu_parseopt (&po, argc, argv, optv, flags);
......
...@@ -35,4 +35,24 @@ argv: ...@@ -35,4 +35,24 @@ argv:
35 2: follow 35 2: follow
36 3: options 36 3: options
37 ]) 37 ])
38
39 AT_CHECK([
40 PARSEOPT_DEFAULT
41 parseopt --file=file more arguments follow -x -o options
42 ],
43 [0],
44 [rc=0
45 file_name=file
46 opt_value=(null)
47 x_option=1
48 a_option=0
49 find_value=(null)
50 d_option=0
51 jobs=0
52 argv:
53 0: more
54 1: arguments
55 2: follow
56 3: options
57 ])
38 AT_CLEANUP 58 AT_CLEANUP
......
...@@ -18,7 +18,7 @@ AT_SETUP([MU_PARSEOPT_BUG_ADDRESS]) ...@@ -18,7 +18,7 @@ AT_SETUP([MU_PARSEOPT_BUG_ADDRESS])
18 AT_KEYWORDS([parseopt parseopt_help parseopt_help05]) 18 AT_KEYWORDS([parseopt parseopt_help parseopt_help05])
19 AT_CHECK([ 19 AT_CHECK([
20 PARSEOPT_DEFAULT 20 PARSEOPT_DEFAULT
21 MU_PARSEOPT_BUG_ADDRESS='<gray@gnu.org>' parseopt --help 21 MU_PARSEOPT_BUG_ADDRESS='gray@gnu.org' parseopt --help
22 ], 22 ],
23 [0], 23 [0],
24 [Usage: parseopt [[OPTION]]... 24 [Usage: parseopt [[OPTION]]...
......
...@@ -20,7 +20,7 @@ AT_CHECK([ ...@@ -20,7 +20,7 @@ AT_CHECK([
20 PARSEOPT_DEFAULT 20 PARSEOPT_DEFAULT
21 MU_PARSEOPT_PROG_DOC="Tests option parsing"\ 21 MU_PARSEOPT_PROG_DOC="Tests option parsing"\
22 MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS"\ 22 MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS"\
23 MU_PARSEOPT_BUG_ADDRESS='<gray@gnu.org>'\ 23 MU_PARSEOPT_BUG_ADDRESS='gray@gnu.org'\
24 MU_PARSEOPT_PACKAGE_NAME='GNU Mailutils'\ 24 MU_PARSEOPT_PACKAGE_NAME='GNU Mailutils'\
25 MU_PARSEOPT_PACKAGE_URL='http://mailutils.org'\ 25 MU_PARSEOPT_PACKAGE_URL='http://mailutils.org'\
26 MU_PARSEOPT_EXTRA_INFO='General help using GNU software: <http://www.gnu.org/gethelp/>'\ 26 MU_PARSEOPT_EXTRA_INFO='General help using GNU software: <http://www.gnu.org/gethelp/>'\
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2016 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20 #include <mailutils/mailutils.h>
21 #include <mailutils/cli.h>
22
23 int dtrt_option;
24
25 struct mu_option group_a[] = {
26 { "dtrt", 'd', "VALUE", MU_OPTION_DEFAULT,
27 "do the right thing",
28 mu_c_int, &dtrt_option },
29 MU_OPTION_END
30 };
31
32 struct mu_option *options[] = { group_a, NULL };
33
34 static struct mu_cfg_param config[] = {
35 { "do-the-right-thing", mu_c_int, &dtrt_option, 0, NULL,
36 "do the right thing" },
37 { NULL }
38 };
39
40 struct mu_cli_setup cli = {
41 options,
42 config,
43 "Tests standard command line interface",
44 "ARGUMENTS"
45 };
46
47 static char **
48 getcapa (void)
49 {
50 struct mu_wordsplit ws;
51 char *p;
52
53 p = getenv ("MU_CLI_CAPA");
54 if (!p)
55 return NULL;
56 ws.ws_delim = ",";
57 if (mu_wordsplit (p, &ws,
58 MU_WRDSF_DELIM | MU_WRDSF_NOVAR | MU_WRDSF_NOCMD
59 | MU_WRDSF_WS | MU_WRDSF_SHOWERR))
60 exit (1);
61 return ws.ws_wordv;
62 }
63
64 int
65 main (int argc, char **argv)
66 {
67 int i;
68
69 mu_cli (argc, argv, &cli, getcapa (), NULL, &argc, &argv);
70 printf ("DTRT=%d\n", dtrt_option);
71 printf ("%d arguments:\n", argc);
72 for (i = 0; i < argc; i++)
73 printf ("%d: %s\n", i, argv[i]);
74 return 0;
75 }
...@@ -19,22 +19,27 @@ ...@@ -19,22 +19,27 @@
19 #ifdef HAVE_CONFIG_H 19 #ifdef HAVE_CONFIG_H
20 # include <config.h> 20 # include <config.h>
21 #endif 21 #endif
22 #include <stdlib.h>
22 #include <sieve-priv.h> 23 #include <sieve-priv.h>
23 #include <string.h> 24 #include <string.h>
25 #include <mailutils/cli.h>
24 26
25 mu_list_t mu_sieve_include_path = NULL; 27 mu_list_t mu_sieve_include_path = NULL;
26 mu_list_t mu_sieve_library_path = NULL; 28 mu_list_t mu_sieve_library_path = NULL;
27 mu_list_t mu_sieve_library_path_prefix = NULL; 29 mu_list_t mu_sieve_library_path_prefix = NULL;
28
29 mu_debug_handle_t mu_sieve_debug_handle; 30 mu_debug_handle_t mu_sieve_debug_handle;
30 31
32 //FIXME: provide definition (from gocs.h)
33 static struct mu_gocs_sieve sieve_settings;
34
31 void 35 void
32 mu_sieve_debug_init () 36 mu_sieve_debug_init (void)
33 { 37 {
34 if (!mu_sieve_debug_handle) 38 if (!mu_sieve_debug_handle)
35 mu_sieve_debug_handle = mu_debug_register_category ("sieve"); 39 mu_sieve_debug_handle = mu_debug_register_category ("sieve");
36 } 40 }
37 41
42 /*FIXME: REMOVE BEGIN */
38 static int 43 static int
39 _path_append (void *item, void *data) 44 _path_append (void *item, void *data)
40 { 45 {
...@@ -81,3 +86,161 @@ mu_sieve_module_init (enum mu_gocs_op op, void *data) ...@@ -81,3 +86,161 @@ mu_sieve_module_init (enum mu_gocs_op op, void *data)
81 mu_sieve_debug_init (); 86 mu_sieve_debug_init ();
82 return 0; 87 return 0;
83 } 88 }
89 /* FIXME: REMOVE END */
90
91 static int
92 cb_clear_library_path (void *data, mu_config_value_t *val)
93 {
94 int flag;
95
96 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
97 return 1;
98 if (mu_str_to_c (val->v.string, mu_c_bool, &flag, NULL))
99 {
100 mu_error (_("not a boolean"));
101 return 1;
102 }
103 if (flag)
104 sieve_settings.clearflags |= MU_SIEVE_CLEAR_LIBRARY_PATH;
105 return 0;
106 }
107
108 static int
109 cb_clear_include_path (void *data, mu_config_value_t *val)
110 {
111 int flag;
112
113 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
114 return 1;
115 if (mu_str_to_c (val->v.string, mu_c_bool, &flag, NULL))
116 {
117 mu_error (_("not a boolean"));
118 return 1;
119 }
120 if (flag)
121 sieve_settings.clearflags |= MU_SIEVE_CLEAR_INCLUDE_PATH;
122 return 0;
123 }
124
125 static int
126 _add_path (const char *arg, void *data)
127 {
128 mu_list_t *plist = data;
129
130 if (!*plist)
131 {
132 int rc = mu_list_create (plist);
133 if (rc)
134 {
135 mu_error (_("cannot create list: %s"), mu_strerror (rc));
136 exit (1);
137 }
138 mu_list_set_destroy_item (*plist, mu_list_free_item);
139 }
140 return mu_string_split (arg, ":", *plist);
141 }
142
143 static int
144 cb_include_path (void *data, mu_config_value_t *val)
145 {
146 return mu_cfg_string_value_cb (val, _add_path,
147 &sieve_settings.include_path);
148 }
149
150 static int
151 cb_library_path (void *data, mu_config_value_t *val)
152 {
153 return mu_cfg_string_value_cb (val, _add_path,
154 &sieve_settings.library_path);
155 }
156
157 static int
158 cb_library_path_prefix (void *data, mu_config_value_t *val)
159 {
160 return mu_cfg_string_value_cb (val, _add_path,
161 &sieve_settings.library_path_prefix);
162 }
163
164 static struct mu_cfg_param mu_sieve_param[] = {
165 { "clear-library-path", mu_cfg_callback, NULL, 0, cb_clear_library_path,
166 N_("Clear library search path.") },
167 { "clear-include-path", mu_cfg_callback, NULL, 0, cb_clear_include_path,
168 N_("Clear include search path.") },
169 { "library-path", mu_cfg_callback, NULL, 0, cb_library_path,
170 N_("Add directories to the library search path. Argument is a "
171 "colon-separated list of directories."),
172 N_("list") },
173 { "library-path-prefix", mu_cfg_callback, NULL, 0, cb_library_path_prefix,
174 N_("Add directories to the beginning of the library search path. "
175 "Argument is a colon-separated list of directories."),
176 N_("list") },
177 { "include-path", mu_cfg_callback, NULL, 0, cb_include_path,
178 N_("Add directories to the include search path. Argument is a "
179 "colon-separated list of directories."),
180 N_("list") },
181 { NULL }
182 };
183
184 /* New capability support */
185 static void
186 cli_includedir (struct mu_parseopt *po, struct mu_option *opt,
187 char const *arg)
188 {
189 _add_path (arg, &sieve_settings.include_path);
190 }
191
192 static void
193 cli_libdir (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
194 {
195 _add_path (arg, &sieve_settings.library_path);
196 }
197
198 static void
199 cli_libdir_prefix (struct mu_parseopt *po, struct mu_option *opt,
200 char const *arg)
201 {
202 _add_path (arg, &sieve_settings.library_path_prefix);
203 }
204
205 static void
206 cli_clear_include_path (struct mu_parseopt *po, struct mu_option *opt,
207 char const *arg)
208 {
209 sieve_settings.clearflags |= MU_SIEVE_CLEAR_INCLUDE_PATH;
210 }
211
212 static void
213 cli_clear_library_path (struct mu_parseopt *po, struct mu_option *opt,
214 char const *arg)
215 {
216 sieve_settings.clearflags |= MU_SIEVE_CLEAR_LIBRARY_PATH;
217 }
218
219 static struct mu_option sieve_option[] = {
220 MU_OPTION_GROUP (N_("Sieve options")),
221 { "includedir", 'I', N_("DIR"), MU_OPTION_DEFAULT,
222 N_("append DIR to the list of directories searched for include files"),
223 mu_c_string, NULL, cli_includedir },
224 { "libdir", 'L', N_("DIR"), MU_OPTION_DEFAULT,
225 N_("append DIR to the list of directories searched for library files"),
226 mu_c_string, NULL, cli_libdir },
227 { "libdir-prefix", 0, N_("DIR"), MU_OPTION_DEFAULT,
228 N_("add DIR to the beginning of the list of directories searched for "
229 "library files"),
230 mu_c_string, NULL, cli_libdir_prefix },
231 { "clear-include-path", 0, NULL, MU_OPTION_DEFAULT,
232 N_("clear Sieve include path"),
233 mu_c_string, NULL, cli_clear_include_path },
234 { "clear-library-path", 0, NULL, MU_OPTION_DEFAULT,
235 N_("clear Sieve library path"),
236 mu_c_string, NULL, cli_clear_library_path },
237 { "clearpath", 0, NULL, MU_OPTION_ALIAS },
238 MU_OPTION_END
239 };
240
241 struct mu_cli_capa mu_cli_capa_sieve = {
242 "sieve",
243 sieve_option,
244 mu_sieve_param,
245 NULL, NULL
246 };
......