Commit 8ad47471 8ad474712f6758cdff637c5391867706957dfd74 by Sergey Poznyakoff

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.
1 parent ca45a7aa
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
1 Subproject commit 04255b6d5551952b4e0c94da15988f573e3e9fc4 1 Subproject commit f32ef1983968e755cd580b06e369476d7e7f88b6
......
...@@ -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);
......