1 /* Copyright (c) 2006, 2007, 2008 Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H */
34 #include "modest-tny-mime-part.h"
35 #include <tny-simple-list.h>
37 #include <string.h> /* for strlen */
38 #include <modest-tny-msg.h>
39 #include "modest-text-utils.h"
43 modest_tny_mime_part_get_header_value (TnyMimePart *part, const gchar *header)
49 g_return_val_if_fail (part && TNY_IS_MIME_PART(part), NULL);
50 g_return_val_if_fail (header, NULL);
52 pairs = tny_simple_list_new ();
54 tny_mime_part_get_header_pairs (part, pairs);
55 iter = tny_list_create_iterator (pairs);
58 while (!tny_iterator_is_done(iter) && !val) {
60 TnyPair *pair = (TnyPair*)tny_iterator_get_current(iter);
61 if (strcasecmp (header, tny_pair_get_name(pair)) == 0)
62 val = g_strdup (tny_pair_get_value(pair));
63 g_object_unref (pair);
65 tny_iterator_next (iter);
68 g_object_unref (pairs);
69 g_object_unref (iter);
77 /* we consider more things attachments than tinymail does...
80 modest_tny_mime_part_is_attachment_for_modest (TnyMimePart *part)
82 gchar *tmp, *content_type;
83 gboolean has_content_disp_name = FALSE;
85 g_return_val_if_fail (part && TNY_IS_MIME_PART(part), FALSE);
87 /* if tinymail thinks it's an attachment, it definitely is */
88 if (tny_mime_part_is_attachment (part) || tny_mime_part_is_purged (part))
91 /* if the mime part is a message itself (ie. embedded), it's an attachment */
92 if (TNY_IS_MSG (part))
95 tmp = modest_tny_mime_part_get_header_value (part, "Content-Disposition");
97 /* If the Content-Disposition header contains a "name"
98 * parameter, treat the mime part as an attachment */
99 gchar *content_disp = g_ascii_strdown(tmp, -1);
100 gint len = strlen (content_disp);
101 const gchar *substr = g_strstr_len (content_disp, len, "name");
102 if (substr != NULL) {
103 gint substrlen = len - (substr - content_disp);
104 /* The parameter can appear in muliple
105 * ways. See RFC 2231 for details */
106 has_content_disp_name =
107 g_strstr_len (substr, substrlen, "name=") != NULL ||
108 g_strstr_len (substr, substrlen, "name*=") != NULL ||
109 g_strstr_len (substr, substrlen, "name*0=") != NULL ||
110 g_strstr_len (substr, substrlen, "name*0*=") != NULL;
113 g_free (content_disp);
116 /* if it doesn't have a content deposition with a name= attribute, it's not an attachment */
117 if (!has_content_disp_name)
120 /* ok, it must be content-disposition "inline" then, because "attachment"
121 * is already handle above "...is_attachment". modest consider these "inline" things
122 * attachments as well, unless they are embedded images for html mail
124 content_type = g_ascii_strdown (tny_mime_part_get_content_type (part), -1);
125 if (!g_str_has_prefix (content_type, "image/")) {
126 g_free (content_type);
127 return TRUE; /* it's not an image, so it must be an attachment */
129 g_free (content_type);
132 /* now, if it's an inline-image, and it has a content-id or location, we
133 * we guess it's an inline image, and not an attachment */
134 if (tny_mime_part_get_content_id (part) || tny_mime_part_get_content_location(part))
137 /* in other cases... */
142 modest_tny_mime_part_is_msg (TnyMimePart *part)
144 const gchar *content_type;
146 if (!TNY_IS_MSG (part))
149 content_type = tny_mime_part_get_content_type (part);
150 if ((g_str_has_prefix (content_type, "message/rfc822") ||
151 g_str_has_prefix (content_type, "multipart/") ||
152 g_str_has_prefix (content_type, "text/"))) {
160 modest_tny_mime_part_to_string (TnyMimePart *part, gint indent)
164 GString *indent_prefix;
165 TnyList *list, *pairs_list;
166 TnyIterator *iter, *pairs_iter;
168 indent_prefix = g_string_new ("");
169 for (i = 0; i < indent; i++) {
170 indent_prefix = g_string_append_c (indent_prefix, ' ');
173 if (TNY_IS_MSG (part)) {
176 header = tny_msg_get_header (TNY_MSG (part));
177 g_print ("(%s(MSG))\n", indent_prefix->str);
178 g_object_unref (header);
181 list = tny_simple_list_new ();
182 tny_mime_part_get_parts (part, list);
183 pairs_list = tny_simple_list_new ();
184 tny_mime_part_get_header_pairs (part, pairs_list);
185 g_print ("%s(content=%s parts=%d location=%s)\n", indent_prefix->str,
186 tny_mime_part_get_content_type (part),
187 tny_list_get_length (list),
188 tny_mime_part_get_content_location (part));
189 for (pairs_iter = tny_list_create_iterator (pairs_list);
190 !tny_iterator_is_done (pairs_iter);
191 tny_iterator_next (pairs_iter)) {
192 TnyPair *pair = TNY_PAIR (tny_iterator_get_current (pairs_iter));
193 g_print ("%s(%s:%s)\n", indent_prefix->str, tny_pair_get_name (pair), tny_pair_get_value (pair));
194 g_object_unref (pair);
196 for (iter = tny_list_create_iterator (list);
197 !tny_iterator_is_done (iter);
198 tny_iterator_next (iter)) {
200 child = (TnyMimePart *) tny_iterator_get_current (iter);
201 modest_tny_mime_part_to_string (child, indent + 3);
202 g_object_unref (child);
204 g_object_unref (iter);
205 g_object_unref (list);
207 g_string_free (indent_prefix, TRUE);
211 modest_tny_mime_part_get_headers_content_type (TnyMimePart *part)
213 gchar *header_content_type;
216 g_return_val_if_fail (TNY_IS_MIME_PART (part), NULL);
218 header_content_type = modest_tny_mime_part_get_header_value (part, "Content-Type");
220 /* See RFC2045 sec 5.2 */
221 if (!header_content_type)
222 return g_strdup ("text/plain; charset=us-ascii");
224 header_content_type = g_strstrip (header_content_type);
226 /* remove the ; suffix */
227 suffix = index (header_content_type, ';');
231 return g_ascii_strdown (header_content_type, -1);
235 modest_tny_mime_part_get_content_type (TnyMimePart *part)
237 const gchar *content_type;
238 gchar *retval = NULL;
240 g_return_val_if_fail (TNY_IS_MIME_PART (part), NULL);
241 content_type = tny_mime_part_get_content_type (part);
243 if (g_str_has_prefix (content_type, "message/rfc822")) {
244 retval = modest_tny_mime_part_get_headers_content_type (part);
247 if (retval == NULL) {
248 retval = g_ascii_strdown (content_type, -1);