NeoMutt  2022-04-29-145-g9b6a0e
Teaching an old dog new tricks
DOXYGEN
envelope.c
Go to the documentation of this file.
1 
30 #include "config.h"
31 #include <stddef.h>
32 #include <stdbool.h>
33 #include <string.h>
34 #include "mutt/lib.h"
35 #include "address/lib.h"
36 #include "envelope.h"
37 #include "email.h"
38 
43 struct Envelope *mutt_env_new(void)
44 {
45  struct Envelope *env = mutt_mem_calloc(1, sizeof(struct Envelope));
46  TAILQ_INIT(&env->return_path);
47  TAILQ_INIT(&env->from);
48  TAILQ_INIT(&env->to);
49  TAILQ_INIT(&env->cc);
50  TAILQ_INIT(&env->bcc);
51  TAILQ_INIT(&env->sender);
52  TAILQ_INIT(&env->reply_to);
55  STAILQ_INIT(&env->references);
56  STAILQ_INIT(&env->in_reply_to);
57  STAILQ_INIT(&env->userhdrs);
58  return env;
59 }
60 
61 #ifdef USE_AUTOCRYPT
67 {
68  return mutt_mem_calloc(1, sizeof(struct AutocryptHeader));
69 }
70 
76 {
77  if (!p)
78  return;
79 
80  struct AutocryptHeader *cur = NULL;
81 
82  while (*p)
83  {
84  cur = *p;
85  *p = (*p)->next;
86  FREE(&cur->addr);
87  FREE(&cur->keydata);
88  FREE(&cur);
89  }
90 }
91 #endif
92 
97 void mutt_env_free(struct Envelope **ptr)
98 {
99  if (!ptr || !*ptr)
100  return;
101 
102  struct Envelope *env = *ptr;
103 
105  mutt_addrlist_clear(&env->from);
106  mutt_addrlist_clear(&env->to);
107  mutt_addrlist_clear(&env->cc);
108  mutt_addrlist_clear(&env->bcc);
113 
114  FREE(&env->list_post);
115  FREE(&env->list_subscribe);
116  FREE(&env->list_unsubscribe);
117  FREE(&env->subject);
118  /* real_subj is just an offset to subject and shouldn't be freed */
119  FREE(&env->disp_subj);
120  FREE(&env->message_id);
121  FREE(&env->supersedes);
122  FREE(&env->date);
123  FREE(&env->x_label);
124  FREE(&env->organization);
125 #ifdef USE_NNTP
126  FREE(&env->newsgroups);
127  FREE(&env->xref);
128  FREE(&env->followup_to);
129  FREE(&env->x_comment_to);
130 #endif
131 
132  mutt_buffer_dealloc(&env->spam);
133 
134  mutt_list_free(&env->references);
136  mutt_list_free(&env->userhdrs);
137 
138 #ifdef USE_AUTOCRYPT
141 #endif
142 
143  FREE(ptr);
144 }
145 
152 bool mutt_env_notify_send(struct Email *e, enum NotifyEnvelope type)
153 {
154  struct EventEmail ev_e = { 1, &e };
155  return notify_send(e->notify, NT_ENVELOPE, type, &ev_e);
156 }
157 
166 void mutt_env_merge(struct Envelope *base, struct Envelope **extra)
167 {
168  if (!base || !extra || !*extra)
169  return;
170 
171 /* copies each existing element if necessary, and sets the element
172  * to NULL in the source so that mutt_env_free doesn't leave us
173  * with dangling pointers. */
174 #define MOVE_ELEM(member) \
175  if (!base->member) \
176  { \
177  base->member = (*extra)->member; \
178  (*extra)->member = NULL; \
179  }
180 
181 #define MOVE_STAILQ(member) \
182  if (STAILQ_EMPTY(&base->member)) \
183  { \
184  STAILQ_SWAP(&base->member, &(*extra)->member, ListNode); \
185  }
186 
187 #define MOVE_ADDRESSLIST(member) \
188  if (TAILQ_EMPTY(&base->member)) \
189  { \
190  TAILQ_SWAP(&base->member, &(*extra)->member, Address, entries); \
191  }
192 
193 #define MOVE_BUFFER(member) \
194  if (mutt_buffer_is_empty(&base->member)) \
195  { \
196  memcpy(&base->member, &(*extra)->member, sizeof(struct Buffer)); \
197  mutt_buffer_init(&(*extra)->member); \
198  }
199 
200  MOVE_ADDRESSLIST(return_path);
201  MOVE_ADDRESSLIST(from);
202  MOVE_ADDRESSLIST(to);
203  MOVE_ADDRESSLIST(cc);
204  MOVE_ADDRESSLIST(bcc);
205  MOVE_ADDRESSLIST(sender);
206  MOVE_ADDRESSLIST(reply_to);
207  MOVE_ADDRESSLIST(mail_followup_to);
208  MOVE_ELEM(list_post);
209  MOVE_ELEM(list_subscribe);
210  MOVE_ELEM(list_unsubscribe);
211  MOVE_ELEM(message_id);
212  MOVE_ELEM(supersedes);
213  MOVE_ELEM(date);
214  MOVE_ADDRESSLIST(x_original_to);
215  if (!(base->changed & MUTT_ENV_CHANGED_XLABEL))
216  {
217  MOVE_ELEM(x_label);
218  }
219  if (!(base->changed & MUTT_ENV_CHANGED_REFS))
220  {
221  MOVE_STAILQ(references);
222  }
223  if (!(base->changed & MUTT_ENV_CHANGED_IRT))
224  {
225  MOVE_STAILQ(in_reply_to);
226  }
227 
228  /* real_subj is subordinate to subject */
229  if (!base->subject)
230  {
231  base->subject = (*extra)->subject;
232  base->real_subj = (*extra)->real_subj;
233  base->disp_subj = (*extra)->disp_subj;
234  (*extra)->subject = NULL;
235  (*extra)->real_subj = NULL;
236  (*extra)->disp_subj = NULL;
237  }
238  /* spam and user headers should never be hashed, and the new envelope may
239  * have better values. Use new versions regardless. */
240  mutt_buffer_dealloc(&base->spam);
241  mutt_list_free(&base->userhdrs);
242  MOVE_BUFFER(spam);
243  MOVE_STAILQ(userhdrs);
244 #undef MOVE_ELEM
245 #undef MOVE_STAILQ
246 #undef MOVE_ADDRESSLIST
247 #undef MOVE_BUFFER
248 
249  mutt_env_free(extra);
250 }
251 
258 bool mutt_env_cmp_strict(const struct Envelope *e1, const struct Envelope *e2)
259 {
260  if (e1 && e2)
261  {
262  if (!mutt_str_equal(e1->message_id, e2->message_id) ||
263  !mutt_str_equal(e1->subject, e2->subject) ||
264  !mutt_list_compare(&e1->references, &e2->references) ||
265  !mutt_addrlist_equal(&e1->from, &e2->from) ||
266  !mutt_addrlist_equal(&e1->sender, &e2->sender) ||
267  !mutt_addrlist_equal(&e1->reply_to, &e2->reply_to) ||
268  !mutt_addrlist_equal(&e1->to, &e2->to) || !mutt_addrlist_equal(&e1->cc, &e2->cc) ||
270  {
271  return false;
272  }
273  else
274  return true;
275  }
276  else
277  {
278  return (!e1 && !e2);
279  }
280 }
281 
288 void mutt_env_to_local(struct Envelope *env)
289 {
290  if (!env)
291  return;
292 
295  mutt_addrlist_to_local(&env->to);
296  mutt_addrlist_to_local(&env->cc);
300 }
301 
302 /* Note that 'member' in the 'env->member' expression is macro argument, not
303  * "real" name of an 'env' compound member. Real name will be substituted by
304  * preprocessor at the macro-expansion time.
305  * Note that #member escapes and double quotes the argument.
306  */
307 #define H_TO_INTL(member) \
308  if (mutt_addrlist_to_intl(&env->member, err) && (rc == 0)) \
309  { \
310  if (tag) \
311  *tag = #member; \
312  rc = 1; \
313  err = NULL; \
314  }
315 
326 int mutt_env_to_intl(struct Envelope *env, const char **tag, char **err)
327 {
328  if (!env)
329  return 1;
330 
331  int rc = 0;
332  H_TO_INTL(return_path);
333  H_TO_INTL(from);
334  H_TO_INTL(to);
335  H_TO_INTL(cc);
336  H_TO_INTL(bcc);
337  H_TO_INTL(reply_to);
338  H_TO_INTL(mail_followup_to);
339  return rc;
340 }
341 
342 #undef H_TO_INTL
bool mutt_addrlist_equal(const struct AddressList *ala, const struct AddressList *alb)
Compare two Address lists for equality.
Definition: address.c:812
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1470
int mutt_addrlist_to_local(struct AddressList *al)
Convert an Address list from Punycode.
Definition: address.c:1388
Email Address Handling.
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:292
Representation of an email.
int mutt_env_to_intl(struct Envelope *env, const char **tag, char **err)
Convert an Envelope's Address fields to Punycode format.
Definition: envelope.c:326
void mutt_env_merge(struct Envelope *base, struct Envelope **extra)
Merge the headers of two Envelopes.
Definition: envelope.c:166
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:97
#define MOVE_ELEM(member)
#define MOVE_ADDRESSLIST(member)
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:43
void mutt_autocrypthdr_free(struct AutocryptHeader **p)
Free an AutocryptHeader.
Definition: envelope.c:75
#define MOVE_STAILQ(member)
#define H_TO_INTL(member)
Definition: envelope.c:307
#define MOVE_BUFFER(member)
struct AutocryptHeader * mutt_autocrypthdr_new(void)
Create a new AutocryptHeader.
Definition: envelope.c:66
bool mutt_env_notify_send(struct Email *e, enum NotifyEnvelope type)
Send an Envelope change notification.
Definition: envelope.c:152
bool mutt_env_cmp_strict(const struct Envelope *e1, const struct Envelope *e2)
Strictly compare two Envelopes.
Definition: envelope.c:258
void mutt_env_to_local(struct Envelope *env)
Convert an Envelope's Address fields to local format.
Definition: envelope.c:288
Representation of an email header (envelope)
NotifyEnvelope
Types of Envelope Event.
Definition: envelope.h:104
#define MUTT_ENV_CHANGED_XLABEL
X-Label edited.
Definition: envelope.h:36
#define MUTT_ENV_CHANGED_IRT
In-Reply-To changed to link/break threads.
Definition: envelope.h:34
#define MUTT_ENV_CHANGED_REFS
References changed to break thread.
Definition: envelope.h:35
bool mutt_list_compare(const struct ListHead *ah, const struct ListHead *bh)
Compare two string lists.
Definition: list.c:218
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define FREE(x)
Definition: memory.h:43
Convenience wrapper for the library headers.
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
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:784
@ NT_ENVELOPE
Envelope has changed, NotifyEnvelope.
Definition: notify_type.h:45
#define STAILQ_INIT(head)
Definition: queue.h:372
#define TAILQ_INIT(head)
Definition: queue.h:765
Parse Autocrypt header info.
Definition: envelope.h:44
struct AutocryptHeader * next
Linked list.
Definition: envelope.h:49
char * keydata
PGP Key data.
Definition: envelope.h:46
char * addr
Email address.
Definition: envelope.h:45
The envelope/body of an email.
Definition: email.h:37
struct Notify * notify
Notifications: NotifyEmail, EventEmail.
Definition: email.h:71
The header of an Email.
Definition: envelope.h:57
struct ListHead userhdrs
user defined headers
Definition: envelope.h:87
char * supersedes
Supersedes header.
Definition: envelope.h:74
char * list_subscribe
This stores a mailto URL, or nothing.
Definition: envelope.h:68
struct AddressList return_path
Return path for the Email.
Definition: envelope.h:58
struct AddressList to
Email's 'To' list.
Definition: envelope.h:60
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Definition: envelope.h:92
char * followup_to
List of 'followup-to' fields.
Definition: envelope.h:81
struct AddressList reply_to
Email's 'reply-to'.
Definition: envelope.h:64
char * message_id
Message ID.
Definition: envelope.h:73
char * x_comment_to
List of 'X-comment-to' fields.
Definition: envelope.h:82
struct AddressList x_original_to
Email's 'X-Orig-to'.
Definition: envelope.h:66
struct AutocryptHeader * autocrypt_gossip
Autocrypt Gossip header.
Definition: envelope.h:90
char * newsgroups
List of newsgroups.
Definition: envelope.h:79
struct AddressList mail_followup_to
Email's 'mail-followup-to'.
Definition: envelope.h:65
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:61
struct AddressList sender
Email's sender.
Definition: envelope.h:63
struct ListHead references
message references (in reverse order)
Definition: envelope.h:85
struct AutocryptHeader * autocrypt
Autocrypt header.
Definition: envelope.h:89
struct Buffer spam
Spam header.
Definition: envelope.h:84
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:86
char * subject
Email's subject.
Definition: envelope.h:70
struct AddressList bcc
Email's 'Bcc' list.
Definition: envelope.h:62
char * xref
List of cross-references.
Definition: envelope.h:80
char * organization
Organisation header.
Definition: envelope.h:77
char * x_label
X-Label.
Definition: envelope.h:76
char * list_post
This stores a mailto URL, or nothing.
Definition: envelope.h:67
char * date
Sent date.
Definition: envelope.h:75
char * real_subj
Offset of the real subject.
Definition: envelope.h:71
char * disp_subj
Display subject (modified copy of subject)
Definition: envelope.h:72
char * list_unsubscribe
This stores a mailto URL, or nothing.
Definition: envelope.h:69
struct AddressList from
Email's 'From' list.
Definition: envelope.h:59
An Event that happened to an Email.
Definition: email.h:160