Commit 01adf04c 01adf04ce8e743b7344a8527bccb1959dc7c18d2 by Sergey Poznyakoff

Convert maidag to mu_cli

1 parent f2279f27
...@@ -58,4 +58,6 @@ void mu_cli (int argc, char **argv, struct mu_cli_setup *setup, ...@@ -58,4 +58,6 @@ void mu_cli (int argc, char **argv, struct mu_cli_setup *setup,
58 58
59 char *mu_site_config_file (void); 59 char *mu_site_config_file (void);
60 60
61 void mu_acl_cfg_init (void);
62
61 #endif 63 #endif
......
...@@ -36,7 +36,7 @@ maidag_LDADD = \ ...@@ -36,7 +36,7 @@ maidag_LDADD = \
36 @LIBMU_SCM@ @GUILE_LIBS@\ 36 @LIBMU_SCM@ @GUILE_LIBS@\
37 @LIBMU_SCM_DEPS@\ 37 @LIBMU_SCM_DEPS@\
38 @MU_LIB_PY@ @PYTHON_LIBS@\ 38 @MU_LIB_PY@ @PYTHON_LIBS@\
39 ${MU_APP_LIBRARIES}\ 39 ${MU_APP_NEW_LIBRARIES}\
40 ${MU_LIB_SIEVE}\ 40 ${MU_LIB_SIEVE}\
41 ${MU_LIB_MBOX}\ 41 ${MU_LIB_MBOX}\
42 ${MU_LIB_IMAP}\ 42 ${MU_LIB_IMAP}\
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ 15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16 16
17 #include "maidag.h" 17 #include "maidag.h"
18 #include "mailutils/cli.h"
18 19
19 enum maidag_mode maidag_mode = mode_mda; 20 enum maidag_mode maidag_mode = mode_mda;
20 int multiple_delivery; /* Don't return errors when delivering to multiple 21 int multiple_delivery; /* Don't return errors when delivering to multiple
...@@ -35,11 +36,11 @@ mu_script_t script_handler; ...@@ -35,11 +36,11 @@ mu_script_t script_handler;
35 mu_list_t script_list; 36 mu_list_t script_list;
36 37
37 char *forward_file = NULL; 38 char *forward_file = NULL;
38 #define FORWARD_FILE_PERM_CHECK ( \ 39 #define FORWARD_FILE_PERM_CHECK ( \
39 MU_FILE_SAFETY_OWNER_MISMATCH | \ 40 MU_FILE_SAFETY_OWNER_MISMATCH | \
40 MU_FILE_SAFETY_GROUP_WRITABLE | \ 41 MU_FILE_SAFETY_GROUP_WRITABLE | \
41 MU_FILE_SAFETY_WORLD_WRITABLE | \ 42 MU_FILE_SAFETY_WORLD_WRITABLE | \
42 MU_FILE_SAFETY_LINKED_WRDIR | \ 43 MU_FILE_SAFETY_LINKED_WRDIR | \
43 MU_FILE_SAFETY_DIR_IWGRP | \ 44 MU_FILE_SAFETY_DIR_IWGRP | \
44 MU_FILE_SAFETY_DIR_IWOTH ) 45 MU_FILE_SAFETY_DIR_IWOTH )
45 int forward_file_checks = FORWARD_FILE_PERM_CHECK; 46 int forward_file_checks = FORWARD_FILE_PERM_CHECK;
...@@ -58,92 +59,7 @@ int reuse_lmtp_address = 1; ...@@ -58,92 +59,7 @@ int reuse_lmtp_address = 1;
58 int maidag_transcript; 59 int maidag_transcript;
59 60
60 const char *program_version = "maidag (" PACKAGE_STRING ")"; 61 const char *program_version = "maidag (" PACKAGE_STRING ")";
61 static char doc[] = 62
62 N_("GNU maidag -- the mail delivery agent.")
63 "\v"
64 N_("Debug flags are:\n\
65 g - guile stack traces\n\
66 t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n\
67 i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n\
68 l - sieve action logs\n\
69 0-9 - Set maidag debugging level\n");
70
71 static char args_doc[] = N_("[recipient...]");
72
73 #define STDERR_OPTION 256
74 #define MESSAGE_ID_HEADER_OPTION 257
75 #define LMTP_OPTION 258
76 #define FOREGROUND_OPTION 260
77 #define URL_OPTION 261
78 #define TRANSCRIPT_OPTION 262
79 #define MDA_OPTION 263
80
81 static struct argp_option options[] =
82 {
83 #define GRID 0
84 { NULL, 0, NULL, 0,
85 N_("General options"), GRID },
86
87 { "foreground", FOREGROUND_OPTION, 0, 0, N_("remain in foreground"),
88 GRID + 1 },
89 { "inetd", 'i', 0, 0, N_("run in inetd mode"), GRID + 1 },
90 { "daemon", 'd', N_("NUMBER"), OPTION_ARG_OPTIONAL,
91 N_("runs in daemon mode with a maximum of NUMBER children"), GRID + 1 },
92 { "url", URL_OPTION, 0, 0, N_("deliver to given URLs"), GRID + 1 },
93 { "mda", MDA_OPTION, 0, 0, N_("force MDA mode even if not started as root"),
94 GRID + 1 },
95 { "from", 'f', N_("EMAIL"), 0,
96 N_("specify the sender's name"), GRID + 1 },
97 { NULL, 'r', NULL, OPTION_ALIAS, NULL },
98 { "lmtp", LMTP_OPTION, N_("URL"), OPTION_ARG_OPTIONAL,
99 N_("operate in LMTP mode"), GRID + 1 },
100 { "debug", 'x', N_("FLAGS"), 0,
101 N_("enable debugging"), GRID + 1 },
102 { "stderr", STDERR_OPTION, NULL, 0,
103 N_("log to standard error"), GRID + 1 },
104 { "transcript", TRANSCRIPT_OPTION, NULL, 0,
105 N_("enable session transcript"), GRID + 1 },
106 #undef GRID
107
108 #define GRID 2
109 { NULL, 0, NULL, 0,
110 N_("Scripting options"), GRID },
111
112 { "language", 'l', N_("STRING"), 0,
113 N_("define scripting language for the next --script option"),
114 GRID + 1 },
115 { "script", 's', N_("PATTERN"), 0,
116 N_("set name pattern for user-defined mail filter"), GRID + 1 },
117 { "message-id-header", MESSAGE_ID_HEADER_OPTION, N_("STRING"), 0,
118 N_("use this header to identify messages when logging Sieve actions"),
119 GRID + 1 },
120 #undef GRID
121 { NULL, 0, NULL, 0, NULL, 0 }
122 };
123
124 static error_t parse_opt (int key, char *arg, struct argp_state *state);
125
126 static struct argp argp = {
127 options,
128 parse_opt,
129 args_doc,
130 doc,
131 NULL,
132 NULL, NULL
133 };
134
135 static const char *maidag_argp_capa[] = {
136 "mailutils",
137 "auth",
138 "common",
139 "debug",
140 "logging",
141 "mailbox",
142 "locking",
143 "mailer",
144 NULL
145 };
146
147 static void 63 static void
148 set_debug_flags (const char *arg) 64 set_debug_flags (const char *arg)
149 { 65 {
...@@ -168,106 +84,196 @@ set_debug_flags (const char *arg) ...@@ -168,106 +84,196 @@ set_debug_flags (const char *arg)
168 } 84 }
169 } 85 }
170 } 86 }
171 87
172 static error_t 88 static void
173 parse_opt (int key, char *arg, struct argp_state *state) 89 set_inetd_mode (struct mu_parseopt *po, struct mu_option *opt,
90 char const *arg)
174 { 91 {
175 static mu_list_t lst; 92 mu_m_server_set_mode (server, MODE_INTERACTIVE);
176 93 }
177 switch (key) 94
95 static void
96 set_daemon_mode (struct mu_parseopt *po, struct mu_option *opt,
97 char const *arg)
98 {
99 mu_m_server_set_mode (server, MODE_DAEMON);
100 if (arg)
178 { 101 {
179 case 'd': 102 size_t max_children;
180 mu_argp_node_list_new (lst, "mode", "daemon"); 103 char *errmsg;
181 if (arg) 104 int rc = mu_str_to_c (arg, mu_c_size, &max_children, &errmsg);
182 mu_argp_node_list_new (lst, "max-children", arg); 105 if (rc)
183 break; 106 {
107 mu_parseopt_error (po, _("%s: bad argument"), arg);
108 exit (po->po_exit_error);
109 }
110 mu_m_server_set_max_children (server, max_children);
111 }
112 }
184 113
185 case 'i': 114 static void
186 mu_argp_node_list_new (lst, "mode", "inetd"); 115 set_foreground (struct mu_parseopt *po, struct mu_option *opt,
187 break; 116 char const *arg)
117 {
118 mu_m_server_set_foreground (server, 1);
119 }
188 120
189 case FOREGROUND_OPTION: 121 static void
190 mu_argp_node_list_new (lst, "foreground", "yes"); 122 set_delivery_url (struct mu_parseopt *po, struct mu_option *opt,
191 break; 123 char const *arg)
192 124 {
193 case MESSAGE_ID_HEADER_OPTION: 125 maidag_mode = mode_url;
194 mu_argp_node_list_new (lst, "message-id-header", arg); 126 mu_log_syslog = 0;
195 break; 127 }
196 128
197 case LMTP_OPTION: 129 static void
198 mu_argp_node_list_new (lst, "delivery-mode", "lmtp"); 130 set_delivery_mda (struct mu_parseopt *po, struct mu_option *opt,
199 if (arg) 131 char const *arg)
200 mu_argp_node_list_new (lst, "listen", arg); 132 {
201 break; 133 maidag_mode = mode_mda;
134 }
202 135
203 case MDA_OPTION: 136 static void
204 mu_argp_node_list_new (lst, "delivery-mode", "mda"); 137 set_sender_address (struct mu_parseopt *po, struct mu_option *opt,
205 break; 138 char const *arg)
206 139 {
207 case TRANSCRIPT_OPTION: 140 if (sender_address != NULL)
208 maidag_transcript = 1; 141 {
209 break; 142 mu_parseopt_error (po, _("multiple --from options"));
210 143 exit (po->po_exit_error);
211 case 'r': 144 }
212 case 'f': 145 else
213 if (sender_address != NULL) 146 {
214 argp_error (state, _("multiple --from options")); 147 char *errmsg;
215 sender_address = arg; 148 int rc = mu_str_to_c (arg, opt->opt_type, opt->opt_ptr, &errmsg);
216 break; 149 if (rc)
217 150 {
218 case 'l': 151 mu_parseopt_error (po, _("can't set sender address: %s"),
219 script_handler = mu_script_lang_handler (arg); 152 errmsg ? errmsg : mu_strerror (rc));
220 if (!script_handler) 153 exit (po->po_exit_error);
221 argp_error (state, _("unknown or unsupported language: %s"), 154 }
222 arg); 155 }
223 break; 156 }
157
158 static void
159 set_lmtp_mode (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
160 {
161 maidag_mode = mode_lmtp;
162 if (arg)
163 {
164 struct mu_sockaddr *s;
224 165
225 case 's': 166 if (mu_m_server_parse_url (server, arg, &s))
226 switch (script_register (arg))
227 { 167 {
228 case 0: 168 mu_parseopt_error (po, _("%s: invalid URL"), arg);
229 break; 169 exit (po->po_exit_error);
170 }
171 mu_m_server_listen (server, s, MU_IP_TCP);
172 }
173 }
230 174
231 case EINVAL: 175 static void
232 argp_error (state, _("%s has unknown file suffix"), arg); 176 set_debug (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
233 break; 177 {
178 set_debug_flags (arg);
179 }
234 180
235 default: 181 static void
236 argp_error (state, _("error registering script")); 182 set_stderr (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
237 } 183 {
238 break; 184 mu_log_syslog = 0;
239 185 }
240 case 'x':
241 mu_argp_node_list_new (lst, "debug", arg);
242 break;
243 186
244 case STDERR_OPTION: 187 static void
245 mu_argp_node_list_new (lst, "stderr", "yes"); 188 set_script_lang (struct mu_parseopt *po, struct mu_option *opt,
246 break; 189 char const *arg)
190 {
191 script_handler = mu_script_lang_handler (arg);
192 if (!script_handler)
193 {
194 mu_parseopt_error (po, _("unknown or unsupported language: %s"), arg);
195 exit (po->po_exit_error);
196 }
197 }
247 198
248 case URL_OPTION: 199 static void
249 mu_argp_node_list_new (lst, "delivery-mode", "url"); 200 set_script_pattern (struct mu_parseopt *po, struct mu_option *opt,
250 break; 201 char const *arg)
251 202 {
252 case ARGP_KEY_INIT: 203 switch (script_register (arg))
253 mu_argp_node_list_init (&lst); 204 {
254 break; 205 case 0:
255 206 return;
256 case ARGP_KEY_FINI: 207
257 mu_argp_node_list_finish (lst, NULL, NULL); 208 case EINVAL:
209 mu_parseopt_error (po, _("%s has unknown file suffix"), arg);
258 break; 210 break;
259
260 case ARGP_KEY_ERROR:
261 exit (EX_USAGE);
262 211
263 default: 212 default:
264 return ARGP_ERR_UNKNOWN; 213 mu_parseopt_error (po, _("error registering script"));
265 } 214 }
266 return 0; 215 exit (po->po_exit_error);
267 } 216 }
268 217
269 218 static struct mu_option maidag_options[] = {
219 MU_OPTION_GROUP (N_("General options")),
220 { "foreground", 0, NULL, MU_OPTION_DEFAULT,
221 N_("remain in foreground"),
222 mu_c_bool, NULL, set_foreground },
223 { "inetd", 'i', NULL, MU_OPTION_DEFAULT,
224 N_("run in inetd mode"),
225 mu_c_bool, NULL, set_inetd_mode },
226 { "daemon", 'd', N_("NUMBER"), MU_OPTION_ARG_OPTIONAL,
227 N_("runs in daemon mode with a maximum of NUMBER children"),
228 mu_c_string, NULL, set_daemon_mode },
229 { "url", 0, NULL, MU_OPTION_DEFAULT,
230 N_("deliver to given URLs"),
231 mu_c_string, NULL, set_delivery_url },
232 { "mda", 0, NULL, MU_OPTION_DEFAULT,
233 N_("force MDA mode even if not started as root"),
234 mu_c_string, NULL, set_delivery_mda },
235 { "from", 'f', N_("EMAIL"), MU_OPTION_DEFAULT,
236 N_("specify the sender's name"),
237 mu_c_string, &sender_address, set_sender_address },
238 { NULL, 'r', NULL, MU_OPTION_ALIAS },
239 { "lmtp", 0, N_("URL"), MU_OPTION_ARG_OPTIONAL,
240 N_("operate in LMTP mode"),
241 mu_c_string, NULL, set_lmtp_mode },
242 { "debug", 'x', N_("FLAGS"), MU_OPTION_DEFAULT,
243 N_("enable debugging"),
244 mu_c_string, NULL, set_debug },
245 { "stderr", 0, NULL, MU_OPTION_DEFAULT,
246 N_("log to standard error"),
247 mu_c_string, NULL, set_stderr },
248 { "transcript", 0, NULL, MU_OPTION_DEFAULT,
249 N_("enable session transcript"),
250 mu_c_bool, &maidag_transcript },
251
252 MU_OPTION_GROUP (N_("Scripting options")),
253 { "language", 'l', N_("STRING"), MU_OPTION_DEFAULT,
254 N_("define scripting language for the next --script option"),
255 mu_c_string, NULL, set_script_lang },
256 { "script", 's', N_("PATTERN"), MU_OPTION_DEFAULT,
257 N_("set name pattern for user-defined mail filter"),
258 mu_c_string, NULL, set_script_pattern },
259 { "message-id-header", 0, N_("STRING"), MU_OPTION_DEFAULT,
260 N_("use this header to identify messages when logging Sieve actions"),
261 mu_c_string, &message_id_header },
262 MU_OPTION_END
263 }, *options[] = { maidag_options, NULL };
270 264
265 static char *capa[] = {
266 "auth",
267 "debug",
268 "logging",
269 "mailbox",
270 "locking",
271 "mailer",
272 "sieve",
273 "tls",
274 NULL
275 };
276
271 static int 277 static int
272 cb_debug (void *data, mu_config_value_t *val) 278 cb_debug (void *data, mu_config_value_t *val)
273 { 279 {
...@@ -483,6 +489,20 @@ maidag_cfg_init () ...@@ -483,6 +489,20 @@ maidag_cfg_init ()
483 mu_cfg_section_add_params (section, filter_cfg_param); 489 mu_cfg_section_add_params (section, filter_cfg_param);
484 } 490 }
485 } 491 }
492
493 struct mu_cli_setup cli = {
494 options,
495 maidag_cfg_param,
496 N_("GNU maidag -- the mail delivery agent."),
497 N_("[recipient...]"),
498 NULL,
499 N_("Debug flags are:\n\
500 g - guile stack traces\n\
501 t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n\
502 i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n\
503 l - sieve action logs\n\
504 0-9 - Set maidag debugging level\n")
505 };
486 506
487 /* FIXME: These are for compatibility with MU 2.0. 507 /* FIXME: These are for compatibility with MU 2.0.
488 Remove in 2.2 */ 508 Remove in 2.2 */
...@@ -494,7 +514,6 @@ extern mu_record_t mu_remote_prog_record; ...@@ -494,7 +514,6 @@ extern mu_record_t mu_remote_prog_record;
494 int 514 int
495 main (int argc, char *argv[]) 515 main (int argc, char *argv[])
496 { 516 {
497 int arg_index;
498 maidag_delivery_fn delivery_fun = NULL; 517 maidag_delivery_fn delivery_fun = NULL;
499 518
500 /* Preparative work: close inherited fds, force a reasonable umask 519 /* Preparative work: close inherited fds, force a reasonable umask
...@@ -518,18 +537,10 @@ main (int argc, char *argv[]) ...@@ -518,18 +537,10 @@ main (int argc, char *argv[])
518 mu_register_all_formats (); 537 mu_register_all_formats ();
519 mu_registrar_record (mu_smtp_record); 538 mu_registrar_record (mu_smtp_record);
520 539
521 mu_gocs_register ("sieve", mu_sieve_module_init);
522
523 mu_tcpwrapper_cfg_init (); 540 mu_tcpwrapper_cfg_init ();
524 mu_acl_cfg_init (); 541 mu_acl_cfg_init ();
525 maidag_cfg_init (); 542 maidag_cfg_init ();
526 543
527 /* Parse command line */
528 #ifdef WITH_TLS
529 mu_gocs_register ("tls", mu_tls_module_init);
530 #endif
531 mu_argp_init (NULL, NULL);
532
533 mu_m_server_create (&server, program_version); 544 mu_m_server_create (&server, program_version);
534 mu_m_server_set_conn (server, lmtp_connection); 545 mu_m_server_set_conn (server, lmtp_connection);
535 mu_m_server_set_prefork (server, mu_tcp_wrapper_prefork); 546 mu_m_server_set_prefork (server, mu_tcp_wrapper_prefork);
...@@ -541,9 +552,10 @@ main (int argc, char *argv[]) ...@@ -541,9 +552,10 @@ main (int argc, char *argv[])
541 mu_log_syslog = -1; 552 mu_log_syslog = -1;
542 mu_log_print_severity = 1; 553 mu_log_print_severity = 1;
543 554
544 if (mu_app_init (&argp, maidag_argp_capa, maidag_cfg_param, 555 /* Parse command line */
545 argc, argv, 0, &arg_index, server)) 556 mu_cli_capa_register (&mu_cli_capa_tls);
546 exit (EX_CONFIG); 557 mu_cli_capa_register (&mu_cli_capa_sieve);
558 mu_cli (argc, argv, &cli, capa, NULL, &argc, &argv);
547 559
548 current_uid = getuid (); 560 current_uid = getuid ();
549 561
...@@ -554,9 +566,6 @@ main (int argc, char *argv[]) ...@@ -554,9 +566,6 @@ main (int argc, char *argv[])
554 MU_STRERR_SYSLOG : MU_STRERR_STDERR); 566 MU_STRERR_SYSLOG : MU_STRERR_STDERR);
555 } 567 }
556 568
557 argc -= arg_index;
558 argv += arg_index;
559
560 switch (maidag_mode) 569 switch (maidag_mode)
561 { 570 {
562 case mode_lmtp: 571 case mode_lmtp:
......
...@@ -91,8 +91,6 @@ ...@@ -91,8 +91,6 @@
91 # define USE_MAILBOX_QUOTAS 1 91 # define USE_MAILBOX_QUOTAS 1
92 #endif 92 #endif
93 93
94 #include "mailutils/libargp.h"
95
96 #include "tcpwrap.h" 94 #include "tcpwrap.h"
97 #include "muscript.h" 95 #include "muscript.h"
98 96
......