No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | e-mail-parser-application-mbox.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | e-mail-parser-application-mbox.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /*
2 * e-mail-parser-application-mbox.c
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
16 *
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include "e-mail-format-extensions.h"
24
25 #include <glib-object.h>
26 #include <glib/gi18n-lib.h>
27
28 #include <em-format/e-mail-parser-extension.h>
29 #include <em-format/e-mail-parser.h>
30 #include <em-format/e-mail-part-utils.h>
31 #include <e-util/e-util.h>
32
33 #include <camel/camel.h>
34
35 #include <string.h>
36
37 typedef struct _EMailParserApplicationMBox {
38 GObject parent;
39 } EMailParserApplicationMBox;
40
41 typedef struct _EMailParserApplicationMBoxClass {
42 GObjectClass parent_class;
43 } EMailParserApplicationMBoxClass;
44
45 static void e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface);
46 static void e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface);
47
48 G_DEFINE_TYPE_EXTENDED (
49 EMailParserApplicationMBox,
50 e_mail_parser_application_mbox,
51 G_TYPE_OBJECT,
52 0,
53 G_IMPLEMENT_INTERFACE (
54 E_TYPE_MAIL_EXTENSION,
55 e_mail_parser_mail_extension_interface_init)
56 G_IMPLEMENT_INTERFACE (
57 E_TYPE_MAIL_PARSER_EXTENSION,
58 e_mail_parser_parser_extension_interface_init));
59
60 static const gchar * parser_mime_types[] = { "application/mbox",
61 NULL };
62
63 static GSList *
64 empe_app_mbox_parse (EMailParserExtension *extension,
65 EMailParser *parser,
66 CamelMimePart *part,
67 GString *part_id,
68 GCancellable *cancellable)
69 {
70 CamelMimeParser *mime_parser;
71 CamelStream *mem_stream;
72 camel_mime_parser_state_t state;
73 gint old_len;
74 gint messages;
75 GSList *parts;
76 GError *error = NULL;
77
78 if (g_cancellable_is_cancelled (cancellable))
79 return NULL;
80
81 /* Extract messages from the application/mbox part and
82 * render them as a flat list of messages. */
83
84 /* XXX If the mbox has multiple messages, maybe render them
85 * as a multipart/digest so each message can be expanded
86 * or collapsed individually.
87 *
88 * See attachment_handler_mail_x_uid_list() for example. */
89
90 /* XXX This is based on em_utils_read_messages_from_stream().
91 * Perhaps refactor that function to return an array of
92 * messages instead of assuming we want to append them
93 * to a folder? */
94
95 mime_parser = camel_mime_parser_new ();
96 camel_mime_parser_scan_from (mime_parser, TRUE);
97
98 mem_stream = camel_stream_mem_new ();
99 camel_data_wrapper_decode_to_stream_sync (
100 camel_medium_get_content (CAMEL_MEDIUM (part)),
101 mem_stream, NULL, NULL);
102 g_seekable_seek (G_SEEKABLE (mem_stream), 0, G_SEEK_SET, cancellable, NULL);
103
104 camel_mime_parser_init_with_stream (mime_parser, mem_stream, &error);
105 if (error != NULL) {
106 parts = e_mail_parser_error (
107 parser, cancellable,
108 _("Error parsing MBOX part: %s"),
109 error->message);
110 g_object_unref (mem_stream);
111 g_object_unref (mime_parser);
112 g_error_free (error);
113 return parts;
114 }
115
116 g_object_unref (mem_stream);
117
118 old_len = part_id->len;
119
120 /* Extract messages from the mbox. */
121 messages = 0;
122 state = camel_mime_parser_step (mime_parser, NULL, NULL);
123
124 parts = NULL;
125 while (state == CAMEL_MIME_PARSER_STATE_FROM) {
126 CamelMimeMessage *message;
127 CamelMimePart *opart;
128 GSList *new_parts;
129
130 message = camel_mime_message_new ();
131 opart = CAMEL_MIME_PART (message);
132
133 if (!camel_mime_part_construct_from_parser_sync (
134 opart, mime_parser, NULL, NULL)) {
135 g_object_unref (message);
136 break;
137 }
138
139 g_string_append_printf (part_id, ".mbox.%d", messages);
140
141 opart = camel_mime_part_new ();
142 camel_medium_set_content (CAMEL_MEDIUM (opart), CAMEL_DATA_WRAPPER (message));
143 camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (opart), "message/rfc822");
144
145 new_parts = e_mail_parser_parse_part_as (
146 parser, opart,
147 part_id, "message/rfc822", cancellable);
148
149 /* Wrap every message as attachment */
150 new_parts = e_mail_parser_wrap_as_attachment (
151 parser, opart,
152 new_parts, part_id, cancellable);
153
154 /* Inline all messages in mbox */
155 if (new_parts && new_parts->data) {
156 EMailPart *p = new_parts->data;
157
158 p->force_inline = TRUE;
159 }
160
161 parts = g_slist_concat (parts, new_parts);
162
163 g_string_truncate (part_id, old_len);
164
165 g_object_unref (message);
166 g_object_unref (opart);
167
168 /* Skip past CAMEL_MIME_PARSER_STATE_FROM_END. */
169 camel_mime_parser_step (mime_parser, NULL, NULL);
170
171 state = camel_mime_parser_step (mime_parser, NULL, NULL);
172
173 messages++;
174 }
175
176 g_object_unref (mime_parser);
177
178 return parts;
179 }
180
181 static guint32
182 empe_app_mbox_get_flags (EMailParserExtension *extension)
183 {
184 return E_MAIL_PARSER_EXTENSION_INLINE |
185 E_MAIL_PARSER_EXTENSION_COMPOUND_TYPE;
186 }
187
188 static const gchar **
189 empe_app_mbox_mime_types (EMailExtension *extension)
190 {
191 return parser_mime_types;
192 }
193
194 static void
195 e_mail_parser_application_mbox_class_init (EMailParserApplicationMBoxClass *class)
196 {
197 }
198
199 static void
200 e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *interface)
201 {
202 interface->parse = empe_app_mbox_parse;
203 interface->get_flags = empe_app_mbox_get_flags;
204 }
205
206 static void
207 e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *interface)
208 {
209 interface->mime_types = empe_app_mbox_mime_types;
210 }
211
212 static void
213 e_mail_parser_application_mbox_init (EMailParserApplicationMBox *self)
214 {
215 }