[evolution-data-server] Bug #201807 - Cannot specify sendmail parameters
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug #201807 - Cannot specify sendmail parameters
- Date: Wed, 17 Oct 2012 17:47:42 +0000 (UTC)
commit 9744d28c13f071c85ce74decb087a48973a7a2ed
Author: Milan Crha <mcrha redhat com>
Date: Wed Oct 17 19:46:42 2012 +0200
Bug #201807 - Cannot specify sendmail parameters
camel/providers/sendmail/camel-sendmail-settings.c | 181 +++++++++++++++++++-
camel/providers/sendmail/camel-sendmail-settings.h | 10 +
.../providers/sendmail/camel-sendmail-transport.c | 114 +++++++++++--
3 files changed, 288 insertions(+), 17 deletions(-)
---
diff --git a/camel/providers/sendmail/camel-sendmail-settings.c b/camel/providers/sendmail/camel-sendmail-settings.c
index 2389f3b..2863afc 100644
--- a/camel/providers/sendmail/camel-sendmail-settings.c
+++ b/camel/providers/sendmail/camel-sendmail-settings.c
@@ -25,14 +25,18 @@
struct _CamelSendmailSettingsPrivate {
GMutex *property_lock;
gchar *custom_binary;
+ gchar *custom_args;
gboolean use_custom_binary;
+ gboolean use_custom_args;
};
enum {
PROP_0,
PROP_USE_CUSTOM_BINARY,
- PROP_CUSTOM_BINARY
+ PROP_USE_CUSTOM_ARGS,
+ PROP_CUSTOM_BINARY,
+ PROP_CUSTOM_ARGS
};
G_DEFINE_TYPE (CamelSendmailSettings, camel_sendmail_settings, CAMEL_TYPE_SETTINGS)
@@ -50,11 +54,23 @@ sendmail_settings_set_property (GObject *object,
g_value_get_boolean (value));
return;
+ case PROP_USE_CUSTOM_ARGS:
+ camel_sendmail_settings_set_use_custom_args (
+ 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;
+
+ case PROP_CUSTOM_ARGS:
+ camel_sendmail_settings_set_custom_args (
+ CAMEL_SENDMAIL_SETTINGS (object),
+ g_value_get_string (value));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -74,12 +90,26 @@ sendmail_settings_get_property (GObject *object,
CAMEL_SENDMAIL_SETTINGS (object)));
return;
+ case PROP_USE_CUSTOM_ARGS:
+ g_value_set_boolean (
+ value,
+ camel_sendmail_settings_get_use_custom_args (
+ 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;
+
+ case PROP_CUSTOM_ARGS:
+ g_value_take_string (
+ value,
+ camel_sendmail_settings_dup_custom_args (
+ CAMEL_SENDMAIL_SETTINGS (object)));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -95,6 +125,7 @@ sendmail_settings_finalize (GObject *object)
g_mutex_free (priv->property_lock);
g_free (priv->custom_binary);
+ g_free (priv->custom_args);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (camel_sendmail_settings_parent_class)->finalize (object);
@@ -126,6 +157,18 @@ camel_sendmail_settings_class_init (CamelSendmailSettingsClass *class)
g_object_class_install_property (
object_class,
+ PROP_USE_CUSTOM_ARGS,
+ g_param_spec_boolean (
+ "use-custom-args",
+ "Use Custom Arguments",
+ "Whether the custom-args property identifies arguments to use",
+ 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",
@@ -135,6 +178,18 @@ camel_sendmail_settings_class_init (CamelSendmailSettingsClass *class)
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CUSTOM_ARGS,
+ g_param_spec_string (
+ "custom-args",
+ "Custom Arguments",
+ "Custom arguments to use, instead of default (predefined) arguments",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
}
static void
@@ -186,6 +241,47 @@ camel_sendmail_settings_set_use_custom_binary (CamelSendmailSettings *settings,
}
/**
+ * camel_sendmail_settings_get_use_custom_args:
+ * @settings: a #CamelSendmailSettings
+ *
+ * Returns whether the 'custom-args' property should be used as arguments to use, instead of default arguments.
+ *
+ * Returns: whether the 'custom-args' property should be used as arguments to use, instead of default arguments
+ *
+ * Since: 3.8
+ **/
+gboolean
+camel_sendmail_settings_get_use_custom_args (CamelSendmailSettings *settings)
+{
+ g_return_val_if_fail (CAMEL_IS_SENDMAIL_SETTINGS (settings), FALSE);
+
+ return settings->priv->use_custom_args;
+}
+
+/**
+ * camel_sendmail_settings_set_use_custom_args:
+ * @settings: a #CamelSendmailSettings
+ * @use_custom_args: whether to use custom arguments
+ *
+ * Sets whether to use custom arguments, instead of default arguments.
+ *
+ * Since: 3.8
+ **/
+void
+camel_sendmail_settings_set_use_custom_args (CamelSendmailSettings *settings,
+ gboolean use_custom_args)
+{
+ g_return_if_fail (CAMEL_IS_SENDMAIL_SETTINGS (settings));
+
+ if ((settings->priv->use_custom_args ? 1 : 0) == (use_custom_args ? 1 : 0))
+ return;
+
+ settings->priv->use_custom_args = use_custom_args;
+
+ g_object_notify (G_OBJECT (settings), "use-custom-args");
+}
+
+/**
* camel_sendmail_settings_get_custom_binary:
* @settings: a #CamelSendmailSettings
*
@@ -267,3 +363,86 @@ camel_sendmail_settings_set_custom_binary (CamelSendmailSettings *settings,
g_object_notify (G_OBJECT (settings), "custom-binary");
}
+
+/**
+ * camel_sendmail_settings_get_custom_args:
+ * @settings: a #CamelSendmailSettings
+ *
+ * Returns the custom arguments to use, instead of default arguments.
+ *
+ * Returns: the custom arguments to use, instead of default arguments, or %NULL
+ *
+ * Since: 3.8
+ **/
+const gchar *
+camel_sendmail_settings_get_custom_args (CamelSendmailSettings *settings)
+{
+ g_return_val_if_fail (CAMEL_IS_SENDMAIL_SETTINGS (settings), NULL);
+
+ return settings->priv->custom_args;
+}
+
+/**
+ * camel_sendmail_settings_dup_custom_args:
+ * @settings: a #CamelSendmailSettings
+ *
+ * Thread-safe variation of camel_sendmail_settings_get_custom_args().
+ * 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-args
+ *
+ * Since: 3.8
+ **/
+gchar *
+camel_sendmail_settings_dup_custom_args (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_args (settings);
+ duplicate = g_strdup (protected);
+
+ g_mutex_unlock (settings->priv->property_lock);
+
+ return duplicate;
+}
+
+/**
+ * camel_sendmail_settings_set_custom_args:
+ * @settings: a #CamelSendmailSettings
+ * @custom_args: a custom arguments, or %NULL
+ *
+ * Sets the custom arguments to use, instead of default arguments.
+ *
+ * Since: 3.8
+ **/
+void
+camel_sendmail_settings_set_custom_args (CamelSendmailSettings *settings,
+ const gchar *custom_args)
+{
+ g_return_if_fail (CAMEL_IS_SENDMAIL_SETTINGS (settings));
+
+ /* The default namespace is an empty string. */
+ if (custom_args && !*custom_args)
+ custom_args = NULL;
+
+ g_mutex_lock (settings->priv->property_lock);
+
+ if (g_strcmp0 (settings->priv->custom_args, custom_args) == 0) {
+ g_mutex_unlock (settings->priv->property_lock);
+ return;
+ }
+
+ g_free (settings->priv->custom_args);
+ settings->priv->custom_args = g_strdup (custom_args);
+
+ g_mutex_unlock (settings->priv->property_lock);
+
+ g_object_notify (G_OBJECT (settings), "custom-args");
+}
diff --git a/camel/providers/sendmail/camel-sendmail-settings.h b/camel/providers/sendmail/camel-sendmail-settings.h
index a85ec82..c33d4ee 100644
--- a/camel/providers/sendmail/camel-sendmail-settings.h
+++ b/camel/providers/sendmail/camel-sendmail-settings.h
@@ -59,11 +59,21 @@ 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);
+gboolean camel_sendmail_settings_get_use_custom_args (CamelSendmailSettings *settings);
+void camel_sendmail_settings_set_use_custom_args (CamelSendmailSettings *settings,
+ gboolean use_custom_args);
+
+const gchar * camel_sendmail_settings_get_custom_args (CamelSendmailSettings *settings);
+gchar * camel_sendmail_settings_dup_custom_args (CamelSendmailSettings *settings);
+void camel_sendmail_settings_set_custom_args (CamelSendmailSettings *settings,
+ const gchar *custom_args);
+
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 9404a28..f570cbd 100644
--- a/camel/providers/sendmail/camel-sendmail-transport.c
+++ b/camel/providers/sendmail/camel-sendmail-transport.c
@@ -52,6 +52,63 @@ sendmail_get_name (CamelService *service,
return g_strdup (_("Mail delivery via the sendmail program"));
}
+static GPtrArray *
+parse_sendmail_args (const gchar *binary,
+ const gchar *args,
+ const gchar *from_addr,
+ CamelAddress *recipients)
+{
+ GPtrArray *args_arr;
+ gint ii, len, argc = 0;
+ gchar **argv = NULL;
+
+ g_return_val_if_fail (binary != NULL, NULL);
+ g_return_val_if_fail (args != NULL, NULL);
+ g_return_val_if_fail (from_addr != NULL, NULL);
+
+ len = camel_address_length (recipients);
+
+ args_arr = g_ptr_array_new_full (5, g_free);
+ g_ptr_array_add (args_arr, g_strdup (binary));
+
+ if (args && g_shell_parse_argv (args, &argc, &argv, NULL) && argc > 0 && argv) {
+ for (ii = 0; ii < argc; ii++) {
+ const gchar *arg = argv[ii];
+
+ if (g_strcmp0 (arg, "%F") == 0) {
+ g_ptr_array_add (args_arr, g_strdup (from_addr));
+ } else if (g_strcmp0 (arg, "%R") == 0) {
+ gint jj;
+
+ for (jj = 0; jj < len; jj++) {
+ const gchar *addr = NULL;
+
+ if (!camel_internet_address_get (
+ CAMEL_INTERNET_ADDRESS (recipients), jj, NULL, &addr)) {
+
+ /* should not happen, as the array is checked beforehand */
+
+ g_ptr_array_free (args_arr, TRUE);
+ g_strfreev (argv);
+
+ return NULL;
+ }
+
+ g_ptr_array_add (args_arr, g_strdup (addr));
+ }
+ } else {
+ g_ptr_array_add (args_arr, g_strdup (arg));
+ }
+ }
+
+ g_strfreev (argv);
+ }
+
+ g_ptr_array_add (args_arr, NULL);
+
+ return args_arr;
+}
+
static gboolean
sendmail_send_to_sync (CamelTransport *transport,
CamelMimeMessage *message,
@@ -61,7 +118,8 @@ sendmail_send_to_sync (CamelTransport *transport,
GError **error)
{
struct _camel_header_raw *header, *savedbcc, *n, *tail;
- const gchar *from_addr, *addr, **argv;
+ const gchar *from_addr, *addr;
+ GPtrArray *argv_arr;
gint i, len, fd[2], nullfd, wstat;
CamelStream *filter;
CamelMimeFilter *crlf;
@@ -69,7 +127,7 @@ sendmail_send_to_sync (CamelTransport *transport,
CamelStream *out;
CamelSendmailSettings *settings;
const gchar *binary = SENDMAIL_PATH;
- gchar *custom_binary = NULL;
+ gchar *custom_binary = NULL, *custom_args = NULL;
gboolean success;
pid_t pid;
@@ -87,16 +145,16 @@ sendmail_send_to_sync (CamelTransport *transport,
binary = custom_binary;
}
+ if (camel_sendmail_settings_get_use_custom_args (settings)) {
+ custom_args = camel_sendmail_settings_dup_custom_args (settings);
+ /* means no arguments used */
+ if (!custom_args)
+ custom_args = g_strdup ("");
+ }
+
g_object_unref (settings);
len = camel_address_length (recipients);
- argv = g_malloc ((len + 6) * sizeof (gchar *));
- argv[0] = binary;
- argv[1] = "-i";
- argv[2] = "-f";
- argv[3] = from_addr;
- argv[4] = "--";
-
for (i = 0; i < len; i++) {
success = camel_internet_address_get (
CAMEL_INTERNET_ADDRESS (recipients), i, NULL, &addr);
@@ -105,14 +163,28 @@ sendmail_send_to_sync (CamelTransport *transport,
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
_("Could not parse recipient list"));
- g_free (argv);
+ g_free (custom_binary);
+ g_free (custom_args);
+
return FALSE;
}
-
- argv[i + 5] = addr;
}
- argv[i + 5] = NULL;
+ argv_arr = parse_sendmail_args (binary,
+ custom_args ? custom_args : "-i -f %F -- %R",
+ from_addr,
+ recipients);
+
+ if (!argv_arr) {
+ g_set_error (
+ error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+ _("Could not parse arguments"));
+
+ g_free (custom_binary);
+ g_free (custom_args);
+
+ return FALSE;
+ }
/* unlink the bcc headers */
savedbcc = NULL;
@@ -143,6 +215,8 @@ sendmail_send_to_sync (CamelTransport *transport,
/* restore the bcc headers */
header->next = savedbcc;
g_free (custom_binary);
+ g_free (custom_args);
+ g_ptr_array_free (argv_arr, TRUE);
return FALSE;
}
@@ -165,11 +239,12 @@ sendmail_send_to_sync (CamelTransport *transport,
close (fd[0]);
close (fd[1]);
sigprocmask (SIG_SETMASK, &omask, NULL);
- g_free (argv);
/* restore the bcc headers */
header->next = savedbcc;
g_free (custom_binary);
+ g_free (custom_args);
+ g_ptr_array_free (argv_arr, TRUE);
return FALSE;
case 0:
@@ -183,10 +258,11 @@ sendmail_send_to_sync (CamelTransport *transport,
}
close (fd[1]);
- execv (binary, (gchar **) argv);
+ execv (binary, (gchar **) argv_arr->pdata);
_exit (255);
}
- g_free (argv);
+
+ g_ptr_array_free (argv_arr, TRUE);
/* Parent process. Write the message out. */
close (fd[0]);
@@ -218,6 +294,7 @@ sendmail_send_to_sync (CamelTransport *transport,
/* restore the bcc headers */
header->next = savedbcc;
g_free (custom_binary);
+ g_free (custom_args);
return FALSE;
}
@@ -239,6 +316,8 @@ sendmail_send_to_sync (CamelTransport *transport,
_("'%s' exited with signal %s: mail not sent."),
binary, g_strsignal (WTERMSIG (wstat)));
g_free (custom_binary);
+ g_free (custom_args);
+
return FALSE;
} else if (WEXITSTATUS (wstat) != 0) {
if (WEXITSTATUS (wstat) == 255) {
@@ -254,10 +333,13 @@ sendmail_send_to_sync (CamelTransport *transport,
binary, WEXITSTATUS (wstat));
}
g_free (custom_binary);
+ g_free (custom_args);
+
return FALSE;
}
g_free (custom_binary);
+ g_free (custom_args);
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]