Edit an email or view it in an external editor.
60{
61 char buf[256] = { 0 };
62 int rc;
63 FILE *fp = NULL;
64 struct stat st = { 0 };
65 bool old_append = m->
append;
66
69
70
73
76 {
77 mutt_error(
_(
"could not create temporary folder: %s"), strerror(errno));
80 return -1;
81 }
82
84
90 int oerrno = errno;
91
94
95 if (rc == -1)
96 {
97 mutt_error(
_(
"could not write temporary mail folder: %s"), strerror(oerrno));
98 goto bail;
99 }
100
102 if (rc == -1)
103 {
105 goto bail;
106 }
107
108
109
110
111
112
113 if ((st.st_size != 0) && (truncate(
buf_string(fname), st.st_size - 1) == -1))
114 {
115 rc = -1;
116 mutt_error(
_(
"could not truncate temporary mail folder: %s"), strerror(errno));
117 goto bail;
118 }
119
121 {
122
124 if (rc == -1)
125 {
128
129
130 }
131 }
132
133
135 if (rc == -1)
136 {
138 goto bail;
139 }
140
141
143 if (mtime == (time_t) -1)
144 {
145 rc = -1;
147 goto bail;
148 }
149
152
154 if (rc == -1)
155 {
157 goto bail;
158 }
159
160 if (st.st_size == 0)
161 {
163 rc = 1;
164 goto bail;
165 }
166
167 if ((action ==
EVM_EDIT) && (st.st_mtime == mtime))
168 {
170 rc = 1;
171 goto bail;
172 }
173
174 if ((action ==
EVM_VIEW) && (st.st_mtime != mtime))
175 {
176 mutt_message(
_(
"Message of read-only mailbox modified! Ignoring changes."));
177 rc = 1;
178 goto bail;
179 }
180
182 {
183
184 rc = 1;
185 goto bail;
186 }
187
189 if (!fp)
190 {
191 rc = -1;
192 mutt_error(
_(
"Can't open message file: %s"), strerror(errno));
193 goto bail;
194 }
195
197 {
198 rc = -1;
199
200 mutt_error(
_(
"Can't append to folder: %s"), strerror(errno));
201 goto bail;
202 }
205
206 if (fgets(buf,
sizeof(buf), fp) &&
is_from(buf, NULL, 0, NULL))
207 {
210 }
211 else
212 {
214 }
215
216
217
218
219 bool o_read = e->
read;
226
227 if (!msg)
228 {
229 rc = -1;
230 mutt_error(
_(
"Can't append to folder: %s"), strerror(errno));
232 goto bail;
233 }
234
236 if (rc == 0)
237 {
238 fputc(
'\n', msg->
fp);
240 }
241
244
247
248bail:
250
251 if (rc >= 0)
253
254 if (rc == 0)
255 {
259
261 if (c_delete_untag)
263 }
264 else if (rc == -1)
265 {
267 }
268
270
272 return rc;
273}
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
unsigned char cs_subset_enum(const struct ConfigSubset *sub, const char *name)
Get a enumeration config item by name.
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
int mutt_append_message(struct Mailbox *m_dst, struct Mailbox *m_src, struct Email *e, struct Message *msg, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
Append a message.
int mutt_copy_hdr(FILE *fp_in, FILE *fp_out, LOFF_T off_start, LOFF_T off_end, CopyHeaderFlags chflags, const char *prefix, int wraplen)
Copy header from one file to another.
#define CH_NOSTATUS
Suppress the status and x-status fields.
#define CH_FROM
Retain the "From " message separator?
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
#define CH_FORCE_FROM
Give CH_FROM precedence over CH_WEED?
#define MUTT_CM_NO_FLAGS
No flags are set.
#define CH_NO_FLAGS
No flags are set.
#define CH_NOLEN
Don't write Content-Length: and Lines:
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
@ MUTT_MMDF
'mmdf' Mailbox type
@ MUTT_MBOX
'mbox' Mailbox type
void mutt_edit_file(const char *editor, const char *file)
Let the user edit a file.
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
time_t mutt_file_decrease_mtime(const char *fp, struct stat *st)
Decrease a file's modification time by 1 second.
int mutt_file_chmod_rm_stat(const char *path, mode_t mode, struct stat *st)
Remove permissions from a file.
#define mutt_file_fclose(FP)
#define mutt_file_fopen(PATH, MODE)
void mutt_set_flag(struct Mailbox *m, struct Email *e, enum MessageType flag, bool bf, bool upd_mbox)
Set a flag on an email.
bool is_from(const char *s, char *path, size_t pathlen, time_t *tp)
Is a string a 'From' header line?
#define mutt_message(...)
#define mutt_debug(LEVEL,...)
@ LL_DEBUG1
Log at debug level 1.
@ MUTT_READ
Messages that have been read.
@ MUTT_PURGE
Messages to be purged (bypass trash)
@ MUTT_TAG
Tagged messages.
@ MUTT_DELETE
Messages to be deleted.
int mx_msg_close(struct Mailbox *m, struct Message **ptr)
Close a message.
bool mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
struct Message * mx_msg_open_new(struct Mailbox *m, const struct Email *e, MsgOpenFlags flags)
Open a new message.
int mx_msg_commit(struct Mailbox *m, struct Message *msg)
Commit a message to a folder - Wrapper for MxOps::msg_commit()
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
enum MxStatus mx_mbox_close(struct Mailbox *m)
Save changes and close mailbox.
uint8_t MsgOpenFlags
Flags for mx_msg_open_new(), e.g. MUTT_ADD_FROM.
#define MUTT_ADD_FROM
add a From_ line
#define MUTT_MSG_NO_FLAGS
No flags are set.
#define MUTT_NEWFOLDER
Create a new folder - same as MUTT_APPEND, but uses mutt_file_fopen() with mode "w" for mbox-style fo...
#define MUTT_APPEND
Open mailbox for appending messages.
#define MUTT_QUIET
Do not print any messages.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
@ EVM_VIEW
View the message.
@ EVM_EDIT
Edit the message.
String manipulation buffer.
bool old
Email is seen, but unread.
bool append
Mailbox is opened in append mode.
time_t last_checked
Last time we checked this mailbox for new mail.
enum MailboxType type
Mailbox type.
A local copy of an email.
FILE * fp
pointer to the message data
Container for Accounts, Notifications.
struct ConfigSubset * sub
Inherited config items.
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.