NeoMutt  2018-07-16 +2225-8687db
Teaching an old dog new tricks
DOXYGEN
context.c File Reference

The "currently-open" mailbox. More...

#include "config.h"
#include <string.h>
#include "mutt/mutt.h"
#include "email/lib.h"
#include "context.h"
#include "globals.h"
#include "mutt_header.h"
#include "mutt_thread.h"
#include "mx.h"
#include "ncrypt/ncrypt.h"
#include "pattern.h"
#include "score.h"
#include "sort.h"

Go to the source code of this file.

Functions

void ctx_free (struct Context **ptr)
 Free a Context. More...
 
void ctx_cleanup (struct Context *ctx)
 Release memory and initialize a Context object. More...
 
void ctx_update (struct Context *ctx)
 Update the Context's message counts. More...
 
void ctx_update_tables (struct Context *ctx, bool committing)
 Update a Context structure's internal tables. More...
 
int ctx_mailbox_observer (struct NotifyCallback *nc)
 Watch for changes affecting the Context - Implements observer_t. More...
 
bool message_is_visible (struct Context *ctx, int index)
 Is a message in the index within limit. More...
 
bool message_is_tagged (struct Context *ctx, int index)
 Is a message in the index tagged (and within limit) More...
 
int el_add_tagged (struct EmailList *el, struct Context *ctx, struct Email *e, bool use_tagged)
 Get a list of the tagged Emails. More...
 
int el_add_email (struct EmailList *el, struct Email *e)
 Get a list of the selected Emails. More...
 

Detailed Description

The "currently-open" mailbox.

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 context.c.

Function Documentation

void ctx_free ( struct Context **  ptr)

Free a Context.

Parameters
[out]ptrContext to free

Definition at line 47 of file context.c.

48 {
49  if (!ptr || !*ptr)
50  return;
51 
52  struct Context *ctx = *ptr;
53  if (ctx->mailbox)
55 
56  FREE(ptr);
57 }
The "current" mailbox.
Definition: context.h:39
int ctx_mailbox_observer(struct NotifyCallback *nc)
Watch for changes affecting the Context - Implements observer_t.
Definition: context.c:261
struct Mailbox * mailbox
Definition: context.h:53
bool notify_observer_remove(struct Notify *notify, observer_t callback)
Remove an observer from an object.
Definition: notify.c:193
#define FREE(x)
Definition: memory.h:40
struct Notify * notify
Notifications handler.
Definition: mailbox.h:151
void ctx_cleanup ( struct Context ctx)

Release memory and initialize a Context object.

Parameters
ctxContext to cleanup

Definition at line 63 of file context.c.

64 {
65  FREE(&ctx->pattern);
67  if (ctx->mailbox)
69  memset(ctx, 0, sizeof(struct Context));
70 }
The "current" mailbox.
Definition: context.h:39
int ctx_mailbox_observer(struct NotifyCallback *nc)
Watch for changes affecting the Context - Implements observer_t.
Definition: context.c:261
struct PatternHead * limit_pattern
compiled limit pattern
Definition: context.h:43
struct Mailbox * mailbox
Definition: context.h:53
bool notify_observer_remove(struct Notify *notify, observer_t callback)
Remove an observer from an object.
Definition: notify.c:193
#define FREE(x)
Definition: memory.h:40
struct Notify * notify
Notifications handler.
Definition: mailbox.h:151
char * pattern
limit pattern string
Definition: context.h:42
void mutt_pattern_free(struct PatternHead **pat)
Free a Pattern.
Definition: pattern.c:1337
void ctx_update ( struct Context ctx)

Update the Context's message counts.

Parameters
ctxMailbox

this routine is called to update the counts in the context structure

Definition at line 78 of file context.c.

79 {
80  if (!ctx || !ctx->mailbox)
81  return;
82 
83  struct Mailbox *m = ctx->mailbox;
84 
87 
88  /* reset counters */
89  m->msg_unread = 0;
90  m->msg_flagged = 0;
91  m->msg_new = 0;
92  m->msg_deleted = 0;
93  m->msg_tagged = 0;
94  m->vcount = 0;
95  m->changed = false;
96 
97  mutt_clear_threads(ctx);
98 
99  struct Email *e = NULL;
100  for (int msgno = 0; msgno < m->msg_count; msgno++)
101  {
102  e = m->emails[msgno];
103 
104  if (WithCrypto)
105  {
106  /* NOTE: this _must_ be done before the check for mailcap! */
107  e->security = crypt_query(e->content);
108  }
109 
110  if (!ctx->pattern)
111  {
112  m->v2r[m->vcount] = msgno;
113  e->vnum = m->vcount++;
114  }
115  else
116  e->vnum = -1;
117  e->msgno = msgno;
118 
119  if (e->env->supersedes)
120  {
121  struct Email *e2 = NULL;
122 
123  if (!m->id_hash)
124  m->id_hash = mutt_make_id_hash(m);
125 
126  e2 = mutt_hash_find(m->id_hash, e->env->supersedes);
127  if (e2)
128  {
129  e2->superseded = true;
130  if (C_Score)
131  mutt_score_message(ctx->mailbox, e2, true);
132  }
133  }
134 
135  /* add this message to the hash tables */
136  if (m->id_hash && e->env->message_id)
138  if (m->subj_hash && e->env->real_subj)
140  mutt_label_hash_add(m, e);
141 
142  if (C_Score)
143  mutt_score_message(ctx->mailbox, e, false);
144 
145  if (e->changed)
146  m->changed = true;
147  if (e->flagged)
148  m->msg_flagged++;
149  if (e->deleted)
150  m->msg_deleted++;
151  if (!e->read)
152  {
153  m->msg_unread++;
154  if (!e->old)
155  m->msg_new++;
156  }
157  }
158 
159  mutt_sort_headers(ctx, true); /* rethread from scratch */
160 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:111
int msg_count
Total number of messages.
Definition: mailbox.h:103
The envelope/body of an email.
Definition: email.h:37
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:108
int msg_unread
Number of unread messages.
Definition: mailbox.h:104
char * supersedes
Supersedes header.
Definition: envelope.h:56
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:105
struct Body * content
List of MIME parts.
Definition: email.h:90
void * mutt_hash_find(const struct Hash *table, const char *strkey)
Find the HashElem data in a Hash table element using a key.
Definition: hash.c:379
void mutt_score_message(struct Mailbox *m, struct Email *e, bool upd_mbox)
Apply scoring to an email.
Definition: score.c:170
char * real_subj
Offset of the real subject.
Definition: envelope.h:53
bool changed
Email has been edited.
Definition: email.h:48
void mutt_label_hash_add(struct Mailbox *m, struct Email *e)
Add a message&#39;s labels to the Hash Table.
Definition: mutt_header.c:372
int vcount
The number of virtual messages.
Definition: mailbox.h:114
bool read
Email is read.
Definition: email.h:51
char * message_id
Message ID.
Definition: envelope.h:55
struct Mailbox * mailbox
Definition: context.h:53
bool old
Email is seen, but unread.
Definition: email.h:50
struct Envelope * env
Envelope information.
Definition: email.h:89
bool superseded
Got superseded?
Definition: email.h:53
void mutt_sort_headers(struct Context *ctx, bool init)
Sort emails by their headers.
Definition: sort.c:363
A mailbox.
Definition: mailbox.h:93
int msg_tagged
How many messages are tagged?
Definition: mailbox.h:109
int vnum
Virtual message number.
Definition: email.h:87
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
struct Hash * mutt_make_id_hash(struct Mailbox *m)
Create a Hash Table for message-ids.
Definition: mutt_thread.c:1438
void mutt_clear_threads(struct Context *ctx)
Clear the threading of message in a mailbox.
Definition: mutt_thread.c:603
int * v2r
Mapping from virtual to real msgno.
Definition: mailbox.h:113
bool flagged
Marked important?
Definition: email.h:43
int msg_new
Number of new messages.
Definition: mailbox.h:107
struct Hash * subj_hash
Hash table by subject.
Definition: mailbox.h:140
bool deleted
Email is deleted.
Definition: email.h:45
WHERE bool C_Score
Config: Use message scoring.
Definition: globals.h:248
bool changed
Mailbox has been modified.
Definition: mailbox.h:126
void mutt_hash_free(struct Hash **ptr)
elem_free a hash table
Definition: hash.c:472
struct HashElem * mutt_hash_insert(struct Hash *table, const char *strkey, void *data)
Add a new element to the Hash table (with string keys)
Definition: hash.c:352
char * pattern
limit pattern string
Definition: context.h:42
#define WithCrypto
Definition: ncrypt.h:156
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:663
struct Hash * id_hash
Hash table by msg id.
Definition: mailbox.h:139
int msgno
Number displayed to the user.
Definition: email.h:86
void ctx_update_tables ( struct Context ctx,
bool  committing 
)

Update a Context structure's internal tables.

Parameters
ctxMailbox
committingCommit the changes?

Definition at line 167 of file context.c.

168 {
169  if (!ctx || !ctx->mailbox)
170  return;
171 
172  struct Mailbox *m = ctx->mailbox;
173 
174  int i, j, padding;
175 
176  /* update memory to reflect the new state of the mailbox */
177  m->vcount = 0;
178  ctx->vsize = 0;
179  m->msg_tagged = 0;
180  m->msg_deleted = 0;
181  m->msg_new = 0;
182  m->msg_unread = 0;
183  m->changed = false;
184  m->msg_flagged = 0;
185  padding = mx_msg_padding_size(m);
186  for (i = 0, j = 0; i < m->msg_count; i++)
187  {
188  if (!m->emails[i]->quasi_deleted &&
189  ((committing && (!m->emails[i]->deleted || ((m->magic == MUTT_MAILDIR) && C_MaildirTrash))) ||
190  (!committing && m->emails[i]->active)))
191  {
192  if (i != j)
193  {
194  m->emails[j] = m->emails[i];
195  m->emails[i] = NULL;
196  }
197  m->emails[j]->msgno = j;
198  if (m->emails[j]->vnum != -1)
199  {
200  m->v2r[m->vcount] = j;
201  m->emails[j]->vnum = m->vcount++;
202  struct Body *b = m->emails[j]->content;
203  ctx->vsize += b->length + b->offset - b->hdr_offset + padding;
204  }
205 
206  if (committing)
207  {
208  m->emails[j]->changed = false;
209  m->emails[j]->env->changed = false;
210  }
211  else if (m->emails[j]->changed)
212  m->changed = true;
213 
214  if (!committing || ((m->magic == MUTT_MAILDIR) && C_MaildirTrash))
215  {
216  if (m->emails[j]->deleted)
217  m->msg_deleted++;
218  }
219 
220  if (m->emails[j]->tagged)
221  m->msg_tagged++;
222  if (m->emails[j]->flagged)
223  m->msg_flagged++;
224  if (!m->emails[j]->read)
225  {
226  m->msg_unread++;
227  if (!m->emails[j]->old)
228  m->msg_new++;
229  }
230 
231  j++;
232  }
233  else
234  {
235  if ((m->magic == MUTT_NOTMUCH) || (m->magic == MUTT_MH) ||
236  (m->magic == MUTT_MAILDIR) || (m->magic == MUTT_IMAP))
237  {
238  mailbox_size_sub(m, m->emails[i]);
239  }
240  /* remove message from the hash tables */
241  if (m->subj_hash && m->emails[i]->env->real_subj)
242  mutt_hash_delete(m->subj_hash, m->emails[i]->env->real_subj, m->emails[i]);
243  if (m->id_hash && m->emails[i]->env->message_id)
244  mutt_hash_delete(m->id_hash, m->emails[i]->env->message_id, m->emails[i]);
245  mutt_label_hash_remove(m, m->emails[i]);
246  /* The path mx_mbox_check() -> imap_check_mailbox() ->
247  * imap_expunge_mailbox() -> ctx_update_tables()
248  * can occur before a call to mx_mbox_sync(), resulting in
249  * last_tag being stale if it's not reset here. */
250  if (ctx->last_tag == m->emails[i])
251  ctx->last_tag = NULL;
252  mutt_email_free(&m->emails[i]);
253  }
254  }
255  m->msg_count = j;
256 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:111
void mutt_hash_delete(struct Hash *table, const char *strkey, const void *data)
Remove an element from a Hash table.
Definition: hash.c:444
int msg_count
Total number of messages.
Definition: mailbox.h:103
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:108
int msg_unread
Number of unread messages.
Definition: mailbox.h:104
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:105
struct Body * content
List of MIME parts.
Definition: email.h:90
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
char * real_subj
Offset of the real subject.
Definition: envelope.h:53
bool changed
Email has been edited.
Definition: email.h:48
void mutt_label_hash_remove(struct Mailbox *m, struct Email *e)
Rmove a message&#39;s labels from the Hash Table.
Definition: mutt_header.c:385
int vcount
The number of virtual messages.
Definition: mailbox.h:114
The body of an email.
Definition: body.h:34
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Definition: envelope.h:71
bool tagged
Email is tagged.
Definition: email.h:44
bool read
Email is read.
Definition: email.h:51
char * message_id
Message ID.
Definition: envelope.h:55
struct Mailbox * mailbox
Definition: context.h:53
bool old
Email is seen, but unread.
Definition: email.h:50
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:117
struct Envelope * env
Envelope information.
Definition: email.h:89
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
bool quasi_deleted
Deleted from neomutt, but not modified on disk.
Definition: email.h:47
off_t vsize
Definition: context.h:41
bool active
Message is not to be removed.
Definition: email.h:59
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
A mailbox.
Definition: mailbox.h:93
WHERE bool C_MaildirTrash
Config: Use the maildir &#39;trashed&#39; flag, rather than deleting.
Definition: globals.h:238
&#39;MH&#39; Mailbox type
Definition: mailbox.h:50
int msg_tagged
How many messages are tagged?
Definition: mailbox.h:109
int vnum
Virtual message number.
Definition: email.h:87
void mutt_email_free(struct Email **e)
Free an Email.
Definition: email.c:41
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:54
int * v2r
Mapping from virtual to real msgno.
Definition: mailbox.h:113
bool flagged
Marked important?
Definition: email.h:43
int msg_new
Number of new messages.
Definition: mailbox.h:107
struct Hash * subj_hash
Hash table by subject.
Definition: mailbox.h:140
bool deleted
Email is deleted.
Definition: email.h:45
bool changed
Mailbox has been modified.
Definition: mailbox.h:126
int mx_msg_padding_size(struct Mailbox *m)
Bytes of padding between messages - Wrapper for MxOps::msg_padding_size.
Definition: mx.c:1467
long hdr_offset
Offset in stream where the headers begin.
Definition: body.h:42
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:182
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
struct Hash * id_hash
Hash table by msg id.
Definition: mailbox.h:139
struct Email * last_tag
last tagged msg.
Definition: context.h:44
int msgno
Number displayed to the user.
Definition: email.h:86
int ctx_mailbox_observer ( struct NotifyCallback nc)

Watch for changes affecting the Context - Implements observer_t.

Definition at line 261 of file context.c.

262 {
263  if (!nc)
264  return -1;
265  if ((nc->obj_type != NT_MAILBOX) || (nc->event_type != NT_MAILBOX))
266  return 0;
267  struct Context *ctx = (struct Context *) nc->data;
268  if (!ctx)
269  return -1;
270 
271  switch (nc->event_subtype)
272  {
273  case MBN_CLOSED:
274  mutt_clear_threads(ctx);
275  ctx_cleanup(ctx);
276  break;
277  case MBN_INVALID:
278  ctx_update(ctx);
279  break;
280  case MBN_UPDATE:
281  ctx_update_tables(ctx, true);
282  break;
283  case MBN_RESORT:
284  mutt_sort_headers(ctx, true);
285  break;
286  case MBN_UNTAG:
287  if (ctx->last_tag && ctx->last_tag->deleted)
288  ctx->last_tag = NULL;
289  break;
290  }
291 
292  return 0;
293 }
void ctx_update_tables(struct Context *ctx, bool committing)
Update a Context structure&#39;s internal tables.
Definition: context.c:167
The "current" mailbox.
Definition: context.h:39
intptr_t data
Observer: private to observer.
Definition: observer.h:48
Mailbox was closed.
Definition: mailbox.h:64
Update internal tables.
Definition: mailbox.h:67
int event_subtype
Send: event subtype.
Definition: observer.h:45
int event_type
Send: event type.
Definition: observer.h:44
void mutt_sort_headers(struct Context *ctx, bool init)
Sort emails by their headers.
Definition: sort.c:363
void ctx_update(struct Context *ctx)
Update the Context&#39;s message counts.
Definition: context.c:78
Clear the &#39;last-tagged&#39; pointer.
Definition: mailbox.h:68
Email list needs resorting.
Definition: mailbox.h:66
void ctx_cleanup(struct Context *ctx)
Release memory and initialize a Context object.
Definition: context.c:63
void mutt_clear_threads(struct Context *ctx)
Clear the threading of message in a mailbox.
Definition: mutt_thread.c:603
Email list was changed.
Definition: mailbox.h:65
bool deleted
Email is deleted.
Definition: email.h:45
int obj_type
Notify: type of object event happened on.
Definition: observer.h:43
Mailbox has changed.
Definition: notify_type.h:35
struct Email * last_tag
last tagged msg.
Definition: context.h:44
bool message_is_visible ( struct Context ctx,
int  index 
)

Is a message in the index within limit.

Parameters
ctxOpen mailbox
indexMessage ID (index into ctx->emails[]
Return values
trueThe message is within limit

If no limit is in effect, all the messages are visible.

Definition at line 303 of file context.c.

304 {
305  if (!ctx || !ctx->mailbox->emails || (index >= ctx->mailbox->msg_count))
306  return false;
307 
308  return !ctx->pattern || ctx->mailbox->emails[index]->limited;
309 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:111
int msg_count
Total number of messages.
Definition: mailbox.h:103
struct Mailbox * mailbox
Definition: context.h:53
bool limited
Is this message in a limited view?
Definition: email.h:74
char * pattern
limit pattern string
Definition: context.h:42
bool message_is_tagged ( struct Context ctx,
int  index 
)

Is a message in the index tagged (and within limit)

Parameters
ctxOpen mailbox
indexMessage ID (index into ctx->emails[]
Return values
trueThe message is both tagged and within limit

If a limit is in effect, the message must be visible within it.

Definition at line 319 of file context.c.

320 {
321  return message_is_visible(ctx, index) && ctx->mailbox->emails[index]->tagged;
322 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:111
bool tagged
Email is tagged.
Definition: email.h:44
struct Mailbox * mailbox
Definition: context.h:53
bool message_is_visible(struct Context *ctx, int index)
Is a message in the index within limit.
Definition: context.c:303
int el_add_tagged ( struct EmailList *  el,
struct Context ctx,
struct Email e,
bool  use_tagged 
)

Get a list of the tagged Emails.

Parameters
elEmpty EmailList to populate
ctxCurrent Mailbox
eCurrent Email
use_taggedUse tagged Emails
Return values
numNumber of selected emails
-1Error

Definition at line 333 of file context.c.

334 {
335  int count = 0;
336 
337  if (use_tagged)
338  {
339  if (!ctx || !ctx->mailbox || !ctx->mailbox->emails)
340  return -1;
341 
342  for (size_t i = 0; i < ctx->mailbox->msg_count; i++)
343  {
344  if (!message_is_tagged(ctx, i))
345  continue;
346 
347  struct EmailNode *en = mutt_mem_calloc(1, sizeof(*en));
348  en->email = ctx->mailbox->emails[i];
349  STAILQ_INSERT_TAIL(el, en, entries);
350  count++;
351  }
352  }
353  else
354  {
355  if (!e)
356  return -1;
357 
358  struct EmailNode *en = mutt_mem_calloc(1, sizeof(*en));
359  en->email = e;
360  STAILQ_INSERT_TAIL(el, en, entries);
361  count = 1;
362  }
363 
364  return count;
365 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:111
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
int msg_count
Total number of messages.
Definition: mailbox.h:103
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:387
struct Mailbox * mailbox
Definition: context.h:53
struct Email * email
Email in the list.
Definition: email.h:119
List of Emails.
Definition: email.h:117
bool message_is_tagged(struct Context *ctx, int index)
Is a message in the index tagged (and within limit)
Definition: context.c:319
int el_add_email ( struct EmailList *  el,
struct Email e 
)

Get a list of the selected Emails.

Parameters
eCurrent Email
elEmailList to add to
Return values
0Success
-1Error

Definition at line 374 of file context.c.

375 {
376  if (!el || !e)
377  return -1;
378 
379  struct EmailNode *en = mutt_mem_calloc(1, sizeof(*en));
380  en->email = e;
381  STAILQ_INSERT_TAIL(el, en, entries);
382 
383  return 0;
384 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:387
struct Email * email
Email in the list.
Definition: email.h:119
List of Emails.
Definition: email.h:117