NeoMutt  2025-12-11-694-ga89709
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
exec.c File Reference

Execute a Pattern. More...

#include "config.h"
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "private.h"
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "alias/alias.h"
#include "alias/gui.h"
#include "alias/lib.h"
#include "mutt.h"
#include "lib.h"
#include "attach/lib.h"
#include "ncrypt/lib.h"
#include "send/lib.h"
#include "mx.h"
#include <sys/stat.h>
+ Include dependency graph for exec.c:

Go to the source code of this file.

Functions

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.
 
static bool patmatch (const struct Pattern *pat, const char *buf)
 Compare a string to a Pattern.
 
static void print_crypt_pattern_op_error (int op)
 Print an error for a disabled crypto pattern.
 
static bool msg_search (struct Pattern *pat, struct Email *e, struct Message *msg)
 Search an email.
 
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.
 
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.
 
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.
 
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.
 
static bool match_tags (struct Pattern *pat, struct TagList *tags)
 match a pattern against a tags list
 
static int match_addrlist (struct Pattern *pat, bool match_personal, int n,...)
 match a pattern against an address list
 
static bool match_reference (struct Pattern *pat, struct ListHead *refs)
 Match references against a Pattern.
 
static bool mutt_is_predicate_recipient (bool all_addr, struct Envelope *env, addr_predicate_t p)
 Test an Envelopes Addresses using a predicate function.
 
bool mutt_is_subscribed_list_recipient (bool all_addr, struct Envelope *env)
 Matches subscribed mailing lists.
 
bool mutt_is_list_recipient (bool all_addr, struct Envelope *env)
 Matches known mailing lists.
 
static int match_user (bool all_addr, int n,...)
 Matches the user's email Address.
 
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.
 
static int match_threadparent (struct PatternList *pat, PatternExecFlags flags, struct Mailbox *m, struct MuttThread *t)
 Match Pattern against an email's parent.
 
static int match_threadchildren (struct PatternList *pat, PatternExecFlags flags, struct Mailbox *m, struct MuttThread *t)
 Match Pattern against an email's children.
 
static bool match_content_type (const struct Pattern *pat, struct Body *b)
 Match a Pattern against an Attachment's Content-Type.
 
static bool match_mime_content_type (const struct Pattern *pat, struct Email *e, FILE *fp)
 Match a Pattern against an email's Content-Type.
 
static bool match_update_dynamic_date (struct Pattern *pat)
 Update a dynamic date pattern.
 
static void set_pattern_cache_value (int *cache_entry, int value)
 Sets a value in the PatternCache cache entry.
 
static bool get_pattern_cache_value (int cache_entry)
 Get pattern cache value.
 
static int is_pattern_cache_set (int cache_entry)
 Is a given Pattern cached?
 
static int msg_search_sendmode (struct Email *e, struct Pattern *pat)
 Search in send-mode.
 
static bool pattern_needs_msg (const struct Mailbox *m, const struct Pattern *pat)
 Check whether a pattern needs a full message.
 
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.
 
bool mutt_pattern_alias_exec (struct Pattern *pat, PatternExecFlags flags, struct AliasView *av, struct PatternCache *cache)
 Match a pattern against an alias.
 

Detailed Description

Execute a Pattern.

Authors
  • Romeu Vieira
  • Richard Russon
  • Pietro Cerutti
  • Leon Philman
  • Dennis Schön
  • Alejandro Colomar

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file exec.c.

Function Documentation

◆ pattern_exec()

static bool pattern_exec ( struct Pattern * pat,
PatternExecFlags flags,
struct Mailbox * m,
struct Email * e,
struct Message * msg,
struct PatternCache * cache )
static

Match a pattern against an email header.

Parameters
patPattern to match
flagsFlags, e.g. MUTT_MATCH_FULL_ADDRESS
mMailbox
eEmail
msgMEssage
cacheCache for common Patterns
Return values
trueSuccess, pattern matched
falsePattern did not match

flags: MUTT_MATCH_FULL_ADDRESS: match both personal and machine address cache: For repeated matches against the same Header, passing in non-NULL will store some of the cacheable pattern matches in this structure.

Definition at line 843 of file exec.c.

846{
847 /* Dispatch on the pattern operation type. Each case tests a specific
848 * email attribute (flags, dates, addresses, etc.) against the pattern,
849 * applying pat_not to invert the result when '!' was used. */
850 switch (pat->op)
851 {
852 case MUTT_PAT_AND:
853 return pat->pat_not ^ (perform_and(pat->child, flags, m, e, msg, cache) > 0);
854 case MUTT_PAT_OR:
855 return pat->pat_not ^ (perform_or(pat->child, flags, m, e, msg, cache) > 0);
856 case MUTT_PAT_THREAD:
857 return pat->pat_not ^
858 match_threadcomplete(pat->child, flags, m, e->thread, 1, 1, 1, 1);
859 case MUTT_PAT_PARENT:
860 return pat->pat_not ^ match_threadparent(pat->child, flags, m, e->thread);
862 return pat->pat_not ^ match_threadchildren(pat->child, flags, m, e->thread);
863 case MUTT_ALL:
864 return !pat->pat_not;
865 case MUTT_EXPIRED:
866 return pat->pat_not ^ e->expired;
867 case MUTT_SUPERSEDED:
868 return pat->pat_not ^ e->superseded;
869 case MUTT_FLAG:
870 return pat->pat_not ^ e->flagged;
871 case MUTT_TAG:
872 return pat->pat_not ^ e->tagged;
873 case MUTT_NEW:
874 return pat->pat_not ? e->old || e->read : !(e->old || e->read);
875 case MUTT_UNREAD:
876 return pat->pat_not ? e->read : !e->read;
877 case MUTT_REPLIED:
878 return pat->pat_not ^ e->replied;
879 case MUTT_OLD:
880 return pat->pat_not ? (!e->old || e->read) : (e->old && !e->read);
881 case MUTT_READ:
882 return pat->pat_not ^ e->read;
883 case MUTT_DELETED:
884 return pat->pat_not ^ e->deleted;
885 case MUTT_PAT_MESSAGE:
886 return pat->pat_not ^
887 ((email_msgno(e) >= pat->min) && (email_msgno(e) <= pat->max));
888 case MUTT_PAT_DATE:
889 if (pat->dynamic)
891 return pat->pat_not ^ ((e->date_sent >= pat->min) && (e->date_sent <= pat->max));
893 if (pat->dynamic)
895 return pat->pat_not ^ ((e->received >= pat->min) && (e->received <= pat->max));
896 case MUTT_PAT_BODY:
897 case MUTT_PAT_HEADER:
899 if (pat->sendmode)
900 {
901 if (!e->body || !e->body->filename)
902 return false;
903 return pat->pat_not ^ msg_search_sendmode(e, pat);
904 }
905 /* m can be NULL in certain cases, such as when replying to a message
906 * from the attachment menu and the user has a reply-hook using "~e".
907 * This is also the case when message scoring. */
908 if (!m)
909 return false;
910 /* IMAP search sets e->matched at search compile time */
911 if ((m->type == MUTT_IMAP) && pat->string_match)
912 return e->matched;
913 return pat->pat_not ^ msg_search(pat, e, msg);
915 if (!m)
916 return false;
917 if (m->type == MUTT_IMAP)
918 {
919 return (pat->string_match) ? e->matched : false;
920 }
921 mutt_error(_("error: server custom search only supported with IMAP"));
922 return false;
923 case MUTT_PAT_SENDER:
924 if (!e->env)
925 return false;
926 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
927 1, &e->env->sender);
928 case MUTT_PAT_FROM:
929 if (!e->env)
930 return false;
931 return pat->pat_not ^
932 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->from);
933 case MUTT_PAT_TO:
934 if (!e->env)
935 return false;
936 return pat->pat_not ^
937 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->to);
938 case MUTT_PAT_CC:
939 if (!e->env)
940 return false;
941 return pat->pat_not ^
942 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->cc);
943 case MUTT_PAT_BCC:
944 if (!e->env)
945 return false;
946 return pat->pat_not ^
947 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->bcc);
948 case MUTT_PAT_SUBJECT:
949 if (!e->env)
950 return false;
951 return pat->pat_not ^ (e->env->subject && patmatch(pat, e->env->subject));
952 case MUTT_PAT_ID:
954 if (!e->env)
955 return false;
956 return pat->pat_not ^ (e->env->message_id && patmatch(pat, e->env->message_id));
957 case MUTT_PAT_SCORE:
958 return pat->pat_not ^ (e->score >= pat->min &&
959 (pat->max == MUTT_MAXRANGE || e->score <= pat->max));
960 case MUTT_PAT_SIZE:
961 return pat->pat_not ^ (e->body->length >= pat->min &&
962 (pat->max == MUTT_MAXRANGE || e->body->length <= pat->max));
964 if (!e->env)
965 return false;
966 return pat->pat_not ^ (match_reference(pat, &e->env->references) ||
967 match_reference(pat, &e->env->in_reply_to));
968 case MUTT_PAT_ADDRESS:
969 if (!e->env)
970 return false;
971 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
972 5, &e->env->from, &e->env->sender,
973 &e->env->to, &e->env->cc, &e->env->bcc);
975 if (!e->env)
976 return false;
977 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 3,
978 &e->env->to, &e->env->cc, &e->env->bcc);
979 case MUTT_PAT_LIST: /* known list, subscribed or not */
980 {
981 if (!e->env)
982 return false;
983
984 /* Use pattern cache to avoid repeated list membership lookups */
985 bool result;
986 if (cache)
987 {
988 int *cache_entry = pat->all_addr ? &cache->list_all : &cache->list_one;
989 if (!is_pattern_cache_set(*cache_entry))
990 {
991 set_pattern_cache_value(cache_entry,
992 mutt_is_list_recipient(pat->all_addr, e->env));
993 }
994 result = get_pattern_cache_value(*cache_entry);
995 }
996 else
997 {
998 result = mutt_is_list_recipient(pat->all_addr, e->env);
999 }
1000 return pat->pat_not ^ result;
1001 }
1003 {
1004 if (!e->env)
1005 return false;
1006
1007 bool result;
1008 if (cache)
1009 {
1010 int *cache_entry = pat->all_addr ? &cache->sub_all : &cache->sub_one;
1011 if (!is_pattern_cache_set(*cache_entry))
1012 {
1013 set_pattern_cache_value(cache_entry,
1015 }
1016 result = get_pattern_cache_value(*cache_entry);
1017 }
1018 else
1019 {
1021 }
1022 return pat->pat_not ^ result;
1023 }
1025 {
1026 if (!e->env)
1027 return false;
1028
1029 bool result;
1030 if (cache)
1031 {
1032 int *cache_entry = pat->all_addr ? &cache->pers_recip_all : &cache->pers_recip_one;
1033 if (!is_pattern_cache_set(*cache_entry))
1034 {
1035 set_pattern_cache_value(cache_entry,
1036 match_user(pat->all_addr, 3, &e->env->to,
1037 &e->env->cc, &e->env->bcc));
1038 }
1039 result = get_pattern_cache_value(*cache_entry);
1040 }
1041 else
1042 {
1043 result = match_user(pat->all_addr, 3, &e->env->to, &e->env->cc, &e->env->bcc);
1044 }
1045 return pat->pat_not ^ result;
1046 }
1048 {
1049 if (!e->env)
1050 return false;
1051
1052 bool result;
1053 if (cache)
1054 {
1055 int *cache_entry = pat->all_addr ? &cache->pers_from_all : &cache->pers_from_one;
1056 if (!is_pattern_cache_set(*cache_entry))
1057 {
1058 set_pattern_cache_value(cache_entry,
1059 match_user(pat->all_addr, 1, &e->env->from));
1060 }
1061 result = get_pattern_cache_value(*cache_entry);
1062 }
1063 else
1064 {
1065 result = match_user(pat->all_addr, 1, &e->env->from);
1066 }
1067 return pat->pat_not ^ result;
1068 }
1069 case MUTT_PAT_COLLAPSED:
1070 return pat->pat_not ^ (e->collapsed && e->num_hidden > 1);
1072 /* Cryptographic flag patterns require WithCrypto to be enabled */
1073 if (!WithCrypto)
1074 {
1076 return false;
1077 }
1078 return pat->pat_not ^ ((e->security & SEC_SIGN) ? 1 : 0);
1080 if (!WithCrypto)
1081 {
1083 return false;
1084 }
1085 return pat->pat_not ^ ((e->security & SEC_GOODSIGN) ? 1 : 0);
1087 if (!WithCrypto)
1088 {
1090 return false;
1091 }
1092 return pat->pat_not ^ ((e->security & SEC_ENCRYPT) ? 1 : 0);
1093 case MUTT_PAT_PGP_KEY:
1094 if (!(WithCrypto & APPLICATION_PGP))
1095 {
1097 return false;
1098 }
1099 return pat->pat_not ^ ((e->security & PGP_KEY) == PGP_KEY);
1100 case MUTT_PAT_XLABEL:
1101 if (!e->env)
1102 return false;
1103 return pat->pat_not ^ (e->env->x_label && patmatch(pat, e->env->x_label));
1105 {
1106 return match_tags(pat, &e->tags);
1107 }
1108 case MUTT_PAT_HORMEL:
1109 if (!e->env)
1110 return false;
1111 return pat->pat_not ^ (e->env->spam.data && patmatch(pat, e->env->spam.data));
1113 return pat->pat_not ^ (e->thread && e->thread->duplicate_thread);
1115 {
1116 int count = msg ? mutt_count_body_parts(e, msg->fp) : 0;
1117 return pat->pat_not ^
1118 (count >= pat->min && (pat->max == MUTT_MAXRANGE || count <= pat->max));
1119 }
1120 case MUTT_PAT_MIMETYPE:
1121 if (!m || !msg)
1122 return false;
1123 return pat->pat_not ^ match_mime_content_type(pat, e, msg->fp);
1125 return pat->pat_not ^ (e->thread && !e->thread->child);
1126 case MUTT_PAT_BROKEN:
1127 return pat->pat_not ^ (e->thread && e->thread->fake_thread);
1129 if (!e->env)
1130 return false;
1131 return pat->pat_not ^ (e->env->newsgroups && patmatch(pat, e->env->newsgroups));
1132 }
1133 mutt_error(_("error: unknown op %d (report this error)"), pat->op);
1134 return false;
1135}
int mutt_count_body_parts(struct Email *e, FILE *fp)
Count the MIME Body parts.
Definition commands.c:226
@ MUTT_IMAP
'IMAP' Mailbox type
Definition mailbox.h:49
#define mutt_error(...)
Definition logging2.h:94
#define _(a)
Definition message.h:28
@ 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
#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 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
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_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 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 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
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 void set_pattern_cache_value(int *cache_entry, int value)
Sets a value in the PatternCache cache entry.
Definition exec.c:687
@ 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
#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
LOFF_T length
length (in bytes) of attachment
Definition body.h:53
char * data
Pointer to data.
Definition buffer.h:37
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
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
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
enum MailboxType type
Mailbox type.
Definition mailbox.h:101
FILE * fp
pointer to the message data
Definition message.h:35
bool fake_thread
Emails grouped by Subject.
Definition thread.h:38
struct MuttThread * child
Child of this Thread.
Definition thread.h:45
bool duplicate_thread
Duplicated Email in Thread.
Definition thread.h:37
int pers_recip_all
^~p
Definition lib.h:123
int pers_from_one
~P
Definition lib.h:126
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
bool all_addr
All Addresses in the list must match.
Definition lib.h:81
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
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 pat_not
Pattern should be inverted (not)
Definition lib.h:80
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ patmatch()

static bool patmatch ( const struct Pattern * pat,
const char * buf )
static

Compare a string to a Pattern.

Parameters
patPattern to use
bufString to compare
Return values
trueMatch
falseNo match

Definition at line 70 of file exec.c.

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}
bool group_match(struct Group *g, const char *str)
Does a string match an entry in a Group?
Definition group.c:161
struct ListNode * mutt_list_find(const struct ListHead *h, const char *data)
Find a string in a List.
Definition list.c:103
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case)
Definition string.c:528
bool group_match
Check a group of Addresses.
Definition lib.h:83
union Pattern::@006112053024257132210207314205210350156165326341 p
struct Group * group
Address group if group_match is set.
Definition lib.h:94
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 ign_case
Ignore case for local string_match searches.
Definition lib.h:84
bool is_multi
Multiple case (only for ~I pattern now)
Definition lib.h:88
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ print_crypt_pattern_op_error()

static void print_crypt_pattern_op_error ( int op)
static

Print an error for a disabled crypto pattern.

Parameters
opOperation, e.g. MUTT_PAT_CRYPT_SIGN

Definition at line 85 of file exec.c.

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}
const struct PatternFlags * lookup_op(int op)
Lookup the Pattern Flags for an op.
Definition flags.c:258
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ msg_search()

static bool msg_search ( struct Pattern * pat,
struct Email * e,
struct Message * msg )
static

Search an email.

Parameters
patPattern to find
eEmail
msgMessage
Return values
truePattern found
falseError or pattern not found

Definition at line 111 of file exec.c.

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}
void mutt_parse_mime_message(struct Email *e, FILE *fp)
Parse a MIME email.
Definition commands.c:627
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 cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
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
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition crypt.c:131
size_t mutt_rfc822_read_line(FILE *fp, struct Buffer *buf)
Read a header line from a file.
Definition parse.c:1130
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition file.c:648
#define mutt_file_fclose(FP)
Definition file.h:139
#define mutt_file_fopen(PATH, MODE)
Definition file.h:138
#define mutt_perror(...)
Definition logging2.h:95
int mutt_body_handler(struct Body *b, struct State *state)
Handler for the Body of an email.
Definition handler.c:1664
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define STATE_CHARCONV
Do character set conversions.
Definition state.h:37
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:503
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 ASSERT(COND)
Definition signal2.h:59
LOFF_T offset
offset where the actual data begins
Definition body.h:52
String manipulation buffer.
Definition buffer.h:36
LOFF_T offset
Where in the stream does this message begin?
Definition email.h:71
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
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
#define mutt_file_mkstemp()
Definition tmp.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ perform_and()

static bool perform_and ( struct PatternList * pat,
PatternExecFlags flags,
struct Mailbox * m,
struct Email * e,
struct Message * msg,
struct PatternCache * cache )
static

Perform a logical AND on a set of Patterns.

Parameters
patPatterns to test
flagsOptional flags, e.g. MUTT_MATCH_FULL_ADDRESS
mMailbox
eEmail
msgMessage
cacheCached Patterns
Return values
trueALL of the Patterns evaluates to true

Definition at line 302 of file exec.c.

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}
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
#define SLIST_FOREACH(var, head, field)
Definition queue.h:229
A simple (non-regex) pattern.
Definition lib.h:78
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ perform_alias_and()

static bool perform_alias_and ( struct PatternList * pat,
PatternExecFlags flags,
struct AliasView * av,
struct PatternCache * cache )
static

Perform a logical AND on a set of Patterns.

Parameters
patPatterns to test
flagsOptional flags, e.g. MUTT_MATCH_FULL_ADDRESS
avAliasView
cacheCached Patterns
Return values
trueALL of the Patterns evaluate to true

Definition at line 326 of file exec.c.

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}
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:1178
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ perform_or()

static int perform_or ( struct PatternList * pat,
PatternExecFlags flags,
struct Mailbox * m,
struct Email * e,
struct Message * msg,
struct PatternCache * cache )
static

Perform a logical OR on a set of Patterns.

Parameters
patPatterns to test
flagsOptional flags, e.g. MUTT_MATCH_FULL_ADDRESS
mMailbox
eEmail
msgMessage
cacheCached Patterns
Return values
trueONE (or more) of the Patterns evaluates to true

Definition at line 351 of file exec.c.

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}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ perform_alias_or()

static int perform_alias_or ( struct PatternList * pat,
PatternExecFlags flags,
struct AliasView * av,
struct PatternCache * cache )
static

Perform a logical OR on a set of Patterns.

Parameters
patPatterns to test
flagsOptional flags, e.g. MUTT_MATCH_FULL_ADDRESS
avAliasView
cacheCached Patterns
Return values
trueONE (or more) of the Patterns evaluates to true

Definition at line 375 of file exec.c.

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}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ match_tags()

static bool match_tags ( struct Pattern * pat,
struct TagList * tags )
static

match a pattern against a tags list

Parameters
patpattern to find
tagstags list
Return values
trueif any tag match

Definition at line 396 of file exec.c.

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}
#define STAILQ_FOREACH(var, head, field)
Definition queue.h:390
LinkedList Tag Element.
Definition tags.h:41
char * name
Tag name.
Definition tags.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ match_addrlist()

static int match_addrlist ( struct Pattern * pat,
bool match_personal,
int n,
... )
static

match a pattern against an address list

Parameters
patpattern to find
match_personalif true, also match the pattern against the real name
nnumber of addresses supplied
...variable number of addresses
Return values
true
  • one address matches (all_addr is false)
  • all the addresses match (all_addr is true)

Definition at line 417 of file exec.c.

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}
struct Address * alias_reverse_lookup(const struct Address *addr)
Does the user have an alias for the given address.
Definition reverse.c:112
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:782
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
bool is_alias
Is there an alias for this Address?
Definition lib.h:85
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ match_reference()

static bool match_reference ( struct Pattern * pat,
struct ListHead * refs )
static

Match references against a Pattern.

Parameters
patPattern to match
refsList of References
Return values
trueOne of the references matches

Definition at line 448 of file exec.c.

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}
A List node for strings.
Definition list.h:37
char * data
String.
Definition list.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_predicate_recipient()

static bool mutt_is_predicate_recipient ( bool all_addr,
struct Envelope * env,
addr_predicate_t p )
static

Test an Envelopes Addresses using a predicate function.

Parameters
all_addrIf true, ALL Addresses must match
envEnvelope
pPredicate function, e.g. mutt_is_subscribed_list()
Return values
true
  • One Address matches (all_addr is false)
  • All the Addresses match (all_addr is true)

Test the 'To' and 'Cc' fields of an Address using a test function (the predicate).

Definition at line 470 of file exec.c.

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}
#define countof(x)
Definition memory.h:49
+ Here is the caller graph for this function:

◆ mutt_is_subscribed_list_recipient()

bool mutt_is_subscribed_list_recipient ( bool all_addr,
struct Envelope * env )

Matches subscribed mailing lists.

Parameters
all_addrIf true, ALL Addresses must be on the subscribed list
envEnvelope
Return values
true
  • One Address is subscribed (all_addr is false)
  • All the Addresses are subscribed (all_addr is true)

Definition at line 494 of file exec.c.

495{
497}
bool mutt_is_subscribed_list(const struct Address *addr)
Is this the email address of a user-subscribed mailing list?
Definition maillist.c:60
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_list_recipient()

bool mutt_is_list_recipient ( bool all_addr,
struct Envelope * env )

Matches known mailing lists.

Parameters
all_addrIf true, ALL Addresses must be mailing lists
envEnvelope
Return values
true
  • One Address is a mailing list (all_addr is false)
  • All the Addresses are mailing lists (all_addr is true)

Definition at line 507 of file exec.c.

508{
509 return mutt_is_predicate_recipient(all_addr, env, &mutt_is_mail_list);
510}
bool mutt_is_mail_list(const struct Address *addr)
Is this the email address of a mailing list?
Definition maillist.c:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ match_user()

static int match_user ( bool all_addr,
int n,
... )
static

Matches the user's email Address.

Parameters
all_addrIf true, ALL Addresses must refer to the user
nnumber of AddressLists supplied
...Variable number of AddressLists
Return values
true
  • One Address refers to the user (all_addr is false)
  • All the Addresses refer to the user (all_addr is true)

Definition at line 521 of file exec.c.

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}
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition alias.c:600
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ match_threadcomplete()

static int match_threadcomplete ( struct PatternList * pat,
PatternExecFlags flags,
struct Mailbox * m,
struct MuttThread * t,
int left,
int up,
int right,
int down )
static

Match a Pattern against an email thread.

Parameters
patPattern to match
flagsFlags, e.g. MUTT_MATCH_FULL_ADDRESS
mMailbox
tEmail thread
leftNavigate to the previous email
upNavigate to the email's parent
rightNavigate to the next email
downNavigate to the email's children
Return values
1Success, match found
0No match

Definition at line 556 of file exec.c.

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}
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:1151
#define SLIST_FIRST(head)
Definition queue.h:227
The envelope/body of an email.
Definition email.h:39
struct MuttThread * parent
Parent of this Thread.
Definition thread.h:44
struct MuttThread * prev
Previous sibling Thread.
Definition thread.h:47
struct Email * message
Email this Thread refers to.
Definition thread.h:49
struct MuttThread * next
Next sibling Thread.
Definition thread.h:46
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ match_threadparent()

static int match_threadparent ( struct PatternList * pat,
PatternExecFlags flags,
struct Mailbox * m,
struct MuttThread * t )
static

Match Pattern against an email's parent.

Parameters
patPattern to match
flagsFlags, e.g. MUTT_MATCH_FULL_ADDRESS
mMailbox
tThread of email
Return values
1Success, pattern matched
0Pattern did not match
-1Error

Definition at line 594 of file exec.c.

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}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ match_threadchildren()

static int match_threadchildren ( struct PatternList * pat,
PatternExecFlags flags,
struct Mailbox * m,
struct MuttThread * t )
static

Match Pattern against an email's children.

Parameters
patPattern to match
flagsFlags, e.g. MUTT_MATCH_FULL_ADDRESS
mMailbox
tThread of email
Return values
1Success, pattern matched
0Pattern did not match
-1Error

Definition at line 613 of file exec.c.

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}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ match_content_type()

static bool match_content_type ( const struct Pattern * pat,
struct Body * b )
static

Match a Pattern against an Attachment's Content-Type.

Parameters
patPattern to match
bAttachment
Return values
trueSuccess, pattern matched
falsePattern did not match

Definition at line 633 of file exec.c.

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}
#define BODY_TYPE(body)
Get the type name of a body part.
Definition mime.h:93
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
struct Body * parts
parts of a multipart or message/rfc822
Definition body.h:73
struct Body * next
next attachment in the list
Definition body.h:72
char * subtype
content-type subtype
Definition body.h:61
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ match_mime_content_type()

static bool match_mime_content_type ( const struct Pattern * pat,
struct Email * e,
FILE * fp )
static

Match a Pattern against an email's Content-Type.

Parameters
patPattern to match
eEmail
fpMessage file
Return values
trueSuccess, pattern matched
falsePattern did not match

Definition at line 658 of file exec.c.

659{
661 return match_content_type(pat, e->body);
662}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ match_update_dynamic_date()

static bool match_update_dynamic_date ( struct Pattern * pat)
static

Update a dynamic date pattern.

Parameters
patPattern to modify
Return values
truePattern valid and updated
falsePattern invalid

Definition at line 670 of file exec.c.

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}
bool eval_date_minmax(struct Pattern *pat, const char *s, struct Buffer *err)
Evaluate a date-range pattern against 'now'.
Definition compile.c:544
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set_pattern_cache_value()

static void set_pattern_cache_value ( int * cache_entry,
int value )
static

Sets a value in the PatternCache cache entry.

Parameters
cache_entryCache entry to update
valueValue to set

Normalizes the "true" value to 2.

Definition at line 687 of file exec.c.

688{
689 *cache_entry = (value != 0) ? 2 : 1;
690}
+ Here is the caller graph for this function:

◆ get_pattern_cache_value()

static bool get_pattern_cache_value ( int cache_entry)
static

Get pattern cache value.

Parameters
cache_entryCache entry to get
Return values
1The cache value is set and has a true value
0otherwise (even if unset!)

Definition at line 698 of file exec.c.

699{
700 return cache_entry == 2;
701}
+ Here is the caller graph for this function:

◆ is_pattern_cache_set()

static int is_pattern_cache_set ( int cache_entry)
static

Is a given Pattern cached?

Parameters
cache_entryCache entry to check
Return values
truePattern is cached

Definition at line 708 of file exec.c.

709{
710 return cache_entry != 0;
711}
+ Here is the caller graph for this function:

◆ msg_search_sendmode()

static int msg_search_sendmode ( struct Email * e,
struct Pattern * pat )
static

Search in send-mode.

Parameters
eEmail to search
patPattern to find
Return values
1Success, pattern matched
0Pattern did not match
-1Error

Definition at line 721 of file exec.c.

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}
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:678
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition file.h:40
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
char * filename
When sending a message, this is the file to which this structure refers.
Definition body.h:59
#define buf_mktemp(buf)
Definition tmp.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pattern_needs_msg()

static bool pattern_needs_msg ( const struct Mailbox * m,
const struct Pattern * pat )
static

Check whether a pattern needs a full message.

Parameters
mMailbox
patPattern
Return values
trueThe pattern needs a full message
falseThe pattern does not need a full message

Definition at line 796 of file exec.c.

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}
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pattern_exec()

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.

Parameters
patPattern to match
flagsFlags, e.g. MUTT_MATCH_FULL_ADDRESS
mMailbox
eEmail
cacheCache for common Patterns
Return values
trueSuccess, pattern matched
falsePattern did not match

flags: MUTT_MATCH_FULL_ADDRESS: match both personal and machine address cache: For repeated matches against the same Header, passing in non-NULL will store some of the cacheable pattern matches in this structure.

Definition at line 1151 of file exec.c.

1153{
1154 const bool needs_msg = pattern_needs_msg(m, pat);
1155 struct Message *msg = needs_msg ? mx_msg_open(m, e) : NULL;
1156 if (needs_msg && !msg)
1157 {
1158 return false;
1159 }
1160 const bool matched = pattern_exec(pat, flags, m, e, msg, cache);
1161 mx_msg_close(m, &msg);
1162 return matched;
1163}
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
A local copy of an email.
Definition message.h:34
struct Message::@264267271004327071125374067057142037276212342100 flags
Flags for the Message.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pattern_alias_exec()

bool mutt_pattern_alias_exec ( struct Pattern * pat,
PatternExecFlags flags,
struct AliasView * av,
struct PatternCache * cache )

Match a pattern against an alias.

Parameters
patPattern to match
flagsFlags, e.g. MUTT_MATCH_FULL_ADDRESS
avAliasView
cacheCache for common Patterns
Return values
trueSuccess, pattern matched
falsePattern did not match

flags: MUTT_MATCH_FULL_ADDRESS: match both personal and machine address cache: For repeated matches against the same Alias, passing in non-NULL will store some of the cacheable pattern matches in this structure.

Definition at line 1178 of file exec.c.

1180{
1181 switch (pat->op)
1182 {
1183 case MUTT_PAT_FROM: /* alias */
1184 if (!av->alias)
1185 return false;
1186 return pat->pat_not ^ (av->alias->name && patmatch(pat, av->alias->name));
1187 case MUTT_PAT_CC: /* comment */
1188 if (!av->alias)
1189 return false;
1190 return pat->pat_not ^ (av->alias->comment && patmatch(pat, av->alias->comment));
1191 case MUTT_PAT_TO: /* alias address list */
1192 if (!av->alias)
1193 return false;
1194 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
1195 1, &av->alias->addr);
1197 if (!av->alias)
1198 return false;
1199 return match_tags(pat, &av->alias->tags);
1200 case MUTT_PAT_AND:
1201 return pat->pat_not ^ (perform_alias_and(pat->child, flags, av, cache) > 0);
1202 case MUTT_PAT_OR:
1203 return pat->pat_not ^ (perform_alias_or(pat->child, flags, av, cache) > 0);
1204 }
1205
1206 return false;
1207}
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 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
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function: