summaryrefslogtreecommitdiff
path: root/mail
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2016-11-04 18:00:14 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2016-11-04 18:00:14 +0200
commitaf20212718728b315449ff35685772302883fc3d (patch)
tree8bc92e4a5c194e5d54d18e2486aac5ae8256fca2 /mail
parentedb05144ade1984e28d88cfaea7c2fb0ec675f5b (diff)
downloadmailutils-af20212718728b315449ff35685772302883fc3d.tar.gz
mailutils-af20212718728b315449ff35685772302883fc3d.tar.bz2
Fix operation of mail -t; some other minor fixes
* mail/escape.c (parse_headers): Moved to send.c (check_headers): New function. (escape_continue): Use check_headers. * mail/mail.c (read_recipients): New variable. The -t option sets read_recipients and editheaders * mail/mail.h (parse_headers): New proto. * mail/send.c: Special handling for -t option. (parse_headers): New function. * movemail/movemail.c (onerror statement): Accept a list as argument. * doc/texinfo/mailutils.texi: Update. * doc/texinfo/programs.texi: Update.
Diffstat (limited to 'mail')
-rw-r--r--mail/escape.c121
-rw-r--r--mail/mail.c13
-rw-r--r--mail/mail.h9
-rw-r--r--mail/send.c166
-rw-r--r--mail/table.c4
5 files changed, 191 insertions, 122 deletions
diff --git a/mail/escape.c b/mail/escape.c
index c07d29ad1..4c337e0dd 100644
--- a/mail/escape.c
+++ b/mail/escape.c
@@ -37,119 +37,26 @@ dump_headers (mu_stream_t out, compose_env_t *env)
mu_stream_destroy (&stream);
}
-#define STATE_INIT 0
-#define STATE_READ 1
-#define STATE_BODY 2
-
static int
-parse_headers (mu_stream_t input, compose_env_t *env)
+check_headers (mu_stream_t input, compose_env_t *env)
{
- int status;
- mu_header_t header;
- char *name = NULL;
- char *value = NULL;
- int state = STATE_INIT;
- char *buf = NULL;
- size_t size = 0, n;
- int errcnt = 0, line = 0;
+ char *p;
- if ((status = mu_header_create (&header, NULL, 0)) != 0)
- {
- mu_error (_("Cannot create header: %s"), mu_strerror (status));
- return 1;
- }
-
mu_stream_seek (input, 0, MU_SEEK_SET, NULL);
- while (state != STATE_BODY &&
- errcnt == 0 &&
- mu_stream_getline (input, &buf, &size, &n) == 0 && n > 0)
+ switch (parse_headers (input, env))
{
- mu_rtrim_class (buf, MU_CTYPE_SPACE);
-
- line++;
- switch (state)
- {
- case STATE_INIT:
- if (!buf[0] || mu_isspace (buf[0]))
- continue;
- else
- state = STATE_READ;
- /*FALLTHRU*/
-
- case STATE_READ:
- if (buf[0] == 0)
- state = STATE_BODY;
- else if (mu_isspace (buf[0]))
- {
- /* A continuation line */
- if (name)
- {
- char *p = NULL;
- mu_asprintf (&p, "%s\n%s", value, buf);
- free (value);
- value = p;
- }
- else
- {
- mu_error (_("%d: not a header line"), line);
- errcnt++;
- }
- }
- else
- {
- char *p;
-
- if (name)
- {
- mu_header_set_value (header, name, value[0] ? value : NULL, 0);
- free (name);
- free (value);
- name = value = NULL;
- }
- p = strchr (buf, ':');
- if (p)
- {
- *p++ = 0;
- while (*p && mu_isspace (*p))
- p++;
- value = mu_strdup (p);
- name = mu_strdup (buf);
- }
- else
- {
- mu_error (_("%d: not a header line"), line);
- errcnt++;
- }
- }
- break;
- }
+ case parse_headers_ok:
+ return 0;
+ case parse_headers_fatal:
+ return -1;
+ case parse_headers_error:
+ break;
}
- free (buf);
- if (name)
- {
- mu_header_set_value (header, name, value, 0);
- free (name);
- free (value);
- }
-
- if (errcnt)
- {
- char *p;
-
- mu_header_destroy (&header);
- p = ml_readline (_("Edit again?"));
- if (mu_true_answer_p (p) == 1)
- return -1;
- else
- return 1;
- }
-
- mu_header_destroy (&env->header);
- env->header = header;
- return 0;
-}
-
+ p = ml_readline (_("Edit again?"));
+ return mu_true_answer_p (p);
+}
+
static void
escape_continue (void)
{
@@ -386,7 +293,7 @@ escape_run_editor (char *ed, int argc, char **argv, compose_env_t *env)
return rc;
}
}
- while ((rc = parse_headers (tempstream, env)) < 0);
+ while (check_headers (tempstream, env));
}
else
{
diff --git a/mail/mail.c b/mail/mail.c
index cd8c46680..6a804252c 100644
--- a/mail/mail.c
+++ b/mail/mail.c
@@ -23,6 +23,7 @@
mu_mailbox_t mbox; /* Mailbox being operated upon */
size_t total; /* Total number of messages in the mailbox */
int interactive; /* Is the session interactive */
+int read_recipients; /* Read recipients from the message (mail -t) */
static mu_list_t command_list;/* List of commands to be executed after parsing
command line */
@@ -72,6 +73,8 @@ cli_command_option (struct mu_parseopt *po, struct mu_option *opt,
break;
case 't':
+ read_recipients = 1;
+ util_cache_command (&command_list, "set editheaders");
util_cache_command (&command_list, "setq mode=send");
break;
@@ -186,7 +189,7 @@ static struct mu_option mail_options[] = {
mu_c_string, NULL, cli_subject },
{ "to", 't', NULL, MU_OPTION_DEFAULT,
- N_("precede message by a list of addresses"),
+ N_("read recipients from the message header"),
mu_c_string, NULL, cli_command_option },
{ "user", 'u', N_("USER"), MU_OPTION_DEFAULT,
@@ -227,7 +230,7 @@ static struct mu_cli_setup cli = {
options,
NULL,
N_("GNU mail -- process mail messages.\n"
-"If -f or --file is given, mail operates on the mailbox named "
+ "If -f or --file is given, mail operates on the mailbox named "
"by the first argument, or the user's mbox, if no argument given."),
N_("[address...]"),
alt_args,
@@ -421,6 +424,12 @@ main (int argc, char **argv)
/* argument parsing */
mu_cli (argc, argv, &cli, mail_capa, NULL, &argc, &argv);
+ if (read_recipients)
+ {
+ argv += argc;
+ argc = 0;
+ }
+
if ((hint & (HINT_SEND_MODE|HINT_FILE_OPTION)) ==
(HINT_SEND_MODE|HINT_FILE_OPTION))
{
diff --git a/mail/mail.h b/mail/mail.h
index b589d3e13..0c4465f48 100644
--- a/mail/mail.h
+++ b/mail/mail.h
@@ -288,6 +288,15 @@ extern int escape_attach (int argc, char **argv, compose_env_t *env);
extern int escape_remove_attachment (int argc, char **argv,
compose_env_t *env);
+enum
+ {
+ parse_headers_ok,
+ parse_headers_error,
+ parse_headers_fatal
+ };
+
+extern int parse_headers (mu_stream_t input, compose_env_t *env);
+
/* Cursor */
extern void set_cursor (unsigned value);
extern size_t get_cursor (void);
diff --git a/mail/send.c b/mail/send.c
index c2ed4e4ce..8a39d08c0 100644
--- a/mail/send.c
+++ b/mail/send.c
@@ -488,8 +488,42 @@ mail_send (int argc, char **argv)
compose_init (&env);
if (argc < 2)
- compose_header_set (&env, MU_HEADER_TO, ml_readline_with_intr ("To: "),
- COMPOSE_REPLACE);
+ {
+ if (interactive)
+ compose_header_set (&env, MU_HEADER_TO, ml_readline_with_intr ("To: "),
+ COMPOSE_REPLACE);
+ else if (!mailvar_get (NULL, "editheaders", mailvar_type_boolean, 0))
+ {
+ if (parse_headers (mu_strin, &env) != parse_headers_ok)
+ {
+ mu_error ("%s", _("Errors parsing message"));
+ exit (EXIT_FAILURE);
+ }
+ if (add_header_list)
+ {
+ mu_iterator_t itr;
+ mu_list_get_iterator (add_header_list, &itr);
+ for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
+ mu_iterator_next (itr))
+ {
+ struct add_header *hp;
+ int mode;
+ if (mu_iterator_current (itr, (void**) &hp))
+ break;
+ mode = hp->mode;
+ if (mu_header_sget_value (env.header, hp->name, NULL) == 0)
+ mode = COMPOSE_REPLACE;
+ compose_header_set (&env, hp->name, hp->value, hp->mode);
+ }
+ mu_iterator_destroy (&itr);
+ }
+ }
+ else
+ {
+ mu_error ("%s", _("No recipients specified"));
+ exit (EXIT_FAILURE);
+ }
+ }
else
{
while (--argc)
@@ -511,27 +545,137 @@ mail_send (int argc, char **argv)
}
}
- if (mailvar_get (NULL, "mailx", mailvar_type_boolean, 0))
- read_cc_bcc (&env);
-
- if (mailvar_get (NULL, "asksub", mailvar_type_boolean, 0) == 0)
- compose_header_set (&env, MU_HEADER_SUBJECT,
- ml_readline_with_intr ("Subject: "), COMPOSE_REPLACE);
+ if (interactive)
+ {
+ if (mailvar_get (NULL, "mailx", mailvar_type_boolean, 0))
+ read_cc_bcc (&env);
+ if (mailvar_get (NULL, "asksub", mailvar_type_boolean, 0) == 0)
+ compose_header_set (&env, MU_HEADER_SUBJECT,
+ ml_readline_with_intr ("Subject: "),
+ COMPOSE_REPLACE);
+ }
+
status = mail_send0 (&env, save_to);
compose_destroy (&env);
return status;
}
+
+int
+parse_headers (mu_stream_t input, compose_env_t *env)
+{
+ int status;
+ mu_header_t header;
+ char *name = NULL;
+ char *value = NULL;
+ enum { STATE_INIT, STATE_READ, STATE_BODY } state = STATE_INIT;
+ char *buf = NULL;
+ size_t size = 0, n;
+ int errcnt = 0, line = 0;
+
+ if ((status = mu_header_create (&header, NULL, 0)) != 0)
+ {
+ mu_error (_("Cannot create header: %s"), mu_strerror (status));
+ return parse_headers_fatal;
+ }
+
+ while (state != STATE_BODY &&
+ errcnt == 0 &&
+ mu_stream_getline (input, &buf, &size, &n) == 0 && n > 0)
+ {
+ mu_rtrim_class (buf, MU_CTYPE_SPACE);
+
+ line++;
+ switch (state)
+ {
+ case STATE_INIT:
+ if (!buf[0] || mu_isspace (buf[0]))
+ continue;
+ else
+ state = STATE_READ;
+ /*FALLTHRU*/
+
+ case STATE_READ:
+ if (buf[0] == 0)
+ state = STATE_BODY;
+ else if (mu_isspace (buf[0]))
+ {
+ /* A continuation line */
+ if (name)
+ {
+ char *p = NULL;
+ mu_asprintf (&p, "%s\n%s", value, buf);
+ free (value);
+ value = p;
+ }
+ else
+ {
+ mu_error (_("%d: not a header line"), line);
+ errcnt++;
+ }
+ }
+ else
+ {
+ char *p;
+
+ if (name)
+ {
+ mu_header_set_value (header, name, value[0] ? value : NULL, 0);
+ free (name);
+ free (value);
+ name = value = NULL;
+ }
+ p = strchr (buf, ':');
+ if (p)
+ {
+ *p++ = 0;
+ while (*p && mu_isspace (*p))
+ p++;
+ value = mu_strdup (p);
+ name = mu_strdup (buf);
+ }
+ else
+ {
+ mu_error (_("%d: not a header line"), line);
+ errcnt++;
+ }
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ free (buf);
+ if (name)
+ {
+ mu_header_set_value (header, name, value, 0);
+ free (name);
+ free (value);
+ }
+
+ if (errcnt)
+ {
+ mu_header_destroy (&header);
+ return parse_headers_error;
+ }
+
+ mu_header_destroy (&env->header);
+ env->header = header;
+ return parse_headers_ok;
+}
+
void
-compose_init (compose_env_t * env)
+compose_init (compose_env_t *env)
{
memset (env, 0, sizeof (*env));
mu_list_foreach (add_header_list, seed_headers, env);
}
int
-compose_header_set (compose_env_t * env, const char *name,
+compose_header_set (compose_env_t *env, const char *name,
const char *value, int mode)
{
int status;
@@ -601,7 +745,7 @@ compose_header_set (compose_env_t * env, const char *name,
}
char *
-compose_header_get (compose_env_t * env, char *name, char *defval)
+compose_header_get (compose_env_t *env, char *name, char *defval)
{
char *p;
diff --git a/mail/table.c b/mail/table.c
index b5ffa0322..4c3f4f728 100644
--- a/mail/table.c
+++ b/mail/table.c
@@ -226,8 +226,8 @@ static const struct mail_escape_entry mail_escape_table[] = {
{"!", "!", "![shell-command]", escape_shell },
{":", ":", ":[mail-command]", escape_command },
{"-", "-", "-[mail-command]", escape_command },
- {"+", "+", "+[name [content-type [encoding]]]", escape_attach },
- {"^", "^", "^[N]", escape_remove_attachment },
+ {"+", "+", "+name [content-type [encoding]]", escape_attach },
+ {"^", "^", "^N", escape_remove_attachment },
{"?", "?", "?", escape_help },
{"A", "A", "A", escape_sign },
{"a", "a", "a", escape_sign },

Return to:

Send suggestions and report system problems to the System administrator.