diff options
Diffstat (limited to 'camel')
-rw-r--r-- | camel/ChangeLog | 8 | ||||
-rw-r--r-- | camel/camel-transport.c | 111 | ||||
-rw-r--r-- | camel/camel-transport.h | 87 | ||||
-rw-r--r-- | camel/camel-types.h | 1 | ||||
-rw-r--r-- | camel/providers/Makefile.am | 2 | ||||
-rw-r--r-- | camel/providers/sendmail/Makefile.am | 25 | ||||
-rw-r--r-- | camel/providers/sendmail/camel-sendmail-provider.c | 51 | ||||
-rw-r--r-- | camel/providers/sendmail/camel-sendmail-transport.c | 203 | ||||
-rw-r--r-- | camel/providers/sendmail/camel-sendmail-transport.h | 64 |
9 files changed, 551 insertions, 1 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 7ae791a9a1..4166f9b7c0 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,5 +1,13 @@ 2000-02-24 Dan Winship <danw@helixcode.com> + * camel-transport.h: + * camel-transport.c: Add an abstract CamelTransport class. + + * providers/sendmail/*: A CamelTransport that uses sendmail + to deliver mail. + +2000-02-24 Dan Winship <danw@helixcode.com> + * camel-folder.c: use CamelExceptions for run-time errors, not incorrect code. Don't bother validating that an object exists from inside one of its methods, since you couldn't have gotten there if diff --git a/camel/camel-transport.c b/camel/camel-transport.c new file mode 100644 index 0000000000..ad4dfc6bc7 --- /dev/null +++ b/camel/camel-transport.c @@ -0,0 +1,111 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* camel-transport.c : Abstract class for an email transport */ + +/* + * + * Author : + * Dan Winship <danw@helixcode.com> + * + * 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 <config.h> +#include "camel-transport.h" +#include "camel-exception.h" +#include "camel-log.h" + +/* Returns the class for a CamelTransport */ +#define CT_CLASS(so) CAMEL_TRANSPORT_CLASS (GTK_OBJECT(so)->klass) + +GtkType +camel_transport_get_type (void) +{ + static GtkType camel_transport_type = 0; + + if (!camel_transport_type) { + GtkTypeInfo camel_transport_info = + { + "CamelTransport", + sizeof (CamelTransport), + sizeof (CamelTransportClass), + (GtkClassInitFunc) NULL, + (GtkObjectInitFunc) NULL, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + camel_transport_type = gtk_type_unique (CAMEL_SERVICE_TYPE, &camel_transport_info); + } + + return camel_transport_type; +} + + +/** + * camel_transport_can_send: Determine if a message is send-able on a transport + * @transport: the transport + * @message: the message + * + * Determines if a CamelMedium is of an appropriate subclass to send + * via the given @transport. (Mail transports are not able to send + * netnews articles, and vice versa.) + * + * Return value: TRUE or FALSE + **/ +gboolean +camel_transport_can_send (CamelTransport *transport, CamelMedium *message) +{ + return CT_CLASS (transport)->can_send (transport, message); +} + +/** + * camel_transport_send: Send a message via a transport + * @transport: the transport + * @message: the message + * @ex: a CamelException + * + * Sends the message to the recipients indicated in the message. + * + * Return value: success or failure. + **/ +gboolean +camel_transport_send (CamelTransport *transport, CamelMedium *message, + CamelException *ex) +{ + return CT_CLASS (transport)->send (transport, message, ex); +} + +/** + * camel_transport_send_to: Send a message non-standard recipients + * @transport: the transport + * @message: the message + * @recipients: the recipients + * @ex: a CamelException + * + * Sends the message to the given recipients, rather than to the + * recipients indicated in the message. + * + * Return value: success or failure. + **/ +gboolean +camel_transport_send_to (CamelTransport *transport, CamelMedium *message, + GList *recipients, CamelException *ex) +{ + return CT_CLASS (transport)->send_to (transport, message, + recipients, ex); +} diff --git a/camel/camel-transport.h b/camel/camel-transport.h new file mode 100644 index 0000000000..1e41f4ac71 --- /dev/null +++ b/camel/camel-transport.h @@ -0,0 +1,87 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* camel-transport.h : Abstract class for an email transport */ + +/* + * + * Author : + * Dan Winship <danw@helixcode.com> + * + * 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 + */ + + +#ifndef CAMEL_TRANSPORT_H +#define CAMEL_TRANSPORT_H 1 + + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus }*/ + +#include <gtk/gtk.h> +#include "camel-types.h" +#include "camel-service.h" + +#define CAMEL_TRANSPORT_TYPE (camel_transport_get_type ()) +#define CAMEL_TRANSPORT(obj) (GTK_CHECK_CAST((obj), CAMEL_TRANSPORT_TYPE, CamelTransport)) +#define CAMEL_TRANSPORT_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_TRANSPORT_TYPE, CamelTransportClass)) +#define CAMEL_IS_TRANSPORT(o) (GTK_CHECK_TYPE((o), CAMEL_TRANSPORT_TYPE)) + + +struct _CamelTransport +{ + CamelService parent_object; + +}; + + + +typedef struct { + CamelServiceClass parent_class; + + gboolean (*can_send) (CamelTransport *transport, CamelMedium *message); + gboolean (*send) (CamelTransport *transport, CamelMedium *message, + CamelException *ex); + gboolean (*send_to) (CamelTransport *transport, + CamelMedium *message, GList *recipients, + CamelException *ex); +} CamelTransportClass; + + +/* public methods */ +gboolean camel_transport_can_send (CamelTransport *transport, + CamelMedium *message); + +gboolean camel_transport_send (CamelTransport *transport, + CamelMedium *message, + CamelException *ex); + +gboolean camel_transport_send_to (CamelTransport *transport, + CamelMedium *message, + GList *recipients, + CamelException *ex); + +/* Standard Gtk function */ +GtkType camel_transport_get_type (void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CAMEL_TRANSPORT_H */ diff --git a/camel/camel-types.h b/camel/camel-types.h index d8505c66c6..c070404e95 100644 --- a/camel/camel-types.h +++ b/camel/camel-types.h @@ -49,6 +49,7 @@ typedef struct _CamelStreamBufferedFs CamelStreamBufferedFs; typedef struct _CamelStreamDataWrapper CamelStreamDataWrapper; typedef struct _CamelStreamFs CamelStreamFs; typedef struct _CamelStreamMem CamelStreamMem; +typedef struct _CamelTransport CamelTransport; #ifdef __cplusplus } diff --git a/camel/providers/Makefile.am b/camel/providers/Makefile.am index cf43b07714..ea9b1f3136 100644 --- a/camel/providers/Makefile.am +++ b/camel/providers/Makefile.am @@ -1,5 +1,5 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = mbox +SUBDIRS = mbox sendmail # this ones are disabled for the moment. # MH maildir diff --git a/camel/providers/sendmail/Makefile.am b/camel/providers/sendmail/Makefile.am new file mode 100644 index 0000000000..aada24aee7 --- /dev/null +++ b/camel/providers/sendmail/Makefile.am @@ -0,0 +1,25 @@ +## Process this file with automake to produce Makefile.in + +SUBDIRS = + +libcamelsendmailincludedir = $(includedir)/camel + + +providerdir = $(pkglibdir)/camel-providers/$(VERSION) + +provider_LTLIBRARIES = libcamelsendmail.la + +INCLUDES = -I.. -I$(srcdir)/.. -I$(includedir) \ + -I$(top_srcdir)/intl \ + $(GTK_INCLUDEDIR) -I$(top_srcdir)/camel + +libcamelsendmail_la_SOURCES = \ + camel-sendmail-provider.c \ + camel-sendmail-transport.c + +libcamelsendmailinclude_HEADERS = \ + camel-sendmail-transport.h + +libcamelsendmail_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir) + +EXTRA_DIST = diff --git a/camel/providers/sendmail/camel-sendmail-provider.c b/camel/providers/sendmail/camel-sendmail-provider.c new file mode 100644 index 0000000000..2b1d07efcd --- /dev/null +++ b/camel/providers/sendmail/camel-sendmail-provider.c @@ -0,0 +1,51 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* camel-sendmail-provider.c: sendmail provider registration code */ + +/* + * Authors : + * Dan Winship <danw@helixcode.com> + * + * Copyright (C) 2000 Helix Code, Inc. (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 "config.h" +#include "camel-provider.h" +#include "camel-sendmail-transport.h" + +static CamelProvider _sendmail_provider = { + (GtkType) 0, + PROVIDER_TRANSPORT, + "sendmail", + "Camel sendmail provider", + "A provider to send mail via the sendmail program", + (GModule *) NULL +}; + +CamelProvider * +camel_provider_module_init (void); + + +CamelProvider * +camel_provider_module_init (void) +{ + _sendmail_provider.object_type = camel_sendmail_transport_get_type(); + return &_sendmail_provider; +} + + + diff --git a/camel/providers/sendmail/camel-sendmail-transport.c b/camel/providers/sendmail/camel-sendmail-transport.c new file mode 100644 index 0000000000..fed9ec459d --- /dev/null +++ b/camel/providers/sendmail/camel-sendmail-transport.c @@ -0,0 +1,203 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* camel-sendmail-transport.c: Sendmail-based transport class. */ + +/* + * + * Author : + * Dan Winship <danw@helixcode.com> + * + * 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 <config.h> + +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <sys/wait.h> +#include <unistd.h> + +#include "camel-sendmail-transport.h" +#include "camel-mime-message.h" +#include "camel-data-wrapper.h" +#include "camel-stream-fs.h" +#include "camel-exception.h" + +static gboolean _can_send (CamelTransport *transport, CamelMedium *message); +static gboolean _send (CamelTransport *transport, CamelMedium *message, + CamelException *ex); +static gboolean _send_to (CamelTransport *transport, CamelMedium *message, + GList *recipients, CamelException *ex); + + +static void +camel_sendmail_transport_class_init (CamelSendmailTransportClass *camel_sendmail_transport_class) +{ + CamelTransportClass *camel_transport_class = + CAMEL_TRANSPORT_CLASS (camel_sendmail_transport_class); + + /* virtual method overload */ + camel_transport_class->can_send = _can_send; + camel_transport_class->send = _send; + camel_transport_class->send_to = _send_to; +} + +GtkType +camel_sendmail_transport_get_type (void) +{ + static GtkType camel_sendmail_transport_type = 0; + + if (!camel_sendmail_transport_type) { + GtkTypeInfo camel_sendmail_transport_info = + { + "CamelSendmailTransport", + sizeof (CamelSendmailTransport), + sizeof (CamelSendmailTransportClass), + (GtkClassInitFunc) camel_sendmail_transport_class_init, + (GtkObjectInitFunc) NULL, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + camel_sendmail_transport_type = gtk_type_unique (CAMEL_TRANSPORT_TYPE, &camel_sendmail_transport_info); + } + + return camel_sendmail_transport_type; +} + + +static gboolean +_can_send (CamelTransport *transport, CamelMedium *message) +{ + return CAMEL_IS_MIME_MESSAGE (message); +} + + +static gboolean +_send_internal (CamelMedium *message, char **argv, CamelException *ex) +{ + int fd[2], nullfd, wstat; + sigset_t mask, omask; + CamelStream *out; + pid_t pid; + + g_asssert (CAMEL_IS_MIME_MESSAGE (message)); + + if (pipe (fd) == -1) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + "Could not create pipe to sendmail: " + "%s: mail not sent", + g_strerror (errno)); + return FALSE; + } + + /* Block SIGCHLD so the calling application doesn't notice + * sendmail exiting before we do. + */ + sigemptyset (&mask); + sigaddset (&mask, SIGCHLD); + sigprocmask (SIG_BLOCK, &mask, &omask); + + switch (fork ()) { + case -1: + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + "Could not fork sendmail: " + "%s: mail not sent", g_strerror (errno)); + sigprocmask (SIG_SETMASK, &omask, NULL); + return FALSE; + + case 0: + /* Child process */ + nullfd = open ("/dev/null", O_RDWR); + dup2 (fd[0], STDIN_FILENO); + dup2 (nullfd, STDOUT_FILENO); + dup2 (nullfd, STDERR_FILENO); + close (nullfd); + close (fd[1]); + + execv (SENDMAIL_PATH, argv); + _exit (255); + } + + /* Parent process. Write the message out. */ + close (fd[0]); + out = camel_stream_fs_new_with_fd (fd[1]); + camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), out); + camel_stream_close (out); + + /* Wait for sendmail to exit. */ + while (waitpid (pid, &wstat, 0) == -1 && errno == EINTR) + ; + sigprocmask (SIG_SETMASK, &omask, NULL); + + if (!WIFEXITED (wstat)) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + "sendmail exited with signal %s: " + "mail not sent.", + g_strsignal (WTERMSIG (wstat))); + return FALSE; + } else if (WEXITSTATUS (wstat) != 0) { + if (WEXITSTATUS (wstat) == 255) { + camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, + "Could not execute " + SENDMAIL_PATH ": mail not sent."); + } else { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + "sendmail exited with status " + "%d: mail not sent.", + WEXITSTATUS (wstat)); + } + return FALSE; + } + + return TRUE; +} + +static gboolean +_send_to (CamelTransport *transport, CamelMedium *message, + GList *recipients, CamelException *ex) +{ + GList *r; + char **argv; + int i, len; + gboolean status; + + len = g_list_length (recipients); + argv = g_malloc ((len + 4) * sizeof (char *)); + argv[0] = "sendmail"; + argv[1] = "-i"; + argv[2] = "--"; + + for (i = 1, r = recipients; i <= len; i++, r = r->next) + argv[i + 2] = r->data; + argv[i + 2] = NULL; + + status = _send_internal (message, argv, ex); + g_free (argv); + return status; +} + +static gboolean +_send (CamelTransport *transport, CamelMedium *message, + CamelException *ex) +{ + char *argv[4] = { "sendmail", "-t", "-i", NULL }; + + return _send_internal (message, argv, ex); +} diff --git a/camel/providers/sendmail/camel-sendmail-transport.h b/camel/providers/sendmail/camel-sendmail-transport.h new file mode 100644 index 0000000000..3f3714584a --- /dev/null +++ b/camel/providers/sendmail/camel-sendmail-transport.h @@ -0,0 +1,64 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* camel-sendmail-transport.h: Sendmail-based transport class */ + +/* + * + * Author : + * Dan Winship <danw@helixcode.com> + * + * 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 + */ + + +#ifndef CAMEL_SENDMAIL_TRANSPORT_H +#define CAMEL_SENDMAIL_TRANSPORT_H 1 + + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus }*/ + +#include "camel-transport.h" + +#define CAMEL_SENDMAIL_TRANSPORT_TYPE (camel_sendmail_transport_get_type ()) +#define CAMEL_SENDMAIL_TRANSPORT(obj) (GTK_CHECK_CAST((obj), CAMEL_SENDMAIL_TRANSPORT_TYPE, CamelSendmailTransport)) +#define CAMEL_SENDMAIL_TRANSPORT_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_SENDMAIL_TRANSPORT_TYPE, CamelSendmailTransportClass)) +#define CAMEL_IS_SENDMAIL_TRANSPORT(o) (GTK_CHECK_TYPE((o), CAMEL_SENDMAIL_TRANSPORT_TYPE)) + + +typedef struct { + CamelTransport parent_object; + +} CamelSendmailTransport; + + +typedef struct { + CamelTransportClass parent_class; + +} CamelSendmailTransportClass; + + +/* Standard Gtk function */ +GtkType camel_sendmail_transport_get_type (void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CAMEL_SENDMAIL_TRANSPORT_H */ |