📄 recvcmd.c
字号:
/* * Copyright (C) 1999-2000 Thomas Roessler <roessler@does-not-exist.org> * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */#if HAVE_CONFIG_H# include "config.h"#endif#include "mutt.h"#include "mutt_curses.h"#include "mutt_menu.h"#include "rfc1524.h"#include "mime.h"#include "mailbox.h"#include "attach.h"#include "mapping.h"#include "mx.h"#include "copy.h"#include "mutt_idna.h"/* some helper functions to verify that we are exclusively operating * on message/rfc822 attachments */static short check_msg (BODY * b, short err){ if (!mutt_is_message_type (b->type, b->subtype)) { if (err) mutt_error _("You may only bounce message/rfc822 parts."); return -1; } return 0;}static short check_all_msg (ATTACHPTR ** idx, short idxlen, BODY * cur, short err){ short i; if (cur && check_msg (cur, err) == -1) return -1; else if (!cur) { for (i = 0; i < idxlen; i++) { if (idx[i]->content->tagged) { if (check_msg (idx[i]->content, err) == -1) return -1; } } } return 0;}/* can we decode all tagged attachments? */static short check_can_decode (ATTACHPTR ** idx, short idxlen, BODY * cur){ short i; if (cur) return mutt_can_decode (cur); for (i = 0; i < idxlen; i++) if (idx[i]->content->tagged && !mutt_can_decode (idx[i]->content)) return 0; return 1;}static short count_tagged (ATTACHPTR **idx, short idxlen){ short count = 0; short i; for (i = 0; i < idxlen; i++) if (idx[i]->content->tagged) count++; return count;}/* count the number of tagged children below a multipart or message * attachment. */static short count_tagged_children (ATTACHPTR ** idx, short idxlen, short i){ short level = idx[i]->level; short count = 0; while ((++i < idxlen) && (level < idx[i]->level)) if (idx[i]->content->tagged) count++; return count;}/** ** ** The bounce function, from the attachment menu ** **/void mutt_attach_bounce (FILE * fp, HEADER * hdr, ATTACHPTR ** idx, short idxlen, BODY * cur){ short i; char prompt[STRING]; char buf[HUGE_STRING]; char *err = NULL; ADDRESS *adr = NULL; int ret = 0; int p = 0; if (check_all_msg (idx, idxlen, cur, 1) == -1) return; /* one or more messages? */ p = (cur || count_tagged (idx, idxlen) == 1); if (p) strfcpy (prompt, _("Bounce message to: "), sizeof (prompt)); else strfcpy (prompt, _("Bounce tagged messages to: "), sizeof (prompt)); buf[0] = '\0'; if (mutt_get_field (prompt, buf, sizeof (buf), M_ALIAS) || buf[0] == '\0') return; if (!(adr = rfc822_parse_adrlist (adr, buf))) { mutt_error _("Error parsing address!"); return; } adr = mutt_expand_aliases (adr); if (mutt_addrlist_to_idna (adr, &err) < 0) { mutt_error (_("Bad IDN: '%s'"), err); FREE (&err); rfc822_free_address (&adr); return; } buf[0] = 0; rfc822_write_address (buf, sizeof (buf), adr, 1);#define extra_space (15+7+2) /* * See commands.c. */ snprintf (prompt, sizeof (prompt) - 4, (p ? _("Bounce message to %s") : _("Bounce messages to %s")), buf); if (mutt_strwidth (prompt) > COLS - extra_space) { mutt_format_string (prompt, sizeof (prompt) - 4, 0, COLS-extra_space, 0, 0, prompt, sizeof (prompt), 0); safe_strcat (prompt, sizeof (prompt), "...?"); } else safe_strcat (prompt, sizeof (prompt), "?"); if (query_quadoption (OPT_BOUNCE, prompt) != M_YES) { rfc822_free_address (&adr); CLEARLINE (LINES - 1); mutt_message (p ? _("Message not bounced.") : _("Messages not bounced.")); return; } CLEARLINE (LINES - 1); if (cur) ret = mutt_bounce_message (fp, cur->hdr, adr); else { for (i = 0; i < idxlen; i++) { if (idx[i]->content->tagged) if (mutt_bounce_message (fp, idx[i]->content->hdr, adr)) ret = 1; } } if (!ret) mutt_message (p ? _("Message bounced.") : _("Messages bounced.")); else mutt_error (p ? _("Error bouncing message!") : _("Error bouncing messages!"));}/** ** ** resend-message, from the attachment menu ** ** **/void mutt_attach_resend (FILE * fp, HEADER * hdr, ATTACHPTR ** idx, short idxlen, BODY * cur){ short i; if (check_all_msg (idx, idxlen, cur, 1) == -1) return; if (cur) mutt_resend_message (fp, Context, cur->hdr); else { for (i = 0; i < idxlen; i++) if (idx[i]->content->tagged) mutt_resend_message (fp, Context, idx[i]->content->hdr); }}/** ** ** forward-message, from the attachment menu ** **/ /* try to find a common parent message for the tagged attachments. */static HEADER *find_common_parent (ATTACHPTR ** idx, short idxlen, short nattach){ short i; short nchildren; for (i = 0; i < idxlen; i++) if (idx[i]->content->tagged) break; while (--i >= 0) { if (mutt_is_message_type (idx[i]->content->type, idx[i]->content->subtype)) { nchildren = count_tagged_children (idx, idxlen, i); if (nchildren == nattach) return idx[i]->content->hdr; } } return NULL;}/* * check whether attachment #i is a parent of the attachment * pointed to by cur * * Note: This and the calling procedure could be optimized quite a * bit. For now, it's not worth the effort. */static int is_parent (short i, ATTACHPTR **idx, short idxlen, BODY *cur){ short level = idx[i]->level; while ((++i < idxlen) && idx[i]->level > level) { if (idx[i]->content == cur) return 1; } return 0;}static HEADER *find_parent (ATTACHPTR **idx, short idxlen, BODY *cur, short nattach){ short i; HEADER *parent = NULL; if (cur) { for (i = 0; i < idxlen; i++) { if (mutt_is_message_type (idx[i]->content->type, idx[i]->content->subtype) && is_parent (i, idx, idxlen, cur)) parent = idx[i]->content->hdr; if (idx[i]->content == cur) break; } } else if (nattach) parent = find_common_parent (idx, idxlen, nattach); return parent;}static void include_header (int quote, FILE * ifp, HEADER * hdr, FILE * ofp, char *_prefix){ int chflags = CH_DECODE; char prefix[SHORT_STRING]; if (option (OPTWEED)) chflags |= CH_WEED | CH_REORDER; if (quote) { if (_prefix) strfcpy (prefix, _prefix, sizeof (prefix)); else if (!option (OPTTEXTFLOWED)) _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context, hdr, 0); else strfcpy (prefix, ">", sizeof (prefix)); chflags |= CH_PREFIX; } mutt_copy_header (ifp, hdr, ofp, chflags, quote ? prefix : NULL);}/* Attach all the body parts which can't be decoded. * This code is shared by forwarding and replying. */static BODY ** copy_problematic_attachments (FILE *fp, BODY **last, ATTACHPTR **idx, short idxlen, short force){ short i; for (i = 0; i < idxlen; i++) { if (idx[i]->content->tagged && (force || !mutt_can_decode (idx[i]->content))) { if (mutt_copy_body (fp, last, idx[i]->content) == -1) return NULL; /* XXXXX - may lead to crashes */ last = &((*last)->next); } } return last;}/* * forward one or several MIME bodies * (non-message types) */static void attach_forward_bodies (FILE * fp, HEADER * hdr, ATTACHPTR ** idx, short idxlen, BODY * cur, short nattach){ short i; short mime_fwd_all = 0; short mime_fwd_any = 1; HEADER *parent = NULL; HEADER *tmphdr = NULL; BODY **last; char tmpbody[_POSIX_PATH_MAX]; FILE *tmpfp = NULL; char prefix[STRING]; int rc = 0; STATE st; /* * First, find the parent message. * Note: This could be made an option by just * putting the following lines into an if block. */ parent = find_parent (idx, idxlen, cur, nattach); if (parent == NULL) parent = hdr; tmphdr = mutt_new_header (); tmphdr->env = mutt_new_envelope (); mutt_make_forward_subject (tmphdr->env, Context, parent); mutt_mktemp (tmpbody); if ((tmpfp = safe_fopen (tmpbody, "w")) == NULL) { mutt_error (_("Can't open temporary file %s."), tmpbody); return; } mutt_forward_intro (tmpfp, parent); /* prepare the prefix here since we'll need it later. */ if (option (OPTFORWQUOTE)) { if (!option (OPTTEXTFLOWED)) _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context, parent, 0); else strfcpy (prefix, ">", sizeof (prefix)); } include_header (option (OPTFORWQUOTE), fp, parent, tmpfp, prefix); /* * Now, we have prepared the first part of the message body: The * original message's header. * * The next part is more interesting: either include the message bodies, * or attach them. */ if ((!cur || mutt_can_decode (cur)) && (rc = query_quadoption (OPT_MIMEFWD, _("Forward as attachments?"))) == M_YES) mime_fwd_all = 1; else if (rc == -1) goto bail; /* * shortcut MIMEFWDREST when there is only one attachment. Is * this intuitive? */ if (!mime_fwd_all && !cur && (nattach > 1) && !check_can_decode (idx, idxlen, cur)) { if ((rc = query_quadoption (OPT_MIMEFWDREST,_("Can't decode all tagged attachments. MIME-forward the others?"))) == -1) goto bail;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -