1 /* cli.c -- Command line interface for GNU Mailutils
2 Copyright (C) 2016-2021 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 <stdarg.h>
22 #include <unistd.h>
23 #include <mailutils/cfg.h>
24 #include <mailutils/opt.h>
25 #include <mailutils/cli.h>
26 #include <mailutils/nls.h>
27
28 void
mu_cli_simple(int argc,char ** argv,...)29 mu_cli_simple (int argc, char **argv, ...)
30 {
31 struct mu_cli_setup setup;
32 struct mu_parseopt pohint;
33 struct mu_cfg_parse_hints cfhint;
34 char **capa = NULL;
35 void *data = NULL;
36 int *ret_argc = NULL;
37 char ***ret_argv = NULL;
38
39 mu_opool_t args_pool = NULL, optv_pool = NULL;
40
41 va_list ap;
42 int opt;
43
44 memset (&setup, 0, sizeof (setup));
45 memset (&pohint, 0, sizeof (pohint));
46 memset (&cfhint, 0, sizeof (cfhint));
47
48 va_start (ap, argv);
49 while ((opt = va_arg (ap, int)) != MU_CLI_OPTION_END)
50 {
51 switch (opt)
52 {
53 case MU_CLI_OPTION_OPTIONS:
54 {
55 struct mu_option *p;
56 if (!optv_pool)
57 mu_opool_create (&optv_pool, MU_OPOOL_ENOMEMABRT);
58 p = va_arg (ap, struct mu_option *);
59 mu_opool_append (optv_pool, &p, sizeof p);
60 }
61 break;
62
63 case MU_CLI_OPTION_CONFIG:
64 setup.cfg = va_arg (ap, struct mu_cfg_param *);
65 break;
66
67 case MU_CLI_OPTION_CAPABILITIES:
68 capa = va_arg (ap, char **);
69 break;
70
71 case MU_CLI_OPTION_EX_USAGE:
72 setup.ex_usage = va_arg (ap, int);
73 break;
74
75 case MU_CLI_OPTION_EX_CONFIG:
76 setup.ex_config = va_arg (ap, int);
77 break;
78
79 case MU_CLI_OPTION_DATA:
80 data = va_arg (ap, void *);
81 break;
82
83 case MU_CLI_OPTION_IN_ORDER:
84 setup.inorder = 1;
85 break;
86
87 case MU_CLI_OPTION_RETURN_ARGC:
88 ret_argc = va_arg (ap, int *);
89 break;
90
91 case MU_CLI_OPTION_RETURN_ARGV:
92 ret_argv = va_arg (ap, char ***);
93 break;
94
95 case MU_CLI_OPTION_IGNORE_ERRORS:
96 pohint.po_flags |= MU_PARSEOPT_IGNORE_ERRORS;
97 break;
98
99 case MU_CLI_OPTION_NO_STDOPT:
100 pohint.po_flags |= MU_PARSEOPT_NO_STDOPT;
101 break;
102
103 case MU_CLI_OPTION_NO_ERREXIT:
104 pohint.po_flags |= MU_PARSEOPT_NO_ERREXIT;
105 break;
106
107 case MU_CLI_OPTION_IMMEDIATE:
108 pohint.po_flags |= MU_PARSEOPT_IMMEDIATE;
109 break;
110
111 case MU_CLI_OPTION_NO_SORT:
112 pohint.po_flags |= MU_PARSEOPT_NO_SORT;
113 break;
114
115 case MU_CLI_OPTION_SINGLE_DASH:
116 pohint.po_flags |= MU_PARSEOPT_SINGLE_DASH;
117 break;
118
119 case MU_CLI_OPTION_PROG_NAME:
120 pohint.po_prog_name = va_arg (ap, char *);
121 if (pohint.po_prog_name)
122 pohint.po_flags |= MU_PARSEOPT_PROG_NAME;
123 break;
124
125 case MU_CLI_OPTION_PROG_DOC:
126 pohint.po_prog_doc = va_arg (ap, char *);
127 if (pohint.po_prog_doc)
128 pohint.po_flags |= MU_PARSEOPT_PROG_DOC;
129 break;
130
131 case MU_CLI_OPTION_PROG_ARGS:
132 {
133 char *p;
134 if (!args_pool)
135 mu_opool_create (&args_pool, MU_OPOOL_ENOMEMABRT);
136 p = va_arg (ap, char *);
137 mu_opool_append (args_pool, &p, sizeof p);
138 }
139 break;
140
141 case MU_CLI_OPTION_BUG_ADDRESS:
142 pohint.po_bug_address = va_arg (ap, char *);
143 if (pohint.po_bug_address)
144 pohint.po_flags |= MU_PARSEOPT_BUG_ADDRESS;
145 break;
146
147 case MU_CLI_OPTION_PACKAGE_NAME:
148 pohint.po_package_name = va_arg (ap, char *);
149 if (pohint.po_package_name)
150 pohint.po_flags |= MU_PARSEOPT_PACKAGE_NAME;
151 break;
152
153 case MU_CLI_OPTION_PACKAGE_URL:
154 pohint.po_package_url = va_arg (ap, char *);
155 if (pohint.po_package_url)
156 pohint.po_flags |= MU_PARSEOPT_PACKAGE_URL;
157 break;
158
159 case MU_CLI_OPTION_EXTRA_INFO:
160 pohint.po_extra_info = va_arg (ap, char *);
161 if (pohint.po_extra_info)
162 pohint.po_flags |= MU_PARSEOPT_EXTRA_INFO;
163 break;
164
165 case MU_CLI_OPTION_HELP_HOOK:
166 pohint.po_help_hook =
167 va_arg (ap, void (*) (struct mu_parseopt *, mu_stream_t));
168 if (pohint.po_help_hook)
169 pohint.po_flags |= MU_PARSEOPT_HELP_HOOK;
170 break;
171
172 case MU_CLI_OPTION_VERSION_HOOK:
173 pohint.po_version_hook =
174 va_arg (ap, void (*) (struct mu_parseopt *, mu_stream_t));
175 if (pohint.po_version_hook)
176 pohint.po_flags |= MU_PARSEOPT_VERSION_HOOK;
177 break;
178
179 case MU_CLI_OPTION_PROG_DOC_HOOK:
180 pohint.po_prog_doc_hook =
181 va_arg (ap, void (*) (struct mu_parseopt *, mu_stream_t));
182 if (pohint.po_prog_doc_hook)
183 pohint.po_flags |= MU_PARSEOPT_PROG_DOC_HOOK;
184 break;
185
186 case MU_CLI_OPTION_NEGATION:
187 pohint.po_negation = va_arg (ap, char *);
188 if (pohint.po_negation)
189 pohint.po_flags |= MU_PARSEOPT_NEGATION;
190 break;
191
192 case MU_CLI_OPTION_SPECIAL_ARGS:
193 pohint.po_special_args = va_arg (ap, char *);
194 if (pohint.po_special_args)
195 pohint.po_flags |= MU_PARSEOPT_SPECIAL_ARGS;
196 break;
197
198 case MU_CLI_OPTION_CONF_SITE_FILE:
199 if ((cfhint.site_file = va_arg (ap, char *)) == NULL)
200 cfhint.site_file = mu_site_config_file ();
201 cfhint.flags = MU_CFHINT_SITE_FILE;
202 break;
203
204 case MU_CLI_OPTION_CONF_PER_USER_FILE:
205 cfhint.flags |= MU_CFHINT_PER_USER_FILE;
206 break;
207
208 case MU_CLI_OPTION_CONF_NO_OVERRIDE:
209 cfhint.flags |= MU_CFHINT_NO_CONFIG_OVERRIDE;
210 break;
211
212 case MU_CLI_OPTION_CONF_PROGNAME:
213 if ((cfhint.program = va_arg (ap, char *)) != NULL)
214 cfhint.flags |= MU_CFHINT_PROGRAM;
215 break;
216
217 default:
218 mu_diag_output (MU_DIAG_CRIT,
219 _("%s:%d: INTERNAL ERROR: unrecognized mu_cli_simple option"),
220 __FILE__, __LINE__);
221 abort ();
222 }
223 }
224 if (optv_pool)
225 {
226 struct mu_option *p = NULL;
227 mu_opool_append (optv_pool, &p, sizeof p);
228 setup.optv = mu_opool_finish (optv_pool, NULL);
229 }
230 if (args_pool)
231 {
232 char *p = NULL;
233 mu_opool_append (args_pool, &p, sizeof p);
234 pohint.po_prog_args = mu_opool_finish (args_pool, NULL);
235 pohint.po_flags |= MU_PARSEOPT_PROG_ARGS;
236 }
237 mu_cli_ext (argc, argv, &setup, &pohint, &cfhint, capa, data,
238 ret_argc, ret_argv);
239 mu_opool_destroy (&args_pool);
240 mu_opool_destroy (&optv_pool);
241 va_end (ap);
242 }
243