📄 send.c
字号:
env->cc = NULL; }}void mutt_make_forward_subject (ENVELOPE *env, CONTEXT *ctx, HEADER *cur){ char buffer[STRING]; /* set the default subject for the message. */ mutt_make_string (buffer, sizeof (buffer), NONULL(ForwFmt), ctx, cur); mutt_str_replace (&env->subject, buffer);}void mutt_make_misc_reply_headers (ENVELOPE *env, CONTEXT *ctx, HEADER *cur, ENVELOPE *curenv){ /* This takes precedence over a subject that might have * been taken from a List-Post header. Is that correct? */ if (curenv->real_subj) { FREE (&env->subject); env->subject = safe_malloc (mutt_strlen (curenv->real_subj) + 5); sprintf (env->subject, "Re: %s", curenv->real_subj); /* __SPRINTF_CHECKED__ */ } else if (!env->subject) env->subject = safe_strdup ("Re: your mail");}void mutt_add_to_reference_headers (ENVELOPE *env, ENVELOPE *curenv, LIST ***pp, LIST ***qq){ LIST **p = NULL, **q = NULL; if (pp) p = *pp; if (qq) q = *qq; if (!p) p = &env->references; if (!q) q = &env->in_reply_to; while (*p) p = &(*p)->next; while (*q) q = &(*q)->next; *p = mutt_make_references (curenv); if (curenv->message_id) { *q = mutt_new_list(); (*q)->data = safe_strdup (curenv->message_id); } if (pp) *pp = p; if (qq) *qq = q; }static void mutt_make_reference_headers (ENVELOPE *curenv, ENVELOPE *env, CONTEXT *ctx){ env->references = NULL; env->in_reply_to = NULL; if (!curenv) { HEADER *h; LIST **p = NULL, **q = NULL; int i; for(i = 0; i < ctx->vcount; i++) { h = ctx->hdrs[ctx->v2r[i]]; if (h->tagged) mutt_add_to_reference_headers (env, h->env, &p, &q); } } else mutt_add_to_reference_headers (env, curenv, NULL, NULL);}static intenvelope_defaults (ENVELOPE *env, CONTEXT *ctx, HEADER *cur, int flags){ ENVELOPE *curenv = NULL; int i = 0, tag = 0; if (!cur) { tag = 1; for (i = 0; i < ctx->vcount; i++) if (ctx->hdrs[ctx->v2r[i]]->tagged) { cur = ctx->hdrs[ctx->v2r[i]]; curenv = cur->env; break; } if (!cur) { /* This could happen if the user tagged some messages and then did * a limit such that none of the tagged message are visible. */ mutt_error _("No tagged messages are visible!"); return (-1); } } else curenv = cur->env; if (flags & SENDREPLY) { if (tag) { HEADER *h; for (i = 0; i < ctx->vcount; i++) { h = ctx->hdrs[ctx->v2r[i]]; if (h->tagged && mutt_fetch_recips (env, h->env, flags) == -1) return -1; } } else if (mutt_fetch_recips (env, curenv, flags) == -1) return -1; if ((flags & SENDLISTREPLY) && !env->to) { mutt_error _("No mailing lists found!"); return (-1); } mutt_make_misc_reply_headers (env, ctx, cur, curenv); mutt_make_reference_headers (tag ? NULL : curenv, env, ctx); } else if (flags & SENDFORWARD) mutt_make_forward_subject (env, ctx, cur); return (0);}static intgenerate_body (FILE *tempfp, /* stream for outgoing message */ HEADER *msg, /* header for outgoing message */ int flags, /* compose mode */ CONTEXT *ctx, /* current mailbox */ HEADER *cur) /* current message */{ int i; HEADER *h; BODY *tmp; if (flags & SENDREPLY) { if ((i = query_quadoption (OPT_INCLUDE, _("Include message in reply?"))) == -1) return (-1); if (i == M_YES) { mutt_message _("Including quoted message..."); if (!cur) { for (i = 0; i < ctx->vcount; i++) { h = ctx->hdrs[ctx->v2r[i]]; if (h->tagged) { if (include_reply (ctx, h, tempfp) == -1) { mutt_error _("Could not include all requested messages!"); return (-1); } fputc ('\n', tempfp); } } } else include_reply (ctx, cur, tempfp); } } else if (flags & SENDFORWARD) { if ((i = query_quadoption (OPT_MIMEFWD, _("Forward as attachment?"))) == M_YES) { BODY *last = msg->content; mutt_message _("Preparing forwarded message..."); while (last && last->next) last = last->next; if (cur) { tmp = mutt_make_message_attach (ctx, cur, 0); if (last) last->next = tmp; else msg->content = tmp; } else { for (i = 0; i < ctx->vcount; i++) { if (ctx->hdrs[ctx->v2r[i]]->tagged) { tmp = mutt_make_message_attach (ctx, ctx->hdrs[ctx->v2r[i]], 0); if (last) { last->next = tmp; last = tmp; } else last = msg->content = tmp; } } } } else if (i != -1) { if (cur) include_forward (ctx, cur, tempfp); else for (i=0; i < ctx->vcount; i++) if (ctx->hdrs[ctx->v2r[i]]->tagged) include_forward (ctx, ctx->hdrs[ctx->v2r[i]], tempfp); } else if (i == -1) return -1; } /* if (WithCrypto && (flags & SENDKEY)) */ else if ((WithCrypto & APPLICATION_PGP) && (flags & SENDKEY)) { BODY *tmp; if ((WithCrypto & APPLICATION_PGP) && (tmp = crypt_pgp_make_key_attachment (NULL)) == NULL) return -1; tmp->next = msg->content; msg->content = tmp; } mutt_clear_error (); return (0);}void mutt_set_followup_to (ENVELOPE *e){ ADDRESS *t = NULL; ADDRESS *from; /* * Only generate the Mail-Followup-To if the user has requested it, and * it hasn't already been set */ if (option (OPTFOLLOWUPTO) && !e->mail_followup_to) { if (mutt_is_list_cc (0, e->to, e->cc)) { /* * this message goes to known mailing lists, so create a proper * mail-followup-to header */ t = rfc822_append (&e->mail_followup_to, e->to); rfc822_append (&t, e->cc); } /* remove ourselves from the mail-followup-to header */ e->mail_followup_to = remove_user (e->mail_followup_to, 0); /* * If we are not subscribed to any of the lists in question, * re-add ourselves to the mail-followup-to header. The * mail-followup-to header generated is a no-op with group-reply, * but makes sure list-reply has the desired effect. */ if (e->mail_followup_to && !mutt_is_list_recipient (0, e->to, e->cc)) { if (e->reply_to) from = rfc822_cpy_adr (e->reply_to); else if (e->from) from = rfc822_cpy_adr (e->from); else from = mutt_default_from (); if (from) { /* Normally, this loop will not even be entered. */ for (t = from; t && t->next; t = t->next) ; t->next = e->mail_followup_to; /* t cannot be NULL at this point. */ e->mail_followup_to = from; } } e->mail_followup_to = mutt_remove_duplicates (e->mail_followup_to); }}/* look through the recipients of the message we are replying to, and if we find an address that matches $alternates, we use that as the default from field */static ADDRESS *set_reverse_name (ENVELOPE *env){ ADDRESS *tmp; for (tmp = env->to; tmp; tmp = tmp->next) { if (mutt_addr_is_user (tmp)) break; } if (!tmp) { for (tmp = env->cc; tmp; tmp = tmp->next) { if (mutt_addr_is_user (tmp)) break; } } if (!tmp && mutt_addr_is_user (env->from)) tmp = env->from; if (tmp) { tmp = rfc822_cpy_adr_real (tmp); if (!option (OPTREVREAL)) FREE (&tmp->personal); if (!tmp->personal) tmp->personal = safe_strdup (Realname); } return (tmp);}ADDRESS *mutt_default_from (void){ ADDRESS *adr; const char *fqdn = mutt_fqdn(1); /* * Note: We let $from override $realname here. Is this the right * thing to do? */ if (From) adr = rfc822_cpy_adr_real (From); else if (option (OPTUSEDOMAIN)) { adr = rfc822_new_address (); adr->mailbox = safe_malloc (mutt_strlen (Username) + mutt_strlen (fqdn) + 2); sprintf (adr->mailbox, "%s@%s", NONULL(Username), NONULL(fqdn)); /* __SPRINTF_CHECKED__ */ } else { adr = rfc822_new_address (); adr->mailbox = safe_strdup (NONULL(Username)); } return (adr);}static int send_message (HEADER *msg){ char tempfile[_POSIX_PATH_MAX]; FILE *tempfp; int i; /* Write out the message in MIME form. */ mutt_mktemp (tempfile); if ((tempfp = safe_fopen (tempfile, "w")) == NULL) return (-1);#ifdef MIXMASTER mutt_write_rfc822_header (tempfp, msg->env, msg->content, 0, msg->chain ? 1 : 0);#endif#ifndef MIXMASTER mutt_write_rfc822_header (tempfp, msg->env, msg->content, 0, 0);#endif fputc ('\n', tempfp); /* tie off the header. */ if ((mutt_write_mime_body (msg->content, tempfp) == -1)) { fclose(tempfp); unlink (tempfile); return (-1); } if (fclose (tempfp) != 0) { mutt_perror (tempfile); unlink (tempfile); return (-1); }#ifdef MIXMASTER if (msg->chain) return mix_send_message (msg->chain, tempfile);#endif i = mutt_invoke_sendmail (msg->env->from, msg->env->to, msg->env->cc, msg->env->bcc, tempfile, (msg->content->encoding == ENC8BIT)); return (i);}/* rfc2047 encode the content-descriptions */static void encode_descriptions (BODY *b, short recurse){ BODY *t; for (t = b; t; t = t->next) { if (t->description) { rfc2047_encode_string (&t->description); } if (recurse && t->parts) encode_descriptions (t->parts, recurse); }}/* rfc2047 decode them in case of an error */static void decode_descriptions (BODY *b){ BODY *t; for (t = b; t; t = t->next) { if (t->description) { rfc2047_decode (&t->description); } if (t->parts) decode_descriptions (t->parts); }}static void fix_end_of_file (const char *data){ FILE *fp; int c; if ((fp = safe_fopen (data, "a+")) == NULL) return; fseek (fp,-1,SEEK_END); if ((c = fgetc(fp)) != '\n') fputc ('\n', fp); safe_fclose (&fp);}int mutt_resend_message (FILE *fp, CONTEXT *ctx, HEADER *cur){ HEADER *msg = mutt_new_header (); if (mutt_prepare_template (fp, ctx, msg, cur, 1) < 0) return -1; return ci_send_message (SENDRESEND, msg, NULL, ctx, cur);}intci_send_message (int flags, /* send mode */ HEADER *msg, /* template to use for new message */ char *tempfile, /* file specified by -i or -H */ CONTEXT *ctx, /* current mailbox */ HEADER *cur) /* current message */{ char buffer[LONG_STRING]; char fcc[_POSIX_PATH_MAX] = ""; /* where to copy this message */ FILE *tempfp = NULL; BODY *pbody; int i, killfrom = 0; int fcc_error = 0; int free_clear_content = 0; BODY *save_content = NULL; BODY *clear_content = NULL; char *pgpkeylist = NULL; /* save current value of "pgp_sign_as" */ char *signas = NULL; char *tag = NULL, *err = NULL; char *ctype; int rv = -1; if (!flags && !msg && quadoption (OPT_RECALL) != M_NO && mutt_num_postponed (1)) { /* If the user is composing a new message, check to see if there * are any postponed messages first. */ if ((i = query_quadoption (OPT_RECALL, _("Recall postponed message?"))) == -1) return rv; if(i == M_YES) flags |= SENDPOSTPONED; } if ((WithCrypto & APPLICATION_PGP) && (flags & SENDPOSTPONED)) signas = safe_strdup(PgpSignAs); /* Delay expansion of aliases until absolutely necessary--shouldn't * be necessary unless we are prompting the user or about to execute a * send-hook. */ if (!msg) { msg = mutt_new_header (); if (flags == SENDPOSTPONED) { if ((flags = mutt_get_postponed (ctx, msg, &cur, fcc, sizeof (fcc))) < 0) goto cleanup; } if (flags & (SENDPOSTPONED|SENDRESEND)) { if ((tempfp = safe_fopen (msg->content->filename, "a+")) == NULL) { mutt_perror (msg->content->filename); goto cleanup; } } if (!msg->env) msg->env = mutt_new_envelope (); } /* Parse and use an eventual list-post header */ if ((flags & SENDLISTREPLY) && cur && cur->env && cur->env->list_post) { /* Use any list-post header as a template */ url_parse_mailto (msg->env, NULL, cur->env->list_post); /* We don't let them set the sender's address. */ rfc822_free_address (&msg->env->from); } if (! (flags & (SENDKEY | SENDPOSTPONED | SENDRESEND))) { pbody = mutt_new_body (); pbody->next = msg->content; /* don't kill command-line attachments */ msg->content = pbody; if (!(ctype = safe_strdup (ContentType))) ctype = safe_strdup ("text/plain"); mutt_parse_content_type (ctype, msg->content); FREE (&ctype); msg->content->unlink = 1; msg->content->use_disp = 0; msg->content->disposition = DISPINLINE; if (option (OPTTEXTFLOWED) && msg->content->type == TYPETEXT && !ascii_strcasecmp (msg->content->subtype, "plain")) mutt_set_parameter ("format", "flowed", &msg->content->parameter); if (!tempfile) { mutt_mktemp (buffer); tempfp = safe_fopen (buffer, "w+"); msg->content->filename = safe_strdup (buffer); } else { tempfp = safe_fopen (tempfile, "a+"); msg->content->filename = safe_strdup (tempfile); } if (!tempfp) { dprint(1,(debugfile, "newsend_message: can't create tempfile %s (errno=%d)\n", msg->content->filename, errno)); mutt_perror (msg->content->filename); goto cleanup; } } /* this is handled here so that the user can match ~f in send-hook */ if (cur && option (OPTREVNAME) && !(flags & (SENDPOSTPONED|SENDRESEND))) { /* we shouldn't have to worry about freeing `msg->env->from' before * setting it here since this code will only execute when doing some * sort of reply. the pointer will only be set when using the -H command * line option. * * We shouldn't have to worry about alias expansion here since we are * either replying to a real or postponed message, therefore no aliases * should exist since the user has not had the opportunity to add * addresses to the list. We just have to ensure the postponed messages * have their aliases expanded. */ msg->env->from = set_reverse_name (cur->env);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -