Fix operation of mail -t; some other minor fixes
* mail/escape.c (parse_headers): Moved to send.c (check_headers): New function. (escape_continue): Use check_headers. * mail/mail.c (read_recipients): New variable. The -t option sets read_recipients and editheaders * mail/mail.h (parse_headers): New proto. * mail/send.c: Special handling for -t option. (parse_headers): New function. * movemail/movemail.c (onerror statement): Accept a list as argument. * doc/texinfo/mailutils.texi: Update. * doc/texinfo/programs.texi: Update.
Showing
8 changed files
with
243 additions
and
161 deletions
... | @@ -236,7 +236,6 @@ Reading Mail | ... | @@ -236,7 +236,6 @@ Reading Mail |
236 | @command{movemail} --- Moves Mail from the User Maildrop to the Local File | 236 | @command{movemail} --- Moves Mail from the User Maildrop to the Local File |
237 | 237 | ||
238 | * Movemail Configuration:: | 238 | * Movemail Configuration:: |
239 | * Movemail Options:: Description of the Available Options | ||
240 | * Ownership:: Setting Destination Mailbox Ownership | 239 | * Ownership:: Setting Destination Mailbox Ownership |
241 | * Summary:: Short Movemail Invocation Summary | 240 | * Summary:: Short Movemail Invocation Summary |
242 | 241 | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -37,119 +37,26 @@ dump_headers (mu_stream_t out, compose_env_t *env) | ... | @@ -37,119 +37,26 @@ dump_headers (mu_stream_t out, compose_env_t *env) |
37 | mu_stream_destroy (&stream); | 37 | mu_stream_destroy (&stream); |
38 | } | 38 | } |
39 | 39 | ||
40 | #define STATE_INIT 0 | ||
41 | #define STATE_READ 1 | ||
42 | #define STATE_BODY 2 | ||
43 | |||
44 | static int | 40 | static int |
45 | parse_headers (mu_stream_t input, compose_env_t *env) | 41 | check_headers (mu_stream_t input, compose_env_t *env) |
46 | { | 42 | { |
47 | int status; | 43 | char *p; |
48 | mu_header_t header; | ||
49 | char *name = NULL; | ||
50 | char *value = NULL; | ||
51 | int state = STATE_INIT; | ||
52 | char *buf = NULL; | ||
53 | size_t size = 0, n; | ||
54 | int errcnt = 0, line = 0; | ||
55 | 44 | ||
56 | if ((status = mu_header_create (&header, NULL, 0)) != 0) | ||
57 | { | ||
58 | mu_error (_("Cannot create header: %s"), mu_strerror (status)); | ||
59 | return 1; | ||
60 | } | ||
61 | |||
62 | mu_stream_seek (input, 0, MU_SEEK_SET, NULL); | 45 | mu_stream_seek (input, 0, MU_SEEK_SET, NULL); |
63 | while (state != STATE_BODY && | 46 | switch (parse_headers (input, env)) |
64 | errcnt == 0 && | ||
65 | mu_stream_getline (input, &buf, &size, &n) == 0 && n > 0) | ||
66 | { | 47 | { |
67 | mu_rtrim_class (buf, MU_CTYPE_SPACE); | 48 | case parse_headers_ok: |
68 | 49 | return 0; | |
69 | line++; | 50 | case parse_headers_fatal: |
70 | switch (state) | 51 | return -1; |
71 | { | 52 | case parse_headers_error: |
72 | case STATE_INIT: | 53 | break; |
73 | if (!buf[0] || mu_isspace (buf[0])) | ||
74 | continue; | ||
75 | else | ||
76 | state = STATE_READ; | ||
77 | /*FALLTHRU*/ | ||
78 | |||
79 | case STATE_READ: | ||
80 | if (buf[0] == 0) | ||
81 | state = STATE_BODY; | ||
82 | else if (mu_isspace (buf[0])) | ||
83 | { | ||
84 | /* A continuation line */ | ||
85 | if (name) | ||
86 | { | ||
87 | char *p = NULL; | ||
88 | mu_asprintf (&p, "%s\n%s", value, buf); | ||
89 | free (value); | ||
90 | value = p; | ||
91 | } | ||
92 | else | ||
93 | { | ||
94 | mu_error (_("%d: not a header line"), line); | ||
95 | errcnt++; | ||
96 | } | ||
97 | } | ||
98 | else | ||
99 | { | ||
100 | char *p; | ||
101 | |||
102 | if (name) | ||
103 | { | ||
104 | mu_header_set_value (header, name, value[0] ? value : NULL, 0); | ||
105 | free (name); | ||
106 | free (value); | ||
107 | name = value = NULL; | ||
108 | } | ||
109 | p = strchr (buf, ':'); | ||
110 | if (p) | ||
111 | { | ||
112 | *p++ = 0; | ||
113 | while (*p && mu_isspace (*p)) | ||
114 | p++; | ||
115 | value = mu_strdup (p); | ||
116 | name = mu_strdup (buf); | ||
117 | } | ||
118 | else | ||
119 | { | ||
120 | mu_error (_("%d: not a header line"), line); | ||
121 | errcnt++; | ||
122 | } | ||
123 | } | ||
124 | break; | ||
125 | } | ||
126 | } | 54 | } |
127 | 55 | ||
128 | free (buf); | 56 | p = ml_readline (_("Edit again?")); |
129 | if (name) | 57 | return mu_true_answer_p (p); |
130 | { | 58 | } |
131 | mu_header_set_value (header, name, value, 0); | 59 | |
132 | free (name); | ||
133 | free (value); | ||
134 | } | ||
135 | |||
136 | if (errcnt) | ||
137 | { | ||
138 | char *p; | ||
139 | |||
140 | mu_header_destroy (&header); | ||
141 | p = ml_readline (_("Edit again?")); | ||
142 | if (mu_true_answer_p (p) == 1) | ||
143 | return -1; | ||
144 | else | ||
145 | return 1; | ||
146 | } | ||
147 | |||
148 | mu_header_destroy (&env->header); | ||
149 | env->header = header; | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static void | 60 | static void |
154 | escape_continue (void) | 61 | escape_continue (void) |
155 | { | 62 | { |
... | @@ -386,7 +293,7 @@ escape_run_editor (char *ed, int argc, char **argv, compose_env_t *env) | ... | @@ -386,7 +293,7 @@ escape_run_editor (char *ed, int argc, char **argv, compose_env_t *env) |
386 | return rc; | 293 | return rc; |
387 | } | 294 | } |
388 | } | 295 | } |
389 | while ((rc = parse_headers (tempstream, env)) < 0); | 296 | while (check_headers (tempstream, env)); |
390 | } | 297 | } |
391 | else | 298 | else |
392 | { | 299 | { | ... | ... |
... | @@ -23,6 +23,7 @@ | ... | @@ -23,6 +23,7 @@ |
23 | mu_mailbox_t mbox; /* Mailbox being operated upon */ | 23 | mu_mailbox_t mbox; /* Mailbox being operated upon */ |
24 | size_t total; /* Total number of messages in the mailbox */ | 24 | size_t total; /* Total number of messages in the mailbox */ |
25 | int interactive; /* Is the session interactive */ | 25 | int interactive; /* Is the session interactive */ |
26 | int read_recipients; /* Read recipients from the message (mail -t) */ | ||
26 | 27 | ||
27 | static mu_list_t command_list;/* List of commands to be executed after parsing | 28 | static mu_list_t command_list;/* List of commands to be executed after parsing |
28 | command line */ | 29 | command line */ |
... | @@ -72,6 +73,8 @@ cli_command_option (struct mu_parseopt *po, struct mu_option *opt, | ... | @@ -72,6 +73,8 @@ cli_command_option (struct mu_parseopt *po, struct mu_option *opt, |
72 | break; | 73 | break; |
73 | 74 | ||
74 | case 't': | 75 | case 't': |
76 | read_recipients = 1; | ||
77 | util_cache_command (&command_list, "set editheaders"); | ||
75 | util_cache_command (&command_list, "setq mode=send"); | 78 | util_cache_command (&command_list, "setq mode=send"); |
76 | break; | 79 | break; |
77 | 80 | ||
... | @@ -186,7 +189,7 @@ static struct mu_option mail_options[] = { | ... | @@ -186,7 +189,7 @@ static struct mu_option mail_options[] = { |
186 | mu_c_string, NULL, cli_subject }, | 189 | mu_c_string, NULL, cli_subject }, |
187 | 190 | ||
188 | { "to", 't', NULL, MU_OPTION_DEFAULT, | 191 | { "to", 't', NULL, MU_OPTION_DEFAULT, |
189 | N_("precede message by a list of addresses"), | 192 | N_("read recipients from the message header"), |
190 | mu_c_string, NULL, cli_command_option }, | 193 | mu_c_string, NULL, cli_command_option }, |
191 | 194 | ||
192 | { "user", 'u', N_("USER"), MU_OPTION_DEFAULT, | 195 | { "user", 'u', N_("USER"), MU_OPTION_DEFAULT, |
... | @@ -227,7 +230,7 @@ static struct mu_cli_setup cli = { | ... | @@ -227,7 +230,7 @@ static struct mu_cli_setup cli = { |
227 | options, | 230 | options, |
228 | NULL, | 231 | NULL, |
229 | N_("GNU mail -- process mail messages.\n" | 232 | N_("GNU mail -- process mail messages.\n" |
230 | "If -f or --file is given, mail operates on the mailbox named " | 233 | "If -f or --file is given, mail operates on the mailbox named " |
231 | "by the first argument, or the user's mbox, if no argument given."), | 234 | "by the first argument, or the user's mbox, if no argument given."), |
232 | N_("[address...]"), | 235 | N_("[address...]"), |
233 | alt_args, | 236 | alt_args, |
... | @@ -421,6 +424,12 @@ main (int argc, char **argv) | ... | @@ -421,6 +424,12 @@ main (int argc, char **argv) |
421 | /* argument parsing */ | 424 | /* argument parsing */ |
422 | mu_cli (argc, argv, &cli, mail_capa, NULL, &argc, &argv); | 425 | mu_cli (argc, argv, &cli, mail_capa, NULL, &argc, &argv); |
423 | 426 | ||
427 | if (read_recipients) | ||
428 | { | ||
429 | argv += argc; | ||
430 | argc = 0; | ||
431 | } | ||
432 | |||
424 | if ((hint & (HINT_SEND_MODE|HINT_FILE_OPTION)) == | 433 | if ((hint & (HINT_SEND_MODE|HINT_FILE_OPTION)) == |
425 | (HINT_SEND_MODE|HINT_FILE_OPTION)) | 434 | (HINT_SEND_MODE|HINT_FILE_OPTION)) |
426 | { | 435 | { | ... | ... |
... | @@ -288,6 +288,15 @@ extern int escape_attach (int argc, char **argv, compose_env_t *env); | ... | @@ -288,6 +288,15 @@ extern int escape_attach (int argc, char **argv, compose_env_t *env); |
288 | extern int escape_remove_attachment (int argc, char **argv, | 288 | extern int escape_remove_attachment (int argc, char **argv, |
289 | compose_env_t *env); | 289 | compose_env_t *env); |
290 | 290 | ||
291 | enum | ||
292 | { | ||
293 | parse_headers_ok, | ||
294 | parse_headers_error, | ||
295 | parse_headers_fatal | ||
296 | }; | ||
297 | |||
298 | extern int parse_headers (mu_stream_t input, compose_env_t *env); | ||
299 | |||
291 | /* Cursor */ | 300 | /* Cursor */ |
292 | extern void set_cursor (unsigned value); | 301 | extern void set_cursor (unsigned value); |
293 | extern size_t get_cursor (void); | 302 | extern size_t get_cursor (void); | ... | ... |
... | @@ -488,8 +488,42 @@ mail_send (int argc, char **argv) | ... | @@ -488,8 +488,42 @@ mail_send (int argc, char **argv) |
488 | compose_init (&env); | 488 | compose_init (&env); |
489 | 489 | ||
490 | if (argc < 2) | 490 | if (argc < 2) |
491 | compose_header_set (&env, MU_HEADER_TO, ml_readline_with_intr ("To: "), | 491 | { |
492 | COMPOSE_REPLACE); | 492 | if (interactive) |
493 | compose_header_set (&env, MU_HEADER_TO, ml_readline_with_intr ("To: "), | ||
494 | COMPOSE_REPLACE); | ||
495 | else if (!mailvar_get (NULL, "editheaders", mailvar_type_boolean, 0)) | ||
496 | { | ||
497 | if (parse_headers (mu_strin, &env) != parse_headers_ok) | ||
498 | { | ||
499 | mu_error ("%s", _("Errors parsing message")); | ||
500 | exit (EXIT_FAILURE); | ||
501 | } | ||
502 | if (add_header_list) | ||
503 | { | ||
504 | mu_iterator_t itr; | ||
505 | mu_list_get_iterator (add_header_list, &itr); | ||
506 | for (mu_iterator_first (itr); !mu_iterator_is_done (itr); | ||
507 | mu_iterator_next (itr)) | ||
508 | { | ||
509 | struct add_header *hp; | ||
510 | int mode; | ||
511 | if (mu_iterator_current (itr, (void**) &hp)) | ||
512 | break; | ||
513 | mode = hp->mode; | ||
514 | if (mu_header_sget_value (env.header, hp->name, NULL) == 0) | ||
515 | mode = COMPOSE_REPLACE; | ||
516 | compose_header_set (&env, hp->name, hp->value, hp->mode); | ||
517 | } | ||
518 | mu_iterator_destroy (&itr); | ||
519 | } | ||
520 | } | ||
521 | else | ||
522 | { | ||
523 | mu_error ("%s", _("No recipients specified")); | ||
524 | exit (EXIT_FAILURE); | ||
525 | } | ||
526 | } | ||
493 | else | 527 | else |
494 | { | 528 | { |
495 | while (--argc) | 529 | while (--argc) |
... | @@ -511,27 +545,137 @@ mail_send (int argc, char **argv) | ... | @@ -511,27 +545,137 @@ mail_send (int argc, char **argv) |
511 | } | 545 | } |
512 | } | 546 | } |
513 | 547 | ||
514 | if (mailvar_get (NULL, "mailx", mailvar_type_boolean, 0)) | 548 | if (interactive) |
515 | read_cc_bcc (&env); | 549 | { |
516 | 550 | if (mailvar_get (NULL, "mailx", mailvar_type_boolean, 0)) | |
517 | if (mailvar_get (NULL, "asksub", mailvar_type_boolean, 0) == 0) | 551 | read_cc_bcc (&env); |
518 | compose_header_set (&env, MU_HEADER_SUBJECT, | ||
519 | ml_readline_with_intr ("Subject: "), COMPOSE_REPLACE); | ||
520 | 552 | ||
553 | if (mailvar_get (NULL, "asksub", mailvar_type_boolean, 0) == 0) | ||
554 | compose_header_set (&env, MU_HEADER_SUBJECT, | ||
555 | ml_readline_with_intr ("Subject: "), | ||
556 | COMPOSE_REPLACE); | ||
557 | } | ||
558 | |||
521 | status = mail_send0 (&env, save_to); | 559 | status = mail_send0 (&env, save_to); |
522 | compose_destroy (&env); | 560 | compose_destroy (&env); |
523 | return status; | 561 | return status; |
524 | } | 562 | } |
563 | |||
564 | int | ||
565 | parse_headers (mu_stream_t input, compose_env_t *env) | ||
566 | { | ||
567 | int status; | ||
568 | mu_header_t header; | ||
569 | char *name = NULL; | ||
570 | char *value = NULL; | ||
571 | enum { STATE_INIT, STATE_READ, STATE_BODY } state = STATE_INIT; | ||
572 | char *buf = NULL; | ||
573 | size_t size = 0, n; | ||
574 | int errcnt = 0, line = 0; | ||
575 | |||
576 | if ((status = mu_header_create (&header, NULL, 0)) != 0) | ||
577 | { | ||
578 | mu_error (_("Cannot create header: %s"), mu_strerror (status)); | ||
579 | return parse_headers_fatal; | ||
580 | } | ||
581 | |||
582 | while (state != STATE_BODY && | ||
583 | errcnt == 0 && | ||
584 | mu_stream_getline (input, &buf, &size, &n) == 0 && n > 0) | ||
585 | { | ||
586 | mu_rtrim_class (buf, MU_CTYPE_SPACE); | ||
587 | |||
588 | line++; | ||
589 | switch (state) | ||
590 | { | ||
591 | case STATE_INIT: | ||
592 | if (!buf[0] || mu_isspace (buf[0])) | ||
593 | continue; | ||
594 | else | ||
595 | state = STATE_READ; | ||
596 | /*FALLTHRU*/ | ||
597 | |||
598 | case STATE_READ: | ||
599 | if (buf[0] == 0) | ||
600 | state = STATE_BODY; | ||
601 | else if (mu_isspace (buf[0])) | ||
602 | { | ||
603 | /* A continuation line */ | ||
604 | if (name) | ||
605 | { | ||
606 | char *p = NULL; | ||
607 | mu_asprintf (&p, "%s\n%s", value, buf); | ||
608 | free (value); | ||
609 | value = p; | ||
610 | } | ||
611 | else | ||
612 | { | ||
613 | mu_error (_("%d: not a header line"), line); | ||
614 | errcnt++; | ||
615 | } | ||
616 | } | ||
617 | else | ||
618 | { | ||
619 | char *p; | ||
620 | |||
621 | if (name) | ||
622 | { | ||
623 | mu_header_set_value (header, name, value[0] ? value : NULL, 0); | ||
624 | free (name); | ||
625 | free (value); | ||
626 | name = value = NULL; | ||
627 | } | ||
628 | p = strchr (buf, ':'); | ||
629 | if (p) | ||
630 | { | ||
631 | *p++ = 0; | ||
632 | while (*p && mu_isspace (*p)) | ||
633 | p++; | ||
634 | value = mu_strdup (p); | ||
635 | name = mu_strdup (buf); | ||
636 | } | ||
637 | else | ||
638 | { | ||
639 | mu_error (_("%d: not a header line"), line); | ||
640 | errcnt++; | ||
641 | } | ||
642 | } | ||
643 | break; | ||
644 | |||
645 | default: | ||
646 | abort (); | ||
647 | } | ||
648 | } | ||
649 | |||
650 | free (buf); | ||
651 | if (name) | ||
652 | { | ||
653 | mu_header_set_value (header, name, value, 0); | ||
654 | free (name); | ||
655 | free (value); | ||
656 | } | ||
657 | |||
658 | if (errcnt) | ||
659 | { | ||
660 | mu_header_destroy (&header); | ||
661 | return parse_headers_error; | ||
662 | } | ||
663 | |||
664 | mu_header_destroy (&env->header); | ||
665 | env->header = header; | ||
666 | return parse_headers_ok; | ||
667 | } | ||
668 | |||
525 | 669 | ||
526 | void | 670 | void |
527 | compose_init (compose_env_t * env) | 671 | compose_init (compose_env_t *env) |
528 | { | 672 | { |
529 | memset (env, 0, sizeof (*env)); | 673 | memset (env, 0, sizeof (*env)); |
530 | mu_list_foreach (add_header_list, seed_headers, env); | 674 | mu_list_foreach (add_header_list, seed_headers, env); |
531 | } | 675 | } |
532 | 676 | ||
533 | int | 677 | int |
534 | compose_header_set (compose_env_t * env, const char *name, | 678 | compose_header_set (compose_env_t *env, const char *name, |
535 | const char *value, int mode) | 679 | const char *value, int mode) |
536 | { | 680 | { |
537 | int status; | 681 | int status; |
... | @@ -601,7 +745,7 @@ compose_header_set (compose_env_t * env, const char *name, | ... | @@ -601,7 +745,7 @@ compose_header_set (compose_env_t * env, const char *name, |
601 | } | 745 | } |
602 | 746 | ||
603 | char * | 747 | char * |
604 | compose_header_get (compose_env_t * env, char *name, char *defval) | 748 | compose_header_get (compose_env_t *env, char *name, char *defval) |
605 | { | 749 | { |
606 | char *p; | 750 | char *p; |
607 | 751 | ... | ... |
... | @@ -226,8 +226,8 @@ static const struct mail_escape_entry mail_escape_table[] = { | ... | @@ -226,8 +226,8 @@ static const struct mail_escape_entry mail_escape_table[] = { |
226 | {"!", "!", "![shell-command]", escape_shell }, | 226 | {"!", "!", "![shell-command]", escape_shell }, |
227 | {":", ":", ":[mail-command]", escape_command }, | 227 | {":", ":", ":[mail-command]", escape_command }, |
228 | {"-", "-", "-[mail-command]", escape_command }, | 228 | {"-", "-", "-[mail-command]", escape_command }, |
229 | {"+", "+", "+[name [content-type [encoding]]]", escape_attach }, | 229 | {"+", "+", "+name [content-type [encoding]]", escape_attach }, |
230 | {"^", "^", "^[N]", escape_remove_attachment }, | 230 | {"^", "^", "^N", escape_remove_attachment }, |
231 | {"?", "?", "?", escape_help }, | 231 | {"?", "?", "?", escape_help }, |
232 | {"A", "A", "A", escape_sign }, | 232 | {"A", "A", "A", escape_sign }, |
233 | {"a", "a", "a", escape_sign }, | 233 | {"a", "a", "a", escape_sign }, | ... | ... |
... | @@ -194,51 +194,54 @@ set_mailbox_ownership_list (char const *str) | ... | @@ -194,51 +194,54 @@ set_mailbox_ownership_list (char const *str) |
194 | } | 194 | } |
195 | 195 | ||
196 | static int | 196 | static int |
197 | set_onerror_action (char const *str) | 197 | set_onerror_action (void *item, void *data) |
198 | { | 198 | { |
199 | struct mu_wordsplit ws; | 199 | char *str = item; |
200 | static struct mu_kwd onerror_kw[] = { | 200 | |
201 | { "skip", ONERROR_SKIP }, | ||
202 | { "delete", ONERROR_DELETE }, | ||
203 | { "count", ONERROR_COUNT }, | ||
204 | { NULL } | ||
205 | }; | ||
206 | int i, flag; | ||
207 | |||
208 | if (strcmp (str, "abort") == 0) | 201 | if (strcmp (str, "abort") == 0) |
202 | onerror_flags = 0; | ||
203 | else | ||
209 | { | 204 | { |
210 | onerror_flags = 0; | 205 | static struct mu_kwd onerror_kw[] = { |
211 | return 0; | 206 | { "skip", ONERROR_SKIP }, |
212 | } | 207 | { "delete", ONERROR_DELETE }, |
213 | ws.ws_delim = ","; | 208 | { "count", ONERROR_COUNT }, |
214 | if (mu_wordsplit (str, &ws, | 209 | { NULL } |
215 | MU_WRDSF_NOVAR | MU_WRDSF_NOCMD | | 210 | }; |
216 | MU_WRDSF_DELIM | MU_WRDSF_WS)) | 211 | int flag, clr = 0; |
217 | { | 212 | |
218 | mu_error (_("cannot split argument: %s"), mu_wordsplit_strerror (&ws)); | 213 | if (strncmp (str, "no", 2) == 0) |
219 | return 1; | ||
220 | } | ||
221 | for (i = 0; i < ws.ws_wordc; i++) | ||
222 | { | ||
223 | int clr = 0; | ||
224 | char *name = ws.ws_wordv[i]; | ||
225 | |||
226 | if (strncmp (name, "no", 2) == 0) | ||
227 | { | 214 | { |
228 | clr = 1; | 215 | clr = 1; |
229 | name += 2; | 216 | str += 2; |
217 | } | ||
218 | if (mu_kwd_xlat_name (onerror_kw, str, &flag)) | ||
219 | { | ||
220 | mu_error (_("unknown keyword: %s"), str); | ||
221 | return 1; | ||
230 | } | 222 | } |
231 | if (mu_kwd_xlat_name (onerror_kw, name, &flag)) | ||
232 | mu_error (_("unknown keyword: %s"), ws.ws_wordv[i]); | ||
233 | if (clr) | 223 | if (clr) |
234 | onerror_flags &= ~flag; | 224 | onerror_flags &= ~flag; |
235 | else | 225 | else |
236 | onerror_flags |= flag; | 226 | onerror_flags |= flag; |
237 | } | 227 | } |
238 | mu_wordsplit_free (&ws); | ||
239 | return 0; | 228 | return 0; |
240 | } | 229 | } |
241 | 230 | ||
231 | static int | ||
232 | set_onerror_actions (char const *str) | ||
233 | { | ||
234 | mu_list_t list; | ||
235 | int rc; | ||
236 | |||
237 | mu_list_create (&list); | ||
238 | mu_list_set_destroy_item (list, mu_list_free_item); | ||
239 | mu_string_split (str, ",", list); | ||
240 | rc = mu_list_foreach (list, set_onerror_action, NULL); | ||
241 | mu_list_destroy (&list); | ||
242 | return rc; | ||
243 | } | ||
244 | |||
242 | static void | 245 | static void |
243 | cli_mailbox_ownership (struct mu_parseopt *po, struct mu_option *opt, | 246 | cli_mailbox_ownership (struct mu_parseopt *po, struct mu_option *opt, |
244 | char const *arg) | 247 | char const *arg) |
... | @@ -250,7 +253,7 @@ cli_mailbox_ownership (struct mu_parseopt *po, struct mu_option *opt, | ... | @@ -250,7 +253,7 @@ cli_mailbox_ownership (struct mu_parseopt *po, struct mu_option *opt, |
250 | static void | 253 | static void |
251 | cli_onerror (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | 254 | cli_onerror (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
252 | { | 255 | { |
253 | if (set_onerror_action (arg)) | 256 | if (set_onerror_actions (arg)) |
254 | exit (po->po_exit_error); | 257 | exit (po->po_exit_error); |
255 | } | 258 | } |
256 | 259 | ||
... | @@ -327,9 +330,20 @@ cb_mailbox_ownership (void *data, mu_config_value_t *val) | ... | @@ -327,9 +330,20 @@ cb_mailbox_ownership (void *data, mu_config_value_t *val) |
327 | static int | 330 | static int |
328 | cb_onerror (void *data, mu_config_value_t *val) | 331 | cb_onerror (void *data, mu_config_value_t *val) |
329 | { | 332 | { |
330 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) | 333 | switch (val->type) |
331 | return 1; | 334 | { |
332 | return set_onerror_action (val->v.string); | 335 | case MU_CFG_LIST: |
336 | mu_list_foreach (val->v.list, set_onerror_action, NULL); | ||
337 | break; | ||
338 | |||
339 | case MU_CFG_STRING: | ||
340 | set_onerror_actions (val->v.string); | ||
341 | break; | ||
342 | |||
343 | default: | ||
344 | mu_error ("%s", _("too many arguments")); | ||
345 | } | ||
346 | return 0; | ||
333 | } | 347 | } |
334 | 348 | ||
335 | struct mu_cfg_param movemail_cfg_param[] = { | 349 | struct mu_cfg_param movemail_cfg_param[] = { |
... | @@ -360,12 +374,12 @@ struct mu_cfg_param movemail_cfg_param[] = { | ... | @@ -360,12 +374,12 @@ struct mu_cfg_param movemail_cfg_param[] = { |
360 | { "ignore-errors", mu_c_bool, &ignore_errors, 0, NULL, | 374 | { "ignore-errors", mu_c_bool, &ignore_errors, 0, NULL, |
361 | N_("Continue after an error.") }, | 375 | N_("Continue after an error.") }, |
362 | { "onerror", mu_cfg_callback, NULL, 0, cb_onerror, | 376 | { "onerror", mu_cfg_callback, NULL, 0, cb_onerror, |
363 | N_("What to do after an error. Argument is a comma-separated list of:\n" | 377 | N_("What to do after an error. Argument is a list of:\n" |
378 | " abort - terminate the program (the default)\n" | ||
364 | " skip - skip to the next message\n" | 379 | " skip - skip to the next message\n" |
365 | " delete - delete this one and to the next message\n" | 380 | " delete - delete this one and to the next message\n" |
366 | " count - count this message as processed\n" | 381 | " count - count this message as processed\n" |
367 | "Each keyword can be prefixed with \"no\" to reverse its meaning\n" | 382 | "Each keyword can be prefixed with \"no\" to reverse its meaning."), |
368 | "Setting onerror=abort reverts to the default behavior."), | ||
369 | N_("arg: list") }, | 383 | N_("arg: list") }, |
370 | { NULL } | 384 | { NULL } |
371 | }; | 385 | }; | ... | ... |
-
Please register or sign in to post a comment