diff options
Diffstat (limited to 'mail/reply.c')
-rw-r--r-- | mail/reply.c | 318 |
1 files changed, 252 insertions, 66 deletions
diff --git a/mail/reply.c b/mail/reply.c index 80ae4f83a..eed71fae1 100644 --- a/mail/reply.c +++ b/mail/reply.c @@ -1,5 +1,5 @@ /* GNU Mailutils -- a suite of utilities for electronic mail - Copyright (C) 1999-2019 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 @@ -38,99 +38,285 @@ make_references (compose_env_t *env, mu_message_t msg) } /* - * r[eply] [msglist] -- GNU extension - * r[espond] [msglist] -- GNU extension + * r[eply] [message] + * r[espond] [message] + * Reply to all recipients of the message. Save to record. + * reply_all = 1, send_to = 0 * R[eply] [msglist] * R[espond] [msglist] + * Reply to the sender of each message in msglist. Save to record. + * reply_all = 0, send_to = 0 + * fo[llowup] message + * Reply to all recipients of the message. Save by name. + * reply_all = 1, send_to = 1 + * F[ollowup] msglist + * Reply to the sender of each message in msglist. Save by name. + * reply_all = 0, send_to = 1 */ -int -reply0 (msgset_t *mspec, mu_message_t msg, void *data) +static void +compose_set_address (compose_env_t *env, char const *hname, char const *input) { - mu_header_t hdr; - compose_env_t env; - int status; - char *str; - - set_cursor (mspec->msg_part[0]); + struct mu_address hint = MU_ADDRESS_HINT_INITIALIZER; + mu_address_t iaddr, oaddr = NULL, ap; + char *result = NULL; - compose_init (&env); - - mu_message_get_header (msg, &hdr); + if (mu_address_create_hint (&iaddr, input, &hint, 0)) + result = mu_strdup (input); + else + { + for (ap = iaddr; ap; ap = ap->next) + { + const char *email; + if (mu_address_sget_email (ap, 1, &email) || email == NULL) + continue; + if (!(mailvar_is_true (mailvar_name_metoo) && + mail_is_my_name (email))) + mu_address_union (&oaddr, ap); + } + mu_address_destroy (&iaddr); + mu_address_aget_printable (oaddr, &result); + mu_address_destroy (&oaddr); + } + if (result && result[0]) + { + compose_header_set (env, hname, result, COMPOSE_SINGLE_LINE); + free (result); + } +} - compose_header_set (&env, MU_HEADER_TO, - util_get_sender (mspec->msg_part[0], 0), - COMPOSE_SINGLE_LINE); +static void +compose_remove_personal (compose_env_t *env, char *hname) +{ + char const *value; - if (*(int*) data) /* reply starts with a lowercase */ + value = compose_header_get (env, hname, NULL); + if (value) { - /* Add all recepients of the originate letter */ + mu_address_t addr = NULL, ap; + struct mu_address hint = MU_ADDRESS_HINT_INITIALIZER; + char *result; + + mu_address_create_hint (&addr, value, &hint, 0); + for (ap = addr; ap; ap = ap->next) + { + free (ap->printable); + ap->printable = NULL; + free (ap->comments); + ap->comments = NULL; + free (ap->personal); + ap->personal = NULL; + free (ap->route); + ap->route = NULL; + } + mu_address_aget_printable (addr, &result); + compose_header_set (env, hname, result, COMPOSE_REPLACE); + free (result); + mu_address_destroy (&addr); + } +} - mu_address_t addr = NULL; - size_t i, count = 0; +/* + * r[eply] [message] + * r[espond] [message] + * fo[llowup] message + * + * Reply to all recipients of a single message + */ +int +respond_all (int argc, char **argv, int record_sender) +{ + int status; + compose_env_t env; + mu_message_t msg; + mu_header_t hdr; + char const *str; + char *p; - if (mu_header_aget_value (hdr, MU_HEADER_TO, &str) == 0) + msgset_t *msgset = NULL; + + if (msgset_parse (argc, argv, MSG_NODELETED, &msgset)) + return 1; + + if (msgset->next) + { + mu_error (_("Can't reply to multiple messages at once")); + status = 1; + } + else if (util_get_message (mbox, msgset_msgno (msgset), &msg)) + { + status = 1; + } + else + { + set_cursor (msgset_msgno (msgset)); + + mu_message_get_header (msg, &hdr); + + compose_init (&env); + + p = util_message_sender (msg, 0); + if (p) { - mu_address_create (&addr, str); - free (str); - mu_address_get_count (addr, &count); + compose_set_address (&env, MU_HEADER_TO, p); + free (p); } - - /* Make sure we do not include our alternate names */ - for (i = 1; i <= count; i++) + + /* Add the rest of recipients */ + if (mu_header_sget_value (hdr, MU_HEADER_TO, &str) == 0) { - const char *email; - if (mu_address_sget_email (addr, i, &email) || email == NULL) - continue; - if (mailvar_is_true (mailvar_name_metoo) || !mail_is_my_name (email)) - compose_header_set (&env, MU_HEADER_TO, - email, - COMPOSE_SINGLE_LINE); + compose_set_address (&env, MU_HEADER_TO, str); } - mu_address_destroy (&addr); + if (mu_header_sget_value (hdr, MU_HEADER_CC, &str) == 0) + { + compose_set_address (&env, MU_HEADER_CC, str); + } + + /* Add header line */ + //FIXME: decode + if (mu_header_aget_value (hdr, MU_HEADER_SUBJECT, &p) == 0) + { + char *subj = NULL; + + if (mu_unre_subject (p, NULL)) + util_strcat (&subj, util_reply_prefix ()); + util_strcat (&subj, p); + free (p); + compose_header_set (&env, MU_HEADER_SUBJECT, subj, COMPOSE_REPLACE); + free (subj); + } + else + compose_header_set (&env, MU_HEADER_SUBJECT, "", COMPOSE_REPLACE); - /* Finally, add any Ccs */ - if (mu_header_aget_value (hdr, MU_HEADER_CC, &str) == 0) - compose_header_set (&env, MU_HEADER_TO, str, COMPOSE_SINGLE_LINE); + if (!mailvar_is_true (mailvar_name_fullnames)) + { + compose_remove_personal (&env, MU_HEADER_TO); + compose_remove_personal (&env, MU_HEADER_CC); + } + + mu_printf ("To: %s\n", compose_header_get (&env, MU_HEADER_TO, "")); + str = compose_header_get (&env, MU_HEADER_CC, NULL); + if (str) + mu_printf ("Cc: %s\n", str); + mu_printf ("Subject: %s\n\n", + compose_header_get (&env, MU_HEADER_SUBJECT, "")); + + make_in_reply_to (&env, msg); + make_references (&env, msg); + status = mail_compose_send (&env, record_sender); + compose_destroy (&env); + util_mark_read (msg); } + msgset_free (msgset); + + return status; +} - if (mu_header_aget_value (hdr, MU_HEADER_SUBJECT, &str) == 0) +/* + * R[eply] [msglist] + * R[espond] [msglist] + * F[ollowup] msglist + * + * Reply to the sender of each message in msglist. + */ +int +respond_msg (int argc, char **argv, int record_sender) +{ + mu_message_t msg; + mu_header_t hdr; + compose_env_t env; + int status; + char *p; + char const *str; + + msgset_t *msgset = NULL, *mp; + + if (msgset_parse (argc, argv, MSG_NODELETED, &msgset)) + return 1; + + if (util_get_message (mbox, msgset_msgno (msgset), &msg)) { - char *p = NULL; - - if (mu_unre_subject (str, NULL)) - util_strcat (&p, util_reply_prefix ()); - util_strcat (&p, str); - free (str); - compose_header_set (&env, MU_HEADER_SUBJECT, p, COMPOSE_REPLACE); - free (p); + status = 1; } else - compose_header_set (&env, MU_HEADER_SUBJECT, "", COMPOSE_REPLACE); - - mu_printf ("To: %s\n", - compose_header_get (&env, MU_HEADER_TO, "")); - str = compose_header_get (&env, MU_HEADER_CC, NULL); - if (str) - mu_printf ("Cc: %s\n", str); - mu_printf ("Subject: %s\n\n", - compose_header_get (&env, MU_HEADER_SUBJECT, "")); + { + size_t last; + + set_cursor (msgset_msgno (msgset)); + + mu_message_get_header (msg, &hdr); + + compose_init (&env); + + for (mp = msgset; mp; mp = mp->next) + { + mu_message_t mesg; + last = msgset_msgno (mp); + if (util_get_message (mbox, last, &mesg) == 0) + { + p = util_message_sender (mesg, 0); + if (p) + { + compose_set_address (&env, MU_HEADER_TO, p); + free (p); + } + util_mark_read (mesg); + } + } + + /* Add subject header */ + if (mu_header_aget_value (hdr, MU_HEADER_SUBJECT, &p) == 0) + { + char *subj = NULL; + + if (mu_unre_subject (p, NULL)) + util_strcat (&subj, util_reply_prefix ()); + util_strcat (&subj, p); + free (p); + compose_header_set (&env, MU_HEADER_SUBJECT, subj, COMPOSE_REPLACE); + free (subj); + } + else + compose_header_set (&env, MU_HEADER_SUBJECT, "", COMPOSE_REPLACE); + + if (!mailvar_is_true (mailvar_name_fullnames)) + { + compose_remove_personal (&env, MU_HEADER_TO); + compose_remove_personal (&env, MU_HEADER_CC); + } + + mu_printf ("To: %s\n", compose_header_get (&env, MU_HEADER_TO, "")); + str = compose_header_get (&env, MU_HEADER_CC, NULL); + if (str) + mu_printf ("Cc: %s\n", str); + mu_printf ("Subject: %s\n\n", + compose_header_get (&env, MU_HEADER_SUBJECT, "")); - make_in_reply_to (&env, msg); - make_references (&env, msg); - status = mail_send0 (&env, mailvar_is_true (mailvar_name_byname)); - compose_destroy (&env); + make_in_reply_to (&env, msg); + make_references (&env, msg); + status = mail_compose_send (&env, record_sender); + compose_destroy (&env); - return status; + set_cursor (last); + } + msgset_free (msgset); + + return status; } int mail_reply (int argc, char **argv) { - int lower = mu_islower (argv[0][0]); + int all = mu_islower (argv[0][0]); if (mailvar_is_true (mailvar_name_flipr)) - lower = !lower; - return util_foreach_msg (argc, argv, MSG_NODELETED, reply0, &lower); + all = !all; + return (all ? respond_all : respond_msg) (argc, argv, 0); } - + +int +mail_followup (int argc, char **argv) +{ + int all = mu_islower (argv[0][0]); + return (all ? respond_all : respond_msg) (argc, argv, 1); +} |