mutt stable branch with some hacks
at master 213 lines 5.1 kB view raw
1/* 2 * Copyright (C) 1996-2009,2012 Michael R. Elkins <me@mutt.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 */ 18 19#if HAVE_CONFIG_H 20# include "config.h" 21#endif 22 23#include "mutt.h" 24#include "mutt_crypt.h" 25#include "mutt_idna.h" 26 27#include <sys/stat.h> 28#include <string.h> 29#include <ctype.h> 30 31void mutt_edit_headers (const char *editor, 32 const char *body, 33 HEADER *msg, 34 char *fcc, 35 size_t fcclen) 36{ 37 char path[_POSIX_PATH_MAX]; /* tempfile used to edit headers + body */ 38 char buffer[LONG_STRING]; 39 const char *p; 40 FILE *ifp, *ofp; 41 int i, keep; 42 ENVELOPE *n; 43 time_t mtime; 44 struct stat st; 45 LIST *cur, **last = NULL, *tmp; 46 47 mutt_mktemp (path, sizeof (path)); 48 if ((ofp = safe_fopen (path, "w")) == NULL) 49 { 50 mutt_perror (path); 51 return; 52 } 53 54 mutt_env_to_local (msg->env); 55 mutt_write_rfc822_header (ofp, msg->env, NULL, 1, 0); 56 fputc ('\n', ofp); /* tie off the header. */ 57 58 /* now copy the body of the message. */ 59 if ((ifp = fopen (body, "r")) == NULL) 60 { 61 mutt_perror (body); 62 return; 63 } 64 65 mutt_copy_stream (ifp, ofp); 66 67 safe_fclose (&ifp); 68 safe_fclose (&ofp); 69 70 if (stat (path, &st) == -1) 71 { 72 mutt_perror (path); 73 return; 74 } 75 76 mtime = mutt_decrease_mtime (path, &st); 77 78 mutt_edit_file (editor, path); 79 stat (path, &st); 80 if (mtime == st.st_mtime) 81 { 82 dprint (1, (debugfile, "ci_edit_headers(): temp file was not modified.\n")); 83 /* the file has not changed! */ 84 mutt_unlink (path); 85 return; 86 } 87 88 mutt_unlink (body); 89 mutt_free_list (&msg->env->userhdrs); 90 91 /* Read the temp file back in */ 92 if ((ifp = fopen (path, "r")) == NULL) 93 { 94 mutt_perror (path); 95 return; 96 } 97 98 if ((ofp = safe_fopen (body, "w")) == NULL) 99 { 100 /* intentionally leak a possible temporary file here */ 101 safe_fclose (&ifp); 102 mutt_perror (body); 103 return; 104 } 105 106 n = mutt_read_rfc822_header (ifp, NULL, 1, 0); 107 while ((i = fread (buffer, 1, sizeof (buffer), ifp)) > 0) 108 fwrite (buffer, 1, i, ofp); 109 safe_fclose (&ofp); 110 safe_fclose (&ifp); 111 mutt_unlink (path); 112 113 /* in case the user modifies/removes the In-Reply-To header with 114 $edit_headers set, we remove References: as they're likely invalid; 115 we can simply compare strings as we don't generate References for 116 multiple Message-Ids in IRT anyways */ 117 if (msg->env->in_reply_to && 118 (!n->in_reply_to || mutt_strcmp (n->in_reply_to->data, 119 msg->env->in_reply_to->data) != 0)) 120 mutt_free_list (&msg->env->references); 121 122 /* restore old info. */ 123 mutt_free_list (&n->references); 124 n->references = msg->env->references; 125 msg->env->references = NULL; 126 127 mutt_free_envelope (&msg->env); 128 msg->env = n; n = NULL; 129 130 mutt_expand_aliases_env (msg->env); 131 132 /* search through the user defined headers added to see if 133 * fcc: or attach: or pgp: was specified 134 */ 135 136 cur = msg->env->userhdrs; 137 last = &msg->env->userhdrs; 138 while (cur) 139 { 140 keep = 1; 141 142 if (fcc && ascii_strncasecmp ("fcc:", cur->data, 4) == 0) 143 { 144 p = skip_email_wsp(cur->data + 4); 145 if (*p) 146 { 147 strfcpy (fcc, p, fcclen); 148 mutt_pretty_mailbox (fcc, fcclen); 149 } 150 keep = 0; 151 } 152 else if (ascii_strncasecmp ("attach:", cur->data, 7) == 0) 153 { 154 BODY *body; 155 BODY *parts; 156 size_t l = 0; 157 158 p = skip_email_wsp(cur->data + 7); 159 if (*p) 160 { 161 for ( ; *p && *p != ' ' && *p != '\t'; p++) 162 { 163 if (*p == '\\') 164 { 165 if (!*(p+1)) 166 break; 167 p++; 168 } 169 if (l < sizeof (path) - 1) 170 path[l++] = *p; 171 } 172 p = skip_email_wsp(p); 173 path[l] = 0; 174 175 mutt_expand_path (path, sizeof (path)); 176 if ((body = mutt_make_file_attach (path))) 177 { 178 body->description = safe_strdup (p); 179 for (parts = msg->content; parts->next; parts = parts->next) ; 180 parts->next = body; 181 } 182 else 183 { 184 mutt_pretty_mailbox (path, sizeof (path)); 185 mutt_error (_("%s: unable to attach file"), path); 186 } 187 } 188 keep = 0; 189 } 190 else if ((WithCrypto & APPLICATION_PGP) 191 && ascii_strncasecmp ("pgp:", cur->data, 4) == 0) 192 { 193 msg->security = mutt_parse_crypt_hdr (cur->data + 4, 0, APPLICATION_PGP); 194 if (msg->security) 195 msg->security |= APPLICATION_PGP; 196 keep = 0; 197 } 198 199 if (keep) 200 { 201 last = &cur->next; 202 cur = cur->next; 203 } 204 else 205 { 206 tmp = cur; 207 *last = cur->next; 208 cur = cur->next; 209 tmp->next = NULL; 210 mutt_free_list (&tmp); 211 } 212 } 213}