NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
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 "ncrypt/lib.h"
#include "send/lib.h"
#include "attachments.h"
#include "copy.h"
#include "handler.h"
#include "maillist.h"
#include "muttlib.h"
#include "mx.h"
#include <sys/stat.h>
+ Include dependency graph for exec.c:

Go to the source code of this file.

Functions

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

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 int 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
1Success, pattern matched
0Pattern did not match
-1Error

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

795 {
796  switch (pat->op)
797  {
798  case MUTT_PAT_AND:
799  return pat->pat_not ^ (perform_and(pat->child, flags, m, e, msg, cache) > 0);
800  case MUTT_PAT_OR:
801  return pat->pat_not ^ (perform_or(pat->child, flags, m, e, msg, cache) > 0);
802  case MUTT_PAT_THREAD:
803  return pat->pat_not ^
804  match_threadcomplete(pat->child, flags, m, e->thread, 1, 1, 1, 1);
805  case MUTT_PAT_PARENT:
806  return pat->pat_not ^ match_threadparent(pat->child, flags, m, e->thread);
807  case MUTT_PAT_CHILDREN:
808  return pat->pat_not ^ match_threadchildren(pat->child, flags, m, e->thread);
809  case MUTT_ALL:
810  return !pat->pat_not;
811  case MUTT_EXPIRED:
812  return pat->pat_not ^ e->expired;
813  case MUTT_SUPERSEDED:
814  return pat->pat_not ^ e->superseded;
815  case MUTT_FLAG:
816  return pat->pat_not ^ e->flagged;
817  case MUTT_TAG:
818  return pat->pat_not ^ e->tagged;
819  case MUTT_NEW:
820  return pat->pat_not ? e->old || e->read : !(e->old || e->read);
821  case MUTT_UNREAD:
822  return pat->pat_not ? e->read : !e->read;
823  case MUTT_REPLIED:
824  return pat->pat_not ^ e->replied;
825  case MUTT_OLD:
826  return pat->pat_not ? (!e->old || e->read) : (e->old && !e->read);
827  case MUTT_READ:
828  return pat->pat_not ^ e->read;
829  case MUTT_DELETED:
830  return pat->pat_not ^ e->deleted;
831  case MUTT_PAT_MESSAGE:
832  return pat->pat_not ^ ((EMSG(e) >= pat->min) && (EMSG(e) <= pat->max));
833  case MUTT_PAT_DATE:
834  if (pat->dynamic)
836  return pat->pat_not ^ (e->date_sent >= pat->min && e->date_sent <= pat->max);
838  if (pat->dynamic)
840  return pat->pat_not ^ (e->received >= pat->min && e->received <= pat->max);
841  case MUTT_PAT_BODY:
842  case MUTT_PAT_HEADER:
843  case MUTT_PAT_WHOLE_MSG:
844  if (pat->sendmode)
845  {
846  if (!e->body || !e->body->filename)
847  return 0;
848  return pat->pat_not ^ msg_search_sendmode(e, pat);
849  }
850  /* m can be NULL in certain cases, such as when replying to a message
851  * from the attachment menu and the user has a reply-hook using "~e".
852  * This is also the case when message scoring. */
853  if (!m)
854  return 0;
855 #ifdef USE_IMAP
856  /* IMAP search sets e->matched at search compile time */
857  if ((m->type == MUTT_IMAP) && pat->string_match)
858  return e->matched;
859 #endif
860  return pat->pat_not ^ msg_search(pat, m, e, msg);
862 #ifdef USE_IMAP
863  if (!m)
864  return 0;
865  if (m->type == MUTT_IMAP)
866  {
867  if (pat->string_match)
868  return e->matched;
869  return 0;
870  }
871  mutt_error(_("error: server custom search only supported with IMAP"));
872  return 0;
873 #else
874  mutt_error(_("error: server custom search only supported with IMAP"));
875  return -1;
876 #endif
877  case MUTT_PAT_SENDER:
878  if (!e->env)
879  return 0;
880  return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
881  1, &e->env->sender);
882  case MUTT_PAT_FROM:
883  if (!e->env)
884  return 0;
885  return pat->pat_not ^
886  match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->from);
887  case MUTT_PAT_TO:
888  if (!e->env)
889  return 0;
890  return pat->pat_not ^
891  match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->to);
892  case MUTT_PAT_CC:
893  if (!e->env)
894  return 0;
895  return pat->pat_not ^
896  match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->cc);
897  case MUTT_PAT_SUBJECT:
898  if (!e->env)
899  return 0;
900  return pat->pat_not ^ (e->env->subject && patmatch(pat, e->env->subject));
901  case MUTT_PAT_ID:
903  if (!e->env)
904  return 0;
905  return pat->pat_not ^ (e->env->message_id && patmatch(pat, e->env->message_id));
906  case MUTT_PAT_SCORE:
907  return pat->pat_not ^ (e->score >= pat->min &&
908  (pat->max == MUTT_MAXRANGE || e->score <= pat->max));
909  case MUTT_PAT_SIZE:
910  return pat->pat_not ^ (e->body->length >= pat->min &&
911  (pat->max == MUTT_MAXRANGE || e->body->length <= pat->max));
912  case MUTT_PAT_REFERENCE:
913  if (!e->env)
914  return 0;
915  return pat->pat_not ^ (match_reference(pat, &e->env->references) ||
916  match_reference(pat, &e->env->in_reply_to));
917  case MUTT_PAT_ADDRESS:
918  if (!e->env)
919  return 0;
920  return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
921  4, &e->env->from, &e->env->sender,
922  &e->env->to, &e->env->cc);
923  case MUTT_PAT_RECIPIENT:
924  if (!e->env)
925  return 0;
926  return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
927  2, &e->env->to, &e->env->cc);
928  case MUTT_PAT_LIST: /* known list, subscribed or not */
929  {
930  if (!e->env)
931  return 0;
932 
933  int result;
934  if (cache)
935  {
936  int *cache_entry = pat->all_addr ? &cache->list_all : &cache->list_one;
937  if (!is_pattern_cache_set(*cache_entry))
938  {
939  set_pattern_cache_value(cache_entry,
941  }
942  result = get_pattern_cache_value(*cache_entry);
943  }
944  else
945  result = mutt_is_list_recipient(pat->all_addr, e->env);
946  return pat->pat_not ^ result;
947  }
949  {
950  if (!e->env)
951  return 0;
952 
953  int result;
954  if (cache)
955  {
956  int *cache_entry = pat->all_addr ? &cache->sub_all : &cache->sub_one;
957  if (!is_pattern_cache_set(*cache_entry))
958  {
960  cache_entry, mutt_is_subscribed_list_recipient(pat->all_addr, e->env));
961  }
962  result = get_pattern_cache_value(*cache_entry);
963  }
964  else
966  return pat->pat_not ^ result;
967  }
969  {
970  if (!e->env)
971  return 0;
972 
973  int result;
974  if (cache)
975  {
976  int *cache_entry = pat->all_addr ? &cache->pers_recip_all : &cache->pers_recip_one;
977  if (!is_pattern_cache_set(*cache_entry))
978  {
980  cache_entry, match_user(pat->all_addr, &e->env->to, &e->env->cc));
981  }
982  result = get_pattern_cache_value(*cache_entry);
983  }
984  else
985  result = match_user(pat->all_addr, &e->env->to, &e->env->cc);
986  return pat->pat_not ^ result;
987  }
989  {
990  if (!e->env)
991  return 0;
992 
993  int result;
994  if (cache)
995  {
996  int *cache_entry = pat->all_addr ? &cache->pers_from_all : &cache->pers_from_one;
997  if (!is_pattern_cache_set(*cache_entry))
998  {
999  set_pattern_cache_value(cache_entry,
1000  match_user(pat->all_addr, &e->env->from, NULL));
1001  }
1002  result = get_pattern_cache_value(*cache_entry);
1003  }
1004  else
1005  result = match_user(pat->all_addr, &e->env->from, NULL);
1006  return pat->pat_not ^ result;
1007  }
1008  case MUTT_PAT_COLLAPSED:
1009  return pat->pat_not ^ (e->collapsed && e->num_hidden > 1);
1010  case MUTT_PAT_CRYPT_SIGN:
1011  if (!WithCrypto)
1012  {
1014  return 0;
1015  }
1016  return pat->pat_not ^ ((e->security & SEC_SIGN) ? 1 : 0);
1018  if (!WithCrypto)
1019  {
1021  return 0;
1022  }
1023  return pat->pat_not ^ ((e->security & SEC_GOODSIGN) ? 1 : 0);
1025  if (!WithCrypto)
1026  {
1028  return 0;
1029  }
1030  return pat->pat_not ^ ((e->security & SEC_ENCRYPT) ? 1 : 0);
1031  case MUTT_PAT_PGP_KEY:
1032  if (!(WithCrypto & APPLICATION_PGP))
1033  {
1035  return 0;
1036  }
1037  return pat->pat_not ^ ((e->security & PGP_KEY) == PGP_KEY);
1038  case MUTT_PAT_XLABEL:
1039  if (!e->env)
1040  return 0;
1041  return pat->pat_not ^ (e->env->x_label && patmatch(pat, e->env->x_label));
1042  case MUTT_PAT_DRIVER_TAGS:
1043  {
1044  char *tags = driver_tags_get(&e->tags);
1045  bool rc = (pat->pat_not ^ (tags && patmatch(pat, tags)));
1046  FREE(&tags);
1047  return rc;
1048  }
1049  case MUTT_PAT_HORMEL:
1050  if (!e->env)
1051  return 0;
1052  return pat->pat_not ^ (e->env->spam.data && patmatch(pat, e->env->spam.data));
1053  case MUTT_PAT_DUPLICATED:
1054  return pat->pat_not ^ (e->thread && e->thread->duplicate_thread);
1055  case MUTT_PAT_MIMEATTACH:
1056  if (!m)
1057  return 0;
1058  {
1059  int count = mutt_count_body_parts(m, e, msg->fp);
1060  return pat->pat_not ^ (count >= pat->min &&
1061  (pat->max == MUTT_MAXRANGE || count <= pat->max));
1062  }
1063  case MUTT_PAT_MIMETYPE:
1064  if (!m)
1065  return 0;
1066  return pat->pat_not ^ match_mime_content_type(pat, m, e, msg->fp);
1067  case MUTT_PAT_UNREFERENCED:
1068  return pat->pat_not ^ (e->thread && !e->thread->child);
1069  case MUTT_PAT_BROKEN:
1070  return pat->pat_not ^ (e->thread && e->thread->fake_thread);
1071 #ifdef USE_NNTP
1072  case MUTT_PAT_NEWSGROUPS:
1073  if (!e->env)
1074  return 0;
1075  return pat->pat_not ^ (e->env->newsgroups && patmatch(pat, e->env->newsgroups));
1076 #endif
1077  }
1078  mutt_error(_("error: unknown op %d (report this error)"), pat->op);
1079  return 0;
1080 }
Pattern matches message number.
Definition: lib.h:148
struct PatternList * child
Arguments to logical operation.
Definition: lib.h:82
Deleted messages.
Definition: mutt.h:97
static int match_threadparent(struct PatternList *pat, PatternExecFlags flags, struct Mailbox *m, struct MuttThread *t)
Match Pattern against an email&#39;s parent.
Definition: exec.c:542
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
Pattern matches email&#39;s Message-Id.
Definition: lib.h:141
#define WithCrypto
Definition: lib.h:113
Pattern matches email&#39;s body.
Definition: lib.h:143
static int get_pattern_cache_value(int cache_entry)
Get pattern cache value.
Definition: exec.c:648
static bool match_mime_content_type(const struct Pattern *pat, struct Mailbox *m, struct Email *e, FILE *fp)
Match a Pattern against an email&#39;s Content-Type.
Definition: exec.c:607
Message is signed.
Definition: lib.h:158
struct Body * body
List of MIME parts.
Definition: email.h:91
static int msg_search_sendmode(struct Email *e, struct Pattern *pat)
Search in send-mode.
Definition: exec.c:671
#define mutt_error(...)
Definition: logging.h:88
static int match_user(int all_addr, struct AddressList *al1, struct AddressList *al2)
Matches the user&#39;s email Address.
Definition: exec.c:468
int pers_recip_all
^~p
Definition: lib.h:111
struct MuttThread * thread
Thread of Emails.
Definition: email.h:95
Email is on mailing list.
Definition: lib.h:153
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:75
Pattern matches &#39;To:&#39; field.
Definition: lib.h:131
static void set_pattern_cache_value(int *cache_entry, int value)
Sets a value in the PatternCache cache entry.
Definition: exec.c:637
Flagged messages.
Definition: mutt.h:98
#define EMSG(e)
Definition: private.h:117
Pattern matches date received.
Definition: lib.h:137
#define _(a)
Definition: message.h:28
Pattern matches &#39;References:&#39; or &#39;In-Reply-To:&#39; field.
Definition: lib.h:151
bool expired
Already expired?
Definition: email.h:52
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:504
int mutt_is_subscribed_list_recipient(bool all_addr, struct Envelope *e)
Matches subscribed mailing lists.
Definition: exec.c:441
Message is unreferenced in the thread.
Definition: lib.h:139
static int match_addrlist(struct Pattern *pat, bool match_personal, int n,...)
Match a Pattern against an Address list.
Definition: exec.c:365
Messages that have been replied to.
Definition: mutt.h:91
int sub_all
^~u
Definition: lib.h:109
Pattern matches &#39;From:&#39; field.
Definition: lib.h:135
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:320
Pattern matches email&#39;s header.
Definition: lib.h:144
int mutt_count_body_parts(struct Mailbox *m, struct Email *e, FILE *fp)
Count the MIME Body parts.
Definition: attachments.c:253
Server-side pattern matches.
Definition: lib.h:163
Message is encrypted.
Definition: lib.h:160
static bool match_update_dynamic_date(struct Pattern *pat)
Update a dynamic date pattern.
Definition: exec.c:620
All messages.
Definition: mutt.h:87
bool tagged
Email is tagged.
Definition: email.h:44
bool read
Email is read.
Definition: email.h:51
bool dynamic
Evaluate date ranges at run time.
Definition: lib.h:77
Message is crypographically verified.
Definition: lib.h:159
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:82
char * message_id
Message ID.
Definition: envelope.h:69
bool all_addr
All Addresses in the list must match.
Definition: lib.h:72
bool old
Email is seen, but unread.
Definition: email.h:50
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
static int match_threadchildren(struct PatternList *pat, PatternExecFlags flags, struct Mailbox *m, struct MuttThread *t)
Match Pattern against an email&#39;s children.
Definition: exec.c:561
Pattern matches sender.
Definition: lib.h:147
static bool patmatch(const struct Pattern *pat, const char *buf)
Compare a string to a Pattern.
Definition: exec.c:71
Pattern matches keyword/label.
Definition: lib.h:162
Email is addressed to the user.
Definition: lib.h:155
struct Envelope * env
Envelope information.
Definition: email.h:90
Email is from the user.
Definition: lib.h:156
Pattern matches newsgroup.
Definition: lib.h:168
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
bool string_match
Check a string for a match.
Definition: lib.h:73
bool pat_not
Pattern should be inverted (not)
Definition: lib.h:71
bool superseded
Got superseded?
Definition: email.h:53
int min
Minimum for range checks.
Definition: lib.h:80
Pattern matches any address field.
Definition: lib.h:157
struct TagList tags
For drivers that support server tagging.
Definition: email.h:109
Message is part of a broken thread.
Definition: lib.h:140
Email is on subscribed mailing list.
Definition: lib.h:154
int score
Message score.
Definition: email.h:89
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:82
Old messages.
Definition: mutt.h:90
int pers_from_one
~P
Definition: lib.h:114
struct MuttThread * child
Child of this Thread.
Definition: thread.h:46
bool duplicate_thread
Duplicated Email in Thread.
Definition: thread.h:37
int pers_recip_one
~p
Definition: lib.h:112
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:87
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
Pattern matches MIME type.
Definition: lib.h:166
bool fake_thread
Emails grouped by Subject.
Definition: thread.h:36
int mutt_is_list_recipient(bool all_addr, struct Envelope *e)
Matches known mailing lists.
Definition: exec.c:454
Message-Id is among results from an external query.
Definition: lib.h:142
char * driver_tags_get(struct TagList *list)
Get tags.
Definition: tags.c:145
size_t num_hidden
Number of hidden messages in this view (only valid when collapsed is set)
Definition: email.h:75
Superseded messages.
Definition: mutt.h:103
Tagged messages.
Definition: mutt.h:99
char * data
Pointer to data.
Definition: buffer.h:35
int list_all
^~l
Definition: lib.h:107
New messages.
Definition: mutt.h:89
Messages that have been read.
Definition: mutt.h:92
Pattern matches number of attachments.
Definition: lib.h:165
static int is_pattern_cache_set(int cache_entry)
Is a given Pattern cached?
Definition: exec.c:658
bool collapsed
Is this message part of a collapsed thread?
Definition: email.h:73
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition: lib.h:70
#define MUTT_MAXRANGE
Definition: private.h:119
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
Expired messages.
Definition: mutt.h:102
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:275
int pers_from_all
^~P
Definition: lib.h:113
#define SEC_SIGN
Email is signed.
Definition: lib.h:76
Unread messages.
Definition: mutt.h:93
Pattern matches &#39;Date:&#39; field.
Definition: lib.h:136
static bool msg_search(struct Pattern *pat, struct Mailbox *m, struct Email *e, struct Message *msg)
Search an email.
Definition: exec.c:113
Thread is collapsed.
Definition: lib.h:133
char * subject
Email&#39;s subject.
Definition: envelope.h:66
Pattern matches &#39;Cc:&#39; field.
Definition: lib.h:132
Duplicate message.
Definition: lib.h:138
Both patterns must match.
Definition: lib.h:126
#define PGP_KEY
Definition: lib.h:96
bool flagged
Marked important?
Definition: email.h:43
char * newsgroups
List of newsgroups.
Definition: envelope.h:75
bool deleted
Email is deleted.
Definition: email.h:45
Either pattern can match.
Definition: lib.h:127
bool sendmode
Evaluate searches in send-mode.
Definition: lib.h:78
bool replied
Email has been replied to.
Definition: email.h:54
static void print_crypt_pattern_op_error(int op)
Print an error for a disabled crypto pattern.
Definition: exec.c:86
Pattern matches parent.
Definition: lib.h:129
FILE * fp
pointer to the message data
Definition: mxapi.h:43
Pattern matches email&#39;s spam score.
Definition: lib.h:145
User is a recipient of the email.
Definition: lib.h:152
static bool match_reference(struct Pattern *pat, struct ListHead *refs)
Match references against a Pattern.
Definition: exec.c:395
#define FREE(x)
Definition: memory.h:40
int max
Maximum for range checks.
Definition: lib.h:81
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
struct AddressList sender
Email&#39;s sender.
Definition: envelope.h:61
Pattern matches raw email text.
Definition: lib.h:146
Pattern matches a child email.
Definition: lib.h:130
Pattern matches message tags.
Definition: lib.h:164
Pattern matches email thread.
Definition: lib.h:128
struct ListHead references
message references (in reverse order)
Definition: envelope.h:81
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
char * x_label
X-Label.
Definition: envelope.h:72
#define SEC_GOODSIGN
Email has a valid signature.
Definition: lib.h:77
int list_one
~l
Definition: lib.h:108
#define MUTT_MATCH_FULL_ADDRESS
Match the full address.
Definition: lib.h:95
Message has PGP key.
Definition: lib.h:161
time_t received
Time when the message was placed in the mailbox.
Definition: email.h:83
Pattern matches email&#39;s score.
Definition: lib.h:149
Pattern matches email&#39;s size.
Definition: lib.h:150
struct Buffer spam
Spam header.
Definition: envelope.h:80
bool matched
Search matches this Email.
Definition: email.h:68
int sub_one
~u
Definition: lib.h:110
Pattern matches &#39;Subject:&#39; field.
Definition: lib.h:134
+ 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 71 of file exec.c.

72 {
73  if (pat->is_multi)
74  return (mutt_list_find(&pat->p.multi_cases, buf) != NULL);
75  if (pat->string_match)
76  return pat->ign_case ? strcasestr(buf, pat->p.str) : strstr(buf, pat->p.str);
77  if (pat->group_match)
78  return mutt_group_match(pat->p.group, buf);
79  return (regexec(pat->p.regex, buf, 0, NULL, 0) == 0);
80 }
regex_t * regex
Compiled regex, for non-pattern matching.
Definition: lib.h:84
bool group_match
Check a group of Addresses.
Definition: lib.h:74
union Pattern::@3 p
bool is_multi
Multiple case (only for ~I pattern now)
Definition: lib.h:79
bool mutt_group_match(struct Group *g, const char *s)
Does a string match an entry in a Group?
Definition: group.c:325
struct ListNode * mutt_list_find(const struct ListHead *h, const char *data)
Find a string in a List.
Definition: list.c:102
bool string_match
Check a string for a match.
Definition: lib.h:73
bool ign_case
Ignore case for local string_match searches.
Definition: lib.h:75
char * str
String, if string_match is set.
Definition: lib.h:86
struct Group * group
Address group if group_match is set.
Definition: lib.h:85
struct ListHead multi_cases
Multiple strings for ~I pattern.
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 86 of file exec.c.

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

Search an email.

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

Definition at line 113 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;
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 =
132  cs_subset_bool(NeoMutt->sub, "thorough_search");
133  if (c_thorough_search)
134  {
135  /* decode the header / body */
136  struct State s = { 0 };
137  s.fp_in = msg->fp;
138  s.flags = MUTT_CHARCONV;
139 #ifdef USE_FMEMOPEN
140  s.fp_out = open_memstream(&temp, &tempsize);
141  if (!s.fp_out)
142  {
143  mutt_perror(_("Error opening 'memory stream'"));
144  return false;
145  }
146 #else
148  if (!s.fp_out)
149  {
150  mutt_perror(_("Can't create temporary file"));
151  return false;
152  }
153 #endif
154 
155  if (needs_head)
156  {
157  mutt_copy_header(msg->fp, e, s.fp_out, CH_FROM | CH_DECODE, NULL, 0);
158  }
159 
160  if (needs_body)
161  {
162  mutt_parse_mime_message(m, e, msg->fp);
163 
164  if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT) &&
166  {
167  if (s.fp_out)
168  {
170 #ifdef USE_FMEMOPEN
171  FREE(&temp);
172 #endif
173  }
174  return false;
175  }
176 
177  fseeko(msg->fp, e->offset, SEEK_SET);
178  mutt_body_handler(e->body, &s);
179  }
180 
181 #ifdef USE_FMEMOPEN
183  len = tempsize;
184 
185  if (tempsize != 0)
186  {
187  fp = fmemopen(temp, tempsize, "r");
188  if (!fp)
189  {
190  mutt_perror(_("Error re-opening 'memory stream'"));
191  FREE(&temp);
192  return false;
193  }
194  }
195  else
196  { /* fmemopen can't handle empty buffers */
197  fp = mutt_file_fopen("/dev/null", "r");
198  if (!fp)
199  {
200  mutt_perror(_("Error opening /dev/null"));
201  return false;
202  }
203  }
204 #else
205  fp = s.fp_out;
206  fflush(fp);
207  fseek(fp, 0, SEEK_SET);
208  fstat(fileno(fp), &st);
209  len = (long) st.st_size;
210 #endif
211  }
212  else
213  {
214  /* raw header / body */
215  fp = msg->fp;
216  if (needs_head)
217  {
218  fseeko(fp, e->offset, SEEK_SET);
219  len = e->body->offset - e->offset;
220  }
221  if (needs_body)
222  {
223  if (pat->op == MUTT_PAT_BODY)
224  {
225  fseeko(fp, e->body->offset, SEEK_SET);
226  }
227  len += e->body->length;
228  }
229  }
230 
231  size_t blen = 256;
232  char *buf = mutt_mem_malloc(blen);
233 
234  /* search the file "fp" */
235  while (len > 0)
236  {
237  if (pat->op == MUTT_PAT_HEADER)
238  {
239  buf = mutt_rfc822_read_line(fp, buf, &blen);
240  if (*buf == '\0')
241  break;
242  }
243  else if (!fgets(buf, blen - 1, fp))
244  break; /* don't loop forever */
245  if (patmatch(pat, buf))
246  {
247  match = true;
248  break;
249  }
250  len -= mutt_str_len(buf);
251  }
252 
253  FREE(&buf);
254 
255  if (c_thorough_search)
256  mutt_file_fclose(&fp);
257 
258 #ifdef USE_FMEMOPEN
259  FREE(&temp);
260 #endif
261 
262  return match;
263 }
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:591
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
#define WithCrypto
Definition: lib.h:113
Pattern matches email&#39;s body.
Definition: lib.h:143
struct Body * body
List of MIME parts.
Definition: email.h:91
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:75
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define CH_FROM
Retain the "From " message separator?
Definition: copy.h:56
#define _(a)
Definition: message.h:28
FILE * fp_out
File to write to.
Definition: state.h:47
#define mutt_perror(...)
Definition: logging.h:89
Container for Accounts, Notifications.
Definition: neomutt.h:36
FILE * fp_in
File to read from.
Definition: state.h:46
Pattern matches email&#39;s header.
Definition: lib.h:144
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:135
static bool patmatch(const struct Pattern *pat, const char *buf)
Compare a string to a Pattern.
Definition: exec.c:71
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:54
#define mutt_file_mkstemp()
Definition: file.h:108
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition: lib.h:70
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:84
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
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:413
FILE * fp
pointer to the message data
Definition: mxapi.h:43
#define FREE(x)
Definition: memory.h:40
Keep track when processing files.
Definition: state.h:44
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1604
Pattern matches raw email text.
Definition: lib.h:146
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:589
char * mutt_rfc822_read_line(FILE *fp, char *line, size_t *linelen)
Read a header line from a file.
Definition: parse.c:1049
+ 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 275 of file exec.c.

