/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* mail-ops.c: callbacks for the mail toolbar/menus */ /* * Author : * Dan Winship * * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include #include #include #include "camel/camel.h" #include "mail-ops.h" #include "mail-format.h" #include "folder-browser.h" #include "session.h" #include "e-util/e-setup.h" #include "composer/e-msg-composer.h" #ifndef HAVE_MKSTEMP #include #include #endif static void mail_exception_dialog (char *head, CamelException *ex, GtkWindow *window) { char *msg; msg = g_strdup_printf ("%s:\n%s", head, camel_exception_get_description (ex)); gnome_error_dialog_parented (msg, window); g_free (msg); } void fetch_mail (GtkWidget *button, gpointer user_data) { FolderBrowser *fb = FOLDER_BROWSER (user_data); GtkWindow *window; CamelException *ex; CamelStore *store = NULL; CamelFolder *folder = NULL, *outfolder = NULL; int nmsgs, i; CamelMimeMessage *msg = NULL; char *path, *url = NULL, *provider; gboolean get_remote; window = GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (fb), GTK_TYPE_WINDOW)); /* FIXME: We want a better config solution than this. */ path = g_strdup_printf ("=%s/config=/mail/get_remote", evolution_dir); get_remote = gnome_config_get_bool_with_default (path, FALSE); g_free (path); path = g_strdup_printf ("=%s/config=/mail/remote_url", evolution_dir); url = gnome_config_get_string_with_default (path, NULL); g_free (path); if (!get_remote || !url) { if (url) g_free (url); gnome_error_dialog_parented ("You have no remote mail source " "configured", window); return; } /* FIXME: this should go away when the provider situation is * improved. */ path = g_strdup_printf ("=%s/config=/mail/remote_provider", evolution_dir); provider = gnome_config_get_string_with_default (path, NULL); g_free (path); if (provider) { camel_provider_register_as_module (provider); g_free (provider); } ex = camel_exception_new (); /* If fetching mail from an mbox store, safely copy it to a * temporary store first. */ if (!strncmp (url, "mbox:", 5)) { char *tmp_mbox, *source; int tmpfd; tmp_mbox = g_strdup_printf ("%s/movemail.XXXX", evolution_folders_dir); #ifdef HAVE_MKSTEMP tmpfd = mkstemp (tmp_mbox); #else if (mktemp (tmp_mbox)) { tmpfd = open (tmp_mbox, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); } else tmpfd = -1; #endif if (tmpfd == -1) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, "Couldn't create temporary " "mbox: %s", g_strerror (errno)); mail_exception_dialog ("Unable to move mail", ex, window); goto cleanup; } close (tmpfd); /* Skip over "mbox://" plus host part (if any) or url. */ source = strchr (url + 7, '/'); switch (camel_movemail (source, tmp_mbox, ex)) { case -1: mail_exception_dialog ("Unable to move mail", ex, window); /* FALL THROUGH */ case 0: unlink (tmp_mbox); g_free (tmp_mbox); goto cleanup; } folder = camel_store_get_folder (default_session->store, strrchr (tmp_mbox, '/') + 1, ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { mail_exception_dialog ("Unable to move mail", ex, window); g_free (tmp_mbox); goto cleanup; } } else { store = camel_session_get_store (default_session->session, url, ex); if (!store) { mail_exception_dialog ("Unable to get new mail", ex, window); goto cleanup; } camel_service_connect_with_url (CAMEL_SERVICE (store), url, ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { mail_exception_dialog ("Unable to get new mail", ex, window); goto cleanup; } folder = camel_store_get_folder (store, "inbox", ex); if (!folder) { mail_exception_dialog ("Unable to get new mail", ex, window); goto cleanup; } } camel_folder_open (folder, FOLDER_OPEN_READ, ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { mail_exception_dialog ("Unable to get new mail", ex, window); goto cleanup; } nmsgs = camel_folder_get_message_count (folder, ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { mail_exception_dialog ("Unable to get new mail", ex, window); goto cleanup; } if (nmsgs == 0) goto cleanup; outfolder = camel_store_get_folder (default_session->store, "inbox", ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { mail_exception_dialog ("Unable to open inbox to store mail", ex, window); goto cleanup; } camel_folder_open (outfolder, FOLDER_OPEN_WRITE, ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { mail_exception_dialog ("Unable to open inbox to store mail", ex, window); goto cleanup; } for (i = 1; i <= nmsgs; i++) { msg = camel_folder_get_message_by_number (folder, i, ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { mail_exception_dialog ("Unable to read message", ex, window); goto cleanup; } camel_folder_append_message (outfolder, msg, ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { mail_exception_dialog ("Unable to write message", ex, window); goto cleanup; } camel_folder_delete_message_by_number (folder, i, ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { mail_exception_dialog ("Unable to delete message", ex, window); goto cleanup; } } msg = NULL; folder_browser_set_uri (fb, "inbox"); /* FIXME */ cleanup: if (url) g_free (url); if (folder) { if (camel_folder_is_open (folder)) camel_folder_close (folder, TRUE, ex); gtk_object_unref (GTK_OBJECT (folder)); } if (store) { camel_service_disconnect (CAMEL_SERVICE (store), ex); gtk_object_unref (GTK_OBJECT (store)); } #if 0 /* FIXME: we'll want to do this when the rest of the mail * stuff is refcounting things properly. */ if (outfolder) { if (camel_folder_is_open (outfolder)) camel_folder_close (outfolder, FALSE, ex); gtk_object_unref (GTK_OBJECT (outfolder)); } #endif camel_exception_free (ex); if (msg) gtk_object_unref (GTK_OBJECT (msg)); } static void composer_send_cb (EMsgComposer *composer, gpointer data) { CamelMimeMessage *message; CamelTransport *transport; CamelException *ex; static gboolean loaded = FALSE; message = e_msg_composer_get_message (composer); camel_mime_message_set_from (message, "Dan Winship "); camel_medium_add_header (CAMEL_MEDIUM (message), "X-Mailer", "Evolution 0.0.0.0.0.0.0.0.0.1"); camel_mime_message_set_date (message, CAMEL_MESSAGE_DATE_CURRENT, 0); if (!loaded) { camel_provider_register_as_module ("/usr/local/lib/evolution/camel-providers/0.0.1/libcamelsendmail.so"); loaded = TRUE; } ex = camel_exception_new (); transport = camel_session_get_transport_for_protocol ( default_session->session, "sendmail", ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) g_warning (camel_exception_get_description (ex)); else { camel_transport_send (transport, CAMEL_MEDIUM (message), ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) g_warning (camel_exception_get_description (ex)); gtk_object_destroy (GTK_OBJECT (transport)); } gtk_object_unref (GTK_OBJECT (message)); gtk_object_destroy (GTK_OBJECT (composer)); } void send_msg (GtkWidget *widget, gpointer user_data) { GtkWidget *composer; composer = e_msg_composer_new (); gtk_signal_connect (GTK_OBJECT (composer), "send", GTK_SIGNAL_FUNC (composer_send_cb), NULL); gtk_widget_show (composer); } /* Send according to a mailto (RFC 2368) URL. */ void send_to_url (const char *url) { GtkWidget *composer; composer = e_msg_composer_new_from_url (url); gtk_signal_connect (GTK_OBJECT (composer), "send", GTK_SIGNAL_FUNC (composer_send_cb), NULL); gtk_widget_show (composer); } static void reply (FolderBrowser *fb, gboolean to_all) { EMsgComposer *composer; composer = mail_generate_reply (fb->mail_display->current_message, to_all); gtk_signal_connect (GTK_OBJECT (composer), "send", GTK_SIGNAL_FUNC (composer_send_cb), NULL); gtk_widget_show (GTK_WIDGET (composer)); } void reply_to_sender (GtkWidget *button, gpointer user_data) { reply (FOLDER_BROWSER (user_data), FALSE); } void reply_to_all (GtkWidget *button, gpointer user_data) { reply (FOLDER_BROWSER (user_data), TRUE); } void forward_msg (GtkWidget *button, gpointer user_data) { FolderBrowser *fb; EMsgComposer *composer; fb = FOLDER_BROWSER (user_data); composer = mail_generate_forward (fb->mail_display->current_message, TRUE, TRUE); gtk_signal_connect (GTK_OBJECT (composer), "send", GTK_SIGNAL_FUNC (composer_send_cb), NULL); gtk_widget_show (GTK_WIDGET (composer)); }