NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
mailbox.c
Go to the documentation of this file.
1 
31 #include "config.h"
32 #include <assert.h>
33 #include <sys/stat.h>
34 #include "config/lib.h"
35 #include "email/lib.h"
36 #include "mailbox.h"
37 #include "neomutt.h"
38 
40 static const struct Mapping MailboxTypes[] = {
41  // clang-format off
42  { "compressed", MUTT_COMPRESSED },
43  { "imap", MUTT_IMAP },
44  { "maildir", MUTT_MAILDIR },
45  { "mbox", MUTT_MBOX },
46  { "mh", MUTT_MH },
47  { "mmdf", MUTT_MMDF },
48  { "nntp", MUTT_NNTP },
49  { "notmuch", MUTT_NOTMUCH },
50  { "pop", MUTT_POP },
51  // clang-format off
52  { NULL, 0 },
53 };
54 
58 int mailbox_gen(void)
59 {
60  static int gen = 0;
61  return gen++;
62 }
63 
68 struct Mailbox *mailbox_new(void)
69 {
70  struct Mailbox *m = mutt_mem_calloc(1, sizeof(struct Mailbox));
71 
73  m->notify = notify_new();
74 
75  m->email_max = 25;
76  m->emails = mutt_mem_calloc(m->email_max, sizeof(struct Email *));
77  m->v2r = mutt_mem_calloc(m->email_max, sizeof(int));
78  m->gen = mailbox_gen();
79 
80  return m;
81 }
82 
87 void mailbox_free(struct Mailbox **ptr)
88 {
89  if (!ptr || !*ptr)
90  return;
91 
92  struct Mailbox *m = *ptr;
93 
94  mutt_debug(LL_NOTIFY, "NT_MAILBOX_DELETE: %s %p\n", mailbox_get_type_name(m->type), m);
95  struct EventMailbox ev_m = { m };
97 
98  mutt_debug(LL_NOTIFY, "NT_EMAIL_DELETE_ALL\n");
99  struct EventEmail ev_e = { 0, NULL };
101 
102  for (size_t i = 0; i < m->email_max; i++)
103  email_free(&m->emails[i]);
104 
105  if (m->mdata_free && m->mdata)
106  m->mdata_free(&m->mdata);
107 
109  cs_subset_free(&m->sub);
110  FREE(&m->name);
111  FREE(&m->realpath);
112  FREE(&m->emails);
113  FREE(&m->v2r);
114  notify_free(&m->notify);
115  mailbox_gc_run();
116 
117  FREE(ptr);
118 }
119 
125 struct Mailbox *mailbox_find(const char *path)
126 {
127  if (!path)
128  return NULL;
129 
130  struct stat sb;
131  struct stat tmp_sb;
132 
133  if (stat(path, &sb) != 0)
134  return NULL;
135 
136  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
138  struct MailboxNode *np = NULL;
139  struct Mailbox *m = NULL;
140  STAILQ_FOREACH(np, &ml, entries)
141  {
142  if ((stat(mailbox_path(np->mailbox), &tmp_sb) == 0) &&
143  (sb.st_dev == tmp_sb.st_dev) && (sb.st_ino == tmp_sb.st_ino))
144  {
145  m = np->mailbox;
146  break;
147  }
148  }
150 
151  return m;
152 }
153 
162 struct Mailbox *mailbox_find_name(const char *name)
163 {
164  if (!name)
165  return NULL;
166 
167  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
169  struct MailboxNode *np = NULL;
170  struct Mailbox *m = NULL;
171  STAILQ_FOREACH(np, &ml, entries)
172  {
173  if (mutt_str_equal(np->mailbox->name, name))
174  {
175  m = np->mailbox;
176  break;
177  }
178  }
180 
181  return m;
182 }
183 
190 void mailbox_update(struct Mailbox *m)
191 {
192  struct stat sb;
193 
194  if (!m)
195  return;
196 
197  if (stat(mailbox_path(m), &sb) == 0)
198  m->size = (off_t) sb.st_size;
199  else
200  m->size = 0;
201 }
202 
208 void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
209 {
210  if (!m)
211  return;
212 
213  mutt_debug(LL_NOTIFY, "NT_MAILBOX_CHANGE: %s %p\n", mailbox_get_type_name(m->type), m);
214  struct EventMailbox ev_m = { m };
215  notify_send(m->notify, NT_MAILBOX, action, &ev_m);
216 }
217 
223 void mailbox_size_add(struct Mailbox *m, const struct Email *e)
224 {
225  m->size += email_size(e);
226 }
227 
233 void mailbox_size_sub(struct Mailbox *m, const struct Email *e)
234 {
235  m->size -= email_size(e);
236 }
237 
244 bool mailbox_set_subset(struct Mailbox *m, struct ConfigSubset *sub)
245 {
246  if (!m || m->sub || !sub)
247  return false;
248 
249  m->sub = cs_subset_new(m->name, sub, m->notify);
251  return true;
252 }
253 
254 static struct
255 {
256  struct Email *arr[10];
257  size_t idx;
258 } gc = { 0 };
259 
265 void mailbox_gc_add(struct Email *e)
266 {
267  assert(e);
268  if (gc.idx == mutt_array_size(gc.arr))
269  {
270  mailbox_gc_run();
271  }
272  gc.arr[gc.idx++] = e;
273 }
274 
278 void mailbox_gc_run(void)
279 {
280  for (size_t i = 0; i < gc.idx; i++)
281  {
282  email_free(&gc.arr[i]);
283  }
284  gc.idx = 0;
285 }
286 
292 const char *mailbox_get_type_name(enum MailboxType type)
293 {
294  const char *name = mutt_map_get_name(type, MailboxTypes);
295  if (name)
296  return name;
297  return "UNKNOWN";
298 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
Mailbox is about to be deleted.
Definition: mailbox.h:174
An Event that happened to an Email.
Definition: email.h:155
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
off_t size
Size of the Mailbox.
Definition: mailbox.h:87
NotifyMailbox
Types of Mailbox Event.
Definition: mailbox.h:171
The envelope/body of an email.
Definition: email.h:37
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:44
Log of notifications.
Definition: logging.h:45
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
void mailbox_size_add(struct Mailbox *m, const struct Email *e)
Add an email&#39;s size to the total size of a Mailbox.
Definition: mailbox.c:223
Structs that make up an email.
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:141
void notify_free(struct Notify **ptr)
Free a notification handler.
Definition: notify.c:73
size_t idx
Definition: mailbox.c:257
struct Mailbox * mailbox_find(const char *path)
Find the mailbox with a given path.
Definition: mailbox.c:125
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
Match any Mailbox type.
Definition: mailbox.h:45
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:164
struct Email * arr[10]
Definition: mailbox.c:256
size_t email_size(const struct Email *e)
compute the size of an email
Definition: email.c:125
const char * mailbox_get_type_name(enum MailboxType type)
Get the type of a Mailbox.
Definition: mailbox.c:292
void cs_subset_free(struct ConfigSubset **ptr)
Free a Config Subset.
Definition: subset.c:104
An Event that happened to a Mailbox.
Definition: mailbox.h:190
int mailbox_gen(void)
Get the next generation number.
Definition: mailbox.c:58
Container for Accounts, Notifications.
Definition: neomutt.h:36
Convenience wrapper for the config headers.
void(* mdata_free)(void **ptr)
Free the private data attached to the Mailbox.
Definition: mailbox.h:146
static struct @0 gc
#define mutt_array_size(x)
Definition: memory.h:33
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:87
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
void * mdata
Driver specific data.
Definition: mailbox.h:136
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
struct Notify * notify_new(void)
Create a new notifications handler.
Definition: notify.c:60
A set of inherited config items.
Definition: subset.h:46
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:55
int email_max
Number of pointers in emails.
Definition: mailbox.h:100
struct Mailbox * mailbox_find_name(const char *name)
Find the mailbox with a given name.
Definition: mailbox.c:162
A mailbox.
Definition: mailbox.h:81
struct ConfigSubset * sub
Inherited config items.
Definition: mailbox.h:86
Container for Accounts, Notifications.
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
Compressed file Mailbox type.
Definition: mailbox.h:56
&#39;MH&#39; Mailbox type
Definition: mailbox.h:50
void mailbox_update(struct Mailbox *m)
Get the mailbox&#39;s current size.
Definition: mailbox.c:190
enum ConfigScope scope
Scope of Subset, e.g. SET_SCOPE_ACCOUNT.
Definition: subset.h:49
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
struct ConfigSubset * cs_subset_new(const char *name, struct ConfigSubset *sub_parent, struct Notify *not_parent)
Create a new Config Subset.
Definition: subset.c:144
All the Emails are about to be deleted.
Definition: email.h:148
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:54
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
Email has changed, NotifyEmail, EventEmail.
Definition: notify_type.h:44
Representation of a mailbox.
int * v2r
Mapping from virtual to real msgno.
Definition: mailbox.h:101
struct Mailbox * mailbox_new(void)
Create a new Mailbox.
Definition: mailbox.c:68
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
void mailbox_gc_run(void)
Run the garbage-collection.
Definition: mailbox.c:278
bool mailbox_set_subset(struct Mailbox *m, struct ConfigSubset *sub)
Set a Mailbox&#39;s Config Subset.
Definition: mailbox.c:244
#define FREE(x)
Definition: memory.h:40
Mailbox has changed, NotifyMailbox, EventMailbox.
Definition: notify_type.h:48
Mapping between user-readable string and a constant.
Definition: mapping.h:31
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
This Config is Mailbox-specific.
Definition: subset.h:40
List of Mailboxes.
Definition: mailbox.h:156
struct Notify * notify
Notifications: NotifyMailbox, EventMailbox.
Definition: mailbox.h:148
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
void mailbox_size_sub(struct Mailbox *m, const struct Email *e)
Subtract an email&#39;s size from the total size of a Mailbox.
Definition: mailbox.c:233
struct Buffer pathbuf
Definition: mailbox.h:83
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:208
int gen
Generation number, for sorting.
Definition: mailbox.h:150
void mailbox_gc_add(struct Email *e)
Add an Email to the garbage-collection set.
Definition: mailbox.c:265
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:158
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:171