No issues found
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) version 3.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with the program; if not, see <http://www.gnu.org/licenses/>
14 *
15 *
16 * Authors:
17 * Dan Winship <danw@ximian.com>
18 * Peter Williams <peterw@ximian.com>
19 * Jeffrey Stedfast <fejj@ximian.com>
20 *
21 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include <ctype.h>
33 #include <errno.h>
34 #include <string.h>
35
36 #include <glib/gstdio.h>
37
38 #include <glib/gi18n.h>
39
40 #include "e-mail-session.h"
41 #include "mail-folder-cache.h"
42 #include "mail-tools.h"
43
44 /* **************************************** */
45
46 #ifndef G_OS_WIN32
47
48 static gchar *
49 mail_tool_get_local_movemail_path (CamelStore *store,
50 GError **error)
51 {
52 const gchar *uid;
53 guchar *safe_uid, *c;
54 const gchar *data_dir;
55 gchar *path, *full;
56 struct stat st;
57
58 uid = camel_service_get_uid (CAMEL_SERVICE (store));
59 safe_uid = (guchar *) g_strdup ((const gchar *) uid);
60 for (c = safe_uid; *c; c++)
61 if (strchr ("/:;=|%&#!*^()\\, ", *c) || !isprint ((gint) *c))
62 *c = '_';
63
64 data_dir = mail_session_get_data_dir ();
65 path = g_build_filename (data_dir, "spool", NULL);
66
67 if (g_stat (path, &st) == -1 && g_mkdir_with_parents (path, 0700) == -1) {
68 g_set_error (
69 error, G_FILE_ERROR,
70 g_file_error_from_errno (errno),
71 _("Could not create spool directory '%s': %s"),
72 path, g_strerror (errno));
73 g_free (path);
74 return NULL;
75 }
76
77 full = g_strdup_printf ("%s/movemail.%s", path, safe_uid);
78 g_free (path);
79 g_free (safe_uid);
80
81 return full;
82 }
83
84 #endif
85
86 gchar *
87 mail_tool_do_movemail (CamelStore *store,
88 GError **error)
89 {
90 #ifndef G_OS_WIN32
91 CamelService *service;
92 CamelProvider *provider;
93 CamelSettings *settings;
94 gchar *src_path;
95 gchar *dest_path;
96 struct stat sb;
97 gboolean success;
98
99 g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
100
101 service = CAMEL_SERVICE (store);
102 provider = camel_service_get_provider (service);
103
104 g_return_val_if_fail (provider != NULL, NULL);
105
106 if (g_strcmp0 (provider->protocol, "mbox") != 0) {
107 /* This is really only an internal error anyway */
108 g_set_error (
109 error, CAMEL_SERVICE_ERROR,
110 CAMEL_SERVICE_ERROR_URL_INVALID,
111 _("Trying to movemail a non-mbox source '%s'"),
112 camel_service_get_uid (CAMEL_SERVICE (store)));
113 return NULL;
114 }
115
116 settings = camel_service_ref_settings (service);
117
118 src_path = camel_local_settings_dup_path (
119 CAMEL_LOCAL_SETTINGS (settings));
120
121 g_object_unref (settings);
122
123 /* Set up our destination. */
124 dest_path = mail_tool_get_local_movemail_path (store, error);
125 if (dest_path == NULL)
126 return NULL;
127
128 /* Movemail from source to dest_path */
129 success = camel_movemail (src_path, dest_path, error) != -1;
130
131 g_free (src_path);
132
133 if (g_stat (dest_path, &sb) < 0 || sb.st_size == 0) {
134 g_unlink (dest_path); /* Clean up the movemail.foo file. */
135 g_free (dest_path);
136 return NULL;
137 }
138
139 if (!success) {
140 g_free (dest_path);
141 return NULL;
142 }
143
144 return dest_path;
145 #else
146 /* Unclear yet whether camel-movemail etc makes any sense on
147 * Win32, at least it is not ported yet.
148 */
149 g_warning ("%s: Not implemented", __FUNCTION__);
150 return NULL;
151 #endif
152 }
153
154 gchar *
155 mail_tool_generate_forward_subject (CamelMimeMessage *msg)
156 {
157 const gchar *subject;
158 gchar *fwd_subj;
159 const gint max_subject_length = 1024;
160
161 subject = camel_mime_message_get_subject (msg);
162
163 if (subject && *subject) {
164 /* Truncate insanely long subjects */
165 if (strlen (subject) < max_subject_length) {
166 fwd_subj = g_strdup_printf ("[Fwd: %s]", subject);
167 } else {
168 /* We can't use %.*s because it depends on the
169 * locale being C/POSIX or UTF-8 to work correctly
170 * in glibc. */
171 fwd_subj = g_malloc (max_subject_length + 11);
172 memcpy (fwd_subj, "[Fwd: ", 6);
173 memcpy (fwd_subj + 6, subject, max_subject_length);
174 memcpy (fwd_subj + 6 + max_subject_length, "...]", 5);
175 }
176 } else {
177 const CamelInternetAddress *from;
178 gchar *fromstr;
179
180 from = camel_mime_message_get_from (msg);
181 if (from) {
182 fromstr = camel_address_format (CAMEL_ADDRESS (from));
183 fwd_subj = g_strdup_printf ("[Fwd: %s]", fromstr);
184 g_free (fromstr);
185 } else
186 fwd_subj = g_strdup ("[Fwd: No Subject]");
187 }
188
189 return fwd_subj;
190 }
191
192 struct _camel_header_raw *
193 mail_tool_remove_xevolution_headers (CamelMimeMessage *message)
194 {
195 struct _camel_header_raw *scan, *list = NULL;
196
197 for (scan = ((CamelMimePart *) message)->headers; scan; scan = scan->next)
198 if (!strncmp (scan->name, "X-Evolution", 11))
199 camel_header_raw_append (&list, scan->name, scan->value, scan->offset);
200
201 for (scan = list; scan; scan = scan->next)
202 camel_medium_remove_header ((CamelMedium *) message, scan->name);
203
204 return list;
205 }
206
207 void
208 mail_tool_restore_xevolution_headers (CamelMimeMessage *message,
209 struct _camel_header_raw *xev)
210 {
211 CamelMedium *medium;
212
213 medium = CAMEL_MEDIUM (message);
214
215 for (; xev; xev = xev->next)
216 camel_medium_add_header (medium, xev->name, xev->value);
217 }
218
219 CamelMimePart *
220 mail_tool_make_message_attachment (CamelMimeMessage *message)
221 {
222 CamelMimePart *part;
223 const gchar *subject;
224 struct _camel_header_raw *xev;
225 gchar *desc;
226
227 subject = camel_mime_message_get_subject (message);
228 if (subject)
229 desc = g_strdup_printf (_("Forwarded message - %s"), subject);
230 else
231 desc = g_strdup (_("Forwarded message"));
232
233 /* rip off the X-Evolution headers */
234 xev = mail_tool_remove_xevolution_headers (message);
235 camel_header_raw_clear (&xev);
236
237 /* remove Bcc headers */
238 camel_medium_remove_header (CAMEL_MEDIUM (message), "Bcc");
239
240 part = camel_mime_part_new ();
241 camel_mime_part_set_disposition (part, "inline");
242 camel_mime_part_set_description (part, desc);
243 camel_medium_set_content (
244 CAMEL_MEDIUM (part), CAMEL_DATA_WRAPPER (message));
245 camel_mime_part_set_content_type (part, "message/rfc822");
246 g_free (desc);
247
248 return part;
249 }