NeoMutt  2025-09-05-55-g97fc89
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
envelope.c File Reference

Representation of an email header (envelope) More...

#include "config.h"
#include <stdbool.h>
#include <string.h>
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "envelope.h"
#include "email.h"
+ Include dependency graph for envelope.c:

Go to the source code of this file.

Macros

#define MOVE_ELEM(member)
 
#define MOVE_STAILQ(member)
 
#define MOVE_ADDRESSLIST(member)
 
#define MOVE_BUFFER(member)
 
#define H_TO_INTL(member)
 

Functions

struct Envelopemutt_env_new (void)
 Create a new Envelope.
 
void mutt_env_set_subject (struct Envelope *env, const char *subj)
 Set both subject and real_subj to subj.
 
struct AutocryptHeadermutt_autocrypthdr_new (void)
 Create a new AutocryptHeader.
 
void mutt_autocrypthdr_free (struct AutocryptHeader **ptr)
 Free an AutocryptHeader.
 
void mutt_env_free (struct Envelope **ptr)
 Free an Envelope.
 
bool mutt_env_notify_send (struct Email *e, enum NotifyEnvelope type)
 Send an Envelope change notification.
 
void mutt_env_merge (struct Envelope *base, struct Envelope **extra)
 Merge the headers of two Envelopes.
 
bool mutt_env_cmp_strict (const struct Envelope *e1, const struct Envelope *e2)
 Strictly compare two Envelopes.
 
void mutt_env_to_local (struct Envelope *env)
 Convert an Envelope's Address fields to local format.
 
int mutt_env_to_intl (struct Envelope *env, const char **tag, char **err)
 Convert an Envelope's Address fields to Punycode format.
 

Detailed Description

Representation of an email header (envelope)

Authors
  • Richard Russon
  • Pietro Cerutti
  • наб

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

Macro Definition Documentation

◆ MOVE_ELEM

#define MOVE_ELEM ( member)
Value:
if (!base->member) \
{ \
base->member = (*extra)->member; \
(*extra)->member = NULL; \
}

◆ MOVE_STAILQ

#define MOVE_STAILQ ( member)
Value:
if (STAILQ_EMPTY(&base->member)) \
{ \
STAILQ_SWAP(&base->member, &(*extra)->member, ListNode); \
}
#define STAILQ_EMPTY(head)
Definition queue.h:382
A List node for strings.
Definition list.h:37

◆ MOVE_ADDRESSLIST

#define MOVE_ADDRESSLIST ( member)
Value:
if (TAILQ_EMPTY(&base->member)) \
{ \
TAILQ_SWAP(&base->member, &(*extra)->member, Address, entries); \
}
#define TAILQ_EMPTY(head)
Definition queue.h:778
An email address.
Definition address.h:35

◆ MOVE_BUFFER

#define MOVE_BUFFER ( member)
Value:
if (buf_is_empty(&base->member)) \
{ \
memcpy(&base->member, &(*extra)->member, sizeof(struct Buffer)); \
buf_init(&(*extra)->member); \
}
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:291
String manipulation buffer.
Definition buffer.h:36

◆ H_TO_INTL

#define H_TO_INTL ( member)
Value:
if (mutt_addrlist_to_intl(&env->member, err) && (rc == 0)) \
{ \
if (tag) \
*tag = #member; \
rc = 1; \
err = NULL; \
}
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition address.c:1293

Definition at line 335 of file envelope.c.

335#define H_TO_INTL(member) \
336 if (mutt_addrlist_to_intl(&env->member, err) && (rc == 0)) \
337 { \
338 if (tag) \
339 *tag = #member; \
340 rc = 1; \
341 err = NULL; \
342 }

Function Documentation

◆ mutt_env_new()

struct Envelope * mutt_env_new ( void )

Create a new Envelope.

Return values
ptrNew Envelope

Definition at line 45 of file envelope.c.

46{
47 struct Envelope *env = MUTT_MEM_CALLOC(1, struct Envelope);
49 TAILQ_INIT(&env->from);
50 TAILQ_INIT(&env->to);
51 TAILQ_INIT(&env->cc);
52 TAILQ_INIT(&env->bcc);
53 TAILQ_INIT(&env->sender);
54 TAILQ_INIT(&env->reply_to);
59 STAILQ_INIT(&env->userhdrs);
60 return env;
61}
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:47
#define STAILQ_INIT(head)
Definition queue.h:410
#define TAILQ_INIT(head)
Definition queue.h:822
The header of an Email.
Definition envelope.h:57
struct ListHead userhdrs
user defined headers
Definition envelope.h:85
struct AddressList return_path
Return path for the Email.
Definition envelope.h:58
struct AddressList to
Email's 'To' list.
Definition envelope.h:60
struct AddressList reply_to
Email's 'reply-to'.
Definition envelope.h:64
struct AddressList x_original_to
Email's 'X-Original-to'.
Definition envelope.h:66
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:83
struct ListHead in_reply_to
in-reply-to header content
Definition envelope.h:84
struct AddressList bcc
Email's 'Bcc' list.
Definition envelope.h:62
struct AddressList from
Email's 'From' list.
Definition envelope.h:59
+ Here is the caller graph for this function:

◆ mutt_env_set_subject()

void mutt_env_set_subject ( struct Envelope * env,
const char * subj )

Set both subject and real_subj to subj.

Parameters
envEnvelope
subjSubject

Definition at line 68 of file envelope.c.

69{
70 mutt_str_replace((char **) &env->subject, subj);
71 *(char **) &env->real_subj = NULL;
72
73 if (env->subject)
74 {
75 regmatch_t match;
76 const struct Regex *c_reply_regex = cs_subset_regex(NeoMutt->sub, "reply_regex");
77 if (mutt_regex_capture(c_reply_regex, env->subject, 1, &match))
78 {
79 if (env->subject[match.rm_eo] != '\0')
80 *(char **) &env->real_subj = env->subject + match.rm_eo;
81 }
82 else
83 {
84 *(char **) &env->real_subj = env->subject;
85 }
86 }
87}
const struct Regex * cs_subset_regex(const struct ConfigSubset *sub, const char *name)
Get a regex config item by name.
Definition helpers.c:217
bool mutt_regex_capture(const struct Regex *regex, const char *str, size_t nmatch, regmatch_t matches[])
Match a regex against a string, with provided options.
Definition regex.c:596
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition string.c:282
char *const subject
Email's subject.
Definition envelope.h:70
char *const real_subj
Offset of the real subject.
Definition envelope.h:71
Container for Accounts, Notifications.
Definition neomutt.h:43
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:47
Cached regular expression.
Definition regex3.h:86
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypthdr_new()

struct AutocryptHeader * mutt_autocrypthdr_new ( void )

Create a new AutocryptHeader.

Return values
ptrNew AutocryptHeader

Definition at line 94 of file envelope.c.

95{
96 return MUTT_MEM_CALLOC(1, struct AutocryptHeader);
97}
Parse Autocrypt header info.
Definition envelope.h:44
+ Here is the caller graph for this function:

◆ mutt_autocrypthdr_free()

void mutt_autocrypthdr_free ( struct AutocryptHeader ** ptr)

Free an AutocryptHeader.

Parameters
ptrAutocryptHeader to free

Definition at line 103 of file envelope.c.

104{
105 if (!ptr || !*ptr)
106 return;
107
108 struct AutocryptHeader *cur = NULL;
109
110 while (*ptr)
111 {
112 cur = *ptr;
113 *ptr = (*ptr)->next;
114 FREE(&cur->addr);
115 FREE(&cur->keydata);
116 FREE(&cur);
117 }
118}
#define FREE(x)
Definition memory.h:62
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
+ Here is the caller graph for this function:

◆ mutt_env_free()

void mutt_env_free ( struct Envelope ** ptr)

Free an Envelope.

Parameters
[out]ptrEnvelope to free

Definition at line 125 of file envelope.c.

126{
127 if (!ptr || !*ptr)
128 return;
129
130 struct Envelope *env = *ptr;
131
134 mutt_addrlist_clear(&env->to);
135 mutt_addrlist_clear(&env->cc);
141
142 FREE(&env->list_post);
143 FREE(&env->list_subscribe);
144 FREE(&env->list_unsubscribe);
145 FREE((char **) &env->subject);
146 /* real_subj is just an offset to subject and shouldn't be freed */
147 FREE(&env->disp_subj);
148 FREE(&env->message_id);
149 FREE(&env->supersedes);
150 FREE(&env->date);
151 FREE(&env->x_label);
152 FREE(&env->organization);
153 FREE(&env->newsgroups);
154 FREE(&env->xref);
155 FREE(&env->followup_to);
156 FREE(&env->x_comment_to);
157
158 buf_dealloc(&env->spam);
159
163
164#ifdef USE_AUTOCRYPT
167#endif
168
169 FREE(ptr);
170}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition address.c:1460
void buf_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition buffer.c:377
void mutt_autocrypthdr_free(struct AutocryptHeader **ptr)
Free an AutocryptHeader.
Definition envelope.c:103
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition list.c:123
char * supersedes
Supersedes header.
Definition envelope.h:74
char * list_subscribe
This stores a mailto URL, or nothing.
Definition envelope.h:68
char * followup_to
List of 'followup-to' fields.
Definition envelope.h:80
char * message_id
Message ID.
Definition envelope.h:73
char * x_comment_to
List of 'X-comment-to' fields.
Definition envelope.h:81
struct AutocryptHeader * autocrypt_gossip
Autocrypt Gossip header.
Definition envelope.h:88
char * newsgroups
List of newsgroups.
Definition envelope.h:78
struct AutocryptHeader * autocrypt
Autocrypt header.
Definition envelope.h:87
struct Buffer spam
Spam header.
Definition envelope.h:82
char * xref
List of cross-references.
Definition envelope.h:79
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 * 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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_env_notify_send()

bool mutt_env_notify_send ( struct Email * e,
enum NotifyEnvelope type )

Send an Envelope change notification.

Parameters
eEmail
typeNotification type, e.g. NT_ENVELOPE_SUBJECT
Return values
trueSuccessfully sent

Definition at line 178 of file envelope.c.

179{
180 struct EventEmail ev_e = { 1, &e };
181 return notify_send(e->notify, NT_ENVELOPE, type, &ev_e);
182}
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition notify.c:173
@ NT_ENVELOPE
Envelope has changed, NotifyEnvelope.
Definition notify_type.h:45
struct Notify * notify
Notifications: NotifyEmail, EventEmail.
Definition email.h:73
An Event that happened to an Email.
Definition email.h:196
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_env_merge()

void mutt_env_merge ( struct Envelope * base,
struct Envelope ** extra )

Merge the headers of two Envelopes.

Parameters
[in]baseEnvelope destination for all the headers
[out]extraEnvelope to copy from

Any fields that are missing from base will be copied from extra. extra will be freed afterwards.

Definition at line 192 of file envelope.c.

193{
194 if (!base || !extra || !*extra)
195 return;
196
197/* copies each existing element if necessary, and sets the element
198 * to NULL in the source so that mutt_env_free doesn't leave us
199 * with dangling pointers. */
200#define MOVE_ELEM(member) \
201 if (!base->member) \
202 { \
203 base->member = (*extra)->member; \
204 (*extra)->member = NULL; \
205 }
206
207#define MOVE_STAILQ(member) \
208 if (STAILQ_EMPTY(&base->member)) \
209 { \
210 STAILQ_SWAP(&base->member, &(*extra)->member, ListNode); \
211 }
212
213#define MOVE_ADDRESSLIST(member) \
214 if (TAILQ_EMPTY(&base->member)) \
215 { \
216 TAILQ_SWAP(&base->member, &(*extra)->member, Address, entries); \
217 }
218
219#define MOVE_BUFFER(member) \
220 if (buf_is_empty(&base->member)) \
221 { \
222 memcpy(&base->member, &(*extra)->member, sizeof(struct Buffer)); \
223 buf_init(&(*extra)->member); \
224 }
225
226 MOVE_ADDRESSLIST(return_path);
227 MOVE_ADDRESSLIST(from);
230 MOVE_ADDRESSLIST(bcc);
231 MOVE_ADDRESSLIST(sender);
232 MOVE_ADDRESSLIST(reply_to);
233 MOVE_ADDRESSLIST(mail_followup_to);
234 MOVE_ELEM(list_post);
235 MOVE_ELEM(list_subscribe);
236 MOVE_ELEM(list_unsubscribe);
237 MOVE_ELEM(message_id);
238 MOVE_ELEM(supersedes);
239 MOVE_ELEM(date);
240 MOVE_ADDRESSLIST(x_original_to);
241 if (!(base->changed & MUTT_ENV_CHANGED_XLABEL))
242 {
243 MOVE_ELEM(x_label);
244 }
245 if (!(base->changed & MUTT_ENV_CHANGED_REFS))
246 {
247 MOVE_STAILQ(references);
248 }
249 if (!(base->changed & MUTT_ENV_CHANGED_IRT))
250 {
251 MOVE_STAILQ(in_reply_to);
252 }
253
254 /* real_subj is subordinate to subject */
255 if (!base->subject)
256 {
257 *(char **) &base->subject = (*extra)->subject;
258 *(char **) &base->real_subj = (*extra)->real_subj;
259 base->disp_subj = (*extra)->disp_subj;
260 *(char **) &(*extra)->subject = NULL;
261 *(char **) &(*extra)->real_subj = NULL;
262 (*extra)->disp_subj = NULL;
263 }
264 /* spam and user headers should never be hashed, and the new envelope may
265 * have better values. Use new versions regardless. */
266 buf_dealloc(&base->spam);
267 mutt_list_free(&base->userhdrs);
268 MOVE_BUFFER(spam);
269 MOVE_STAILQ(userhdrs);
270#undef MOVE_ELEM
271#undef MOVE_STAILQ
272#undef MOVE_ADDRESSLIST
273#undef MOVE_BUFFER
274
275 mutt_env_free(extra);
276}
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition envelope.c:125
#define MOVE_ELEM(member)
#define MOVE_ADDRESSLIST(member)
#define MOVE_STAILQ(member)
#define MOVE_BUFFER(member)
#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
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Definition envelope.h:90
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_env_cmp_strict()

bool mutt_env_cmp_strict ( const struct Envelope * e1,
const struct Envelope * e2 )

Strictly compare two Envelopes.

Parameters
e1First Envelope
e2Second Envelope
Return values
trueEnvelopes are strictly identical

Definition at line 284 of file envelope.c.

285{
286 if (e1 && e2)
287 {
288 if (!mutt_str_equal(e1->message_id, e2->message_id) ||
289 !mutt_str_equal(e1->subject, e2->subject) ||
291 !mutt_addrlist_equal(&e1->from, &e2->from) ||
292 !mutt_addrlist_equal(&e1->sender, &e2->sender) ||
294 !mutt_addrlist_equal(&e1->to, &e2->to) || !mutt_addrlist_equal(&e1->cc, &e2->cc) ||
296 {
297 return false;
298 }
299 else
300 {
301 return true;
302 }
303 }
304 else
305 {
306 return (!e1 && !e2);
307 }
308}
bool mutt_addrlist_equal(const struct AddressList *ala, const struct AddressList *alb)
Compare two Address lists for equality.
Definition address.c:840
bool mutt_list_equal(const struct ListHead *ah, const struct ListHead *bh)
Compare two string lists.
Definition list.c:217
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:660
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_env_to_local()

void mutt_env_to_local ( struct Envelope * env)

Convert an Envelope's Address fields to local format.

Parameters
envEnvelope to modify

Run mutt_addrlist_to_local() on each of the Address fields in the Envelope.

Definition at line 316 of file envelope.c.

317{
318 if (!env)
319 return;
320
328}
int mutt_addrlist_to_local(struct AddressList *al)
Convert an Address list from Punycode.
Definition address.c:1378
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_env_to_intl()

int mutt_env_to_intl ( struct Envelope * env,
const char ** tag,
char ** err )

Convert an Envelope's Address fields to Punycode format.

Parameters
[in]envEnvelope to modify
[out]tagName of the failed field
[out]errFailed address
Return values
0Success, all addresses converted
1Error, tag and err will be set

Run mutt_addrlist_to_intl() on each of the Address fields in the Envelope.

Definition at line 354 of file envelope.c.

355{
356 if (!env)
357 return 1;
358
359 int rc = 0;
360 H_TO_INTL(return_path);
361 H_TO_INTL(from);
362 H_TO_INTL(to);
363 H_TO_INTL(cc);
364 H_TO_INTL(bcc);
365 H_TO_INTL(reply_to);
366 H_TO_INTL(mail_followup_to);
367 return rc;
368}
#define H_TO_INTL(member)
Definition envelope.c:335
+ Here is the caller graph for this function: