summaryrefslogtreecommitdiff
path: root/mail/send.c
diff options
context:
space:
mode:
Diffstat (limited to 'mail/send.c')
-rw-r--r--mail/send.c236
1 files changed, 153 insertions, 83 deletions
diff --git a/mail/send.c b/mail/send.c
index 1c33c0de5..dc9ff5850 100644
--- a/mail/send.c
+++ b/mail/send.c
@@ -1,5 +1,5 @@
/* GNU Mailutils -- a suite of utilities for electronic mail
- Copyright (C) 1999-2021 Free Software Foundation, Inc.
+ Copyright (C) 1999-2024 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -676,7 +676,7 @@ read_cc_bcc (compose_env_t *env)
* m[ail] address...
if address is starting with
- '/' it is considered a file and the message is saveed to a file;
+ '/' it is considered a file and the message is saved to a file;
'.' it is considered to be a relative path;
'|' it is considered to be a pipe, and the message is written to
there;
@@ -693,6 +693,7 @@ mail_send (int argc, char **argv)
compose_env_t env;
int status;
int save_to = mu_isupper (argv[0][0]);
+
compose_init (&env);
if (argc < 2)
@@ -764,7 +765,7 @@ mail_send (int argc, char **argv)
COMPOSE_REPLACE);
}
- status = mail_send0 (&env, save_to);
+ status = mail_compose_send (&env, save_to);
compose_destroy (&env);
return status;
}
@@ -889,78 +890,91 @@ compose_header_set (compose_env_t *env, const char *name,
const char *value, int mode)
{
int status;
- char *old_value;
-
+ char *expansion = NULL;
+
if (!value || value[0] == 0)
return EINVAL;
+ if (is_address_field (name)
+ && mailvar_is_true (mailvar_name_inplacealiases))
+ {
+ struct mu_address hint = MU_ADDRESS_HINT_INITIALIZER;
+ mu_address_t a;
+
+ status = mu_address_create_hint (&a, value, &hint, 0);
+ if (status)
+ {
+ mu_error (_("Cannot parse address `%s': %s"),
+ value, mu_strerror (status));
+ return status;
+ }
+ util_address_expand_aliases (&a);
+ status = mu_address_aget_printable (a, &expansion);
+ mu_address_destroy (&a);
+ if (status)
+ {
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_address_aget_printable",
+ NULL, status);
+ return status;
+ }
+ value = expansion;
+ }
+
if (!env->header
&& (status = mu_header_create (&env->header, NULL, 0)) != 0)
{
mu_error (_("Cannot create header: %s"), mu_strerror (status));
- return status;
}
-
- switch (mode)
+ else
{
- case COMPOSE_REPLACE:
- if (is_address_field (name)
- && mailvar_is_true (mailvar_name_inplacealiases))
+ switch (mode)
{
- char *exp = alias_expand (value);
- status = mu_header_set_value (env->header, name, exp ? exp : value, 1);
- free (exp);
- }
- else
- status = mu_header_set_value (env->header, name, value, 1);
- break;
+ case COMPOSE_REPLACE:
+ status = mu_header_set_value (env->header, name, value, 1);
+ break;
- case COMPOSE_APPEND:
- if (is_address_field (name)
- && mailvar_is_true (mailvar_name_inplacealiases))
- {
- char *exp = alias_expand (value);
- status = mu_header_append (env->header, name, exp ? exp : value);
- free (exp);
- }
- else
- status = mu_header_append (env->header, name, value);
- break;
+ case COMPOSE_APPEND:
+ status = mu_header_append (env->header, name, value);
+ break;
- case COMPOSE_SINGLE_LINE:
- if (mu_header_aget_value (env->header, name, &old_value) == 0
- && old_value[0])
- {
- if (is_address_field (name)
- && mailvar_is_true (mailvar_name_inplacealiases))
- {
- char *exp = alias_expand (value);
- status = util_merge_addresses (&old_value, exp ? exp : value);
- if (status == 0)
- status = mu_header_set_value (env->header, name, old_value, 1);
- free (exp);
- }
- else
- {
- size_t size = strlen (old_value) + strlen (value) + 2;
- char *p = realloc (old_value, size);
- if (!p)
- status = ENOMEM;
- else
- {
- old_value = p;
- strcat (old_value, ",");
- strcat (old_value, value);
- status = mu_header_set_value (env->header, name, old_value,
- 1);
- }
- }
- free (old_value);
+ case COMPOSE_SINGLE_LINE:
+ {
+ char *old_value;
+
+ if (mu_header_aget_value (env->header, name, &old_value) == 0
+ && old_value[0])
+ {
+ if (is_address_field (name))
+ {
+ status = util_merge_addresses (&old_value, value);
+ if (status == 0)
+ status = mu_header_set_value (env->header, name,
+ old_value, 1);
+ }
+ else
+ {
+ size_t size = strlen (old_value) + strlen (value) + 2;
+ char *p = realloc (old_value, size);
+ if (!p)
+ status = ENOMEM;
+ else
+ {
+ old_value = p;
+ strcat (old_value, ",");
+ strcat (old_value, value);
+ status = mu_header_set_value (env->header,
+ name, old_value,
+ 1);
+ }
+ }
+ free (old_value);
+ }
+ else
+ status = mu_header_set_value (env->header, name, value, 1);
+ }
}
- else
- status = compose_header_set (env, name, value, COMPOSE_REPLACE);
}
-
+ free (expansion);
return status;
}
@@ -1130,12 +1144,27 @@ save_dead_message (mu_message_t msg)
static int
send_message (mu_message_t msg)
{
+ char *mailer_url = NULL;
char *sendmail;
int status;
if (mailvar_get (&sendmail, mailvar_name_sendmail,
mailvar_type_string, 0) == 0)
{
+ if (mailvar_is_true (mailvar_name_mailx))
+ {
+ /*
+ * Mailx compatibility: assume sendmail:// scheme.
+ */
+ if (!mu_is_proto (sendmail))
+ {
+ status = mu_asprintf (&mailer_url, "sendmail://%s", sendmail);
+ if (status)
+ return status;
+ sendmail = mailer_url;
+ }
+ }
+
if (sendmail[0] == '/')
status = msg_to_pipe (sendmail, msg);
else
@@ -1151,8 +1180,10 @@ send_message (mu_message_t msg)
if (mailvar_get (&return_address_str, mailvar_name_return_address,
mailvar_type_string, 0) == 0)
{
- status = mu_address_create (&return_address,
- return_address_str);
+ struct mu_address hint = MU_ADDRESS_HINT_INITIALIZER;
+ status = mu_address_create_hint (&return_address,
+ return_address_str,
+ &hint, 0);
if (status)
{
mu_error (_("invalid return address: %s"),
@@ -1189,10 +1220,38 @@ send_message (mu_message_t msg)
mu_error (_("Variable sendmail not set: no mailer"));
status = ENOSYS;
}
+ free (mailer_url);
return status;
}
-/* mail_send0(): shared between mail_send() and mail_reply();
+#define MU_DATETIME_RFC822_LENGTH 31
+
+static void
+message_add_date (mu_message_t msg)
+{
+ mu_header_t hdr;
+ char buf[MU_DATETIME_RFC822_LENGTH+1];
+ struct tm ltm;
+ time_t t;
+ int rc;
+
+ rc = mu_message_get_header (msg, &hdr);
+ if (rc)
+ {
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_message_get_header", NULL, rc);
+ return;
+ }
+
+ t = time (NULL);
+ localtime_r (&t, &ltm);
+
+ mu_strftime (buf, sizeof (buf), MU_DATETIME_FORM_RFC822, &ltm);
+ rc = mu_header_set_value (hdr, MU_HEADER_DATE, buf, 1);
+ if (rc)
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_header_set_value", MU_HEADER_DATE, rc);
+}
+
+/* mail_compose_send(): shared between mail_send() and mail_reply();
If the variable "record" is set, the outgoing message is
saved after being sent. If "save_to" argument is non-zero,
@@ -1208,7 +1267,7 @@ send_message (mu_message_t msg)
addresses on the command line and message contents on standard input. */
int
-mail_send0 (compose_env_t *env, int save_to)
+mail_compose_send (compose_env_t *env, int save_to)
{
int done = 0;
int rc;
@@ -1265,8 +1324,9 @@ mail_send0 (compose_env_t *env, int save_to)
if (strcmp (buf, ".") == 0 && mailvar_is_true (mailvar_name_dot))
done = 1;
- else if (mailvar_get (&escape, mailvar_name_escape,
- mailvar_type_string, 0) == 0
+ else if (interactive
+ && mailvar_get (&escape, mailvar_name_escape,
+ mailvar_type_string, 0) == 0
&& buf[0] == escape[0])
{
if (buf[1] == buf[0])
@@ -1324,10 +1384,10 @@ mail_send0 (compose_env_t *env, int save_to)
read_cc_bcc (env);
/* Prepare the header */
- if (mailvar_is_true (mailvar_name_xmailer))
- mu_header_set_value (env->header, MU_HEADER_X_MAILER, program_version, 1);
+ if (mailvar_is_true (mailvar_name_useragent))
+ mu_header_set_value (env->header, MU_HEADER_USER_AGENT, program_version, 1);
- if (util_header_expand (&env->header) == 0)
+ if (util_header_expand_aliases (&env->header) == 0)
{
mu_message_t msg = NULL;
int status = 0;
@@ -1353,23 +1413,23 @@ mail_send0 (compose_env_t *env, int save_to)
if (status)
break;
+ message_add_date (msg);
+
/* Save outgoing message */
if (save_to)
{
- char const *rcpt = compose_header_get (env, MU_HEADER_TO, NULL);
- if (rcpt)
+ mu_header_t hdr;
+ char const *rcpt;
+
+ mu_message_get_header (msg, &hdr);
+ if (mu_header_sget_value (hdr, MU_HEADER_TO, &rcpt) == 0)
{
mu_address_t addr = NULL;
-
- mu_address_create (&addr, rcpt);
- mu_address_aget_email (addr, 1, &savefile);
+ struct mu_address hint = MU_ADDRESS_HINT_INITIALIZER;
+
+ mu_address_create_hint (&addr, rcpt, &hint, 0);
+ savefile = util_outfilename (addr);
mu_address_destroy (&addr);
- if (savefile)
- {
- char *p = strchr (savefile, '@');
- if (p)
- *p = 0;
- }
}
}
util_save_outgoing (msg, savefile);
@@ -1454,8 +1514,18 @@ msg_to_pipe (const char *cmd, mu_message_t msg)
{
mu_stream_t progstream, msgstream;
int status, rc;
-
- status = mu_command_stream_create (&progstream, cmd, MU_STREAM_WRITE);
+ char *argv[4];
+
+ argv[0] = getenv ("SHELL");
+ if (!argv[0])
+ argv[0] = "/bin/sh";
+ argv[1] = "-c";
+ argv[2] = (char*) cmd;
+ argv[3] = NULL;
+ status = mu_prog_stream_create (&progstream,
+ argv[0],
+ 3, argv,
+ 0, NULL, MU_STREAM_WRITE);
if (status)
{
mu_error (_("Cannot pipe to %s: %s"), cmd, mu_strerror (status));

Return to:

Send suggestions and report system problems to the System administrator.