1 /*
2  * e-mail-formatter-message-rfc822.c
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, see <http://www.gnu.org/licenses/>.
15  *
16  */
17 
18 #include "evolution-config.h"
19 
20 #include <string.h>
21 #include <glib/gi18n-lib.h>
22 
23 #include <e-util/e-util.h>
24 
25 #include "e-mail-formatter-extension.h"
26 #include "e-mail-part-list.h"
27 #include "e-mail-part-utils.h"
28 
29 typedef EMailFormatterExtension EMailFormatterMessageRFC822;
30 typedef EMailFormatterExtensionClass EMailFormatterMessageRFC822Class;
31 
32 GType e_mail_formatter_message_rfc822_get_type (void);
33 
34 G_DEFINE_TYPE (
35 	EMailFormatterMessageRFC822,
36 	e_mail_formatter_message_rfc822,
37 	E_TYPE_MAIL_FORMATTER_EXTENSION)
38 
39 static const gchar *formatter_mime_types[] = {
40 	"message/rfc822",
41 	"application/vnd.evolution.rfc822.end",
42 	NULL
43 };
44 
45 static gboolean
emfe_message_rfc822_format(EMailFormatterExtension * extension,EMailFormatter * formatter,EMailFormatterContext * context,EMailPart * part,GOutputStream * stream,GCancellable * cancellable)46 emfe_message_rfc822_format (EMailFormatterExtension *extension,
47                             EMailFormatter *formatter,
48                             EMailFormatterContext *context,
49                             EMailPart *part,
50                             GOutputStream *stream,
51                             GCancellable *cancellable)
52 {
53 	const gchar *part_id;
54 
55 	part_id = e_mail_part_get_id (part);
56 
57 	if (g_cancellable_is_cancelled (cancellable))
58 		return FALSE;
59 
60 	if (context->mode == E_MAIL_FORMATTER_MODE_RAW) {
61 		GQueue queue = G_QUEUE_INIT;
62 		GList *head, *link;
63 		gchar *header, *end;
64 		const gchar *string;
65 
66 		header = e_mail_formatter_get_html_header (formatter);
67 		g_output_stream_write_all (
68 			stream, header, strlen (header),
69 			NULL, cancellable, NULL);
70 		g_free (header);
71 
72 		/* Print content of the message normally */
73 		context->mode = E_MAIL_FORMATTER_MODE_NORMAL;
74 
75 		e_mail_part_list_queue_parts (
76 			context->part_list, part_id, &queue);
77 
78 		/* Discard the first EMailPart. */
79 		if (!g_queue_is_empty (&queue))
80 			g_object_unref (g_queue_pop_head (&queue));
81 
82 		head = g_queue_peek_head_link (&queue);
83 
84 		end = g_strconcat (part_id, ".end", NULL);
85 
86 		for (link = head; link != NULL; link = g_list_next (link)) {
87 			EMailPart *p = link->data;
88 			const gchar *p_id;
89 
90 			p_id = e_mail_part_get_id (p);
91 
92 			/* Check for nested rfc822 messages */
93 			if (e_mail_part_id_has_suffix (p, ".rfc822")) {
94 				gchar *sub_end = g_strconcat (p_id, ".end", NULL);
95 
96 				while (link != NULL) {
97 					p = link->data;
98 
99 					p_id = e_mail_part_get_id (p);
100 
101 					if (g_strcmp0 (p_id, sub_end) == 0)
102 						break;
103 
104 					link = g_list_next (link);
105 				}
106 				g_free (sub_end);
107 				continue;
108 			}
109 
110 			if ((g_strcmp0 (p_id, end) == 0))
111 				break;
112 
113 			if (p->is_hidden)
114 				continue;
115 
116 			e_mail_formatter_format_as (
117 				formatter, context, p,
118 				stream, NULL, cancellable);
119 		}
120 
121 		g_free (end);
122 
123 		while (!g_queue_is_empty (&queue))
124 			g_object_unref (g_queue_pop_head (&queue));
125 
126 		context->mode = E_MAIL_FORMATTER_MODE_RAW;
127 
128 		string = "</body></html>";
129 
130 		g_output_stream_write_all (
131 			stream, string, strlen (string),
132 			NULL, cancellable, NULL);
133 
134 	} else if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) {
135 		GQueue queue = G_QUEUE_INIT;
136 		GList *head, *link;
137 		gchar *end;
138 
139 		/* Part is EMailPartAttachment */
140 		e_mail_part_list_queue_parts (
141 			context->part_list, part_id, &queue);
142 
143 		/* Discard the first EMailPart. */
144 		if (!g_queue_is_empty (&queue))
145 			g_object_unref (g_queue_pop_head (&queue));
146 
147 		if (g_queue_is_empty (&queue))
148 			return FALSE;
149 
150 		part = g_queue_pop_head (&queue);
151 		end = g_strconcat (part_id, ".end", NULL);
152 		g_object_unref (part);
153 
154 		head = g_queue_peek_head_link (&queue);
155 
156 		for (link = head; link != NULL; link = g_list_next (link)) {
157 			EMailPart *p = link->data;
158 			const gchar *p_id;
159 
160 			p_id = e_mail_part_get_id (p);
161 
162 			/* Check for nested rfc822 messages */
163 			if (e_mail_part_id_has_suffix (p, ".rfc822")) {
164 				gchar *sub_end = g_strconcat (p_id, ".end", NULL);
165 
166 				while (link != NULL) {
167 					p = link->data;
168 
169 					p_id = e_mail_part_get_id (p);
170 
171 					if (g_strcmp0 (p_id, sub_end) == 0)
172 						break;
173 
174 					link = g_list_next (link);
175 				}
176 				g_free (sub_end);
177 				continue;
178 			}
179 
180 			if ((g_strcmp0 (p_id, end) == 0))
181 				break;
182 
183 			if (p->is_hidden)
184 				continue;
185 
186 			e_mail_formatter_format_as (
187 				formatter, context, p,
188 				stream, NULL, cancellable);
189 		}
190 
191 		g_free (end);
192 
193 		while (!g_queue_is_empty (&queue))
194 			g_object_unref (g_queue_pop_head (&queue));
195 
196 	} else {
197 		EMailPart *p;
198 		CamelFolder *folder;
199 		const gchar *message_uid;
200 		const gchar *default_charset, *charset;
201 		gchar *str;
202 		gchar *uri;
203 
204 		p = e_mail_part_list_ref_part (context->part_list, part_id);
205 		if (p == NULL)
206 			return FALSE;
207 
208 		folder = e_mail_part_list_get_folder (context->part_list);
209 		message_uid = e_mail_part_list_get_message_uid (context->part_list);
210 		default_charset = e_mail_formatter_get_default_charset (formatter);
211 		charset = e_mail_formatter_get_charset (formatter);
212 
213 		if (!default_charset)
214 			default_charset = "";
215 		if (!charset)
216 			charset = "";
217 
218 		uri = e_mail_part_build_uri (
219 			folder, message_uid,
220 			"part_id", G_TYPE_STRING, e_mail_part_get_id (p),
221 			"mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW,
222 			"headers_collapsable", G_TYPE_INT, 0,
223 			"formatter_default_charset", G_TYPE_STRING, default_charset,
224 			"formatter_charset", G_TYPE_STRING, charset,
225 			NULL);
226 
227 		str = g_strdup_printf (
228 			"<div class=\"part-container "
229 			"-e-mail-formatter-body-color\">\n"
230 			"<iframe width=\"100%%\" height=\"10\""
231 			" id=\"%s.iframe\" "
232 			" class=\"-e-mail-formatter-frame-color\""
233 			" frameborder=\"0\" src=\"%s\" name=\"%s\"></iframe>"
234 			"</div>",
235 			part_id, uri, part_id);
236 
237 		g_output_stream_write_all (
238 			stream, str, strlen (str),
239 			NULL, cancellable, NULL);
240 
241 		g_free (str);
242 		g_free (uri);
243 
244 		g_object_unref (p);
245 	}
246 
247 	return TRUE;
248 }
249 
250 static void
e_mail_formatter_message_rfc822_class_init(EMailFormatterExtensionClass * class)251 e_mail_formatter_message_rfc822_class_init (EMailFormatterExtensionClass *class)
252 {
253 	class->display_name = _("RFC822 message");
254 	class->description = _("Format part as an RFC822 message");
255 	class->mime_types = formatter_mime_types;
256 	class->priority = G_PRIORITY_LOW;
257 	class->format = emfe_message_rfc822_format;
258 }
259 
260 static void
e_mail_formatter_message_rfc822_init(EMailFormatterExtension * extension)261 e_mail_formatter_message_rfc822_init (EMailFormatterExtension *extension)
262 {
263 }
264