NeoMutt  2025-12-11-435-g4ac674
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
message.c File Reference

Maildir Message. More...

#include "config.h"
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <utime.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "message.h"
#include "edata.h"
#include "globals.h"
#include "hcache.h"
#include "mx.h"
#include "shared.h"
+ Include dependency graph for message.c:

Go to the source code of this file.

Functions

int nm_update_filename (struct Mailbox *m, const char *old_file, const char *new_file, struct Email *e)
 Change the filename.
 
static int maildir_sort_flags (const void *a, const void *b, void *sdata)
 Compare two flag characters - Implements sort_t -.
 
void maildir_gen_flags (char *dest, size_t destlen, struct Email *e)
 Generate the Maildir flags for an email.
 
static FILE * maildir_open_find_message_dir (const char *folder, const char *unique, const char *subfolder, char **newname)
 Find a message in a maildir folder.
 
FILE * maildir_open_find_message (const char *folder, const char *msg, char **newname)
 Find a message by name.
 
static int maildir_sync_message (struct Mailbox *m, struct Email *e)
 Sync an email to a Maildir folder.
 
bool maildir_sync_mailbox_message (struct Mailbox *m, struct Email *e, struct HeaderCache *hc)
 Save changes to the mailbox.
 
static int maildir_commit_message (struct Mailbox *m, struct Message *msg, struct Email *e)
 Commit a message to a maildir folder.
 
int maildir_rewrite_message (struct Mailbox *m, struct Email *e)
 Sync a message in an Maildir folder.
 
bool maildir_msg_open (struct Mailbox *m, struct Message *msg, struct Email *e)
 Open an email message in a Mailbox - Implements MxOps::msg_open() -.
 
bool maildir_msg_open_new (struct Mailbox *m, struct Message *msg, const struct Email *e)
 Open a new message in a Mailbox - Implements MxOps::msg_open_new() -.
 
int maildir_msg_commit (struct Mailbox *m, struct Message *msg)
 Save changes to an email - Implements MxOps::msg_commit() -.
 
int maildir_msg_close (struct Mailbox *m, struct Message *msg)
 Close an email - Implements MxOps::msg_close() -.
 
int maildir_msg_save_hcache (struct Mailbox *m, struct Email *e)
 Save message to the header cache - Implements MxOps::msg_save_hcache() -.
 

Detailed Description

Maildir Message.

Authors
  • Richard Russon

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, see http://www.gnu.org/licenses/.

Definition in file message.c.

Function Documentation

◆ nm_update_filename()

int nm_update_filename ( struct Mailbox * m,
const char * old_file,
const char * new_file,
struct Email * e )

Change the filename.

Parameters
mMailbox
old_fileOld filename
new_fileNew filename
eEmail
Return values
0Success
-1Failure

Definition at line 1808 of file notmuch.c.

1810{
1811 char buf[PATH_MAX] = { 0 };
1812 struct NmMboxData *mdata = nm_mdata_get(m);
1813 if (!mdata || !new_file)
1814 return -1;
1815
1816 if (!old_file && nm_edata_get(e))
1817 {
1818 email_get_fullpath(e, buf, sizeof(buf));
1819 old_file = buf;
1820 }
1821
1822 int rc = rename_filename(m, old_file, new_file, e);
1823
1824 nm_db_release(m);
1825 mdata->mtime.tv_sec = mutt_date_now();
1826 mdata->mtime.tv_nsec = 0;
1827 return rc;
1828}
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
Definition date.c:457
#define PATH_MAX
Definition mutt.h:49
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition db.c:233
struct NmEmailData * nm_edata_get(struct Email *e)
Get the Notmuch Email data.
Definition edata.c:72
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition mdata.c:96
static char * email_get_fullpath(struct Email *e, char *buf, size_t buflen)
Get the full path of an email.
Definition notmuch.c:230
static int rename_filename(struct Mailbox *m, const char *old_file, const char *new_file, struct Email *e)
Rename the file.
Definition notmuch.c:1367
void * mdata
Driver specific data.
Definition mailbox.h:131
Notmuch-specific Mailbox data -.
Definition mdata.h:35
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ maildir_gen_flags()

void maildir_gen_flags ( char * dest,
size_t destlen,
struct Email * e )

Generate the Maildir flags for an email.

Parameters
destBuffer for the result
destlenLength of buffer
eEmail

Definition at line 71 of file message.c.

72{
73 *dest = '\0';
74
75 const char *flags = NULL;
76
78 if (edata)
79 flags = edata->custom_flags;
80
81 /* The maildir specification requires that all files in the cur
82 * subdirectory have the :unique string appended, regardless of whether
83 * or not there are any flags. If .old is set, we know that this message
84 * will end up in the cur directory, so we include it in the following
85 * test even though there is no associated flag. */
86
87 if (e->flagged || e->replied || e->read || e->deleted || e->old || flags)
88 {
89 char tmp[1024] = { 0 };
90 snprintf(tmp, sizeof(tmp), "%s%s%s%s%s", e->flagged ? "F" : "", e->replied ? "R" : "",
91 e->read ? "S" : "", e->deleted ? "T" : "", NONULL(flags));
92 if (flags)
93 mutt_qsort_r(tmp, strlen(tmp), 1, maildir_sort_flags, NULL);
94
95 const char c_maildir_field_delimiter = *cc_maildir_field_delimiter();
96 snprintf(dest, destlen, "%c2,%s", c_maildir_field_delimiter, tmp);
97 }
98}
const char * cc_maildir_field_delimiter(void)
Get the cached value of $maildir_field_delimiter.
static int maildir_sort_flags(const void *a, const void *b, void *sdata)
Compare two flag characters - Implements sort_t -.
Definition message.c:60
struct MaildirEmailData * maildir_edata_get(struct Email *e)
Get the private data for this Email.
Definition edata.c:63
void mutt_qsort_r(void *base, size_t nmemb, size_t size, sort_t compar, void *sdata)
Sort an array, where the comparator has access to opaque data rather than requiring global variables.
Definition qsort_r.c:67
#define NONULL(x)
Definition string2.h:44
bool read
Email is read.
Definition email.h:50
void * edata
Driver-specific data.
Definition email.h:74
bool old
Email is seen, but unread.
Definition email.h:49
bool flagged
Marked important?
Definition email.h:47
bool replied
Email has been replied to.
Definition email.h:51
bool deleted
Email is deleted.
Definition email.h:78
Maildir-specific Email data -.
Definition edata.h:32
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ maildir_open_find_message_dir()

static FILE * maildir_open_find_message_dir ( const char * folder,
const char * unique,
const char * subfolder,
char ** newname )
static

Find a message in a maildir folder.

Parameters
[in]folderBase folder
[in]uniqueUnique part of filename
[in]subfolderSubfolder to search, e.g. 'cur'
[out]newnameFile's new name
Return values
ptrFile handle

These functions try to find a message in a maildir folder when it has moved under our feet. Note that this code is rather expensive, but then again, it's called rarely.

Definition at line 112 of file message.c.

114{
115 struct Buffer *dirname = buf_pool_get();
116 struct Buffer *tunique = buf_pool_get();
117 struct Buffer *fname = buf_pool_get();
118
119 struct dirent *de = NULL;
120
121 FILE *fp = NULL;
122 int oe = ENOENT;
123
124 buf_printf(dirname, "%s/%s", folder, subfolder);
125
127 if (!dir)
128 {
129 errno = ENOENT;
130 goto cleanup;
131 }
132
133 while ((de = readdir(dir)))
134 {
135 maildir_canon_filename(tunique, de->d_name);
136
137 if (mutt_str_equal(buf_string(tunique), unique))
138 {
139 buf_printf(fname, "%s/%s/%s", folder, subfolder, de->d_name);
140 fp = mutt_file_fopen(buf_string(fname), "r");
141 oe = errno;
142 break;
143 }
144 }
145
146 closedir(dir);
147
148 if (newname && fp)
149 *newname = buf_strdup(fname);
150
151 errno = oe;
152
153cleanup:
154 buf_pool_release(&dirname);
155 buf_pool_release(&tunique);
156 buf_pool_release(&fname);
157
158 return fp;
159}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:571
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
DIR * mutt_file_opendir(const char *path, enum MuttOpenDirMode mode)
Open a directory.
Definition file.c:539
@ MUTT_OPENDIR_CREATE
Create the directory if it doesn't exist.
Definition file.h:64
#define mutt_file_fopen(PATH, MODE)
Definition file.h:138
void maildir_canon_filename(struct Buffer *dest, const char *src)
Generate the canonical filename for a Maildir folder.
Definition shared.c:72
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:662
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
String manipulation buffer.
Definition buffer.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ maildir_open_find_message()

FILE * maildir_open_find_message ( const char * folder,
const char * msg,
char ** newname )

Find a message by name.

Parameters
[in]folderMaildir path
[in]msgEmail path
[out]newnameNew name, if it has moved
Return values
ptrFile handle

Definition at line 168 of file message.c.

169{
170 static unsigned int new_hits = 0, cur_hits = 0; /* simple dynamic optimization */
171
172 struct Buffer *unique = buf_pool_get();
173 maildir_canon_filename(unique, msg);
174
175 /* Prevent counter saturation by halving both when either gets large */
176 if ((new_hits > (UINT_MAX / 2)) || (cur_hits > (UINT_MAX / 2)))
177 {
178 new_hits /= 2;
179 cur_hits /= 2;
180 }
181
182 FILE *fp = maildir_open_find_message_dir(folder, buf_string(unique),
183 (new_hits > cur_hits) ? "new" : "cur", newname);
184 if (fp || (errno != ENOENT))
185 {
186 if (new_hits > cur_hits)
187 new_hits++;
188 else
189 cur_hits++;
190
191 goto cleanup;
192 }
193 fp = maildir_open_find_message_dir(folder, buf_string(unique),
194 (new_hits > cur_hits) ? "cur" : "new", newname);
195 if (fp || (errno != ENOENT))
196 {
197 if (new_hits > cur_hits)
198 cur_hits++;
199 else
200 new_hits++;
201
202 goto cleanup;
203 }
204
205 fp = NULL;
206
207cleanup:
208 buf_pool_release(&unique);
209
210 return fp;
211}
static FILE * maildir_open_find_message_dir(const char *folder, const char *unique, const char *subfolder, char **newname)
Find a message in a maildir folder.
Definition message.c:112
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ maildir_sync_message()

static int maildir_sync_message ( struct Mailbox * m,
struct Email * e )
static

Sync an email to a Maildir folder.

Parameters
mMailbox
eEmail
Return values
0Success
-1Error

Definition at line 220 of file message.c.

221{
222 if (!m || !e)
223 return -1;
224
225 struct Buffer *newpath = NULL;
226 struct Buffer *partpath = NULL;
227 struct Buffer *fullpath = NULL;
228 struct Buffer *oldpath = NULL;
229 char suffix[PATH_MAX] = { 0 };
230 int rc = 0;
231
232 if (e->attach_del || e->env->changed)
233 {
234 /* when doing attachment deletion/rethreading, fall back to the maildir case. */
235 if (maildir_rewrite_message(m, e) != 0)
236 return -1;
237 e->env->changed = false;
238 }
239 else
240 {
241 /* we just have to rename the file. */
242
243 char *p = strrchr(e->path, '/');
244 if (!p)
245 {
246 mutt_debug(LL_DEBUG1, "%s: unable to find subdir!\n", e->path);
247 return -1;
248 }
249 p++;
250 newpath = buf_pool_get();
251 partpath = buf_pool_get();
252 fullpath = buf_pool_get();
253 oldpath = buf_pool_get();
254
255 buf_strcpy(newpath, p);
256
257 /* kill the previous flags */
258 const char c_maildir_field_delimiter = *cc_maildir_field_delimiter();
259 p = strchr(newpath->data, c_maildir_field_delimiter);
260 if (p)
261 {
262 *p = '\0';
263 newpath->dptr = p; /* fix buffer up, just to be safe */
264 }
265
266 maildir_gen_flags(suffix, sizeof(suffix), e);
267
268 buf_printf(partpath, "%s/%s%s", (e->read || e->old) ? "cur" : "new",
269 buf_string(newpath), suffix);
270 buf_printf(fullpath, "%s/%s", mailbox_path(m), buf_string(partpath));
271 buf_printf(oldpath, "%s/%s", mailbox_path(m), e->path);
272
273 if (mutt_str_equal(buf_string(fullpath), buf_string(oldpath)))
274 {
275 /* message hasn't really changed */
276 goto cleanup;
277 }
278
279 /* record that the message is possibly marked as trashed on disk */
280 e->trash = e->deleted;
281
282 struct stat st = { 0 };
283 if (stat(buf_string(oldpath), &st) == -1)
284 {
285 mutt_debug(LL_DEBUG1, "File already removed (just continuing)\n");
286 goto cleanup;
287 }
288
289 if (rename(buf_string(oldpath), buf_string(fullpath)) != 0)
290 {
291 mutt_perror("rename");
292 rc = -1;
293 goto cleanup;
294 }
295 mutt_str_replace(&e->path, buf_string(partpath));
296 }
297
298cleanup:
299 buf_pool_release(&newpath);
300 buf_pool_release(&partpath);
301 buf_pool_release(&fullpath);
302 buf_pool_release(&oldpath);
303
304 return rc;
305}
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition mailbox.h:213
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
#define mutt_perror(...)
Definition logging2.h:95
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
int maildir_rewrite_message(struct Mailbox *m, struct Email *e)
Sync a message in an Maildir folder.
Definition message.c:467
void maildir_gen_flags(char *dest, size_t destlen, struct Email *e)
Generate the Maildir flags for an email.
Definition message.c:71
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition string.c:284
char * dptr
Current read/write position.
Definition buffer.h:38
char * data
Pointer to data.
Definition buffer.h:37
struct Envelope * env
Envelope information.
Definition email.h:68
bool attach_del
Has an attachment marked for deletion.
Definition email.h:99
char * path
Path of Email (for local Mailboxes)
Definition email.h:70
bool trash
Message is marked as trashed on disk (used by the maildir_trash option)
Definition email.h:53
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Definition envelope.h:90
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ maildir_sync_mailbox_message()

bool maildir_sync_mailbox_message ( struct Mailbox * m,
struct Email * e,
struct HeaderCache * hc )

Save changes to the mailbox.

Parameters
mMailbox
eEmail
hcHeader cache handle
Return values
trueSuccess
falseError

Definition at line 315 of file message.c.

316{
317 if (!e)
318 return false;
319
320 const bool c_maildir_trash = cs_subset_bool(NeoMutt->sub, "maildir_trash");
321 if (e->deleted && !c_maildir_trash)
322 {
323 char path[PATH_MAX] = { 0 };
324 snprintf(path, sizeof(path), "%s/%s", mailbox_path(m), e->path);
326 unlink(path);
327 }
328 else if (e->changed || e->attach_del ||
329 ((c_maildir_trash || e->trash) && (e->deleted != e->trash)))
330 {
331 if (maildir_sync_message(m, e) == -1)
332 return false;
333 }
334
335 if (e->changed)
337
338 return true;
339}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
int maildir_hcache_store(struct HeaderCache *hc, struct Email *e)
Save an Email to the Header Cache.
Definition hcache.c:163
int maildir_hcache_delete(struct HeaderCache *hc, struct Email *e)
Delete an Email from the Header Cache.
Definition hcache.c:89
static int maildir_sync_message(struct Mailbox *m, struct Email *e)
Sync an email to a Maildir folder.
Definition message.c:220
bool changed
Email has been edited.
Definition email.h:77
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ maildir_commit_message()

static int maildir_commit_message ( struct Mailbox * m,
struct Message * msg,
struct Email * e )
static

Commit a message to a maildir folder.

