NeoMutt  2020-08-21-74-g346364
Teaching an old dog new tricks
DOXYGEN
hook.c File Reference

Parse and execute user-defined hooks. More...

#include "config.h"
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "mutt/lib.h"
#include "address/lib.h"
#include "email/lib.h"
#include "alias/lib.h"
#include "mutt.h"
#include "hook.h"
#include "ncrypt/lib.h"
#include "pattern/lib.h"
#include "context.h"
#include "format_flags.h"
#include "hdrline.h"
#include "init.h"
#include "mutt_attach.h"
#include "mutt_commands.h"
#include "mutt_globals.h"
#include "muttlib.h"
#include "mx.h"
#include "compmbox/lib.h"
+ Include dependency graph for hook.c:

Go to the source code of this file.

Data Structures

struct  Hook
 A list of user hooks. More...
 

Functions

 TAILQ_HEAD (HookList, Hook)
 
enum CommandResult mutt_parse_hook (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'hook' family of commands - Implements Command::parse() More...
 
static void delete_hook (struct Hook *h)
 Delete a Hook. More...
 
void mutt_delete_hooks (HookFlags type)
 Delete matching hooks. More...
 
static void delete_idxfmt_hooklist (int type, void *obj, intptr_t data)
 Delete a index-format-hook from the Hash Table - Implements hash_hdata_free_t. More...
 
static void delete_idxfmt_hooks (void)
 Delete all the index-format-hooks. More...
 
enum CommandResult mutt_parse_idxfmt_hook (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'index-format-hook' command - Implements Command::parse() More...
 
enum CommandResult mutt_parse_unhook (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unhook' command - Implements Command::parse() More...
 
void mutt_folder_hook (const char *path, const char *desc)
 Perform a folder hook. More...
 
char * mutt_find_hook (HookFlags type, const char *pat)
 Find a matching hook. More...
 
void mutt_message_hook (struct Mailbox *m, struct Email *e, HookFlags type)
 Perform a message hook. More...
 
static int addr_hook (char *path, size_t pathlen, HookFlags type, struct Context *ctx, struct Email *e)
 Perform an address hook (get a path) More...
 
void mutt_default_save (char *path, size_t pathlen, struct Email *e)
 Find the default save path for an email. More...
 
void mutt_select_fcc (struct Buffer *path, struct Email *e)
 Select the FCC path for an email. More...
 
static void list_hook (struct ListHead *matches, const char *match, HookFlags hook)
 Find hook strings matching. More...
 
void mutt_crypt_hook (struct ListHead *list, struct Address *addr)
 Find crypto hooks for an Address. More...
 
void mutt_account_hook (const char *url)
 Perform an account hook. More...
 
void mutt_timeout_hook (void)
 Execute any timeout hooks. More...
 
void mutt_startup_shutdown_hook (HookFlags type)
 Execute any startup/shutdown hooks. More...
 
const char * mutt_idxfmt_hook (const char *name, struct Mailbox *m, struct Email *e)
 Get index-format-hook format string. More...
 

Variables

char * C_DefaultHook
 Config: Pattern to use for hooks that only have a simple regex. More...
 
bool C_ForceName
 Config: Save outgoing mail in a folder of their name. More...
 
bool C_SaveName
 Config: Save outgoing message to mailbox of recipient's name if it exists. More...
 
static struct HookList Hooks = TAILQ_HEAD_INITIALIZER(Hooks)
 
static struct HashTableIdxFmtHooks = NULL
 
static HookFlags current_hook_type = MUTT_HOOK_NO_FLAGS
 

Detailed Description

Parse and execute user-defined hooks.

Authors
  • Michael R. Elkins, and others
  • Pietro Cerutti

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

Function Documentation

◆ TAILQ_HEAD()

TAILQ_HEAD ( HookList  ,
Hook   
)

◆ mutt_parse_hook()

enum CommandResult mutt_parse_hook ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'hook' family of commands - Implements Command::parse()

This is used by 'account-hook', 'append-hook' and many more.

Definition at line 85 of file hook.c.

87 {
88  struct Hook *hook = NULL;
89  int rc = MUTT_CMD_ERROR;
90  bool pat_not = false;
91  regex_t *rx = NULL;
92  struct PatternList *pat = NULL;
93 
94  struct Buffer *cmd = mutt_buffer_pool_get();
95  struct Buffer *pattern = mutt_buffer_pool_get();
96 
97  if (~data & MUTT_GLOBAL_HOOK) /* NOT a global hook */
98  {
99  if (*s->dptr == '!')
100  {
101  s->dptr++;
102  SKIPWS(s->dptr);
103  pat_not = true;
104  }
105 
107 
108  if (!MoreArgs(s))
109  {
110  mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
111  rc = MUTT_CMD_WARNING;
112  goto cleanup;
113  }
114  }
115 
116  mutt_extract_token(cmd, s,
121 
122  if (mutt_buffer_is_empty(cmd))
123  {
124  mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
125  rc = MUTT_CMD_WARNING;
126  goto cleanup;
127  }
128 
129  if (MoreArgs(s))
130  {
131  mutt_buffer_printf(err, _("%s: too many arguments"), buf->data);
132  rc = MUTT_CMD_WARNING;
133  goto cleanup;
134  }
135 
137  {
138  /* Accidentally using the ^ mailbox shortcut in the .neomuttrc is a
139  * common mistake */
140  if ((pattern->data[0] == '^') && !CurrentFolder)
141  {
142  mutt_buffer_strcpy(err, _("current mailbox shortcut '^' is unset"));
143  goto cleanup;
144  }
145 
146  struct Buffer *tmp = mutt_buffer_pool_get();
147  mutt_buffer_copy(tmp, pattern);
149 
150  /* Check for other mailbox shortcuts that expand to the empty string.
151  * This is likely a mistake too */
152  if (mutt_buffer_is_empty(tmp) && !mutt_buffer_is_empty(pattern))
153  {
154  mutt_buffer_strcpy(err, _("mailbox shortcut expanded to empty regex"));
156  goto cleanup;
157  }
158 
159  mutt_buffer_copy(pattern, tmp);
161  }
162 #ifdef USE_COMP_MBOX
164  {
165  if (mutt_comp_valid_command(mutt_b2s(cmd)) == 0)
166  {
167  mutt_buffer_strcpy(err, _("badly formatted command string"));
168  goto cleanup;
169  }
170  }
171 #endif
172  else if (C_DefaultHook && (~data & MUTT_GLOBAL_HOOK) &&
174  (!WithCrypto || !(data & MUTT_CRYPT_HOOK)))
175  {
176  /* At this stage remain only message-hooks, reply-hooks, send-hooks,
177  * send2-hooks, save-hooks, and fcc-hooks: All those allowing full
178  * patterns. If given a simple regex, we expand $default_hook. */
180  }
181 
183  {
185  }
186 
187  /* check to make sure that a matching hook doesn't already exist */
188  TAILQ_FOREACH(hook, &Hooks, entries)
189  {
190  if (data & MUTT_GLOBAL_HOOK)
191  {
192  /* Ignore duplicate global hooks */
193  if (mutt_str_equal(hook->command, mutt_b2s(cmd)))
194  {
195  rc = MUTT_CMD_SUCCESS;
196  goto cleanup;
197  }
198  }
199  else if ((hook->type == data) && (hook->regex.pat_not == pat_not) &&
200  mutt_str_equal(mutt_b2s(pattern), hook->regex.pattern))
201  {
203  MUTT_ACCOUNT_HOOK | MUTT_REPLY_HOOK | MUTT_CRYPT_HOOK |
205  {
206  /* these hooks allow multiple commands with the same
207  * pattern, so if we've already seen this pattern/command pair, just
208  * ignore it instead of creating a duplicate */
209  if (mutt_str_equal(hook->command, mutt_b2s(cmd)))
210  {
211  rc = MUTT_CMD_SUCCESS;
212  goto cleanup;
213  }
214  }
215  else
216  {
217  /* other hooks only allow one command per pattern, so update the
218  * entry with the new command. this currently does not change the
219  * order of execution of the hooks, which i think is desirable since
220  * a common action to perform is to change the default (.) entry
221  * based upon some other information. */
222  FREE(&hook->command);
223  hook->command = mutt_buffer_strdup(cmd);
224  rc = MUTT_CMD_SUCCESS;
225  goto cleanup;
226  }
227  }
228  }
229 
231  {
232  /* These are managed separately by the charset code */
234  if (mutt_ch_lookup_add(type, mutt_b2s(pattern), mutt_b2s(cmd), err))
235  rc = MUTT_CMD_SUCCESS;
236  goto cleanup;
237  }
240  {
241  PatternCompFlags comp_flags;
242 
243  if (data & (MUTT_SEND2_HOOK))
244  comp_flags = MUTT_PC_SEND_MODE_SEARCH;
245  else if (data & (MUTT_SEND_HOOK | MUTT_FCC_HOOK))
246  comp_flags = MUTT_PC_NO_FLAGS;
247  else
248  comp_flags = MUTT_PC_FULL_MSG;
249 
250  pat = mutt_pattern_comp(mutt_b2s(pattern), comp_flags, err);
251  if (!pat)
252  goto cleanup;
253  }
254  else if (~data & MUTT_GLOBAL_HOOK) /* NOT a global hook */
255  {
256  /* Hooks not allowing full patterns: Check syntax of regex */
257  rx = mutt_mem_malloc(sizeof(regex_t));
258  int rc2 = REG_COMP(rx, NONULL(mutt_b2s(pattern)),
259  ((data & MUTT_CRYPT_HOOK) ? REG_ICASE : 0));
260  if (rc2 != 0)
261  {
262  regerror(rc2, rx, err->data, err->dsize);
263  FREE(&rx);
264  goto cleanup;
265  }
266  }
267 
268  hook = mutt_mem_calloc(1, sizeof(struct Hook));
269  hook->type = data;
270  hook->command = mutt_buffer_strdup(cmd);
271  hook->pattern = pat;
272  hook->regex.pattern = mutt_buffer_strdup(pattern);
273  hook->regex.regex = rx;
274  hook->regex.pat_not = pat_not;
275  TAILQ_INSERT_TAIL(&Hooks, hook, entries);
276  rc = MUTT_CMD_SUCCESS;
277 
278 cleanup:
280  mutt_buffer_pool_release(&pattern);
281  return rc;
282 }
#define MUTT_SEND_HOOK
send-hook: when composing a new email
Definition: hook.h:47
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
static struct HookList Hooks
Definition: hook.c:75
#define NONULL(x)
Definition: string2.h:37
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define WithCrypto
Definition: lib.h:123
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define MUTT_SHUTDOWN_HOOK
shutdown-hook: run when leaving NeoMutt
Definition: hook.h:65
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
Error: Can&#39;t help the user.
Definition: mutt_commands.h:35
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer&#39;s contents to another Buffer.
Definition: buffer.c:445
HookFlags type
Hook type.
Definition: hook.c:67
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
regex_t * regex
compiled expression
Definition: regex3.h:91
char * mutt_buffer_strdup(struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
String manipulation buffer.
Definition: buffer.h:33
bool pat_not
do not match
Definition: regex3.h:92
A list of user hooks.
Definition: hook.c:65
#define _(a)
Definition: message.h:28
struct PatternList * mutt_pattern_comp(const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: compile.c:1056
#define MUTT_CHARSET_HOOK
charset-hook: create a charset alias for malformed emails
Definition: hook.h:50
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:53
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:52
void mutt_check_simple(struct Buffer *s, const char *simple)
Convert a simple search into a real request.
Definition: pattern.c:107
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
#define MUTT_CRYPT_HOOK
crypt-hook: automatically select a PGP/SMIME key
Definition: hook.h:53
void mutt_buffer_expand_path_regex(struct Buffer *buf, bool regex)
Create the canonical path (with regex char escaping)
Definition: muttlib.c:140
Character set conversion.
Definition: charset.h:69
char * command
Filename, command or pattern to execute.
Definition: hook.c:69
size_t dsize
Length of data.
Definition: buffer.h:37
#define MoreArgs(buf)
Definition: buffer.h:43
#define MUTT_ICONV_HOOK
iconv-hook: create a system charset alias
Definition: hook.h:51
#define SKIPWS(ch)
Definition: string2.h:46
#define MUTT_PC_SEND_MODE_SEARCH
Allow send-mode body searching.
Definition: lib.h:60
struct Regex regex
Regular expression.
Definition: hook.c:68
#define MUTT_APPEND_HOOK
append-hook: append to a compressed mailbox
Definition: hook.h:59
#define MUTT_MBOX_HOOK
mbox-hook: move messages after reading them
Definition: hook.h:46
#define MUTT_GLOBAL_HOOK
Hooks which don&#39;t take a regex.
Definition: hook.h:66
Alias for another character set.
Definition: charset.h:68
#define mutt_b2s(buf)
Definition: buffer.h:41
#define MUTT_SAVE_HOOK
save-hook: set a default folder when saving an email
Definition: hook.h:49
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:414
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
#define MUTT_CLOSE_HOOK
close-hook: write to a compressed mailbox
Definition: hook.h:60
char * dptr
Current read/write position.
Definition: buffer.h:36
#define MUTT_TOKEN_SPACE
Don&#39;t treat whitespace as a term.
Definition: mutt.h:73
#define MUTT_PC_NO_FLAGS
No flags are set.
Definition: lib.h:57
char * data
Pointer to data.
Definition: buffer.h:35
int mutt_comp_valid_command(const char *cmd)
Is this command string allowed?
Definition: compress.c:388
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:802
#define MUTT_OPEN_HOOK
open-hook: to read a compressed mailbox
Definition: hook.h:58
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
#define MUTT_TIMEOUT_HOOK
timeout-hook: run a command periodically
Definition: hook.h:63
Success: Command worked.
Definition: mutt_commands.h:37
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:323
Warning: Help given to the user.
Definition: mutt_commands.h:36
#define MUTT_SEND2_HOOK
send2-hook: when changing fields in the compose menu
Definition: hook.h:56
WHERE char * CurrentFolder
Currently selected mailbox.
Definition: mutt_globals.h:54
#define MUTT_REPLY_HOOK
reply-hook: when replying to an email
Definition: hook.h:55
#define FREE(x)
Definition: memory.h:40
char * C_DefaultHook
Config: Pattern to use for hooks that only have a simple regex.
Definition: hook.c:58
char * pattern
printable version
Definition: regex3.h:90
#define MUTT_PC_FULL_MSG
Enable body and header matching.
Definition: lib.h:58
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
#define MUTT_STARTUP_HOOK
startup-hook: run when starting NeoMutt
Definition: hook.h:64
LookupType
Types of character set lookups.
Definition: charset.h:66
#define MUTT_FCC_HOOK
fcc-hook: to save outgoing email
Definition: hook.h:48
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:70
uint8_t PatternCompFlags
Flags for mutt_pattern_comp(), e.g. MUTT_PC_FULL_MSG.
Definition: lib.h:56
#define MUTT_ACCOUNT_HOOK
account-hook: when changing between accounts
Definition: hook.h:54
bool mutt_ch_lookup_add(enum LookupType type, const char *pat, const char *replace, struct Buffer *err)
Add a new character set lookup.
Definition: charset.c:485
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:70
#define MUTT_FOLDER_HOOK
folder-hook: when entering a mailbox
Definition: hook.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ delete_hook()

static void delete_hook ( struct Hook h)
static

Delete a Hook.

Parameters
hHook to delete

Definition at line 288 of file hook.c.

289 {
290  FREE(&h->command);
291  FREE(&h->regex.pattern);
292  if (h->regex.regex)
293  {
294  regfree(h->regex.regex);
295  FREE(&h->regex.regex);
296  }
298  FREE(&h);
299 }
regex_t * regex
compiled expression
Definition: regex3.h:91
char * command
Filename, command or pattern to execute.
Definition: hook.c:69
struct Regex regex
Regular expression.
Definition: hook.c:68
#define FREE(x)
Definition: memory.h:40
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: compile.c:1004
char * pattern
printable version
Definition: regex3.h:90
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:70
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_delete_hooks()

void mutt_delete_hooks ( HookFlags  type)

Delete matching hooks.

Parameters
typeHook type to delete, see HookFlags

If 0 is passed, all the hooks will be deleted.

Definition at line 307 of file hook.c.

308 {
309  struct Hook *h = NULL;
310  struct Hook *tmp = NULL;
311 
312  TAILQ_FOREACH_SAFE(h, &Hooks, entries, tmp)
313  {
314  if ((type == MUTT_HOOK_NO_FLAGS) || (type == h->type))
315  {
316  TAILQ_REMOVE(&Hooks, h, entries);
317  delete_hook(h);
318  }
319  }
320 }
static struct HookList Hooks
Definition: hook.c:75
HookFlags type
Hook type.
Definition: hook.c:67
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:728
A list of user hooks.
Definition: hook.c:65
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:44
static void delete_hook(struct Hook *h)
Delete a Hook.
Definition: hook.c:288
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ delete_idxfmt_hooklist()

static void delete_idxfmt_hooklist ( int  type,
void *  obj,
intptr_t  data 
)
static

Delete a index-format-hook from the Hash Table - Implements hash_hdata_free_t.

Definition at line 325 of file hook.c.

326 {
327  struct HookList *hl = obj;
328  struct Hook *h = NULL;
329  struct Hook *tmp = NULL;
330 
331  TAILQ_FOREACH_SAFE(h, hl, entries, tmp)
332  {
333  TAILQ_REMOVE(hl, h, entries);
334  delete_hook(h);
335  }
336 
337  FREE(&hl);
338 }
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:728
A list of user hooks.
Definition: hook.c:65
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
#define FREE(x)
Definition: memory.h:40
static void delete_hook(struct Hook *h)
Delete a Hook.
Definition: hook.c:288
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ delete_idxfmt_hooks()

static void delete_idxfmt_hooks ( void  )
static

Delete all the index-format-hooks.

Definition at line 343 of file hook.c.

344 {
346 }
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:447
static struct HashTable * IdxFmtHooks
Definition: hook.c:77
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_parse_idxfmt_hook()

enum CommandResult mutt_parse_idxfmt_hook ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'index-format-hook' command - Implements Command::parse()

Definition at line 351 of file hook.c.

353 {
354  enum CommandResult rc = MUTT_CMD_ERROR;
355  bool pat_not = false;
356 
357  struct Buffer *name = mutt_buffer_pool_get();
358  struct Buffer *pattern = mutt_buffer_pool_get();
359  struct Buffer *fmtstring = mutt_buffer_pool_get();
360 
361  if (!IdxFmtHooks)
362  {
365  }
366 
367  if (!MoreArgs(s))
368  {
369  mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
370  goto out;
371  }
373  struct HookList *hl = mutt_hash_find(IdxFmtHooks, mutt_b2s(name));
374 
375  if (*s->dptr == '!')
376  {
377  s->dptr++;
378  SKIPWS(s->dptr);
379  pat_not = true;
380  }
382 
383  if (!MoreArgs(s))
384  {
385  mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
386  goto out;
387  }
389 
390  if (MoreArgs(s))
391  {
392  mutt_buffer_printf(err, _("%s: too many arguments"), buf->data);
393  goto out;
394  }
395 
396  if (C_DefaultHook)
398 
399  /* check to make sure that a matching hook doesn't already exist */
400  struct Hook *hook = NULL;
401  if (hl)
402  {
403  TAILQ_FOREACH(hook, hl, entries)
404  {
405  if ((hook->regex.pat_not == pat_not) &&
406  mutt_str_equal(mutt_b2s(pattern), hook->regex.pattern))
407  {
408  mutt_str_replace(&hook->command, mutt_b2s(fmtstring));
409  rc = MUTT_CMD_SUCCESS;
410  goto out;
411  }
412  }
413  }
414 
415  /* MUTT_PC_PATTERN_DYNAMIC sets so that date ranges are regenerated during
416  * matching. This of course is slower, but index-format-hook is commonly
417  * used for date ranges, and they need to be evaluated relative to "now", not
418  * the hook compilation time. */
419  struct PatternList *pat = mutt_pattern_comp(
421  if (!pat)
422  goto out;
423 
424  hook = mutt_mem_calloc(1, sizeof(struct Hook));
425  hook->type = MUTT_IDXFMTHOOK;
426  hook->command = mutt_buffer_strdup(fmtstring);
427  hook->pattern = pat;
428  hook->regex.pattern = mutt_buffer_strdup(pattern);
429  hook->regex.regex = NULL;
430  hook->regex.pat_not = pat_not;
431 
432  if (!hl)
433  {
434  hl = mutt_mem_calloc(1, sizeof(*hl));
435  TAILQ_INIT(hl);
437  }
438 
439  TAILQ_INSERT_TAIL(hl, hook, entries);
440  rc = MUTT_CMD_SUCCESS;
441 
442 out:
444  mutt_buffer_pool_release(&pattern);
445  mutt_buffer_pool_release(&fmtstring);
446 
447  return rc;
448 }
#define MUTT_PC_PATTERN_DYNAMIC
Enable runtime date range evaluation.
Definition: lib.h:59
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
Definition: hash.c:354
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
Definition: hash.c:327
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
CommandResult
Error codes for command_t parse functions.
Definition: mutt_commands.h:33
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
Error: Can&#39;t help the user.
Definition: mutt_commands.h:35
HookFlags type
Hook type.
Definition: hook.c:67
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
regex_t * regex
compiled expression
Definition: regex3.h:91
char * mutt_buffer_strdup(struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
String manipulation buffer.
Definition: buffer.h:33
bool pat_not
do not match
Definition: regex3.h:92
A list of user hooks.
Definition: hook.c:65
#define _(a)
Definition: message.h:28
struct PatternList * mutt_pattern_comp(const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: compile.c:1056
void mutt_check_simple(struct Buffer *s, const char *simple)
Convert a simple search into a real request.
Definition: pattern.c:107
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
#define MUTT_IDXFMTHOOK
index-format-hook: customise the format of the index
Definition: hook.h:62
char * command
Filename, command or pattern to execute.
Definition: hook.c:69
#define MoreArgs(buf)
Definition: buffer.h:43
#define SKIPWS(ch)
Definition: string2.h:46
#define TAILQ_INIT(head)
Definition: queue.h:758
struct Regex regex
Regular expression.
Definition: hook.c:68
static void delete_idxfmt_hooklist(int type, void *obj, intptr_t data)
Delete a index-format-hook from the Hash Table - Implements hash_hdata_free_t.
Definition: hook.c:325
#define mutt_b2s(buf)
Definition: buffer.h:41
void mutt_hash_set_destructor(struct HashTable *table, hash_hdata_free_t fn, intptr_t fn_data)
Set the destructor for a Hash Table.
Definition: hash.c:293
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:414
char * dptr
Current read/write position.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:35
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:802
Success: Command worked.
Definition: mutt_commands.h:37
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
static struct HashTable * IdxFmtHooks
Definition: hook.c:77
char * C_DefaultHook
Config: Pattern to use for hooks that only have a simple regex.
Definition: hook.c:58
char * pattern
printable version
Definition: regex3.h:90
#define MUTT_HASH_STRDUP_KEYS
make a copy of the keys
Definition: hash.h:99
#define MUTT_PC_FULL_MSG
Enable body and header matching.
Definition: lib.h:58
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition: hash.c:251
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:70
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:70
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_parse_unhook()

enum CommandResult mutt_parse_unhook ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unhook' command - Implements Command::parse()

Definition at line 453 of file hook.c.

455 {
456  while (MoreArgs(s))
457  {
459  if (mutt_str_equal("*", buf->data))
460  {
462  {
463  mutt_buffer_printf(err, "%s", _("unhook: Can't do unhook * from within a hook"));
464  return MUTT_CMD_WARNING;
465  }
469  }
470  else
471  {
472  HookFlags type = mutt_get_hook_type(buf->data);
473 
474  if (type == MUTT_HOOK_NO_FLAGS)
475  {
476  mutt_buffer_printf(err, _("unhook: unknown hook type: %s"), buf->data);
477  return MUTT_CMD_ERROR;
478  }
479  if (type & (MUTT_CHARSET_HOOK | MUTT_ICONV_HOOK))
480  {
482  return MUTT_CMD_SUCCESS;
483  }
484  if (current_hook_type == type)
485  {
486  mutt_buffer_printf(err, _("unhook: Can't delete a %s from within a %s"),
487  buf->data, buf->data);
488  return MUTT_CMD_WARNING;
489  }
490  if (type == MUTT_IDXFMTHOOK)
492  else
493  mutt_delete_hooks(type);
494  }
495  }
496  return MUTT_CMD_SUCCESS;
497 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
Error: Can&#39;t help the user.
Definition: mutt_commands.h:35
static void delete_idxfmt_hooks(void)
Delete all the index-format-hooks.
Definition: hook.c:343
HookFlags mutt_get_hook_type(const char *name)
Find a hook by name.
Definition: init.c:714
static HookFlags current_hook_type
Definition: hook.c:78
#define _(a)
Definition: message.h:28
void mutt_delete_hooks(HookFlags type)
Delete matching hooks.
Definition: hook.c:307
#define MUTT_CHARSET_HOOK
charset-hook: create a charset alias for malformed emails
Definition: hook.h:50
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
uint32_t HookFlags
Flags for mutt_parse_hook(), e.g. MUTT_FOLDER_HOOK.
Definition: hook.h:43
#define MUTT_IDXFMTHOOK
index-format-hook: customise the format of the index
Definition: hook.h:62
void mutt_ch_lookup_remove(void)
Remove all the character set lookups.
Definition: charset.c:517
#define MoreArgs(buf)
Definition: buffer.h:43
#define MUTT_ICONV_HOOK
iconv-hook: create a system charset alias
Definition: hook.h:51
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:414
char * data
Pointer to data.
Definition: buffer.h:35
Success: Command worked.
Definition: mutt_commands.h:37
Warning: Help given to the user.
Definition: mutt_commands.h:36
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:44
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:70
+ Here is the call graph for this function:

◆ mutt_folder_hook()

void mutt_folder_hook ( const char *  path,
const char *  desc 
)

Perform a folder hook.

Parameters
pathPath to potentially match
descDescription to potentially match

Definition at line 504 of file hook.c.

505 {
506  if (!path && !desc)
507  return;
508 
509  struct Hook *hook = NULL;
510  struct Buffer *err = mutt_buffer_pool_get();
511 
513 
514  TAILQ_FOREACH(hook, &Hooks, entries)
515  {
516  if (!hook->command)
517  continue;
518 
519  if (!(hook->type & MUTT_FOLDER_HOOK))
520  continue;
521 
522  const char *match = NULL;
523  if (mutt_regex_match(&hook->regex, path))
524  match = path;
525  else if (mutt_regex_match(&hook->regex, desc))
526  match = desc;
527 
528  if (match)
529  {
530  mutt_debug(LL_DEBUG1, "folder-hook '%s' matches '%s'\n", hook->regex.pattern, match);
531  mutt_debug(LL_DEBUG5, " %s\n", hook->command);
532  if (mutt_parse_rc_line(hook->command, err) == MUTT_CMD_ERROR)
533  {
534  mutt_error("%s", mutt_b2s(err));
535  break;
536  }
537  }
538  }
540 
542 }
static struct HookList Hooks
Definition: hook.c:75
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
Error: Can&#39;t help the user.
Definition: mutt_commands.h:35
HookFlags type
Hook type.
Definition: hook.c:67
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
static HookFlags current_hook_type
Definition: hook.c:78
String manipulation buffer.
Definition: buffer.h:33
A list of user hooks.
Definition: hook.c:65
enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: init.c:1041
char * command
Filename, command or pattern to execute.
Definition: hook.c:69
struct Regex regex
Regular expression.
Definition: hook.c:68
#define mutt_b2s(buf)
Definition: buffer.h:41
Log at debug level 1.
Definition: logging.h:40
#define mutt_error(...)
Definition: logging.h:84
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:609
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:44
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
char * pattern
printable version
Definition: regex3.h:90
Log at debug level 5.
Definition: logging.h:44
#define MUTT_FOLDER_HOOK
folder-hook: when entering a mailbox
Definition: hook.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_find_hook()

char* mutt_find_hook ( HookFlags  type,
const char *  pat 
)

Find a matching hook.

Parameters
typeHook type, see HookFlags
patPattern to match
Return values
ptrCommand string
Note
The returned string must not be freed.

Definition at line 552 of file hook.c.

553 {
554  struct Hook *tmp = NULL;
555 
556  TAILQ_FOREACH(tmp, &Hooks, entries)
557  {
558  if (tmp->type & type)
559  {
560  if (mutt_regex_match(&tmp->regex, pat))
561  return tmp->command;
562  }
563  }
564  return NULL;
565 }
static struct HookList Hooks
Definition: hook.c:75
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
HookFlags type
Hook type.
Definition: hook.c:67
A list of user hooks.
Definition: hook.c:65
char * command
Filename, command or pattern to execute.
Definition: hook.c:69
struct Regex regex
Regular expression.
Definition: hook.c:68
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:609
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_message_hook()

void mutt_message_hook ( struct Mailbox m,
struct Email e,
HookFlags  type 
)

Perform a message hook.

Parameters
mMailbox Context
eEmail
typeHook type, see HookFlags

Definition at line 573 of file hook.c.

574 {
575  struct Hook *hook = NULL;
576  struct PatternCache cache = { 0 };
577  struct Buffer *err = mutt_buffer_pool_get();
578 
579  current_hook_type = type;
580 
581  TAILQ_FOREACH(hook, &Hooks, entries)
582  {
583  if (!hook->command)
584  continue;
585 
586  if (hook->type & type)
587  {
588  if ((mutt_pattern_exec(SLIST_FIRST(hook->pattern), 0, m, e, &cache) > 0) ^
589  hook->regex.pat_not)
590  {
591  if (mutt_parse_rc_line(hook->command, err) == MUTT_CMD_ERROR)
592  {
593  mutt_error("%s", mutt_b2s(err));
596 
597  return;
598  }
599  /* Executing arbitrary commands could affect the pattern results,
600  * so the cache has to be wiped */
601  memset(&cache, 0, sizeof(cache));
602  }
603  }
604  }
606 
608 }
static struct HookList Hooks
Definition: hook.c:75
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
Error: Can&#39;t help the user.
Definition: mutt_commands.h:35
HookFlags type
Hook type.
Definition: hook.c:67
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
static HookFlags current_hook_type
Definition: hook.c:78
String manipulation buffer.
Definition: buffer.h:33
bool pat_not
do not match
Definition: regex3.h:92
A list of user hooks.
Definition: hook.c:65
enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: init.c:1041
char * command
Filename, command or pattern to execute.
Definition: hook.c:69
struct Regex regex
Regular expression.
Definition: hook.c:68
#define mutt_b2s(buf)
Definition: buffer.h:41
#define SLIST_FIRST(head)
Definition: queue.h:228
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:694
#define mutt_error(...)
Definition: logging.h:84
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:44
Cache commonly-used patterns.
Definition: lib.h:102
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:70
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ addr_hook()

static int addr_hook ( char *  path,
size_t  pathlen,
HookFlags  type,
struct Context ctx,
struct Email e 
)
static

Perform an address hook (get a path)

Parameters
pathBuffer for path
pathlenLength of buffer
typeHook type, see HookFlags
ctxMailbox Context
eEmail
Return values
0Success
-1Failure

Definition at line 620 of file hook.c.

622 {
623  struct Hook *hook = NULL;
624  struct PatternCache cache = { 0 };
625 
626  /* determine if a matching hook exists */
627  TAILQ_FOREACH(hook, &Hooks, entries)
628  {
629  if (!hook->command)
630  continue;
631 
632  if (hook->type & type)
633  {
634  struct Mailbox *m = ctx ? ctx->mailbox : NULL;
635  if ((mutt_pattern_exec(SLIST_FIRST(hook->pattern), 0, m, e, &cache) > 0) ^
636  hook->regex.pat_not)
637  {
638  mutt_make_string_flags(path, pathlen, 0, hook->command, m,
639  ctx ? ctx->msg_in_pager : -1, e, MUTT_FORMAT_PLAIN);
640  return 0;
641  }
642  }
643  }
644 
645  return -1;
646 }
static struct HookList Hooks
Definition: hook.c:75
void mutt_make_string_flags(char *buf, size_t buflen, int cols, const char *s, struct Mailbox *m, int inpgr, struct Email *e, MuttFormatFlags flags)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1403
int msg_in_pager
Message currently shown in the pager.
Definition: context.h:44
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
HookFlags type
Hook type.
Definition: hook.c:67
bool pat_not
do not match
Definition: regex3.h:92
A list of user hooks.
Definition: hook.c:65
char * command
Filename, command or pattern to execute.
Definition: hook.c:69
struct Mailbox * mailbox
Definition: context.h:50
struct Regex regex
Regular expression.
Definition: hook.c:68
#define SLIST_FIRST(head)
Definition: queue.h:228
A mailbox.
Definition: mailbox.h:81
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:694
#define MUTT_FORMAT_PLAIN
Do not prepend DISP_TO, DISP_CC ...
Definition: format_flags.h:38
Cache commonly-used patterns.
Definition: lib.h:102
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:70
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_default_save()

void mutt_default_save ( char *  path,
size_t  pathlen,
struct Email e 
)

Find the default save path for an email.

Parameters
pathBuffer for the path
pathlenLength of buffer
eEmail

Definition at line 654 of file hook.c.

655 {
656  *path = '\0';
657  if (addr_hook(path, pathlen, MUTT_SAVE_HOOK, Context, e) == 0)
658  return;
659 
660  struct Envelope *env = e->env;
661  const struct Address *from = TAILQ_FIRST(&env->from);
662  const struct Address *reply_to = TAILQ_FIRST(&env->reply_to);
663  const struct Address *to = TAILQ_FIRST(&env->to);
664  const struct Address *cc = TAILQ_FIRST(&env->cc);
665  const struct Address *addr = NULL;
666  bool from_me = mutt_addr_is_user(from);
667 
668  if (!from_me && reply_to && reply_to->mailbox)
669  addr = reply_to;
670  else if (!from_me && from && from->mailbox)
671  addr = from;
672  else if (to && to->mailbox)
673  addr = to;
674  else if (cc && cc->mailbox)
675  addr = cc;
676  else
677  addr = NULL;
678  if (addr)
679  {
680  struct Buffer *tmp = mutt_buffer_pool_get();
681  mutt_safe_path(tmp, addr);
682  snprintf(path, pathlen, "=%s", mutt_b2s(tmp));
684  }
685 }
The "current" mailbox.
Definition: context.h:38
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define TAILQ_FIRST(head)
Definition: queue.h:716
struct AddressList reply_to
Email&#39;s &#39;reply-to&#39;.
Definition: envelope.h:62
static int addr_hook(char *path, size_t pathlen, HookFlags type, struct Context *ctx, struct Email *e)
Perform an address hook (get a path)
Definition: hook.c:620
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
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct Envelope * env
Envelope information.
Definition: email.h:90
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
void mutt_safe_path(struct Buffer *dest, const struct Address *a)
Make a safe filename from an email address.
Definition: muttlib.c:753
#define mutt_b2s(buf)
Definition: buffer.h:41
#define MUTT_SAVE_HOOK
save-hook: set a default folder when saving an email
Definition: hook.h:49
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition: alias.c:544
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
The header of an Email.
Definition: envelope.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_select_fcc()

void mutt_select_fcc ( struct Buffer path,
struct Email e 
)

Select the FCC path for an email.

Parameters
pathBuffer for the path
eEmail

Definition at line 692 of file hook.c.

693 {
695 
696  if (addr_hook(path->data, path->dsize, MUTT_FCC_HOOK, NULL, e) != 0)
697  {
698  const struct Address *to = TAILQ_FIRST(&e->env->to);
699  const struct Address *cc = TAILQ_FIRST(&e->env->cc);
700  const struct Address *bcc = TAILQ_FIRST(&e->env->bcc);
701  if ((C_SaveName || C_ForceName) && (to || cc || bcc))
702  {
703  const struct Address *addr = to ? to : (cc ? cc : bcc);
704  struct Buffer *buf = mutt_buffer_pool_get();
705  mutt_safe_path(buf, addr);
708  if (!C_ForceName && (mx_access(mutt_b2s(path), W_OK) != 0))
710  }
711  else
713  }
714  else
715  mutt_buffer_fix_dptr(path);
716 
718 }
#define NONULL(x)
Definition: string2.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define TAILQ_FIRST(head)
Definition: queue.h:716
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
static int addr_hook(char *path, size_t pathlen, HookFlags type, struct Context *ctx, struct Email *e)
Perform an address hook (get a path)
Definition: hook.c:620
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
An email address.
Definition: address.h:34
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:598
size_t dsize
Length of data.
Definition: buffer.h:37
struct Envelope * env
Envelope information.
Definition: email.h:90
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
bool C_ForceName
Config: Save outgoing mail in a folder of their name.
Definition: hook.c:59
void mutt_buffer_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:181
void mutt_safe_path(struct Buffer *dest, const struct Address *a)
Make a safe filename from an email address.
Definition: muttlib.c:753
#define mutt_b2s(buf)
Definition: buffer.h:41
#define PATH_MAX
Definition: mutt.h:44
char * data
Pointer to data.
Definition: buffer.h:35
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: mutt_globals.h:96
bool C_SaveName
Config: Save outgoing message to mailbox of recipient&#39;s name if it exists.
Definition: hook.c:60
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
WHERE char * C_Record
Config: Folder to save &#39;sent&#39; messages.
Definition: mutt_globals.h:98
size_t mutt_buffer_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:374
int mx_access(const char *path, int flags)
Wrapper for access, checks permissions on a given mailbox.
Definition: mx.c:183
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define MUTT_FCC_HOOK
fcc-hook: to save outgoing email
Definition: hook.h:48
void mutt_buffer_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:265
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ list_hook()

static void list_hook ( struct ListHead *  matches,
const char *  match,
HookFlags  hook 
)
static

Find hook strings matching.

Parameters
[out]matchesList of hook strings
[in]matchString to match
[in]hookHook type, see HookFlags

Definition at line 726 of file hook.c.

727 {
728  struct Hook *tmp = NULL;
729 
730  TAILQ_FOREACH(tmp, &Hooks, entries)
731  {
732  if ((tmp->type & hook) && mutt_regex_match(&tmp->regex, match))
733  {
735  }
736  }
737 }
static struct HookList Hooks
Definition: hook.c:75
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
HookFlags type
Hook type.
Definition: hook.c:67
A list of user hooks.
Definition: hook.c:65
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
char * command
Filename, command or pattern to execute.
Definition: hook.c:69
struct Regex regex
Regular expression.
Definition: hook.c:68
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:609
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_crypt_hook()

void mutt_crypt_hook ( struct ListHead *  list,
struct Address addr 
)

Find crypto hooks for an Address.

Parameters
[out]listList of keys
[in]addrAddress to match

The crypt-hook associates keys with addresses.

Definition at line 746 of file hook.c.

747 {
748  list_hook(list, addr->mailbox, MUTT_CRYPT_HOOK);
749 }
char * mailbox
Mailbox and host address.
Definition: address.h:37
static void list_hook(struct ListHead *matches, const char *match, HookFlags hook)
Find hook strings matching.
Definition: hook.c:726
#define MUTT_CRYPT_HOOK
crypt-hook: automatically select a PGP/SMIME key
Definition: hook.h:53
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_account_hook()

void mutt_account_hook ( const char *  url)

Perform an account hook.

Parameters
urlAccount URL to match

Definition at line 755 of file hook.c.

756 {
757  /* parsing commands with URLs in an account hook can cause a recursive
758  * call. We just skip processing if this occurs. Typically such commands
759  * belong in a folder-hook -- perhaps we should warn the user. */
760  static bool inhook = false;
761  if (inhook)
762  return;
763 
764  struct Hook *hook = NULL;
765  struct Buffer *err = mutt_buffer_pool_get();
766 
767  TAILQ_FOREACH(hook, &Hooks, entries)
768  {
769  if (!(hook->command && (hook->type & MUTT_ACCOUNT_HOOK)))
770  continue;
771 
772  if (mutt_regex_match(&hook->regex, url))
773  {
774  inhook = true;
775  mutt_debug(LL_DEBUG1, "account-hook '%s' matches '%s'\n", hook->regex.pattern, url);
776  mutt_debug(LL_DEBUG5, " %s\n", hook->command);
777 
778  if (mutt_parse_rc_line(hook->command, err) == MUTT_CMD_ERROR)
779  {
780  mutt_error("%s", mutt_b2s(err));
782 
783  inhook = false;
784  goto done;
785  }
786 
787  inhook = false;
788  }
789  }
790 done:
792 }
static struct HookList Hooks
Definition: hook.c:75
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
Error: Can&#39;t help the user.
Definition: mutt_commands.h:35
HookFlags type
Hook type.
Definition: hook.c:67
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
A list of user hooks.
Definition: hook.c:65
enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: init.c:1041
char * command
Filename, command or pattern to execute.
Definition: hook.c:69
struct Regex regex
Regular expression.
Definition: hook.c:68
#define mutt_b2s(buf)
Definition: buffer.h:41
Log at debug level 1.
Definition: logging.h:40
#define mutt_error(...)
Definition: logging.h:84
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:609
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
char * pattern
printable version
Definition: regex3.h:90
Log at debug level 5.
Definition: logging.h:44
#define MUTT_ACCOUNT_HOOK
account-hook: when changing between accounts
Definition: hook.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_timeout_hook()

void mutt_timeout_hook ( void  )

Execute any timeout hooks.

The user can configure hooks to be run on timeout. This function finds all the matching hooks and executes them.

Definition at line 800 of file hook.c.

801 {
802  struct Hook *hook = NULL;
803  struct Buffer err;
804  char buf[256];
805 
806  mutt_buffer_init(&err);
807  err.data = buf;
808  err.dsize = sizeof(buf);
809 
810  TAILQ_FOREACH(hook, &Hooks, entries)
811  {
812  if (!(hook->command && (hook->type & MUTT_TIMEOUT_HOOK)))
813  continue;
814 
815  if (mutt_parse_rc_line(hook->command, &err) == MUTT_CMD_ERROR)
816  {
817  mutt_error("%s", err.data);
818  mutt_buffer_reset(&err);
819 
820  /* The hooks should be independent of each other, so even though this on
821  * failed, we'll carry on with the others. */
822  }
823  }
824 
825  /* Delete temporary attachment files */
827 }
static struct HookList Hooks
Definition: hook.c:75
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
Error: Can&#39;t help the user.
Definition: mutt_commands.h:35
HookFlags type
Hook type.
Definition: hook.c:67
String manipulation buffer.
Definition: buffer.h:33
A list of user hooks.
Definition: hook.c:65
enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: init.c:1041
void mutt_unlink_temp_attachments(void)
Delete all temporary attachments.
Definition: mutt_attach.c:1258
char * command
Filename, command or pattern to execute.
Definition: hook.c:69
#define MUTT_TIMEOUT_HOOK
timeout-hook: run a command periodically
Definition: hook.h:63
#define mutt_error(...)
Definition: logging.h:84
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_startup_shutdown_hook()

void mutt_startup_shutdown_hook ( HookFlags  type)

Execute any startup/shutdown hooks.

Parameters
typeHook type: MUTT_STARTUP_HOOK or MUTT_SHUTDOWN_HOOK

The user can configure hooks to be run on startup/shutdown. This function finds all the matching hooks and executes them.

Definition at line 836 of file hook.c.

837 {
838  struct Hook *hook = NULL;
839  struct Buffer err = mutt_buffer_make(0);
840  char buf[256];
841 
842  err.data = buf;
843  err.dsize = sizeof(buf);
844 
845  TAILQ_FOREACH(hook, &Hooks, entries)
846  {
847  if (!(hook->command && (hook->type & type)))
848  continue;
849 
850  if (mutt_parse_rc_line(hook->command, &err) == MUTT_CMD_ERROR)
851  {
852  mutt_error("%s", err.data);
853  mutt_buffer_reset(&err);
854  }
855  }
856 }
static struct HookList Hooks
Definition: hook.c:75
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
Error: Can&#39;t help the user.
Definition: mutt_commands.h:35
HookFlags type
Hook type.
Definition: hook.c:67
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
String manipulation buffer.
Definition: buffer.h:33
A list of user hooks.
Definition: hook.c:65
enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: init.c:1041
char * command
Filename, command or pattern to execute.
Definition: hook.c:69
size_t dsize
Length of data.
Definition: buffer.h:37
char * data
Pointer to data.
Definition: buffer.h:35
#define mutt_error(...)
Definition: logging.h:84
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_idxfmt_hook()

const char* mutt_idxfmt_hook ( const char *  name,
struct Mailbox m,
struct Email e 
)

Get index-format-hook format string.

Parameters
nameHook name
mMailbox
eEmail
Return values
ptrprintf(3)-like format string
NULLNo matching hook

Definition at line 866 of file hook.c.

867 {
868  if (!IdxFmtHooks)
869  return NULL;
870 
871  struct HookList *hl = mutt_hash_find(IdxFmtHooks, name);
872  if (!hl)
873  return NULL;
874 
876 
877  struct PatternCache cache = { 0 };
878  const char *fmtstring = NULL;
879  struct Hook *hook = NULL;
880 
881  TAILQ_FOREACH(hook, hl, entries)
882  {
883  struct Pattern *pat = SLIST_FIRST(hook->pattern);
884  if ((mutt_pattern_exec(pat, 0, m, e, &cache) > 0) ^ hook->regex.pat_not)
885  {
886  fmtstring = hook->command;
887  break;
888  }
889  }
890 
892 
893  return fmtstring;
894 }
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
Definition: hash.c:354
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
static HookFlags current_hook_type
Definition: hook.c:78
bool pat_not
do not match
Definition: regex3.h:92
A list of user hooks.
Definition: hook.c:65
#define MUTT_IDXFMTHOOK
index-format-hook: customise the format of the index
Definition: hook.h:62
A simple (non-regex) pattern.
Definition: lib.h:65
char * command
Filename, command or pattern to execute.
Definition: hook.c:69
struct Regex regex
Regular expression.
Definition: hook.c:68
#define SLIST_FIRST(head)
Definition: queue.h:228
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:694
static struct HashTable * IdxFmtHooks
Definition: hook.c:77
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:44
Cache commonly-used patterns.
Definition: lib.h:102
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:70
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_DefaultHook

char* C_DefaultHook

Config: Pattern to use for hooks that only have a simple regex.

Definition at line 58 of file hook.c.

◆ C_ForceName

bool C_ForceName

Config: Save outgoing mail in a folder of their name.

Definition at line 59 of file hook.c.

◆ C_SaveName

bool C_SaveName

Config: Save outgoing message to mailbox of recipient's name if it exists.

Definition at line 60 of file hook.c.

◆ Hooks

struct HookList Hooks = TAILQ_HEAD_INITIALIZER(Hooks)
static

Definition at line 75 of file hook.c.

◆ IdxFmtHooks

struct HashTable* IdxFmtHooks = NULL
static

Definition at line 77 of file hook.c.

◆ current_hook_type

HookFlags current_hook_type = MUTT_HOOK_NO_FLAGS
static

Definition at line 78 of file hook.c.