mail: new options to read attachments from file descriptors
* mail/mail.c (default_encoding,default_content_type) (content_name,content_filename): New statics. (cli_attach): Use the value of --content-name option as the content-type name parameter. The "-" argument instructs the program to read attachment from stdin (eqv --attach-fd=0) (cli_attach_fd): New function. (mail_options): New options: --content-name, --content-filename, --attach-fd * mail/mail.h (send_attach_file_default): Remove. (send_attach_file): New proto. * mail/send.c (atchinfo): New fields: id, name, source. (atchinfo_free): Update. (default_encoding,default_content_type): Remove globals. (send_attach_file): Rewrite. (send_attach_file_default): Remove. (escape_list_attachments): Print attachment identifier instead of the file name, which can be NULL. (saveatt): Use mu_attachment_create and mu_attachment_copy_from_stream. * NEWS: Update. * doc/texinfo/programs.texi: Document the new options.
Showing
5 changed files
with
321 additions
and
37 deletions
1 | GNU mailutils NEWS -- history of user-visible changes. 2016-12-17 | 1 | GNU mailutils NEWS -- history of user-visible changes. 2017-01-13 |
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 | ||
... | @@ -7,6 +7,54 @@ Please send mailutils bug reports to <bug-mailutils@gnu.org>. | ... | @@ -7,6 +7,54 @@ Please send mailutils bug reports to <bug-mailutils@gnu.org>. |
7 | 7 | ||
8 | Version 3.1.90 (Git) | 8 | Version 3.1.90 (Git) |
9 | 9 | ||
10 | |||
11 | |||
12 | ** Modifying attachment name and filename | ||
13 | |||
14 | Two new options are provided for modifying attachment name (a.k.a | ||
15 | description), and file name: | ||
16 | |||
17 | --content-name=STRING | ||
18 | Sets the attachment name (description). Technically speaking, it | ||
19 | is the "name" parameter in the Content-Type MIME header. | ||
20 | |||
21 | --content-filename=NAME | ||
22 | Sets the file name (the "filename" parameter in the | ||
23 | Content-Description MIME header of the outgoing message. | ||
24 | |||
25 | Both options affect only the next `--attach' or `--attach-fd' option. | ||
26 | |||
27 | * Constructing attachments from command line | ||
28 | |||
29 | The new option `--attach-fd=N' instructs mail to read attachment from | ||
30 | file descriptor N. By default, the attachments created using this | ||
31 | option are unnamed, i.e. neither name parameter of the Content-Type | ||
32 | header, nor the filename parameter of the Content-Disposition header | ||
33 | are set. Use the --content-name and --content-filename options to | ||
34 | change these. | ||
35 | |||
36 | The option `--attach-fd=0' causes attachment to be read from the | ||
37 | standard input. The option `--attach=-' has the same effect. For | ||
38 | obvious reasons, the interactive mode is suppressed in this case. | ||
39 | |||
40 | The `--attach-fd' option is useful when calling `mail' from another | ||
41 | program. | ||
42 | |||
43 | Example: | ||
44 | |||
45 | Suppose that the 'mail' binary is opened at file descriptor 5 and | ||
46 | the mail.c file is opened at descriptor 6, the following command | ||
47 | line sends them as attachments: | ||
48 | |||
49 | mail --encoding=base64 \ | ||
50 | --content-type=application/octet-stream \ | ||
51 | --content-name="the mail(1) binary" --content-filename="mail" \ | ||
52 | --attach-fd=5 \ | ||
53 | --encoding=binary\ | ||
54 | --content-type=text/plain --content-name="mail.c source file"\ | ||
55 | --content-filename=mail.c --attach-fd=6 \ | ||
56 | root@example.org | ||
57 | |||
10 | 58 | ||
11 | Version 3.1.1 - 2016-12-15 | 59 | Version 3.1.1 - 2016-12-15 |
12 | 60 | ... | ... |
... | @@ -2915,6 +2915,7 @@ Configuration Files}, for a detailed description of their format. | ... | @@ -2915,6 +2915,7 @@ Configuration Files}, for a detailed description of their format. |
2915 | * Invoking Mail:: Command Line Options. | 2915 | * Invoking Mail:: Command Line Options. |
2916 | * Specifying Messages:: How to Specify Message Sets. | 2916 | * Specifying Messages:: How to Specify Message Sets. |
2917 | * Composing Mail:: Composing Mail. | 2917 | * Composing Mail:: Composing Mail. |
2918 | * Attachments:: Attaching Files. | ||
2918 | * Reading Mail:: Reading Mail. | 2919 | * Reading Mail:: Reading Mail. |
2919 | * Scripting:: Scripting. | 2920 | * Scripting:: Scripting. |
2920 | * Mail Variables:: How to Alter the Behavior of @command{mail}. | 2921 | * Mail Variables:: How to Alter the Behavior of @command{mail}. |
... | @@ -2938,9 +2939,22 @@ mail sending mode, otherwise it operates in mail reading mode. | ... | @@ -2938,9 +2939,22 @@ mail sending mode, otherwise it operates in mail reading mode. |
2938 | @table @option | 2939 | @table @option |
2939 | @item -A @var{file} | 2940 | @item -A @var{file} |
2940 | @itemx --attach=@var{file} | 2941 | @itemx --attach=@var{file} |
2941 | Attach @var{file} to the composed message. The encoding and content | 2942 | Attach @var{file} to the composed message. The encoding, content |
2942 | type are controlled by the @option{--encoding} and | 2943 | type, and content description are controlled by the |
2943 | @option{--content-type} options, correspondingly. | 2944 | @option{--encoding}, @option{--content-type}, and |
2945 | @option{--content-name} options, correspondingly. | ||
2946 | |||
2947 | The option @option{--attach=-} instructs @command{mail} to read the | ||
2948 | file to be attached from the standard input. Interactive shell is | ||
2949 | disabled in this case. | ||
2950 | |||
2951 | @item --attach-fd=@var{fd} | ||
2952 | Read attachment body from the file descriptor @var{fd}. The | ||
2953 | descriptor must be open for reading. This option is useful when | ||
2954 | calling @command{mail} from another program. | ||
2955 | |||
2956 | See the options @option{--encoding}, @option{--content-type}, | ||
2957 | @option{--content-name}, and @option{--content-filename}. | ||
2944 | 2958 | ||
2945 | @item -a @var{header}:@var{value} | 2959 | @item -a @var{header}:@var{value} |
2946 | @itemx --append=@var{header}:@var{value} | 2960 | @itemx --append=@var{header}:@var{value} |
... | @@ -2950,6 +2964,14 @@ Append the given header to the composed message. | ... | @@ -2950,6 +2964,14 @@ Append the given header to the composed message. |
2950 | This options sets the content type to be used by all subsequent | 2964 | This options sets the content type to be used by all subsequent |
2951 | @option{--attach} options. | 2965 | @option{--attach} options. |
2952 | 2966 | ||
2967 | @item --content-filename=@var{name} | ||
2968 | Set the @samp{filename} parameter in the @samp{Content-Disposition} | ||
2969 | header for the next @option{--attach-fd} option. | ||
2970 | |||
2971 | @item --content-name=@var{text} | ||
2972 | Set the @samp{name} parameter (description) in the @samp{Content-Type} | ||
2973 | header for the next @option{--attach} or @option{--attach-fd} option. | ||
2974 | |||
2953 | @item -E @var{command} | 2975 | @item -E @var{command} |
2954 | @itemx --exec=@var{command} | 2976 | @itemx --exec=@var{command} |
2955 | Execute @var{command} before opening the mailbox. Any number of | 2977 | Execute @var{command} before opening the mailbox. Any number of |
... | @@ -3412,6 +3434,115 @@ the old contents of your message. | ... | @@ -3412,6 +3434,115 @@ the old contents of your message. |
3412 | 3434 | ||
3413 | @c ********************************************************************* | 3435 | @c ********************************************************************* |
3414 | 3436 | ||
3437 | @node Attachments | ||
3438 | @subsection Sending Attachments | ||
3439 | |||
3440 | The simplest way to attach a file from command line is by using the | ||
3441 | @option{--attach} (@option{-A}) option. Its argument specifies the | ||
3442 | file to attach. For example, the following will attach the content | ||
3443 | of the file @file{archive.tar}: | ||
3444 | |||
3445 | @example | ||
3446 | $ mail --attach=archive.tar | ||
3447 | @end example | ||
3448 | |||
3449 | By default, the content type will be set to | ||
3450 | @samp{application/octet-stream}, and the attachment will be encoded | ||
3451 | using the @samp{base64} encoding. To change the content type, use the | ||
3452 | @option{--content-type} option. For example, to send an HTML | ||
3453 | attachment: | ||
3454 | |||
3455 | @example | ||
3456 | $ mail --content-type=text/html --attach=in.html | ||
3457 | @end example | ||
3458 | |||
3459 | The @option{--content-type} option affects all @option{--attach} | ||
3460 | options that follow it. To change the content type, simply add | ||
3461 | another @option{--content-type} option. For example, to send both | ||
3462 | the HTML file and the archive: | ||
3463 | |||
3464 | @example | ||
3465 | $ mail --content-type=text/html --attach=in.html \ | ||
3466 | --content-type=application/x-tar --attach=archive.tar | ||
3467 | @end example | ||
3468 | |||
3469 | Similarly, the encoding to use is set up by the @option{--encoding} | ||
3470 | option. As well as @option{--content-type}, this option affects all | ||
3471 | attachments supplied after it in the command line, until changed by | ||
3472 | the eventual next appearance of the same option. Extending the above | ||
3473 | example: | ||
3474 | |||
3475 | @example | ||
3476 | $ mail --content-type=text/html --encoding=quoted-printable \ | ||
3477 | --attach=in.html \ | ||
3478 | --content-type=application/x-tar --encoding=base64 \ | ||
3479 | --attach=archive.tar | ||
3480 | @end example | ||
3481 | |||
3482 | Each attachment can also be assigned a @dfn{description} and a | ||
3483 | @dfn{file name}. Normally, these are the same as the file name | ||
3484 | supplied with the @option{--attach} option. However, you can change | ||
3485 | either or both of them using the @option{--content-name} and | ||
3486 | @option{--content-filename}, correspondingly. Both of these options | ||
3487 | affect only the next @option{--attach} (or @option{--attach-fd}, see | ||
3488 | below) option. | ||
3489 | |||
3490 | All the examples above will enter the usual interactive shell, | ||
3491 | allowing you to compose the body of the message. If that's not | ||
3492 | needed, the non-interactive use can be forced by redirecting | ||
3493 | @file{/dev/null} to the standard input, e.g.: | ||
3494 | |||
3495 | @example | ||
3496 | $ mail --attach=archive.tar < /dev/null | ||
3497 | @end example | ||
3498 | |||
3499 | This will normally produce a message saying: | ||
3500 | |||
3501 | @example | ||
3502 | mail: Null message body; hope that's ok | ||
3503 | @end example | ||
3504 | |||
3505 | To suppress this message, unset the @samp{nullbodymsg} variable, | ||
3506 | as shown in the example below: | ||
3507 | |||
3508 | @example | ||
3509 | $ mail -E 'set nonullbodymsg' --attach=archive.tar < /dev/null | ||
3510 | @end example | ||
3511 | |||
3512 | The option @option{--attach=-} forces @command{mail} to read the file | ||
3513 | to be attached from the standard input stream. This option implies | ||
3514 | disables the interactive mode and sets @samp{nonullbodymsg} | ||
3515 | implicitly, so that the above example can be rewritten as: | ||
3516 | |||
3517 | @example | ||
3518 | $ mail --attach=- < archive.tar | ||
3519 | @end example | ||
3520 | |||
3521 | Special option is provided to facilitate the use of @command{mail} | ||
3522 | in scripts. The @option{--attach-fd=@var{N}} instructs the program to | ||
3523 | read the data to be attached from the file descriptor @var{N}. The | ||
3524 | above example is equivalent to: | ||
3525 | |||
3526 | @example | ||
3527 | $ mail --attach-fd=0 < archive.tar | ||
3528 | @end example | ||
3529 | |||
3530 | Attachments created using this option have neither filename not | ||
3531 | description set, so normally the use of @option{--content-name} and/or | ||
3532 | @option{--content-filename} is advised. | ||
3533 | |||
3534 | @example | ||
3535 | $ mail --subject 'mail(1)' \ | ||
3536 | --content-name="The mail(1) binary" --content-filename="mail" \ | ||
3537 | --attach-fd 5 \ | ||
3538 | --encoding=binary --content-type=text/plain \ | ||
3539 | --content-name="mail.c source file" --content-filename=mail.c \ | ||
3540 | --attach-fd 6 gray@@example.org 5</usr/bin/mail \ | ||
3541 | 6<mailutils/mail/mail.c | ||
3542 | @end example | ||
3543 | |||
3544 | @c ********************************************************************* | ||
3545 | |||
3415 | @node Reading Mail | 3546 | @node Reading Mail |
3416 | @subsection Reading Mail | 3547 | @subsection Reading Mail |
3417 | 3548 | ... | ... |
... | @@ -35,6 +35,11 @@ const char *program_version = "mail (" PACKAGE_STRING ")"; | ... | @@ -35,6 +35,11 @@ const char *program_version = "mail (" PACKAGE_STRING ")"; |
35 | int hint; | 35 | int hint; |
36 | char *file; | 36 | char *file; |
37 | char *user; | 37 | char *user; |
38 | |||
39 | char *default_encoding; | ||
40 | char *default_content_type; | ||
41 | char *content_name; | ||
42 | char *content_filename; | ||
38 | 43 | ||
39 | static void | 44 | static void |
40 | cli_f_option (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | 45 | cli_f_option (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
... | @@ -134,9 +139,45 @@ cli_append (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ... | @@ -134,9 +139,45 @@ cli_append (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
134 | static void | 139 | static void |
135 | cli_attach (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | 140 | cli_attach (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
136 | { | 141 | { |
142 | int fd = -1; | ||
143 | |||
137 | hint |= HINT_SEND_MODE; | 144 | hint |= HINT_SEND_MODE; |
138 | if (send_attach_file_default (arg)) | 145 | if (strcmp (arg, "-") == 0) |
146 | { | ||
147 | arg = NULL; | ||
148 | fd = 0; | ||
149 | } | ||
150 | if (send_attach_file (fd, arg, content_filename, content_name, | ||
151 | default_content_type, default_encoding)) | ||
139 | exit (1); | 152 | exit (1); |
153 | |||
154 | free (content_name); | ||
155 | content_name = NULL; | ||
156 | free (content_filename); | ||
157 | content_filename = NULL; | ||
158 | } | ||
159 | |||
160 | static void | ||
161 | cli_attach_fd (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
162 | { | ||
163 | int rc, fd; | ||
164 | |||
165 | hint |= HINT_SEND_MODE; | ||
166 | rc = mu_str_to_c (arg, mu_c_int, &fd, NULL); | ||
167 | if (rc) | ||
168 | { | ||
169 | mu_parseopt_error (po, _("%s: bad descriptor"), arg); | ||
170 | exit (po->po_exit_error); | ||
171 | } | ||
172 | |||
173 | if (send_attach_file (fd, NULL, content_filename, content_name, | ||
174 | default_content_type, default_encoding)) | ||
175 | exit (1); | ||
176 | |||
177 | free (content_name); | ||
178 | content_name = NULL; | ||
179 | free (content_filename); | ||
180 | content_filename = NULL; | ||
140 | } | 181 | } |
141 | 182 | ||
142 | static struct mu_option mail_options[] = { | 183 | static struct mu_option mail_options[] = { |
... | @@ -212,10 +253,21 @@ static struct mu_option mail_options[] = { | ... | @@ -212,10 +253,21 @@ static struct mu_option mail_options[] = { |
212 | N_("set content type for subsequent --attach options"), | 253 | N_("set content type for subsequent --attach options"), |
213 | mu_c_string, &default_content_type }, | 254 | mu_c_string, &default_content_type }, |
214 | 255 | ||
256 | { "content-name", 0, N_("NAME"), MU_OPTION_DEFAULT, | ||
257 | N_("set the Content-Type name parameter for the next --attach option"), | ||
258 | mu_c_string, &content_name }, | ||
259 | { "content-filename", 0, N_("NAME"), MU_OPTION_DEFAULT, | ||
260 | N_("set the Content-Disposition filename parameter for the next --attach option"), | ||
261 | mu_c_string, &content_filename }, | ||
262 | |||
215 | { "attach", 'A', N_("FILE"), MU_OPTION_DEFAULT, | 263 | { "attach", 'A', N_("FILE"), MU_OPTION_DEFAULT, |
216 | N_("attach FILE"), | 264 | N_("attach FILE"), |
217 | mu_c_string, NULL, cli_attach }, | 265 | mu_c_string, NULL, cli_attach }, |
218 | 266 | ||
267 | { "attach-fd", 0, N_("FD"), MU_OPTION_DEFAULT, | ||
268 | N_("attach from file descriptor FD"), | ||
269 | mu_c_string, NULL, cli_attach_fd }, | ||
270 | |||
219 | MU_OPTION_END | 271 | MU_OPTION_END |
220 | }, *options[] = { mail_options, NULL }; | 272 | }, *options[] = { mail_options, NULL }; |
221 | 273 | ... | ... |
... | @@ -258,7 +258,11 @@ extern char *mail_expand_name (const char *name); | ... | @@ -258,7 +258,11 @@ extern char *mail_expand_name (const char *name); |
258 | 258 | ||
259 | extern void send_append_header (char const *text); | 259 | extern void send_append_header (char const *text); |
260 | extern void send_append_header2 (char const *name, char const *value, int mode); | 260 | extern void send_append_header2 (char const *name, char const *value, int mode); |
261 | extern int send_attach_file_default (const char *name); | 261 | extern int send_attach_file (int fd, |
262 | const char *filename, | ||
263 | const char *content_filename, | ||
264 | const char *content_name, | ||
265 | const char *content_type, const char *encoding); | ||
262 | 266 | ||
263 | extern int escape_check_args (int argc, char **argv, int minargs, int maxargs); | 267 | extern int escape_check_args (int argc, char **argv, int minargs, int maxargs); |
264 | 268 | ... | ... |
... | @@ -134,55 +134,97 @@ mail_sendheader (int argc, char **argv) | ... | @@ -134,55 +134,97 @@ mail_sendheader (int argc, char **argv) |
134 | /* Attachments */ | 134 | /* Attachments */ |
135 | struct atchinfo | 135 | struct atchinfo |
136 | { | 136 | { |
137 | char *id; | ||
137 | char *encoding; | 138 | char *encoding; |
138 | char *content_type; | 139 | char *content_type; |
140 | char *name; | ||
139 | char *filename; | 141 | char *filename; |
142 | mu_stream_t source; | ||
140 | }; | 143 | }; |
141 | 144 | ||
142 | static mu_list_t attlist; | 145 | static mu_list_t attlist; |
143 | 146 | ||
144 | char *default_encoding; | ||
145 | char *default_content_type; | ||
146 | |||
147 | static void | 147 | static void |
148 | atchinfo_free (void *p) | 148 | atchinfo_free (void *p) |
149 | { | 149 | { |
150 | struct atchinfo *ap = p; | 150 | struct atchinfo *ap = p; |
151 | free (ap->id); | ||
151 | free (ap->encoding); | 152 | free (ap->encoding); |
152 | free (ap->content_type); | 153 | free (ap->content_type); |
154 | free (ap->name); | ||
153 | free (ap->filename); | 155 | free (ap->filename); |
156 | mu_stream_destroy (&ap->source); | ||
154 | free (ap); | 157 | free (ap); |
155 | } | 158 | } |
156 | 159 | ||
157 | int | 160 | int |
158 | send_attach_file (const char *name, | 161 | send_attach_file (int fd, |
162 | const char *realname, | ||
163 | const char *content_filename, const char *content_name, | ||
159 | const char *content_type, const char *encoding) | 164 | const char *content_type, const char *encoding) |
160 | { | 165 | { |
161 | int rc; | 166 | int rc; |
162 | struct stat st; | 167 | struct stat st; |
163 | struct atchinfo *aptr; | 168 | struct atchinfo *aptr; |
164 | mu_list_t list; | 169 | mu_list_t list; |
165 | 170 | mu_stream_t stream = NULL; | |
166 | if (stat (name, &st)) | 171 | char *id = NULL; |
172 | |||
173 | if (fd >= 0) | ||
167 | { | 174 | { |
168 | if (errno == ENOENT) | 175 | rc = mu_fd_stream_create (&stream, NULL, fd, MU_STREAM_READ); |
176 | if (rc) | ||
169 | { | 177 | { |
170 | mu_error (_("%s: file does not exist"), name); | 178 | mu_error (_("can't open descriptor %d: %s"), fd, mu_strerror (rc)); |
171 | return 1; | 179 | return 1; |
172 | } | 180 | } |
173 | else | 181 | mu_asprintf (&id, "fd %d", fd); |
182 | if (fd == 0) | ||
174 | { | 183 | { |
175 | mu_error (_("%s: cannot stat: %s"), name, mu_strerror (errno)); | 184 | mu_stream_destroy (&mu_strin); |
176 | return 1; | 185 | mu_nullstream_create (&mu_strin, MU_STREAM_READ); |
186 | mu_stream_ioctl (mu_strin, MU_IOCTL_NULLSTREAM, | ||
187 | MU_IOCTL_NULLSTREAM_SET_PATTERN, NULL); | ||
188 | util_do_command ("set nullbody nullbodymsg"); | ||
177 | } | 189 | } |
178 | } | 190 | } |
179 | 191 | else if (realname) | |
180 | if (!S_ISREG (st.st_mode)) | ||
181 | { | 192 | { |
182 | mu_error (_("%s: not a regular file"), name); | 193 | if (!content_filename) |
183 | return 1; | 194 | content_filename = realname; |
184 | } | 195 | if (stat (realname, &st)) |
196 | { | ||
197 | if (errno == ENOENT) | ||
198 | { | ||
199 | mu_error (_("%s: file does not exist"), realname); | ||
200 | return 1; | ||
201 | } | ||
202 | else | ||
203 | { | ||
204 | mu_error (_("%s: cannot stat: %s"), realname, | ||
205 | mu_strerror (errno)); | ||
206 | return 1; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | if (!S_ISREG (st.st_mode)) | ||
211 | { | ||
212 | mu_error (_("%s: not a regular file"), realname); | ||
213 | return 1; | ||
214 | } | ||
185 | 215 | ||
216 | rc = mu_mapfile_stream_create (&stream, realname, MU_STREAM_READ); | ||
217 | if (rc) | ||
218 | { | ||
219 | mu_error (_("can't open file %s: %s"), | ||
220 | realname, mu_strerror (rc)); | ||
221 | return 1; | ||
222 | } | ||
223 | mu_asprintf (&id, "\"%s\"", realname); | ||
224 | } | ||
225 | else | ||
226 | abort (); | ||
227 | |||
186 | if (!encoding) | 228 | if (!encoding) |
187 | encoding = "base64"; | 229 | encoding = "base64"; |
188 | mu_filter_get_list (&list); | 230 | mu_filter_get_list (&list); |
... | @@ -190,6 +232,8 @@ send_attach_file (const char *name, | ... | @@ -190,6 +232,8 @@ send_attach_file (const char *name, |
190 | if (rc) | 232 | if (rc) |
191 | { | 233 | { |
192 | mu_error (_("unsupported encoding: %s"), encoding); | 234 | mu_error (_("unsupported encoding: %s"), encoding); |
235 | free (id); | ||
236 | mu_stream_destroy (&stream); | ||
193 | return 1; | 237 | return 1; |
194 | } | 238 | } |
195 | 239 | ||
... | @@ -205,11 +249,13 @@ send_attach_file (const char *name, | ... | @@ -205,11 +249,13 @@ send_attach_file (const char *name, |
205 | } | 249 | } |
206 | aptr = mu_alloc (sizeof (*aptr)); | 250 | aptr = mu_alloc (sizeof (*aptr)); |
207 | 251 | ||
252 | aptr->id = id; | ||
208 | aptr->encoding = mu_strdup (encoding); | 253 | aptr->encoding = mu_strdup (encoding); |
209 | aptr->content_type = mu_strdup (content_type ? | 254 | aptr->content_type = mu_strdup (content_type ? |
210 | content_type : | 255 | content_type : "application/octet-stream"); |
211 | "application/octet-stream"); | 256 | aptr->name = content_name ? mu_strdup (content_name) : NULL; |
212 | aptr->filename = mu_strdup (name); | 257 | aptr->filename = content_filename ? mu_strdup (content_filename) : NULL; |
258 | aptr->source = stream; | ||
213 | rc = mu_list_append (attlist, aptr); | 259 | rc = mu_list_append (attlist, aptr); |
214 | if (rc) | 260 | if (rc) |
215 | { | 261 | { |
... | @@ -220,12 +266,6 @@ send_attach_file (const char *name, | ... | @@ -220,12 +266,6 @@ send_attach_file (const char *name, |
220 | } | 266 | } |
221 | 267 | ||
222 | int | 268 | int |
223 | send_attach_file_default (const char *name) | ||
224 | { | ||
225 | return send_attach_file (name, default_content_type, default_encoding); | ||
226 | } | ||
227 | |||
228 | int | ||
229 | escape_list_attachments (int argc, char **argv, compose_env_t *env) | 269 | escape_list_attachments (int argc, char **argv, compose_env_t *env) |
230 | { | 270 | { |
231 | mu_iterator_t itr; | 271 | mu_iterator_t itr; |
... | @@ -246,7 +286,7 @@ escape_list_attachments (int argc, char **argv, compose_env_t *env) | ... | @@ -246,7 +286,7 @@ escape_list_attachments (int argc, char **argv, compose_env_t *env) |
246 | continue; | 286 | continue; |
247 | 287 | ||
248 | mu_printf ("%3d %-12s %-30s %-s\n", | 288 | mu_printf ("%3d %-12s %-30s %-s\n", |
249 | i, aptr->filename, aptr->content_type, aptr->encoding); | 289 | i, aptr->id, aptr->content_type, aptr->encoding); |
250 | } | 290 | } |
251 | mu_iterator_destroy (&itr); | 291 | mu_iterator_destroy (&itr); |
252 | 292 | ||
... | @@ -266,7 +306,8 @@ escape_attach (int argc, char **argv, compose_env_t *env) | ... | @@ -266,7 +306,8 @@ escape_attach (int argc, char **argv, compose_env_t *env) |
266 | case 3: | 306 | case 3: |
267 | content_type = argv[2]; | 307 | content_type = argv[2]; |
268 | case 2: | 308 | case 2: |
269 | return send_attach_file (argv[1], content_type, encoding); | 309 | return send_attach_file (-1, argv[1], argv[1], argv[1], |
310 | content_type, encoding); | ||
270 | default: | 311 | default: |
271 | return escape_check_args (argc, argv, 2, 4); | 312 | return escape_check_args (argc, argv, 2, 4); |
272 | } | 313 | } |
... | @@ -309,12 +350,20 @@ saveatt (void *item, void *data) | ... | @@ -309,12 +350,20 @@ saveatt (void *item, void *data) |
309 | int rc; | 350 | int rc; |
310 | size_t nparts; | 351 | size_t nparts; |
311 | char *p; | 352 | char *p; |
312 | 353 | ||
313 | rc = mu_message_create_attachment (aptr->content_type, aptr->encoding, | 354 | rc = mu_attachment_create (&part, aptr->content_type, aptr->encoding, |
314 | aptr->filename, &part); | 355 | aptr->name, aptr->filename); |
356 | if (rc) | ||
357 | { | ||
358 | mu_error (_("can't create attachment %s: %s"), | ||
359 | aptr->id, mu_strerror (rc)); | ||
360 | return 1; | ||
361 | } | ||
362 | |||
363 | rc = mu_attachment_copy_from_stream (part, aptr->source, aptr->encoding); | ||
315 | if (rc) | 364 | if (rc) |
316 | { | 365 | { |
317 | mu_error (_("cannot attach \"%s\": %s"), aptr->filename, | 366 | mu_error (_("cannot attach %s: %s"), aptr->filename, |
318 | mu_strerror (rc)); | 367 | mu_strerror (rc)); |
319 | return 1; | 368 | return 1; |
320 | } | 369 | } | ... | ... |
-
Please register or sign in to post a comment