Parameters
mMailbox
msgMessage to commit
eEmail
Return values
0Success
-1Failure

msg->path contains the file name of a file in tmp/. We take the flags from this file's name.

m is the mail folder we commit to.

e is a header structure to which we write the message's new file name. This is used in the maildir folder sync routines. When this routine is invoked from mx_msg_commit(), e is NULL.

msg->path looks like this:

tmp/{cur,new}.neomutt-HOSTNAME-PID-COUNTER:flags

See also maildir_msg_open_new().

Definition at line 364 of file message.c.

365{
366 char subdir[4] = { 0 };
367 char suffix[PATH_MAX] = { 0 };
368 int rc = 0;
369
370 if (mutt_file_fsync_close(&msg->fp))
371 {
372 mutt_perror(_("Could not flush message to disk"));
373 return -1;
374 }
375
376 /* extract the subdir */
377 char *s = strrchr(msg->path, '/');
378 if (!s)
379 {
380 mutt_debug(LL_DEBUG1, "path '%s' lacks expected '/'\n", msg->path);
381 return -1;
382 }
383 s++;
384 mutt_str_copy(subdir, s, 4);
385
386 /* extract the flags */
387 const char c_maildir_field_delimiter = *cc_maildir_field_delimiter();
388 s = strchr(s, c_maildir_field_delimiter);
389 if (s)
390 mutt_str_copy(suffix, s, sizeof(suffix));
391 else
392 suffix[0] = '\0';
393
394 /* construct a new file name. */
395 struct Buffer *path = buf_pool_get();
396 struct Buffer *full = buf_pool_get();
397 for (int retries = 0; retries < 16; retries++)
398 {
399 buf_printf(path, "%s/%lld.R%" PRIu64 ".%s%s", subdir, (long long) mutt_date_now(),
400 mutt_rand64(), NONULL(ShortHostname), suffix);
401 buf_printf(full, "%s/%s", mailbox_path(m), buf_string(path));
402
403 mutt_debug(LL_DEBUG2, "renaming %s to %s\n", msg->path, buf_string(full));
404
405 if (mutt_file_safe_rename(msg->path, buf_string(full)) == 0)
406 {
407 /* Adjust the mtime on the file to match the time at which this
408 * message was received. Currently this is only set when copying
409 * messages between mailboxes, so we test to ensure that it is
410 * actually set. */
411 if (msg->received != 0)
412 {
413 struct utimbuf ut = { 0 };
414 int rc_utime;
415
416 ut.actime = msg->received;
417 ut.modtime = msg->received;
418 do
419 {
420 rc_utime = utime(buf_string(full), &ut);
421 } while ((rc_utime == -1) && (errno == EINTR));
422 if (rc_utime == -1)
423 {
424 mutt_perror(_("maildir_commit_message(): unable to set time on file"));
425 rc = -1;
426 goto cleanup;
427 }
428 }
429
430#ifdef USE_NOTMUCH
431 if (m->type == MUTT_NOTMUCH)
432 nm_update_filename(m, e->path, buf_string(full), e);
433#endif
434 if (e)
435 mutt_str_replace(&e->path, buf_string(path));
437 FREE(&msg->path);
438
439 goto cleanup;
440 }
441 else if (errno != EEXIST)
442 {
443 mutt_perror("%s", mailbox_path(m));
444 rc = -1;
445 goto cleanup;
446 }
447 }
448
449 /* All retries exhausted */
450 mutt_debug(LL_DEBUG1, "failed after 16 retries\n");
451 rc = -1;
452
453cleanup:
454 buf_pool_release(&path);
455 buf_pool_release(&full);
456
457 return rc;
458}
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition mailbox.h:50
int mutt_file_safe_rename(const char *src, const char *target)
NFS-safe renaming of files.
Definition file.c:306
int mutt_file_fsync_close(FILE **fp)
Flush the data, before closing a file (and NULL the pointer)
Definition file.c:128
char * ShortHostname
Short version of the hostname.
Definition globals.c:36
@ LL_DEBUG2
Log at debug level 2.
Definition logging2.h:46
int nm_update_filename(struct Mailbox *m, const char *old_file, const char *new_file, struct Email *e)
Change the filename.
Definition notmuch.c:1808
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define _(a)
Definition message.h:28
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition string.c:583
uint64_t mutt_rand64(void)
Create a 64-bit random number.
Definition random.c:123
enum MailboxType type
Mailbox type.
Definition mailbox.h:101
FILE * fp
pointer to the message data
Definition message.h:35
char * path
path to temp file
Definition message.h:36
char * committed_path
the final path generated by mx_msg_commit()
Definition message.h:37
time_t received
Time at which this message was received.
Definition message.h:46
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ maildir_rewrite_message()

int maildir_rewrite_message ( struct Mailbox * m,
struct Email * e )

Sync a message in an Maildir folder.

Parameters
mMailbox
eEmail
Return values
0Success
-1Error

Definition at line 467 of file message.c.

468{
469 if (!m || !e)
470 return -1;
471
472 bool restore = true;
473
474 long old_body_offset = e->body->offset;
475 long old_body_length = e->body->length;
476 long old_hdr_lines = e->lines;
477
478 struct Message *src = mx_msg_open(m, e);
479 struct Message *dest = mx_msg_open_new(m, e, MUTT_MSG_NO_FLAGS);
480 if (!src || !dest)
481 {
482 mx_msg_close(m, &src);
483 mx_msg_close(m, &dest);
484 return -1;
485 }
486
487 int rc = mutt_copy_message(dest->fp, e, src, MUTT_CM_UPDATE, CH_UPDATE | CH_UPDATE_LEN, 0);
488 if (rc == 0)
489 {
490 char oldpath[PATH_MAX] = { 0 };
491 char partpath[PATH_MAX] = { 0 };
492 snprintf(oldpath, sizeof(oldpath), "%s/%s", mailbox_path(m), e->path);
493 mutt_str_copy(partpath, e->path, sizeof(partpath));
494
495 rc = maildir_commit_message(m, dest, e);
496
497 if (rc == 0)
498 {
499 unlink(oldpath);
500 restore = false;
501 }
502 }
503 mx_msg_close(m, &src);
504 mx_msg_close(m, &dest);
505
506 if ((rc == -1) && restore)
507 {
508 e->body->offset = old_body_offset;
509 e->body->length = old_body_length;
510 e->lines = old_hdr_lines;
511 }
512
514 return rc;
515}
int mutt_copy_message(FILE *fp_out, struct Email *e, struct Message *msg, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
Copy a message from a Mailbox.
Definition copy_email.c:917
#define MUTT_CM_UPDATE
Update structs on sync.
Definition copy_email.h:42
#define CH_UPDATE
Update the status and x-status fields?
Definition copy_email.h:56
#define CH_UPDATE_LEN
Update Lines: and Content-Length:
Definition copy_email.h:66
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition body.c:58
static int maildir_commit_message(struct Mailbox *m, struct Message *msg, struct Email *e)
Commit a message to a maildir folder.
Definition message.c:364
int mx_msg_close(struct Mailbox *m, struct Message **ptr)
Close a message.
Definition mx.c:1182
struct Message * mx_msg_open(struct Mailbox *m, struct Email *e)
Return a stream pointer for a message.
Definition mx.c:1136
struct Message * mx_msg_open_new(struct Mailbox *m, const struct Email *e, MsgOpenFlags flags)
Open a new message.
Definition mx.c:1041
#define MUTT_MSG_NO_FLAGS
No flags are set.
Definition mx.h:38
struct Body * parts
parts of a multipart or message/rfc822
Definition body.h:73
LOFF_T offset
offset where the actual data begins
Definition body.h:52
LOFF_T length
length (in bytes) of attachment
Definition body.h:53
int lines
How many lines in the body of this message?
Definition email.h:62
struct Body * body
List of MIME parts.
Definition email.h:69
A local copy of an email.
Definition message.h:34
+ Here is the call graph for this function:
+ Here is the caller graph for this function: