mutt stable branch with some hacks
at master 235 lines 5.4 kB view raw
1/* 2 * Copyright (C) 1999-2002 Thomas Roessler <roessler@does-not-exist.org> 3 * 4 * This program is free software; you can redistribute it 5 * and/or modify it under the terms of the GNU General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later 8 * version. 9 * 10 * This program is distributed in the hope that it will be 11 * useful, but WITHOUT ANY WARRANTY; without even the implied 12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 13 * PURPOSE. See the GNU General Public License for more 14 * details. 15 * 16 * You should have received a copy of the GNU General Public 17 * License along with this program; if not, write to the Free 18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA. 20 */ 21 22/* simple, editor-based message editing */ 23 24#if HAVE_CONFIG_H 25# include "config.h" 26#endif 27 28#include "mutt.h" 29#include "copy.h" 30#include "mailbox.h" 31#include "mx.h" 32 33#include <sys/stat.h> 34#include <errno.h> 35 36#include <time.h> 37 38/* 39 * return value: 40 * 41 * 1 message not modified 42 * 0 message edited successfully 43 * -1 error 44 */ 45 46static int edit_one_message (CONTEXT *ctx, HEADER *cur) 47{ 48 char tmp[_POSIX_PATH_MAX]; 49 char buff[STRING]; 50 int omagic; 51 int oerrno; 52 int rc; 53 54 unsigned short o_read; 55 unsigned short o_old; 56 57 int of, cf; 58 59 CONTEXT tmpctx; 60 MESSAGE *msg; 61 62 FILE *fp = NULL; 63 64 struct stat sb; 65 time_t mtime = 0; 66 67 mutt_mktemp (tmp, sizeof (tmp)); 68 69 omagic = DefaultMagic; 70 DefaultMagic = MUTT_MBOX; 71 72 rc = (mx_open_mailbox (tmp, MUTT_NEWFOLDER, &tmpctx) == NULL) ? -1 : 0; 73 74 DefaultMagic = omagic; 75 76 if (rc == -1) 77 { 78 mutt_error (_("could not create temporary folder: %s"), strerror (errno)); 79 return -1; 80 } 81 82 rc = mutt_append_message (&tmpctx, ctx, cur, 0, CH_NOLEN | 83 ((ctx->magic == MUTT_MBOX || ctx->magic == MUTT_MMDF) ? 0 : CH_NOSTATUS)); 84 oerrno = errno; 85 86 mx_close_mailbox (&tmpctx, NULL); 87 88 if (rc == -1) 89 { 90 mutt_error (_("could not write temporary mail folder: %s"), strerror (oerrno)); 91 goto bail; 92 } 93 94 if ((rc = stat (tmp, &sb)) == -1) 95 { 96 mutt_error (_("Can't stat %s: %s"), tmp, strerror (errno)); 97 goto bail; 98 } 99 100 /* 101 * 2002-09-05 me@sigpipe.org 102 * The file the user is going to edit is not a real mbox, so we need to 103 * truncate the last newline in the temp file, which is logically part of 104 * the message separator, and not the body of the message. If we fail to 105 * remove it, the message will grow by one line each time the user edits 106 * the message. 107 */ 108 if (sb.st_size != 0 && truncate (tmp, sb.st_size - 1) == -1) 109 { 110 mutt_error (_("could not truncate temporary mail folder: %s"), 111 strerror (errno)); 112 goto bail; 113 } 114 115 mtime = mutt_decrease_mtime (tmp, &sb); 116 117 mutt_edit_file (NONULL(Editor), tmp); 118 119 if ((rc = stat (tmp, &sb)) == -1) 120 { 121 mutt_error (_("Can't stat %s: %s"), tmp, strerror (errno)); 122 goto bail; 123 } 124 125 if (sb.st_size == 0) 126 { 127 mutt_message (_("Message file is empty!")); 128 rc = 1; 129 goto bail; 130 } 131 132 if (sb.st_mtime == mtime) 133 { 134 mutt_message (_("Message not modified!")); 135 rc = 1; 136 goto bail; 137 } 138 139 if ((fp = fopen (tmp, "r")) == NULL) 140 { 141 rc = -1; 142 mutt_error (_("Can't open message file: %s"), strerror (errno)); 143 goto bail; 144 } 145 146 if (mx_open_mailbox (ctx->path, MUTT_APPEND, &tmpctx) == NULL) 147 { 148 rc = -1; 149 /* L10N: %s is from strerror(errno) */ 150 mutt_error (_("Can't append to folder: %s"), strerror (errno)); 151 goto bail; 152 } 153 154 of = 0; 155 cf = ((tmpctx.magic == MUTT_MBOX || tmpctx.magic == MUTT_MMDF) ? 0 : CH_NOSTATUS); 156 157 if (fgets (buff, sizeof (buff), fp) && is_from (buff, NULL, 0, NULL)) 158 { 159 if (tmpctx.magic == MUTT_MBOX || tmpctx.magic == MUTT_MMDF) 160 cf = CH_FROM | CH_FORCE_FROM; 161 } 162 else 163 of = MUTT_ADD_FROM; 164 165 /* 166 * XXX - we have to play games with the message flags to avoid 167 * problematic behavior with maildir folders. 168 * 169 */ 170 171 o_read = cur->read; o_old = cur->old; 172 cur->read = cur->old = 0; 173 msg = mx_open_new_message (&tmpctx, cur, of); 174 cur->read = o_read; cur->old = o_old; 175 176 if (msg == NULL) 177 { 178 mutt_error (_("Can't append to folder: %s"), strerror (errno)); 179 mx_close_mailbox (&tmpctx, NULL); 180 goto bail; 181 } 182 183 if ((rc = mutt_copy_hdr (fp, msg->fp, 0, sb.st_size, CH_NOLEN | cf, NULL)) == 0) 184 { 185 fputc ('\n', msg->fp); 186 rc = mutt_copy_stream (fp, msg->fp); 187 } 188 189 rc = mx_commit_message (msg, &tmpctx); 190 mx_close_message (&tmpctx, &msg); 191 192 mx_close_mailbox (&tmpctx, NULL); 193 194 bail: 195 if (fp) safe_fclose (&fp); 196 197 if (rc >= 0) 198 unlink (tmp); 199 200 if (rc == 0) 201 { 202 mutt_set_flag (Context, cur, MUTT_DELETE, 1); 203 mutt_set_flag (Context, cur, MUTT_PURGE, 1); 204 mutt_set_flag (Context, cur, MUTT_READ, 1); 205 206 if (option (OPTDELETEUNTAG)) 207 mutt_set_flag (Context, cur, MUTT_TAG, 0); 208 } 209 else if (rc == -1) 210 mutt_message (_("Error. Preserving temporary file: %s"), tmp); 211 212 213 return rc; 214} 215 216int mutt_edit_message (CONTEXT *ctx, HEADER *hdr) 217{ 218 int i, j; 219 220 if (hdr) 221 return edit_one_message (ctx, hdr); 222 223 224 for (i = 0; i < ctx->vcount; i++) 225 { 226 j = ctx->v2r[i]; 227 if (ctx->hdrs[j]->tagged) 228 { 229 if (edit_one_message (ctx, ctx->hdrs[j]) == -1) 230 return -1; 231 } 232 } 233 234 return 0; 235}