NeoMutt
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
exec.c File Reference

Execute a Pattern. More...

#include "config.h"
#include <assert.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 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
  • Pietro Cerutti
  • Richard Russon

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

827{
828 switch (pat->op)
829 {
830 case MUTT_PAT_AND:
831 return pat->pat_not ^ (perform_and(pat->child, flags, m, e, msg, cache) > 0);
832 case MUTT_PAT_OR:
833 return pat->pat_not ^ (perform_or(pat->child, flags, m, e, msg, cache) > 0);
834 case MUTT_PAT_THREAD:
835 return pat->pat_not ^
836 match_threadcomplete(pat->child, flags, m, e->thread, 1, 1, 1, 1);
837 case MUTT_PAT_PARENT:
838 return pat->pat_not ^ match_threadparent(pat->child, flags, m, e->thread);
840 return pat->pat_not ^ match_threadchildren(pat->child, flags, m, e->thread);
841 case MUTT_ALL:
842 return !pat->pat_not;
843 case MUTT_EXPIRED:
844 return pat->pat_not ^ e->expired;
845 case MUTT_SUPERSEDED:
846 return pat->pat_not ^ e->superseded;
847 case MUTT_FLAG:
848 return pat->pat_not ^ e->flagged;
849 case MUTT_TAG:
850 return pat->pat_not ^ e->tagged;
851 case MUTT_NEW:
852 return pat->pat_not ? e->old || e->read : !(e->old || e->read);
853 case MUTT_UNREAD:
854 return pat->pat_not ? e->read : !e->read;
855 case MUTT_REPLIED:
856 return pat->pat_not ^ e->replied;
857 case MUTT_OLD:
858 return pat->pat_not ? (!e->old || e->read) : (e->old && !e->read);
859 case MUTT_READ:
860 return pat->pat_not ^ e->read;
861 case MUTT_DELETED:
862 return pat->pat_not ^ e->deleted;
863 case MUTT_PAT_MESSAGE:
864 return pat->pat_not ^ ((EMSG(e) >= pat->min) && (EMSG(e) <= pat->max));
865 case MUTT_PAT_DATE:
866 if (pat->dynamic)
868 return pat->pat_not ^ ((e->date_sent >= pat->min) && (e->date_sent <= pat->max));
870 if (pat->dynamic)
872 return pat->pat_not ^ ((e->received >= pat->min) && (e->received <= pat->max));
873 case MUTT_PAT_BODY:
874 case MUTT_PAT_HEADER:
876 if (pat->sendmode)
877 {
878 if (!e->body || !e->body->filename)
879 return false;
880 return pat->pat_not ^ msg_search_sendmode(e, pat);
881 }
882 /* m can be NULL in certain cases, such as when replying to a message
883 * from the attachment menu and the user has a reply-hook using "~e".
884 * This is also the case when message scoring. */
885 if (!m)
886 return false;
887#ifdef USE_IMAP
888 /* IMAP search sets e->matched at search compile time */
889 if ((m->type == MUTT_IMAP) && pat->string_match)
890 return e->matched;
891#endif
892 return pat->pat_not ^ msg_search(pat, e, msg);
894#ifdef USE_IMAP
895 if (!m)
896 return false;
897 if (m->type == MUTT_IMAP)
898 {
899 return (pat->string_match) ? e->matched : false;
900 }
901#endif
902 mutt_error(_("error: server custom search only supported with IMAP"));
903 return false;
904 case MUTT_PAT_SENDER:
905 if (!e->env)
906 return false;
907 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
908 1, &e->env->sender);
909 case MUTT_PAT_FROM:
910 if (!e->env)
911 return false;
912 return pat->pat_not ^
913 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->from);
914 case MUTT_PAT_TO:
915 if (!e->env)
916 return false;
917 return pat->pat_not ^
918 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->to);
919 case MUTT_PAT_CC:
920 if (!e->env)
921 return false;
922 return pat->pat_not ^
923 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->cc);
924 case MUTT_PAT_BCC:
925 if (!e->env)
926 return false;
927 return pat->pat_not ^
928 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->bcc);
929 case MUTT_PAT_SUBJECT:
930 if (!e->env)
931 return false;
932 return pat->pat_not ^ (e->env->subject && patmatch(pat, e->env->subject));
933 case MUTT_PAT_ID:
935 if (!e->env)
936 return false;
937 return pat->pat_not ^ (e->env->message_id && patmatch(pat, e->env->message_id));
938 case MUTT_PAT_SCORE:
939 return pat->pat_not ^ (e->score >= pat->min &&
940 (pat->max == MUTT_MAXRANGE || e->score <= pat->max));
941 case MUTT_PAT_SIZE:
942 return pat->pat_not ^ (e->body->length >= pat->min &&
943 (pat->max == MUTT_MAXRANGE || e->body->length <= pat->max));
945 if (!e->env)
946 return false;
947 return pat->pat_not ^ (match_reference(pat, &e->env->references) ||
948 match_reference(pat, &e->env->in_reply_to));
949 case MUTT_PAT_ADDRESS:
950 if (!e->env)
951 return false;
952 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
953 5, &e->env->from, &e->env->sender,
954 &e->env->to, &e->env->cc, &e->env->bcc);
956 if (!e->env)
957 return false;
958 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 3,
959 &e->env->to, &e->env->cc, &e->env->bcc);
960 case MUTT_PAT_LIST: /* known list, subscribed or not */
961 {
962 if (!e->env)
963 return false;
964
965 bool result;
966 if (cache)
967 {
968 int *cache_entry = pat->all_addr ? &cache->list_all : &cache->list_one;
969 if (!is_pattern_cache_set(*cache_entry))
970 {
971 set_pattern_cache_value(cache_entry,
973 }
974 result = get_pattern_cache_value(*cache_entry);
975 }
976 else
977 {
978 result = mutt_is_list_recipient(pat->all_addr, e->env);
979 }
980 return pat->pat_not ^ result;
981 }
983 {
984 if (!e->env)
985 return false;
986
987 bool result;
988 if (cache)
989 {
990 int *cache_entry = pat->all_addr ? &cache->sub_all : &cache->sub_one;
991 if (!is_pattern_cache_set(*cache_entry))
992 {
993 set_pattern_cache_value(cache_entry,
995 }
996 result = get_pattern_cache_value(*cache_entry);
997 }
998 else
999 {
1001 }
1002 return pat->pat_not ^ result;
1003 }
1005 {
1006 if (!e->env)
1007 return false;
1008
1009 bool result;
1010 if (cache)
1011 {
1012 int *cache_entry = pat->all_addr ? &cache->pers_recip_all : &cache->pers_recip_one;
1013 if (!is_pattern_cache_set(*cache_entry))
1014 {
1015 set_pattern_cache_value(cache_entry,
1016 match_user(pat->all_addr, 3, &e->env->to,
1017 &e->env->cc, &e->env->bcc));
1018 }
1019 result = get_pattern_cache_value(*cache_entry);
1020 }
1021 else
1022 {
1023 result = match_user(pat->all_addr, 3, &e->env->to, &e->env->cc, &e->env->bcc);
1024 }
1025 return pat->pat_not ^ result;
1026 }
1028 {
1029 if (!e->env)
1030 return false;
1031
1032 bool result;
1033 if (cache)
1034 {
1035 int *cache_entry = pat->all_addr ? &cache->pers_from_all : &cache->pers_from_one;
1036 if (!is_pattern_cache_set(*cache_entry))
1037 {
1038 set_pattern_cache_value(cache_entry,
1039 match_user(pat->all_addr, 1, &e->env->from));
1040 }
1041 result = get_pattern_cache_value(*cache_entry);
1042 }
1043 else
1044 {
1045 result = match_user(pat->all_addr, 1, &e->env->from);
1046 }
1047 return pat->pat_not ^ result;
1048 }
1049 case MUTT_PAT_COLLAPSED:
1050 return pat->pat_not ^ (e->collapsed && e->num_hidden > 1);
1052 if (!WithCrypto)
1053 {
1055 return false;
1056 }
1057 return pat->pat_not ^ ((e->security & SEC_SIGN) ? 1 : 0);
1059 if (!WithCrypto)
1060 {
1062 return false;
1063 }
1064 return pat->pat_not ^ ((e->security & SEC_GOODSIGN) ? 1 : 0);
1066 if (!WithCrypto)
1067 {
1069 return false;
1070 }
1071 return pat->pat_not ^ ((e->security & SEC_ENCRYPT) ? 1 : 0);
1072 case MUTT_PAT_PGP_KEY:
1073 if (!(WithCrypto & APPLICATION_PGP))
1074 {
1076 return false;
1077 }
1078 return pat->pat_not ^ ((e->security & PGP_KEY) == PGP_KEY);
1079 case MUTT_PAT_XLABEL:
1080 if (!e->env)
1081 return false;
1082 return pat->pat_not ^ (e->env->x_label && patmatch(pat, e->env->x_label));
1084 {
1085 char *tags = driver_tags_get_with_hidden(&e->tags);
1086 const bool rc = (pat->pat_not ^ (tags && patmatch(pat, tags)));
1087 FREE(&tags);
1088 return rc;
1089 }
1090 case MUTT_PAT_HORMEL:
1091 if (!e->env)
1092 return false;
1093 return pat->pat_not ^ (e->env->spam.data && patmatch(pat, e->env->spam.data));
1095 return pat->pat_not ^ (e->thread && e->thread->duplicate_thread);
1097 if (!m)
1098 return false;
1099 {
1100 int count = mutt_count_body_parts(m, e, msg->fp);
1101 return pat->pat_not ^ (count >= pat->min &&
1102 (pat->max == MUTT_MAXRANGE || count <= pat->max));
1103 }
1104 case MUTT_PAT_MIMETYPE:
1105 if (!m)
1106 return false;
1107 return pat->pat_not ^ match_mime_content_type(pat, e, msg->fp);
1109 return pat->pat_not ^ (e->thread && !e->thread->child);
1110 case MUTT_PAT_BROKEN:
1111 return pat->pat_not ^ (e->thread && e->thread->fake_thread);
1112#ifdef USE_NNTP
1114 if (!e->env)
1115 return false;
1116 return pat->pat_not ^ (e->env->newsgroups && patmatch(pat, e->env->newsgroups));
1117#endif
1118 }
1119 mutt_error(_("error: unknown op %d (report this error)"), pat->op);
1120 return false;
1121}
int mutt_count_body_parts(const struct Mailbox *m, struct Email *e, FILE *fp)
Count the MIME Body parts.
Definition: attachments.c:251
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:503
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:538
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:576
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:640
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:595
static bool match_reference(struct Pattern *pat, struct ListHead *refs)
Match references against a Pattern.
Definition: exec.c:430
static int match_addrlist(struct Pattern *pat, bool match_personal, int n,...)
Match a Pattern against an Address list.
Definition: exec.c:399
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:690
bool mutt_is_subscribed_list_recipient(bool all_addr, struct Envelope *env)
Matches subscribed mailing lists.
Definition: exec.c:476
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:350
bool mutt_is_list_recipient(bool all_addr, struct Envelope *env)
Matches known mailing lists.
Definition: exec.c:489
static bool match_update_dynamic_date(struct Pattern *pat)
Update a dynamic date pattern.
Definition: exec.c:652
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:301
static bool get_pattern_cache_value(int cache_entry)
Get pattern cache value.
Definition: exec.c:680
static void set_pattern_cache_value(int *cache_entry, int value)
Sets a value in the PatternCache cache entry.
Definition: exec.c:669
static int msg_search_sendmode(struct Email *e, struct Pattern *pat)
Search in send-mode.
Definition: exec.c:703
#define mutt_error(...)
Definition: logging2.h:92
@ MUTT_IMAP
'IMAP' Mailbox type
Definition: mailbox.h:50
#define FREE(x)
Definition: memory.h:45
#define _(a)
Definition: message.h:28
@ MUTT_ALL
All messages.
Definition: mutt.h:67
@ MUTT_SUPERSEDED
Superseded messages.
Definition: mutt.h:83
@ MUTT_EXPIRED
Expired messages.
Definition: mutt.h:82
@ MUTT_READ
Messages that have been read.
Definition: mutt.h:72
@ MUTT_OLD
Old messages.
Definition: mutt.h:70
@ MUTT_TAG
Tagged messages.
Definition: mutt.h:79
@ MUTT_FLAG
Flagged messages.
Definition: mutt.h:78
@ MUTT_DELETED
Deleted messages.
Definition: mutt.h:77
@ MUTT_NEW
New messages.
Definition: mutt.h:69
@ MUTT_UNREAD
Unread messages.
Definition: mutt.h:73
@ MUTT_REPLIED
Messages that have been replied to.
Definition: mutt.h:71
#define SEC_GOODSIGN
Email has a valid signature.
Definition: lib.h:81
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:91
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:79
#define PGP_KEY
Definition: lib.h:100
#define WithCrypto
Definition: lib.h:117
#define SEC_SIGN
Email is signed.
Definition: lib.h:80
@ 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:180
@ 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:131
#define EMSG(e)
Definition: private.h:129
LOFF_T length
length (in bytes) of attachment
Definition: body.h:53
char * filename
When sending a message, this is the file to which this structure refers.
Definition: body.h:58
char * data
Pointer to data.
Definition: buffer.h:35
bool read
Email is read.
Definition: email.h:48
bool matched
Search matches this Email.
Definition: email.h:101
struct Envelope * env
Envelope information.
Definition: email.h:66
bool collapsed
Is this message part of a collapsed thread?
Definition: email.h:119
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:41
struct Body * body
List of MIME parts.
Definition: email.h:67
bool old
Email is seen, but unread.
Definition: email.h:47
size_t num_hidden
Number of hidden messages in this view (only valid when collapsed is set)
Definition: email.h:122
bool flagged
Marked important?
Definition: email.h:45
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:58
bool replied
Email has been replied to.
Definition: email.h:49
bool expired
Already expired?
Definition: email.h:44
struct TagList tags
For drivers that support server tagging.
Definition: email.h:70
int score
Message score.
Definition: email.h:112
bool deleted
Email is deleted.
Definition: email.h:76
bool tagged
Email is tagged.
Definition: email.h:106
bool superseded
Got superseded?
Definition: email.h:50
time_t received
Time when the message was placed in the mailbox.
Definition: email.h:59
struct MuttThread * thread
Thread of Emails.
Definition: email.h:118
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:79
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:85
struct Buffer spam
Spam header.
Definition: envelope.h:84
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:86
char * subject
Email's subject.
Definition: envelope.h:70
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 list_one
~l
Definition: lib.h:119
int pers_from_one
~P
Definition: lib.h:125
int list_all
^~l
Definition: lib.h:118
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
char * driver_tags_get_with_hidden(struct TagList *list)
Get tags with hiddens.
Definition: tags.c:158
+ 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 mutt_group_match(pat->p.group, buf);
78 return (regexec(pat->p.regex, buf, 0, NULL, 0) == 0);
79}
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:102
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case)
Definition: string.c:593
bool group_match
Check a group of Addresses.
Definition: lib.h:82
union Pattern::@1 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 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 is the pattern character, i.e. "g". */
93 mutt_error(_("Pattern operator '~%c' is disabled"), 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:213
Mapping between user character and internal constant.
Definition: private.h:62
int tag
Character used to represent this operation, e.g. 'A' for '~A'.
Definition: private.h:63
int op
Operation to perform, e.g. MUTT_PAT_SCORE.
Definition: private.h:64
+ 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 return false;
179 }
180 mutt_body_handler(e->body, &state);
181 }
182
183#ifdef USE_FMEMOPEN
184 mutt_file_fclose(&state.fp_out);
185 len = tempsize;
186
187 if (tempsize != 0)
188 {
189 fp = fmemopen(temp, tempsize, "r");
190 if (!fp)
191 {
192 mutt_perror(_("Error re-opening 'memory stream'"));
193 FREE(&temp);
194 return false;
195 }
196 }
197 else
198 { /* fmemopen can't handle empty buffers */
199 fp = mutt_file_fopen("/dev/null", "r");
200 if (!fp)
201 {
202 mutt_perror(_("Error opening /dev/null"));
203 FREE(&temp);
204 return false;
205 }
206 }
207#else
208 fp = state.fp_out;
209 fflush(fp);
210 if (!mutt_file_seek(fp, 0, SEEK_SET) || fstat(fileno(fp), &st))
211 {
212 mutt_perror(_("Error checking length of temporary file"));
213 mutt_file_fclose(&fp);
214 return false;
215 }
216 len = (long) st.st_size;
217#endif
218 }
219 else
220 {
221 /* raw header / body */
222 fp = msg->fp;
223 if (needs_head)
224 {
225 if (!mutt_file_seek(fp, e->offset, SEEK_SET))
226 {
227 return false;
228 }
229 len = e->body->offset - e->offset;
230 }
231 if (needs_body)
232 {
233 if (pat->op == MUTT_PAT_BODY)
234 {
235 if (!mutt_file_seek(fp, e->body->offset, SEEK_SET))
236 {
237 return false;
238 }
239 }
240 len += e->body->length;
241 }
242 }
243
244 /* search the file "fp" */
245 if (pat->op == MUTT_PAT_HEADER)
246 {
247 struct Buffer *buf = buf_pool_get();
248 while (len > 0)
249 {
250 if (mutt_rfc822_read_line(fp, buf) == 0)
251 {
252 break;
253 }
254 len -= buf_len(buf);
255 if (patmatch(pat, buf_string(buf)))
256 {
257 match = true;
258 break;
259 }
260 }
261 buf_pool_release(&buf);
262 }
263 else
264 {
265 char buf[1024] = { 0 };
266 while (len > 0)
267 {
268 if (!fgets(buf, sizeof(buf), fp))
269 {
270 break; /* don't loop forever */
271 }
272 len -= mutt_str_len(buf);
273 if (patmatch(pat, buf))
274 {
275 match = true;
276 break;
277 }
278 }
279 }
280
281 if (c_thorough_search)
282 mutt_file_fclose(&fp);
283
284#ifdef USE_FMEMOPEN
285 FREE(&temp);
286#endif
287
288 return match;
289}
void mutt_parse_mime_message(struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:596
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:466
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:93
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:48
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:423
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:54
#define CH_FROM
Retain the "From " message separator?
Definition: copy.h:56
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:135
size_t mutt_rfc822_read_line(FILE *fp, struct Buffer *buf)
Read a header line from a file.
Definition: parse.c:1090
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:636
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition: file.c:733
#define mutt_perror(...)
Definition: logging2.h:93
int mutt_body_handler(struct Body *b, struct State *state)
Handler for the Body of an email.
Definition: handler.c:1618
#define STATE_CHARCONV
Do character set conversions.
Definition: state.h:36
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:568
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
LOFF_T offset
offset where the actual data begins
Definition: body.h:52
String manipulation buffer.
Definition: buffer.h:34
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:69
Container for Accounts, Notifications.
Definition: neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45
Keep track when processing files.
Definition: state.h:47
StateFlags flags
Flags, e.g. STATE_DISPLAY.
Definition: state.h:51
FILE * fp_out
File to write to.
Definition: state.h:49
FILE * fp_in
File to read from.
Definition: state.h:48
#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 301 of file exec.c.

304{
305 struct Pattern *p = NULL;
306
307 SLIST_FOREACH(p, pat, entries)
308 {
309 if (!pattern_exec(p, flags, m, e, msg, cache))
310 {
311 return false;
312 }
313 }
314 return true;
315}
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:824
#define SLIST_FOREACH(var, head, field)
Definition: queue.h:231
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 325 of file exec.c.

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

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

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

400{
401 va_list ap;
402
403 va_start(ap, n);
404 while (n-- > 0)
405 {
406 struct AddressList *al = va_arg(ap, struct AddressList *);
407 struct Address *a = NULL;
408 TAILQ_FOREACH(a, al, entries)
409 {
410 if (pat->all_addr ^
411 ((!pat->is_alias || alias_reverse_lookup(a)) &&
412 ((a->mailbox && patmatch(pat, buf_string(a->mailbox))) ||
413 (match_personal && a->personal && patmatch(pat, buf_string(a->personal))))))
414 {
415 va_end(ap);
416 return !pat->all_addr; /* Found match, or non-match if all_addr */
417 }
418 }
419 }
420 va_end(ap);
421 return pat->all_addr; /* No matches, or all matches if all_addr */
422}
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:725
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 430 of file exec.c.

431{
432 struct ListNode *np = NULL;
433 STAILQ_FOREACH(np, refs, entries)
434 {
435 if (patmatch(pat, np->data))
436 return true;
437 }
438 return false;
439}
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
A List node for strings.
Definition: list.h:35
char * data
String.
Definition: list.h:36
+ 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 452 of file exec.c.

453{
454 struct AddressList *als[] = { &env->to, &env->cc };
455 for (size_t i = 0; i < mutt_array_size(als); ++i)
456 {
457 struct AddressList *al = als[i];
458 struct Address *a = NULL;
459 TAILQ_FOREACH(a, al, entries)
460 {
461 if (all_addr ^ p(a))
462 return !all_addr;
463 }
464 }
465 return all_addr;
466}
#define mutt_array_size(x)
Definition: memory.h:38
+ 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 476 of file exec.c.

477{
479}
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:452
bool mutt_is_subscribed_list(const struct Address *addr)
Is this the email address of a user-subscribed mailing list? - Implements addr_predicate_t -.
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 489 of file exec.c.

490{
491 return mutt_is_predicate_recipient(all_addr, env, &mutt_is_mail_list);
492}
bool mutt_is_mail_list(const struct Address *addr)
Is this the email address of a mailing list? - Implements addr_predicate_t -.
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 503 of file exec.c.

504{
505 va_list ap;
506
507 va_start(ap, n);
508 while (n-- > 0)
509 {
510 struct AddressList *al = va_arg(ap, struct AddressList *);
511 struct Address *a = NULL;
512 TAILQ_FOREACH(a, al, entries)
513 {
514 if (all_addr ^ mutt_addr_is_user(a))
515 {
516 va_end(ap);
517 return !all_addr;
518 }
519 }
520 }
521 va_end(ap);
522 return all_addr;
523}
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition: alias.c:570
+ 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 538 of file exec.c.

541{
542 if (!t)
543 return 0;
544
545 int a;
546 struct Email *e = t->message;
547 if (e)
548 if (mutt_pattern_exec(SLIST_FIRST(pat), flags, m, e, NULL))
549 return 1;
550
551 if (up && (a = match_threadcomplete(pat, flags, m, t->parent, 1, 1, 1, 0)))
552 return a;
553 if (right && t->parent && (a = match_threadcomplete(pat, flags, m, t->next, 0, 0, 1, 1)))
554 {
555 return a;
556 }
557 if (left && t->parent && (a = match_threadcomplete(pat, flags, m, t->prev, 1, 0, 0, 1)))
558 {
559 return a;
560 }
561 if (down && (a = match_threadcomplete(pat, flags, m, t->child, 1, 0, 1, 1)))
562 return a;
563 return 0;
564}
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:1137
#define SLIST_FIRST(head)
Definition: queue.h:229
The envelope/body of an email.
Definition: email.h:37
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 576 of file exec.c.

578{
579 if (!t || !t->parent || !t->parent->message)
580 return 0;
581
582 return mutt_pattern_exec(SLIST_FIRST(pat), flags, m, t->parent->message, NULL);
583}
+ 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 595 of file exec.c.

597{
598 if (!t || !t->child)
599 return 0;
600
601 for (t = t->child; t; t = t->next)
602 if (t->message && mutt_pattern_exec(SLIST_FIRST(pat), flags, m, t->message, NULL))
603 return 1;
604
605 return 0;
606}
+ 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 615 of file exec.c.

616{
617 if (!b)
618 return false;
619
620 char buf[256] = { 0 };
621 snprintf(buf, sizeof(buf), "%s/%s", TYPE(b), b->subtype);
622
623 if (patmatch(pat, buf))
624 return true;
625 if (match_content_type(pat, b->parts))
626 return true;
627 if (match_content_type(pat, b->next))
628 return true;
629 return false;
630}
static bool match_content_type(const struct Pattern *pat, struct Body *b)
Match a Pattern against an Attachment's Content-Type.
Definition: exec.c:615
#define TYPE(body)
Definition: mime.h:89
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:72
struct Body * next
next attachment in the list
Definition: body.h:71
char * subtype
content-type subtype
Definition: body.h:60
+ 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 640 of file exec.c.

641{
643 return match_content_type(pat, e->body);
644}
+ 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 652 of file exec.c.

653{
654 struct Buffer *err = buf_pool_get();
655
656 bool rc = eval_date_minmax(pat, pat->p.str, err);
657 buf_pool_release(&err);
658
659 return rc;
660}
bool eval_date_minmax(struct Pattern *pat, const char *s, struct Buffer *err)
Evaluate a date-range pattern against 'now'.
Definition: compile.c:496
+ 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 669 of file exec.c.

670{
671 *cache_entry = (value != 0) ? 2 : 1;
672}
+ 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 680 of file exec.c.

681{
682 return cache_entry == 2;
683}
+ 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 690 of file exec.c.

691{
692 return cache_entry != 0;
693}
+ 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 703 of file exec.c.

704{
705 bool match = false;
706 char *buf = NULL;
707 size_t blen = 0;
708 FILE *fp = NULL;
709
710 if ((pat->op == MUTT_PAT_HEADER) || (pat->op == MUTT_PAT_WHOLE_MSG))
711 {
712 struct Buffer *tempfile = buf_pool_get();
713 buf_mktemp(tempfile);
714 fp = mutt_file_fopen(buf_string(tempfile), "w+");
715 if (!fp)
716 {
717 mutt_perror("%s", buf_string(tempfile));
718 buf_pool_release(&tempfile);
719 return 0;
720 }
721
723 false, false, NeoMutt->sub);
724 fflush(fp);
725 if (mutt_file_seek(fp, 0, SEEK_SET))
726 {
727 while ((buf = mutt_file_read_line(buf, &blen, fp, NULL, MUTT_RL_NO_FLAGS)) != NULL)
728 {
729 if (patmatch(pat, buf) == 0)
730 {
731 match = true;
732 break;
733 }
734 }
735 }
736
737 FREE(&buf);
738 mutt_file_fclose(&fp);
739 unlink(buf_string(tempfile));
740 buf_pool_release(&tempfile);
741
742 if (match)
743 return match;
744 }
745
746 if ((pat->op == MUTT_PAT_BODY) || (pat->op == MUTT_PAT_WHOLE_MSG))
747 {
748 fp = mutt_file_fopen(e->body->filename, "r");
749 if (!fp)
750 {
751 mutt_perror("%s", e->body->filename);
752 return 0;
753 }
754
755 while ((buf = mutt_file_read_line(buf, &blen, fp, NULL, MUTT_RL_NO_FLAGS)) != NULL)
756 {
757 if (patmatch(pat, buf) == 0)
758 {
759 match = true;
760 break;
761 }
762 }
763
764 FREE(&buf);
765 mutt_file_fclose(&fp);
766 }
767
768 return match;
769}
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:763
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition: file.h:39
int mutt_rfc822_write_header(FILE *fp, struct Envelope *env, struct Body *attach, enum MuttWriteHeaderMode mode, bool privacy, bool hide_protected_subject, struct ConfigSubset *sub)
Write out one RFC822 header line.
Definition: header.c:575
@ MUTT_WRITE_HEADER_POSTPONE
A postponed Email, just the envelope info.
Definition: header.h:42
#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 778 of file exec.c.

