[evolution-data-server] Bug #549819 - Cannot specify a custom sendmail program
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug #549819 - Cannot specify a custom sendmail program
- Date: Mon, 17 Sep 2012 16:35:47 +0000 (UTC)
commit 78df73389288659d30551b6a02746600f41f3f25
Author: Milan Crha <mcrha redhat com>
Date: Mon Sep 17 18:35:10 2012 +0200
Bug #549819 - Cannot specify a custom sendmail program
camel/providers/sendmail/Makefile.am | 2 +
camel/providers/sendmail/camel-sendmail-provider.c | 2 +
camel/providers/sendmail/camel-sendmail-settings.c | 269 ++++++++++++++++++++
camel/providers/sendmail/camel-sendmail-settings.h | 69 +++++
.../providers/sendmail/camel-sendmail-transport.c | 46 +++-
5 files changed, 376 insertions(+), 12 deletions(-)
---
diff --git a/camel/providers/sendmail/Makefile.am b/camel/providers/sendmail/Makefile.am
index 8466eb0..b656a56 100644
--- a/camel/providers/sendmail/Makefile.am
+++ b/camel/providers/sendmail/Makefile.am
@@ -15,6 +15,8 @@ libcamelsendmail_la_CPPFLAGS = \
$(NULL)
libcamelsendmail_la_SOURCES = \
+ camel-sendmail-settings.h \
+ camel-sendmail-settings.c \
camel-sendmail-provider.c \
camel-sendmail-transport.c
diff --git a/camel/providers/sendmail/camel-sendmail-provider.c b/camel/providers/sendmail/camel-sendmail-provider.c
index f5a82f3..d913b85 100644
--- a/camel/providers/sendmail/camel-sendmail-provider.c
+++ b/camel/providers/sendmail/camel-sendmail-provider.c
@@ -44,6 +44,8 @@ static CamelProvider sendmail_provider = {
0, /* url_flags */
+ NULL, /* conf entries */
+
NULL, /* port entries */
/* ... */
diff --git a/camel/providers/sendmail/camel-sendmail-settings.c b/camel/providers/sendmail/camel-sendmail-settings.c
new file mode 100644
index 0000000..2389f3b
--- /dev/null
+++ b/camel/providers/sendmail/camel-sendmail-settings.c
@@ -0,0 +1,269 @@
+/*
+ * camel-sendmail-settings.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "camel-sendmail-settings.h"
+
+#define CAMEL_SENDMAIL_SETTINGS_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), CAMEL_TYPE_SENDMAIL_SETTINGS, CamelSendmailSettingsPrivate))
+
+struct _CamelSendmailSettingsPrivate {
+ GMutex *property_lock;
+ gchar *custom_binary;
+
+ gboolean use_custom_binary;
+};
+
+enum {
+ PROP_0,
+ PROP_USE_CUSTOM_BINARY,
+ PROP_CUSTOM_BINARY
+};
+
+G_DEFINE_TYPE (CamelSendmailSettings, camel_sendmail_settings, CAMEL_TYPE_SETTINGS)
+
+static void
+sendmail_settings_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_USE_CUSTOM_BINARY:
+ camel_sendmail_settings_set_use_custom_binary (
+ CAMEL_SENDMAIL_SETTINGS (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_CUSTOM_BINARY:
+ camel_sendmail_settings_set_custom_binary (
+ CAMEL_SENDMAIL_SETTINGS (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+sendmail_settings_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_USE_CUSTOM_BINARY:
+ g_value_set_boolean (
+ value,
+ camel_sendmail_settings_get_use_custom_binary (
+ CAMEL_SENDMAIL_SETTINGS (object)));
+ return;
+
+ case PROP_CUSTOM_BINARY:
+ g_value_take_string (
+ value,
+ camel_sendmail_settings_dup_custom_binary (
+ CAMEL_SENDMAIL_SETTINGS (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+sendmail_settings_finalize (GObject *object)
+{
+ CamelSendmailSettingsPrivate *priv;
+
+ priv = CAMEL_SENDMAIL_SETTINGS_GET_PRIVATE (object);
+
+ g_mutex_free (priv->property_lock);
+
+ g_free (priv->custom_binary);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (camel_sendmail_settings_parent_class)->finalize (object);
+}
+
+static void
+camel_sendmail_settings_class_init (CamelSendmailSettingsClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (CamelSendmailSettingsPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = sendmail_settings_set_property;
+ object_class->get_property = sendmail_settings_get_property;
+ object_class->finalize = sendmail_settings_finalize;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_USE_CUSTOM_BINARY,
+ g_param_spec_boolean (
+ "use-custom-binary",
+ "Use Custom Binary",
+ "Whether the custom-binary property identifies binary to run",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CUSTOM_BINARY,
+ g_param_spec_string (
+ "custom-binary",
+ "Custom Binary",
+ "Custom binary to run, instead of sendmail",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+camel_sendmail_settings_init (CamelSendmailSettings *settings)
+{
+ settings->priv = CAMEL_SENDMAIL_SETTINGS_GET_PRIVATE (settings);
+ settings->priv->property_lock = g_mutex_new ();
+}
+
+/**
+ * camel_sendmail_settings_get_use_custom_binary:
+ * @settings: a #CamelSendmailSettings
+ *
+ * Returns whether the 'custom-binary' property should be used as binary to run, instead of sendmail.
+ *
+ * Returns: whether the 'custom-binary' property should be used as binary to run, instead of sendmail
+ *
+ * Since: 3.8
+ **/
+gboolean
+camel_sendmail_settings_get_use_custom_binary (CamelSendmailSettings *settings)
+{
+ g_return_val_if_fail (CAMEL_IS_SENDMAIL_SETTINGS (settings), FALSE);
+
+ return settings->priv->use_custom_binary;
+}
+
+/**
+ * camel_sendmail_settings_set_use_custom_binary:
+ * @settings: a #CamelSendmailSettings
+ * @use_custom_binary: whether to use custom binary
+ *
+ * Sets whether to use custom binary, instead of sendmail.
+ *
+ * Since: 3.8
+ **/
+void
+camel_sendmail_settings_set_use_custom_binary (CamelSendmailSettings *settings,
+ gboolean use_custom_binary)
+{
+ g_return_if_fail (CAMEL_IS_SENDMAIL_SETTINGS (settings));
+
+ if ((settings->priv->use_custom_binary ? 1 : 0) == (use_custom_binary ? 1 : 0))
+ return;
+
+ settings->priv->use_custom_binary = use_custom_binary;
+
+ g_object_notify (G_OBJECT (settings), "use-custom-binary");
+}
+
+/**
+ * camel_sendmail_settings_get_custom_binary:
+ * @settings: a #CamelSendmailSettings
+ *
+ * Returns the custom binary to run, instead of sendmail.
+ *
+ * Returns: the custom binary to run, instead of sendmail, or %NULL
+ *
+ * Since: 3.8
+ **/
+const gchar *
+camel_sendmail_settings_get_custom_binary (CamelSendmailSettings *settings)
+{
+ g_return_val_if_fail (CAMEL_IS_SENDMAIL_SETTINGS (settings), NULL);
+
+ return settings->priv->custom_binary;
+}
+
+/**
+ * camel_sendmail_settings_dup_custom_binary:
+ * @settings: a #CamelSendmailSettings
+ *
+ * Thread-safe variation of camel_sendmail_settings_get_custom_binary().
+ * Use this function when accessing @settings from multiple threads.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: a newly-allocated copy of #CamelSendmailSettings:custom-binary
+ *
+ * Since: 3.8
+ **/
+gchar *
+camel_sendmail_settings_dup_custom_binary (CamelSendmailSettings *settings)
+{
+ const gchar *protected;
+ gchar *duplicate;
+
+ g_return_val_if_fail (CAMEL_IS_SENDMAIL_SETTINGS (settings), NULL);
+
+ g_mutex_lock (settings->priv->property_lock);
+
+ protected = camel_sendmail_settings_get_custom_binary (settings);
+ duplicate = g_strdup (protected);
+
+ g_mutex_unlock (settings->priv->property_lock);
+
+ return duplicate;
+}
+
+/**
+ * camel_sendmail_settings_set_custom_binary:
+ * @settings: a #CamelSendmailSettings
+ * @custom_binary: a custom binary name, or %NULL
+ *
+ * Sets the custom binary name to run, instead of sendmail.
+ *
+ * Since: 3.8
+ **/
+void
+camel_sendmail_settings_set_custom_binary (CamelSendmailSettings *settings,
+ const gchar *custom_binary)
+{
+ g_return_if_fail (CAMEL_IS_SENDMAIL_SETTINGS (settings));
+
+ /* The default namespace is an empty string. */
+ if (custom_binary && !*custom_binary)
+ custom_binary = NULL;
+
+ g_mutex_lock (settings->priv->property_lock);
+
+ if (g_strcmp0 (settings->priv->custom_binary, custom_binary) == 0) {
+ g_mutex_unlock (settings->priv->property_lock);
+ return;
+ }
+
+ g_free (settings->priv->custom_binary);
+ settings->priv->custom_binary = g_strdup (custom_binary);
+
+ g_mutex_unlock (settings->priv->property_lock);
+
+ g_object_notify (G_OBJECT (settings), "custom-binary");
+}
diff --git a/camel/providers/sendmail/camel-sendmail-settings.h b/camel/providers/sendmail/camel-sendmail-settings.h
new file mode 100644
index 0000000..a85ec82
--- /dev/null
+++ b/camel/providers/sendmail/camel-sendmail-settings.h
@@ -0,0 +1,69 @@
+/*
+ * camel-sendmail-settings.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef CAMEL_SENDMAIL_SETTINGS_H
+#define CAMEL_SENDMAIL_SETTINGS_H
+
+#include <camel/camel.h>
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_SENDMAIL_SETTINGS \
+ (camel_sendmail_settings_get_type ())
+#define CAMEL_SENDMAIL_SETTINGS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), CAMEL_TYPE_SENDMAIL_SETTINGS, CamelSendmailSettings))
+#define CAMEL_SENDMAIL_SETTINGS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), CAMEL_TYPE_SENDMAIL_SETTINGS, CamelSendmailSettingsClass))
+#define CAMEL_IS_SENDMAIL_SETTINGS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), CAMEL_TYPE_SENDMAIL_SETTINGS))
+#define CAMEL_IS_SENDMAIL_SETTINGS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), CAMEL_TYPE_SENDMAIL_SETTINGS))
+#define CAMEL_SENDMAIL_SETTINGS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), CAMEL_TYPE_SENDMAIL_SETTINGS))
+
+G_BEGIN_DECLS
+
+typedef struct _CamelSendmailSettings CamelSendmailSettings;
+typedef struct _CamelSendmailSettingsClass CamelSendmailSettingsClass;
+typedef struct _CamelSendmailSettingsPrivate CamelSendmailSettingsPrivate;
+
+struct _CamelSendmailSettings {
+ CamelSettings parent;
+ CamelSendmailSettingsPrivate *priv;
+};
+
+struct _CamelSendmailSettingsClass {
+ CamelSettingsClass parent_class;
+};
+
+GType camel_sendmail_settings_get_type (void);
+gboolean camel_sendmail_settings_get_use_custom_binary (CamelSendmailSettings *settings);
+void camel_sendmail_settings_set_use_custom_binary (CamelSendmailSettings *settings,
+ gboolean use_custom_binary);
+const gchar * camel_sendmail_settings_get_custom_binary (CamelSendmailSettings *settings);
+gchar * camel_sendmail_settings_dup_custom_binary (CamelSendmailSettings *settings);
+void camel_sendmail_settings_set_custom_binary (CamelSendmailSettings *settings,
+ const gchar *custom_binary);
+
+G_END_DECLS
+
+#endif /* CAMEL_SENDMAIL_SETTINGS_H */
diff --git a/camel/providers/sendmail/camel-sendmail-transport.c b/camel/providers/sendmail/camel-sendmail-transport.c
index 1b4c626..9404a28 100644
--- a/camel/providers/sendmail/camel-sendmail-transport.c
+++ b/camel/providers/sendmail/camel-sendmail-transport.c
@@ -35,6 +35,7 @@
#include <glib/gi18n-lib.h>
+#include "camel-sendmail-settings.h"
#include "camel-sendmail-transport.h"
G_DEFINE_TYPE (
@@ -66,6 +67,9 @@ sendmail_send_to_sync (CamelTransport *transport,
CamelMimeFilter *crlf;
sigset_t mask, omask;
CamelStream *out;
+ CamelSendmailSettings *settings;
+ const gchar *binary = SENDMAIL_PATH;
+ gchar *custom_binary = NULL;
gboolean success;
pid_t pid;
@@ -75,9 +79,19 @@ sendmail_send_to_sync (CamelTransport *transport,
if (!success)
return FALSE;
+ settings = CAMEL_SENDMAIL_SETTINGS (camel_service_ref_settings (CAMEL_SERVICE (transport)));
+
+ if (camel_sendmail_settings_get_use_custom_binary (settings)) {
+ custom_binary = camel_sendmail_settings_dup_custom_binary (settings);
+ if (custom_binary && *custom_binary)
+ binary = custom_binary;
+ }
+
+ g_object_unref (settings);
+
len = camel_address_length (recipients);
argv = g_malloc ((len + 6) * sizeof (gchar *));
- argv[0] = "sendmail";
+ argv[0] = binary;
argv[1] = "-i";
argv[2] = "-f";
argv[3] = from_addr;
@@ -123,11 +137,12 @@ sendmail_send_to_sync (CamelTransport *transport,
g_set_error (
error, G_IO_ERROR,
g_io_error_from_errno (errno),
- _("Could not create pipe to sendmail: %s: "
- "mail not sent"), g_strerror (errno));
+ _("Could not create pipe to '%s': %s: "
+ "mail not sent"), binary, g_strerror (errno));
/* restore the bcc headers */
header->next = savedbcc;
+ g_free (custom_binary);
return FALSE;
}
@@ -145,8 +160,8 @@ sendmail_send_to_sync (CamelTransport *transport,
g_set_error (
error, G_IO_ERROR,
g_io_error_from_errno (errno),
- _("Could not fork sendmail: %s: "
- "mail not sent"), g_strerror (errno));
+ _("Could not fork '%s': %s: "
+ "mail not sent"), binary, g_strerror (errno));
close (fd[0]);
close (fd[1]);
sigprocmask (SIG_SETMASK, &omask, NULL);
@@ -154,6 +169,7 @@ sendmail_send_to_sync (CamelTransport *transport,
/* restore the bcc headers */
header->next = savedbcc;
+ g_free (custom_binary);
return FALSE;
case 0:
@@ -167,7 +183,7 @@ sendmail_send_to_sync (CamelTransport *transport,
}
close (fd[1]);
- execv (SENDMAIL_PATH, (gchar **) argv);
+ execv (binary, (gchar **) argv);
_exit (255);
}
g_free (argv);
@@ -201,6 +217,7 @@ sendmail_send_to_sync (CamelTransport *transport,
/* restore the bcc headers */
header->next = savedbcc;
+ g_free (custom_binary);
return FALSE;
}
@@ -219,25 +236,29 @@ sendmail_send_to_sync (CamelTransport *transport,
if (!WIFEXITED (wstat)) {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
- _("sendmail exited with signal %s: mail not sent."),
- g_strsignal (WTERMSIG (wstat)));
+ _("'%s' exited with signal %s: mail not sent."),
+ binary, g_strsignal (WTERMSIG (wstat)));
+ g_free (custom_binary);
return FALSE;
} else if (WEXITSTATUS (wstat) != 0) {
if (WEXITSTATUS (wstat) == 255) {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
- _("Could not execute %s: mail not sent."),
- SENDMAIL_PATH);
+ _("Could not execute '%s': mail not sent."),
+ binary);
} else {
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
- _("sendmail exited with status %d: "
+ _("'%s' exited with status %d: "
"mail not sent."),
- WEXITSTATUS (wstat));
+ binary, WEXITSTATUS (wstat));
}
+ g_free (custom_binary);
return FALSE;
}
+ g_free (custom_binary);
+
return TRUE;
}
@@ -249,6 +270,7 @@ camel_sendmail_transport_class_init (CamelSendmailTransportClass *class)
service_class = CAMEL_SERVICE_CLASS (class);
service_class->get_name = sendmail_get_name;
+ service_class->settings_type = CAMEL_TYPE_SENDMAIL_SETTINGS;
transport_class = CAMEL_TRANSPORT_CLASS (class);
transport_class->send_to_sync = sendmail_send_to_sync;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]