NeoMutt  2024-02-01-35-geee02f
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
  • 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 823 of file exec.c.

826{
827 switch (pat->op)
828 {
829 case MUTT_PAT_AND:
830 return pat->pat_not ^ (perform_and(pat->child, flags, m, e, msg, cache) > 0);
831 case MUTT_PAT_OR:
832 return pat->pat_not ^ (perform_or(pat->child, flags, m, e, msg, cache) > 0);
833 case MUTT_PAT_THREAD:
834 return pat->pat_not ^
835 match_threadcomplete(pat->child, flags, m, e->thread, 1, 1, 1, 1);
836 case MUTT_PAT_PARENT:
837 return pat->pat_not ^ match_threadparent(pat->child, flags, m, e->thread);
839 return pat->pat_not ^ match_threadchildren(pat->child, flags, m, e->thread);
840 case MUTT_ALL:
841 return !pat->pat_not;
842 case MUTT_EXPIRED:
843 return pat->pat_not ^ e->expired;
844 case MUTT_SUPERSEDED:
845 return pat->pat_not ^ e->superseded;
846 case MUTT_FLAG:
847 return pat->pat_not ^ e->flagged;
848 case MUTT_TAG:
849 return pat->pat_not ^ e->tagged;
850 case MUTT_NEW:
851 return pat->pat_not ? e->old || e->read : !(e->old || e->read);
852 case MUTT_UNREAD:
853 return pat->pat_not ? e->read : !e->read;
854 case MUTT_REPLIED:
855 return pat->pat_not ^ e->replied;
856 case MUTT_OLD:
857 return pat->pat_not ? (!e->old || e->read) : (e->old && !e->read);
858 case MUTT_READ:
859 return pat->pat_not ^ e->read;
860 case MUTT_DELETED:
861 return pat->pat_not ^ e->deleted;
862 case MUTT_PAT_MESSAGE:
863 return pat->pat_not ^
864 ((email_msgno(e) >= pat->min) && (email_msgno(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 /* IMAP search sets e->matched at search compile time */
888 if ((m->type == MUTT_IMAP) && pat->string_match)
889 return e->matched;
890 return pat->pat_not ^ msg_search(pat, e, msg);
892 if (!m)
893 return false;
894 if (m->type == MUTT_IMAP)
895 {
896 return (pat->string_match) ? e->matched : false;
897 }
898 mutt_error(_("error: server custom search only supported with IMAP"));
899 return false;
900 case MUTT_PAT_SENDER:
901 if (!e->env)
902 return false;
903 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
904 1, &e->env->sender);
905 case MUTT_PAT_FROM:
906 if (!e->env)
907 return false;
908 return pat->pat_not ^
909 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->from);
910 case MUTT_PAT_TO:
911 if (!e->env)
912 return false;
913 return pat->pat_not ^
914 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->to);
915 case MUTT_PAT_CC:
916 if (!e->env)
917 return false;
918 return pat->pat_not ^
919 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->cc);
920 case MUTT_PAT_BCC:
921 if (!e->env)
922 return false;
923 return pat->pat_not ^
924 match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->bcc);
925 case MUTT_PAT_SUBJECT:
926 if (!e->env)
927 return false;
928 return pat->pat_not ^ (e->env->subject && patmatch(pat, e->env->subject));
929 case MUTT_PAT_ID:
931 if (!e->env)
932 return false;
933 return pat->pat_not ^ (e->env->message_id && patmatch(pat, e->env->message_id));
934 case MUTT_PAT_SCORE:
935 return pat->pat_not ^ (e->score >= pat->min &&
936 (pat->max == MUTT_MAXRANGE || e->score <= pat->max));
937 case MUTT_PAT_SIZE:
938 return pat->pat_not ^ (e->body->length >= pat->min &&
939 (pat->max == MUTT_MAXRANGE || e->body->length <= pat->max));
941 if (!e->env)
942 return false;
943 return pat->pat_not ^ (match_reference(pat, &e->env->references) ||
944 match_reference(pat, &e->env->in_reply_to));
945 case MUTT_PAT_ADDRESS:
946 if (!e->env)
947 return false;
948 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
949 5, &e->env->from, &e->env->sender,
950 &e->env->to, &e->env->cc, &e->env->bcc);
952 if (!e->env)
953 return false;
954 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 3,
955 &e->env->to, &e->env->cc, &e->env->bcc);
956 case MUTT_PAT_LIST: /* known list, subscribed or not */
957 {
958 if (!e->env)
959 return false;
960
961 bool result;
962 if (cache)
963 {
964 int *cache_entry = pat->all_addr ? &cache->list_all : &cache->list_one;
965 if (!is_pattern_cache_set(*cache_entry))
966 {
967 set_pattern_cache_value(cache_entry,
969 }
970 result = get_pattern_cache_value(*cache_entry);
971 }
972 else
973 {
974 result = mutt_is_list_recipient(pat->all_addr, e->env);
975 }
976 return pat->pat_not ^ result;
977 }
979 {
980 if (!e->env)
981 return false;
982
983 bool result;
984 if (cache)
985 {
986 int *cache_entry = pat->all_addr ? &cache->sub_all : &cache->sub_one;
987 if (!is_pattern_cache_set(*cache_entry))
988 {
989 set_pattern_cache_value(cache_entry,
991 }
992 result = get_pattern_cache_value(*cache_entry);
993 }
994 else
995 {
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->pers_recip_all : &cache->pers_recip_one;
1009 if (!is_pattern_cache_set(*cache_entry))
1010 {
1011 set_pattern_cache_value(cache_entry,
1012 match_user(pat->all_addr, 3, &e->env->to,
1013 &e->env->cc, &e->env->bcc));
1014 }
1015 result = get_pattern_cache_value(*cache_entry);
1016 }
1017 else
1018 {
1019 result = match_user(pat->all_addr, 3, &e->env->to, &e->env->cc, &e->env->bcc);
1020 }
1021 return pat->pat_not ^ result;
1022 }
1024 {
1025 if (!e->env)
1026 return false;
1027
1028 bool result;
1029 if (cache)
1030 {
1031 int *cache_entry = pat->all_addr ? &cache->pers_from_all : &cache->pers_from_one;
1032 if (!is_pattern_cache_set(*cache_entry))
1033 {
1034 set_pattern_cache_value(cache_entry,
1035 match_user(pat->all_addr, 1, &e->env->from));
1036 }
1037 result = get_pattern_cache_value(*cache_entry);
1038 }
1039 else
1040 {
1041 result = match_user(pat->all_addr, 1, &e->env->from);
1042 }
1043 return pat->pat_not ^ result;
1044 }
1045 case MUTT_PAT_COLLAPSED:
1046 return pat->pat_not ^ (e->collapsed && e->num_hidden > 1);
1048 if (!WithCrypto)
1049 {
1051 return false;
1052 }
1053 return pat->pat_not ^ ((e->security & SEC_SIGN) ? 1 : 0);
1055 if (!WithCrypto)
1056 {
1058 return false;
1059 }
1060 return pat->pat_not ^ ((e->security & SEC_GOODSIGN) ? 1 : 0);
1062 if (!WithCrypto)
1063 {
1065 return false;
1066 }
1067 return pat->pat_not ^ ((e->security & SEC_ENCRYPT) ? 1 : 0);
1068 case MUTT_PAT_PGP_KEY:
1069 if (!(WithCrypto & APPLICATION_PGP))
1070 {
1072 return false;
1073 }
1074 return pat->pat_not ^ ((e->security & PGP_KEY) == PGP_KEY);
1075 case MUTT_PAT_XLABEL:
1076 if (!e->env)
1077 return false;
1078 return pat->pat_not ^ (e->env->x_label && patmatch(pat, e->env->x_label));
1080 {
1081 struct Buffer *tags = buf_pool_get();
1083 const bool rc = (pat->pat_not ^
1084 (!buf_is_empty(tags) && patmatch(pat, buf_string(tags))));
1085 buf_pool_release(&tags);
1086 return rc;
1087 }
1088 case MUTT_PAT_HORMEL:
1089 if (!e->env)
1090 return false;
1091 return pat->pat_not ^ (e->env->spam.data && patmatch(pat, e->env->spam.data));
1093 return pat->pat_not ^ (e->thread && e->thread->duplicate_thread);
1095 if (!m)
1096 return false;
1097 {
1098 int count = mutt_count_body_parts(m, e, msg->fp);
1099 return pat->pat_not ^ (count >= pat->min &&
1100 (pat->max == MUTT_MAXRANGE || count <= pat->max));
1101 }
1102 case MUTT_PAT_MIMETYPE:
1103 if (!m)
1104 return false;
1105 return pat->pat_not ^ match_mime_content_type(pat, e, msg->fp);
1107 return pat->pat_not ^ (e->thread && !e->thread->child);
1108 case MUTT_PAT_BROKEN:
1109 return pat->pat_not ^ (e->thread && e->thread->fake_thread);
1111 if (!e->env)
1112 return false;
1113 return pat->pat_not ^ (e->env->newsgroups && patmatch(pat, e->env->newsgroups));
1114 }
1115 mutt_error(_("error: unknown op %d (report this error)"), pat->op);
1116 return false;
1117}
int mutt_count_body_parts(const struct Mailbox *m, struct Email *e, FILE *fp)
Count the MIME Body parts.
Definition: attachments.c:252
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:308
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:97
@ 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:114
static int match_user(bool all_addr, int n,...)
Matches the user's email Address.
Definition: exec.c:506
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:541
static void print_crypt_pattern_op_error(int op)
Print an error for a disabled crypto pattern.
Definition: exec.c:88
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:579
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:643
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:598
static bool match_reference(struct Pattern *pat, struct ListHead *refs)
Match references against a Pattern.
Definition: exec.c:433
static int match_addrlist(struct Pattern *pat, bool match_personal, int n,...)
Match a Pattern against an Address list.
Definition: exec.c:402
static bool patmatch(const struct Pattern *pat, const char *buf)
Compare a string to a Pattern.
Definition: exec.c:73
static int is_pattern_cache_set(int cache_entry)
Is a given Pattern cached?
Definition: exec.c:693
bool mutt_is_subscribed_list_recipient(bool all_addr, struct Envelope *env)
Matches subscribed mailing lists.
Definition: exec.c:479
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
bool mutt_is_list_recipient(bool all_addr, struct Envelope *env)
Matches known mailing lists.
Definition: exec.c:492
static bool match_update_dynamic_date(struct Pattern *pat)
Update a dynamic date pattern.
Definition: exec.c:655
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:683
static void set_pattern_cache_value(int *cache_entry, int value)
Sets a value in the PatternCache cache entry.
Definition: exec.c:672
static int msg_search_sendmode(struct Email *e, struct Pattern *pat)
Search in send-mode.
Definition: exec.c:706
#define mutt_error(...)
Definition: logging2.h:92
#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:80
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:90
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:78
#define PGP_KEY
Definition: lib.h:99
#define WithCrypto
Definition: lib.h:116
#define SEC_SIGN
Email is signed.
Definition: lib.h:79
@ 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:140
static int email_msgno(struct Email *e)
Helper to get the Email's message number.
Definition: private.h:135
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 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
String manipulation buffer.
Definition: buffer.h:36
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:105
struct Envelope * env
Envelope information.
Definition: email.h:68
bool collapsed
Is this message part of a collapsed thread?
Definition: email.h:123
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:126
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:116
bool deleted
Email is deleted.
Definition: email.h:78
bool tagged
Email is tagged.
Definition: email.h:110
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:122
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 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
void driver_tags_get_with_hidden(struct TagList *tl, struct Buffer *tags)
Get all tags, also hidden ones, separated by space.
Definition: tags.c:174
+ 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 73 of file exec.c.

74{
75 if (pat->is_multi)
76 return (mutt_list_find(&pat->p.multi_cases, buf) != NULL);
77 if (pat->string_match)
78 return pat->ign_case ? mutt_istr_find(buf, pat->p.str) : strstr(buf, pat->p.str);
79 if (pat->group_match)
80 return mutt_group_match(pat->p.group, buf);
81 return (regexec(pat->p.regex, buf, 0, NULL, 0) == 0);
82}
bool mutt_group_match(struct Group *g, const char *s)
Does a string match an entry in a Group?
Definition: group.c:371
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:570
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 88 of file exec.c.

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

115{
116 assert(msg);
117
118 bool match = false;
119
120 FILE *fp = NULL;
121 long len = 0;
122#ifdef USE_FMEMOPEN
123 char *temp = NULL;
124 size_t tempsize = 0;
125#else
126 struct stat st = { 0 };
127#endif
128
129 const bool needs_head = (pat->op == MUTT_PAT_HEADER) || (pat->op == MUTT_PAT_WHOLE_MSG);
130 const bool needs_body = (pat->op == MUTT_PAT_BODY) || (pat->op == MUTT_PAT_WHOLE_MSG);
131 const bool c_thorough_search = cs_subset_bool(NeoMutt->sub, "thorough_search");
132 if (c_thorough_search)
133 {
134 /* decode the header / body */
135 struct State state = { 0 };
136 state.fp_in = msg->fp;
137 state.flags = STATE_CHARCONV;
138#ifdef USE_FMEMOPEN
139 state.fp_out = open_memstream(&temp, &tempsize);
140 if (!state.fp_out)
141 {
142 mutt_perror(_("Error opening 'memory stream'"));
143 return false;
144 }
145#else
146 state.fp_out = mutt_file_mkstemp();
147 if (!state.fp_out)
148 {
149 mutt_perror(_("Can't create temporary file"));
150 return false;
151 }
152#endif
153
154 if (needs_head)
155 {
156 mutt_copy_header(msg->fp, e, state.fp_out, CH_FROM | CH_DECODE, NULL, 0);
157 }
158
159 if (needs_body)
160 {
162
163 if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT) &&
165 {
166 if (state.fp_out)
167 {
168 mutt_file_fclose(&state.fp_out);
169#ifdef USE_FMEMOPEN
170 FREE(&temp);
171#endif
172 }
173 return false;
174 }
175
176 if (!mutt_file_seek(msg->fp, e->offset, SEEK_SET))
177 {
178#ifdef USE_FMEMOPEN
179 FREE(&temp);
180#endif
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: attachments.c:597
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:508
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:425
#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:1081
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition: file.c:771
#define mutt_file_fclose(FP)
Definition: file.h:148
#define mutt_file_fopen(PATH, MODE)
Definition: file.h:147
#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:1631
#define FREE(x)
Definition: memory.h:45
#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:545
LOFF_T offset
offset where the actual data begins
Definition: body.h:52
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:71
Container for Accounts, Notifications.
Definition: neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45
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:823
#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 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:1160
+ 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_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 402 of file exec.c.

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

434{
435 struct ListNode *np = NULL;
436 STAILQ_FOREACH(np, refs, entries)
437 {
438 if (patmatch(pat, np->data))
439 return true;
440 }
441 return false;
442}
#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 455 of file exec.c.

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

480{
482}
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:455
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:57
+ 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 492 of file exec.c.

493{
494 return mutt_is_predicate_recipient(all_addr, env, &mutt_is_mail_list);
495}
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:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ match_user()

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

Matches the user's email Address.

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

Definition at line 506 of file exec.c.

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

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

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

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

619{
620 if (!b)
621 return false;
622
623 char buf[256] = { 0 };
624 snprintf(buf, sizeof(buf), "%s/%s", TYPE(b), b->subtype);
625
626 if (patmatch(pat, buf))
627 return true;
628 if (match_content_type(pat, b->parts))
629 return true;
630 if (match_content_type(pat, b->next))
631 return true;
632 return false;
633}
static bool match_content_type(const struct Pattern *pat, struct Body *b)
Match a Pattern against an Attachment's Content-Type.
Definition: exec.c:618
#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 643 of file exec.c.

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

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

673{
674 *cache_entry = (value != 0) ? 2 : 1;
675}
+ 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 683 of file exec.c.

684{
685 return cache_entry == 2;
686}
+ 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 693 of file exec.c.

694{
695 return cache_entry != 0;
696}
+ 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 706 of file exec.c.

707{
708 bool match = false;
709 char *buf = NULL;
710 size_t blen = 0;
711 FILE *fp = NULL;
712
713 if ((pat->op == MUTT_PAT_HEADER) || (pat->op == MUTT_PAT_WHOLE_MSG))
714 {
715 struct Buffer *tempfile = buf_pool_get();
716 buf_mktemp(tempfile);
717 fp = mutt_file_fopen(buf_string(tempfile), "w+");
718 if (!fp)
719 {
720 mutt_perror("%s", buf_string(tempfile));
721 buf_pool_release(&tempfile);
722 return 0;
723 }
724
726 false, false, NeoMutt->sub);
727 fflush(fp);
728 if (mutt_file_seek(fp, 0, SEEK_SET))
729 {
730 while ((buf = mutt_file_read_line(buf, &blen, fp, NULL, MUTT_RL_NO_FLAGS)) != NULL)
731 {
732 if (patmatch(pat, buf) == 0)
733 {
734 match = true;
735 break;
736 }
737 }
738 }
739
740 FREE(&buf);
741 mutt_file_fclose(&fp);
742 unlink(buf_string(tempfile));
743 buf_pool_release(&tempfile);
744
745 if (match)
746 return match;
747 }
748
749 if ((pat->op == MUTT_PAT_BODY) || (pat->op == MUTT_PAT_WHOLE_MSG))
750 {
751 fp = mutt_file_fopen(e->body->filename, "r");
752 if (!fp)
753 {
754 mutt_perror("%s", e->body->filename);
755 return 0;
756 }
757
758 while ((buf = mutt_file_read_line(buf, &blen, fp, NULL, MUTT_RL_NO_FLAGS)) != NULL)
759 {
760 if (patmatch(pat, buf) == 0)
761 {
762 match = true;
763 break;
764 }
765 }
766
767 FREE(&buf);
768 mutt_file_fclose(&fp);
769 }
770
771 return match;
772}
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:801
#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
#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 781 of file exec.c.

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

1135{
1136 const bool needs_msg = pattern_needs_msg(m, pat);
1137 struct Message *msg = needs_msg ? mx_msg_open(m, e) : NULL;
1138 if (needs_msg && !msg)
1139 {
1140 return false;
1141 }
1142 const bool matched = pattern_exec(pat, flags, m, e, msg, cache);
1143 mx_msg_close(m, &msg);
1144 return matched;
1145}
int mx_msg_close(struct Mailbox *m, struct Message **ptr)
Close a message.
Definition: mx.c:1178
struct Message * mx_msg_open(struct Mailbox *m, struct Email *e)
Return a stream pointer for a message.
Definition: mx.c:1132
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 1160 of file exec.c.

1162{
1163 switch (pat->op)
1164 {
1165 case MUTT_PAT_FROM: /* alias */
1166 if (!av->alias)
1167 return false;
1168 return pat->pat_not ^ (av->alias->name && patmatch(pat, av->alias->name));
1169 case MUTT_PAT_CC: /* comment */
1170 if (!av->alias)
1171 return false;
1172 return pat->pat_not ^ (av->alias->comment && patmatch(pat, av->alias->comment));
1173 case MUTT_PAT_TO: /* alias address list */
1174 if (!av->alias)
1175 return false;
1176 return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
1177 1, &av->alias->addr);
1179 {
1180 if (!av->alias)
1181 return false;
1182
1183 struct Buffer *tags = buf_pool_get();
1184 alias_tags_to_buffer(&av->alias->tags, tags);
1185
1186 bool rc = false;
1187 if (!buf_is_empty(tags))
1188 {
1189 rc = (pat->pat_not ^ (patmatch(pat, buf_string(tags))));
1190 }
1191
1192 buf_pool_release(&tags);
1193 return rc;
1194 }
1195
1196 case MUTT_PAT_AND:
1197 return pat->pat_not ^ (perform_alias_and(pat->child, flags, av, cache) > 0);
1198 case MUTT_PAT_OR:
1199 return pat->pat_not ^ (perform_alias_or(pat->child, flags, av, cache) > 0);
1200 }
1201
1202 return false;
1203}
void alias_tags_to_buffer(struct TagList *tl, struct Buffer *buf)
Write a comma-separated list of tags to a Buffer.
Definition: commands.c:49
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: