NeoMutt  2025-09-05-43-g177ed6
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 "copy.h"
#include "handler.h"
#include "maillist.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

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 845 of file exec.c.

848{
849 switch (pat->op)
850 {
851 case MUTT_PAT_AND:
852 return pat->pat_not ^ (perform_and(pat->child, flags, m, e, msg, cache) > 0);
853 case MUTT_PAT_OR:
854 return pat->pat_not ^ (perform_or(pat->child, flags, m, e, msg, cache) > 0);
855 case MUTT_PAT_THREAD:
856 return pat->pat_not ^
857 match_threadcomplete(pat->child, flags, m, e->thread, 1, 1, 1, 1);
858 case MUTT_PAT_PARENT:
859 return pat->pat_not ^ match_threadparent(pat->child, flags, m, e->thread);
861 return pat->pat_not ^ match_threadchildren(pat->child, flags, m, e->thread);
862 case MUTT_ALL:
863 return !pat->pat_not;
864 case MUTT_EXPIRED:
865 return pat->pat_not ^ e->expired;
866 case MUTT_SUPERSEDED:
867 return pat->pat_not ^ e->superseded;
868 case MUTT_FLAG:
869 return pat->pat_not ^ e->flagged;
870 case MUTT_TAG:
871 return pat->pat_not ^ e->tagged;
872 case MUTT_NEW:
873 return pat->pat_not ? e->old || e->read : !(e->old || e->read);
874 case MUTT_UNREAD:
875 return pat->pat_not ? e->read : !e->read;
876 case MUTT_REPLIED:
877 return pat->pat_not ^ e->replied;
878 case MUTT_OLD:
879 return pat->pat_not ? (!e->old || e->read) : (e->old && !e->read);
880 case MUTT_READ:
881 return pat->pat_not ^ e->read;
882 case MUTT_DELETED:
883 return pat->pat_not ^ e->deleted;
884 case MUTT_PAT_MESSAGE:
885 return pat->pat_not ^
886 ((email_msgno(e) >= pat->min) && (email_msgno(e) <= pat->max));
887 case MUTT_PAT_DATE:
888 if (pat->dynamic)
890 return pat->pat_not ^ ((e->date_sent >= pat->min) && (e->date_sent <= pat->max));
892 if (pat->dynamic)
894 return pat->pat_not ^ ((e->received >= pat->min) && (e->received <= pat->max));
895 case MUTT_PAT_BODY:
896 case MUTT_PAT_HEADER:
898 if (pat->sendmode)
899 {
900 if (!e->body || !e->body->filename)
901 return false;
902 return pat->pat_not ^ msg_search_sendmode(e, pat);
903 }
904 /* m can be NULL in certain cases, such as when replying to a message
905 * from the attachment menu and the user has a reply-hook using "~e".
906 * This is also the case when message scoring. */
907 if (!m)
908 return false;
909 /* IMAP search sets e->matched at search compile time */
910 if ((m->type == MUTT_IMAP) && pat->string_match)
911 return e->matched;
912 return pat->pat_not ^ msg_search(pat, e, msg);
914 if (!m)
915 return false;
916 if (m->type == MUTT_IMAP)
917 {
918 return (pat->string_match) ? e->matched : false;
919 }
920 mutt_error(_("error: server custom search only supported with IMAP"));
921 return false;
922 case MUTT_PAT_SENDER:
923 if (!e->env)
924 return false;
925 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
926 1, &e->env->sender);
927 case MUTT_PAT_FROM:
928 if (!e->env)
929 return false;
930 return pat->pat_not ^
931 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->from);
932 case MUTT_PAT_TO:
933 if (!e->env)
934 return false;
935 return pat->pat_not ^
936 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->to);
937 case MUTT_PAT_CC:
938 if (!e->env)
939 return false;
940 return pat->pat_not ^
941 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->cc);
942 case MUTT_PAT_BCC:
943 if (!e->env)
944 return false;
945 return pat->pat_not ^
946 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->bcc);
947 case MUTT_PAT_SUBJECT:
948 if (!e->env)
949 return false;
950 return pat->pat_not ^ (e->env->subject && patmatch(pat, e->env->subject));
951 case MUTT_PAT_ID:
953 if (!e->env)
954 return false;
955 return pat->pat_not ^ (e->env->message_id && patmatch(pat, e->env->message_id));
956 case MUTT_PAT_SCORE:
957 return pat->pat_not ^ (e->score >= pat->min &&
958 (pat->max == MUTT_MAXRANGE || e->score <= pat->max));
959 case MUTT_PAT_SIZE:
960 return pat->pat_not ^ (e->body->length >= pat->min &&
961 (pat->max == MUTT_MAXRANGE || e->body->length <= pat->max));
963 if (!e->env)
964 return false;
965 return pat->pat_not ^ (match_reference(pat, &e->env->references) ||
966 match_reference(pat, &e->env->in_reply_to));
967 case MUTT_PAT_ADDRESS:
968 if (!e->env)
969 return false;
970 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
971 5, &e->env->from, &e->env->sender,
972 &e->env->to, &e->env->cc, &e->env->bcc);
974 if (!e->env)
975 return false;
976 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 3,
977 &e->env->to, &e->env->cc, &e->env->bcc);
978 case MUTT_PAT_LIST: /* known list, subscribed or not */
979 {
980 if (!e->env)
981 return false;
982
983 bool result;
984 if (cache)
985 {
986 int *cache_entry = pat->all_addr ? &cache->list_all : &cache->list_one;
987 if (!is_pattern_cache_set(*cache_entry))
988 {
989 set_pattern_cache_value(cache_entry,
990 mutt_is_list_recipient(pat->all_addr, e->env));
991 }
992 result = get_pattern_cache_value(*cache_entry);
993 }
994 else
995 {
996 result = mutt_is_list_recipient(pat->all_addr, e->env);
997 }
998 return pat->pat_not ^ result;
999 }
1001 {
1002 if (!e->env)
1003 return false;
1004
1005 bool result;
1006 if (cache)
1007 {
1008 int *cache_entry = pat->all_addr ? &cache->sub_all : &cache->sub_one;
1009 if (!is_pattern_cache_set(*cache_entry))
1010 {
1011 set_pattern_cache_value(cache_entry,
1013 }
1014 result = get_pattern_cache_value(*cache_entry);
1015 }
1016 else
1017 {
1019 }
1020 return pat->pat_not ^ result;
1021 }
1023 {
1024 if (!e->env)
1025 return false;
1026
1027 bool result;
1028 if (cache)
1029 {
1030 int *cache_entry = pat->all_addr ? &cache->pers_recip_all : &cache->pers_recip_one;
1031 if (!is_pattern_cache_set(*cache_entry))
1032 {
1033 set_pattern_cache_value(cache_entry,
1034 match_user(pat->all_addr, 3, &e->env->to,
1035 &e->env->cc, &e->env->bcc));
1036 }
1037 result = get_pattern_cache_value(*cache_entry);
1038 }
1039 else
1040 {
1041 result = match_user(pat->all_addr, 3, &e->env->to, &e->env->cc, &e->env->bcc);
1042 }
1043 return pat->pat_not ^ result;
1044 }
1046 {
1047 if (!e->env)
1048 return false;
1049
1050 bool result;
1051 if (cache)
1052 {
1053 int *cache_entry = pat->all_addr ? &cache->pers_from_all : &cache->pers_from_one;
1054 if (!is_pattern_cache_set(*cache_entry))
1055 {
1056 set_pattern_cache_value(cache_entry,
1057 match_user(pat->all_addr, 1, &e->env->from));
1058 }
1059 result = get_pattern_cache_value(*cache_entry);
1060 }
1061 else
1062 {
1063 result = match_user(pat->all_addr, 1, &e->env->from);
1064 }
1065 return pat->pat_not ^ result;
1066 }
1067 case MUTT_PAT_COLLAPSED:
1068 return pat->pat_not ^ (e->collapsed && e->num_hidden > 1);
1070 if (!WithCrypto)
1071 {
1073 return false;
1074 }
1075 return pat->pat_not ^ ((e->security & SEC_SIGN) ? 1 : 0);
1077 if (!WithCrypto)
1078 {
1080 return false;
1081 }
1082 return pat->pat_not ^ ((e->security & SEC_GOODSIGN) ? 1 : 0);
1084 if (!WithCrypto)
1085 {
1087 return false;
1088 }
1089 return pat->pat_not ^ ((e->security & SEC_ENCRYPT) ? 1 : 0);
1090 case MUTT_PAT_PGP_KEY:
1091 if (!(WithCrypto & APPLICATION_PGP))
1092 {
1094 return false;
1095 }
1096 return pat->pat_not ^ ((e->security & PGP_KEY) == PGP_KEY);
1097 case MUTT_PAT_XLABEL:
1098 if (!e->env)
1099 return false;
1100 return pat->pat_not ^ (e->env->x_label && patmatch(pat, e->env->x_label));
1102 {
1103 return match_tags(pat, &e->tags);
1104 }
1105 case MUTT_PAT_HORMEL:
1106 if (!e->env)
1107 return false;
1108 return pat->pat_not ^ (e->env->spam.data && patmatch(pat, e->env->spam.data));
1110 return pat->pat_not ^ (e->thread && e->thread->duplicate_thread);
1112 {
1113 int count = msg ? mutt_count_body_parts(e, msg->fp) : 0;
1114 return pat->pat_not ^
1115 (count >= pat->min && (pat->max == MUTT_MAXRANGE || count <= pat->max));
1116 }
1117 case MUTT_PAT_MIMETYPE:
1118 if (!m || !msg)
1119 return false;
1120 return pat->pat_not ^ match_mime_content_type(pat, e, msg->fp);
1122 return pat->pat_not ^ (e->thread && !e->thread->child);
1123 case MUTT_PAT_BROKEN:
1124 return pat->pat_not ^ (e->thread && e->thread->fake_thread);
1126 if (!e->env)
1127 return false;
1128 return pat->pat_not ^ (e->env->newsgroups && patmatch(pat, e->env->newsgroups));
1129 }
1130 mutt_error(_("error: unknown op %d (report this error)"), pat->op);
1131 return false;
1132}
int mutt_count_body_parts(struct Email *e, FILE *fp)
Count the MIME Body parts.
Definition commands.c:251
@ MUTT_IMAP
'IMAP' Mailbox type
Definition mailbox.h:50
static bool msg_search(struct Pattern *pat, struct Email *e, struct Message *msg)
Search an email.
Definition exec.c:113
static int match_user(bool all_addr, int n,...)
Matches the user's email Address.
Definition exec.c:523
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:558
static void print_crypt_pattern_op_error(int op)
Print an error for a disabled crypto pattern.
Definition exec.c:87
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:596
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:660
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:615
static bool match_reference(struct Pattern *pat, struct ListHead *refs)
Match references against a Pattern.
Definition exec.c:450
static int match_addrlist(struct Pattern *pat, bool match_personal, int n,...)
match a pattern against an address list
Definition exec.c:419
static bool patmatch(const struct Pattern *pat, const char *buf)
Compare a string to a Pattern.
Definition exec.c:72
static int is_pattern_cache_set(int cache_entry)
Is a given Pattern cached?
Definition exec.c:710
static bool match_tags(struct Pattern *pat, struct TagList *tags)
match a pattern against a tags list
Definition exec.c:398
bool mutt_is_subscribed_list_recipient(bool all_addr, struct Envelope *env)
Matches subscribed mailing lists.
Definition exec.c:496
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:353
static bool match_update_dynamic_date(struct Pattern *pat)
Update a dynamic date pattern.
Definition exec.c:672
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:304
static bool get_pattern_cache_value(int cache_entry)
Get pattern cache value.
Definition exec.c:700
static void set_pattern_cache_value(int *cache_entry, int value)
Sets a value in the PatternCache cache entry.
Definition exec.c:689
#define mutt_error(...)
Definition logging2.h:93
#define _(a)
Definition message.h:28
@ MUTT_ALL
All messages.
Definition mutt.h:68
@ MUTT_SUPERSEDED
Superseded messages.
Definition mutt.h:84
@ MUTT_EXPIRED
Expired messages.
Definition mutt.h:83
@ MUTT_READ
Messages that have been read.
Definition mutt.h:73
@ MUTT_OLD
Old messages.
Definition mutt.h:71
@ MUTT_TAG
Tagged messages.
Definition mutt.h:80
@ MUTT_FLAG
Flagged messages.
Definition mutt.h:79
@ MUTT_DELETED
Deleted messages.
Definition mutt.h:78
@ MUTT_NEW
New messages.
Definition mutt.h:70
@ MUTT_UNREAD
Unread messages.
Definition mutt.h:74
@ MUTT_REPLIED
Messages that have been replied to.
Definition mutt.h:72
#define SEC_GOODSIGN
Email has a valid signature.
Definition lib.h:86
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition lib.h:96
#define SEC_ENCRYPT
Email is encrypted.
Definition lib.h:84
#define PGP_KEY
Definition lib.h:105
#define WithCrypto
Definition lib.h:122
#define SEC_SIGN
Email is signed.
Definition lib.h:85
@ MUTT_PAT_HEADER
Pattern matches email's header.
Definition lib.h:156
@ MUTT_PAT_WHOLE_MSG
Pattern matches raw email text.
Definition lib.h:158
@ MUTT_PAT_BROKEN
Message is part of a broken thread.
Definition lib.h:152
@ MUTT_PAT_ID_EXTERNAL
Message-Id is among results from an external query.
Definition lib.h:154
@ MUTT_PAT_OR
Either pattern can match.
Definition lib.h:138
@ MUTT_PAT_CHILDREN
Pattern matches a child email.
Definition lib.h:141
@ MUTT_PAT_PARENT
Pattern matches parent.
Definition lib.h:140
@ MUTT_PAT_REFERENCE
Pattern matches 'References:' or 'In-Reply-To:' field.
Definition lib.h:163
@ MUTT_PAT_FROM
Pattern matches 'From:' field.
Definition lib.h:147
@ MUTT_PAT_DRIVER_TAGS
Pattern matches message tags.
Definition lib.h:176
@ MUTT_PAT_COLLAPSED
Thread is collapsed.
Definition lib.h:145
@ MUTT_PAT_CRYPT_VERIFIED
Message is crypographically verified.
Definition lib.h:171
@ MUTT_PAT_HORMEL
Pattern matches email's spam score.
Definition lib.h:157
@ MUTT_PAT_SUBJECT
Pattern matches 'Subject:' field.
Definition lib.h:146
@ MUTT_PAT_LIST
Email is on mailing list.
Definition lib.h:165
@ MUTT_PAT_NEWSGROUPS
Pattern matches newsgroup.
Definition lib.h:179
@ MUTT_PAT_PERSONAL_RECIP
Email is addressed to the user.
Definition lib.h:167
@ MUTT_PAT_CC
Pattern matches 'Cc:' field.
Definition lib.h:143
@ MUTT_PAT_SUBSCRIBED_LIST
Email is on subscribed mailing list.
Definition lib.h:166
@ MUTT_PAT_SERVERSEARCH
Server-side pattern matches.
Definition lib.h:175
@ MUTT_PAT_RECIPIENT
User is a recipient of the email.
Definition lib.h:164
@ MUTT_PAT_CRYPT_ENCRYPT
Message is encrypted.
Definition lib.h:172
@ MUTT_PAT_UNREFERENCED
Message is unreferenced in the thread.
Definition lib.h:151
@ MUTT_PAT_CRYPT_SIGN
Message is signed.
Definition lib.h:170
@ MUTT_PAT_MESSAGE
Pattern matches message number.
Definition lib.h:160
@ MUTT_PAT_AND
Both patterns must match.
Definition lib.h:137
@ MUTT_PAT_DATE
Pattern matches 'Date:' field.
Definition lib.h:148
@ MUTT_PAT_XLABEL
Pattern matches keyword/label.
Definition lib.h:174
@ MUTT_PAT_SCORE
Pattern matches email's score.
Definition lib.h:161
@ MUTT_PAT_MIMEATTACH
Pattern matches number of attachments.
Definition lib.h:177
@ MUTT_PAT_DUPLICATED
Duplicate message.
Definition lib.h:150
@ MUTT_PAT_PERSONAL_FROM
Email is from the user.
Definition lib.h:168
@ MUTT_PAT_TO
Pattern matches 'To:' field.
Definition lib.h:142
@ MUTT_PAT_BCC
Pattern matches 'Bcc:' field.
Definition lib.h:144
@ MUTT_PAT_SENDER
Pattern matches sender.
Definition lib.h:159
@ MUTT_PAT_DATE_RECEIVED
Pattern matches date received.
Definition lib.h:149
@ MUTT_PAT_ADDRESS
Pattern matches any address field.
Definition lib.h:169
@ MUTT_PAT_MIMETYPE
Pattern matches MIME type.
Definition lib.h:178
@ MUTT_PAT_PGP_KEY
Message has PGP key.
Definition lib.h:173
@ MUTT_PAT_ID
Pattern matches email's Message-Id.
Definition lib.h:153
@ MUTT_PAT_THREAD
Pattern matches email thread.
Definition lib.h:139
@ MUTT_PAT_SIZE
Pattern matches email's size.
Definition lib.h:162
@ MUTT_PAT_BODY
Pattern matches email's body.
Definition lib.h:155
#define MUTT_MATCH_FULL_ADDRESS
Match the full address.
Definition lib.h:106
#define MUTT_MAXRANGE
Definition private.h:141
static int email_msgno(struct Email *e)
Helper to get the Email's message number.
Definition private.h:136
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:102
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:122
int pers_from_one
~P
Definition lib.h:125
int sub_all
^~u
Definition lib.h:120
int pers_recip_one
~p
Definition lib.h:123
int pers_from_all
^~P
Definition lib.h:124
int sub_one
~u
Definition lib.h:121
bool all_addr
All Addresses in the list must match.
Definition lib.h:80
struct PatternList * child
Arguments to logical operation.
Definition lib.h:90
long min
Minimum for range checks.
Definition lib.h:88
bool string_match
Check a string for a match.
Definition lib.h:81
long max
Maximum for range checks.
Definition lib.h:89
bool dynamic
Evaluate date ranges at run time.
Definition lib.h:85
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition lib.h:78
bool sendmode
Evaluate searches in send-mode.
Definition lib.h:86
bool pat_not
Pattern should be inverted (not)
Definition lib.h:79
+ 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 72 of file exec.c.

73{
74 if (pat->is_multi)
75 return (mutt_list_find(&pat->p.multi_cases, buf) != NULL);
76 if (pat->string_match)
77 return pat->ign_case ? mutt_istr_find(buf, pat->p.str) : strstr(buf, pat->p.str);
78 if (pat->group_match)
79 return mutt_group_match(pat->p.group, buf);
80 return (regexec(pat->p.regex, buf, 0, NULL, 0) == 0);
81}
bool mutt_group_match(struct Group *g, const char *s)
Does a string match an entry in a Group?
Definition group.c:370
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:523
bool group_match
Check a group of Addresses.
Definition lib.h:82
union Pattern::@006112053024257132210207314205210350156165326341 p
struct Group * group
Address group if group_match is set.
Definition lib.h:93
regex_t * regex
Compiled regex, for non-pattern matching.
Definition lib.h:92
struct ListHead multi_cases
Multiple strings for ~I pattern.
Definition lib.h:95
char * str
String, if string_match is set.
Definition lib.h:94
bool ign_case
Ignore case for local string_match searches.
Definition lib.h:83
bool is_multi
Multiple case (only for ~I pattern now)
Definition lib.h:87
+ 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 87 of file exec.c.

88{
89 const struct PatternFlags *entry = lookup_op(op);
90 if (entry)
91 {
92 /* L10N: One of the crypt pattern operators: ~g, ~G, ~k, ~V
93 was invoked when NeoMutt was compiled without crypto support.
94 %c is the pattern character, i.e. "g". */
95 mutt_error(_("Pattern operator '~%c' is disabled"), entry->tag);
96 }
97 else
98 {
99 /* L10N: An unknown pattern operator was somehow invoked.
100 This shouldn't be possible unless there is a bug. */
101 mutt_error(_("error: unknown op %d (report this error)"), op);
102 }
103}
const struct PatternFlags * lookup_op(int op)
Lookup the Pattern Flags for an op.
Definition flags.c:211
Mapping between user character and internal constant.
Definition private.h:64
char tag
Character used to represent this operation, e.g. 'A' for '~A'.
Definition private.h:65
int op
Operation to perform, e.g. MUTT_PAT_SCORE.
Definition private.h:66
+ 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 113 of file exec.c.

114{
115 ASSERT(msg);
116
117 bool match = false;
118
119 FILE *fp = NULL;
120 long len = 0;
121#ifdef USE_FMEMOPEN
122 char *temp = NULL;
123 size_t tempsize = 0;
124#else
125 struct stat st = { 0 };
126#endif
127
128 const bool needs_head = (pat->op == MUTT_PAT_HEADER) || (pat->op == MUTT_PAT_WHOLE_MSG);
129 const bool needs_body = (pat->op == MUTT_PAT_BODY) || (pat->op == MUTT_PAT_WHOLE_MSG);
130 const bool c_thorough_search = cs_subset_bool(NeoMutt->sub, "thorough_search");
131 if (c_thorough_search)
132 {
133 /* decode the header / body */
134 struct State state = { 0 };
135 state.fp_in = msg->fp;
136 state.flags = STATE_CHARCONV;
137#ifdef USE_FMEMOPEN
138 state.fp_out = open_memstream(&temp, &tempsize);
139 if (!state.fp_out)
140 {
141 mutt_perror(_("Error opening 'memory stream'"));
142 return false;
143 }
144#else
145 state.fp_out = mutt_file_mkstemp();
146 if (!state.fp_out)
147 {
148 mutt_perror(_("Can't create temporary file"));
149 return false;
150 }
151#endif
152
153 if (needs_head)
154 {
155 mutt_copy_header(msg->fp, e, state.fp_out, CH_FROM | CH_DECODE, NULL, 0);
156 }
157
158 if (needs_body)
159 {
161
162 if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT) &&
164 {
165 if (state.fp_out)
166 {
167 mutt_file_fclose(&state.fp_out);
168#ifdef USE_FMEMOPEN
169 FREE(&temp);
170#endif
171 }
172 return false;
173 }
174
175 if (!mutt_file_seek(msg->fp, e->offset, SEEK_SET))
176 {
177#ifdef USE_FMEMOPEN
178 FREE(&temp);
179#endif
180 mutt_file_fclose(&state.fp_out);
181 return false;
182 }
183 mutt_body_handler(e->body, &state);
184 }
185
186#ifdef USE_FMEMOPEN
187 mutt_file_fclose(&state.fp_out);
188 len = tempsize;
189
190 if (tempsize != 0)
191 {
192 fp = fmemopen(temp, tempsize, "r");
193 if (!fp)
194 {
195 mutt_perror(_("Error re-opening 'memory stream'"));
196 FREE(&temp);
197 return false;
198 }
199 }
200 else
201 { /* fmemopen can't handle empty buffers */
202 fp = mutt_file_fopen("/dev/null", "r");
203 if (!fp)
204 {
205 mutt_perror(_("Error opening /dev/null"));
206 FREE(&temp);
207 return false;
208 }
209 }
210#else
211 fp = state.fp_out;
212 fflush(fp);
213 if (!mutt_file_seek(fp, 0, SEEK_SET) || fstat(fileno(fp), &st))
214 {
215 mutt_perror(_("Error checking length of temporary file"));
216 mutt_file_fclose(&fp);
217 return false;
218 }
219 len = (long) st.st_size;
220#endif
221 }
222 else
223 {
224 /* raw header / body */
225 fp = msg->fp;
226 if (needs_head)
227 {
228 if (!mutt_file_seek(fp, e->offset, SEEK_SET))
229 {
230 return false;
231 }
232 len = e->body->offset - e->offset;
233 }
234 if (needs_body)
235 {
236 if (pat->op == MUTT_PAT_BODY)
237 {
238 if (!mutt_file_seek(fp, e->body->offset, SEEK_SET))
239 {
240 return false;
241 }
242 }
243 len += e->body->length;
244 }
245 }
246
247 /* search the file "fp" */
248 if (pat->op == MUTT_PAT_HEADER)
249 {
250 struct Buffer *buf = buf_pool_get();
251 while (len > 0)
252 {
253 if (mutt_rfc822_read_line(fp, buf) == 0)
254 {
255 break;
256 }
257 len -= buf_len(buf);
258 if (patmatch(pat, buf_string(buf)))
259 {
260 match = true;
261 break;
262 }
263 }
264 buf_pool_release(&buf);
265 }
266 else
267 {
268 char buf[1024] = { 0 };
269 while (len > 0)
270 {
271 if (!fgets(buf, sizeof(buf), fp))
272 {
273 break; /* don't loop forever */
274 }
275 len -= mutt_str_len(buf);
276 if (patmatch(pat, buf))
277 {
278 match = true;
279 break;
280 }
281 }
282 }
283
284 if (c_thorough_search)
285 mutt_file_fclose(&fp);
286
287#ifdef USE_FMEMOPEN
288 FREE(&temp);
289#endif
290
291 return match;
292}
void mutt_parse_mime_message(struct Email *e, FILE *fp)
Parse a MIME email.
Definition commands.c:596
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.c:421
#define CH_DECODE
Do RFC2047 header decoding.
Definition copy.h:56
#define CH_FROM
Retain the "From " message separator?
Definition copy.h:58
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition crypt.c:132
size_t mutt_rfc822_read_line(FILE *fp, struct Buffer *buf)
Read a header line from a file.
Definition parse.c:1124
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition file.c:655
#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:94
int mutt_body_handler(struct Body *b, struct State *state)
Handler for the Body of an email.
Definition handler.c:1632
#define FREE(x)
Definition memory.h:62
#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:498
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:96
#define ASSERT(COND)
Definition signal2.h:60
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:43
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:47
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 304 of file exec.c.

307{
308 struct Pattern *p = NULL;
309
310 SLIST_FOREACH(p, pat, entries)
311 {
312 if (!pattern_exec(p, flags, m, e, msg, cache))
313 {
314 return false;
315 }
316 }
317 return true;
318}
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:845
#define SLIST_FOREACH(var, head, field)
Definition queue.h:229
A simple (non-regex) pattern.
Definition lib.h:77
+ 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 328 of file exec.c.

330{
331 struct Pattern *p = NULL;
332
333 SLIST_FOREACH(p, pat, entries)
334 {
335 if (!mutt_pattern_alias_exec(p, flags, av, cache))
336 {
337 return false;
338 }
339 }
340 return true;
341}
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:1175
+ 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 353 of file exec.c.

356{
357 struct Pattern *p = NULL;
358
359 SLIST_FOREACH(p, pat, entries)
360 {
361 if (pattern_exec(p, flags, m, e, msg, cache))
362 {
363 return true;
364 }
365 }
366 return false;
367}
+ 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 377 of file exec.c.

379{
380 struct Pattern *p = NULL;
381
382 SLIST_FOREACH(p, pat, entries)
383 {
384 if (mutt_pattern_alias_exec(p, flags, av, cache))
385 {
386 return true;
387 }
388 }
389 return false;
390}
+ 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 398 of file exec.c.

399{
400 struct Tag *tag = NULL;
401 bool matched = false;
402 STAILQ_FOREACH(tag, tags, entries)
403 {
404 matched |= patmatch(pat, tag->name);
405 }
406 return pat->pat_not ^ matched;
407}
#define STAILQ_FOREACH(var, head, field)
Definition queue.h:390
LinkedList Tag Element.
Definition tags.h:42
char * name
Tag name.
Definition tags.h:43
+ 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 419 of file exec.c.

420{
421 va_list ap;
422
423 va_start(ap, n);
424 while (n-- > 0)
425 {
426 struct AddressList *al = va_arg(ap, struct AddressList *);
427 struct Address *a = NULL;
428 TAILQ_FOREACH(a, al, entries)
429 {
430 if (pat->all_addr ^
431 ((!pat->is_alias || alias_reverse_lookup(a)) &&
432 ((a->mailbox && patmatch(pat, buf_string(a->mailbox))) ||
433 (match_personal && a->personal && patmatch(pat, buf_string(a->personal))))))
434 {
435 va_end(ap);
436 return !pat->all_addr; /* Found match, or non-match if all_addr */
437 }
438 }
439 }
440 va_end(ap);
441 return pat->all_addr; /* No matches, or all matches if all_addr */
442}
struct Address * alias_reverse_lookup(const struct Address *addr)
Does the user have an alias for the given address.
Definition reverse.c:105
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:782
An email address.
Definition address.h:36
struct Buffer * personal
Real name of address.
Definition address.h:37
struct Buffer * mailbox
Mailbox and host address.
Definition address.h:38
bool is_alias
Is there an alias for this Address?
Definition lib.h:84
+ 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 450 of file exec.c.

451{
452 struct ListNode *np = NULL;
453 STAILQ_FOREACH(np, refs, entries)
454 {
455 if (patmatch(pat, np->data))
456 return true;
457 }
458 return false;
459}
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 472 of file exec.c.

473{
474 struct AddressList *als[] = { &env->to, &env->cc };
475 for (size_t i = 0; i < countof(als); i++)
476 {
477 struct AddressList *al = als[i];
478 struct Address *a = NULL;
479 TAILQ_FOREACH(a, al, entries)
480 {
481 if (all_addr ^ p(a))
482 return !all_addr;
483 }
484 }
485 return all_addr;
486}
#define countof(x)
Definition memory.h:44
+ 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 496 of file exec.c.

497{
499}
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:472
bool mutt_is_subscribed_list(const struct Address *addr)
Is this the email address of a user-subscribed mailing list?
Definition maillist.c:56
+ 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 509 of file exec.c.

510{
511 return mutt_is_predicate_recipient(all_addr, env, &mutt_is_mail_list);
512}
bool mutt_is_mail_list(const struct Address *addr)
Is this the email address of a mailing list?
Definition maillist.c:44
+ 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 523 of file exec.c.

524{
525 va_list ap;
526
527 va_start(ap, n);
528 while (n-- > 0)
529 {
530 struct AddressList *al = va_arg(ap, struct AddressList *);
531 struct Address *a = NULL;
532 TAILQ_FOREACH(a, al, entries)
533 {
534 if (all_addr ^ mutt_addr_is_user(a))
535 {
536 va_end(ap);
537 return !all_addr;
538 }
539 }
540 }
541 va_end(ap);
542 return all_addr;
543}
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition alias.c:596
+ 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 558 of file exec.c.

561{
562 if (!t)
563 return 0;
564
565 int a;
566 struct Email *e = t->message;
567 if (e)
568 if (mutt_pattern_exec(SLIST_FIRST(pat), flags, m, e, NULL))
569 return 1;
570
571 if (up && (a = match_threadcomplete(pat, flags, m, t->parent, 1, 1, 1, 0)))
572 return a;
573 if (right && t->parent && (a = match_threadcomplete(pat, flags, m, t->next, 0, 0, 1, 1)))
574 {
575 return a;
576 }
577 if (left && t->parent && (a = match_threadcomplete(pat, flags, m, t->prev, 1, 0, 0, 1)))
578 {
579 return a;
580 }
581 if (down && (a = match_threadcomplete(pat, flags, m, t->child, 1, 0, 1, 1)))
582 return a;
583 return 0;
584}
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:1148
#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 596 of file exec.c.

598{
599 if (!t || !t->parent || !t->parent->message)
600 return 0;
601
602 return mutt_pattern_exec(SLIST_FIRST(pat), flags, m, t->parent->message, NULL);
603}
+ 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 615 of file exec.c.

617{
618 if (!t || !t->child)
619 return 0;
620
621 for (t = t->child; t; t = t->next)
622 if (t->message && mutt_pattern_exec(SLIST_FIRST(pat), flags, m, t->message, NULL))
623 return 1;
624
625 return 0;
626}
+ 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 635 of file exec.c.

636{
637 if (!b)
638 return false;
639
640 char buf[256] = { 0 };
641 snprintf(buf, sizeof(buf), "%s/%s", BODY_TYPE(b), b->subtype);
642
643 if (patmatch(pat, buf))
644 return true;
645 if (match_content_type(pat, b->parts))
646 return true;
647 if (match_content_type(pat, b->next))
648 return true;
649 return false;
650}
static bool match_content_type(const struct Pattern *pat, struct Body *b)
Match a Pattern against an Attachment's Content-Type.
Definition exec.c:635
#define BODY_TYPE(body)
Definition mime.h:89
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 660 of file exec.c.

661{
663 return match_content_type(pat, e->body);
664}
+ 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 672 of file exec.c.

673{
674 struct Buffer *err = buf_pool_get();
675
676 bool rc = eval_date_minmax(pat, pat->p.str, err);
677 buf_pool_release(&err);
678
679 return rc;
680}
bool eval_date_minmax(struct Pattern *pat, const char *s, struct Buffer *err)
Evaluate a date-range pattern against 'now'.
Definition compile.c:492
+ 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 689 of file exec.c.

690{
691 *cache_entry = (value != 0) ? 2 : 1;
692}
+ 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 700 of file exec.c.

701{
702 return cache_entry == 2;
703}
+ 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 710 of file exec.c.

711{
712 return cache_entry != 0;
713}
+ 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 723 of file exec.c.

724{
725 bool match = false;
726 char *buf = NULL;
727 size_t blen = 0;
728 FILE *fp = NULL;
729
730 if ((pat->op == MUTT_PAT_HEADER) || (pat->op == MUTT_PAT_WHOLE_MSG))
731 {
732 struct Buffer *tempfile = buf_pool_get();
733 buf_mktemp(tempfile);
734 fp = mutt_file_fopen(buf_string(tempfile), "w+");
735 if (!fp)
736 {
737 mutt_perror("%s", buf_string(tempfile));
738 buf_pool_release(&tempfile);
739 return 0;
740 }
741
743 false, false, NeoMutt->sub);
744 fflush(fp);
745 if (mutt_file_seek(fp, 0, SEEK_SET))
746 {
747 while ((buf = mutt_file_read_line(buf, &blen, fp, NULL, MUTT_RL_NO_FLAGS)) != NULL)
748 {
749 if (patmatch(pat, buf) == 0)
750 {
751 match = true;
752 break;
753 }
754 }
755 }
756
757 FREE(&buf);
758 mutt_file_fclose(&fp);
759 unlink(buf_string(tempfile));
760 buf_pool_release(&tempfile);
761
762 if (match)
763 return match;
764 }
765
766 if ((pat->op == MUTT_PAT_BODY) || (pat->op == MUTT_PAT_WHOLE_MSG))
767 {
768 fp = mutt_file_fopen(e->body->filename, "r");
769 if (!fp)
770 {
771 mutt_perror("%s", e->body->filename);
772 return 0;
773 }
774
775 while ((buf = mutt_file_read_line(buf, &blen, fp, NULL, MUTT_RL_NO_FLAGS)) != NULL)
776 {
777 if (patmatch(pat, buf) == 0)
778 {
779 match = true;
780 break;
781 }
782 }
783
784 FREE(&buf);
785 mutt_file_fclose(&fp);
786 }
787
788 return match;
789}
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:685
#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:577
@ MUTT_WRITE_HEADER_POSTPONE
A postponed Email, just the envelope info.
Definition header.h:42
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 798 of file exec.c.

799{
800 if (!m)
801 {
802 return false;
803 }
804
805 if ((pat->op == MUTT_PAT_MIMETYPE) || (pat->op == MUTT_PAT_MIMEATTACH))
806 {
807 return true;
808 }
809
810 if ((pat->op == MUTT_PAT_WHOLE_MSG) || (pat->op == MUTT_PAT_BODY) || (pat->op == MUTT_PAT_HEADER))
811 {
812 return !((m->type == MUTT_IMAP) && pat->string_match);
813 }
814
815 if ((pat->op == MUTT_PAT_AND) || (pat->op == MUTT_PAT_OR))
816 {
817 struct Pattern *p = NULL;
818 SLIST_FOREACH(p, pat->child, entries)
819 {
820 if (pattern_needs_msg(m, p))
821 {
822 return true;
823 }
824 }
825 }
826
827 return false;
828}
static bool pattern_needs_msg(const struct Mailbox *m, const struct Pattern *pat)
Check whether a pattern needs a full message.
Definition exec.c:798
+ 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 1148 of file exec.c.

1150{
1151 const bool needs_msg = pattern_needs_msg(m, pat);
1152 struct Message *msg = needs_msg ? mx_msg_open(m, e) : NULL;
1153 if (needs_msg && !msg)
1154 {
1155 return false;
1156 }
1157 const bool matched = pattern_exec(pat, flags, m, e, msg, cache);
1158 mx_msg_close(m, &msg);
1159 return matched;
1160}
int mx_msg_close(struct Mailbox *m, struct Message **ptr)
Close a message.
Definition mx.c:1185
struct Message * mx_msg_open(struct Mailbox *m, struct Email *e)
Return a stream pointer for a message.
Definition mx.c:1139
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 1175 of file exec.c.

1177{
1178 switch (pat->op)
1179 {
1180 case MUTT_PAT_FROM: /* alias */
1181 if (!av->alias)
1182 return false;
1183 return pat->pat_not ^ (av->alias->name && patmatch(pat, av->alias->name));
1184 case MUTT_PAT_CC: /* comment */
1185 if (!av->alias)
1186 return false;
1187 return pat->pat_not ^ (av->alias->comment && patmatch(pat, av->alias->comment));
1188 case MUTT_PAT_TO: /* alias address list */
1189 if (!av->alias)
1190 return false;
1191 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
1192 1, &av->alias->addr);
1194 if (!av->alias)
1195 return false;
1196 return match_tags(pat, &av->alias->tags);
1197 case MUTT_PAT_AND:
1198 return pat->pat_not ^ (perform_alias_and(pat->child, flags, av, cache) > 0);
1199 case MUTT_PAT_OR:
1200 return pat->pat_not ^ (perform_alias_or(pat->child, flags, av, cache) > 0);
1201 }
1202
1203 return false;
1204}
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:328
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:377
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: