NeoMutt  2025-09-05-43-g177ed6
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
search.c File Reference

IMAP search routines. More...

#include "config.h"
#include <stdbool.h>
#include <string.h>
#include "private.h"
#include "mutt/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "lib.h"
#include "pattern/lib.h"
#include "adata.h"
#include "mdata.h"
+ Include dependency graph for search.c:

Go to the source code of this file.

Functions

static int check_pattern_list (const struct PatternList *patterns)
 Check how many patterns in a list can be searched server-side.
 
static bool compile_search (const struct ImapAccountData *adata, const struct Pattern *pat, struct Buffer *buf)
 Convert NeoMutt pattern to IMAP search.
 
static bool check_pattern (const struct Pattern *pat)
 Check whether a pattern can be searched server-side.
 
static bool compile_search_children (const struct ImapAccountData *adata, const struct Pattern *pat, struct Buffer *buf)
 Compile a search command for a pattern's children.
 
static bool compile_search_self (const struct ImapAccountData *adata, const struct Pattern *pat, struct Buffer *buf)
 Compile a search command for a pattern.
 
bool imap_search (struct Mailbox *m, const struct PatternList *pat)
 Find messages in mailbox matching a pattern.
 
void cmd_parse_search (struct ImapAccountData *adata, const char *s)
 Store SEARCH response for later use.
 

Detailed Description

IMAP search routines.

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 search.c.

Function Documentation

◆ check_pattern_list()

static int check_pattern_list ( const struct PatternList * patterns)
static

Check how many patterns in a list can be searched server-side.

Parameters
patternsList of patterns to match
Return values
numNumber of patterns search that can be searched server-side

Definition at line 81 of file search.c.

82{
83 int positives = 0;
84
85 const struct Pattern *pat = NULL;
86 SLIST_FOREACH(pat, patterns, entries)
87 {
88 positives += check_pattern(pat);
89 }
90
91 return positives;
92}
#define SLIST_FOREACH(var, head, field)
Definition queue.h:229
static bool check_pattern(const struct Pattern *pat)
Check whether a pattern can be searched server-side.
Definition search.c:55
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:

◆ compile_search()

static bool compile_search ( const struct ImapAccountData * adata,
const struct Pattern * pat,
struct Buffer * buf )
static

Convert NeoMutt pattern to IMAP search.

Parameters
adataImap Account data
patPattern to convert
bufBuffer for result
Return values
trueSuccess
falseFailure

Convert neomutt Pattern to IMAP SEARCH command containing only elements that require full-text search (neomutt already has what it needs for most match types, and does a better job (eg server doesn't support regexes).

Definition at line 207 of file search.c.

209{
210 if (!check_pattern(pat))
211 return true;
212
213 if (pat->pat_not)
214 buf_addstr(buf, "NOT ");
215
216 return pat->child ? compile_search_children(adata, pat, buf) :
217 compile_search_self(adata, pat, buf);
218}
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:226
static bool compile_search_children(const struct ImapAccountData *adata, const struct Pattern *pat, struct Buffer *buf)
Compile a search command for a pattern's children.
Definition search.c:102
static bool compile_search_self(const struct ImapAccountData *adata, const struct Pattern *pat, struct Buffer *buf)
Compile a search command for a pattern.
Definition search.c:141
struct PatternList * child
Arguments to logical operation.
Definition lib.h:90
bool pat_not
Pattern should be inverted (not)
Definition lib.h:79
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ check_pattern()

static bool check_pattern ( const struct Pattern * pat)
static

Check whether a pattern can be searched server-side.

Parameters
patPattern to check
Return values
truePattern can be searched server-side
falsePattern cannot be searched server-side

Definition at line 55 of file search.c.

56{
57 switch (pat->op)
58 {
59 case MUTT_PAT_BODY:
60 case MUTT_PAT_HEADER:
62 if (pat->string_match)
63 return true;
64 break;
66 return true;
67 break;
68 default:
69 if (pat->child && check_pattern_list(pat->child))
70 return true;
71 break;
72 }
73 return false;
74}
@ 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_SERVERSEARCH
Server-side pattern matches.
Definition lib.h:175
@ MUTT_PAT_BODY
Pattern matches email's body.
Definition lib.h:155
static int check_pattern_list(const struct PatternList *patterns)
Check how many patterns in a list can be searched server-side.
Definition search.c:81
bool string_match
Check a string for a match.
Definition lib.h:81
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition lib.h:78
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compile_search_children()

static bool compile_search_children ( const struct ImapAccountData * adata,
const struct Pattern * pat,
struct Buffer * buf )
static

Compile a search command for a pattern's children.

Parameters
adataImap Account data
patParent pattern
bufBuffer for the resulting command
Return values
trueSuccess
falseFailure

Definition at line 102 of file search.c.

104{
105 int clauses = check_pattern_list(pat->child);
106 if (clauses == 0)
107 return true;
108
109 buf_addch(buf, '(');
110
111 struct Pattern *c;
112 SLIST_FOREACH(c, pat->child, entries)
113 {
114 if (!check_pattern(c))
115 continue;
116
117 if ((pat->op == MUTT_PAT_OR) && (clauses > 1))
118 buf_addstr(buf, "OR ");
119
120 if (!compile_search(adata, c, buf))
121 return false;
122
123 if (clauses > 1)
124 buf_addch(buf, ' ');
125
126 clauses--;
127 }
128
129 buf_addch(buf, ')');
130 return true;
131}
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition buffer.c:241
@ MUTT_PAT_OR
Either pattern can match.
Definition lib.h:138
static bool compile_search(const struct ImapAccountData *adata, const struct Pattern *pat, struct Buffer *buf)
Convert NeoMutt pattern to IMAP search.
Definition search.c:207
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compile_search_self()

static bool compile_search_self ( const struct ImapAccountData * adata,
const struct Pattern * pat,
struct Buffer * buf )
static

Compile a search command for a pattern.

Parameters
adataImap Account data
patPattern
bufBuffer for the resulting command
Return values
trueSuccess
falseFailure

Definition at line 141 of file search.c.

143{
144 char term[256] = { 0 };
145 char *delim = NULL;
146
147 switch (pat->op)
148 {
149 case MUTT_PAT_HEADER:
150 buf_addstr(buf, "HEADER ");
151
152 /* extract header name */
153 delim = strchr(pat->p.str, ':');
154 if (!delim)
155 {
156 mutt_error(_("Header search without header name: %s"), pat->p.str);
157 return false;
158 }
159 *delim = '\0';
160 imap_quote_string(term, sizeof(term), pat->p.str, false);
161 buf_addstr(buf, term);
162 buf_addch(buf, ' ');
163
164 /* and field */
165 *delim = ':';
166 delim++;
167 SKIPWS(delim);
168 imap_quote_string(term, sizeof(term), delim, false);
169 buf_addstr(buf, term);
170 break;
171 case MUTT_PAT_BODY:
172 buf_addstr(buf, "BODY ");
173 imap_quote_string(term, sizeof(term), pat->p.str, false);
174 buf_addstr(buf, term);
175 break;
177 buf_addstr(buf, "TEXT ");
178 imap_quote_string(term, sizeof(term), pat->p.str, false);
179 buf_addstr(buf, term);
180 break;
182 if (!(adata->capabilities & IMAP_CAP_X_GM_EXT_1))
183 {
184 mutt_error(_("Server-side custom search not supported: %s"), pat->p.str);
185 return false;
186 }
187 buf_addstr(buf, "X-GM-RAW ");
188 imap_quote_string(term, sizeof(term), pat->p.str, false);
189 buf_addstr(buf, term);
190 break;
191 }
192 return true;
193}
#define mutt_error(...)
Definition logging2.h:93
#define IMAP_CAP_X_GM_EXT_1
https://developers.google.com/gmail/imap/imap-extensions
Definition private.h:140
void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
Quote string according to IMAP rules.
Definition util.c:885
#define _(a)
Definition message.h:28
#define SKIPWS(ch)
Definition string2.h:51
ImapCapFlags capabilities
Capability flags.
Definition adata.h:55
union Pattern::@006112053024257132210207314205210350156165326341 p
char * str
String, if string_match is set.
Definition lib.h:94
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_search()

bool imap_search ( struct Mailbox * m,
const struct PatternList * pat )

Find messages in mailbox matching a pattern.

Parameters
mMailbox
patPattern to match
Return values
trueSuccess
falseFailure

Definition at line 227 of file search.c.

228{
229 for (int i = 0; i < m->msg_count; i++)
230 {
231 struct Email *e = m->emails[i];
232 if (!e)
233 break;
234 e->matched = false;
235 }
236
237 if (check_pattern_list(pat) == 0)
238 return true;
239
240 struct Buffer *buf = buf_pool_get();
241 buf_addstr(buf, "UID SEARCH ");
242
244 const bool ok = compile_search(adata, SLIST_FIRST(pat), buf) &&
246
248 return ok;
249}
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition adata.c:123
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition command.c:1302
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition private.h:71
@ IMAP_EXEC_SUCCESS
Imap command executed or queued successfully.
Definition private.h:82
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:96
#define SLIST_FIRST(head)
Definition queue.h:227
void * adata
Private data (for Mailbox backends)
Definition account.h:42
String manipulation buffer.
Definition buffer.h:36
The envelope/body of an email.
Definition email.h:39
bool matched
Search matches this Email.
Definition email.h:102
IMAP-specific Account data -.
Definition adata.h:40
char * buf
Definition adata.h:59
int msg_count
Total number of messages.
Definition mailbox.h:88
struct Email ** emails
Array of Emails.
Definition mailbox.h:96
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cmd_parse_search()

void cmd_parse_search ( struct ImapAccountData * adata,
const char * s )

Store SEARCH response for later use.

Parameters
adataImap Account data
sCommand string with search results

Definition at line 256 of file search.c.

257{
258 unsigned int uid;
259 struct Email *e = NULL;
260 struct ImapMboxData *mdata = adata->mailbox->mdata;
261
262 mutt_debug(LL_DEBUG2, "Handling SEARCH\n");
263
264 while ((s = imap_next_word((char *) s)) && (*s != '\0'))
265 {
266 if (!mutt_str_atoui(s, &uid))
267 continue;
268 e = mutt_hash_int_find(mdata->uid_hash, uid);
269 if (e)
270 e->matched = true;
271 }
272}
const char * mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition atoi.c:218
#define mutt_debug(LEVEL,...)
Definition logging2.h:90
void * mutt_hash_int_find(const struct HashTable *table, unsigned int intkey)
Find the HashElem data in a Hash Table element using a key.
Definition hash.c:392
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition util.c:823
@ LL_DEBUG2
Log at debug level 2.
Definition logging2.h:45
struct Mailbox * mailbox
Current selected mailbox.
Definition adata.h:76
IMAP-specific Mailbox data -.
Definition mdata.h:40
void * mdata
Driver specific data.
Definition mailbox.h:132
+ Here is the call graph for this function:
+ Here is the caller graph for this function: