NeoMutt  2018-07-16 +1783-b00bd9
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"
+ Include dependency graph for context.c:

Go to the source code of this file.

Functions

void ctx_free (struct Context **ctx)
 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...
 
void ctx_mailbox_changed (struct Mailbox *m, enum MailboxNotification action)
 Act on a Mailbox change notification. 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...
 
void el_free (struct EmailList *el)
 Drop a private list of Emails. 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 **  ctx)

Free a Context.

Parameters
[out]ctxContext to free

Definition at line 47 of file context.c.

48 {
49  if (!ctx || !*ctx)
50  return;
51 
52  FREE(ctx);
53 }
#define FREE(x)
Definition: memory.h:40

+ Here is the caller graph for this function:

void ctx_cleanup ( struct Context ctx)

Release memory and initialize a Context object.

Parameters
ctxContext to cleanup

Definition at line 59 of file context.c.

60 {
61  FREE(&ctx->pattern);
63  memset(ctx, 0, sizeof(struct Context));
64 }
The "current" mailbox.
Definition: context.h:38
struct PatternHead * limit_pattern
compiled limit pattern
Definition: context.h:42
#define FREE(x)
Definition: memory.h:40
char * pattern
limit pattern string
Definition: context.h:41
void mutt_pattern_free(struct PatternHead **pat)
Free a Pattern.
Definition: pattern.c:1336

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 72 of file context.c.

73 {
74  if (!ctx || !ctx->mailbox)
75  return;
76 
77  struct Mailbox *m = ctx->mailbox;
78 
81 
82  /* reset counters */
83  m->msg_unread = 0;
84  m->msg_flagged = 0;
85  m->msg_new = 0;
86  m->msg_deleted = 0;
87  m->msg_tagged = 0;
88  m->vcount = 0;
89  m->changed = false;
90 
91  mutt_clear_threads(ctx);
92 
93  struct Email *e = NULL;
94  for (int msgno = 0; msgno < m->msg_count; msgno++)
95  {
96  e = m->emails[msgno];
97 
98  if (WithCrypto)
99  {
100  /* NOTE: this _must_ be done before the check for mailcap! */
101  e->security = crypt_query(e->content);
102  }
103 
104  if (!ctx->pattern)
105  {
106  m->v2r[m->vcount] = msgno;
107  e->virtual = m->vcount++;
108  }
109  else
110  e->virtual = -1;
111  e->msgno = msgno;
112 
113  if (e->env->supersedes)
114  {
115  struct Email *e2 = NULL;
116 
117  if (!m->id_hash)
118  m->id_hash = mutt_make_id_hash(m);
119 
120  e2 = mutt_hash_find(m->id_hash, e->env->supersedes);
121  if (e2)
122  {
123  e2->superseded = true;
124  if (C_Score)
125  mutt_score_message(ctx->mailbox, e2, true);
126  }
127  }
128 
129  /* add this message to the hash tables */
130  if (m->id_hash && e->env->message_id)
132  if (m->subj_hash && e->env->real_subj)
134  mutt_label_hash_add(m, e);
135 
136  if (C_Score)
137  mutt_score_message(ctx->mailbox, e, false);
138 
139  if (e->changed)
140  m->changed = true;
141  if (e->flagged)
142  m->msg_flagged++;
143  if (e->deleted)
144  m->msg_deleted++;
145  if (!e->read)
146  {
147  m->msg_unread++;
148  if (!e->old)
149  m->msg_new++;
150  }
151  }
152 
153  mutt_sort_headers(ctx, true); /* rethread from scratch */
154 }
struct Email ** emails
Definition: mailbox.h:99
int msg_count
total number of messages
Definition: mailbox.h:92
The envelope/body of an email.
Definition: email.h:37
int msg_deleted
number of deleted messages
Definition: mailbox.h:96
int msg_unread
number of unread messages
Definition: mailbox.h:93
char * supersedes
Definition: envelope.h:54
int msg_flagged
number of flagged messages
Definition: mailbox.h:94
int virtual
virtual message number
Definition: email.h:90
struct Body * content
list of MIME parts
Definition: email.h:93
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:51
bool changed
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:373
int vcount
the number of virtual messages
Definition: mailbox.h:102
bool read
Definition: email.h:51
char * message_id
Definition: envelope.h:53
struct Mailbox * mailbox
Definition: context.h:52
bool old
Definition: email.h:50
struct Envelope * env
envelope information
Definition: email.h:92
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:361
A mailbox.
Definition: mailbox.h:83
int msg_tagged
how many messages are tagged?
Definition: mailbox.h:97
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:1433
void mutt_clear_threads(struct Context *ctx)
Clear the threading of message in a mailbox.
Definition: mutt_thread.c:599
int * v2r
mapping from virtual to real msgno
Definition: mailbox.h:101
bool flagged
marked important?
Definition: email.h:43
int msg_new
number of new messages
Definition: mailbox.h:95
struct Hash * subj_hash
hash table by subject
Definition: mailbox.h:128
bool 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:114
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:41
#define WithCrypto
Definition: ncrypt.h:155
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:660
struct Hash * id_hash
hash table by msg id
Definition: mailbox.h:127
int msgno
number displayed to the user
Definition: email.h:89

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ctx_update_tables ( struct Context ctx,
bool  committing 
)

Update a Context structure's internal tables.

Parameters
ctxMailbox
committingCommit the changes?

Definition at line 161 of file context.c.

162 {
163  if (!ctx || !ctx->mailbox)
164  return;
165 
166  struct Mailbox *m = ctx->mailbox;
167 
168  int i, j, padding;
169 
170  /* update memory to reflect the new state of the mailbox */
171  m->vcount = 0;
172  ctx->vsize = 0;
173  m->msg_tagged = 0;
174  m->msg_deleted = 0;
175  m->msg_new = 0;
176  m->msg_unread = 0;
177  m->changed = false;
178  m->msg_flagged = 0;
179  padding = mx_msg_padding_size(m);
180  for (i = 0, j = 0; i < m->msg_count; i++)
181  {
182  if (!m->emails[i]->quasi_deleted &&
183  ((committing && (!m->emails[i]->deleted || ((m->magic == MUTT_MAILDIR) && C_MaildirTrash))) ||
184  (!committing && m->emails[i]->active)))
185  {
186  if (i != j)
187  {
188  m->emails[j] = m->emails[i];
189  m->emails[i] = NULL;
190  }
191  m->emails[j]->msgno = j;
192  if (m->emails[j]->virtual != -1)
193  {
194  m->v2r[m->vcount] = j;
195  m->emails[j]->virtual = m->vcount++;
196  struct Body *b = m->emails[j]->content;
197  ctx->vsize += b->length + b->offset - b->hdr_offset + padding;
198  }
199 
200  if (committing)
201  {
202  m->emails[j]->changed = false;
203  m->emails[j]->env->changed = false;
204  }
205  else if (m->emails[j]->changed)
206  m->changed = true;
207 
208  if (!committing || ((m->magic == MUTT_MAILDIR) && C_MaildirTrash))
209  {
210  if (m->emails[j]->deleted)
211  m->msg_deleted++;
212  }
213 
214  if (m->emails[j]->tagged)
215  m->msg_tagged++;
216  if (m->emails[j]->flagged)
217  m->msg_flagged++;
218  if (!m->emails[j]->read)
219  {
220  m->msg_unread++;
221  if (!m->emails[j]->old)
222  m->msg_new++;
223  }
224 
225  j++;
226  }
227  else
228  {
229  if ((m->magic == MUTT_NOTMUCH) || (m->magic == MUTT_MH) ||
230  (m->magic == MUTT_MAILDIR) || (m->magic == MUTT_IMAP))
231  {
232  mutt_mailbox_size_sub(m, m->emails[i]);
233  }
234  /* remove message from the hash tables */
235  if (m->subj_hash && m->emails[i]->env->real_subj)
236  mutt_hash_delete(m->subj_hash, m->emails[i]->env->real_subj, m->emails[i]);
237  if (m->id_hash && m->emails[i]->env->message_id)
238  mutt_hash_delete(m->id_hash, m->emails[i]->env->message_id, m->emails[i]);
239  mutt_label_hash_remove(m, m->emails[i]);
240  /* The path mx_mbox_check() -> imap_check_mailbox() ->
241  * imap_expunge_mailbox() -> ctx_update_tables()
242  * can occur before a call to mx_mbox_sync(), resulting in
243  * last_tag being stale if it's not reset here. */
244  if (ctx->last_tag == m->emails[i])
245  ctx->last_tag = NULL;
246  mutt_email_free(&m->emails[i]);
247  }
248  }
249  m->msg_count = j;
250 }
struct Email ** emails
Definition: mailbox.h:99
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: magic.h:43
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:92
int msg_deleted
number of deleted messages
Definition: mailbox.h:96
int msg_unread
number of unread messages
Definition: mailbox.h:93
int msg_flagged
number of flagged messages
Definition: mailbox.h:94
&#39;Maildir&#39; Mailbox type
Definition: magic.h:40
int virtual
virtual message number
Definition: email.h:90
struct Body * content
list of MIME parts
Definition: email.h:93
LOFF_T offset
offset where the actual data begins
Definition: body.h:46
char * real_subj
offset of the real subject
Definition: envelope.h:51
bool changed
Definition: email.h:48
&#39;IMAP&#39; Mailbox type
Definition: magic.h:42
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:386
int vcount
the number of virtual messages
Definition: mailbox.h:102
The body of an email.
Definition: body.h:34
unsigned char changed
Definition: envelope.h:69
bool tagged
Definition: email.h:44
bool read
Definition: email.h:51
char * message_id
Definition: envelope.h:53
struct Mailbox * mailbox
Definition: context.h:52
bool old
Definition: email.h:50
void mutt_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:582
enum MailboxType magic
mailbox type
Definition: mailbox.h:105
struct Envelope * env
envelope information
Definition: email.h:92
bool quasi_deleted
deleted from neomutt, but not modified on disk
Definition: email.h:47
off_t vsize
Definition: context.h:40
bool active
message is not to be removed
Definition: email.h:59
LOFF_T length
length (in bytes) of attachment
Definition: body.h:47
A mailbox.
Definition: mailbox.h:83
WHERE bool C_MaildirTrash
Config: Use the maildir &#39;trashed&#39; flag, rather than deleting.
Definition: globals.h:238
int msg_tagged
how many messages are tagged?
Definition: mailbox.h:97
void mutt_email_free(struct Email **e)
Free an Email.
Definition: email.c:41
int * v2r
mapping from virtual to real msgno
Definition: mailbox.h:101
bool flagged
marked important?
Definition: email.h:43
int msg_new
number of new messages
Definition: mailbox.h:95
struct Hash * subj_hash
hash table by subject
Definition: mailbox.h:128
bool deleted
Definition: email.h:45
&#39;MH&#39; Mailbox type
Definition: magic.h:39
bool changed
mailbox has been modified
Definition: mailbox.h:114
int mx_msg_padding_size(struct Mailbox *m)
Bytes of padding between messages - Wrapper for MxOps::msg_padding_size.
Definition: mx.c:1454
long hdr_offset
offset in stream where the headers begin.
Definition: body.h:42
struct Hash * id_hash
hash table by msg id
Definition: mailbox.h:127
struct Email * last_tag
last tagged msg.
Definition: context.h:43
int msgno
number displayed to the user
Definition: email.h:89

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ctx_mailbox_changed ( struct Mailbox m,
enum MailboxNotification  action 
)

Act on a Mailbox change notification.

Parameters
mMailbox
actionEvent occurring

Definition at line 257 of file context.c.

258 {
259  if (!m || !m->ndata)
260  return;
261 
262  struct Context *ctx = m->ndata;
263 
264  switch (action)
265  {
266  case MBN_CLOSED:
267  mutt_clear_threads(ctx);
268  ctx_cleanup(ctx);
269  break;
270  case MBN_INVALID:
271  ctx_update(ctx);
272  break;
273  case MBN_UPDATE:
274  ctx_update_tables(ctx, true);
275  break;
276  case MBN_RESORT:
277  mutt_sort_headers(ctx, true);
278  break;
279  case MBN_UNTAG:
280  if (ctx->last_tag && ctx->last_tag->deleted)
281  ctx->last_tag = NULL;
282  break;
283  }
284 }
void ctx_update_tables(struct Context *ctx, bool committing)
Update a Context structure&#39;s internal tables.
Definition: context.c:161
The "current" mailbox.
Definition: context.h:38
Mailbox was closed.
Definition: mailbox.h:54
Update internal tables.
Definition: mailbox.h:57
void mutt_sort_headers(struct Context *ctx, bool init)
Sort emails by their headers.
Definition: sort.c:361
void ctx_update(struct Context *ctx)
Update the Context&#39;s message counts.
Definition: context.c:72
Clear the &#39;last-tagged&#39; pointer.
Definition: mailbox.h:58
Email list needs resorting.
Definition: mailbox.h:56
void ctx_cleanup(struct Context *ctx)
Release memory and initialize a Context object.
Definition: context.c:59
void mutt_clear_threads(struct Context *ctx)
Clear the threading of message in a mailbox.
Definition: mutt_thread.c:599
Email list was changed.
Definition: mailbox.h:55
bool deleted
Definition: email.h:45
void * ndata
Notification callback private data.
Definition: mailbox.h:140
struct Email * last_tag
last tagged msg.
Definition: context.h:43

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 294 of file context.c.

295 {
296  if (!ctx || !ctx->mailbox->emails || (index >= ctx->mailbox->msg_count))
297  return false;
298 
299  return !ctx->pattern || ctx->mailbox->emails[index]->limited;
300 }
struct Email ** emails
Definition: mailbox.h:99
int msg_count
total number of messages
Definition: mailbox.h:92
struct Mailbox * mailbox
Definition: context.h:52
bool limited
is this message in a limited view?
Definition: email.h:77
char * pattern
limit pattern string
Definition: context.h:41

+ Here is the caller graph for this function:

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 310 of file context.c.

311 {
312  return message_is_visible(ctx, index) && ctx->mailbox->emails[index]->tagged;
313 }
struct Email ** emails
Definition: mailbox.h:99
bool tagged
Definition: email.h:44
struct Mailbox * mailbox
Definition: context.h:52
bool message_is_visible(struct Context *ctx, int index)
Is a message in the index within limit.
Definition: context.c:294

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void el_free ( struct EmailList *  el)

Drop a private list of Emails.

Parameters
elEmailList to empty

The Emails are not freed.

Definition at line 321 of file context.c.

322 {
323  if (!el)
324  return;
325 
326  struct EmailNode *en = NULL, *tmp = NULL;
327  STAILQ_FOREACH_SAFE(en, el, entries, tmp)
328  {
329  STAILQ_REMOVE(el, en, EmailNode, entries);
330  FREE(&en);
331  }
332  STAILQ_INIT(el);
333 }
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:400
#define STAILQ_INIT(head)
Definition: queue.h:370
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:360
#define FREE(x)
Definition: memory.h:40
List of Emails.
Definition: email.h:121

+ Here is the caller graph for this function:

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 344 of file context.c.

345 {
346  int count = 0;
347 
348  if (use_tagged)
349  {
350  if (!ctx || !ctx->mailbox || !ctx->mailbox->emails)
351  return -1;
352 
353  for (size_t i = 0; i < ctx->mailbox->msg_count; i++)
354  {
355  if (!message_is_tagged(ctx, i))
356  continue;
357 
358  struct EmailNode *en = mutt_mem_calloc(1, sizeof(*en));
359  en->email = ctx->mailbox->emails[i];
360  STAILQ_INSERT_TAIL(el, en, entries);
361  count++;
362  }
363  }
364  else
365  {
366  if (!e)
367  return -1;
368 
369  struct EmailNode *en = mutt_mem_calloc(1, sizeof(*en));
370  en->email = e;
371  STAILQ_INSERT_TAIL(el, en, entries);
372  count = 1;
373  }
374 
375  return count;
376 }
struct Email ** emails
Definition: mailbox.h:99
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
int msg_count
total number of messages
Definition: mailbox.h:92
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:387
struct Mailbox * mailbox
Definition: context.h:52
struct Email * email
Definition: email.h:123
List of Emails.
Definition: email.h:121
bool message_is_tagged(struct Context *ctx, int index)
Is a message in the index tagged (and within limit)
Definition: context.c:310

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 385 of file context.c.

386 {
387  if (!el || !e)
388  return -1;
389 
390  struct EmailNode *en = mutt_mem_calloc(1, sizeof(*en));
391  en->email = e;
392  STAILQ_INSERT_TAIL(el, en, entries);
393 
394  return 0;
395 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:387
struct Email * email
Definition: email.h:123
List of Emails.
Definition: email.h:121

+ Here is the call graph for this function:

+ Here is the caller graph for this function: