NeoMutt  2024-10-02-37-gfa9146
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
email.c
Go to the documentation of this file.
1
29#include "config.h"
30#include <stdbool.h>
31#include <stdio.h>
32#include <string.h>
33#include "mutt/lib.h"
34#include "address/lib.h"
35#include "email/lib.h"
36#include "lib.h"
37#include "attach/lib.h"
38#include "ncrypt/lib.h"
39
40void dump_addr_list(char *buf, size_t buflen, const struct AddressList *al, const char *name)
41{
42 if (!buf || !al)
43 return;
44 if (TAILQ_EMPTY(al))
45 return;
46
47 buf[0] = '\0';
48 struct Buffer *tmpbuf = buf_pool_get();
49 mutt_addrlist_write(al, tmpbuf, true);
50 mutt_str_copy(buf, buf_string(tmpbuf), buflen);
51 buf_pool_release(&tmpbuf);
52
53 mutt_debug(LL_DEBUG1, "\t%s: %s\n", name, buf);
54}
55
56void dump_list_head(const struct ListHead *list, const char *name)
57{
58 if (!list || !name)
59 return;
60 if (STAILQ_EMPTY(list))
61 return;
62
63 struct Buffer *buf = buf_pool_get();
64
65 struct ListNode *np = NULL;
66 STAILQ_FOREACH(np, list, entries)
67 {
68 if (!buf_is_empty(buf))
69 buf_addch(buf, ',');
70 buf_addstr(buf, np->data);
71 }
72
73 mutt_debug(LL_DEBUG1, "\t%s: %s\n", name, buf_string(buf));
74 buf_pool_release(&buf);
75}
76
77void dump_envelope(const struct Envelope *env)
78{
79 mutt_debug(LL_DEBUG1, "Envelope\n");
80
81 if (!env)
82 {
83 mutt_debug(LL_DEBUG1, "\tNULL pointer\n");
84 return;
85 }
86
87 struct Buffer *buf = buf_pool_get();
88 char arr[1024];
89
90#define ADD_FLAG(F) add_flag(buf, (env->changed & F), #F)
95#undef ADD_FLAG
96 mutt_debug(LL_DEBUG1, "\tchanged: %s\n", buf_is_empty(buf) ? "[NONE]" : buf_string(buf));
97
98#define ADDR_LIST(AL) dump_addr_list(arr, sizeof(arr), &env->AL, #AL)
99 ADDR_LIST(return_path);
100 ADDR_LIST(from);
101 ADDR_LIST(to);
102 ADDR_LIST(cc);
103 ADDR_LIST(bcc);
104 ADDR_LIST(sender);
105 ADDR_LIST(reply_to);
106 ADDR_LIST(mail_followup_to);
107 ADDR_LIST(x_original_to);
108#undef ADDR_LIST
109
110#define OPT_STRING(S) \
111 if (env->S) \
112 mutt_debug(LL_DEBUG1, "\t%s: %s\n", #S, env->S)
113 OPT_STRING(list_post);
114 OPT_STRING(list_subscribe);
115 OPT_STRING(list_unsubscribe);
116 OPT_STRING(subject);
117 OPT_STRING(real_subj);
118 OPT_STRING(disp_subj);
119 OPT_STRING(message_id);
120 OPT_STRING(supersedes);
121 OPT_STRING(date);
122 OPT_STRING(x_label);
123 OPT_STRING(organization);
124 OPT_STRING(newsgroups);
125 OPT_STRING(xref);
126 OPT_STRING(followup_to);
127 OPT_STRING(x_comment_to);
128#undef OPT_STRING
129
130 dump_list_head(&env->references, "references");
131 dump_list_head(&env->in_reply_to, "in_reply_to");
132 dump_list_head(&env->userhdrs, "userhdrs");
133
134 if (!buf_is_empty(&env->spam))
135 mutt_debug(LL_DEBUG1, "\tspam: %s\n", buf_string(&env->spam));
136
137#ifdef USE_AUTOCRYPT
138 if (env->autocrypt)
139 mutt_debug(LL_DEBUG1, "\tautocrypt: %p\n", (void *) env->autocrypt);
140 if (env->autocrypt_gossip)
141 mutt_debug(LL_DEBUG1, "\tautocrypt_gossip: %p\n", (void *) env->autocrypt_gossip);
142#endif
143
144 buf_pool_release(&buf);
145}
146
147void dump_email(const struct Email *e)
148{
149 mutt_debug(LL_DEBUG1, "Email\n");
150
151 if (!e)
152 {
153 mutt_debug(LL_DEBUG1, "\tNULL pointer\n");
154 return;
155 }
156
157 struct Buffer *buf = buf_pool_get();
158 char arr[256];
159
160 mutt_debug(LL_DEBUG1, "\tpath: %s\n", e->path);
161
162#define ADD_FLAG(F) add_flag(buf, e->F, #F)
163 ADD_FLAG(active);
164 ADD_FLAG(attach_del);
165 ADD_FLAG(attach_valid);
166 ADD_FLAG(changed);
167 ADD_FLAG(collapsed);
168 ADD_FLAG(deleted);
169 ADD_FLAG(display_subject);
170 ADD_FLAG(expired);
171 ADD_FLAG(flagged);
172 ADD_FLAG(matched);
173 ADD_FLAG(mime);
174 ADD_FLAG(old);
175 ADD_FLAG(purge);
176 ADD_FLAG(quasi_deleted);
177 ADD_FLAG(read);
178 ADD_FLAG(recip_valid);
179 ADD_FLAG(replied);
180 ADD_FLAG(searched);
181 ADD_FLAG(subject_changed);
182 ADD_FLAG(superseded);
183 ADD_FLAG(tagged);
184 ADD_FLAG(threaded);
185 ADD_FLAG(trash);
186 ADD_FLAG(visible);
187#undef ADD_FLAG
188 mutt_debug(LL_DEBUG1, "\tFlags: %s\n", buf_is_empty(buf) ? "[NONE]" : buf_string(buf));
189
190#define ADD_FLAG(F) add_flag(buf, (e->security & F), #F)
191 buf_reset(buf);
206#undef ADD_FLAG
207 mutt_debug(LL_DEBUG1, "\tSecurity: %s\n", buf_is_empty(buf) ? "[NONE]" : buf_string(buf));
208
209 mutt_date_make_tls(arr, sizeof(arr), e->date_sent);
210 mutt_debug(LL_DEBUG1, "\tSent: %s (%c%02u%02u)\n", arr,
211 e->zoccident ? '-' : '+', e->zhours, e->zminutes);
212
213 mutt_date_make_tls(arr, sizeof(arr), e->received);
214 mutt_debug(LL_DEBUG1, "\tRecv: %s\n", arr);
215
216 buf_pool_release(&buf);
217
218 mutt_debug(LL_DEBUG1, "\tnum_hidden: %ld\n", e->num_hidden);
219 mutt_debug(LL_DEBUG1, "\trecipient: %d\n", e->recipient);
220 mutt_debug(LL_DEBUG1, "\toffset: %ld\n", e->offset);
221 mutt_debug(LL_DEBUG1, "\tlines: %d\n", e->lines);
222 mutt_debug(LL_DEBUG1, "\tindex: %d\n", e->index);
223 mutt_debug(LL_DEBUG1, "\tmsgno: %d\n", e->msgno);
224 mutt_debug(LL_DEBUG1, "\tvnum: %d\n", e->vnum);
225 mutt_debug(LL_DEBUG1, "\tscore: %d\n", e->score);
226 mutt_debug(LL_DEBUG1, "\tattach_total: %d\n", e->attach_total);
227 // if (e->maildir_flags)
228 // mutt_debug(LL_DEBUG1, "\tmaildir_flags: %s\n", e->maildir_flags);
229
230 // struct MuttThread *thread
231 // struct Envelope *env
232 // struct Body *content
233 // struct TagList tags
234
235 // void *edata
236}
237
238void dump_param_list(const struct ParameterList *pl)
239{
240 mutt_debug(LL_DEBUG1, "\tparameters\n");
241
242 if (!pl)
243 {
244 mutt_debug(LL_DEBUG1, "\tNULL pointer\n");
245 return;
246 }
247
248 if (TAILQ_EMPTY(pl))
249 {
250 mutt_debug(LL_DEBUG1, "\tempty\n");
251 return;
252 }
253
254 struct Parameter *np = NULL;
255 TAILQ_FOREACH(np, pl, entries)
256 {
257 mutt_debug(LL_DEBUG1, "\t\t%s = %s\n", NONULL(np->attribute), NONULL(np->value));
258 }
259}
260
261void dump_body(const struct Body *body)
262{
263 mutt_debug(LL_DEBUG1, "Body\n");
264
265 if (!body)
266 {
267 mutt_debug(LL_DEBUG1, "\tNULL pointer\n");
268 return;
269 }
270
271 struct Buffer *buf = buf_pool_get();
272 char arr[256];
273
274#define ADD_FLAG(F) add_flag(buf, body->F, #F)
275 ADD_FLAG(attach_qualifies);
276 ADD_FLAG(badsig);
277 ADD_FLAG(deleted);
278 ADD_FLAG(force_charset);
279 ADD_FLAG(goodsig);
280#ifdef USE_AUTOCRYPT
281 ADD_FLAG(is_autocrypt);
282#endif
283 ADD_FLAG(noconv);
284 ADD_FLAG(tagged);
285 ADD_FLAG(unlink);
286 ADD_FLAG(use_disp);
287 ADD_FLAG(warnsig);
288#undef ADD_FLAG
289 mutt_debug(LL_DEBUG1, "\tFlags: %s\n", buf_is_empty(buf) ? "[NONE]" : buf_string(buf));
290
291#define OPT_STRING(S) \
292 if (body->S) \
293 mutt_debug(LL_DEBUG1, "\t%s: %s\n", #S, body->S)
294 OPT_STRING(charset);
295 OPT_STRING(description);
296 OPT_STRING(d_filename);
297 OPT_STRING(filename);
298 OPT_STRING(form_name);
299 OPT_STRING(language);
300 OPT_STRING(subtype);
301 OPT_STRING(xtype);
302#undef OPT_STRING
303
304 mutt_debug(LL_DEBUG1, "\thdr_offset: %ld\n", body->hdr_offset);
305 mutt_debug(LL_DEBUG1, "\toffset: %ld\n", body->offset);
306 mutt_debug(LL_DEBUG1, "\tlength: %ld\n", body->length);
307 mutt_debug(LL_DEBUG1, "\tattach_count: %d\n", body->attach_count);
308
309 mutt_debug(LL_DEBUG1, "\tcontent type: %s\n", name_content_type(body->type));
310 mutt_debug(LL_DEBUG1, "\tcontent encoding: %s\n", name_content_encoding(body->encoding));
311 mutt_debug(LL_DEBUG1, "\tcontent disposition: %s\n",
313
314 if (body->stamp != 0)
315 {
316 mutt_date_make_tls(arr, sizeof(arr), body->stamp);
317 mutt_debug(LL_DEBUG1, "\tstamp: %s\n", arr);
318 }
319
321
322 // struct Content *content; ///< Detailed info about the content of the attachment.
323 // struct Body *next; ///< next attachment in the list
324 // struct Body *parts; ///< parts of a multipart or message/rfc822
325 // struct Email *email; ///< header information for message/rfc822
326 // struct AttachPtr *aptr; ///< Menu information, used in recvattach.c
327 // struct Envelope *mime_headers; ///< Memory hole protected headers
328
329 if (body->next)
330 {
331 mutt_debug(LL_DEBUG1, "-NEXT-------------------------\n");
332 dump_body(body->next);
333 }
334 if (body->parts)
335 {
336 mutt_debug(LL_DEBUG1, "-PARTS-------------------------\n");
337 dump_body(body->parts);
338 }
339 if (body->next || body->parts)
340 mutt_debug(LL_DEBUG1, "--------------------------\n");
341 buf_pool_release(&buf);
342}
343
344void dump_attach(const struct AttachPtr *att)
345{
346 mutt_debug(LL_DEBUG1, "AttachPtr\n");
347
348 if (!att)
349 {
350 mutt_debug(LL_DEBUG1, "\tNULL pointer\n");
351 return;
352 }
353
354 struct Buffer *buf = buf_pool_get();
355
356#define ADD_FLAG(F) add_flag(buf, att->F, #F)
357 ADD_FLAG(unowned);
358 ADD_FLAG(decrypted);
359 ADD_FLAG(collapsed);
360#undef ADD_FLAG
361
362 if (att->fp)
363 mutt_debug(LL_DEBUG1, "\tfp: %p (%d)\n", (void *) att->fp, fileno(att->fp));
364 mutt_debug(LL_DEBUG1, "\tparent_type: %d\n", att->parent_type);
365 mutt_debug(LL_DEBUG1, "\tlevel: %d\n", att->level);
366 mutt_debug(LL_DEBUG1, "\tnum: %d\n", att->num);
367
368 // struct Body *content; ///< Attachment
369 buf_pool_release(&buf);
370}
371
372char body_name(const struct Body *b)
373{
374 if (!b)
375 return '!';
376
377 if (b->type == TYPE_MULTIPART)
378 return '&';
379
380 if (b->description)
381 return b->description[0];
382
383 if (b->filename)
384 {
385 const char *base = basename(b->filename);
386 if (mutt_str_startswith(base, "neomutt-"))
387 return '0';
388
389 return base[0];
390 }
391
392 return '!';
393}
394
395void dump_body_next(struct Buffer *buf, const struct Body *b)
396{
397 if (!b)
398 return;
399
400 buf_addstr(buf, "<");
401 for (; b; b = b->next)
402 {
403 buf_add_printf(buf, "%c", body_name(b));
404 dump_body_next(buf, b->parts);
405 if (b->next)
406 buf_addch(buf, ',');
407 }
408 buf_addstr(buf, ">");
409}
410
411void dump_body_one_line(const struct Body *b)
412{
413 if (!b)
414 return;
415
416 struct Buffer *buf = buf_pool_get();
417 buf_addstr(buf, "Body layout: ");
418 dump_body_next(buf, b);
419
420 mutt_message("%s", buf_string(buf));
421 buf_pool_release(&buf);
422}
size_t mutt_addrlist_write(const struct AddressList *al, struct Buffer *buf, bool display)
Write an Address to a buffer.
Definition: address.c:1206
Email Address Handling.
GUI display the mailboxes in a side panel.
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:204
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:76
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:291
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:241
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:226
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
void dump_list_head(const struct ListHead *list, const char *name)
Definition: email.c:56
#define OPT_STRING(S)
void dump_email(const struct Email *e)
Definition: email.c:147
#define ADDR_LIST(AL)
void dump_body_next(struct Buffer *buf, const struct Body *b)
Definition: email.c:395
void dump_attach(const struct AttachPtr *att)
Definition: email.c:344
void dump_param_list(const struct ParameterList *pl)
Definition: email.c:238
void dump_envelope(const struct Envelope *env)
Definition: email.c:77
#define ADD_FLAG(F)
void dump_body_one_line(const struct Body *b)
Definition: email.c:411
char body_name(const struct Body *b)
Definition: email.c:372
void dump_body(const struct Body *body)
Definition: email.c:261
void dump_addr_list(char *buf, size_t buflen, const struct AddressList *al, const char *name)
Definition: email.c:40
const char * name_content_encoding(enum ContentEncoding enc)
Definition: names.c:65
const char * name_content_type(enum ContentType type)
Definition: names.c:47
const char * name_content_disposition(enum ContentDisposition disp)
Definition: names.c:80
Structs that make up an email.
#define MUTT_ENV_CHANGED_SUBJECT
Protected header update.
Definition: envelope.h:37
#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
#define mutt_message(...)
Definition: logging2.h:91
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
@ TYPE_MULTIPART
Type: 'multipart/*'.
Definition: mime.h:37
int mutt_date_make_tls(char *buf, size_t buflen, time_t timestamp)
Format date in TLS certificate verification style.
Definition: date.c:837
Convenience wrapper for the library headers.
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:230
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:581
API for encryption/signing of emails.
#define SEC_INLINE
Email has an inline signature.
Definition: lib.h:85
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:87
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: lib.h:86
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: lib.h:92
#define SEC_GOODSIGN
Email has a valid signature.
Definition: lib.h:80
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:90
#define SEC_SIGNOPAQUE
Email has an opaque signature (encrypted)
Definition: lib.h:83
#define SEC_BADSIGN
Email has a bad signature.
Definition: lib.h:81
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:91
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: lib.h:82
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:78
#define SEC_AUTOCRYPT_OVERRIDE
(Autocrypt) Indicates manual set/unset of encryption
Definition: lib.h:88
#define SEC_SIGN
Email is signed.
Definition: lib.h:79
#define SEC_KEYBLOCK
Email has a key attached.
Definition: lib.h:84
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_EMPTY(head)
Definition: queue.h:348
#define TAILQ_EMPTY(head)
Definition: queue.h:721
Key value store.
#define NONULL(x)
Definition: string2.h:37
An email to which things will be attached.
Definition: attach.h:37
int num
Attachment index number.
Definition: attach.h:43
int level
Nesting depth of attachment.
Definition: attach.h:42
FILE * fp
Used in the recvattach menu.
Definition: attach.h:39
int parent_type
Type of parent attachment, e.g. TYPE_MULTIPART.
Definition: attach.h:40
The body of an email.
Definition: body.h:36
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:73
LOFF_T offset
offset where the actual data begins
Definition: body.h:52
signed short attach_count
Number of attachments.
Definition: body.h:91
time_t stamp
Time stamp of last encoding update.
Definition: body.h:77
LOFF_T length
length (in bytes) of attachment
Definition: body.h:53
struct ParameterList parameter
Parameters of the content-type.
Definition: body.h:63
char * description
content-description
Definition: body.h:55
unsigned int disposition
content-disposition, ContentDisposition
Definition: body.h:42
struct Body * next
next attachment in the list
Definition: body.h:72
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition: body.h:41
long hdr_offset
Offset in stream where the headers begin.
Definition: body.h:81
unsigned int type
content-type primary type, ContentType
Definition: body.h:40
char * filename
When sending a message, this is the file to which this structure refers.
Definition: body.h:59
String manipulation buffer.
Definition: buffer.h:36
The envelope/body of an email.
Definition: email.h:39
unsigned int zminutes
Minutes away from UTC.
Definition: email.h:57
int lines
How many lines in the body of this message?
Definition: email.h:62
size_t num_hidden
Number of hidden messages in this view (only valid when collapsed is set)
Definition: email.h:123
bool zoccident
True, if west of UTC, False if east.
Definition: email.h:58
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:71
short attach_total
Number of qualifying attachments in message, if attach_valid.
Definition: email.h:115
unsigned int zhours
Hours away from UTC.
Definition: email.h:56
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:60
int vnum
Virtual message number.
Definition: email.h:114
int score
Message score.
Definition: email.h:113
int msgno
Number displayed to the user.
Definition: email.h:111
char * path
Path of Email (for local Mailboxes)
Definition: email.h:70
int index
The absolute (unsorted) message number.
Definition: email.h:110
short recipient
User_is_recipient()'s return value, cached.
Definition: email.h:116
time_t received
Time when the message was placed in the mailbox.
Definition: email.h:61
The header of an Email.
Definition: envelope.h:57
struct ListHead userhdrs
user defined headers
Definition: envelope.h:85
struct AutocryptHeader * autocrypt_gossip
Autocrypt Gossip header.
Definition: envelope.h:88
struct ListHead references
message references (in reverse order)
Definition: envelope.h:83
struct AutocryptHeader * autocrypt
Autocrypt header.
Definition: envelope.h:87
struct Buffer spam
Spam header.
Definition: envelope.h:82
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:84
A List node for strings.
Definition: list.h:37
char * data
String.
Definition: list.h:38
Attribute associated with a MIME part.
Definition: parameter.h:33
char * attribute
Parameter name.
Definition: parameter.h:34
char * value
Parameter value.
Definition: parameter.h:35