diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-11-04 18:00:14 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-11-04 18:00:14 +0200 |
commit | af20212718728b315449ff35685772302883fc3d (patch) | |
tree | 8bc92e4a5c194e5d54d18e2486aac5ae8256fca2 /mail | |
parent | edb05144ade1984e28d88cfaea7c2fb0ec675f5b (diff) | |
download | mailutils-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.c | 121 | ||||
-rw-r--r-- | mail/mail.c | 13 | ||||
-rw-r--r-- | mail/mail.h | 9 | ||||
-rw-r--r-- | mail/send.c | 166 | ||||
-rw-r--r-- | mail/table.c | 4 |
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 }, |