From 8034bd125495a5b1adcd2449534d1d2208bd96e8 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 24 Feb 2000 21:17:27 +0000 Subject: Add CamelTransport abstract class and CamelSendmailTransport svn path=/trunk/; revision=1921 --- camel/providers/Makefile.am | 2 +- camel/providers/sendmail/Makefile.am | 25 +++ camel/providers/sendmail/camel-sendmail-provider.c | 51 ++++++ .../providers/sendmail/camel-sendmail-transport.c | 203 +++++++++++++++++++++ .../providers/sendmail/camel-sendmail-transport.h | 64 +++++++ 5 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 camel/providers/sendmail/Makefile.am create mode 100644 camel/providers/sendmail/camel-sendmail-provider.c create mode 100644 camel/providers/sendmail/camel-sendmail-transport.c create mode 100644 camel/providers/sendmail/camel-sendmail-transport.h (limited to 'camel/providers') 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 + * + * 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 + * + * 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 +#include +#include + +#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 + * + * 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 */ -- cgit v1.2.3