NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
email.c
Go to the documentation of this file.
1 
29 #include "config.h"
30 #include <stdbool.h>
31 #include <string.h>
32 #include "mutt/lib.h"
33 #include "email.h"
34 #include "body.h"
35 #include "envelope.h"
36 #include "tags.h"
37 
38 void nm_edata_free(void **ptr);
39 
44 void email_free(struct Email **ptr)
45 {
46  if (!ptr || !*ptr)
47  return;
48 
49  struct Email *e = *ptr;
50 
51  mutt_debug(LL_NOTIFY, "NT_EMAIL_DELETE: %p\n", e);
52  struct EventEmail ev_e = { 1, &e };
54 
55  if (e->edata_free && e->edata)
56  e->edata_free(&e->edata);
57 
58  mutt_env_free(&e->env);
59  mutt_body_free(&e->body);
60  FREE(&e->tree);
61  FREE(&e->path);
62 #ifdef MIXMASTER
63  mutt_list_free(&e->chain);
64 #endif
65 #ifdef USE_NOTMUCH
67 #endif
69  notify_free(&e->notify);
70 
71  FREE(ptr);
72 }
73 
78 struct Email *email_new(void)
79 {
80  static size_t sequence = 0;
81 
82  struct Email *e = mutt_mem_calloc(1, sizeof(struct Email));
83 #ifdef MIXMASTER
84  STAILQ_INIT(&e->chain);
85 #endif
86  STAILQ_INIT(&e->tags);
87  e->visible = true;
88  e->sequence = sequence++;
89  e->notify = notify_new();
90 
91  return e;
92 }
93 
100 bool email_cmp_strict(const struct Email *e1, const struct Email *e2)
101 {
102  if (e1 && e2)
103  {
104  if ((e1->received != e2->received) || (e1->date_sent != e2->date_sent) ||
105  (e1->body->length != e2->body->length) || (e1->lines != e2->lines) ||
106  (e1->zhours != e2->zhours) || (e1->zminutes != e2->zminutes) ||
107  (e1->zoccident != e2->zoccident) || (e1->mime != e2->mime) ||
108  !mutt_env_cmp_strict(e1->env, e2->env) || !mutt_body_cmp_strict(e1->body, e2->body))
109  {
110  return false;
111  }
112  return true;
113  }
114  else
115  {
116  return (!e1 && !e2);
117  }
118 }
119 
125 size_t email_size(const struct Email *e)
126 {
127  if (!e || !e->body)
128  return 0;
129  return e->body->length + e->body->offset - e->body->hdr_offset;
130 }
131 
138 void emaillist_clear(struct EmailList *el)
139 {
140  if (!el)
141  return;
142 
143  struct EmailNode *en = NULL, *tmp = NULL;
144  STAILQ_FOREACH_SAFE(en, el, entries, tmp)
145  {
146  STAILQ_REMOVE(el, en, EmailNode, entries);
147  FREE(&en);
148  }
149  STAILQ_INIT(el);
150 }
151 
159 int emaillist_add_email(struct EmailList *el, struct Email *e)
160 {
161  if (!el || !e)
162  return -1;
163 
164  struct EmailNode *en = mutt_mem_calloc(1, sizeof(*en));
165  en->email = e;
166  STAILQ_INSERT_TAIL(el, en, entries);
167 
168  return 0;
169 }
170 
180 struct ListNode *header_find(const struct ListHead *hdrlist, const char *header)
181 {
182  const char *key_end = strchr(header, ':');
183  if (!key_end)
184  return NULL;
185 
186  const int keylen = key_end - header + 1;
187 
188  struct ListNode *n = NULL;
189  STAILQ_FOREACH(n, hdrlist, entries)
190  {
191  if (mutt_istrn_equal(n->data, header, keylen))
192  return n;
193  }
194  return n;
195 }
196 
203 struct ListNode *header_add(struct ListHead *hdrlist, const char *header)
204 {
205  struct ListNode *n = mutt_list_insert_tail(hdrlist, NULL);
206  n->data = mutt_str_dup(header);
207 
208  return n;
209 }
210 
217 struct ListNode *header_update(struct ListNode *hdr, const char *header)
218 {
219  FREE(&hdr->data);
220  hdr->data = mutt_str_dup(header);
221 
222  return hdr;
223 }
224 
233 struct ListNode *header_set(struct ListHead *hdrlist, const char *header)
234 {
235  struct ListNode *n = header_find(hdrlist, header);
236 
237  return n ? header_update(n, header) : header_add(hdrlist, header);
238 }
239 
245 void header_free(struct ListHead *hdrlist, struct ListNode *target)
246 {
247  STAILQ_REMOVE(hdrlist, target, ListNode, entries);
248  FREE(&target->data);
249  FREE(&target);
250 }
An Event that happened to an Email.
Definition: email.h:155
struct ListNode * header_find(const struct ListHead *hdrlist, const char *header)
Find a header, matching on its field, in a list of headers.
Definition: email.c:180
int lines
How many lines in the body of this message?
Definition: email.h:85
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:402
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:96
The envelope/body of an email.
Definition: email.h:37
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:44
struct Body * body
List of MIME parts.
Definition: email.h:91
Log of notifications.
Definition: logging.h:45
void notify_free(struct Notify **ptr)
Free a notification handler.
Definition: notify.c:73
struct ListNode * header_add(struct ListHead *hdrlist, const char *header)
Add a header to a list.
Definition: email.c:203
struct ListNode * header_set(struct ListHead *hdrlist, const char *header)
Set a header value in a list.
Definition: email.c:233
size_t email_size(const struct Email *e)
compute the size of an email
Definition: email.c:125
bool mutt_istrn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings ignoring case (to a maximum), safely.
Definition: string.c:621
bool mutt_env_cmp_strict(const struct Envelope *e1, const struct Envelope *e2)
Strictly compare two Envelopes.
Definition: envelope.c:241
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:389
void emaillist_clear(struct EmailList *el)
Drop a private list of Emails.
Definition: email.c:138
bool zoccident
True, if west of UTC, False if east.
Definition: email.h:65
Representation of the body of an email.
void driver_tags_free(struct TagList *list)
Free tags from a header.
Definition: tags.c:107
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
struct Email * email_new(void)
Create a new Email.
Definition: email.c:78
Email is about to be deleted.
Definition: email.h:147
bool mutt_body_cmp_strict(const struct Body *b1, const struct Body *b2)
Strictly compare two email Body&#39;s.
Definition: body.c:108
Representation of an email.
#define STAILQ_INIT(head)
Definition: queue.h:372
bool mime
Has a MIME-Version header?
Definition: email.h:42
struct Envelope * env
Envelope information.
Definition: email.h:90
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
struct TagList tags
For drivers that support server tagging.
Definition: email.h:109
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:82
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
struct Notify * notify_new(void)
Create a new notifications handler.
Definition: notify.c:60
bool visible
Is this message part of the view?
Definition: email.h:74
struct ListHead chain
Mixmaster chain.
Definition: email.h:102
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
Representation of an email header (envelope)
struct ListNode * header_update(struct ListNode *hdr, const char *header)
Update an existing header.
Definition: email.c:217
void(* edata_free)(void **ptr)
Free the private data attached to the Email.
Definition: email.h:121
size_t sequence
Sequence number assigned on creation.
Definition: email.h:99
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
unsigned int zhours
Hours away from UTC.
Definition: email.h:63
char * tree
Character string to print thread tree.
Definition: email.h:94
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
int emaillist_add_email(struct EmailList *el, struct Email *e)
Add an Email to a list.
Definition: email.c:159
struct Notify * notify
Notifications: NotifyEmail, EventEmail.
Definition: email.h:123
bool email_cmp_strict(const struct Email *e1, const struct Email *e2)
Strictly compare message emails.
Definition: email.c:100
Email has changed, NotifyEmail, EventEmail.
Definition: notify_type.h:44
void header_free(struct ListHead *hdrlist, struct ListNode *target)
Free and remove a header from a header list.
Definition: email.c:245
char * data
String.
Definition: list.h:36
void * edata
Driver-specific data.
Definition: email.h:111
struct Email * email
Email in the list.
Definition: email.h:131
char * path
Path of Email (for local Mailboxes)
Definition: email.h:92
#define FREE(x)
Definition: memory.h:40
Driver based email tags.
List of Emails.
Definition: email.h:129
long hdr_offset
Offset in stream where the headers begin.
Definition: body.h:42
Convenience wrapper for the library headers.
A List node for strings.
Definition: list.h:34
unsigned int zminutes
Minutes away from UTC.
Definition: email.h:64
void nm_edata_free(void **ptr)
Free data attached to an Email.
Definition: edata.c:42
time_t received
Time when the message was placed in the mailbox.
Definition: email.h:83
void * nm_edata
Notmuch private data.
Definition: email.h:106
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