NeoMutt  2025-12-11-435-g4ac674
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
exec.c
Go to the documentation of this file.
1
27
33
34#include "config.h"
35#include <stdarg.h> // IWYU pragma: keep
36#include <stdbool.h>
37#include <stdio.h>
38#include <string.h>
39#include <unistd.h>
40#include "private.h"
41#include "mutt/lib.h"
42#include "address/lib.h"
43#include "config/lib.h"
44#include "email/lib.h"
45#include "core/lib.h"
46#include "alias/alias.h" // IWYU pragma: keep
47#include "alias/gui.h" // IWYU pragma: keep
48#include "alias/lib.h"
49#include "mutt.h"
50#include "lib.h"
51#include "attach/lib.h"
52#include "ncrypt/lib.h"
53#include "send/lib.h"
54#include "mx.h"
55#ifndef USE_FMEMOPEN
56#include <sys/stat.h>
57#endif
58
59static bool pattern_exec(struct Pattern *pat, PatternExecFlags flags,
60 struct Mailbox *m, struct Email *e,
61 struct Message *msg, struct PatternCache *cache);
62
70static bool patmatch(const struct Pattern *pat, const char *buf)
71{
72 if (pat->is_multi)
73 return (mutt_list_find(&pat->p.multi_cases, buf) != NULL);
74 if (pat->string_match)
75 return pat->ign_case ? mutt_istr_find(buf, pat->p.str) : strstr(buf, pat->p.str);
76 if (pat->group_match)
77 return group_match(pat->p.group, buf);
78 return (regexec(pat->p.regex, buf, 0, NULL, 0) == 0);
79}
80
86{
87 const struct PatternFlags *entry = lookup_op(op);
88 if (entry)
89 {
90 /* L10N: One of the crypt pattern operators: ~g, ~G, ~k, ~V
91 was invoked when NeoMutt was compiled without crypto support.
92 %c%c is the pattern prefix and character, e.g. "~g". */
93 mutt_error(_("Pattern operator '%c%c' is disabled"), entry->prefix, entry->tag);
94 }
95 else
96 {
97 /* L10N: An unknown pattern operator was somehow invoked.
98 This shouldn't be possible unless there is a bug. */
99 mutt_error(_("error: unknown op %d (report this error)"), op);
100 }
101}
102
111static bool msg_search(struct Pattern *pat, struct Email *e, struct Message *msg)
112{
113 ASSERT(msg);
114
115 bool match = false;
116
117 FILE *fp = NULL;
118 long len = 0;
119#ifdef USE_FMEMOPEN
120 char *temp = NULL;
121 size_t tempsize = 0;
122#else
123 struct stat st = { 0 };
124#endif
125
126 const bool needs_head = (pat->op == MUTT_PAT_HEADER) || (pat->op == MUTT_PAT_WHOLE_MSG);
127 const bool needs_body = (pat->op == MUTT_PAT_BODY) || (pat->op == MUTT_PAT_WHOLE_MSG);
128 const bool c_thorough_search = cs_subset_bool(NeoMutt->sub, "thorough_search");
129 if (c_thorough_search)
130 {
131 /* decode the header / body */
132 struct State state = { 0 };
133 state.fp_in = msg->fp;
134 state.flags = STATE_CHARCONV;
135#ifdef USE_FMEMOPEN
136 state.fp_out = open_memstream(&temp, &tempsize);
137 if (!state.fp_out)
138 {
139 mutt_perror(_("Error opening 'memory stream'"));
140 return false;
141 }
142#else
143 state.fp_out = mutt_file_mkstemp();
144 if (!state.fp_out)
145 {
146 mutt_perror(_("Can't create temporary file"));
147 return false;
148 }
149#endif
150
151 if (needs_head)
152 {
153 mutt_copy_header(msg->fp, e, state.fp_out, CH_FROM | CH_DECODE, NULL, 0);
154 }
155
156 if (needs_body)
157 {
159
160 if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT) &&
162 {
163 if (state.fp_out)
164 {
165 mutt_file_fclose(&state.fp_out);
166#ifdef USE_FMEMOPEN
167 FREE(&temp);
168#endif
169 }
170 return false;
171 }
172
173 if (!mutt_file_seek(msg->fp, e->offset, SEEK_SET))
174 {
175#ifdef USE_FMEMOPEN
176 FREE(&temp);
177#endif
178 mutt_file_fclose(&state.fp_out);
179 return false;
180 }
181 mutt_body_handler(e->body, &state);
182 }
183
184#ifdef USE_FMEMOPEN
185 mutt_file_fclose(&state.fp_out);
186 len = tempsize;
187
188 if (tempsize != 0)
189 {
190 fp = fmemopen(temp, tempsize, "r");
191 if (!fp)
192 {
193 mutt_perror(_("Error re-opening 'memory stream'"));
194 FREE(&temp);
195 return false;
196 }
197 }
198 else
199 { /* fmemopen can't handle empty buffers */
200 fp = mutt_file_fopen("/dev/null", "r");
201 if (!fp)
202 {
203 mutt_perror(_("Error opening /dev/null"));
204 FREE(&temp);
205 return false;
206 }
207 }
208#else
209 fp = state.fp_out;
210 fflush(fp);
211 if (!mutt_file_seek(fp, 0, SEEK_SET) || fstat(fileno(fp), &st))
212 {
213 mutt_perror(_("Error checking length of temporary file"));
214 mutt_file_fclose(&fp);
215 return false;
216 }
217 len = (long) st.st_size;
218#endif
219 }
220 else
221 {
222 /* raw header / body */
223 fp = msg->fp;
224 if (needs_head)
225 {
226 if (!mutt_file_seek(fp, e->offset, SEEK_SET))
227 {
228 return false;
229 }
230 len = e->body->offset - e->offset;
231 }
232 if (needs_body)
233 {
234 if (pat->op == MUTT_PAT_BODY)
235 {
236 if (!mutt_file_seek(fp, e->body->offset, SEEK_SET))
237 {
238 return false;
239 }
240 }
241 len += e->body->length;
242 }
243 }
244
245 /* search the file "fp" */
246 if (pat->op == MUTT_PAT_HEADER)
247 {
248 struct Buffer *buf = buf_pool_get();
249 while (len > 0)
250 {
251 if (mutt_rfc822_read_line(fp, buf) == 0)
252 {
253 break;
254 }
255 len -= buf_len(buf);
256 if (patmatch(pat, buf_string(buf)))
257 {
258 match = true;
259 break;
260 }
261 }
262 buf_pool_release(&buf);
263 }
264 else
265 {
266 char buf[1024] = { 0 };
267 while (len > 0)
268 {
269 if (!fgets(buf, sizeof(buf), fp))
270 {
271 break; /* don't loop forever */
272 }
273 len -= mutt_str_len(buf);
274 if (patmatch(pat, buf))
275 {
276 match = true;
277 break;
278 }
279 }
280 }
281
282 if (c_thorough_search)
283 mutt_file_fclose(&fp);
284
285#ifdef USE_FMEMOPEN
286 FREE(&temp);
287#endif
288
289 return match;
290}
291
302static bool perform_and(struct PatternList *pat, PatternExecFlags flags,
303 struct Mailbox *m, struct Email *e, struct Message *msg,
304 struct PatternCache *cache)
305{
306 struct Pattern *p = NULL;
307
308 SLIST_FOREACH(p, pat, entries)
309 {
310 if (!pattern_exec(p, flags, m, e, msg, cache))
311 {
312 return false;
313 }
314 }
315 return true;
316}
317
326static bool perform_alias_and(struct PatternList *pat, PatternExecFlags flags,
327 struct AliasView *av, struct PatternCache *cache)
328{
329 struct Pattern *p = NULL;
330
331 SLIST_FOREACH(p, pat, entries)
332 {
333 if (!mutt_pattern_alias_exec(p, flags, av, cache))
334 {
335 return false;
336 }
337 }
338 return true;
339}
340
351static int perform_or(struct PatternList *pat, PatternExecFlags flags,
352 struct Mailbox *m, struct Email *e, struct Message *msg,
353 struct PatternCache *cache)
354{
355 struct Pattern *p = NULL;
356
357 SLIST_FOREACH(p, pat, entries)
358 {
359 if (pattern_exec(p, flags, m, e, msg, cache))
360 {
361 return true;
362 }
363 }
364 return false;
365}
366
375static int perform_alias_or(struct PatternList *pat, PatternExecFlags flags,
376 struct AliasView *av, struct PatternCache *cache)
377{
378 struct Pattern *p = NULL;
379
380 SLIST_FOREACH(p, pat, entries)
381 {
382 if (mutt_pattern_alias_exec(p, flags, av, cache))
383 {
384 return true;
385 }
386 }
387 return false;
388}
389
396static bool match_tags(struct Pattern *pat, struct TagList *tags)
397{
398 struct Tag *tag = NULL;
399 bool matched = false;
400 STAILQ_FOREACH(tag, tags, entries)
401 {
402 matched |= patmatch(pat, tag->name);
403 }
404 return pat->pat_not ^ matched;
405}
406
417static int match_addrlist(struct Pattern *pat, bool match_personal, int n, ...)
418{
419 va_list ap;
420
421 va_start(ap, n);
422 while (n-- > 0)
423 {
424 struct AddressList *al = va_arg(ap, struct AddressList *);
425 struct Address *a = NULL;
426 TAILQ_FOREACH(a, al, entries)
427 {
428 if (pat->all_addr ^
429 ((!pat->is_alias || alias_reverse_lookup(a)) &&
430 ((a->mailbox && patmatch(pat, buf_string(a->mailbox))) ||
431 (match_personal && a->personal && patmatch(pat, buf_string(a->personal))))))
432 {
433 va_end(ap);
434 return !pat->all_addr; /* Found match, or non-match if all_addr */
435 }
436 }
437 }
438 va_end(ap);
439 return pat->all_addr; /* No matches, or all matches if all_addr */
440}
441
448static bool match_reference(struct Pattern *pat, struct ListHead *refs)
449{
450 struct ListNode *np = NULL;
451 STAILQ_FOREACH(np, refs, entries)
452 {
453 if (patmatch(pat, np->data))
454 return true;
455 }
456 return false;
457}
458
470static bool mutt_is_predicate_recipient(bool all_addr, struct Envelope *env, addr_predicate_t p)
471{
472 struct AddressList *als[] = { &env->to, &env->cc };
473 for (size_t i = 0; i < countof(als); i++)
474 {
475 struct AddressList *al = als[i];
476 struct Address *a = NULL;
477 TAILQ_FOREACH(a, al, entries)
478 {
479 if (all_addr ^ p(a))
480 return !all_addr;
481 }
482 }
483 return all_addr;
484}
485
494bool mutt_is_subscribed_list_recipient(bool all_addr, struct Envelope *env)
495{
497}
498
507bool mutt_is_list_recipient(bool all_addr, struct Envelope *env)
508{
509 return mutt_is_predicate_recipient(all_addr, env, &mutt_is_mail_list);
510}
511
521static int match_user(bool all_addr, int n, ...)
522{
523 va_list ap;
524
525 va_start(ap, n);
526 while (n-- > 0)
527 {
528 struct AddressList *al = va_arg(ap, struct AddressList *);
529 struct Address *a = NULL;
530 TAILQ_FOREACH(a, al, entries)
531 {
532 if (all_addr ^ mutt_addr_is_user(a))
533 {
534 va_end(ap);
535 return !all_addr;
536 }
537 }
538 }
539 va_end(ap);
540 return all_addr;
541}
542
556static int match_threadcomplete(struct PatternList *pat, PatternExecFlags flags,
557 struct Mailbox *m, struct MuttThread *t,
558 int left, int up, int right, int down)
559{
560 if (!t)
561 return 0;
562
563 int a;
564 struct Email *e = t->message;
565 if (e)
566 if (mutt_pattern_exec(SLIST_FIRST(pat), flags, m, e, NULL))
567 return 1;
568
569 if (up && (a = match_threadcomplete(pat, flags, m, t->parent, 1, 1, 1, 0)))
570 return a;
571 if (right && t->parent && (a = match_threadcomplete(pat, flags, m, t->next, 0, 0, 1, 1)))
572 {
573 return a;
574 }
575 if (left && t->parent && (a = match_threadcomplete(pat, flags, m, t->prev, 1, 0, 0, 1)))
576 {
577 return a;
578 }
579 if (down && (a = match_threadcomplete(pat, flags, m, t->child, 1, 0, 1, 1)))
580 return a;
581 return 0;
582}
583
594static int match_threadparent(struct PatternList *pat, PatternExecFlags flags,
595 struct Mailbox *m, struct MuttThread *t)
596{
597 if (!t || !t->parent || !t->parent->message)
598 return 0;
599
600 return mutt_pattern_exec(SLIST_FIRST(pat), flags, m, t->parent->message, NULL);
601}
602
613static int match_threadchildren(struct PatternList *pat, PatternExecFlags flags,
614 struct Mailbox *m, struct MuttThread *t)
615{
616 if (!t || !t->child)
617 return 0;
618
619 for (t = t->child; t; t = t->next)
620 if (t->message && mutt_pattern_exec(SLIST_FIRST(pat), flags, m, t->message, NULL))
621 return 1;
622
623 return 0;
624}
625
633static bool match_content_type(const struct Pattern *pat, struct Body *b)
634{
635 if (!b)
636 return false;
637
638 char buf[256] = { 0 };
639 snprintf(buf, sizeof(buf), "%s/%s", BODY_TYPE(b), b->subtype);
640
641 if (patmatch(pat, buf))
642 return true;
643 if (match_content_type(pat, b->parts))
644 return true;
645 if (match_content_type(pat, b->next))
646 return true;
647 return false;
648}
649
658static bool match_mime_content_type(const struct Pattern *pat, struct Email *e, FILE *fp)
659{
661 return match_content_type(pat, e->body);
662}
663
670static bool match_update_dynamic_date(struct Pattern *pat)
671{
672 struct Buffer *err = buf_pool_get();
673
674 bool rc = eval_date_minmax(pat, pat->p.str, err);
675 buf_pool_release(&err);
676
677 return rc;
678}
679
687static void set_pattern_cache_value(int *cache_entry, int value)
688{
689 *cache_entry = (value != 0) ? 2 : 1;
690}
691
698static bool get_pattern_cache_value(int cache_entry)
699{
700 return cache_entry == 2;
701}
702
708static int is_pattern_cache_set(int cache_entry)
709{
710 return cache_entry != 0;
711}
712
721static int msg_search_sendmode(struct Email *e, struct Pattern *pat)
722{
723 bool match = false;
724 char *buf = NULL;
725 size_t blen = 0;
726 FILE *fp = NULL;
727
728 if ((pat->op == MUTT_PAT_HEADER) || (pat->op == MUTT_PAT_WHOLE_MSG))
729 {
730 struct Buffer *tempfile = buf_pool_get();
731 buf_mktemp(tempfile);
732 fp = mutt_file_fopen(buf_string(tempfile), "w+");
733 if (!fp)
734 {
735 mutt_perror("%s", buf_string(tempfile));
736 buf_pool_release(&tempfile);
737 return 0;
738 }
739
741 false, false, NeoMutt->sub);
742 fflush(fp);
743 if (mutt_file_seek(fp, 0, SEEK_SET))
744 {
745 while ((buf = mutt_file_read_line(buf, &blen, fp, NULL, MUTT_RL_NO_FLAGS)) != NULL)
746 {
747 if (patmatch(pat, buf) == 0)
748 {
749 match = true;
750 break;
751 }
752 }
753 }
754
755 FREE(&buf);
756 mutt_file_fclose(&fp);
757 unlink(buf_string(tempfile));
758 buf_pool_release(&tempfile);
759
760 if (match)
761 return match;
762 }
763
764 if ((pat->op == MUTT_PAT_BODY) || (pat->op == MUTT_PAT_WHOLE_MSG))
765 {
766 fp = mutt_file_fopen(e->body->filename, "r");
767 if (!fp)
768 {
769 mutt_perror("%s", e->body->filename);
770 return 0;
771 }
772
773 while ((buf = mutt_file_read_line(buf, &blen, fp, NULL, MUTT_RL_NO_FLAGS)) != NULL)
774 {
775 if (patmatch(pat, buf) == 0)
776 {
777 match = true;
778 break;
779 }
780 }
781
782 FREE(&buf);
783 mutt_file_fclose(&fp);
784 }
785
786 return match;
787}
788
796static bool pattern_needs_msg(const struct Mailbox *m, const struct Pattern *pat)
797{
798 if (!m)
799 {
800 return false;
801 }
802
803 if ((pat->op == MUTT_PAT_MIMETYPE) || (pat->op == MUTT_PAT_MIMEATTACH))
804 {
805 return true;
806 }
807
808 if ((pat->op == MUTT_PAT_WHOLE_MSG) || (pat->op == MUTT_PAT_BODY) || (pat->op == MUTT_PAT_HEADER))
809 {
810 return !((m->type == MUTT_IMAP) && pat->string_match);
811 }
812
813 if ((pat->op == MUTT_PAT_AND) || (pat->op == MUTT_PAT_OR))
814 {
815 struct Pattern *p = NULL;
816 SLIST_FOREACH(p, pat->child, entries)
817 {
818 if (pattern_needs_msg(m, p))
819 {
820 return true;
821 }
822 }
823 }
824
825 return false;
826}
827
843static bool pattern_exec(struct Pattern *pat, PatternExecFlags flags,
844 struct Mailbox *m, struct Email *e,
845 struct Message *msg, struct PatternCache *cache)
846{
847 switch (pat->op)
848 {
849 case MUTT_PAT_AND:
850 return pat->pat_not ^ (perform_and(pat->child, flags, m, e, msg, cache) > 0);
851 case MUTT_PAT_OR:
852 return pat->pat_not ^ (perform_or(pat->child, flags, m, e, msg, cache) > 0);
853 case MUTT_PAT_THREAD:
854 return pat->pat_not ^
855 match_threadcomplete(pat->child, flags, m, e->thread, 1, 1, 1, 1);
856 case MUTT_PAT_PARENT:
857 return pat->pat_not ^ match_threadparent(pat->child, flags, m, e->thread);
859 return pat->pat_not ^ match_threadchildren(pat->child, flags, m, e->thread);
860 case MUTT_ALL:
861 return !pat->pat_not;
862 case MUTT_EXPIRED:
863 return pat->pat_not ^ e->expired;
864 case MUTT_SUPERSEDED:
865 return pat->pat_not ^ e->superseded;
866 case MUTT_FLAG:
867 return pat->pat_not ^ e->flagged;
868 case MUTT_TAG:
869 return pat->pat_not ^ e->tagged;
870 case MUTT_NEW:
871 return pat->pat_not ? e->old || e->read : !(e->old || e->read);
872 case MUTT_UNREAD:
873 return pat->pat_not ? e->read : !e->read;
874 case MUTT_REPLIED:
875 return pat->pat_not ^ e->replied;
876 case MUTT_OLD:
877 return pat->pat_not ? (!e->old || e->read) : (e->old && !e->read);
878 case MUTT_READ:
879 return pat->pat_not ^ e->read;
880 case MUTT_DELETED:
881 return pat->pat_not ^ e->deleted;
882 case MUTT_PAT_MESSAGE:
883 return pat->pat_not ^
884 ((email_msgno(e) >= pat->min) && (email_msgno(e) <= pat->max));
885 case MUTT_PAT_DATE:
886 if (pat->dynamic)
888 return pat->pat_not ^ ((e->date_sent >= pat->min) && (e->date_sent <= pat->max));
890 if (pat->dynamic)
892 return pat->pat_not ^ ((e->received >= pat->min) && (e->received <= pat->max));
893 case MUTT_PAT_BODY:
894 case MUTT_PAT_HEADER:
896 if (pat->sendmode)
897 {
898 if (!e->body || !e->body->filename)
899 return false;
900 return pat->pat_not ^ msg_search_sendmode(e, pat);
901 }
902 /* m can be NULL in certain cases, such as when replying to a message
903 * from the attachment menu and the user has a reply-hook using "~e".
904 * This is also the case when message scoring. */
905 if (!m)
906 return false;
907 /* IMAP search sets e->matched at search compile time */
908 if ((m->type == MUTT_IMAP) && pat->string_match)
909 return e->matched;
910 return pat->pat_not ^ msg_search(pat, e, msg);
912 if (!m)
913 return false;
914 if (m->type == MUTT_IMAP)
915 {
916 return (pat->string_match) ? e->matched : false;
917 }
918 mutt_error(_("error: server custom search only supported with IMAP"));
919 return false;
920 case MUTT_PAT_SENDER:
921 if (!e->env)
922 return false;
923 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
924 1, &e->env->sender);
925 case MUTT_PAT_FROM:
926 if (!e->env)
927 return false;
928 return pat->pat_not ^
929 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->from);
930 case MUTT_PAT_TO:
931 if (!e->env)
932 return false;
933 return pat->pat_not ^
934 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->to);
935 case MUTT_PAT_CC:
936 if (!e->env)
937 return false;
938 return pat->pat_not ^
939 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->cc);
940 case MUTT_PAT_BCC:
941 if (!e->env)
942 return false;
943 return pat->pat_not ^
944 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->bcc);
945 case MUTT_PAT_SUBJECT:
946 if (!e->env)
947 return false;
948 return pat->pat_not ^ (e->env->subject && patmatch(pat, e->env->subject));
949 case MUTT_PAT_ID:
951 if (!e->env)
952 return false;
953 return pat->pat_not ^ (e->env->message_id && patmatch(pat, e->env->message_id));
954 case MUTT_PAT_SCORE:
955 return pat->pat_not ^ (e->score >= pat->min &&
956 (pat->max == MUTT_MAXRANGE || e->score <= pat->max));
957 case MUTT_PAT_SIZE:
958 return pat->pat_not ^ (e->body->length >= pat->min &&
959 (pat->max == MUTT_MAXRANGE || e->body->length <= pat->max));
961 if (!e->env)
962 return false;
963 return pat->pat_not ^ (match_reference(pat, &e->env->references) ||
964 match_reference(pat, &e->env->in_reply_to));
965 case MUTT_PAT_ADDRESS:
966 if (!e->env)
967 return false;
968 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
969 5, &e->env->from, &e->env->sender,
970 &e->env->to, &e->env->cc, &e->env->bcc);
972 if (!e->env)
973 return false;
974 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 3,
975 &e->env->to, &e->env->cc, &e->env->bcc);
976 case MUTT_PAT_LIST: /* known list, subscribed or not */
977 {
978 if (!e->env)
979 return false;
980
981 bool result;
982 if (cache)
983 {
984 int *cache_entry = pat->all_addr ? &cache->list_all : &cache->list_one;
985 if (!is_pattern_cache_set(*cache_entry))
986 {
987 set_pattern_cache_value(cache_entry,
989 }
990 result = get_pattern_cache_value(*cache_entry);
991 }
992 else
993 {
994 result = mutt_is_list_recipient(pat->all_addr, e->env);
995 }
996 return pat->pat_not ^ result;
997 }
999 {
1000 if (!e->env)
1001 return false;
1002
1003 bool result;
1004 if (cache)
1005 {
1006 int *cache_entry = pat->all_addr ? &cache->sub_all : &cache->sub_one;
1007 if (!is_pattern_cache_set(*cache_entry))
1008 {
1009 set_pattern_cache_value(cache_entry,
1011 }
1012 result = get_pattern_cache_value(*cache_entry);
1013 }
1014 else
1015 {
1017 }
1018 return pat->pat_not ^ result;
1019 }
1021 {
1022 if (!e->env)
1023 return false;
1024
1025 bool result;
1026 if (cache)
1027 {
1028 int *cache_entry = pat->all_addr ? &cache->pers_recip_all : &cache->pers_recip_one;
1029 if (!is_pattern_cache_set(*cache_entry))
1030 {
1031 set_pattern_cache_value(cache_entry,
1032 match_user(pat->all_addr, 3, &e->env->to,
1033 &e->env->cc, &e->env->bcc));
1034 }
1035 result = get_pattern_cache_value(*cache_entry);
1036 }
1037 else
1038 {
1039 result = match_user(pat->all_addr, 3, &e->env->to, &e->env->cc, &e->env->bcc);
1040 }
1041 return pat->pat_not ^ result;
1042 }
1044 {
1045 if (!e->env)
1046 return false;
1047
1048 bool result;
1049 if (cache)
1050 {
1051 int *cache_entry = pat->all_addr ? &cache->pers_from_all : &cache->pers_from_one;
1052 if (!is_pattern_cache_set(*cache_entry))
1053 {
1054 set_pattern_cache_value(cache_entry,
1055 match_user(pat->all_addr, 1, &e->env->from));
1056 }
1057 result = get_pattern_cache_value(*cache_entry);
1058 }
1059 else
1060 {
1061 result = match_user(pat->all_addr, 1, &e->env->from);
1062 }
1063 return pat->pat_not ^ result;
1064 }
1065 case MUTT_PAT_COLLAPSED:
1066 return pat->pat_not ^ (e->collapsed && e->num_hidden > 1);
1068 if (!WithCrypto)
1069 {
1071 return false;
1072 }
1073 return pat->pat_not ^ ((e->security & SEC_SIGN) ? 1 : 0);
1075 if (!WithCrypto)
1076 {
1078 return false;
1079 }
1080 return pat->pat_not ^ ((e->security & SEC_GOODSIGN) ? 1 : 0);
1082 if (!WithCrypto)
1083 {
1085 return false;
1086 }
1087 return pat->pat_not ^ ((e->security & SEC_ENCRYPT) ? 1 : 0);
1088 case MUTT_PAT_PGP_KEY:
1089 if (!(WithCrypto & APPLICATION_PGP))
1090 {
1092 return false;
1093 }
1094 return pat->pat_not ^ ((e->security & PGP_KEY) == PGP_KEY);
1095 case MUTT_PAT_XLABEL:
1096 if (!e->env)
1097 return false;
1098 return pat->pat_not ^ (e->env->x_label && patmatch(pat, e->env->x_label));
1100 {
1101 return match_tags(pat, &e->tags);
1102 }
1103 case MUTT_PAT_HORMEL:
1104 if (!e->env)
1105 return false;
1106 return pat->pat_not ^ (e->env->spam.data && patmatch(pat, e->env->spam.data));
1108 return pat->pat_not ^ (e->thread && e->thread->duplicate_thread);
1110 {
1111 int count = msg ? mutt_count_body_parts(e, msg->fp) : 0;
1112 return pat->pat_not ^
1113 (count >= pat->min && (pat->max == MUTT_MAXRANGE || count <= pat->max));
1114 }
1115 case MUTT_PAT_MIMETYPE:
1116 if (!m || !msg)
1117 return false;
1118 return pat->pat_not ^ match_mime_content_type(pat, e, msg->fp);
1120 return pat->pat_not ^ (e->thread && !e->thread->child);
1121 case MUTT_PAT_BROKEN:
1122 return pat->pat_not ^ (e->thread && e->thread->fake_thread);
1124 if (!e->env)
1125 return false;
1126 return pat->pat_not ^ (e->env->newsgroups && patmatch(pat, e->env->newsgroups));
1127 }
1128 mutt_error(_("error: unknown op %d (report this error)"), pat->op);
1129 return false;
1130}
1131
1147 struct Mailbox *m, struct Email *e, struct PatternCache *cache)
1148{
1149 const bool needs_msg = pattern_needs_msg(m, pat);
1150 struct Message *msg = needs_msg ? mx_msg_open(m, e) : NULL;
1151 if (needs_msg && !msg)
1152 {
1153 return false;
1154 }
1155 const bool matched = pattern_exec(pat, flags, m, e, msg, cache);
1156 mx_msg_close(m, &msg);
1157 return matched;
1158}
1159
1174 struct AliasView *av, struct PatternCache *cache)
1175{
1176 switch (pat->op)
1177 {
1178 case MUTT_PAT_FROM: /* alias */
1179 if (!av->alias)
1180 return false;
1181 return pat->pat_not ^ (av->alias->name && patmatch(pat, av->alias->name));
1182 case MUTT_PAT_CC: /* comment */
1183 if (!av->alias)
1184 return false;
1185 return pat->pat_not ^ (av->alias->comment && patmatch(pat, av->alias->comment));
1186 case MUTT_PAT_TO: /* alias address list */
1187 if (!av->alias)
1188 return false;
1189 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
1190 1, &av->alias->addr);
1192 if (!av->alias)
1193 return false;
1194 return match_tags(pat, &av->alias->tags);
1195 case MUTT_PAT_AND:
1196 return pat->pat_not ^ (perform_alias_and(pat->child, flags, av, cache) > 0);
1197 case MUTT_PAT_OR:
1198 return pat->pat_not ^ (perform_alias_or(pat->child, flags, av, cache) > 0);
1199 }
1200
1201 return false;
1202}
bool group_match(struct Group *g, const char *str)
Does a string match an entry in a Group?
Definition group.c:161
Email Address Handling.
bool(* addr_predicate_t)(const struct Address *a)
Definition address.h:55
Email Aliases.
struct Address * alias_reverse_lookup(const struct Address *addr)
Does the user have an alias for the given address.
Definition reverse.c:112
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition alias.c:600
Representation of a single alias to an email address.
void mutt_parse_mime_message(struct Email *e, FILE *fp)
Parse a MIME email.
Definition commands.c:627
int mutt_count_body_parts(struct Email *e, FILE *fp)
Count the MIME Body parts.
Definition commands.c:226
GUI display the mailboxes in a side panel.
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition buffer.c:491
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
bool eval_date_minmax(struct Pattern *pat, const char *s, struct Buffer *err)
Evaluate a date-range pattern against 'now'.
Definition compile.c:544
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
Convenience wrapper for the config headers.
int mutt_copy_header(FILE *fp_in, struct Email *e, FILE *fp_out, CopyHeaderFlags chflags, const char *prefix, int wraplen)
Copy Email header.
Definition copy_email.c:432
#define CH_DECODE
Do RFC2047 header decoding.
Definition copy_email.h:58
#define CH_FROM
Retain the "From " message separator?
Definition copy_email.h:60
Convenience wrapper for the core headers.
@ MUTT_IMAP
'IMAP' Mailbox type
Definition mailbox.h:49
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition crypt.c:131
Structs that make up an email.
size_t mutt_rfc822_read_line(FILE *fp, struct Buffer *buf)
Read a header line from a file.
Definition parse.c:1130
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, ReadLineFlags flags)
Read a line from a file.
Definition file.c:682
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition file.c:652
#define mutt_file_fclose(FP)
Definition file.h:139
#define mutt_file_fopen(PATH, MODE)
Definition file.h:138
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition file.h:40
bool mutt_is_mail_list(const struct Address *addr)
Is this the email address of a mailing list?
Definition maillist.c:45
bool mutt_is_subscribed_list(const struct Address *addr)
Is this the email address of a user-subscribed mailing list?
Definition maillist.c:60
#define mutt_error(...)
Definition logging2.h:94
#define mutt_perror(...)
Definition logging2.h:95
Shared code for the Alias and Query Dialogs.
int mutt_body_handler(struct Body *b, struct State *state)
Handler for the Body of an email.
Definition handler.c:1659
struct ListNode * mutt_list_find(const struct ListHead *h, const char *data)
Find a string in a List.
Definition list.c:103
#define countof(x)
Definition memory.h:49
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define BODY_TYPE(body)
Get the type name of a body part.
Definition mime.h:93
Convenience wrapper for the library headers.
#define _(a)
Definition message.h:28
#define STATE_CHARCONV
Do character set conversions.
Definition state.h:37
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case)
Definition string.c:525
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:500
Many unsorted constants and some structs.
@ MUTT_ALL
All messages.
Definition mutt.h:87
@ MUTT_SUPERSEDED
Superseded messages.
Definition mutt.h:103
@ MUTT_EXPIRED
Expired messages.
Definition mutt.h:102
@ MUTT_READ
Messages that have been read.
Definition mutt.h:92
@ MUTT_OLD
Old messages.
Definition mutt.h:90
@ MUTT_TAG
Tagged messages.
Definition mutt.h:99
@ MUTT_FLAG
Flagged messages.
Definition mutt.h:98
@ MUTT_DELETED
Deleted messages.
Definition mutt.h:97
@ MUTT_NEW
New messages.
Definition mutt.h:89
@ MUTT_UNREAD
Unread messages.
Definition mutt.h:93
@ MUTT_REPLIED
Messages that have been replied to.
Definition mutt.h:91
int mx_msg_close(struct Mailbox *m, struct Message **ptr)
Close a message.
Definition mx.c:1182
struct Message * mx_msg_open(struct Mailbox *m, struct Email *e)
Return a stream pointer for a message.
Definition mx.c:1136
API for mailboxes.
API for encryption/signing of emails.
#define SEC_GOODSIGN
Email has a valid signature.
Definition lib.h:88
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition lib.h:98
#define SEC_ENCRYPT
Email is encrypted.
Definition lib.h:86
#define PGP_KEY
Email contains a PGP key.
Definition lib.h:107
#define WithCrypto
Definition lib.h:124
#define SEC_SIGN
Email is signed.
Definition lib.h:87
static bool msg_search(struct Pattern *pat, struct Email *e, struct Message *msg)
Search an email.
Definition exec.c:111
static bool pattern_needs_msg(const struct Mailbox *m, const struct Pattern *pat)
Check whether a pattern needs a full message.
Definition exec.c:796
static int match_user(bool all_addr, int n,...)
Matches the user's email Address.
Definition exec.c:521
static int match_threadcomplete(struct PatternList *pat, PatternExecFlags flags, struct Mailbox *m, struct MuttThread *t, int left, int up, int right, int down)
Match a Pattern against an email thread.
Definition exec.c:556
bool mutt_pattern_alias_exec(struct Pattern *pat, PatternExecFlags flags, struct AliasView *av, struct PatternCache *cache)
Match a pattern against an alias.
Definition exec.c:1173
static void print_crypt_pattern_op_error(int op)
Print an error for a disabled crypto pattern.
Definition exec.c:85
static int match_threadparent(struct PatternList *pat, PatternExecFlags flags, struct Mailbox *m, struct MuttThread *t)
Match Pattern against an email's parent.
Definition exec.c:594
static bool match_content_type(const struct Pattern *pat, struct Body *b)
Match a Pattern against an Attachment's Content-Type.
Definition exec.c:633
static bool perform_alias_and(struct PatternList *pat, PatternExecFlags flags, struct AliasView *av, struct PatternCache *cache)
Perform a logical AND on a set of Patterns.
Definition exec.c:326
static bool match_mime_content_type(const struct Pattern *pat, struct Email *e, FILE *fp)
Match a Pattern against an email's Content-Type.
Definition exec.c:658
static int match_threadchildren(struct PatternList *pat, PatternExecFlags flags, struct Mailbox *m, struct MuttThread *t)
Match Pattern against an email's children.
Definition exec.c:613
static bool match_reference(struct Pattern *pat, struct ListHead *refs)
Match references against a Pattern.
Definition exec.c:448
static int match_addrlist(struct Pattern *pat, bool match_personal, int n,...)
match a pattern against an address list
Definition exec.c:417
static bool mutt_is_predicate_recipient(bool all_addr, struct Envelope *env, addr_predicate_t p)
Test an Envelopes Addresses using a predicate function.
Definition exec.c:470
static bool patmatch(const struct Pattern *pat, const char *buf)
Compare a string to a Pattern.
Definition exec.c:70
static int is_pattern_cache_set(int cache_entry)
Is a given Pattern cached?
Definition exec.c:708
static int perform_alias_or(struct PatternList *pat, PatternExecFlags flags, struct AliasView *av, struct PatternCache *cache)
Perform a logical OR on a set of Patterns.
Definition exec.c:375
static bool match_tags(struct Pattern *pat, struct TagList *tags)
match a pattern against a tags list
Definition exec.c:396
bool mutt_is_subscribed_list_recipient(bool all_addr, struct Envelope *env)
Matches subscribed mailing lists.
Definition exec.c:494
static int perform_or(struct PatternList *pat, PatternExecFlags flags, struct Mailbox *m, struct Email *e, struct Message *msg, struct PatternCache *cache)
Perform a logical OR on a set of Patterns.
Definition exec.c:351
bool mutt_is_list_recipient(bool all_addr, struct Envelope *env)
Matches known mailing lists.
Definition exec.c:507
static bool match_update_dynamic_date(struct Pattern *pat)
Update a dynamic date pattern.
Definition exec.c:670
static bool perform_and(struct PatternList *pat, PatternExecFlags flags, struct Mailbox *m, struct Email *e, struct Message *msg, struct PatternCache *cache)
Perform a logical AND on a set of Patterns.
Definition exec.c:302
static bool get_pattern_cache_value(int cache_entry)
Get pattern cache value.
Definition exec.c:698
static bool pattern_exec(struct Pattern *pat, PatternExecFlags flags, struct Mailbox *m, struct Email *e, struct Message *msg, struct PatternCache *cache)
Match a pattern against an email header.
Definition exec.c:843
static void set_pattern_cache_value(int *cache_entry, int value)
Sets a value in the PatternCache cache entry.
Definition exec.c:687
bool mutt_pattern_exec(struct Pattern *pat, PatternExecFlags flags, struct Mailbox *m, struct Email *e, struct PatternCache *cache)
Match a pattern against an email header.
Definition exec.c:1146
static int msg_search_sendmode(struct Email *e, struct Pattern *pat)
Search in send-mode.
Definition exec.c:721
const struct PatternFlags * lookup_op(int op)
Lookup the Pattern Flags for an op.
Definition flags.c:258
Match patterns to emails.
@ MUTT_PAT_HEADER
Pattern matches email's header.
Definition lib.h:157
@ MUTT_PAT_WHOLE_MSG
Pattern matches raw email text.
Definition lib.h:159
@ MUTT_PAT_BROKEN
Message is part of a broken thread.
Definition lib.h:153
@ MUTT_PAT_ID_EXTERNAL
Message-Id is among results from an external query.
Definition lib.h:155
@ MUTT_PAT_OR
Either pattern can match.
Definition lib.h:139
@ MUTT_PAT_CHILDREN
Pattern matches a child email.
Definition lib.h:142
@ MUTT_PAT_PARENT
Pattern matches parent.
Definition lib.h:141
@ MUTT_PAT_REFERENCE
Pattern matches 'References:' or 'In-Reply-To:' field.
Definition lib.h:164
@ MUTT_PAT_FROM
Pattern matches 'From:' field.
Definition lib.h:148
@ MUTT_PAT_DRIVER_TAGS
Pattern matches message tags.
Definition lib.h:177
@ MUTT_PAT_COLLAPSED
Thread is collapsed.
Definition lib.h:146
@ MUTT_PAT_CRYPT_VERIFIED
Message is crypographically verified.
Definition lib.h:172
@ MUTT_PAT_HORMEL
Pattern matches email's spam score.
Definition lib.h:158
@ MUTT_PAT_SUBJECT
Pattern matches 'Subject:' field.
Definition lib.h:147
@ MUTT_PAT_LIST
Email is on mailing list.
Definition lib.h:166
@ MUTT_PAT_NEWSGROUPS
Pattern matches newsgroup.
Definition lib.h:180
@ MUTT_PAT_PERSONAL_RECIP
Email is addressed to the user.
Definition lib.h:168
@ MUTT_PAT_CC
Pattern matches 'Cc:' field.
Definition lib.h:144
@ MUTT_PAT_SUBSCRIBED_LIST
Email is on subscribed mailing list.
Definition lib.h:167
@ MUTT_PAT_SERVERSEARCH
Server-side pattern matches.
Definition lib.h:176
@ MUTT_PAT_RECIPIENT
User is a recipient of the email.
Definition lib.h:165
@ MUTT_PAT_CRYPT_ENCRYPT
Message is encrypted.
Definition lib.h:173
@ MUTT_PAT_UNREFERENCED
Message is unreferenced in the thread.
Definition lib.h:152
@ MUTT_PAT_CRYPT_SIGN
Message is signed.
Definition lib.h:171
@ MUTT_PAT_MESSAGE
Pattern matches message number.
Definition lib.h:161
@ MUTT_PAT_AND
Both patterns must match.
Definition lib.h:138
@ MUTT_PAT_DATE
Pattern matches 'Date:' field.
Definition lib.h:149
@ MUTT_PAT_XLABEL
Pattern matches keyword/label.
Definition lib.h:175
@ MUTT_PAT_SCORE
Pattern matches email's score.
Definition lib.h:162
@ MUTT_PAT_MIMEATTACH
Pattern matches number of attachments.
Definition lib.h:178
@ MUTT_PAT_DUPLICATED
Duplicate message.
Definition lib.h:151
@ MUTT_PAT_PERSONAL_FROM
Email is from the user.
Definition lib.h:169
@ MUTT_PAT_TO
Pattern matches 'To:' field.
Definition lib.h:143
@ MUTT_PAT_BCC
Pattern matches 'Bcc:' field.
Definition lib.h:145
@ MUTT_PAT_SENDER
Pattern matches sender.
Definition lib.h:160
@ MUTT_PAT_DATE_RECEIVED
Pattern matches date received.
Definition lib.h:150
@ MUTT_PAT_ADDRESS
Pattern matches any address field.
Definition lib.h:170
@ MUTT_PAT_MIMETYPE
Pattern matches MIME type.
Definition lib.h:179
@ MUTT_PAT_PGP_KEY
Message has PGP key.
Definition lib.h:174
@ MUTT_PAT_ID
Pattern matches email's Message-Id.
Definition lib.h:154
@ MUTT_PAT_THREAD
Pattern matches email thread.
Definition lib.h:140
@ MUTT_PAT_SIZE
Pattern matches email's size.
Definition lib.h:163
@ MUTT_PAT_BODY
Pattern matches email's body.
Definition lib.h:156
#define MUTT_MATCH_FULL_ADDRESS
Match the full address.
Definition lib.h:107
uint8_t PatternExecFlags
Flags for mutt_pattern_exec(), e.g. MUTT_MATCH_FULL_ADDRESS.
Definition lib.h:105
Shared constants/structs that are private to libpattern.
#define MUTT_MAXRANGE
Definition private.h:149
static int email_msgno(struct Email *e)
Helper to get the Email's message number.
Definition private.h:144
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
#define SLIST_FOREACH(var, head, field)
Definition queue.h:229
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:782
#define STAILQ_FOREACH(var, head, field)
Definition queue.h:390
#define SLIST_FIRST(head)
Definition queue.h:227
int mutt_rfc822_write_header(FILE *fp, struct Envelope *env, struct Body *b, enum MuttWriteHeaderMode mode, bool privacy, bool hide_protected_subject, struct ConfigSubset *sub)
Write out one RFC822 header line.
Definition header.c:578
@ MUTT_WRITE_HEADER_POSTPONE
A postponed Email, just the envelope info.
Definition header.h:40
Convenience wrapper for the send headers.
#define ASSERT(COND)
Definition signal2.h:59
An email address.
Definition address.h:35
struct Buffer * personal
Real name of address.
Definition address.h:36
struct Buffer * mailbox
Mailbox and host address.
Definition address.h:37
GUI data wrapping an Alias.
Definition gui.h:38
struct Alias * alias
Alias.
Definition gui.h:46
struct TagList tags
Tags.
Definition alias.h:39
char * comment
Free-form comment string.
Definition alias.h:38
char * name
Short name.
Definition alias.h:36
struct AddressList addr
List of Addresses the Alias expands to.
Definition alias.h:37
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
LOFF_T length
length (in bytes) of attachment
Definition body.h:53
struct Body * next
next attachment in the list
Definition body.h:72
char * subtype
content-type subtype
Definition body.h:61
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
char * data
Pointer to data.
Definition buffer.h:37
The envelope/body of an email.
Definition email.h:39
bool read
Email is read.
Definition email.h:50
bool matched
Search matches this Email.
Definition email.h:102
struct Envelope * env
Envelope information.
Definition email.h:68
bool collapsed
Is this message part of a collapsed thread?
Definition email.h:120
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition email.h:43
struct Body * body
List of MIME parts.
Definition email.h:69
bool old
Email is seen, but unread.
Definition email.h:49
size_t num_hidden
Number of hidden messages in this view (only valid when collapsed is set)
Definition email.h:123
LOFF_T offset
Where in the stream does this message begin?
Definition email.h:71
bool flagged
Marked important?
Definition email.h:47
time_t date_sent
Time when the message was sent (UTC)
Definition email.h:60
bool replied
Email has been replied to.
Definition email.h:51
bool expired
Already expired?
Definition email.h:46
struct TagList tags
For drivers that support server tagging.
Definition email.h:72
int score
Message score.
Definition email.h:113
bool deleted
Email is deleted.
Definition email.h:78
bool tagged
Email is tagged.
Definition email.h:107
bool superseded
Got superseded?
Definition email.h:52
time_t received
Time when the message was placed in the mailbox.
Definition email.h:61
struct MuttThread * thread
Thread of Emails.
Definition email.h:119
The header of an Email.
Definition envelope.h:57
char *const subject
Email's subject.
Definition envelope.h:70
struct AddressList to
Email's 'To' list.
Definition envelope.h:60
char * message_id
Message ID.
Definition envelope.h:73
char * newsgroups
List of newsgroups.
Definition envelope.h:78
struct AddressList cc
Email's 'Cc' list.
Definition envelope.h:61
struct AddressList sender
Email's sender.
Definition envelope.h:63
struct ListHead references
message references (in reverse order)
Definition envelope.h:83
struct Buffer spam
Spam header.
Definition envelope.h:82
struct ListHead in_reply_to
in-reply-to header content
Definition envelope.h:84
struct AddressList bcc
Email's 'Bcc' list.
Definition envelope.h:62
char * x_label
X-Label.
Definition envelope.h:76
struct AddressList from
Email's 'From' list.
Definition envelope.h:59
A List node for strings.
Definition list.h:37
char * data
String.
Definition list.h:38
A mailbox.
Definition mailbox.h:78
enum MailboxType type
Mailbox type.
Definition mailbox.h:101
A local copy of an email.
Definition message.h:34
FILE * fp
pointer to the message data
Definition message.h:35
struct Message::@264267271004327071125374067057142037276212342100 flags
Flags for the Message.
An Email conversation.
Definition thread.h:34
struct MuttThread * parent
Parent of this Thread.
Definition thread.h:44
struct MuttThread * prev
Previous sibling Thread.
Definition thread.h:47
bool fake_thread
Emails grouped by Subject.
Definition thread.h:38
struct MuttThread * child
Child of this Thread.
Definition thread.h:45
struct Email * message
Email this Thread refers to.
Definition thread.h:49
bool duplicate_thread
Duplicated Email in Thread.
Definition thread.h:37
struct MuttThread * next
Next sibling Thread.
Definition thread.h:46
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
Cache commonly-used patterns.
Definition lib.h:118
int pers_recip_all
^~p
Definition lib.h:123
int list_one
~l
Definition lib.h:120
int pers_from_one
~P
Definition lib.h:126
int list_all
^~l
Definition lib.h:119
int sub_all
^~u
Definition lib.h:121
int pers_recip_one
~p
Definition lib.h:124
int pers_from_all
^~P
Definition lib.h:125
int sub_one
~u
Definition lib.h:122
Mapping between user character and internal constant.
Definition private.h:66
char tag
Character used to represent this operation, e.g. 'A' for '~A'.
Definition private.h:68
int op
Operation to perform, e.g. MUTT_PAT_SCORE.
Definition private.h:69
char prefix
Prefix for this pattern, e.g. '~', '', or '='.
Definition private.h:67
A simple (non-regex) pattern.
Definition lib.h:78
bool group_match
Check a group of Addresses.
Definition lib.h:83
union Pattern::@006112053024257132210207314205210350156165326341 p
bool all_addr
All Addresses in the list must match.
Definition lib.h:81
struct Group * group
Address group if group_match is set.
Definition lib.h:94
struct PatternList * child
Arguments to logical operation.
Definition lib.h:91
long min
Minimum for range checks.
Definition lib.h:89
bool string_match
Check a string for a match.
Definition lib.h:82
regex_t * regex
Compiled regex, for non-pattern matching.
Definition lib.h:93
struct ListHead multi_cases
Multiple strings for ~I pattern.
Definition lib.h:96
char * str
String, if string_match is set.
Definition lib.h:95
bool is_alias
Is there an alias for this Address?
Definition lib.h:85
bool ign_case
Ignore case for local string_match searches.
Definition lib.h:84
long max
Maximum for range checks.
Definition lib.h:90
bool dynamic
Evaluate date ranges at run time.
Definition lib.h:86
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition lib.h:79
bool sendmode
Evaluate searches in send-mode.
Definition lib.h:87
bool is_multi
Multiple case (only for ~I pattern now)
Definition lib.h:88
bool pat_not
Pattern should be inverted (not)
Definition lib.h:80
Keep track when processing files.
Definition state.h:48
StateFlags flags
Flags, e.g. STATE_DISPLAY.
Definition state.h:52
FILE * fp_out
File to write to.
Definition state.h:50
FILE * fp_in
File to read from.
Definition state.h:49
LinkedList Tag Element.
Definition tags.h:41
char * name
Tag name.
Definition tags.h:42
#define buf_mktemp(buf)
Definition tmp.h:33
#define mutt_file_mkstemp()
Definition tmp.h:36