278 {
279  struct Pattern *p = NULL;
280 
281  SLIST_FOREACH(p, pat, entries)
282  {
283  if (pattern_exec(p, flags, m, e, msg, cache) <= 0)
284  return false;
285  }
286  return true;
287 }
union Pattern::@3 p
A simple (non-regex) pattern.
Definition: lib.h:68
static int 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:792
#define SLIST_FOREACH(var, head, field)
Definition: queue.h:231
+ 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 297 of file exec.c.

299 {
300  struct Pattern *p = NULL;
301 
302  SLIST_FOREACH(p, pat, entries)
303  {
304  if (mutt_pattern_alias_exec(p, flags, av, cache) <= 0)
305  return false;
306  }
307  return true;
308 }
union Pattern::@3 p
A simple (non-regex) pattern.
Definition: lib.h:68
int mutt_pattern_alias_exec(struct Pattern *pat, PatternExecFlags flags, struct AliasView *av, struct PatternCache *cache)
Match a pattern against an alias.
Definition: exec.c:1120
#define SLIST_FOREACH(var, head, field)
Definition: queue.h:231
+ 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 320 of file exec.c.

323 {
324  struct Pattern *p = NULL;
325 
326  SLIST_FOREACH(p, pat, entries)
327  {
328  if (pattern_exec(p, flags, m, e, msg, cache) > 0)
329  return true;
330  }
331  return false;
332 }
union Pattern::@3 p
A simple (non-regex) pattern.
Definition: lib.h:68
static int 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:792
#define SLIST_FOREACH(var, head, field)
Definition: queue.h:231
+ 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 342 of file exec.c.

