Improve attachment creation API.
* include/mailutils/message.h (mu_attachment_create) (mu_attachment_copy_from_stream) (mu_attachment_copy_from_file): New functions. * libmailutils/mime/attachment.c: Likewise. (mu_message_create_attachment): Rewrite using the three functions above.
Showing
2 changed files
with
172 additions
and
61 deletions
... | @@ -211,10 +211,21 @@ extern int mu_message_set_bodystructure (mu_message_t msg, | ... | @@ -211,10 +211,21 @@ extern int mu_message_set_bodystructure (mu_message_t msg, |
211 | void *owner); | 211 | void *owner); |
212 | 212 | ||
213 | /* misc functions */ | 213 | /* misc functions */ |
214 | extern int mu_attachment_create (mu_message_t *newmsg, | ||
215 | const char *content_type, | ||
216 | const char *encoding, | ||
217 | const char *name, const char *filename); | ||
218 | extern int mu_attachment_copy_from_stream (mu_message_t att, | ||
219 | mu_stream_t stream, | ||
220 | char const *encoding); | ||
221 | extern int mu_attachment_copy_from_file (mu_message_t att, | ||
222 | char const *filename, | ||
223 | char const *encoding); | ||
214 | extern int mu_message_create_attachment (const char *content_type, | 224 | extern int mu_message_create_attachment (const char *content_type, |
215 | const char *encoding, | 225 | const char *encoding, |
216 | const char *filename, | 226 | const char *filename, |
217 | mu_message_t *newmsg); | 227 | mu_message_t *newmsg); |
228 | |||
218 | extern int mu_message_save_attachment (mu_message_t msg, | 229 | extern int mu_message_save_attachment (mu_message_t msg, |
219 | const char *filename, | 230 | const char *filename, |
220 | mu_mime_io_buffer_t buf); | 231 | mu_mime_io_buffer_t buf); | ... | ... |
... | @@ -55,79 +55,179 @@ struct _mu_mime_io_buffer | ... | @@ -55,79 +55,179 @@ struct _mu_mime_io_buffer |
55 | mu_stream_t fstream; /* output file stream for saving attachment */ | 55 | mu_stream_t fstream; /* output file stream for saving attachment */ |
56 | }; | 56 | }; |
57 | 57 | ||
58 | int | 58 | static int |
59 | mu_message_create_attachment (const char *content_type, const char *encoding, | 59 | at_hdr (mu_header_t hdr, const char *content_type, const char *encoding, |
60 | const char *filename, mu_message_t *newmsg) | 60 | const char *name, const char *filename) |
61 | { | 61 | { |
62 | mu_header_t hdr; | 62 | int rc; |
63 | mu_body_t body; | 63 | char *val, *str; |
64 | mu_stream_t fstream = NULL, tstream = NULL; | ||
65 | char *header = NULL, *name = NULL, *fname = NULL; | ||
66 | int ret; | ||
67 | |||
68 | if (newmsg == NULL) | ||
69 | return MU_ERR_OUT_PTR_NULL; | ||
70 | if (filename == NULL) | ||
71 | return EINVAL; | ||
72 | 64 | ||
73 | if ((ret = mu_message_create (newmsg, NULL)) == 0) | 65 | if (!name) |
74 | { | 66 | { |
75 | if (content_type == NULL) | 67 | if (filename) |
76 | content_type = "text/plain"; | ||
77 | if (encoding == NULL) | ||
78 | encoding = "7bit"; | ||
79 | if ((fname = strdup (filename)) != NULL) | ||
80 | { | 68 | { |
81 | name = strrchr (fname, '/'); | 69 | name = strrchr (filename, '/'); |
82 | if (name) | 70 | if (name) |
83 | name++; | 71 | name++; |
84 | else | 72 | else |
85 | name = fname; | 73 | name = filename; |
86 | ret = mu_asprintf (&header, | ||
87 | "Content-Type: %s; name=%s\n" | ||
88 | "Content-Transfer-Encoding: %s\n" | ||
89 | "Content-Disposition: attachment; filename=%s\n\n", | ||
90 | content_type, name, encoding, name); | ||
91 | if (ret == 0) | ||
92 | { | ||
93 | if ((ret = mu_header_create (&hdr, header, | ||
94 | strlen (header))) == 0) | ||
95 | { | ||
96 | mu_stream_t bstr; | ||
97 | mu_message_get_body (*newmsg, &body); | ||
98 | mu_body_get_streamref (body, &bstr); | ||
99 | |||
100 | if ((ret = mu_file_stream_create (&fstream, filename, | ||
101 | MU_STREAM_READ)) == 0) | ||
102 | { | ||
103 | if ((ret = mu_filter_create (&tstream, fstream, encoding, | ||
104 | MU_FILTER_ENCODE, | ||
105 | MU_STREAM_READ)) == 0) | ||
106 | { | ||
107 | mu_stream_copy (bstr, tstream, 0, NULL); | ||
108 | mu_stream_unref (tstream); | ||
109 | mu_message_set_header (*newmsg, hdr, NULL); | ||
110 | } | ||
111 | } | ||
112 | mu_stream_unref (bstr); | ||
113 | free (header); | ||
114 | } | ||
115 | } | ||
116 | } | 74 | } |
117 | } | 75 | } |
76 | |||
77 | if (name) | ||
78 | { | ||
79 | rc = mu_c_str_escape (name, "\\\"", NULL, &str); | ||
80 | if (rc) | ||
81 | return rc; | ||
82 | rc = mu_asprintf (&val, "%s; name=\"%s\"", content_type, str); | ||
83 | free (str); | ||
84 | if (rc) | ||
85 | return rc; | ||
86 | rc = mu_header_append (hdr, MU_HEADER_CONTENT_TYPE, val); | ||
87 | free (val); | ||
88 | } | ||
89 | else | ||
90 | rc = mu_header_append (hdr, MU_HEADER_CONTENT_TYPE, content_type); | ||
91 | |||
92 | if (rc) | ||
93 | return rc; | ||
94 | |||
95 | if (filename) | ||
96 | { | ||
97 | rc = mu_c_str_escape (filename, "\\\"", NULL, &str); | ||
98 | if (rc) | ||
99 | return rc; | ||
100 | rc = mu_asprintf (&val, "%s; filename=\"%s\"", "attachment", str); | ||
101 | free (str); | ||
102 | if (rc) | ||
103 | return rc; | ||
104 | rc = mu_header_append (hdr, MU_HEADER_CONTENT_DISPOSITION, val); | ||
105 | free (val); | ||
106 | } | ||
107 | else | ||
108 | rc = mu_header_append (hdr, MU_HEADER_CONTENT_DISPOSITION, "attachment"); | ||
109 | if (rc) | ||
110 | return rc; | ||
111 | return mu_header_append (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING, encoding); | ||
112 | } | ||
113 | |||
114 | /* Create in *NEWMSG an empty attachment of given CONTENT_TYPE and ENCODING. | ||
115 | NAME, if not NULL, supplies the name of the attachment. | ||
116 | FILENAME, if not NULL, gives the file name. | ||
117 | */ | ||
118 | int | ||
119 | mu_attachment_create (mu_message_t *newmsg, | ||
120 | const char *content_type, const char *encoding, | ||
121 | const char *name, | ||
122 | const char *filename) | ||
123 | { | ||
124 | int rc; | ||
125 | mu_header_t hdr; | ||
118 | 126 | ||
119 | if (ret) | 127 | if (newmsg == NULL) |
128 | return MU_ERR_OUT_PTR_NULL; | ||
129 | |||
130 | rc = mu_message_create (newmsg, NULL); | ||
131 | if (rc) | ||
132 | return rc; | ||
133 | |||
134 | rc = mu_header_create (&hdr, NULL, 0); | ||
135 | if (rc) | ||
120 | { | 136 | { |
121 | if (*newmsg) | 137 | mu_message_destroy (newmsg, NULL); |
122 | mu_message_destroy (newmsg, NULL); | 138 | return rc; |
123 | if (hdr) | ||
124 | mu_header_destroy (&hdr); | ||
125 | if (fstream) | ||
126 | mu_stream_destroy (&fstream); | ||
127 | if (fname) | ||
128 | free (fname); | ||
129 | } | 139 | } |
130 | return ret; | 140 | mu_message_set_header (*newmsg, hdr, NULL); |
141 | |||
142 | rc = at_hdr (hdr, content_type, encoding, name, filename); | ||
143 | |||
144 | if (rc) | ||
145 | mu_message_destroy (newmsg, NULL); | ||
146 | |||
147 | return rc; | ||
148 | } | ||
149 | |||
150 | /* ATT is an attachment created by a previous call to mu_attachment_create(). | ||
151 | |||
152 | Fills in the attachment body with the data from STREAM using the specified | ||
153 | ENCODING. | ||
154 | */ | ||
155 | int | ||
156 | mu_attachment_copy_from_stream (mu_message_t att, mu_stream_t stream, | ||
157 | char const *encoding) | ||
158 | { | ||
159 | mu_body_t body; | ||
160 | mu_stream_t bstr; | ||
161 | mu_stream_t tstream; | ||
162 | int rc; | ||
163 | |||
164 | mu_message_get_body (att, &body); | ||
165 | rc = mu_body_get_streamref (body, &bstr); | ||
166 | if (rc) | ||
167 | return rc; | ||
168 | |||
169 | rc = mu_filter_create (&tstream, stream, encoding, MU_FILTER_ENCODE, | ||
170 | MU_STREAM_READ); | ||
171 | if (rc == 0) | ||
172 | { | ||
173 | rc = mu_stream_copy (bstr, tstream, 0, NULL); | ||
174 | mu_stream_unref (tstream); | ||
175 | } | ||
176 | mu_stream_unref (bstr); | ||
177 | return rc; | ||
178 | } | ||
179 | |||
180 | /* ATT is an attachment created by a previous call to mu_attachment_create(). | ||
181 | |||
182 | Fills in the attachment body with the data from FILENAME using the specified | ||
183 | ENCODING. | ||
184 | */ | ||
185 | int | ||
186 | mu_attachment_copy_from_file (mu_message_t att, char const *filename, | ||
187 | char const *encoding) | ||
188 | { | ||
189 | mu_stream_t stream; | ||
190 | int rc; | ||
191 | |||
192 | rc = mu_file_stream_create (&stream, filename, MU_STREAM_READ); | ||
193 | if (rc == 0) | ||
194 | { | ||
195 | rc = mu_attachment_copy_from_stream (att, stream, encoding); | ||
196 | mu_stream_unref (stream); | ||
197 | } | ||
198 | return rc; | ||
199 | } | ||
200 | |||
201 | int | ||
202 | mu_message_create_attachment (const char *content_type, const char *encoding, | ||
203 | const char *filename, mu_message_t *newmsg) | ||
204 | { | ||
205 | int rc; | ||
206 | char const *name; | ||
207 | mu_message_t att; | ||
208 | |||
209 | if (content_type == NULL) | ||
210 | content_type = "text/plain"; | ||
211 | if (encoding == NULL) | ||
212 | encoding = "7bit"; | ||
213 | |||
214 | name = strrchr (filename, '/'); | ||
215 | if (name) | ||
216 | name++; | ||
217 | else | ||
218 | name = filename; | ||
219 | |||
220 | rc = mu_attachment_create (&att, content_type, encoding, name, filename); | ||
221 | if (rc == 0) | ||
222 | { | ||
223 | rc = mu_attachment_copy_from_file (att, filename, encoding); | ||
224 | if (rc) | ||
225 | mu_message_destroy (&att, NULL); | ||
226 | } | ||
227 | if (rc == 0) | ||
228 | *newmsg = att; | ||
229 | |||
230 | return rc; | ||
131 | } | 231 | } |
132 | 232 | ||
133 | int | 233 | int | ... | ... |
-
Please register or sign in to post a comment