Implement --attach option in mail; fix dead.letter functionality
* NEWS: Update. * doc/imprimatur: Upgrade. * libmailutils/mime/attachment.c (mu_message_create_attachment): Bugfixes. * mail/mail.c: New options --attach, --content-type and --encoding. * mail/mail.h (default_encoding, default_content_type): New externs. (send_attach_file): New proto. * mail/send.c (send_attach_file): New function. (save_dead_message_env): New function. (save_dead_message): Rewrite. (mail_send0): Attach files, if requested.
Showing
6 changed files
with
76 additions
and
6 deletions
1 | GNU mailutils NEWS -- history of user-visible changes. 2012-06-07 | 1 | GNU mailutils NEWS -- history of user-visible changes. 2012-07-18 |
2 | Copyright (C) 2002-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2002-2012 Free Software Foundation, Inc. |
3 | See the end of file for copying conditions. | 3 | See the end of file for copying conditions. |
4 | 4 | ||
... | @@ -82,7 +82,7 @@ are not used to avoid compromising security. | ... | @@ -82,7 +82,7 @@ are not used to avoid compromising security. |
82 | 82 | ||
83 | See <http://mailutils.org/wiki/debug_level>. | 83 | See <http://mailutils.org/wiki/debug_level>. |
84 | 84 | ||
85 | ** Imap4d undergone a lot of changes to comply to existing RFCs | 85 | ** Imap4d underwent a lot of changes to comply to existing RFCs |
86 | 86 | ||
87 | ** Pop3d and imap4d allow for mailbox-independent compulsory locking | 87 | ** Pop3d and imap4d allow for mailbox-independent compulsory locking |
88 | 88 | ||
... | @@ -114,6 +114,27 @@ header field with the given date. | ... | @@ -114,6 +114,27 @@ header field with the given date. |
114 | 114 | ||
115 | See <http://mailutils.org/wiki/Timestamp_(Sieve_test)>. | 115 | See <http://mailutils.org/wiki/Timestamp_(Sieve_test)>. |
116 | 116 | ||
117 | ** mail: sending attachments | ||
118 | |||
119 | The mail[x] utility now allows for sending attachments. Any number of | ||
120 | files can be attached to the composed letter by using the `--attach' | ||
121 | (`-A') options. The files will be attached in the same order in which | ||
122 | they appear in the command line. By default, each attachment is | ||
123 | assigned the content type "application/octet-stream" and is encoded | ||
124 | using Base64. This can be changed using the `--content-type' and | ||
125 | `--encoding' options. These options affect all attachments that | ||
126 | appear after them in the command line, until next occurrence of the | ||
127 | same option or end of command line, whichever occurs first. For | ||
128 | example: | ||
129 | |||
130 | mail -A prog --encoding quoted-printable --content-type text/c \ | ||
131 | -A main.c -A ext.h | ||
132 | |||
133 | Here, the file "prog" will be attached witg the content type | ||
134 | "application/octet-stream" and encoding base64, while the files | ||
135 | "main.c" and "ext.h" will be marked with content type "text/c" and | ||
136 | encoded using "quoted-printable" algorithm. | ||
137 | |||
117 | ** MH: improved compatibility with other implementations | 138 | ** MH: improved compatibility with other implementations |
118 | 139 | ||
119 | ** MH inc: new option --moveto | 140 | ** MH inc: new option --moveto |
... | @@ -181,12 +202,29 @@ imap4d, pop3d, comsat) will be built. Its counterpart, | ... | @@ -181,12 +202,29 @@ imap4d, pop3d, comsat) will be built. Its counterpart, |
181 | `--enable-build-clients' controls whether client utilities will be | 202 | `--enable-build-clients' controls whether client utilities will be |
182 | built. | 203 | built. |
183 | 204 | ||
205 | The effect of both options is overridden by the `--enable-build-*' | ||
206 | options for particular components. For example, to build only | ||
207 | the "mail" utility: | ||
208 | |||
209 | ./configure --disable-build-clients --enable-build-mail | ||
210 | |||
211 | ** The --with-mailbindir option | ||
212 | |||
213 | This option changes installation directory for the "mail" utility. | ||
214 | |||
184 | ** DBM options | 215 | ** DBM options |
185 | 216 | ||
186 | It is normally not needed to specify --with-gdbm, --with-berkeley-db | 217 | It is normally not needed to specify --with-gdbm, --with-berkeley-db |
187 | or --with-ndbm explicitly. Configuration will automatically pick up | 218 | or --with-ndbm explicitly. Configuration will automatically pick up |
188 | all available DBM libraries it can use. | 219 | all available DBM libraries it can use. |
189 | 220 | ||
221 | The option `--with-dbm' can be used to enable or disable building of | ||
222 | all available DBM interfaces. Its effect is overridden by `--with-*' | ||
223 | options for particular interfaces. For example, to build only GDBM | ||
224 | (even if another databases are supported by the system): | ||
225 | |||
226 | ./configure --without-dbm --with-gdbm | ||
227 | |||
190 | ** Nntp client is not yet implemented | 228 | ** Nntp client is not yet implemented |
191 | 229 | ||
192 | ** Link with GSASL by default | 230 | ** Link with GSASL by default | ... | ... |
imprimatur @ f32ef198
... | @@ -88,12 +88,15 @@ mu_message_create_attachment (const char *content_type, const char *encoding, | ... | @@ -88,12 +88,15 @@ mu_message_create_attachment (const char *content_type, const char *encoding, |
88 | "Content-Transfer-Encoding: %s\n" | 88 | "Content-Transfer-Encoding: %s\n" |
89 | "Content-Disposition: attachment; filename=%s\n\n", | 89 | "Content-Disposition: attachment; filename=%s\n\n", |
90 | content_type, name, encoding, name); | 90 | content_type, name, encoding, name); |
91 | if (ret) | 91 | if (ret == 0) |
92 | { | 92 | { |
93 | if ((ret = mu_header_create (&hdr, header, | 93 | if ((ret = mu_header_create (&hdr, header, |
94 | strlen (header))) == 0) | 94 | strlen (header))) == 0) |
95 | { | 95 | { |
96 | mu_stream_t bstr; | ||
96 | mu_message_get_body (*newmsg, &body); | 97 | mu_message_get_body (*newmsg, &body); |
98 | mu_body_get_streamref (body, &bstr); | ||
99 | |||
97 | if ((ret = mu_file_stream_create (&fstream, filename, | 100 | if ((ret = mu_file_stream_create (&fstream, filename, |
98 | MU_STREAM_READ)) == 0) | 101 | MU_STREAM_READ)) == 0) |
99 | { | 102 | { |
... | @@ -101,10 +104,12 @@ mu_message_create_attachment (const char *content_type, const char *encoding, | ... | @@ -101,10 +104,12 @@ mu_message_create_attachment (const char *content_type, const char *encoding, |
101 | MU_FILTER_ENCODE, | 104 | MU_FILTER_ENCODE, |
102 | MU_STREAM_READ)) == 0) | 105 | MU_STREAM_READ)) == 0) |
103 | { | 106 | { |
104 | mu_body_set_stream (body, tstream, *newmsg); | 107 | mu_stream_copy (bstr, tstream, 0, NULL); |
108 | mu_stream_unref (tstream); | ||
105 | mu_message_set_header (*newmsg, hdr, NULL); | 109 | mu_message_set_header (*newmsg, hdr, NULL); |
106 | } | 110 | } |
107 | } | 111 | } |
112 | mu_stream_unref (bstr); | ||
108 | free (header); | 113 | free (header); |
109 | } | 114 | } |
110 | } | 115 | } | ... | ... |
... | @@ -31,7 +31,9 @@ static char doc[] = N_("GNU mail -- process mail messages.\n" | ... | @@ -31,7 +31,9 @@ static char doc[] = N_("GNU mail -- process mail messages.\n" |
31 | "by the first argument, or the user's mbox, if no argument given.\n"); | 31 | "by the first argument, or the user's mbox, if no argument given.\n"); |
32 | static char args_doc[] = N_("[address...]\n-f [OPTION...] [file]\n--file [OPTION...] [file]\n--file=file [OPTION...]"); | 32 | static char args_doc[] = N_("[address...]\n-f [OPTION...] [file]\n--file [OPTION...] [file]\n--file=file [OPTION...]"); |
33 | 33 | ||
34 | #define F_OPTION 256 | 34 | #define F_OPTION 256 |
35 | #define F_ENCODING 257 | ||
36 | #define F_CONTENT_TYPE 258 | ||
35 | 37 | ||
36 | static struct argp_option options[] = { | 38 | static struct argp_option options[] = { |
37 | { NULL, 'f', NULL, OPTION_HIDDEN, NULL, 0 }, | 39 | { NULL, 'f', NULL, OPTION_HIDDEN, NULL, 0 }, |
... | @@ -57,6 +59,12 @@ static struct argp_option options[] = { | ... | @@ -57,6 +59,12 @@ static struct argp_option options[] = { |
57 | N_("append given header to the message being sent"), 0}, | 59 | N_("append given header to the message being sent"), 0}, |
58 | {"exec", 'E', N_("COMMAND"), 0, | 60 | {"exec", 'E', N_("COMMAND"), 0, |
59 | N_("execute COMMAND"), 0 }, | 61 | N_("execute COMMAND"), 0 }, |
62 | {"encoding", F_ENCODING, N_("NAME"), 0, | ||
63 | N_("set encoding for subsequent --attach options"), 0 }, | ||
64 | {"content-type", F_CONTENT_TYPE, N_("TYPE"), 0, | ||
65 | N_("set content type for subsequent --attach options"), 0 }, | ||
66 | {"attach", 'A', N_("FILE"), 0, | ||
67 | N_("attach FILE"), 0 }, | ||
60 | { NULL, 0, NULL, 0, NULL, 0 } | 68 | { NULL, 0, NULL, 0, NULL, 0 } |
61 | }; | 69 | }; |
62 | 70 | ||
... | @@ -84,6 +92,17 @@ parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -84,6 +92,17 @@ parse_opt (int key, char *arg, struct argp_state *state) |
84 | args->hint |= HINT_SEND_MODE; | 92 | args->hint |= HINT_SEND_MODE; |
85 | send_append_header (arg); | 93 | send_append_header (arg); |
86 | break; | 94 | break; |
95 | |||
96 | case 'A': | ||
97 | args->hint |= HINT_SEND_MODE; | ||
98 | if (send_attach_file (arg)) | ||
99 | exit (1); | ||
100 | break; | ||
101 | |||
102 | case F_CONTENT_TYPE: | ||
103 | free (default_content_type); | ||
104 | default_content_type = mu_strdup (arg); | ||
105 | break; | ||
87 | 106 | ||
88 | case 'e': | 107 | case 'e': |
89 | util_cache_command (&command_list, "setq mode=exist"); | 108 | util_cache_command (&command_list, "setq mode=exist"); |
... | @@ -139,6 +158,11 @@ parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -139,6 +158,11 @@ parse_opt (int key, char *arg, struct argp_state *state) |
139 | case 'E': | 158 | case 'E': |
140 | util_cache_command (&command_list, "%s", arg); | 159 | util_cache_command (&command_list, "%s", arg); |
141 | break; | 160 | break; |
161 | |||
162 | case F_ENCODING: | ||
163 | free (default_encoding); | ||
164 | default_encoding = mu_strdup (arg); | ||
165 | break; | ||
142 | 166 | ||
143 | case 'F': | 167 | case 'F': |
144 | util_cache_command (&command_list, "set byname"); | 168 | util_cache_command (&command_list, "set byname"); | ... | ... |
... | @@ -171,6 +171,8 @@ extern mu_mailbox_t mbox; | ... | @@ -171,6 +171,8 @@ extern mu_mailbox_t mbox; |
171 | extern size_t total; | 171 | extern size_t total; |
172 | extern int interactive; | 172 | extern int interactive; |
173 | extern const char *program_version; | 173 | extern const char *program_version; |
174 | extern char *default_encoding; | ||
175 | extern char *default_content_type; | ||
174 | 176 | ||
175 | /* Functions */ | 177 | /* Functions */ |
176 | extern int mail_alias (int argc, char **argv); | 178 | extern int mail_alias (int argc, char **argv); |
... | @@ -256,6 +258,7 @@ extern char *mail_expand_name (const char *name); | ... | @@ -256,6 +258,7 @@ extern char *mail_expand_name (const char *name); |
256 | 258 | ||
257 | extern void send_append_header (char *text); | 259 | extern void send_append_header (char *text); |
258 | extern void send_append_header2 (char *name, char *value, int mode); | 260 | extern void send_append_header2 (char *name, char *value, int mode); |
261 | extern int send_attach_file (const char *name); | ||
259 | 262 | ||
260 | extern int escape_shell (int argc, char **argv, compose_env_t *env); | 263 | extern int escape_shell (int argc, char **argv, compose_env_t *env); |
261 | extern int escape_command (int argc, char **argv, compose_env_t *env); | 264 | extern int escape_command (int argc, char **argv, compose_env_t *env); | ... | ... |
This diff is collapsed.
Click to expand it.
-
Please register or sign in to post a comment