mail: new option --skip-empty-attachments
* libmailutils/cli/cli.c (mu_cli): Use "no-" prefix to indicate negation * mail/mail.c (skip_empty_attachments): New global. (mail_options): New option --skip-empty-attachments * mail/mail.h (skip_empty_attachments): New extern. * mail/send.c (atchinfo) <skip_empty>: New field. (send_attach_file): Initialize skip_empty (saveatt): Optionally skip empty attachments * NEWS: Mention the new option. * doc/texinfo/programs.texi: Document the new option.
Showing
6 changed files
with
55 additions
and
10 deletions
1 | GNU mailutils NEWS -- history of user-visible changes. 2017-01-13 | 1 | GNU mailutils NEWS -- history of user-visible changes. 2017-01-16 |
2 | Copyright (C) 2002-2017 Free Software Foundation, Inc. | 2 | Copyright (C) 2002-2017 Free Software Foundation, Inc. |
3 | See the end of file for copying conditions. | 3 | See the end of file for copying conditions. |
4 | 4 | ||
... | @@ -40,6 +40,9 @@ obvious reasons, the interactive mode is suppressed in this case. | ... | @@ -40,6 +40,9 @@ obvious reasons, the interactive mode is suppressed in this case. |
40 | The `--attach-fd' option is useful when calling `mail' from another | 40 | The `--attach-fd' option is useful when calling `mail' from another |
41 | program. | 41 | program. |
42 | 42 | ||
43 | The new option `--skip-empty-attachments' instructs `mail' to omit | ||
44 | attachments that have zero-size body. | ||
45 | |||
43 | Example: | 46 | Example: |
44 | 47 | ||
45 | Suppose that the 'mail' binary is opened at file descriptor 5 and | 48 | Suppose that the 'mail' binary is opened at file descriptor 5 and | ... | ... |
... | @@ -3044,6 +3044,13 @@ Cause interrupts to terminate program. | ... | @@ -3044,6 +3044,13 @@ Cause interrupts to terminate program. |
3044 | Sets the return email address for outgoing mail. | 3044 | Sets the return email address for outgoing mail. |
3045 | @xref{return-address}. | 3045 | @xref{return-address}. |
3046 | 3046 | ||
3047 | @item --skip-empty-attachments | ||
3048 | @itemx --no-skip-empty-attachments | ||
3049 | Don't create attachments that would have zero-size body. This | ||
3050 | option affects all attachments created by @option{--attach} and | ||
3051 | @option{--attach-fd} options appearing after it in the command line. | ||
3052 | To cancel its effect, use the @option{--no-skip-empty-attachments} option. | ||
3053 | |||
3047 | @item -s @var{subj} | 3054 | @item -s @var{subj} |
3048 | @itemx --subject=@var{subj} | 3055 | @itemx --subject=@var{subj} |
3049 | Send a message with a Subject of @var{subj}. Valid only in sending | 3056 | Send a message with a Subject of @var{subj}. Valid only in sending |
... | @@ -3531,6 +3538,12 @@ Attachments created with this option have neither filename nor | ... | @@ -3531,6 +3538,12 @@ Attachments created with this option have neither filename nor |
3531 | description set, so normally the use of @option{--content-name} and/or | 3538 | description set, so normally the use of @option{--content-name} and/or |
3532 | @option{--content-filename} is advised. | 3539 | @option{--content-filename} is advised. |
3533 | 3540 | ||
3541 | The option @option{--skip-empty-attachments} instructs @command{mail} | ||
3542 | to skip creating attachments that would have zero-size body. This | ||
3543 | option affects all attachments created by @option{--attach} and | ||
3544 | @option{--attach-fd} options appearing after it in the command line. | ||
3545 | To cancel its effect, use the @option{--no-skip-empty-attachments} option. | ||
3546 | |||
3534 | The following Perl program serves as an example of using | 3547 | The following Perl program serves as an example of using |
3535 | @command{mail} from a script to construct a MIME message on the fly. | 3548 | @command{mail} from a script to construct a MIME message on the fly. |
3536 | It scans all mounted file systems for executable files that have | 3549 | It scans all mounted file systems for executable files that have | ... | ... |
... | @@ -710,6 +710,9 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, | ... | @@ -710,6 +710,9 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, |
710 | pohint.po_version_hook = mu_version_hook; | 710 | pohint.po_version_hook = mu_version_hook; |
711 | pohint.po_flags |= MU_PARSEOPT_VERSION_HOOK; | 711 | pohint.po_flags |= MU_PARSEOPT_VERSION_HOOK; |
712 | 712 | ||
713 | pohint.po_negation = "no-"; | ||
714 | pohint.po_flags |= MU_PARSEOPT_NEGATION; | ||
715 | |||
713 | cfhint.site_file = mu_site_config_file (); | 716 | cfhint.site_file = mu_site_config_file (); |
714 | cfhint.flags = MU_CFHINT_SITE_FILE | MU_CFHINT_PER_USER_FILE; | 717 | cfhint.flags = MU_CFHINT_SITE_FILE | MU_CFHINT_PER_USER_FILE; |
715 | 718 | ... | ... |
... | @@ -36,10 +36,11 @@ int hint; | ... | @@ -36,10 +36,11 @@ int hint; |
36 | char *file; | 36 | char *file; |
37 | char *user; | 37 | char *user; |
38 | 38 | ||
39 | int skip_empty_attachments; | ||
39 | char *default_encoding; | 40 | char *default_encoding; |
40 | char *default_content_type; | 41 | char *default_content_type; |
41 | char *content_name; | 42 | static char *content_name; |
42 | char *content_filename; | 43 | static char *content_filename; |
43 | 44 | ||
44 | static void | 45 | static void |
45 | cli_f_option (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | 46 | cli_f_option (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
... | @@ -108,14 +109,12 @@ cli_command_option (struct mu_parseopt *po, struct mu_option *opt, | ... | @@ -108,14 +109,12 @@ cli_command_option (struct mu_parseopt *po, struct mu_option *opt, |
108 | break; | 109 | break; |
109 | 110 | ||
110 | case 0: | 111 | case 0: |
111 | mu_parseopt_error (po, | 112 | mu_parseopt_error (po, _("--%s: option should have been recognized"), |
112 | _("--%s: option should have been recognized"), | ||
113 | opt->opt_long); | 113 | opt->opt_long); |
114 | exit (po->po_exit_error); | 114 | exit (po->po_exit_error); |
115 | 115 | ||
116 | default: | 116 | default: |
117 | mu_parseopt_error (po, | 117 | mu_parseopt_error (po, _("-%c: option should have been recognized"), |
118 | _("-%c: option should have been recognized"), | ||
119 | opt->opt_short); | 118 | opt->opt_short); |
120 | exit (po->po_exit_error); | 119 | exit (po->po_exit_error); |
121 | } | 120 | } |
... | @@ -240,6 +239,10 @@ static struct mu_option mail_options[] = { | ... | @@ -240,6 +239,10 @@ static struct mu_option mail_options[] = { |
240 | { "append", 'a', N_("HEADER: VALUE"), MU_OPTION_DEFAULT, | 239 | { "append", 'a', N_("HEADER: VALUE"), MU_OPTION_DEFAULT, |
241 | N_("append given header to the message being sent"), | 240 | N_("append given header to the message being sent"), |
242 | mu_c_string, NULL, cli_append }, | 241 | mu_c_string, NULL, cli_append }, |
242 | |||
243 | { "skip-empty-attachments", 0, NULL, MU_OPTION_DEFAULT, | ||
244 | N_("skip attachments with empty body"), | ||
245 | mu_c_bool, &skip_empty_attachments }, | ||
243 | 246 | ||
244 | { "exec" , 'E', N_("COMMAND"), MU_OPTION_DEFAULT, | 247 | { "exec" , 'E', N_("COMMAND"), MU_OPTION_DEFAULT, |
245 | N_("execute COMMAND"), | 248 | N_("execute COMMAND"), | ... | ... |
... | @@ -173,7 +173,8 @@ extern int interactive; | ... | @@ -173,7 +173,8 @@ extern int interactive; |
173 | extern const char *program_version; | 173 | extern const char *program_version; |
174 | extern char *default_encoding; | 174 | extern char *default_encoding; |
175 | extern char *default_content_type; | 175 | extern char *default_content_type; |
176 | 176 | extern int skip_empty_attachments; | |
177 | |||
177 | /* Functions */ | 178 | /* Functions */ |
178 | extern int mail_alias (int argc, char **argv); | 179 | extern int mail_alias (int argc, char **argv); |
179 | extern int mail_alt (int argc, char **argv); /* command alternates */ | 180 | extern int mail_alt (int argc, char **argv); /* command alternates */ | ... | ... |
... | @@ -140,6 +140,7 @@ struct atchinfo | ... | @@ -140,6 +140,7 @@ struct atchinfo |
140 | char *name; | 140 | char *name; |
141 | char *filename; | 141 | char *filename; |
142 | mu_stream_t source; | 142 | mu_stream_t source; |
143 | int skip_empty; | ||
143 | }; | 144 | }; |
144 | 145 | ||
145 | static mu_list_t attlist; | 146 | static mu_list_t attlist; |
... | @@ -256,6 +257,7 @@ send_attach_file (int fd, | ... | @@ -256,6 +257,7 @@ send_attach_file (int fd, |
256 | aptr->name = content_name ? mu_strdup (content_name) : NULL; | 257 | aptr->name = content_name ? mu_strdup (content_name) : NULL; |
257 | aptr->filename = content_filename ? mu_strdup (content_filename) : NULL; | 258 | aptr->filename = content_filename ? mu_strdup (content_filename) : NULL; |
258 | aptr->source = stream; | 259 | aptr->source = stream; |
260 | aptr->skip_empty = skip_empty_attachments; | ||
259 | rc = mu_list_append (attlist, aptr); | 261 | rc = mu_list_append (attlist, aptr); |
260 | if (rc) | 262 | if (rc) |
261 | { | 263 | { |
... | @@ -363,11 +365,31 @@ saveatt (void *item, void *data) | ... | @@ -363,11 +365,31 @@ saveatt (void *item, void *data) |
363 | rc = mu_attachment_copy_from_stream (part, aptr->source, aptr->encoding); | 365 | rc = mu_attachment_copy_from_stream (part, aptr->source, aptr->encoding); |
364 | if (rc) | 366 | if (rc) |
365 | { | 367 | { |
366 | mu_error (_("cannot attach %s: %s"), aptr->filename, | 368 | mu_error (_("cannot attach %s: %s"), aptr->id, mu_strerror (rc)); |
367 | mu_strerror (rc)); | ||
368 | return 1; | 369 | return 1; |
369 | } | 370 | } |
370 | 371 | ||
372 | if (aptr->skip_empty) | ||
373 | { | ||
374 | mu_body_t body; | ||
375 | size_t size; | ||
376 | |||
377 | rc = mu_message_get_body (part, &body); | ||
378 | if (rc) | ||
379 | { | ||
380 | mu_diag_funcall (MU_DIAG_ERROR, "mu_message_get_body", aptr->id, rc); | ||
381 | return 1; | ||
382 | } | ||
383 | rc = mu_body_size (body, &size); | ||
384 | if (rc) | ||
385 | { | ||
386 | mu_diag_funcall (MU_DIAG_ERROR, "mu_body_size", aptr->id, rc); | ||
387 | return 1; | ||
388 | } | ||
389 | if (size == 0) | ||
390 | return 0; | ||
391 | } | ||
392 | |||
371 | mu_mime_get_num_parts (mime, &nparts); | 393 | mu_mime_get_num_parts (mime, &nparts); |
372 | mu_message_get_header (part, &hdr); | 394 | mu_message_get_header (part, &hdr); |
373 | mu_rfc2822_msg_id (nparts, &p); | 395 | mu_rfc2822_msg_id (nparts, &p); | ... | ... |
-
Please register or sign in to post a comment