74#define MMC_NEW_DIR (1 << 0)
75#define MMC_CUR_DIR (1 << 1)
87 bool check_new,
bool check_stats)
90 struct dirent *de = NULL;
92 struct stat st = { 0 };
101 if (check_new && c_mail_check_recent)
110 if (!(check_new || check_stats))
120 while ((de = readdir(dir)))
122 if (*de->d_name ==
'.')
125 p = strstr(de->d_name,
":2,");
126 if (p && strchr(p + 3,
'T'))
132 if (p && strchr(p + 3,
'F'))
135 if (!p || !strchr(p + 3,
'S'))
141 if (c_mail_check_recent)
177 return (
int) (*((
const char *) a) - *((
const char *) b));
190 const char *flags = NULL;
194 flags =
edata->maildir_flags;
204 char tmp[1024] = { 0 };
205 snprintf(tmp,
sizeof(tmp),
"%s%s%s%s%s", e->
flagged ?
"F" :
"", e->
replied ?
"R" :
"",
209 snprintf(dest, destlen,
":2,%s", tmp);
239 char subdir[4] = { 0 };
240 char suffix[16] = { 0 };
250 char *s = strrchr(msg->
path,
'/') + 1;
288 }
while ((rc_utime == -1) && (errno == EINTR));
291 mutt_perror(
_(
"maildir_commit_message(): unable to set time on file"));
308 else if (errno != EEXIST)
343 long old_hdr_lines = e->
lines;
373 e->
lines = old_hdr_lines;
396 struct Buffer *newpath = NULL;
397 struct Buffer *partpath = NULL;
398 struct Buffer *fullpath = NULL;
399 struct Buffer *oldpath = NULL;
400 char suffix[16] = { 0 };
417 char *p = strrchr(e->
path,
'/');
432 p = strchr(newpath->
data,
':');
480 struct stat st = { 0 };
483 snprintf(buf,
sizeof(buf),
"%s/%s",
mailbox_path(m),
"cur");
484 if (stat(buf, &st) == 0)
487 snprintf(buf,
sizeof(buf),
"%s/%s",
mailbox_path(m),
"new");
488 if (stat(buf, &st) == 0)
514 const char *subdir,
struct Progress *progress)
516 struct dirent *de = NULL;
520 struct Email *e = NULL;
534 while (((de = readdir(dir))) && !
SigInt)
536 if (*de->d_name ==
'.')
557 entry->
inode = de->d_ino;
587 const char *p = strrchr(fn,
':');
599 struct Progress *progress)
622 struct stat st_lastchanged = { 0 };
625 if (c_maildir_header_cache_verify)
627 rc = stat(fn, &st_lastchanged);
679 struct Progress *progress = NULL;
684 snprintf(msg,
sizeof(msg),
_(
"Scanning %s..."),
mailbox_path(m));
705 snprintf(msg,
sizeof(msg),
_(
"Reading %s..."),
mailbox_path(m));
733 char *t = strrchr(src,
'/');
738 char *u = strpbrk(dest->
data,
",:");
759 const char *subfolder,
char **newname)
765 struct dirent *de = NULL;
779 while ((de = readdir(dir)))
822 char *p = strrchr(
path,
':');
828 q =
edata->maildir_flags;
849 if (!e->
flagged || !c_flag_safe)
865 if (q ==
edata->maildir_flags)
885 const char *fname,
bool is_old,
struct Email *e)
932 bool is_old,
struct Email *e)
934 FILE *fp = fopen(fname,
"r");
958 if (e->
deleted && !c_maildir_trash)
965 const char *key = e->
path + 3;
982 const char *key = e->
path + 3;
1000 static unsigned int new_hits = 0, cur_hits = 0;
1006 (new_hits > cur_hits) ?
"new" :
"cur", newname);
1007 if (fp || (errno != ENOENT))
1009 if ((new_hits < UINT_MAX) && (cur_hits < UINT_MAX))
1011 new_hits += ((new_hits > cur_hits) ? 1 : 0);
1012 cur_hits += ((new_hits > cur_hits) ? 0 : 1);
1018 (new_hits > cur_hits) ?
"cur" :
"new", newname);
1019 if (fp || (errno != ENOENT))
1021 if ((new_hits < UINT_MAX) && (cur_hits < UINT_MAX))
1023 new_hits += ((new_hits > cur_hits) ? 0 : 1);
1024 cur_hits += ((new_hits > cur_hits) ? 1 : 0);
1048 struct dirent *de = NULL;
1059 snprintf(realpath,
sizeof(realpath),
"%s/%s", path, (iter == 0) ?
"cur" :
"new");
1063 while ((de = readdir(dir)))
1065 if (*de->d_name !=
'.')
1073 }
while (rc && iter < 2);
1127 if ((mkdir(tmp, S_IRWXU) != 0) && (errno != EEXIST))
1136 if ((mkdir(tmp, S_IRWXU) != 0) && (errno != EEXIST))
1147 if ((mkdir(tmp, S_IRWXU) != 0) && (errno != EEXIST))
1173 struct stat st_new = { 0 };
1174 struct stat st_cur = { 0 };
1176 bool occult =
false;
1178 bool flags_changed =
false;
1264 if (md && md->
email)
1278 flags_changed =
true;
1285 flags_changed =
true;
1351 bool check_new =
true;
1364 check_new = !m->
has_new && c_maildir_check_cur;
1365 if (check_new || check_stats)
1390 struct Progress *progress = NULL;
1394 snprintf(msg,
sizeof(msg),
_(
"Writing %s..."),
mailbox_path(m));
1424 for (
int i = 0, j = 0; i < m->
msg_count; i++)
1431 if (!e->
deleted || c_maildir_trash)
1468 msg->
fp = fopen(
path,
"r");
1469 if (!msg->
fp && (errno == ENOENT))
1494 char suffix[16] = { 0 };
1495 char subdir[16] = { 0 };
1499 struct Email tmp = *e;
1515 snprintf(
path,
sizeof(
path),
"%s/tmp/%s.%lld.R%" PRIu64
".%s%s",
1521 fd = open(
path, O_WRONLY | O_EXCL | O_CREAT, 0666);
1524 if (errno != EEXIST)
1540 msg->
fp = fdopen(fd,
"w");
1579 char *key = e->
path + 3;
1632 if (!st || !S_ISDIR(st->st_mode))
1636 struct stat stsub = { 0 };
1637 char *subs[] = {
"cur",
"new" };
1640 snprintf(sub,
sizeof(sub),
"%s/%s", path, subs[i]);
1641 if ((stat(sub, &stsub) == 0) && S_ISDIR(stsub.st_mode))
1668 .msg_padding_size = NULL,
1671 .tags_commit = NULL,
#define ARRAY_SORT(head, fn)
Sort an array.
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
#define ARRAY_SIZE(head)
The number of elements stored.
#define ARRAY_FREE(head)
Release all memory.
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
char * mutt_buffer_strdup(const struct Buffer *buf)
Copy a Buffer's string.
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Convenience wrapper for the config headers.
char * HomeDir
User's home directory.
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.
Duplicate the structure of an entire email.
#define MUTT_CM_UPDATE
Update structs on sync.
#define CH_UPDATE
Update the status and x-status fields?
#define CH_UPDATE_LEN
Update Lines: and Content-Length:
Convenience wrapper for the core headers.
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
void mutt_body_free(struct Body **ptr)
Free a Body.
struct Email * email_new(void)
Create a new Email.
void email_free(struct Email **ptr)
Free an Email.
Structs that make up an email.
void mutt_file_get_stat_timespec(struct timespec *dest, struct stat *st, enum MuttStatType type)
Read the stat() time into a time value.
int mutt_file_safe_rename(const char *src, const char *target)
NFS-safe renaming of files.
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
long mutt_file_get_size_fp(FILE *fp)
Get the size of a file.
DIR * mutt_file_opendir(const char *path, enum MuttOpenDirMode mode)
Open a directory.
int mutt_file_stat_timespec_compare(struct stat *st, enum MuttStatType type, struct timespec *b)
Compare stat info with a time value.
int mutt_file_fsync_close(FILE **fp)
Flush the data, before closing a file (and NULL the pointer)
@ MUTT_OPENDIR_CREATE
Create the directory if it doesn't exist.
@ MUTT_STAT_CTIME
File/dir's ctime - creation time.
@ MUTT_STAT_MTIME
File/dir's mtime - last modified time.
char * ShortHostname
Short version of the hostname.
SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
#define mutt_debug(LEVEL,...)
static bool maildir_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Implements MxOps::ac_add() -.
static bool maildir_ac_owns_path(struct Account *a, const char *path)
Check whether an Account own a Mailbox path - Implements MxOps::ac_owns_path() -.
struct MxOps MxMaildirOps
Maildir Mailbox - Implements MxOps -.
static enum MxStatus maildir_mbox_check_stats(struct Mailbox *m, uint8_t flags)
Check the Mailbox statistics - Implements MxOps::mbox_check_stats() -.
static enum MxStatus maildir_mbox_check(struct Mailbox *m)
Check for new mail - Implements MxOps::mbox_check() -.
static enum MxStatus maildir_mbox_close(struct Mailbox *m)
Close a Mailbox - Implements MxOps::mbox_close() -.
static bool maildir_mbox_open_append(struct Mailbox *m, OpenMailboxFlags flags)
Open a Mailbox for appending - Implements MxOps::mbox_open_append() -.
static enum MxOpenReturns maildir_mbox_open(struct Mailbox *m)
Open a Mailbox - Implements MxOps::mbox_open() -.
static enum MxStatus maildir_mbox_sync(struct Mailbox *m)
Save changes to the Mailbox - Implements MxOps::mbox_sync() -.
static int maildir_msg_close(struct Mailbox *m, struct Message *msg)
Close an email - Implements MxOps::msg_close() -.
static int maildir_msg_commit(struct Mailbox *m, struct Message *msg)
Save changes to an email - Implements MxOps::msg_commit() -.
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() -.
static bool maildir_msg_open(struct Mailbox *m, struct Message *msg, int msgno)
Open an email message in a Mailbox - Implements MxOps::msg_open() -.
static int maildir_msg_save_hcache(struct Mailbox *m, struct Email *e)
Save message to the header cache - Implements MxOps::msg_save_hcache() -.
static int maildir_path_canon(char *buf, size_t buflen)
Canonicalise a Mailbox path - Implements MxOps::path_canon() -.
static int maildir_path_parent(char *buf, size_t buflen)
Find the parent of a Mailbox path - Implements MxOps::path_parent() -.
static int maildir_path_pretty(char *buf, size_t buflen, const char *folder)
Abbreviate a Mailbox path - Implements MxOps::path_pretty() -.
static enum MailboxType maildir_path_probe(const char *path, const struct stat *st)
Is this a Maildir Mailbox? - Implements MxOps::path_probe() -.
static int maildir_cmp_inode(const void *a, const void *b)
Compare two Maildirs by inode number - Implements sort_t -.
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
#define MUTT_HASH_NO_FLAGS
No flags are set.
Header cache multiplexor.
int mutt_hcache_store(struct HeaderCache *hc, const char *key, size_t keylen, struct Email *e, uint32_t uidvalidity)
Multiplexor for StoreOps::store.
void mutt_hcache_close(struct HeaderCache *hc)
Multiplexor for StoreOps::close.
struct HeaderCache * mutt_hcache_open(const char *path, const char *folder, hcache_namer_t namer)
Multiplexor for StoreOps::open.
int mutt_hcache_delete_record(struct HeaderCache *hc, const char *key, size_t keylen)
Multiplexor for StoreOps::delete_record.
static struct Email * restore(const unsigned char *d)
Restore an Email from data retrieved from the cache.
struct HCacheEntry mutt_hcache_fetch(struct HeaderCache *hc, const char *key, size_t keylen, uint32_t uidvalidity)
Multiplexor for StoreOps::fetch.
@ LL_DEBUG2
Log at debug level 2.
@ LL_DEBUG1
Log at debug level 1.
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
@ NT_MAILBOX_RESORT
Email list needs resorting.
@ NT_MAILBOX_INVALID
Email list was changed.
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
MailboxType
Supported mailbox formats.
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
@ MUTT_MAILDIR
'Maildir' Mailbox type
struct MaildirEmailData * maildir_edata_get(struct Email *e)
Get the private data for this Email.
void maildir_edata_free(void **ptr)
Free the private Email data - Implements Email::edata_free()
struct MaildirEmailData * maildir_edata_new(void)
Create a new MaildirEmailData object.
bool maildir_update_flags(struct Mailbox *m, struct Email *e_old, struct Email *e_new)
Update the mailbox flags.
void maildir_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
struct MaildirMboxData * maildir_mdata_get(struct Mailbox *m)
Get the private data for this Mailbox.
struct MaildirMboxData * maildir_mdata_new(void)
Create a new MaildirMboxData object.
mode_t mh_umask(struct Mailbox *m)
Create a umask from the mailbox directory.
int maildir_move_to_mailbox(struct Mailbox *m, struct MdEmailArray *mda)
Copy the Maildir list to the Mailbox.
static size_t maildir_hcache_keylen(const char *fn)
Calculate the length of the Maildir path.
static void maildir_delayed_parsing(struct Mailbox *m, struct MdEmailArray *mda, struct Progress *progress)
This function does the second parsing pass.
static int ch_compare(const void *a, const void *b)
qsort() callback to sort characters
static int maildir_rewrite_message(struct Mailbox *m, int msgno)
Sync a message in an MH folder.
static int maildir_read_dir(struct Mailbox *m, const char *subdir)
Read a Maildir style mailbox.
static int maildir_sync_message(struct Mailbox *m, int msgno)
Sync an email to a Maildir folder.
FILE * maildir_open_find_message(const char *folder, const char *msg, char **newname)
Find a message by name.
#define MMC_CUR_DIR
'cur' directory changed
struct Email * maildir_parse_message(enum MailboxType type, const char *fname, bool is_old, struct Email *e)
Actually parse a maildir message.
static void maildir_canon_filename(struct Buffer *dest, const char *src)
Generate the canonical filename for a Maildir folder.
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.
static void maildir_update_mtime(struct Mailbox *m)
Update our record of the Maildir modification time.
#define MMC_NO_DIRS
No directories changed.
static void maildir_check_dir(struct Mailbox *m, const char *dir_name, bool check_new, bool check_stats)
Check for new mail / mail counts.
static int maildir_parse_dir(struct Mailbox *m, struct MdEmailArray *mda, const char *subdir, struct Progress *progress)
Read a Maildir mailbox.
#define MMC_NEW_DIR
'new' directory changed
int maildir_check_empty(const char *path)
Is the mailbox empty.
void maildir_gen_flags(char *dest, size_t destlen, struct Email *e)
Generate the Maildir flags for an email.
static int maildir_commit_message(struct Mailbox *m, struct Message *msg, struct Email *e)
Commit a message to a maildir folder.
struct Email * maildir_parse_stream(enum MailboxType type, FILE *fp, const char *fname, bool is_old, struct Email *e)
Parse a Maildir message.
bool maildir_sync_mailbox_message(struct Mailbox *m, int msgno, struct HeaderCache *hc)
Save changes to the mailbox.
void maildir_parse_flags(struct Email *e, const char *path)
Parse Maildir file flags.
struct MdEmail * maildir_entry_new(void)
Create a new Maildir entry.
#define mutt_array_size(x)
bool MonitorContextChanged
true after the current mailbox has changed
Monitor files for changes.
Convenience wrapper for the library headers.
bool mutt_path_abbr_folder(char *buf, const char *folder)
Create a folder abbreviation.
bool mutt_path_pretty(char *buf, size_t buflen, const char *homedir, bool is_dir)
Tidy a filesystem path.
bool mutt_path_canon(char *buf, size_t buflen, const char *homedir, bool is_dir)
Create the canonical version of a path.
bool mutt_path_parent(char *buf)
Find the parent of a path.
char * mutt_str_dup(const char *str)
Copy a string, safely.
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
Return a stream pointer for a message.
struct Message * mx_msg_open_new(struct Mailbox *m, const struct Email *e, MsgOpenFlags flags)
Open a new message.
#define MUTT_MSG_NO_FLAGS
No flags are set.
uint8_t OpenMailboxFlags
Flags for mutt_open_mailbox(), e.g. MUTT_NOSORT.
#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.
MxOpenReturns
Return values for mbox_open()
@ MX_OPEN_ERROR
Open failed with an error.
@ MX_OPEN_OK
Open succeeded.
#define MUTT_MAILBOX_CHECK_FORCE_STATS
Ignore MailboxType and calculate statistics.
#define MUTT_APPENDNEW
Set in mx_open_mailbox_append if the mailbox doesn't exist.
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close()
@ MX_STATUS_ERROR
An error occurred.
@ MX_STATUS_OK
No changes.
@ MX_STATUS_FLAGS
Nondestructive flags change (IMAP)
@ MX_STATUS_REOPENED
Mailbox was reopened.
@ MX_STATUS_NEW_MAIL
New mail received in Mailbox.
Notmuch virtual mailbox type.
int nm_update_filename(struct Mailbox *m, const char *old_file, const char *new_file, struct Email *e)
Change the filename.
Notmuch-specific Mailbox data.
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
Parses an RFC822 header.
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
@ MUTT_PROGRESS_READ
Progress tracks elements, according to $read_inc
@ MUTT_PROGRESS_WRITE
Progress tracks elements, according to $write_inc
void progress_free(struct Progress **ptr)
Free a Progress Bar.
bool progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
struct Progress * progress_new(const char *msg, enum ProgressType type, size_t size)
Create a new Progress Bar.
uint64_t mutt_rand64(void)
Create a 64-bit random number.
A group of associated Mailboxes.
struct Body * parts
parts of a multipart or message/rfc822
LOFF_T offset
offset where the actual data begins
LOFF_T length
length (in bytes) of attachment
String manipulation buffer.
char * dptr
Current read/write position.
char * data
Pointer to data.
The envelope/body of an email.
bool purge
Skip trash folder when deleting.
struct Envelope * env
Envelope information.
void * edata
Driver-specific data.
int lines
How many lines in the body of this message?
struct Body * body
List of MIME parts.
bool active
Message is not to be removed.
bool old
Email is seen, but unread.
void(* edata_free)(void **ptr)
Free the private data attached to the Email.
bool changed
Email has been edited.
bool attach_del
Has an attachment marked for deletion.
bool flagged
Marked important?
time_t date_sent
Time when the message was sent (UTC)
bool replied
Email has been replied to.
int msgno
Number displayed to the user.
char * path
Path of Email (for local Mailboxes)
bool deleted
Email is deleted.
int index
The absolute (unsorted) message number.
bool trash
Message is marked as trashed on disk (used by the maildir_trash option)
time_t received
Time when the message was placed in the mailbox.
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Wrapper for Email retrieved from the header cache.
uint32_t uidvalidity
IMAP-specific UIDVALIDITY.
struct Email * email
Retrieved email.
void(* mdata_free)(void **ptr)
Free the private data attached to the Mailbox.
bool changed
Mailbox has been modified.
bool has_new
Mailbox has new mail.
struct timespec mtime
Time Mailbox was last changed.
int msg_new
Number of new messages.
int msg_count
Total number of messages.
enum MailboxType type
Mailbox type.
void * mdata
Driver specific data.
struct Email ** emails
Array of Emails.
int msg_deleted
Number of deleted messages.
int msg_flagged
Number of flagged messages.
struct timespec last_visited
Time of last exit from this mailbox.
bool verbose
Display status messages?
int msg_unread
Number of unread messages.
Maildir-specific Email data -.
Maildir-specific Mailbox data -.
mode_t mh_umask
umask to use when creating files
struct timespec mtime_cur
Timestamp of the 'cur' dir.
A local copy of an email.
FILE * fp
pointer to the message data
char * path
path to temp file
char * committed_path
the final path generated by mx_msg_commit()
time_t received
Time at which this message was received.
enum MailboxType type
Mailbox type, e.g. MUTT_IMAP.
Container for Accounts, Notifications.
struct ConfigSubset * sub
Inherited config items.