779{
780 if ((pat->op == MUTT_PAT_MIMETYPE) || (pat->op == MUTT_PAT_MIMEATTACH))
781 {
782 return true;
783 }
784
785 if ((pat->op == MUTT_PAT_WHOLE_MSG) || (pat->op == MUTT_PAT_BODY) || (pat->op == MUTT_PAT_HEADER))
786 {
787#ifdef USE_IMAP
788 return !((m->type == MUTT_IMAP) && pat->string_match);
789#else
790 return true;
791#endif
792 }
793
794 if ((pat->op == MUTT_PAT_AND) || (pat->op == MUTT_PAT_OR))
795 {
796 struct Pattern *p = NULL;
797 SLIST_FOREACH(p, pat->child, entries)
798 {
799 if (pattern_needs_msg(m, p))
800 {
801 return true;
802 }
803 }
804 }
805
806 return false;
807}
static bool pattern_needs_msg(const struct Mailbox *m, const struct Pattern *pat)
Check whether a pattern needs a full message.
Definition: exec.c:778
+ 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 1137 of file exec.c.

1139{
1140 const bool needs_msg = pattern_needs_msg(m, pat);
1141 struct Message *msg = needs_msg ? mx_msg_open(m, e) : NULL;
1142 if (needs_msg && !msg)
1143 {
1144 return false;
1145 }
1146 const bool matched = pattern_exec(pat, flags, m, e, msg, cache);
1147 mx_msg_close(m, &msg);
1148 return matched;
1149}
int mx_msg_close(struct Mailbox *m, struct Message **ptr)
Close a message.
Definition: mx.c:1206
struct Message * mx_msg_open(struct Mailbox *m, struct Email *e)
Return a stream pointer for a message.
Definition: mx.c:1160
A local copy of an email.
Definition: message.h:34
struct Message::@0 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 1164 of file exec.c.

1166{
1167 switch (pat->op)
1168 {
1169 case MUTT_PAT_FROM: /* alias */
1170 if (!av->alias)
1171 return false;
1172 return pat->pat_not ^ (av->alias->name && patmatch(pat, av->alias->name));
1173 case MUTT_PAT_CC: /* comment */
1174 if (!av->alias)
1175 return false;
1176 return pat->pat_not ^ (av->alias->comment && patmatch(pat, av->alias->comment));
1177 case MUTT_PAT_TO: /* alias address list */
1178 if (!av->alias)
1179 return false;
1180 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
1181 1, &av->alias->addr);
1182 case MUTT_PAT_AND:
1183 return pat->pat_not ^ (perform_alias_and(pat->child, flags, av, cache) > 0);
1184 case MUTT_PAT_OR:
1185 return pat->pat_not ^ (perform_alias_or(pat->child, flags, av, cache) > 0);
1186 }
1187
1188 return false;
1189}
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:325
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:374
struct Alias * alias
Alias.
Definition: gui.h:44
char * comment
Free-form comment string.
Definition: alias.h:37
char * name
Short name.
Definition: alias.h:35
struct AddressList addr
List of Addresses the Alias expands to.
Definition: alias.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function: