evolution-3.6.4/libemail-engine/mail-tools.c

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 }