NeoMutt  2023-05-17-16-g61469c
Teaching an old dog new tricks
DOXYGEN
graphviz.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 <sys/stat.h>
34#include <time.h>
35#include "mutt/lib.h"
36#include "address/lib.h"
37#include "config/lib.h"
38#include "email/lib.h"
39#include "core/lib.h"
40#include "conn/lib.h"
41#include "lib.h"
42#include "attach/lib.h"
43#include "compmbox/lib.h"
44#include "imap/lib.h"
45#include "maildir/lib.h"
46#include "mbox/lib.h"
47#include "ncrypt/lib.h"
48#include "nntp/lib.h"
49#include "notmuch/lib.h"
50#include "pattern/lib.h"
51#include "pop/lib.h"
52#include "imap/adata.h" // IWYU pragma: keep
53#include "imap/mdata.h" // IWYU pragma: keep
54#include "imap/private.h" // IWYU pragma: keep
55#include "maildir/edata.h" // IWYU pragma: keep
56#include "maildir/mdata.h" // IWYU pragma: keep
57#include "maildir/private.h" // IWYU pragma: keep
58#include "mview.h"
59#include "nntp/adata.h" // IWYU pragma: keep
60#include "nntp/mdata.h" // IWYU pragma: keep
61#include "notmuch/adata.h" // IWYU pragma: keep
62#include "notmuch/mdata.h" // IWYU pragma: keep
63#include "notmuch/private.h" // IWYU pragma: keep
64#include "pop/adata.h" // IWYU pragma: keep
65#include "pop/private.h" // IWYU pragma: keep
66
67// #define GV_HIDE_MVIEW
68#define GV_HIDE_MVIEW_CONTENTS
69// #define GV_HIDE_MBOX
70// #define GV_HIDE_NEOMUTT
71// #define GV_HIDE_CONFIG
72// #define GV_HIDE_ADATA
73// #define GV_HIDE_MDATA
74// #define GV_HIDE_BODY_CONTENT
75// #define GV_HIDE_ENVELOPE
76
77void dot_email(FILE *fp, struct Email *e, struct ListHead *links);
78void dot_envelope(FILE *fp, struct Envelope *env, struct ListHead *links);
79void dot_patternlist(FILE *fp, struct PatternList *pl, struct ListHead *links);
80
81void dot_type_bool(FILE *fp, const char *name, bool val)
82{
83 static const char *values[] = { "false", "true" };
84 fprintf(fp, "\t\t<tr>\n");
85 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">%s</td>\n", name);
86 fprintf(fp, "\t\t\t<td border=\"0\">=</td>\n");
87 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">%s</td>\n", values[val]);
88 fprintf(fp, "\t\t</tr>\n");
89}
90
91#ifndef GV_HIDE_ADATA
92void dot_type_char(FILE *fp, const char *name, char ch)
93{
94 fprintf(fp, "\t\t<tr>\n");
95 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">%s</td>\n", name);
96 fprintf(fp, "\t\t\t<td border=\"0\">=</td>\n");
97 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">%c</td>\n", ch);
98 fprintf(fp, "\t\t</tr>\n");
99}
100#endif
101
102void dot_type_date(char *buf, size_t buflen, time_t timestamp)
103{
104 mutt_date_localtime_format(buf, buflen, "%Y-%m-%d %H:%M:%S", timestamp);
105}
106
107void dot_type_file(FILE *fp, const char *name, FILE *struct_fp)
108{
109 fprintf(fp, "\t\t<tr>\n");
110 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">%s</td>\n", name);
111 fprintf(fp, "\t\t\t<td border=\"0\">=</td>\n");
112 if (struct_fp)
113 {
114 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">%p (%d)</td>\n",
115 (void *) struct_fp, fileno(struct_fp));
116 }
117 else
118 {
119 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">NULL</td>\n");
120 }
121 fprintf(fp, "\t\t</tr>\n");
122}
123
124void dot_type_number(FILE *fp, const char *name, int num)
125{
126 fprintf(fp, "\t\t<tr>\n");
127 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">%s</td>\n", name);
128 fprintf(fp, "\t\t\t<td border=\"0\">=</td>\n");
129 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">%d</td>\n", num);
130 fprintf(fp, "\t\t</tr>\n");
131}
132
133void dot_type_string_escape(char *buf, size_t buflen)
134{
135 for (; buf[0]; buf++)
136 {
137 if (buf[0] == '<')
138 mutt_str_inline_replace(buf, buflen, 1, "&lt;");
139 else if (buf[0] == '>')
140 mutt_str_inline_replace(buf, buflen, 1, "&gt;");
141 else if (buf[0] == '&')
142 mutt_str_inline_replace(buf, buflen, 1, "&amp;");
143 }
144}
145
146void dot_type_string(FILE *fp, const char *name, const char *str, bool force)
147{
148 if ((!str || (str[0] == '\0')) && !force)
149 return;
150
151 char buf[1024] = "[NULL]";
152
153 if (str)
154 {
155 mutt_str_copy(buf, str, sizeof(buf));
156 dot_type_string_escape(buf, sizeof(buf));
157 }
158
159 bool quoted = ((buf[0] != '[') && (buf[0] != '*'));
160
161 fprintf(fp, "\t\t<tr>\n");
162 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">%s</td>\n", name);
163 fprintf(fp, "\t\t\t<td border=\"0\">=</td>\n");
164 if (quoted)
165 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">\"%s\"</td>\n", buf);
166 else
167 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">%s</td>\n", buf);
168 fprintf(fp, "\t\t</tr>\n");
169}
170
171#ifndef GV_HIDE_MDATA
172void dot_type_umask(char *buf, size_t buflen, int umask)
173{
174 snprintf(buf, buflen, "0%03o", umask);
175}
176#endif
177
178void dot_ptr_name(char *buf, size_t buflen, const void *ptr)
179{
180 snprintf(buf, buflen, "obj_%p", ptr);
181}
182
183void dot_ptr(FILE *fp, const char *name, void *ptr, const char *colour)
184{
185 fprintf(fp, "\t\t<tr>\n");
186 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">%s</td>\n", name);
187 fprintf(fp, "\t\t\t<td border=\"0\">=</td>\n");
188 if (colour && ptr)
189 {
190 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\" bgcolor=\"%s\">%p</td>\n",
191 colour, ptr);
192 }
193 else
194 {
195 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">%p</td>\n", ptr);
196 }
197 fprintf(fp, "\t\t</tr>\n");
198}
199
200void dot_add_link(struct ListHead *links, void *src, void *dst,
201 const char *label, bool back, const char *colour)
202{
203 if (!src || !dst)
204 return;
205 if (!colour)
206 colour = "#c0c0c0";
207
208 char obj1[64] = { 0 };
209 char obj2[64] = { 0 };
210 char text[256] = { 0 };
211 char lstr[128] = { 0 };
212
213 dot_ptr_name(obj1, sizeof(obj1), src);
214 dot_ptr_name(obj2, sizeof(obj2), dst);
215
216 if (label)
217 snprintf(lstr, sizeof(lstr), "edgetooltip=\"%s\"", label);
218
219 snprintf(text, sizeof(text), "%s -> %s [ %s %s color=\"%s\" ]", obj1, obj2,
220 back ? "dir=back" : "", lstr, colour);
222}
223
224void dot_graph_header(FILE *fp)
225{
226 fprintf(fp, "digraph neomutt\n");
227 fprintf(fp, "{\n\n");
228
229 fprintf(fp, "\tgraph [\n");
230 fprintf(fp, "\t\trankdir=\"TB\"\n");
231 fprintf(fp, "\t\tnodesep=\"0.5\"\n");
232 fprintf(fp, "\t\tranksep=\"0.5\"\n");
233 fprintf(fp, "\t];\n");
234 fprintf(fp, "\n");
235 fprintf(fp, "\tnode [\n");
236 fprintf(fp, "\t\tshape=\"plain\"\n");
237 fprintf(fp, "\t];\n");
238 fprintf(fp, "\n");
239 fprintf(fp, "\tedge [\n");
240 fprintf(fp, "\t\tpenwidth=\"4.5\"\n");
241 fprintf(fp, "\t\tarrowsize=\"1.0\"\n");
242 fprintf(fp, "\t\tcolor=\"#c0c0c0\"\n");
243 fprintf(fp, "\t];\n");
244 fprintf(fp, "\n");
245}
246
247void dot_graph_footer(FILE *fp, struct ListHead *links)
248{
249 fprintf(fp, "\n");
250 struct ListNode *np = NULL;
251 STAILQ_FOREACH(np, links, entries)
252 {
253 fprintf(fp, "\t%s;\n", np->data);
254 }
255 fprintf(fp, "\n}\n");
256}
257
258void dot_object_header(FILE *fp, const void *ptr, const char *name, const char *colour)
259{
260 char obj[64] = { 0 };
261 dot_ptr_name(obj, sizeof(obj), ptr);
262
263 if (!colour)
264 colour = "#ffff80";
265
266 fprintf(fp, "\t%s [\n", obj);
267 fprintf(fp, "\t\tlabel=<<table cellspacing=\"0\" border=\"1\" rows=\"*\" "
268 "color=\"#d0d0d0\">\n");
269 fprintf(fp, "\t\t<tr>\n");
270 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\" bgcolor=\"%s\" port=\"top\" colspan=\"3\"><font color=\"#000000\" point-size=\"20\"><b>%s</b></font> <font point-size=\"12\">(%p)</font></td>\n",
271 colour, name, ptr);
272 fprintf(fp, "\t\t</tr>\n");
273}
274
275void dot_object_footer(FILE *fp)
276{
277 fprintf(fp, "\t\t</table>>\n");
278 fprintf(fp, "\t];\n");
279 fprintf(fp, "\n");
280}
281
282void dot_node(FILE *fp, void *ptr, const char *name, const char *colour)
283{
284 char obj[64] = { 0 };
285 dot_ptr_name(obj, sizeof(obj), ptr);
286
287 fprintf(fp, "\t%s [\n", obj);
288 fprintf(fp, "\t\tlabel=<<table cellspacing=\"0\" border=\"1\" rows=\"*\" "
289 "color=\"#d0d0d0\">\n");
290 fprintf(fp, "\t\t<tr>\n");
291 fprintf(fp, "\t\t\t<td border=\"0\" bgcolor=\"%s\" port=\"top\"><font color=\"#000000\" point-size=\"20\"><b>%s</b></font></td>\n",
292 colour, name);
293 fprintf(fp, "\t\t</tr>\n");
295}
296
297void dot_node_link(FILE *fp, void *ptr, const char *name, void *link, const char *colour)
298{
299 char obj[64] = { 0 };
300 dot_ptr_name(obj, sizeof(obj), ptr);
301
302 fprintf(fp, "\t%s [\n", obj);
303 fprintf(fp, "\t\tlabel=<<table cellspacing=\"0\" border=\"1\" rows=\"*\" "
304 "color=\"#d0d0d0\">\n");
305 fprintf(fp, "\t\t<tr>\n");
306 fprintf(fp, "\t\t\t<td border=\"0\" bgcolor=\"%s\" port=\"top\"><font color=\"#000000\" point-size=\"20\"><b>%s</b></font></td>\n",
307 colour, name);
308 fprintf(fp, "\t\t</tr>\n");
309
310 fprintf(fp, "\t\t<tr>\n");
311 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\" bgcolor=\"%s\">%p</td>\n", colour, link);
312 fprintf(fp, "\t\t</tr>\n");
313
315}
316
317void dot_path_fs(char *buf, size_t buflen, const char *path)
318{
319 if (!path)
320 {
321 buf[0] = '\0';
322 return;
323 }
324
325 const char *slash = strrchr(path, '/');
326 if (slash)
327 slash++;
328 else
329 slash = path;
330
331 mutt_str_copy(buf, slash, buflen);
332}
333
334void dot_path_imap(char *buf, size_t buflen, const char *path)
335{
336 char tmp[1024] = { 0 };
337 mutt_str_copy(tmp, path, sizeof(tmp));
338
339 struct Url *u = url_parse(tmp);
340
341 if (u->path && (u->path[0] != '\0'))
342 mutt_str_copy(buf, u->path, buflen);
343 else
344 snprintf(buf, buflen, "%s:%s", u->host, u->user);
345
346 url_free(&u);
347}
348
349#ifndef GV_HIDE_CONFIG
350void dot_config(FILE *fp, const char *name, int type, struct ConfigSubset *sub,
351 struct ListHead *links)
352{
353 if (!sub)
354 return;
355
356 struct Buffer value = buf_make(256);
357 dot_object_header(fp, (void *) name, "Config", "#ffff80");
358 dot_type_string(fp, "scope", sub->name, true);
359
360 if (sub->name)
361 {
362 char scope[256];
363 snprintf(scope, sizeof(scope), "%s:", sub->name);
364
365 struct HashElem **list = get_elem_list(sub->cs);
366 for (size_t i = 0; list[i]; i++)
367 {
368 struct HashElem *item = list[i];
369 if ((item->type & type) == 0)
370 continue;
371
372 const char *iname = item->key.strkey;
373 size_t slen = strlen(scope);
374 if (mutt_str_startswith(iname, scope) != 0)
375 {
376 if (strchr(iname + slen, ':'))
377 continue;
378 if ((DTYPE(item->type) == DT_STRING) && (item->type & DT_SENSITIVE))
379 {
380 dot_type_string(fp, iname + slen, "***", true);
381 }
382 else
383 {
384 buf_reset(&value);
385 cs_subset_he_string_get(sub, item, &value);
386 dot_type_string(fp, iname + slen, value.data, true);
387 }
388 }
389 }
390 FREE(&list);
391 }
392 else
393 {
394 struct HashElem **list = get_elem_list(sub->cs);
395 int i = 0;
396 for (; list[i]; i++)
397 ; // do nothing
398
399 dot_type_number(fp, "count", i);
400 FREE(&list);
401 }
402
404 buf_dealloc(&value);
405}
406#endif
407
408void dot_comp(FILE *fp, struct CompressInfo *ci, struct ListHead *links)
409{
410 dot_object_header(fp, ci, "CompressInfo", "#c0c060");
411 dot_type_string(fp, "append", ci->cmd_append, true);
412 dot_type_string(fp, "close", ci->cmd_close, true);
413 dot_type_string(fp, "open", ci->cmd_open, true);
415}
416
417void dot_mailbox_type(FILE *fp, const char *name, enum MailboxType type)
418{
419 const char *typestr = NULL;
420
421 switch (type)
422 {
423 case MUTT_MBOX:
424 typestr = "MBOX";
425 break;
426 case MUTT_MMDF:
427 typestr = "MMDF";
428 break;
429 case MUTT_MH:
430 typestr = "MH";
431 break;
432 case MUTT_MAILDIR:
433 typestr = "MAILDIR";
434 break;
435 case MUTT_NNTP:
436 typestr = "NNTP";
437 break;
438 case MUTT_IMAP:
439 typestr = "IMAP";
440 break;
441 case MUTT_NOTMUCH:
442 typestr = "NOTMUCH";
443 break;
444 case MUTT_POP:
445 typestr = "POP";
446 break;
447 case MUTT_COMPRESSED:
448 typestr = "COMPRESSED";
449 break;
450 default:
451 typestr = "UNKNOWN";
452 }
453
454 fprintf(fp, "\t\t<tr>\n");
455 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">%s</td>\n", name);
456 fprintf(fp, "\t\t\t<td border=\"0\">=</td>\n");
457 fprintf(fp, "\t\t\t<td border=\"0\" align=\"left\">%s</td>\n", typestr);
458 fprintf(fp, "\t\t</tr>\n");
459}
460
461#ifndef GV_HIDE_MDATA
462void dot_mailbox_imap(FILE *fp, struct ImapMboxData *mdata, struct ListHead *links)
463{
464 dot_object_header(fp, mdata, "ImapMboxData", "#60c060");
465 dot_type_string(fp, "name", mdata->name, true);
466 dot_type_string(fp, "munge_name", mdata->munge_name, true);
467 dot_type_string(fp, "real_name", mdata->real_name, true);
469}
470
471void dot_mailbox_maildir(FILE *fp, struct MaildirMboxData *mdata, struct ListHead *links)
472{
473 char buf[64] = { 0 };
474
475 dot_object_header(fp, mdata, "MaildirMboxData", "#60c060");
476
477 dot_type_date(buf, sizeof(buf), mdata->mtime_cur.tv_sec);
478 dot_type_string(fp, "mtime_cur", buf, true);
479
480 dot_type_umask(buf, sizeof(buf), mdata->mh_umask);
481 dot_type_string(fp, "mh_umask", buf, true);
483}
484
485void dot_mailbox_mbox(FILE *fp, struct MboxAccountData *mdata, struct ListHead *links)
486{
487 char buf[64] = { 0 };
488
489 dot_object_header(fp, mdata, "MboxAccountData", "#60c060");
490 dot_ptr(fp, "fp", mdata->fp, NULL);
491
492 dot_type_date(buf, sizeof(buf), mdata->atime.tv_sec);
493 dot_type_string(fp, "atime", buf, true);
494
496}
497
498void dot_mailbox_nntp(FILE *fp, struct NntpMboxData *mdata, struct ListHead *links)
499{
500 dot_object_header(fp, mdata, "NntpMboxData", "#60c060");
501 dot_type_string(fp, "group", mdata->group, true);
502 dot_type_string(fp, "desc", mdata->desc, true);
503
504 dot_type_number(fp, "first_message", mdata->first_message);
505 dot_type_number(fp, "last_message", mdata->last_message);
506 dot_type_number(fp, "last_loaded", mdata->last_loaded);
507 dot_type_number(fp, "last_cached", mdata->last_cached);
508 dot_type_number(fp, "unread", mdata->unread);
509
510 dot_type_bool(fp, "subscribed", mdata->subscribed);
511 dot_type_bool(fp, "has_new_mail", mdata->has_new_mail);
512 dot_type_bool(fp, "allowed", mdata->allowed);
513 dot_type_bool(fp, "deleted", mdata->deleted);
514
516}
517
518void dot_mailbox_notmuch(FILE *fp, struct NmMboxData *mdata, struct ListHead *links)
519{
520 dot_object_header(fp, mdata, "NmMboxData", "#60c060");
521 dot_type_number(fp, "db_limit", mdata->db_limit);
523}
524
525void dot_mailbox_pop(FILE *fp, struct PopAccountData *adata, struct ListHead *links)
526{
527 dot_object_header(fp, adata, "PopAccountData", "#60c060");
528 dot_ptr(fp, "conn", adata->conn, "#ff8080");
530}
531#endif
532
533void dot_mailbox(FILE *fp, struct Mailbox *m, struct ListHead *links)
534{
535 char buf[64] = { 0 };
536
537 dot_object_header(fp, m, "Mailbox", "#80ff80");
538 dot_mailbox_type(fp, "type", m->type);
539 dot_type_string(fp, "name", m->name, false);
540
541 if ((m->type == MUTT_IMAP) || (m->type == MUTT_POP))
542 {
543 dot_path_imap(buf, sizeof(buf), buf_string(&m->pathbuf));
544 dot_type_string(fp, "pathbuf", buf, true);
545 dot_path_imap(buf, sizeof(buf), m->realpath);
546 dot_type_string(fp, "realpath", buf, true);
547 }
548 else
549 {
550 dot_path_fs(buf, sizeof(buf), buf_string(&m->pathbuf));
551 dot_type_string(fp, "pathbuf", buf, true);
552 dot_path_fs(buf, sizeof(buf), m->realpath);
553 dot_type_string(fp, "realpath", buf, true);
554 }
555
556#ifdef GV_HIDE_MDATA
557 dot_ptr(fp, "mdata", m->mdata, NULL);
558#endif
559 dot_ptr(fp, "account", m->account, "#80ffff");
560 dot_type_number(fp, "opened", m->opened);
561
562 dot_type_number(fp, "msg_count", m->msg_count);
563 // dot_type_number(fp, "msg_unread", m->msg_unread);
564 // dot_type_number(fp, "msg_flagged", m->msg_flagged);
565 // dot_type_number(fp, "msg_new", m->msg_new);
566 // dot_type_number(fp, "msg_deleted", m->msg_deleted);
567 // dot_type_number(fp, "msg_tagged", m->msg_tagged);
568
569 dot_ptr(fp, "emails", m->emails, NULL);
570 dot_type_number(fp, "email_max", m->email_max);
571 dot_ptr(fp, "v2r", m->v2r, NULL);
572 dot_type_number(fp, "vcount", m->vcount);
573
575
576 // dot_add_link(links, m, m->mdata, false, NULL);
577
578#ifndef GV_HIDE_MDATA
579 if (m->mdata)
580 {
581 if (m->type == MUTT_MAILDIR)
582 dot_mailbox_maildir(fp, m->mdata, links);
583 else if (m->type == MUTT_IMAP)
584 dot_mailbox_imap(fp, m->mdata, links);
585 else if (m->type == MUTT_POP)
586 dot_mailbox_pop(fp, m->mdata, links);
587 else if (m->type == MUTT_MBOX)
588 dot_mailbox_mbox(fp, m->mdata, links);
589 else if (m->type == MUTT_NNTP)
590 dot_mailbox_nntp(fp, m->mdata, links);
591 else if (m->type == MUTT_NOTMUCH)
592 dot_mailbox_notmuch(fp, m->mdata, links);
593
594 dot_add_link(links, m, m->mdata, "Mailbox->mdata", false, NULL);
595 }
596#endif
597
598 if (m->compress_info)
599 {
600 dot_comp(fp, m->compress_info, links);
601 dot_add_link(links, m, m->compress_info, "Mailbox->compress_info", false, NULL);
602 }
603
604#ifndef GV_HIDE_CONFIG
605 if (m->name)
606 {
607 dot_config(fp, m->name, DT_INHERIT_MBOX, m->sub, links);
608 dot_add_link(links, m, m->name, "Mailbox Config", false, NULL);
609 }
610#endif
611}
612
613void dot_mailbox_node(FILE *fp, struct MailboxNode *mn, struct ListHead *links)
614{
615 dot_node(fp, mn, "MN", "#80ff80");
616
617 dot_mailbox(fp, mn->mailbox, links);
618
619 dot_add_link(links, mn, mn->mailbox, "MailboxNode->mailbox", false, NULL);
620
621 struct Buffer buf;
622 buf_init(&buf);
623
624 char name[256] = { 0 };
625 buf_addstr(&buf, "{ rank=same ");
626
627 dot_ptr_name(name, sizeof(name), mn);
628 buf_add_printf(&buf, "%s ", name);
629
630 dot_ptr_name(name, sizeof(name), mn->mailbox);
631 buf_add_printf(&buf, "%s ", name);
632
633#ifndef GV_HIDE_MDATA
634 if (mn->mailbox->mdata)
635 {
636 dot_ptr_name(name, sizeof(name), mn->mailbox->mdata);
637 buf_add_printf(&buf, "%s ", name);
638 }
639#endif
640
641#ifndef GV_HIDE_CONFIG
642 if (mn->mailbox->name)
643 {
644 dot_ptr_name(name, sizeof(name), mn->mailbox->name);
645 buf_add_printf(&buf, "%s ", name);
646 }
647#endif
648
649 buf_addstr(&buf, "}");
650
652 buf_dealloc(&buf);
653}
654
655void dot_mailbox_list(FILE *fp, struct MailboxList *ml, struct ListHead *links, bool abbr)
656{
657 struct MailboxNode *prev = NULL;
658 struct MailboxNode *np = NULL;
659 STAILQ_FOREACH(np, ml, entries)
660 {
661 if (abbr)
662 dot_node_link(fp, np, "MN", np->mailbox, "#80ff80");
663 else
664 dot_mailbox_node(fp, np, links);
665 if (prev)
666 dot_add_link(links, prev, np, "MailboxNode->next", false, NULL);
667 prev = np;
668 }
669}
670
671#ifndef GV_HIDE_ADATA
672void dot_connection(FILE *fp, struct Connection *c, struct ListHead *links)
673{
674 dot_object_header(fp, c, "Connection", "#ff8080");
675 // dot_ptr(fp, "sockdata", c->sockdata, "#60c0c0");
676 dot_type_number(fp, "fd", c->fd);
678
679 dot_object_header(fp, c->inbuf, "ConnAccount", "#ff8080");
680 dot_type_string(fp, "user", c->account.user, true);
681 dot_type_string(fp, "host", c->account.host, true);
682 dot_type_number(fp, "port", c->account.port);
684
685 dot_add_link(links, c, c->inbuf, "Connection.ConnAccount", false, NULL);
686}
687
688void dot_account_imap(FILE *fp, struct ImapAccountData *adata, struct ListHead *links)
689{
690 dot_object_header(fp, adata, "ImapAccountData", "#60c0c0");
691 // dot_type_string(fp, "mbox_name", adata->mbox_name, true);
692 // dot_type_string(fp, "login", adata->conn->account.login, true);
693 dot_type_string(fp, "user", adata->conn->account.user, true);
694 dot_type_string(fp, "pass", adata->conn->account.pass[0] ? "***" : "", true);
695 dot_type_number(fp, "port", adata->conn->account.port);
696 // dot_ptr(fp, "conn", adata->conn, "#ff8080");
697 dot_type_bool(fp, "unicode", adata->unicode);
698 dot_type_bool(fp, "qresync", adata->qresync);
699 dot_type_char(fp, "seqid", adata->seqid);
700 dot_ptr(fp, "mailbox", adata->mailbox, "#80ff80");
702
703 if (adata->conn)
704 {
705 dot_connection(fp, adata->conn, links);
706 dot_add_link(links, adata, adata->conn, "ImapAccountData->conn", false, NULL);
707 }
708}
709
710void dot_account_mbox(FILE *fp, struct MboxAccountData *adata, struct ListHead *links)
711{
712 char buf[64] = { 0 };
713
714 dot_object_header(fp, adata, "MboxAccountData", "#60c0c0");
715 dot_ptr(fp, "fp", adata->fp, NULL);
716
717 dot_type_date(buf, sizeof(buf), adata->atime.tv_sec);
718 dot_type_string(fp, "atime", buf, true);
719 dot_type_bool(fp, "locked", adata->locked);
720 dot_type_bool(fp, "append", adata->append);
721
723}
724
725void dot_account_nntp(FILE *fp, struct NntpAccountData *adata, struct ListHead *links)
726{
727 dot_object_header(fp, adata, "NntpAccountData", "#60c0c0");
728 dot_type_number(fp, "groups_num", adata->groups_num);
729
730 dot_type_bool(fp, "hasCAPABILITIES", adata->hasCAPABILITIES);
731 dot_type_bool(fp, "hasSTARTTLS", adata->hasSTARTTLS);
732 dot_type_bool(fp, "hasDATE", adata->hasDATE);
733 dot_type_bool(fp, "hasLIST_NEWSGROUPS", adata->hasLIST_NEWSGROUPS);
734 dot_type_bool(fp, "hasXGTITLE", adata->hasXGTITLE);
735 dot_type_bool(fp, "hasLISTGROUP", adata->hasLISTGROUP);
736 dot_type_bool(fp, "hasLISTGROUPrange", adata->hasLISTGROUPrange);
737 dot_type_bool(fp, "hasOVER", adata->hasOVER);
738 dot_type_bool(fp, "hasXOVER", adata->hasXOVER);
739 dot_type_bool(fp, "cacheable", adata->cacheable);
740 dot_type_bool(fp, "newsrc_modified", adata->newsrc_modified);
741
742 dot_type_string(fp, "authenticators", adata->authenticators, true);
743 dot_type_string(fp, "overview_fmt", adata->overview_fmt, true);
744 dot_type_string(fp, "newsrc_file", adata->newsrc_file, true);
745 dot_type_file(fp, "newsrc_fp", adata->fp_newsrc);
746
747 dot_type_number(fp, "groups_num", adata->groups_num);
748 dot_type_number(fp, "groups_max", adata->groups_max);
749
750 char buf[128];
751 dot_type_date(buf, sizeof(buf), adata->mtime);
752 dot_type_string(fp, "mtime", buf, true);
753 dot_type_date(buf, sizeof(buf), adata->newgroups_time);
754 dot_type_string(fp, "newgroups_time", buf, true);
755 dot_type_date(buf, sizeof(buf), adata->check_time);
756 dot_type_string(fp, "check_time", buf, true);
757
759
760 if (adata->conn)
761 {
762 dot_connection(fp, adata->conn, links);
763 dot_add_link(links, adata, adata->conn, "NntpAccountData->conn", false, NULL);
764 }
765}
766
767void dot_account_notmuch(FILE *fp, struct NmAccountData *adata, struct ListHead *links)
768{
769 dot_object_header(fp, adata, "NmAccountData", "#60c0c0");
770 dot_ptr(fp, "db", adata->db, NULL);
772}
773
774void dot_account_pop(FILE *fp, struct PopAccountData *adata, struct ListHead *links)
775{
776 char buf[64] = { 0 };
777
778 dot_object_header(fp, adata, "PopAccountData", "#60c0c0");
779
780 dot_type_date(buf, sizeof(buf), adata->check_time);
781 dot_type_string(fp, "check_time", buf, true);
782
783 dot_type_string(fp, "login", adata->conn->account.login, true);
784 dot_type_string(fp, "user", adata->conn->account.user, true);
785 dot_type_string(fp, "pass", adata->conn->account.pass[0] ? "***" : "", true);
786 dot_type_number(fp, "port", adata->conn->account.port);
787 // dot_ptr(fp, "conn", adata->conn, "#ff8080");
789
790 dot_connection(fp, adata->conn, links);
791 dot_add_link(links, adata, adata->conn, "PopAccountData->conn", false, NULL);
792}
793#endif
794
795void dot_account(FILE *fp, struct Account *a, struct ListHead *links)
796{
797 dot_object_header(fp, a, "Account", "#80ffff");
798 dot_mailbox_type(fp, "type", a->type);
799 dot_type_string(fp, "name", a->name, true);
800 // dot_ptr(fp, "adata", a->adata, "#60c0c0");
802
803#ifndef GV_HIDE_ADATA
804 if (a->adata)
805 {
806 if (a->type == MUTT_IMAP)
807 dot_account_imap(fp, a->adata, links);
808 else if (a->type == MUTT_POP)
809 dot_account_pop(fp, a->adata, links);
810 else if (a->type == MUTT_MBOX)
811 dot_account_mbox(fp, a->adata, links);
812 else if (a->type == MUTT_NNTP)
813 dot_account_nntp(fp, a->adata, links);
814 else if (a->type == MUTT_NOTMUCH)
815 dot_account_notmuch(fp, a->adata, links);
816
817 dot_add_link(links, a, a->adata, "Account->adata", false, NULL);
818 }
819#endif
820
821#ifndef GV_HIDE_CONFIG
822 if (a->name)
823 {
824 dot_config(fp, a->name, DT_INHERIT_ACC, a->sub, links);
825 dot_add_link(links, a, a->name, "Config", false, NULL);
826
827 char name[256] = { 0 };
828 struct Buffer buf;
829 buf_init(&buf);
830
831 buf_addstr(&buf, "{ rank=same ");
832
833 dot_ptr_name(name, sizeof(name), a);
834 buf_add_printf(&buf, "%s ", name);
835
836 dot_ptr_name(name, sizeof(name), a->name);
837 buf_add_printf(&buf, "%s ", name);
838
839 buf_addstr(&buf, "}");
841 buf_dealloc(&buf);
842 }
843#endif
844
845 struct MailboxNode *first = STAILQ_FIRST(&a->mailboxes);
846 dot_add_link(links, a, first, "Account->mailboxes", false, NULL);
847 dot_mailbox_list(fp, &a->mailboxes, links, false);
848}
849
850void dot_account_list(FILE *fp, struct AccountList *al, struct ListHead *links)
851{
852 struct Account *prev = NULL;
853 struct Account *np = NULL;
854 TAILQ_FOREACH(np, al, entries)
855 {
856#ifdef GV_HIDE_MBOX
857 if (np->type == MUTT_MBOX)
858 continue;
859#endif
860 dot_account(fp, np, links);
861 if (prev)
862 dot_add_link(links, prev, np, "Account->next", false, NULL);
863
864 prev = np;
865 }
866}
867
868#ifndef GV_HIDE_MVIEW
869void dot_mview(FILE *fp, struct MailboxView *mv, struct ListHead *links)
870{
871 dot_object_header(fp, mv, "MailboxView", "#ff80ff");
872 dot_ptr(fp, "mailbox", mv->mailbox, "#80ff80");
873#ifdef GV_HIDE_MVIEW_CONTENTS
874 dot_type_number(fp, "vsize", mv->vsize);
875 dot_type_string(fp, "pattern", mv->pattern, true);
876 dot_type_bool(fp, "collapsed", mv->collapsed);
877#endif
879}
880#endif
881
882void dump_graphviz(const char *title, struct MailboxView *mv)
883{
884 char name[256] = { 0 };
885 struct ListHead links = STAILQ_HEAD_INITIALIZER(links);
886
887 time_t now = time(NULL);
888 if (title)
889 {
890 char date[128];
891 mutt_date_localtime_format(date, sizeof(date), "%T", now);
892 snprintf(name, sizeof(name), "%s-%s.gv", date, title);
893 }
894 else
895 {
896 mutt_date_localtime_format(name, sizeof(name), "%T.gv", now);
897 }
898
899 umask(022);
900 FILE *fp = fopen(name, "w");
901 if (!fp)
902 return;
903
905
906#ifndef GV_HIDE_NEOMUTT
907 dot_node(fp, NeoMutt, "NeoMutt", "#ffa500");
909 "NeoMutt->accounts", false, NULL);
910#ifndef GV_HIDE_CONFIG
911 dot_config(fp, (const char *) NeoMutt->sub, 0, NeoMutt->sub, &links);
912 dot_add_link(&links, NeoMutt, NeoMutt->sub, "NeoMutt Config", false, NULL);
913 struct Buffer buf = buf_make(256);
914 char obj1[64] = { 0 };
915 char obj2[64] = { 0 };
916 dot_ptr_name(obj1, sizeof(obj1), NeoMutt);
917 dot_ptr_name(obj2, sizeof(obj2), NeoMutt->sub);
918 buf_printf(&buf, "{ rank=same %s %s }", obj1, obj2);
920 buf_dealloc(&buf);
921#endif
922#endif
923
924 dot_account_list(fp, &NeoMutt->accounts, &links);
925
926#ifndef GV_HIDE_MVIEW
927 if (mv)
928 dot_mview(fp, mv, &links);
929
930#ifndef GV_HIDE_NEOMUTT
931 /* Globals */
932 fprintf(fp, "\t{ rank=same ");
933 if (mv)
934 {
935 dot_ptr_name(name, sizeof(name), mv);
936 fprintf(fp, "%s ", name);
937 }
938 dot_ptr_name(name, sizeof(name), NeoMutt);
939 fprintf(fp, "%s ", name);
940 fprintf(fp, "}\n");
941#endif
942#endif
943
944 fprintf(fp, "\t{ rank=same ");
945 struct Account *np = NULL;
946 TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
947 {
948#ifdef GV_HIDE_MBOX
949 if (np->type == MUTT_MBOX)
950 continue;
951#endif
952 dot_ptr_name(name, sizeof(name), np);
953 fprintf(fp, "%s ", name);
954 }
955 fprintf(fp, "}\n");
956
957 dot_graph_footer(fp, &links);
958 fclose(fp);
959 mutt_list_free(&links);
960}
961
962#ifndef GV_HIDE_BODY_CONTENT
963void dot_parameter_list(FILE *fp, const char *name, const struct ParameterList *pl)
964{
965 if (!pl)
966 return;
967 if (TAILQ_EMPTY(pl))
968 return;
969
970 dot_object_header(fp, pl, "ParameterList", "#00ff00");
971
972 struct Parameter *np = NULL;
973 TAILQ_FOREACH(np, pl, entries)
974 {
975 dot_type_string(fp, np->attribute, np->value, false);
976 }
977
979}
980
981void dot_content(FILE *fp, struct Content *cont, struct ListHead *links)
982{
983 struct Buffer buf = buf_make(256);
984
985 dot_object_header(fp, cont, "Content", "#800080");
986
987 dot_type_number(fp, "hibin", cont->hibin);
988 dot_type_number(fp, "lobin", cont->lobin);
989 dot_type_number(fp, "nulbin", cont->nulbin);
990 dot_type_number(fp, "crlf", cont->crlf);
991 dot_type_number(fp, "ascii", cont->ascii);
992 dot_type_number(fp, "linemax", cont->linemax);
993
994#define ADD_BOOL(F) add_flag(&buf, cont->F, #F)
995 ADD_BOOL(space);
996 ADD_BOOL(binary);
997 ADD_BOOL(from);
998 ADD_BOOL(dot);
999 ADD_BOOL(cr);
1000#undef ADD_BOOL
1001
1003
1004 buf_dealloc(&buf);
1005}
1006#endif
1007
1008void dot_attach_ptr(FILE *fp, struct AttachPtr *aptr, struct ListHead *links)
1009{
1010 if (!aptr)
1011 return;
1012
1013 struct Buffer buf = buf_make(256);
1014
1015 dot_object_header(fp, aptr, "AttachPtr", "#ff0000");
1016
1017 dot_type_file(fp, "fp", aptr->fp);
1018
1019 dot_type_string(fp, "parent_type", get_content_type(aptr->parent_type), false);
1020
1021 dot_type_number(fp, "level", aptr->level);
1022 dot_type_number(fp, "num", aptr->num);
1023
1024 dot_type_bool(fp, "unowned", aptr->unowned);
1025 dot_type_bool(fp, "collapsed", aptr->collapsed);
1026 dot_type_bool(fp, "decrypted", aptr->decrypted);
1027
1029
1030 dot_add_link(links, aptr->body, aptr, "AttachPtr->body", true, NULL);
1031
1032 buf_dealloc(&buf);
1033}
1034
1035void dot_body(FILE *fp, struct Body *b, struct ListHead *links, bool link_next)
1036{
1037 struct Buffer buf = buf_make(256);
1038
1039 dot_object_header(fp, b, "Body", "#2020ff");
1040
1041 char file[256];
1042 dot_path_fs(file, sizeof(file), b->filename);
1043 dot_type_string(fp, "file", file, false);
1044
1045 dot_type_string(fp, "charset", b->charset, false);
1046 dot_type_string(fp, "description", b->description, false);
1047 dot_type_string(fp, "d_filename", b->d_filename, false);
1048 dot_type_string(fp, "form_name", b->form_name, false);
1049 dot_type_string(fp, "language", b->language, false);
1050 dot_type_string(fp, "subtype", b->subtype, false);
1051 dot_type_string(fp, "xtype", b->xtype, false);
1052
1053 dot_type_string(fp, "type", get_content_type(b->type), true);
1054 dot_type_string(fp, "encoding", get_content_encoding(b->encoding), true);
1055 dot_type_string(fp, "disposition", get_content_disposition(b->disposition), true);
1056
1057 if (b->stamp != 0)
1058 {
1059 char arr[64];
1060 dot_type_date(arr, sizeof(arr), b->stamp);
1061 dot_type_string(fp, "stamp", arr, true);
1062 }
1063
1064#define ADD_BOOL(F) add_flag(&buf, b->F, #F)
1065 ADD_BOOL(attach_qualifies);
1066 ADD_BOOL(badsig);
1067 ADD_BOOL(deleted);
1068 ADD_BOOL(force_charset);
1069 ADD_BOOL(goodsig);
1070#ifdef USE_AUTOCRYPT
1071 ADD_BOOL(is_autocrypt);
1072#endif
1073 ADD_BOOL(noconv);
1074 ADD_BOOL(tagged);
1075 ADD_BOOL(unlink);
1076 ADD_BOOL(use_disp);
1077 ADD_BOOL(warnsig);
1078#undef ADD_BOOL
1079 dot_type_string(fp, "bools", buf_is_empty(&buf) ? "[NONE]" : buf_string(&buf), true);
1080
1081 dot_type_number(fp, "attach_count", b->attach_count);
1082 dot_type_number(fp, "hdr_offset", b->hdr_offset);
1083 dot_type_number(fp, "length", b->length);
1084 dot_type_number(fp, "offset", b->offset);
1085
1086 dot_ptr(fp, "aptr", b->aptr, "#3bcbc4");
1087
1088#ifdef GV_HIDE_BODY_CONTENT
1089 if (!TAILQ_EMPTY(&b->parameter))
1090 {
1091 struct Parameter *param = TAILQ_FIRST(&b->parameter);
1092 if (mutt_str_equal(param->attribute, "boundary"))
1093 {
1094 dot_type_string(fp, "boundary", param->value, false);
1095 }
1096 }
1097#endif
1098
1100
1101#ifndef GV_HIDE_BODY_CONTENT
1102 if (!TAILQ_EMPTY(&b->parameter))
1103 {
1104 dot_parameter_list(fp, "parameter", &b->parameter);
1105 dot_add_link(links, b, &b->parameter, "Body->mime_headers", false, NULL);
1106 }
1107#endif
1108
1109#ifndef GV_HIDE_ENVELOPE
1110 if (b->mime_headers)
1111 {
1112 dot_envelope(fp, b->mime_headers, links);
1113 dot_add_link(links, b, b->mime_headers, "Body->mime_headers", false, NULL);
1114 }
1115#endif
1116
1117 if (b->email)
1118 {
1119 dot_email(fp, b->email, links);
1120 dot_add_link(links, b, b->email, "Body->email", false, NULL);
1121 }
1122
1123 if (b->parts)
1124 {
1125 if (!b->email)
1126 dot_body(fp, b->parts, links, true);
1127 dot_add_link(links, b, b->parts, "Body->parts", false, "#ff0000");
1128 }
1129
1130 if (b->next && link_next)
1131 {
1132 char name[256] = { 0 };
1133 buf_reset(&buf);
1134
1135 buf_addstr(&buf, "{ rank=same ");
1136
1137 dot_ptr_name(name, sizeof(name), b);
1138 buf_add_printf(&buf, "%s ", name);
1139
1140 for (; b->next; b = b->next)
1141 {
1142 dot_body(fp, b->next, links, false);
1143 dot_add_link(links, b, b->next, "Body->next", false, "#008000");
1144
1145 dot_ptr_name(name, sizeof(name), b->next);
1146 buf_add_printf(&buf, "%s ", name);
1147 }
1148
1149 buf_addstr(&buf, "}");
1151 }
1152 else
1153 {
1154#ifndef GV_HIDE_BODY_CONTENT
1155 if (b->content)
1156 {
1157 dot_content(fp, b->content, links);
1158 dot_add_link(links, b, b->content, "Body->content", false, NULL);
1159 }
1160#endif
1161
1162 // if (b->aptr)
1163 // {
1164 // dot_attach_ptr(fp, b->aptr, links);
1165 // dot_add_link(links, b, b->aptr, "Body->aptr", false, NULL);
1166 // }
1167 }
1168
1169 buf_dealloc(&buf);
1170}
1171
1172#ifndef GV_HIDE_ENVELOPE
1173void dot_list_head(FILE *fp, const char *name, const struct ListHead *list)
1174{
1175 if (!list || !name)
1176 return;
1177 if (STAILQ_EMPTY(list))
1178 return;
1179
1180 struct Buffer buf = buf_make(256);
1181
1182 struct ListNode *np = NULL;
1183 STAILQ_FOREACH(np, list, entries)
1184 {
1185 if (!buf_is_empty(&buf))
1186 buf_addch(&buf, ',');
1187 buf_addstr(&buf, np->data);
1188 }
1189
1190 dot_type_string(fp, name, buf_string(&buf), false);
1191}
1192
1193void dot_addr_list(FILE *fp, const char *name, const struct AddressList *al,
1194 struct ListHead *links)
1195{
1196 if (!al)
1197 return;
1198 if (TAILQ_EMPTY(al))
1199 return;
1200
1201 struct Buffer *buf = buf_pool_get();
1202 mutt_addrlist_write(al, buf, true);
1203 dot_type_string(fp, name, buf_string(buf), false);
1204 buf_pool_release(&buf);
1205}
1206
1207void dot_envelope(FILE *fp, struct Envelope *env, struct ListHead *links)
1208{
1209 struct Buffer buf = buf_make(256);
1210
1211 dot_object_header(fp, env, "Envelope", "#ffff00");
1212
1213#define ADD_FLAG(F) add_flag(&buf, (env->changed & F), #F)
1218#undef ADD_BOOL
1219 dot_type_string(fp, "changed", buf_is_empty(&buf) ? "[NONE]" : buf_string(&buf), true);
1220
1221#define ADDR_LIST(AL) dot_addr_list(fp, #AL, &env->AL, links)
1222 ADDR_LIST(return_path);
1223 ADDR_LIST(from);
1224 ADDR_LIST(to);
1225 ADDR_LIST(cc);
1226 ADDR_LIST(bcc);
1227 ADDR_LIST(sender);
1228 ADDR_LIST(reply_to);
1229 ADDR_LIST(mail_followup_to);
1230 ADDR_LIST(x_original_to);
1231#undef ADDR_LIST
1232
1233 dot_type_string(fp, "date", env->date, false);
1234 dot_type_string(fp, "disp_subj", env->disp_subj, false);
1235 dot_type_string(fp, "followup_to", env->followup_to, false);
1236 dot_type_string(fp, "list_post", env->list_post, false);
1237 dot_type_string(fp, "list_subscribe", env->list_subscribe, false);
1238 dot_type_string(fp, "list_unsubscribe", env->list_unsubscribe, false);
1239 dot_type_string(fp, "message_id", env->message_id, false);
1240 dot_type_string(fp, "newsgroups", env->newsgroups, false);
1241 dot_type_string(fp, "organization", env->organization, false);
1242 dot_type_string(fp, "real_subj", env->real_subj, false);
1243 dot_type_string(fp, "spam", buf_string(&env->spam), false);
1244 dot_type_string(fp, "subject", env->subject, false);
1245 dot_type_string(fp, "supersedes", env->supersedes, false);
1246 dot_type_string(fp, "xref", env->xref, false);
1247 dot_type_string(fp, "x_comment_to", env->x_comment_to, false);
1248 dot_type_string(fp, "x_label", env->x_label, false);
1249
1250 if (0)
1251 {
1252 dot_list_head(fp, "references", &env->references);
1253 dot_list_head(fp, "in_reply_to", &env->in_reply_to);
1254 dot_list_head(fp, "userhdrs", &env->userhdrs);
1255 }
1256
1257#ifdef USE_AUTOCRYPT
1258 dot_ptr(fp, "autocrypt", env->autocrypt, NULL);
1259 dot_ptr(fp, "autocrypt_gossip", env->autocrypt_gossip, NULL);
1260#endif
1261
1263
1264 buf_dealloc(&buf);
1265}
1266#endif
1267
1268void dot_email(FILE *fp, struct Email *e, struct ListHead *links)
1269{
1270 struct Buffer buf = buf_make(256);
1271 char arr[256];
1272
1273 dot_object_header(fp, e, "Email", "#ff80ff");
1274
1275 dot_type_string(fp, "path", e->path, true);
1276
1277#define ADD_BOOL(F) add_flag(&buf, e->F, #F)
1278 ADD_BOOL(active);
1279 ADD_BOOL(attach_del);
1280 ADD_BOOL(attach_valid);
1281 ADD_BOOL(changed);
1282 ADD_BOOL(collapsed);
1283 ADD_BOOL(deleted);
1284 ADD_BOOL(display_subject);
1285 ADD_BOOL(expired);
1286 ADD_BOOL(flagged);
1287 ADD_BOOL(matched);
1288 ADD_BOOL(mime);
1289 ADD_BOOL(old);
1290 ADD_BOOL(purge);
1291 ADD_BOOL(quasi_deleted);
1292 ADD_BOOL(read);
1293 ADD_BOOL(recip_valid);
1294 ADD_BOOL(replied);
1295 ADD_BOOL(searched);
1296 ADD_BOOL(subject_changed);
1297 ADD_BOOL(superseded);
1298 ADD_BOOL(tagged);
1299 ADD_BOOL(threaded);
1300 ADD_BOOL(trash);
1301 ADD_BOOL(visible);
1302#undef ADD_BOOL
1303 dot_type_string(fp, "bools", buf_is_empty(&buf) ? "[NONE]" : buf_string(&buf), true);
1304
1305 buf_reset(&buf);
1306#define ADD_BOOL(F) add_flag(&buf, (e->security & F), #F)
1321#undef ADD_BOOL
1322 dot_type_string(fp, "security", buf_is_empty(&buf) ? "[NONE]" : buf_string(&buf), true);
1323
1324 dot_type_number(fp, "num_hidden", e->num_hidden);
1325 dot_type_number(fp, "offset", e->offset);
1326 dot_type_number(fp, "lines", e->lines);
1327 dot_type_number(fp, "index", e->index);
1328 dot_type_number(fp, "msgno", e->msgno);
1329 dot_type_number(fp, "vnum", e->vnum);
1330 dot_type_number(fp, "score", e->score);
1331 dot_type_number(fp, "attach_total", e->attach_total);
1332
1333 // struct MaildirEmailData *edata = maildir_edata_get(e);
1334 // if (edata)
1335 // dot_type_string(fp, "maildir_flags", edata->maildir_flags, false);
1336
1337 if (e->date_sent != 0)
1338 {
1339 char zone[32];
1340 dot_type_date(arr, sizeof(arr), e->date_sent);
1341 snprintf(zone, sizeof(zone), " (%c%02u%02u)", e->zoccident ? '-' : '+',
1342 e->zhours, e->zminutes);
1343 mutt_str_cat(arr, sizeof(arr), zone);
1344 dot_type_string(fp, "date_sent", arr, false);
1345 }
1346
1347 if (e->received != 0)
1348 {
1349 dot_type_date(arr, sizeof(arr), e->received);
1350 dot_type_string(fp, "received", arr, false);
1351 }
1352
1354
1355 if (e->body)
1356 {
1357 dot_body(fp, e->body, links, true);
1358 dot_add_link(links, e, e->body, "Email->body", false, NULL);
1359 }
1360
1361#ifndef GV_HIDE_ENVELOPE
1362 if (e->env)
1363 {
1364 dot_envelope(fp, e->env, links);
1365 dot_add_link(links, e, e->env, "Email->env", false, NULL);
1366
1367 buf_reset(&buf);
1368 buf_addstr(&buf, "{ rank=same ");
1369
1370 dot_ptr_name(arr, sizeof(arr), e);
1371 buf_add_printf(&buf, "%s ", arr);
1372
1373 dot_ptr_name(arr, sizeof(arr), e->env);
1374 buf_add_printf(&buf, "%s ", arr);
1375
1376 buf_addstr(&buf, "}");
1377
1379 }
1380#endif
1381
1382 // struct TagList tags;
1383
1384 buf_dealloc(&buf);
1385}
1386
1388{
1389 char name[256] = { 0 };
1390 struct ListHead links = STAILQ_HEAD_INITIALIZER(links);
1391
1392 time_t now = time(NULL);
1393 mutt_date_localtime_format(name, sizeof(name), "%T-email.gv", now);
1394
1395 umask(022);
1396 FILE *fp = fopen(name, "w");
1397 if (!fp)
1398 return;
1399
1400 dot_graph_header(fp);
1401
1402 dot_body(fp, b, &links, true);
1403
1404 dot_graph_footer(fp, &links);
1405 fclose(fp);
1406 mutt_list_free(&links);
1407}
1408
1409void dump_graphviz_email(struct Email *e, const char *title)
1410{
1411 char name[256] = { 0 };
1412 struct ListHead links = STAILQ_HEAD_INITIALIZER(links);
1413
1414 if (!title)
1415 title = "email";
1416
1417 char format[64];
1418 snprintf(format, sizeof(format), "%%T-%s.gv", title);
1419
1420 time_t now = time(NULL);
1421 mutt_date_localtime_format(name, sizeof(name), format, now);
1422
1423 umask(022);
1424 FILE *fp = fopen(name, "w");
1425 if (!fp)
1426 return;
1427
1428 dot_graph_header(fp);
1429
1430 dot_email(fp, e, &links);
1431
1432 dot_graph_footer(fp, &links);
1433 fclose(fp);
1434 mutt_list_free(&links);
1435}
1436
1437void dot_attach_ptr2(FILE *fp, struct AttachPtr *aptr, struct ListHead *links)
1438{
1439 if (!aptr)
1440 return;
1441
1442 struct Buffer buf = buf_make(256);
1443
1444 dot_object_header(fp, aptr, "AttachPtr", "#3bcbc4");
1445
1446 dot_ptr(fp, "body", aptr->body, "#2020ff");
1447 dot_type_file(fp, "fp", aptr->fp);
1448
1449 dot_type_string(fp, "parent_type", get_content_type(aptr->parent_type), false);
1450 dot_type_number(fp, "level", aptr->level);
1451 dot_type_number(fp, "num", aptr->num);
1452 dot_type_bool(fp, "unowned", aptr->unowned);
1453 dot_type_bool(fp, "collapsed", aptr->collapsed);
1454 dot_type_bool(fp, "decrypted", aptr->decrypted);
1455
1456 // dot_type_string(fp, "tree", aptr->tree, false);
1457
1459
1460 buf_dealloc(&buf);
1461}
1462
1463void dot_array_actx_idx(FILE *fp, struct AttachPtr **idx, short idxlen,
1464 short idxmax, struct ListHead *links)
1465{
1466 dot_object_header(fp, idx, "AttachCtx-&gt;idx", "#9347de");
1467
1468 dot_type_number(fp, "idxlen", idxlen);
1469 dot_type_number(fp, "idxmax", idxmax);
1470
1471 char arr[32];
1472 for (size_t i = 0; i < idxmax; i++)
1473 {
1474 snprintf(arr, sizeof(arr), "idx[%zu]", i);
1475 dot_ptr(fp, arr, idx[i], "#3bcbc4");
1476 }
1477
1479
1480 for (size_t i = 0; i < idxlen; i++)
1481 {
1482 dot_attach_ptr2(fp, idx[i], links);
1483 dot_add_link(links, idx, idx[i], "AttachCtx-&gt;idx", false, NULL);
1484 }
1485}
1486
1487void dot_array_actx_v2r(FILE *fp, short *v2r, short vcount, struct ListHead *links)
1488{
1489 dot_object_header(fp, v2r, "AttachCtx-&gt;v2r", "#9347de");
1490
1491 dot_type_number(fp, "vcount", vcount);
1492
1493 char arr[32];
1494 for (size_t i = 0; i < vcount; i++)
1495 {
1496 snprintf(arr, sizeof(arr), "v2r[%zu]", i);
1497 dot_type_number(fp, arr, v2r[i]);
1498 }
1499
1501}
1502
1503void dot_array_actx_fp_idx(FILE *fp, FILE **fp_idx, short fp_len, short fp_max,
1504 struct ListHead *links)
1505{
1506 dot_object_header(fp, fp_idx, "AttachCtx-&gt;fp_idx", "#f86e28");
1507
1508 dot_type_number(fp, "fp_len", fp_len);
1509 dot_type_number(fp, "fp_max", fp_max);
1510
1511 char arr[32];
1512 for (size_t i = 0; i < fp_max; i++)
1513 {
1514 snprintf(arr, sizeof(arr), "fp_idx[%zu]", i);
1515 dot_type_file(fp, arr, fp_idx[i]);
1516 }
1517
1519}
1520
1521void dot_array_actx_body_idx(FILE *fp, struct Body **body_idx, short body_len,
1522 short body_max, struct ListHead *links)
1523{
1524 dot_object_header(fp, body_idx, "AttachCtx-&gt;body_idx", "#4ff270");
1525
1526 dot_type_number(fp, "body_len", body_len);
1527 dot_type_number(fp, "body_max", body_max);
1528
1529 char arr[32];
1530 for (size_t i = 0; i < body_max; i++)
1531 {
1532 snprintf(arr, sizeof(arr), "body_idx[%zu]", i);
1533 dot_ptr(fp, arr, body_idx[i], "#2020ff");
1534 }
1535
1537
1538 for (size_t i = 0; i < body_max; i++)
1539 {
1540 if (!body_idx[i])
1541 continue;
1542 dot_body(fp, body_idx[i], links, true);
1543 dot_add_link(links, body_idx, body_idx[i], "AttachCtx->Body", false, "#008000");
1544 }
1545}
1546
1547void dot_attach_ctx(FILE *fp, struct AttachCtx *actx, struct ListHead *links)
1548{
1549 struct Buffer buf = buf_make(256);
1550 // char arr[256];
1551
1552 dot_object_header(fp, actx, "AttachCtx", "#9347de");
1553
1554 dot_ptr(fp, "email", actx->email, "#ff80ff");
1555 dot_type_file(fp, "fp_root", actx->fp_root);
1556
1558
1559 if (actx->idx)
1560 {
1561 dot_array_actx_idx(fp, actx->idx, actx->idxlen, actx->idxmax, links);
1562 dot_add_link(links, actx, actx->idx, "AttachCtx-&gt;idx", false, NULL);
1563 }
1564
1565 if (actx->v2r)
1566 {
1567 dot_array_actx_v2r(fp, actx->v2r, actx->vcount, links);
1568 dot_add_link(links, actx, actx->v2r, "AttachCtx-&gt;v2r", false, NULL);
1569 }
1570
1571 if (actx->fp_idx)
1572 {
1573 dot_array_actx_fp_idx(fp, actx->fp_idx, actx->fp_len, actx->fp_max, links);
1574 dot_add_link(links, actx, actx->fp_idx, "AttachCtx-&gt;fp_idx", false, NULL);
1575 }
1576
1577 if (actx->body_idx)
1578 {
1579 dot_array_actx_body_idx(fp, actx->body_idx, actx->body_len, actx->body_max, links);
1580 dot_add_link(links, actx, actx->body_idx, "AttachCtx-&gt;body_idx", false, NULL);
1581 }
1582
1583 buf_dealloc(&buf);
1584}
1585
1587{
1588 char name[256] = { 0 };
1589 struct ListHead links = STAILQ_HEAD_INITIALIZER(links);
1590
1591 time_t now = time(NULL);
1592 mutt_date_localtime_format(name, sizeof(name), "%T-actx.gv", now);
1593
1594 umask(022);
1595 FILE *fp = fopen(name, "w");
1596 if (!fp)
1597 return;
1598
1599 dot_graph_header(fp);
1600
1601 dot_attach_ctx(fp, actx, &links);
1602
1603 dot_graph_footer(fp, &links);
1604 fclose(fp);
1605 mutt_list_free(&links);
1606}
1607
1608const char *pattern_type_name(int type)
1609{
1610 static struct Mapping PatternNames[] = {
1611 // clang-format off
1612 { "address", MUTT_PAT_ADDRESS },
1613 { "AND", MUTT_PAT_AND },
1614 { "bcc", MUTT_PAT_BCC },
1615 { "body", MUTT_PAT_BODY },
1616 { "broken", MUTT_PAT_BROKEN },
1617 { "cc", MUTT_PAT_CC },
1618 { "children", MUTT_PAT_CHILDREN },
1619 { "collapsed", MUTT_PAT_COLLAPSED },
1620 { "crypt_encrypt", MUTT_PAT_CRYPT_ENCRYPT },
1621 { "crypt_sign", MUTT_PAT_CRYPT_SIGN },
1622 { "crypt_verified", MUTT_PAT_CRYPT_VERIFIED },
1623 { "date", MUTT_PAT_DATE },
1624 { "date_received", MUTT_PAT_DATE_RECEIVED },
1625 { "driver_tags", MUTT_PAT_DRIVER_TAGS },
1626 { "duplicated", MUTT_PAT_DUPLICATED },
1627 { "from", MUTT_PAT_FROM },
1628 { "header", MUTT_PAT_HEADER },
1629 { "hormel", MUTT_PAT_HORMEL },
1630 { "id", MUTT_PAT_ID },
1631 { "id_external", MUTT_PAT_ID_EXTERNAL },
1632 { "list", MUTT_PAT_LIST },
1633 { "message", MUTT_PAT_MESSAGE },
1634 { "mimeattach", MUTT_PAT_MIMEATTACH },
1635 { "mimetype", MUTT_PAT_MIMETYPE },
1636 { "newsgroups", MUTT_PAT_NEWSGROUPS },
1637 { "OR", MUTT_PAT_OR },
1638 { "parent", MUTT_PAT_PARENT },
1639 { "personal_from", MUTT_PAT_PERSONAL_FROM },
1640 { "personal_recip", MUTT_PAT_PERSONAL_RECIP },
1641 { "pgp_key", MUTT_PAT_PGP_KEY },
1642 { "recipient", MUTT_PAT_RECIPIENT },
1643 { "reference", MUTT_PAT_REFERENCE },
1644 { "score", MUTT_PAT_SCORE },
1645 { "sender", MUTT_PAT_SENDER },
1646 { "serversearch", MUTT_PAT_SERVERSEARCH },
1647 { "size", MUTT_PAT_SIZE },
1648 { "subject", MUTT_PAT_SUBJECT },
1649 { "subscribed_list", MUTT_PAT_SUBSCRIBED_LIST },
1650 { "thread", MUTT_PAT_THREAD },
1651 { "to", MUTT_PAT_TO },
1652 { "unreferenced", MUTT_PAT_UNREFERENCED },
1653 { "whole_msg", MUTT_PAT_WHOLE_MSG },
1654 { "xlabel", MUTT_PAT_XLABEL },
1655 { NULL, 0 },
1656 // clang-format on
1657 };
1658
1659 return mutt_map_get_name(type, PatternNames);
1660}
1661
1662void dot_pattern(FILE *fp, struct Pattern *pat, struct ListHead *links)
1663{
1664 struct Buffer buf = buf_make(256);
1665 dot_object_header(fp, pat, "Pattern", "#c040c0");
1666
1667 dot_type_string(fp, "op", pattern_type_name(pat->op), true);
1668 if ((pat->min != 0) || (pat->max != 0))
1669 {
1670 dot_type_number(fp, "min", pat->min);
1671 dot_type_number(fp, "max", pat->max);
1672 }
1673
1674#define ADD_BOOL(F) add_flag(&buf, pat->F, #F)
1675 ADD_BOOL(pat_not);
1676 ADD_BOOL(all_addr);
1677 ADD_BOOL(string_match);
1678 ADD_BOOL(group_match);
1679 ADD_BOOL(ign_case);
1680 ADD_BOOL(is_alias);
1681 ADD_BOOL(dynamic);
1682 ADD_BOOL(sendmode);
1683 ADD_BOOL(is_multi);
1684#undef ADD_BOOL
1685 dot_type_string(fp, "flags", buf_is_empty(&buf) ? "[NONE]" : buf_string(&buf), true);
1686
1687 if (pat->group_match)
1688 {
1689 // struct Group *group; ///< Address group if group_match is set
1690 }
1691 else if (pat->string_match)
1692 {
1693 dot_type_string(fp, "str", pat->p.str, true);
1694 }
1695 else if (pat->is_multi)
1696 {
1697 // struct ListHead multi_cases; ///< Multiple strings for ~I pattern
1698 }
1699 else
1700 {
1701 if (pat->p.regex)
1702 {
1703 dot_ptr(fp, "regex", pat->p.regex, NULL);
1704 dot_type_string(fp, "pattern", pat->raw_pattern, true);
1705 }
1706 }
1707
1709
1710 if (pat->child)
1711 {
1712 dot_patternlist(fp, pat->child, links);
1713 struct Pattern *first = SLIST_FIRST(pat->child);
1714 dot_add_link(links, pat, first, "Patern->child", false, "#00ff00");
1715 }
1716 buf_dealloc(&buf);
1717}
1718
1719void dot_patternlist(FILE *fp, struct PatternList *pl, struct ListHead *links)
1720{
1721 struct Buffer buf;
1722 buf_init(&buf);
1723
1724 char name[256] = { 0 };
1725 buf_addstr(&buf, "{ rank=same ");
1726
1727 struct Pattern *prev = NULL;
1728 struct Pattern *np = NULL;
1729 SLIST_FOREACH(np, pl, entries)
1730 {
1731 dot_pattern(fp, np, links);
1732 if (prev)
1733 dot_add_link(links, prev, np, "PatternList->next", false, "#ff0000");
1734 prev = np;
1735
1736 dot_ptr_name(name, sizeof(name), np);
1737 buf_add_printf(&buf, "%s ", name);
1738 }
1739
1740 buf_addstr(&buf, "}");
1741
1743 buf_dealloc(&buf);
1744}
1745
1746void dump_graphviz_patternlist(struct PatternList *pl)
1747{
1748 char name[256] = { 0 };
1749 struct ListHead links = STAILQ_HEAD_INITIALIZER(links);
1750
1751 time_t now = time(NULL);
1752 mutt_date_localtime_format(name, sizeof(name), "%T-pattern.gv", now);
1753
1754 umask(022);
1755 FILE *fp = fopen(name, "w");
1756 if (!fp)
1757 return;
1758
1759 dot_graph_header(fp);
1760
1761 dot_patternlist(fp, pl, &links);
1762
1763 dot_graph_footer(fp, &links);
1764 fclose(fp);
1765 mutt_list_free(&links);
1766}
size_t mutt_addrlist_write(const struct AddressList *al, struct Buffer *buf, bool display)
Write an Address to a buffer.
Definition: address.c:1199
Email Address Handling.
GUI display the mailboxes in a side panel.
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:171
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:214
void buf_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:352
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:86
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:301
struct Buffer buf_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:68
struct Buffer * buf_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:53
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:251
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:236
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:78
Compressed mbox local mailbox type.
Convenience wrapper for the config headers.
Connection Library.
Convenience wrapper for the core headers.
const char * get_content_type(enum ContentType type)
Definition: names.c:46
const char * get_content_encoding(enum ContentEncoding enc)
Definition: names.c:64
const char * get_content_disposition(enum ContentDisposition disp)
Definition: names.c:79
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
void dot_array_actx_idx(FILE *fp, struct AttachPtr **idx, short idxlen, short idxmax, struct ListHead *links)
Definition: graphviz.c:1463
void dot_mailbox_pop(FILE *fp, struct PopAccountData *adata, struct ListHead *links)
Definition: graphviz.c:525
void dot_ptr_name(char *buf, size_t buflen, const void *ptr)
Definition: graphviz.c:178
void dot_parameter_list(FILE *fp, const char *name, const struct ParameterList *pl)
Definition: graphviz.c:963
void dot_graph_header(FILE *fp)
Definition: graphviz.c:224
void dot_account_pop(FILE *fp, struct PopAccountData *adata, struct ListHead *links)
Definition: graphviz.c:774
void dot_object_footer(FILE *fp)
Definition: graphviz.c:275
void dot_path_fs(char *buf, size_t buflen, const char *path)
Definition: graphviz.c:317
void dump_graphviz_body(struct Body *b)
Definition: graphviz.c:1387
void dot_addr_list(FILE *fp, const char *name, const struct AddressList *al, struct ListHead *links)
Definition: graphviz.c:1193
void dot_mailbox_imap(FILE *fp, struct ImapMboxData *mdata, struct ListHead *links)
Definition: graphviz.c:462
void dot_comp(FILE *fp, struct CompressInfo *ci, struct ListHead *links)
Definition: graphviz.c:408
void dot_mailbox_type(FILE *fp, const char *name, enum MailboxType type)
Definition: graphviz.c:417
void dot_attach_ptr2(FILE *fp, struct AttachPtr *aptr, struct ListHead *links)
Definition: graphviz.c:1437
void dot_type_date(char *buf, size_t buflen, time_t timestamp)
Definition: graphviz.c:102
void dot_array_actx_v2r(FILE *fp, short *v2r, short vcount, struct ListHead *links)
Definition: graphviz.c:1487
void dot_type_number(FILE *fp, const char *name, int num)
Definition: graphviz.c:124
#define ADDR_LIST(AL)
void dot_email(FILE *fp, struct Email *e, struct ListHead *links)
Definition: graphviz.c:1268
void dot_type_char(FILE *fp, const char *name, char ch)
Definition: graphviz.c:92
void dot_account_list(FILE *fp, struct AccountList *al, struct ListHead *links)
Definition: graphviz.c:850
void dot_account_mbox(FILE *fp, struct MboxAccountData *adata, struct ListHead *links)
Definition: graphviz.c:710
void dot_type_file(FILE *fp, const char *name, FILE *struct_fp)
Definition: graphviz.c:107
void dump_graphviz(const char *title, struct MailboxView *mv)
Definition: graphviz.c:882
void dot_type_bool(FILE *fp, const char *name, bool val)
Definition: graphviz.c:81
void dot_list_head(FILE *fp, const char *name, const struct ListHead *list)
Definition: graphviz.c:1173
void dot_config(FILE *fp, const char *name, int type, struct ConfigSubset *sub, struct ListHead *links)
Definition: graphviz.c:350
void dot_array_actx_body_idx(FILE *fp, struct Body **body_idx, short body_len, short body_max, struct ListHead *links)
Definition: graphviz.c:1521
void dot_account_imap(FILE *fp, struct ImapAccountData *adata, struct ListHead *links)
Definition: graphviz.c:688
void dot_patternlist(FILE *fp, struct PatternList *pl, struct ListHead *links)
Definition: graphviz.c:1719
void dot_type_umask(char *buf, size_t buflen, int umask)
Definition: graphviz.c:172
void dot_graph_footer(FILE *fp, struct ListHead *links)
Definition: graphviz.c:247
void dot_mailbox_node(FILE *fp, struct MailboxNode *mn, struct ListHead *links)
Definition: graphviz.c:613
void dot_mview(FILE *fp, struct MailboxView *mv, struct ListHead *links)
Definition: graphviz.c:869
void dot_account(FILE *fp, struct Account *a, struct ListHead *links)
Definition: graphviz.c:795
void dot_connection(FILE *fp, struct Connection *c, struct ListHead *links)
Definition: graphviz.c:672
void dot_mailbox_mbox(FILE *fp, struct MboxAccountData *mdata, struct ListHead *links)
Definition: graphviz.c:485
void dot_node_link(FILE *fp, void *ptr, const char *name, void *link, const char *colour)
Definition: graphviz.c:297
void dot_type_string(FILE *fp, const char *name, const char *str, bool force)
Definition: graphviz.c:146
void dot_account_notmuch(FILE *fp, struct NmAccountData *adata, struct ListHead *links)
Definition: graphviz.c:767
void dot_type_string_escape(char *buf, size_t buflen)
Definition: graphviz.c:133
void dot_array_actx_fp_idx(FILE *fp, FILE **fp_idx, short fp_len, short fp_max, struct ListHead *links)
Definition: graphviz.c:1503
void dot_attach_ctx(FILE *fp, struct AttachCtx *actx, struct ListHead *links)
Definition: graphviz.c:1547
void dot_path_imap(char *buf, size_t buflen, const char *path)
Definition: graphviz.c:334
void dot_node(FILE *fp, void *ptr, const char *name, const char *colour)
Definition: graphviz.c:282
void dot_mailbox_notmuch(FILE *fp, struct NmMboxData *mdata, struct ListHead *links)
Definition: graphviz.c:518
void dot_pattern(FILE *fp, struct Pattern *pat, struct ListHead *links)
Definition: graphviz.c:1662
void dot_content(FILE *fp, struct Content *cont, struct ListHead *links)
Definition: graphviz.c:981
#define ADD_FLAG(F)
void dot_account_nntp(FILE *fp, struct NntpAccountData *adata, struct ListHead *links)
Definition: graphviz.c:725
void dot_attach_ptr(FILE *fp, struct AttachPtr *aptr, struct ListHead *links)
Definition: graphviz.c:1008
void dot_mailbox_list(FILE *fp, struct MailboxList *ml, struct ListHead *links, bool abbr)
Definition: graphviz.c:655
void dot_ptr(FILE *fp, const char *name, void *ptr, const char *colour)
Definition: graphviz.c:183
#define ADD_BOOL(F)
const char * pattern_type_name(int type)
Definition: graphviz.c:1608
void dot_object_header(FILE *fp, const void *ptr, const char *name, const char *colour)
Definition: graphviz.c:258
void dump_graphviz_patternlist(struct PatternList *pl)
Definition: graphviz.c:1746
void dot_envelope(FILE *fp, struct Envelope *env, struct ListHead *links)
Definition: graphviz.c:1207
void dump_graphviz_attach_ctx(struct AttachCtx *actx)
Definition: graphviz.c:1586
void dot_mailbox(FILE *fp, struct Mailbox *m, struct ListHead *links)
Definition: graphviz.c:533
void dot_mailbox_maildir(FILE *fp, struct MaildirMboxData *mdata, struct ListHead *links)
Definition: graphviz.c:471
void dot_mailbox_nntp(FILE *fp, struct NntpMboxData *mdata, struct ListHead *links)
Definition: graphviz.c:498
void dump_graphviz_email(struct Email *e, const char *title)
Definition: graphviz.c:1409
void dot_add_link(struct ListHead *links, void *src, void *dst, const char *label, bool back, const char *colour)
Definition: graphviz.c:200
void dot_body(FILE *fp, struct Body *b, struct ListHead *links, bool link_next)
Definition: graphviz.c:1035
Imap-specific Account data.
IMAP network mailbox.
Imap-specific Mailbox data.
Shared constants/structs that are private to IMAP.
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
static const char * timestamp(time_t stamp)
Create a YYYY-MM-DD HH:MM:SS timestamp.
Definition: logging.c:77
MailboxType
Supported mailbox formats.
Definition: mailbox.h:41
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition: mailbox.h:51
@ MUTT_MMDF
'mmdf' Mailbox type
Definition: mailbox.h:46
@ MUTT_POP
'POP3' Mailbox type
Definition: mailbox.h:52
@ MUTT_MH
'MH' Mailbox type
Definition: mailbox.h:47
@ MUTT_NNTP
'NNTP' (Usenet) Mailbox type
Definition: mailbox.h:49
@ MUTT_IMAP
'IMAP' Mailbox type
Definition: mailbox.h:50
@ MUTT_MBOX
'mbox' Mailbox type
Definition: mailbox.h:45
@ MUTT_COMPRESSED
Compressed file Mailbox type.
Definition: mailbox.h:53
@ MUTT_MAILDIR
'Maildir' Mailbox type
Definition: mailbox.h:48
Maildir-specific Email data.
Maildir local mailbox type.
Maildir-specific Mailbox data.
Maildir/MH private types.
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
#define FREE(x)
Definition: memory.h:43
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Definition: date.c:924
Convenience wrapper for the library headers.
bool mutt_str_inline_replace(char *buf, size_t buflen, size_t xlen, const char *rstr)
Replace the beginning of a string.
Definition: string.c:940
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:251
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:798
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:228
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:653
char * mutt_str_cat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:266
View of a Mailbox.
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
Nntp-specific Account data.
Usenet network mailbox type; talk to an NNTP server.
Nntp-specific Mailbox data.
Notmuch-specific Account data.
Notmuch virtual mailbox type.
Notmuch-specific Mailbox data.
Notmuch private types.
Match patterns to emails.
@ MUTT_PAT_HEADER
Pattern matches email's header.
Definition: lib.h:150
@ MUTT_PAT_WHOLE_MSG
Pattern matches raw email text.
Definition: lib.h:152
@ MUTT_PAT_BROKEN
Message is part of a broken thread.
Definition: lib.h:146
@ MUTT_PAT_ID_EXTERNAL
Message-Id is among results from an external query.
Definition: lib.h:148
@ MUTT_PAT_OR
Either pattern can match.
Definition: lib.h:132
@ MUTT_PAT_CHILDREN
Pattern matches a child email.
Definition: lib.h:135
@ MUTT_PAT_PARENT
Pattern matches parent.
Definition: lib.h:134
@ MUTT_PAT_REFERENCE
Pattern matches 'References:' or 'In-Reply-To:' field.
Definition: lib.h:157
@ MUTT_PAT_FROM
Pattern matches 'From:' field.
Definition: lib.h:141
@ MUTT_PAT_DRIVER_TAGS
Pattern matches message tags.
Definition: lib.h:170
@ MUTT_PAT_COLLAPSED
Thread is collapsed.
Definition: lib.h:139
@ MUTT_PAT_CRYPT_VERIFIED
Message is crypographically verified.
Definition: lib.h:165
@ MUTT_PAT_HORMEL
Pattern matches email's spam score.
Definition: lib.h:151
@ MUTT_PAT_SUBJECT
Pattern matches 'Subject:' field.
Definition: lib.h:140
@ MUTT_PAT_LIST
Email is on mailing list.
Definition: lib.h:159
@ MUTT_PAT_NEWSGROUPS
Pattern matches newsgroup.
Definition: lib.h:174
@ MUTT_PAT_PERSONAL_RECIP
Email is addressed to the user.
Definition: lib.h:161
@ MUTT_PAT_CC
Pattern matches 'Cc:' field.
Definition: lib.h:137
@ MUTT_PAT_SUBSCRIBED_LIST
Email is on subscribed mailing list.
Definition: lib.h:160
@ MUTT_PAT_SERVERSEARCH
Server-side pattern matches.
Definition: lib.h:169
@ MUTT_PAT_RECIPIENT
User is a recipient of the email.
Definition: lib.h:158
@ MUTT_PAT_CRYPT_ENCRYPT
Message is encrypted.
Definition: lib.h:166
@ MUTT_PAT_UNREFERENCED
Message is unreferenced in the thread.
Definition: lib.h:145
@ MUTT_PAT_CRYPT_SIGN
Message is signed.
Definition: lib.h:164
@ MUTT_PAT_MESSAGE
Pattern matches message number.
Definition: lib.h:154
@ MUTT_PAT_AND
Both patterns must match.
Definition: lib.h:131
@ MUTT_PAT_DATE
Pattern matches 'Date:' field.
Definition: lib.h:142
@ MUTT_PAT_XLABEL
Pattern matches keyword/label.
Definition: lib.h:168
@ MUTT_PAT_SCORE
Pattern matches email's score.
Definition: lib.h:155
@ MUTT_PAT_MIMEATTACH
Pattern matches number of attachments.
Definition: lib.h:171
@ MUTT_PAT_DUPLICATED
Duplicate message.
Definition: lib.h:144
@ MUTT_PAT_PERSONAL_FROM
Email is from the user.
Definition: lib.h:162
@ MUTT_PAT_TO
Pattern matches 'To:' field.
Definition: lib.h:136
@ MUTT_PAT_BCC
Pattern matches 'Bcc:' field.
Definition: lib.h:138
@ MUTT_PAT_SENDER
Pattern matches sender.
Definition: lib.h:153
@ MUTT_PAT_DATE_RECEIVED
Pattern matches date received.
Definition: lib.h:143
@ MUTT_PAT_ADDRESS
Pattern matches any address field.
Definition: lib.h:163
@ MUTT_PAT_MIMETYPE
Pattern matches MIME type.
Definition: lib.h:172
@ MUTT_PAT_PGP_KEY
Message has PGP key.
Definition: lib.h:167
@ MUTT_PAT_ID
Pattern matches email's Message-Id.
Definition: lib.h:147
@ MUTT_PAT_THREAD
Pattern matches email thread.
Definition: lib.h:133
@ MUTT_PAT_SIZE
Pattern matches email's size.
Definition: lib.h:156
@ MUTT_PAT_BODY
Pattern matches email's body.
Definition: lib.h:149
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:106
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:119
Pop-specific Account data.
POP network mailbox.
POP network mailbox.
#define SLIST_FOREACH(var, head, field)
Definition: queue.h:231
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
#define STAILQ_FIRST(head)
Definition: queue.h:350
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define TAILQ_FIRST(head)
Definition: queue.h:723
#define STAILQ_EMPTY(head)
Definition: queue.h:348
#define SLIST_FIRST(head)
Definition: queue.h:229
#define TAILQ_EMPTY(head)
Definition: queue.h:721
Key value store.
A group of associated Mailboxes.
Definition: account.h:37
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
char * name
Name of Account.
Definition: account.h:39
struct ConfigSubset * sub
Inherited config items.
Definition: account.h:40
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct MailboxList mailboxes
List of Mailboxes.
Definition: account.h:41
A set of attachments.
Definition: attach.h:51
short vcount
The number of virtual attachments.
Definition: attach.h:60
short body_len
Number of Body parts.
Definition: attach.h:67
FILE * fp_root
Used by recvattach for updating.
Definition: attach.h:53
short fp_max
Size of FILE array.
Definition: attach.h:64
struct Email * email
Used by recvattach for updating.
Definition: attach.h:52
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:55
struct Body ** body_idx
Extra struct Body* used for decryption.
Definition: attach.h:66
short fp_len
Number of FILE handles.
Definition: attach.h:63
short body_max
Size of Body array.
Definition: attach.h:68
FILE ** fp_idx
Extra FILE* used for decryption.
Definition: attach.h:62
short idxmax
Size of attachment array.
Definition: attach.h:57
short idxlen
Number of attachmentes.
Definition: attach.h:56
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:59
An email to which things will be attached.
Definition: attach.h:35
struct Body * body
Attachment.
Definition: attach.h:36
bool collapsed
Group is collapsed.
Definition: attach.h:44
int num
Attachment index number.
Definition: attach.h:41
int level
Nesting depth of attachment.
Definition: attach.h:40
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
bool unowned
Don't unlink on detach.
Definition: attach.h:42
bool decrypted
Not part of message as stored in the email->body.
Definition: attach.h:43
int parent_type
Type of parent attachment, e.g. TYPE_MULTIPART.
Definition: attach.h:38
The body of an email.
Definition: body.h:36
char * language
content-language (RFC8255)
Definition: body.h:77
char * d_filename
filename to be used for the content-disposition header If NULL, filename is used instead.
Definition: body.h:56
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:72
LOFF_T offset
offset where the actual data begins
Definition: body.h:52
signed short attach_count
Number of attachments.
Definition: body.h:90
char * xtype
content-type if x-unknown
Definition: body.h:61
time_t stamp
Time stamp of last encoding update.
Definition: body.h:76
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:75
LOFF_T length
length (in bytes) of attachment
Definition: body.h:53
char * charset
Send mode: charset of attached file as stored on disk.
Definition: body.h:78
struct ParameterList parameter
Parameters of the content-type.
Definition: body.h:62
struct AttachPtr * aptr
Menu information, used in recvattach.c.
Definition: body.h:74
struct Email * email
header information for message/rfc822
Definition: body.h:73
char * description
content-description
Definition: body.h:55
unsigned int disposition
content-disposition, ContentDisposition
Definition: body.h:42
struct Content * content
Detailed info about the content of the attachment.
Definition: body.h:69
struct Body * next
next attachment in the list
Definition: body.h:71
char * subtype
content-type subtype
Definition: body.h:60
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition: body.h:41
long hdr_offset
Offset in stream where the headers begin.
Definition: body.h:80
char * form_name
Content-Disposition form-data name param.
Definition: body.h:59
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:58
String manipulation buffer.
Definition: buffer.h:34
char * data
Pointer to data.
Definition: buffer.h:35
Private data for compress.
Definition: lib.h:47
const char * cmd_append
append-hook command
Definition: lib.h:48
const char * cmd_open
open-hook command
Definition: lib.h:50
const char * cmd_close
close-hook command
Definition: lib.h:49
A set of inherited config items.
Definition: subset.h:47
const char * name
Scope name of Subset.
Definition: subset.h:48
struct ConfigSet * cs
Parent ConfigSet.
Definition: subset.h:51
char login[128]
Login name.
Definition: connaccount.h:55
char user[128]
Username.
Definition: connaccount.h:56
char pass[256]
Password.
Definition: connaccount.h:57
char host[128]
Server to login to.
Definition: connaccount.h:54
unsigned short port
Port to connect to.
Definition: connaccount.h:58
char inbuf[1024]
Buffer for incoming traffic.
Definition: connection.h:52
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:50
int fd
Socket file descriptor.
Definition: connection.h:54
Info about an attachment.
Definition: content.h:35
long crlf
\r and \n characters
Definition: content.h:39
long hibin
8-bit characters
Definition: content.h:36
long ascii
Number of ascii chars.
Definition: content.h:40
long nulbin
Null characters (0x0)
Definition: content.h:38
long linemax
Length of the longest line in the file.
Definition: content.h:41
long lobin
Unprintable 7-bit chars (eg., control chars)
Definition: content.h:37
The envelope/body of an email.
Definition: email.h:37
unsigned int zminutes
Minutes away from UTC.
Definition: email.h:55
struct Envelope * env
Envelope information.
Definition: email.h:66
int lines
How many lines in the body of this message?
Definition: email.h:60
struct Body * body
List of MIME parts.
Definition: email.h:67
size_t num_hidden
Number of hidden messages in this view (only valid when collapsed is set)
Definition: email.h:122
bool zoccident
True, if west of UTC, False if east.
Definition: email.h:56
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:69
short attach_total
Number of qualifying attachments in message, if attach_valid.
Definition: email.h:114
unsigned int zhours
Hours away from UTC.
Definition: email.h:54
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:58
int vnum
Virtual message number.
Definition: email.h:113
int score
Message score.
Definition: email.h:112
int msgno
Number displayed to the user.
Definition: email.h:110
char * path
Path of Email (for local Mailboxes)
Definition: email.h:68
int index
The absolute (unsorted) message number.
Definition: email.h:109
time_t received
Time when the message was placed in the mailbox.
Definition: email.h:59
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
char * followup_to
List of 'followup-to' fields.
Definition: envelope.h:81
char * message_id
Message ID.
Definition: envelope.h:73
char * x_comment_to
List of 'X-comment-to' fields.
Definition: envelope.h:82
struct AutocryptHeader * autocrypt_gossip
Autocrypt Gossip header.
Definition: envelope.h:90
char * newsgroups
List of newsgroups.
Definition: envelope.h:79
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
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
The item stored in a Hash Table.
Definition: hash.h:44
union HashKey key
Key representing the data.
Definition: hash.h:46
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:45
IMAP-specific Account data -.
Definition: adata.h:40
bool qresync
true, if QRESYNC is successfully ENABLE'd
Definition: adata.h:63
unsigned char seqid
tag sequence prefix
Definition: adata.h:56
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
Definition: adata.h:62
struct Mailbox * mailbox
Current selected mailbox.
Definition: adata.h:76
struct Connection * conn
Connection to IMAP server.
Definition: adata.h:41
IMAP-specific Mailbox data -.
Definition: mdata.h:39
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: mdata.h:42
char * munge_name
Munged version of the mailbox name.
Definition: mdata.h:41
char * name
Mailbox name.
Definition: mdata.h:40
A List node for strings.
Definition: list.h:35
char * data
String.
Definition: list.h:36
List of Mailboxes.
Definition: mailbox.h:152
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:153
View of a Mailbox.
Definition: mview.h:39
bool collapsed
Are all threads collapsed?
Definition: mview.h:48
off_t vsize
Size (in bytes) of the messages shown.
Definition: mview.h:40
struct Mailbox * mailbox
Current Mailbox.
Definition: mview.h:50
char * pattern
Limit pattern string.
Definition: mview.h:41
A mailbox.
Definition: mailbox.h:79
int vcount
The number of virtual messages.
Definition: mailbox.h:99
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:81
int * v2r
Mapping from virtual to real msgno.
Definition: mailbox.h:98
int msg_count
Total number of messages.
Definition: mailbox.h:88
int email_max
Number of pointers in emails.
Definition: mailbox.h:97
enum MailboxType type
Mailbox type.
Definition: mailbox.h:102
void * mdata
Driver specific data.
Definition: mailbox.h:132
struct Email ** emails
Array of Emails.
Definition: mailbox.h:96
char * name
A short name for the Mailbox.
Definition: mailbox.h:82
struct Buffer pathbuf
Path of the Mailbox.
Definition: mailbox.h:80
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:127
int opened
Number of times mailbox is opened.
Definition: mailbox.h:128
void * compress_info
Compressed mbox module private data.
Definition: mailbox.h:120
struct ConfigSubset * sub
Inherited config items.
Definition: mailbox.h:83
Maildir-specific Mailbox data -.
Definition: mdata.h:35
mode_t mh_umask
umask to use when creating files
Definition: mdata.h:37
struct timespec mtime_cur
Timestamp of the 'cur' dir.
Definition: mdata.h:36
Mapping between user-readable string and a constant.
Definition: mapping.h:32
Mbox-specific Account data -.
Definition: lib.h:49
FILE * fp
Mailbox file.
Definition: lib.h:50
bool append
mailbox is opened in append mode
Definition: lib.h:55
bool locked
is the mailbox locked?
Definition: lib.h:54
struct timespec atime
File's last-access time.
Definition: lib.h:51
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Notmuch-specific Account data -.
Definition: adata.h:35
notmuch_database_t * db
Connection to Notmuch database.
Definition: adata.h:36
Notmuch-specific Mailbox data -.
Definition: mdata.h:34
int db_limit
Maximum number of results to return.
Definition: mdata.h:37
NNTP-specific Account data -.
Definition: adata.h:36
time_t newgroups_time
Definition: adata.h:56
bool newsrc_modified
Definition: adata.h:49
bool hasXOVER
Server supports XOVER command.
Definition: adata.h:45
struct Connection * conn
Connection to NNTP Server.
Definition: adata.h:62
char * authenticators
Definition: adata.h:52
char * overview_fmt
Definition: adata.h:53
bool hasXGTITLE
Server supports XGTITLE command.
Definition: adata.h:41
unsigned int groups_num
Definition: adata.h:58
bool hasCAPABILITIES
Server supports CAPABILITIES command.
Definition: adata.h:37
bool hasSTARTTLS
Server supports STARTTLS command.
Definition: adata.h:38
bool hasLISTGROUPrange
Server supports LISTGROUPrange command.
Definition: adata.h:43
time_t check_time
Definition: adata.h:57
time_t mtime
Definition: adata.h:55
unsigned int groups_max
Definition: adata.h:59
bool hasLISTGROUP
Server supports LISTGROUP command.
Definition: adata.h:42
FILE * fp_newsrc
Definition: adata.h:50
bool cacheable
Definition: adata.h:48
bool hasOVER
Server supports OVER command.
Definition: adata.h:44
char * newsrc_file
Definition: adata.h:51
bool hasDATE
Server supports DATE command.
Definition: adata.h:39
bool hasLIST_NEWSGROUPS
Server supports LIST_NEWSGROUPS command.
Definition: adata.h:40
NNTP-specific Mailbox data -.
Definition: mdata.h:33
anum_t last_cached
Definition: mdata.h:39
bool deleted
Definition: mdata.h:44
bool allowed
Definition: mdata.h:43
anum_t last_message
Definition: mdata.h:37
char * group
Name of newsgroup.
Definition: mdata.h:34
char * desc
Description of newsgroup.
Definition: mdata.h:35
anum_t unread
Definition: mdata.h:40
anum_t last_loaded
Definition: mdata.h:38
bool has_new_mail
Definition: mdata.h:42
anum_t first_message
Definition: mdata.h:36
bool subscribed
Definition: mdata.h:41
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
A simple (non-regex) pattern.
Definition: lib.h:71
bool group_match
Check a group of Addresses.
Definition: lib.h:76
union Pattern::@1 p
struct PatternList * child
Arguments to logical operation.
Definition: lib.h:84
long min
Minimum for range checks.
Definition: lib.h:82
bool string_match
Check a string for a match.
Definition: lib.h:75
regex_t * regex
Compiled regex, for non-pattern matching.
Definition: lib.h:86
char * str
String, if string_match is set.
Definition: lib.h:88
long max
Maximum for range checks.
Definition: lib.h:83
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition: lib.h:72
bool is_multi
Multiple case (only for ~I pattern now)
Definition: lib.h:81
POP-specific Account data -.
Definition: adata.h:37
time_t check_time
Definition: adata.h:51
struct Connection * conn
Connection to POP server.
Definition: adata.h:38
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:69
char * user
Username.
Definition: url.h:71
char * host
Host.
Definition: url.h:73
char * path
Path.
Definition: url.h:75
time_t tv_sec
Number of seconds since the epoch.
Definition: file.h:51
int cs_subset_he_string_get(const struct ConfigSubset *sub, struct HashElem *he, struct Buffer *result)
Get a config item as a string.
Definition: subset.c:359
struct HashElem ** get_elem_list(struct ConfigSet *cs)
Create a sorted list of all config items.
Definition: subset.c:76
#define DT_INHERIT_MBOX
Config item can be Mailbox-specific.
Definition: types.h:55
#define DTYPE(x)
Mask for the Data Type.
Definition: types.h:45
#define DT_INHERIT_ACC
Config item can be Account-specific.
Definition: types.h:54
#define DT_STRING
a string
Definition: types.h:41
#define DT_SENSITIVE
Contains sensitive value, e.g. password.
Definition: types.h:52
const char * strkey
String key.
Definition: hash.h:36
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:238
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123