344 {
345  struct Pattern *p = NULL;
346 
347  SLIST_FOREACH(p, pat, entries)
348  {
349  if (mutt_pattern_alias_exec(p, flags, av, cache) > 0)
350  return true;
351  }
352  return false;
353 }
union Pattern::@3 p
A simple (non-regex) pattern.
Definition: lib.h:68
int mutt_pattern_alias_exec(struct Pattern *pat, PatternExecFlags flags, struct AliasView *av, struct PatternCache *cache)
Match a pattern against an alias.
Definition: exec.c:1120
#define SLIST_FOREACH(var, head, field)
Definition: queue.h:231
+ 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 365 of file exec.c.

366 {
367  va_list ap;
368 
369  va_start(ap, n);
370  for (; n; n--)
371  {
372  struct AddressList *al = va_arg(ap, struct AddressList *);
373  struct Address *a = NULL;
374  TAILQ_FOREACH(a, al, entries)
375  {
376  if (pat->all_addr ^ ((!pat->is_alias || alias_reverse_lookup(a)) &&
377  ((a->mailbox && patmatch(pat, a->mailbox)) ||
378  (match_personal && a->personal && patmatch(pat, a->personal)))))
379  {
380  va_end(ap);
381  return !pat->all_addr; /* Found match, or non-match if all_addr */
382  }
383  }
384  }
385  va_end(ap);
386  return pat->all_addr; /* No matches, or all matches if all_addr */
387 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
An email address.
Definition: address.h:35
char * mailbox
Mailbox and host address.
Definition: address.h:38
bool is_alias
Is there an alias for this Address?
Definition: lib.h:76
bool all_addr
All Addresses in the list must match.
Definition: lib.h:72
static bool patmatch(const struct Pattern *pat, const char *buf)
Compare a string to a Pattern.
Definition: exec.c:71
struct Address * alias_reverse_lookup(const struct Address *addr)
Does the user have an alias for the given address.
Definition: reverse.c:105
char * personal
Real name of address.
Definition: address.h:37
+ 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 395 of file exec.c.

396 {
397  struct ListNode *np = NULL;
398  STAILQ_FOREACH(np, refs, entries)
399  {
400  if (patmatch(pat, np->data))
401  return true;
402  }
403  return false;
404 }
static bool patmatch(const struct Pattern *pat, const char *buf)
Compare a string to a Pattern.
Definition: exec.c:71
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
char * data
String.
Definition: list.h:36
A List node for strings.
Definition: list.h:34
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_predicate_recipient()

static int mutt_is_predicate_recipient ( bool  all_addr,
struct Envelope e,
addr_predicate_t  p 
)
static

Test an Envelopes Addresses using a predicate function.

Parameters
all_addrIf true, ALL Addresses must match
eEnvelope
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 417 of file exec.c.

418 {
419  struct AddressList *als[] = { &e->to, &e->cc };
420  for (size_t i = 0; i < mutt_array_size(als); ++i)
421  {
422  struct AddressList *al = als[i];
423  struct Address *a = NULL;
424  TAILQ_FOREACH(a, al, entries)
425  {
426  if (all_addr ^ p(a))
427  return !all_addr;
428  }
429  }
430  return all_addr;
431 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
An email address.
Definition: address.h:35
#define mutt_array_size(x)
Definition: memory.h:33
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
+ Here is the caller graph for this function:

◆ mutt_is_subscribed_list_recipient()

int mutt_is_subscribed_list_recipient ( bool  all_addr,
struct Envelope e 
)

Matches subscribed mailing lists.

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

Definition at line 441 of file exec.c.

442 {
444 }
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
static int mutt_is_predicate_recipient(bool all_addr, struct Envelope *e, addr_predicate_t p)
Test an Envelopes Addresses using a predicate function.
Definition: exec.c:417
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_list_recipient()

int mutt_is_list_recipient ( bool  all_addr,
struct Envelope e 
)

Matches known mailing lists.

Parameters
all_addrIf true, ALL Addresses must be mailing lists
eEnvelope
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 454 of file exec.c.

455 {
456  return mutt_is_predicate_recipient(all_addr, e, &mutt_is_mail_list);
457 }
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
static int mutt_is_predicate_recipient(bool all_addr, struct Envelope *e, addr_predicate_t p)
Test an Envelopes Addresses using a predicate function.
Definition: exec.c:417
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ match_user()

static int match_user ( int  all_addr,
struct AddressList *  al1,
struct AddressList *  al2 
)
static

Matches the user's email Address.

Parameters
all_addrIf true, ALL Addresses must refer to the user
al1First AddressList
al2Second AddressList
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 468 of file exec.c.

469 {
470  struct Address *a = NULL;
471  if (al1)
472  {
473  TAILQ_FOREACH(a, al1, entries)
474  {
475  if (all_addr ^ mutt_addr_is_user(a))
476  return !all_addr;
477  }
478  }
479 
480  if (al2)
481  {
482  TAILQ_FOREACH(a, al2, entries)
483  {
484  if (all_addr ^ mutt_addr_is_user(a))
485  return !all_addr;
486  }
487  }
488  return all_addr;
489 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
An email address.
Definition: address.h:35
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition: alias.c:562
+ 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 504 of file exec.c.

507 {
508  if (!t)
509  return 0;
510 
511  int a;
512  struct Email *e = t->message;
513  if (e)
514  if (mutt_pattern_exec(SLIST_FIRST(pat), flags, m, e, NULL))
515  return 1;
516 
517  if (up && (a = match_threadcomplete(pat, flags, m, t->parent, 1, 1, 1, 0)))
518  return a;
519  if (right && t->parent && (a = match_threadcomplete(pat, flags, m, t->next, 0, 0, 1, 1)))
520  {
521  return a;
522  }
523  if (left && t->parent && (a = match_threadcomplete(pat, flags, m, t->prev, 1, 0, 0, 1)))
524  {
525  return a;
526  }
527  if (down && (a = match_threadcomplete(pat, flags, m, t->child, 1, 0, 1, 1)))
528  return a;
529  return 0;
530 }
struct MuttThread * next
Next sibling Thread.
Definition: thread.h:47
The envelope/body of an email.
Definition: email.h:37
struct MuttThread * parent
Parent of this Thread.
Definition: thread.h:45
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:504
struct MuttThread * prev
Previous sibling Thread.
Definition: thread.h:48
struct MuttThread * child
Child of this Thread.
Definition: thread.h:46
#define SLIST_FIRST(head)
Definition: queue.h:229
struct Email * message
Email this Thread refers to.
Definition: thread.h:49
int 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:1097
+ 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 542 of file exec.c.

544 {
545  if (!t || !t->parent || !t->parent->message)
546  return 0;
547 
548  return mutt_pattern_exec(SLIST_FIRST(pat), flags, m, t->parent->message, NULL);
549 }
struct MuttThread * parent
Parent of this Thread.
Definition: thread.h:45
#define SLIST_FIRST(head)
Definition: queue.h:229
struct Email * message
Email this Thread refers to.
Definition: thread.h:49
int 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:1097
+ 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 561 of file exec.c.

563 {
564  if (!t || !t->child)
565  return 0;
566 
567  for (t = t->child; t; t = t->next)
568  if (t->message && mutt_pattern_exec(SLIST_FIRST(pat), flags, m, t->message, NULL))
569  return 1;
570 
571  return 0;
572 }
struct MuttThread * next
Next sibling Thread.
Definition: thread.h:47
struct MuttThread * child
Child of this Thread.
Definition: thread.h:46
#define SLIST_FIRST(head)
Definition: queue.h:229
struct Email * message
Email this Thread refers to.
Definition: thread.h:49
int 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:1097
+ 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 581 of file exec.c.

582 {
583  if (!b)
584  return false;
585 
586  char buf[256];
587  snprintf(buf, sizeof(buf), "%s/%s", TYPE(b), b->subtype);
588 
589  if (patmatch(pat, buf))
590  return true;
591  if (match_content_type(pat, b->parts))
592  return true;
593  if (match_content_type(pat, b->next))
594  return true;
595  return false;
596 }
struct Body * next
next attachment in the list
Definition: body.h:53
static bool match_content_type(const struct Pattern *pat, struct Body *b)
Match a Pattern against an Attachment&#39;s Content-Type.
Definition: exec.c:581
static bool patmatch(const struct Pattern *pat, const char *buf)
Compare a string to a Pattern.
Definition: exec.c:71
char * subtype
content-type subtype
Definition: body.h:37
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
#define TYPE(body)
Definition: mime.h:89
+ 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 Mailbox m,
struct Email e,
FILE *  fp 
)
static

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

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

Definition at line 607 of file exec.c.

609 {
610  mutt_parse_mime_message(m, e, fp);
611  return match_content_type(pat, e->body);
612 }
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:591
struct Body * body
List of MIME parts.
Definition: email.h:91
static bool match_content_type(const struct Pattern *pat, struct Body *b)
Match a Pattern against an Attachment&#39;s Content-Type.
Definition: exec.c:581
+ 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 620 of file exec.c.

621 {
622  struct Buffer *err = mutt_buffer_pool_get();
623 
624  bool rc = eval_date_minmax(pat, pat->p.str, err);
626 
627  return rc;
628 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
union Pattern::@3 p
String manipulation buffer.
Definition: buffer.h:33
bool eval_date_minmax(struct Pattern *pat, const char *s, struct Buffer *err)
Evaluate a date-range pattern against &#39;now&#39;.
Definition: compile.c:499
char * str
String, if string_match is set.
Definition: lib.h:86
+ 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 637 of file exec.c.

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

◆ get_pattern_cache_value()

static int 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 648 of file exec.c.

649 {
650  return cache_entry == 2;
651 }
+ 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 658 of file exec.c.

659 {
660  return cache_entry != 0;
661 }
+ 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 671 of file exec.c.

672 {
673  bool match = false;
674  char *buf = NULL;
675  size_t blen = 0;
676  FILE *fp = NULL;
677 
678  if ((pat->op == MUTT_PAT_HEADER) || (pat->op == MUTT_PAT_WHOLE_MSG))
679  {
680  struct Buffer *tempfile = mutt_buffer_pool_get();
681  mutt_buffer_mktemp(tempfile);
682  fp = mutt_file_fopen(mutt_buffer_string(tempfile), "w+");
683  if (!fp)
684  {
685  mutt_perror(mutt_buffer_string(tempfile));
686  mutt_buffer_pool_release(&tempfile);
687  return 0;
688  }
689 
691  false, false, NeoMutt->sub);
692  fflush(fp);
693  fseek(fp, 0, 0);
694 
695  while ((buf = mutt_file_read_line(buf, &blen, fp, NULL, MUTT_RL_NO_FLAGS)) != NULL)
696  {
697  if (patmatch(pat, buf) == 0)
698  {
699  match = true;
700  break;
701  }
702  }
703 
704  FREE(&buf);
705  mutt_file_fclose(&fp);
706  unlink(mutt_buffer_string(tempfile));
707  mutt_buffer_pool_release(&tempfile);
708 
709  if (match)
710  return match;
711  }
712 
713  if ((pat->op == MUTT_PAT_BODY) || (pat->op == MUTT_PAT_WHOLE_MSG))
714  {
715  fp = mutt_file_fopen(e->body->filename, "r");
716  if (!fp)
717  {
719  return 0;
720  }
721 
722  while ((buf = mutt_file_read_line(buf, &blen, fp, NULL, MUTT_RL_NO_FLAGS)) != NULL)
723  {
724  if (patmatch(pat, buf) == 0)
725  {
726  match = true;
727  break;
728  }
729  }
730 
731  FREE(&buf);
732  mutt_file_fclose(&fp);
733  }
734 
735  return match;
736 }
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:74
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
Pattern matches email&#39;s body.
Definition: lib.h:143
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
A postponed Email, just the envelope info.
Definition: header.h:42
struct Body * body
List of MIME parts.
Definition: email.h:91
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
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:667
#define mutt_perror(...)
Definition: logging.h:89
Container for Accounts, Notifications.
Definition: neomutt.h:36
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
Pattern matches email&#39;s header.
Definition: lib.h:144
static bool patmatch(const struct Pattern *pat, const char *buf)
Compare a string to a Pattern.
Definition: exec.c:71
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
struct Envelope * env
Envelope information.
Definition: email.h:90
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition: lib.h:70
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition: file.h:38
#define FREE(x)
Definition: memory.h:40
Pattern matches raw email text.
Definition: lib.h:146
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:589
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:574
+ 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 745 of file exec.c.

746 {
747  if ((pat->op == MUTT_PAT_MIMETYPE) || (pat->op == MUTT_PAT_MIMEATTACH))
748  {
749  return true;
750  }
751 
752  if ((pat->op == MUTT_PAT_WHOLE_MSG) || (pat->op == MUTT_PAT_BODY) || (pat->op == MUTT_PAT_HEADER))
753  {
754 #ifdef USE_IMAP
755  return !((m->type == MUTT_IMAP) && pat->string_match);
756 #else
757  return true;
758 #endif
759  }
760 
761  if ((pat->op == MUTT_PAT_AND) || (pat->op == MUTT_PAT_OR))
762  {
763  struct Pattern *p = NULL;
764  SLIST_FOREACH(p, pat->child, entries)
765  {
766  if (pattern_needs_msg(m, p))
767  {
768  return true;
769  }
770  }
771  }
772 
773  return false;
774 }
struct PatternList * child
Arguments to logical operation.
Definition: lib.h:82
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
Pattern matches email&#39;s body.
Definition: lib.h:143
static bool pattern_needs_msg(const struct Mailbox *m, const struct Pattern *pat)
Check whether a pattern needs a full message.
Definition: exec.c:745
union Pattern::@3 p
A simple (non-regex) pattern.
Definition: lib.h:68
Pattern matches email&#39;s header.
Definition: lib.h:144
bool string_match
Check a string for a match.
Definition: lib.h:73
Pattern matches MIME type.
Definition: lib.h:166
Pattern matches number of attachments.
Definition: lib.h:165
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition: lib.h:70
Both patterns must match.
Definition: lib.h:126
Either pattern can match.
Definition: lib.h:127
#define SLIST_FOREACH(var, head, field)
Definition: queue.h:231
Pattern matches raw email text.
Definition: lib.h:146
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
+ Here is the caller graph for this function:

◆ mutt_pattern_exec()

int 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
1Success, pattern matched
0Pattern did not match
-1Error

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

1099 {
1100  struct Message *msg = pattern_needs_msg(m, pat) ? mx_msg_open(m, e->msgno) : NULL;
1101  const int rc = pattern_exec(pat, flags, m, e, msg, cache);
1102  mx_msg_close(m, &msg);
1103  return rc;
1104 }
static bool pattern_needs_msg(const struct Mailbox *m, const struct Pattern *pat)
Check whether a pattern needs a full message.
Definition: exec.c:745
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1186
A local copy of an email.
Definition: mxapi.h:41
struct Message::@1 flags
static int 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:792
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1140
int msgno
Number displayed to the user.
Definition: email.h:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pattern_alias_exec()

int 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
1Success, pattern matched
0Pattern did not match
-1Error

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

1122 {
1123  switch (pat->op)
1124  {
1125  case MUTT_PAT_FROM: /* alias */
1126  if (!av->alias)
1127  return 0;
1128  return pat->pat_not ^ (av->alias->name && patmatch(pat, av->alias->name));
1129  case MUTT_PAT_CC: /* comment */
1130  if (!av->alias)
1131  return 0;
1132  return pat->pat_not ^ (av->alias->comment && patmatch(pat, av->alias->comment));
1133  case MUTT_PAT_TO: /* alias address list */
1134  if (!av->alias)
1135  return 0;
1136  return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
1137  1, &av->alias->addr);
1138  case MUTT_PAT_AND:
1139  return pat->pat_not ^ (perform_alias_and(pat->child, flags, av, cache) > 0);
1140  case MUTT_PAT_OR:
1141  return pat->pat_not ^ (perform_alias_or(pat->child, flags, av, cache) > 0);
1142  }
1143 
1144  return 0;
1145 }
struct PatternList * child
Arguments to logical operation.
Definition: lib.h:82
char * name
Short name.
Definition: alias.h:35
Pattern matches &#39;To:&#39; field.
Definition: lib.h:131
static int match_addrlist(struct Pattern *pat, bool match_personal, int n,...)
Match a Pattern against an Address list.
Definition: exec.c:365
Pattern matches &#39;From:&#39; field.
Definition: lib.h:135
static bool patmatch(const struct Pattern *pat, const char *buf)
Compare a string to a Pattern.
Definition: exec.c:71
bool pat_not
Pattern should be inverted (not)
Definition: lib.h:71
struct Alias * alias
Alias.
Definition: gui.h:44
struct Message::@1 flags
char * comment
Free-form comment string.
Definition: alias.h:37
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition: lib.h:70
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:342
Pattern matches &#39;Cc:&#39; field.
Definition: lib.h:132
Both patterns must match.
Definition: lib.h:126
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:297
Either pattern can match.
Definition: lib.h:127
struct AddressList addr
List of Addresses the Alias expands to.
Definition: alias.h:36
#define MUTT_MATCH_FULL_ADDRESS
Match the full address.
Definition: lib.h:95
+ Here is the call graph for this function:
+ Here is the caller graph for this function: