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(dirp)))
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)
486 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;
535 while (((de = readdir(dirp))) && !
SigInt)
537 if (*de->d_name ==
'.')
558 entry->
inode = de->d_ino;
587 const char *p = strrchr(fn,
':');
598 struct Progress *progress)
621 struct stat st_lastchanged = { 0 };
624 if (c_maildir_header_cache_verify)
626 rc = stat(fn, &st_lastchanged);
676 struct Progress *progress = NULL;
681 snprintf(msg,
sizeof(msg),
_(
"Scanning %s..."),
mailbox_path(m));
702 snprintf(msg,
sizeof(msg),
_(
"Reading %s..."),
mailbox_path(m));
730 char *t = strrchr(src,
'/');
735 char *u = strpbrk(dest->
data,
",:");
756 const char *subfolder,
char **newname)
762 struct dirent *de = NULL;
776 while ((de = readdir(dp)))
819 char *p = strrchr(
path,
':');
825 q =
edata->maildir_flags;
846 if (!e->
flagged || !c_flag_safe)
862 if (q ==
edata->maildir_flags)
882 const char *fname,
bool is_old,
struct Email *e)
929 bool is_old,
struct Email *e)
931 FILE *fp = fopen(fname,
"r");
955 if (e->
deleted && !c_maildir_trash)
962 const char *key = e->
path + 3;
979 const char *key = e->
path + 3;
997 static unsigned int new_hits = 0, cur_hits = 0;
1003 (new_hits > cur_hits) ?
"new" :
"cur", newname);
1004 if (fp || (errno != ENOENT))
1006 if ((new_hits < UINT_MAX) && (cur_hits < UINT_MAX))
1008 new_hits += ((new_hits > cur_hits) ? 1 : 0);
1009 cur_hits += ((new_hits > cur_hits) ? 0 : 1);
1015 (new_hits > cur_hits) ?
"cur" :
"new", newname);
1016 if (fp || (errno != ENOENT))
1018 if ((new_hits < UINT_MAX) && (cur_hits < UINT_MAX))
1020 new_hits += ((new_hits > cur_hits) ? 0 : 1);
1021 cur_hits += ((new_hits > cur_hits) ? 1 : 0);
1045 struct dirent *de = NULL;
1056 snprintf(realpath,
sizeof(realpath),
"%s/%s", path, (iter == 0) ?
"cur" :
"new");
1057 dp = opendir(realpath);
1060 while ((de = readdir(dp)))
1062 if (*de->d_name !=
'.')
1070 }
while (rc && iter < 2);
1124 if ((mkdir(tmp, S_IRWXU) != 0) && (errno != EEXIST))
1133 if ((mkdir(tmp, S_IRWXU) != 0) && (errno != EEXIST))
1144 if ((mkdir(tmp, S_IRWXU) != 0) && (errno != EEXIST))
1170 struct stat st_new = { 0 };
1171 struct stat st_cur = { 0 };
1173 bool occult =
false;
1175 bool flags_changed =
false;
1261 if (md && md->
email)
1275 flags_changed =
true;
1282 flags_changed =
true;
1348 bool check_new =
true;
1361 check_new = !m->
has_new && c_maildir_check_cur;
1362 if (check_new || check_stats)
1387 struct Progress *progress = NULL;
1391 snprintf(msg,
sizeof(msg),
_(
"Writing %s..."),
mailbox_path(m));
1421 for (
int i = 0, j = 0; i < m->
msg_count; i++)
1428 if (!e->
deleted || c_maildir_trash)
1465 msg->
fp = fopen(
path,
"r");
1466 if (!msg->
fp && (errno == ENOENT))
1491 char suffix[16] = { 0 };
1492 char subdir[16] = { 0 };
1496 struct Email tmp = *e;
1512 snprintf(
path,
sizeof(
path),
"%s/tmp/%s.%lld.R%" PRIu64
".%s%s",
1518 fd = open(
path, O_WRONLY | O_EXCL | O_CREAT, 0666);
1521 if (errno != EEXIST)
1537 msg->
fp = fdopen(fd,
"w");
1576 char *key = e->
path + 3;
1629 if (!st || !S_ISDIR(st->st_mode))
1633 snprintf(cur,
sizeof(cur),
"%s/cur", path);
1635 struct stat st_cur = { 0 };
1636 if ((stat(cur, &st_cur) == 0) && S_ISDIR(st_cur.st_mode))
1662 .msg_padding_size = NULL,
1665 .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_epoch(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.
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_STAT_CTIME
File/dir's ctime - creation time.
@ MUTT_STAT_MTIME
File/dir's mtime - last modified time.
#define mutt_debug(LEVEL,...)
bool maildir_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Implements MxOps::ac_add() -.
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() -.
enum MxStatus maildir_mbox_check(struct Mailbox *m)
Check for new mail - Implements MxOps::mbox_check() -.
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() -.
enum MxStatus maildir_mbox_sync(struct Mailbox *m)
Save changes to the Mailbox - Implements MxOps::mbox_sync() -.
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() -.
int maildir_path_canon(char *buf, size_t buflen)
Canonicalise a Mailbox path - Implements MxOps::path_canon() -.
int maildir_path_parent(char *buf, size_t buflen)
Find the parent of a Mailbox path - Implements MxOps::path_parent() -.
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.
size_t maildir_hcache_keylen(const char *fn)
Calculate the length of the Maildir path.
static int ch_compare(const void *a, const void *b)
qsort() callback to sort characters
int maildir_parse_dir(struct Mailbox *m, struct MdEmailArray *mda, const char *subdir, struct Progress *progress)
Read a Maildir mailbox.
void maildir_update_mtime(struct Mailbox *m)
Update our record of the Maildir modification time.
int maildir_sync_message(struct Mailbox *m, int msgno)
Sync an email to a Maildir folder.
int maildir_rewrite_message(struct Mailbox *m, int msgno)
Sync a message in an MH folder.
FILE * maildir_open_find_message(const char *folder, const char *msg, char **newname)
Find a new.
int maildir_commit_message(struct Mailbox *m, struct Message *msg, struct Email *e)
Commit a message to a maildir folder.
#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.
int maildir_read_dir(struct Mailbox *m, const char *subdir)
Read a Maildir style mailbox.
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.
#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.
#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.
struct Email * maildir_parse_stream(enum MailboxType type, FILE *fp, const char *fname, bool is_old, struct Email *e)
Parse a Maildir message.
void maildir_delayed_parsing(struct Mailbox *m, struct MdEmailArray *mda, struct Progress *progress)
This function does the second parsing pass.
void maildir_canon_filename(struct Buffer *dest, const char *src)
Generate the canonical filename for a Maildir folder.
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.
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.
Hundreds of global variables to back the user variables.
char * ShortHostname
Short version of the hostname.
SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
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.