NeoMutt  2020-03-20-65-g141838
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 <regex.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 "mutt.h"
#include "hook.h"
#include "alias.h"
#include "context.h"
#include "format_flags.h"
#include "globals.h"
#include "hdrline.h"
#include "init.h"
#include "mutt_attach.h"
#include "mutt_commands.h"
#include "muttlib.h"
#include "mx.h"
#include "pattern.h"
#include "ncrypt/lib.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 hashelem_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 HashIdxFmtHooks = 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 86 of file hook.c.

88 {
89  struct Hook *hook = NULL;
90  int rc = MUTT_CMD_ERROR;
91  bool pat_not = false;
92  regex_t *rx = NULL;
93  struct PatternList *pat = NULL;
94 
95  struct Buffer *cmd = mutt_buffer_pool_get();
96  struct Buffer *pattern = mutt_buffer_pool_get();
97 
98  if (~data & MUTT_GLOBAL_HOOK) /* NOT a global hook */
99  {
100  if (*s->dptr == '!')
101  {
102  s->dptr++;
103  SKIPWS(s->dptr);
104  pat_not = true;
105  }
106 
108 
109  if (!MoreArgs(s))
110  {
111  mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
112  rc = MUTT_CMD_WARNING;
113  goto cleanup;
114  }
115  }
116 
117  mutt_extract_token(cmd, s,
122 
123  if (mutt_buffer_is_empty(cmd))
124  {
125  mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
126  rc = MUTT_CMD_WARNING;
127  goto cleanup;
128  }
129 
130  if (MoreArgs(s))
131  {
132  mutt_buffer_printf(err, _("%s: too many arguments"), buf->data);
133  rc = MUTT_CMD_WARNING;
134  goto cleanup;
135  }
136 
138  {
139  /* Accidentally using the ^ mailbox shortcut in the .neomuttrc is a
140  * common mistake */
141  if ((pattern->data[0] == '^') && !CurrentFolder)
142  {
143  mutt_buffer_strcpy(err, _("current mailbox shortcut '^' is unset"));
144  goto cleanup;
145  }
146 
147  struct Buffer *tmp = mutt_buffer_pool_get();
148  mutt_buffer_copy(tmp, pattern);
150 
151  /* Check for other mailbox shortcuts that expand to the empty string.
152  * This is likely a mistake too */
153  if (mutt_buffer_is_empty(tmp) && !mutt_buffer_is_empty(pattern))
154  {
155  mutt_buffer_strcpy(err, _("mailbox shortcut expanded to empty regex"));
157  goto cleanup;
158  }
159 
160  mutt_buffer_copy(pattern, tmp);
162  }
163 #ifdef USE_COMP_MBOX
165  {
166  if (mutt_comp_valid_command(mutt_b2s(cmd)) == 0)
167  {
168  mutt_buffer_strcpy(err, _("badly formatted command string"));
169  goto cleanup;
170  }
171  }
172 #endif
173  else if (C_DefaultHook && (~data & MUTT_GLOBAL_HOOK) &&
175  (!WithCrypto || !(data & MUTT_CRYPT_HOOK)))
176  {
177  /* At this stage remain only message-hooks, reply-hooks, send-hooks,
178  * send2-hooks, save-hooks, and fcc-hooks: All those allowing full
179  * patterns. If given a simple regex, we expand $default_hook. */
181  }
182 
184  {
186  }
187 
188  /* check to make sure that a matching hook doesn't already exist */
189  TAILQ_FOREACH(hook, &Hooks, entries)
190  {
191  if (data & MUTT_GLOBAL_HOOK)
192  {
193  /* Ignore duplicate global hooks */
194  if (mutt_str_strcmp(hook->command, mutt_b2s(cmd)) == 0)
195  {
196  rc = MUTT_CMD_SUCCESS;
197  goto cleanup;
198  }
199  }
200  else if ((hook->type == data) && (hook->regex.pat_not == pat_not) &&
201  (mutt_str_strcmp(mutt_b2s(pattern), hook->regex.pattern) == 0))
202  {
204  MUTT_ACCOUNT_HOOK | MUTT_REPLY_HOOK | MUTT_CRYPT_HOOK |
206  {
207  /* these hooks allow multiple commands with the same
208  * pattern, so if we've already seen this pattern/command pair, just
209  * ignore it instead of creating a duplicate */
210  if (mutt_str_strcmp(hook->command, mutt_b2s(cmd)) == 0)
211  {
212  rc = MUTT_CMD_SUCCESS;
213  goto cleanup;
214  }
215  }
216  else
217  {
218  /* other hooks only allow one command per pattern, so update the
219  * entry with the new command. this currently does not change the
220  * order of execution of the hooks, which i think is desirable since
221  * a common action to perform is to change the default (.) entry
222  * based upon some other information. */
223  FREE(&hook->command);
224  hook->command = mutt_buffer_strdup(cmd);
225  rc = MUTT_CMD_SUCCESS;
226  goto cleanup;
227  }
228  }
229  }
230 
232  {
233  /* These are managed separately by the charset code */
235  if (mutt_ch_lookup_add(type, mutt_b2s(pattern), mutt_b2s(cmd), err))
236  rc = MUTT_CMD_SUCCESS;
237  goto cleanup;
238  }
241  {
242  PatternCompFlags comp_flags;
243 
244  if (data & (MUTT_SEND2_HOOK))
245  comp_flags = MUTT_PC_SEND_MODE_SEARCH;
246  else if (data & (MUTT_SEND_HOOK | MUTT_FCC_HOOK))
247  comp_flags = MUTT_PC_NO_FLAGS;
248  else
249  comp_flags = MUTT_PC_FULL_MSG;
250 
251  pat = mutt_pattern_comp(mutt_b2s(pattern), comp_flags, err);
252  if (!pat)
253  goto cleanup;
254  }
255  else if (~data & MUTT_GLOBAL_HOOK) /* NOT a global hook */
256  {
257  /* Hooks not allowing full patterns: Check syntax of regex */
258  rx = mutt_mem_malloc(sizeof(regex_t));
259  int rc2 = REG_COMP(rx, NONULL(mutt_b2s(pattern)),
260  ((data & MUTT_CRYPT_HOOK) ? REG_ICASE : 0));
261  if (rc2 != 0)
262  {
263  regerror(rc2, rx, err->data, err->dsize);
264  FREE(&rx);
265  goto cleanup;
266  }
267  }
268 
269  hook = mutt_mem_calloc(1, sizeof(struct Hook));
270  hook->type = data;
271  hook->command = mutt_buffer_strdup(cmd);
272  hook->pattern = pat;
273  hook->regex.pattern = mutt_buffer_strdup(pattern);
274  hook->regex.regex = rx;
275  hook->regex.pat_not = pat_not;
276  TAILQ_INSERT_TAIL(&Hooks, hook, entries);
277  rc = MUTT_CMD_SUCCESS;
278 
279 cleanup:
281  mutt_buffer_pool_release(&pattern);
282  return rc;
283 }
#define MUTT_SEND_HOOK
send-hook: when composing a new email
Definition: hook.h:47
Character set conversion.
Definition: charset.h:78
static struct HookList Hooks
Definition: hook.c:76
#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:163
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:68
void mutt_check_simple(struct Buffer *buf, const char *simple)
Convert a simple search into a real request.
Definition: pattern.c:2423
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:90
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:91
A list of user hooks.
Definition: hook.c:66
#define _(a)
Definition: message.h:28
#define MUTT_CHARSET_HOOK
charset-hook: create a charset alias for malformed emails
Definition: hook.h:50
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:52
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:479
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:145
char * command
Filename, command or pattern to execute.
Definition: hook.c:70
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
LookupType
Types of character set lookups.
Definition: charset.h:75
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:52
#define SKIPWS(ch)
Definition: string2.h:47
WHERE char * CurrentFolder
Currently selected mailbox.
Definition: globals.h:54
struct Regex regex
Regular expression.
Definition: hook.c:69
#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
#define mutt_b2s(buf)
Definition: buffer.h:41
struct PatternList * mutt_pattern_comp(const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: pattern.c:1436
#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:416
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
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:328
#define MUTT_PC_NO_FLAGS
No flags are set.
Definition: pattern.h:42
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
#define MUTT_REPLY_HOOK
reply-hook: when replying to an email
Definition: hook.h:55
#define MUTT_PC_SEND_MODE_SEARCH
Allow send-mode body searching.
Definition: pattern.h:45
#define FREE(x)
Definition: memory.h:40
#define MUTT_PC_FULL_MSG
Enable body and header matching.
Definition: pattern.h:43
uint8_t PatternCompFlags
Flags for mutt_pattern_comp(), e.g. MUTT_PC_FULL_MSG.
Definition: pattern.h:41
char * C_DefaultHook
Config: Pattern to use for hooks that only have a simple regex.
Definition: hook.c:59
char * pattern
printable version
Definition: regex3.h:89
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
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
Alias for another character set.
Definition: charset.h:77
#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:71
#define MUTT_ACCOUNT_HOOK
account-hook: when changing between accounts
Definition: hook.h:54
#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 289 of file hook.c.

290 {
291  FREE(&h->command);
292  FREE(&h->regex.pattern);
293  if (h->regex.regex)
294  {
295  regfree(h->regex.regex);
296  FREE(&h->regex.regex);
297  }
299  FREE(&h);
300 }
regex_t * regex
compiled expression
Definition: regex3.h:90
char * command
Filename, command or pattern to execute.
Definition: hook.c:70
struct Regex regex
Regular expression.
Definition: hook.c:69
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: pattern.c:1384
#define FREE(x)
Definition: memory.h:40
char * pattern
printable version
Definition: regex3.h:89
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:71
+ 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 308 of file hook.c.

309 {
310  struct Hook *h = NULL;
311  struct Hook *tmp = NULL;
312 
313  TAILQ_FOREACH_SAFE(h, &Hooks, entries, tmp)
314  {
315  if ((type == MUTT_HOOK_NO_FLAGS) || (type == h->type))
316  {
317  TAILQ_REMOVE(&Hooks, h, entries);
318  delete_hook(h);
319  }
320  }
321 }
static struct HookList Hooks
Definition: hook.c:76
HookFlags type
Hook type.
Definition: hook.c:68
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:728
A list of user hooks.
Definition: hook.c:66
#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:289
+ 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 hashelem_free_t.

Parameters
typeType of Hash Element
objPointer to Hashed object
dataPrivate data

Definition at line 329 of file hook.c.

330 {
331  struct HookList *hl = obj;
332  struct Hook *h = NULL;
333  struct Hook *tmp = NULL;
334 
335  TAILQ_FOREACH_SAFE(h, hl, entries, tmp)
336  {
337  TAILQ_REMOVE(hl, h, entries);
338  delete_hook(h);
339  }
340 
341  FREE(&hl);
342 }
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:728
A list of user hooks.
Definition: hook.c:66
#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:289
+ 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 347 of file hook.c.

348 {
350 }
static struct Hash * IdxFmtHooks
Definition: hook.c:78
void mutt_hash_free(struct Hash **ptr)
Free a hash table.
Definition: hash.c:471
+ 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 355 of file hook.c.

357 {
358  enum CommandResult rc = MUTT_CMD_ERROR;
359  bool pat_not = false;
360 
361  struct Buffer *name = mutt_buffer_pool_get();
362  struct Buffer *pattern = mutt_buffer_pool_get();
363  struct Buffer *fmtstring = mutt_buffer_pool_get();
364 
365  if (!IdxFmtHooks)
366  {
369  }
370 
371  if (!MoreArgs(s))
372  {
373  mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
374  goto out;
375  }
377  struct HookList *hl = mutt_hash_find(IdxFmtHooks, mutt_b2s(name));
378 
379  if (*s->dptr == '!')
380  {
381  s->dptr++;
382  SKIPWS(s->dptr);
383  pat_not = true;
384  }
386 
387  if (!MoreArgs(s))
388  {
389  mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
390  goto out;
391  }
393 
394  if (MoreArgs(s))
395  {
396  mutt_buffer_printf(err, _("%s: too many arguments"), buf->data);
397  goto out;
398  }
399 
400  if (C_DefaultHook)
402 
403  /* check to make sure that a matching hook doesn't already exist */
404  struct Hook *hook = NULL;
405  if (hl)
406  {
407  TAILQ_FOREACH(hook, hl, entries)
408  {
409  if ((hook->regex.pat_not == pat_not) &&
410  (mutt_str_strcmp(mutt_b2s(pattern), hook->regex.pattern) == 0))
411  {
412  mutt_str_replace(&hook->command, mutt_b2s(fmtstring));
413  rc = MUTT_CMD_SUCCESS;
414  goto out;
415  }
416  }
417  }
418 
419  /* MUTT_PC_PATTERN_DYNAMIC sets so that date ranges are regenerated during
420  * matching. This of course is slower, but index-format-hook is commonly
421  * used for date ranges, and they need to be evaluated relative to "now", not
422  * the hook compilation time. */
423  struct PatternList *pat = mutt_pattern_comp(
425  if (!pat)
426  goto out;
427 
428  hook = mutt_mem_calloc(1, sizeof(struct Hook));
429  hook->type = data;
430  hook->command = mutt_buffer_strdup(fmtstring);
431  hook->pattern = pat;
432  hook->regex.pattern = mutt_buffer_strdup(pattern);
433  hook->regex.regex = NULL;
434  hook->regex.pat_not = pat_not;
435 
436  if (!hl)
437  {
438  hl = mutt_mem_calloc(1, sizeof(*hl));
439  TAILQ_INIT(hl);
441  }
442 
443  TAILQ_INSERT_TAIL(hl, hook, entries);
444  rc = MUTT_CMD_SUCCESS;
445 
446 out:
448  mutt_buffer_pool_release(&pattern);
449  mutt_buffer_pool_release(&fmtstring);
450 
451  return rc;
452 }
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:68
void mutt_check_simple(struct Buffer *buf, const char *simple)
Convert a simple search into a real request.
Definition: pattern.c:2423
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:90
void * mutt_hash_find(const struct Hash *table, const char *strkey)
Find the HashElem data in a Hash table element using a key.
Definition: hash.c:378
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:91
A list of user hooks.
Definition: hook.c:66
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
char * command
Filename, command or pattern to execute.
Definition: hook.c:70
#define MUTT_PC_PATTERN_DYNAMIC
Enable runtime date range evaluation.
Definition: pattern.h:44
#define MoreArgs(buf)
Definition: buffer.h:43
const char * name
Definition: pgpmicalg.c:46
#define SKIPWS(ch)
Definition: string2.h:47
#define TAILQ_INIT(head)
Definition: queue.h:758
struct Regex regex
Regular expression.
Definition: hook.c:69
static void delete_idxfmt_hooklist(int type, void *obj, intptr_t data)
Delete a index-format-hook from the Hash Table - Implements hashelem_free_t.
Definition: hook.c:329
#define mutt_b2s(buf)
Definition: buffer.h:41
struct PatternList * mutt_pattern_comp(const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: pattern.c:1436
static struct Hash * IdxFmtHooks
Definition: hook.c:78
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:416
char * dptr
Current read/write position.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:35
struct Hash * mutt_hash_new(size_t nelem, HashFlags flags)
Create a new Hash table (with string keys)
Definition: hash.c:275
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:802
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
Success: Command worked.
Definition: mutt_commands.h:37
#define MUTT_PC_FULL_MSG
Enable body and header matching.
Definition: pattern.h:43
void mutt_hash_set_destructor(struct Hash *table, hashelem_free_t fn, intptr_t fn_data)
Set the destructor for a Hash Table.
Definition: hash.c:317
char * C_DefaultHook
Config: Pattern to use for hooks that only have a simple regex.
Definition: hook.c:59
char * pattern
printable version
Definition: regex3.h:89
#define MUTT_HASH_STRDUP_KEYS
make a copy of the keys
Definition: hash.h:76
struct HashElem * mutt_hash_insert(struct Hash *table, const char *strkey, void *data)
Add a new element to the Hash table (with string keys)
Definition: hash.c:351
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:71
#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 457 of file hook.c.

459 {
460  while (MoreArgs(s))
461  {
463  if (mutt_str_strcmp("*", buf->data) == 0)
464  {
466  {
467  mutt_buffer_printf(err, "%s", _("unhook: Can't do unhook * from within a hook"));
468  return MUTT_CMD_WARNING;
469  }
473  }
474  else
475  {
476  HookFlags type = mutt_get_hook_type(buf->data);
477 
478  if (type == MUTT_HOOK_NO_FLAGS)
479  {
480  mutt_buffer_printf(err, _("unhook: unknown hook type: %s"), buf->data);
481  return MUTT_CMD_ERROR;
482  }
483  if (type & (MUTT_CHARSET_HOOK | MUTT_ICONV_HOOK))
484  {
486  return MUTT_CMD_SUCCESS;
487  }
488  if (current_hook_type == type)
489  {
490  mutt_buffer_printf(err, _("unhook: Can't delete a %s from within a %s"),
491  buf->data, buf->data);
492  return MUTT_CMD_WARNING;
493  }
494  if (type == MUTT_IDXFMTHOOK)
496  else
497  mutt_delete_hooks(type);
498  }
499  }
500  return MUTT_CMD_SUCCESS;
501 }
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:347
HookFlags mutt_get_hook_type(const char *name)
Find a hook by name.
Definition: init.c:715
static HookFlags current_hook_type
Definition: hook.c:79
#define _(a)
Definition: message.h:28
void mutt_delete_hooks(HookFlags type)
Delete matching hooks.
Definition: hook.c:308
#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
#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:416
char * data
Pointer to data.
Definition: buffer.h:35
void mutt_ch_lookup_remove(void)
Remove all the character set lookups.
Definition: charset.c:511
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
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
#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 508 of file hook.c.

509 {
510  if (!path && !desc)
511  return;
512 
513  struct Hook *hook = NULL;
514  struct Buffer *err = mutt_buffer_pool_get();
515  struct Buffer *token = mutt_buffer_pool_get();
516 
518 
519  TAILQ_FOREACH(hook, &Hooks, entries)
520  {
521  if (!hook->command)
522  continue;
523 
524  if (!(hook->type & MUTT_FOLDER_HOOK))
525  continue;
526 
527  const char *match = NULL;
528  if (mutt_regex_match(&hook->regex, path))
529  match = path;
530  else if (mutt_regex_match(&hook->regex, desc))
531  match = desc;
532 
533  if (match)
534  {
535  mutt_debug(LL_DEBUG1, "folder-hook '%s' matches '%s'\n", hook->regex.pattern, match);
536  mutt_debug(LL_DEBUG5, " %s\n", hook->command);
537  if (mutt_parse_rc_line(hook->command, token, err) == MUTT_CMD_ERROR)
538  {
539  mutt_error("%s", mutt_b2s(err));
540  break;
541  }
542  }
543  }
544  mutt_buffer_pool_release(&token);
546 
548 }
static struct HookList Hooks
Definition: hook.c:76
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:68
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:79
String manipulation buffer.
Definition: buffer.h:33
A list of user hooks.
Definition: hook.c:66
char * command
Filename, command or pattern to execute.
Definition: hook.c:70
struct Regex regex
Regular expression.
Definition: hook.c:69
#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:610
#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:89
Log at debug level 5.
Definition: logging.h:44
enum CommandResult mutt_parse_rc_line(char *line, struct Buffer *token, struct Buffer *err)
Parse a line of user config.
Definition: init.c:991
#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 558 of file hook.c.

559 {
560  struct Hook *tmp = NULL;
561 
562  TAILQ_FOREACH(tmp, &Hooks, entries)
563  {
564  if (tmp->type & type)
565  {
566  if (mutt_regex_match(&tmp->regex, pat))
567  return tmp->command;
568  }
569  }
570  return NULL;
571 }
static struct HookList Hooks
Definition: hook.c:76
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
HookFlags type
Hook type.
Definition: hook.c:68
A list of user hooks.
Definition: hook.c:66
char * command
Filename, command or pattern to execute.
Definition: hook.c:70
struct Regex regex
Regular expression.
Definition: hook.c:69
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:610
+ 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 579 of file hook.c.

580 {
581  struct Hook *hook = NULL;
582  struct PatternCache cache = { 0 };
583  struct Buffer *err = mutt_buffer_pool_get();
584  struct Buffer *token = mutt_buffer_pool_get();
585 
586  current_hook_type = type;
587 
588  TAILQ_FOREACH(hook, &Hooks, entries)
589  {
590  if (!hook->command)
591  continue;
592 
593  if (hook->type & type)
594  {
595  if ((mutt_pattern_exec(SLIST_FIRST(hook->pattern), 0, m, e, &cache) > 0) ^
596  hook->regex.pat_not)
597  {
598  if (mutt_parse_rc_line(hook->command, token, err) == MUTT_CMD_ERROR)
599  {
600  mutt_buffer_pool_release(&token);
601  mutt_error("%s", mutt_b2s(err));
604 
605  return;
606  }
607  /* Executing arbitrary commands could affect the pattern results,
608  * so the cache has to be wiped */
609  memset(&cache, 0, sizeof(cache));
610  }
611  }
612  }
613  mutt_buffer_pool_release(&token);
615 
617 }
static struct HookList Hooks
Definition: hook.c:76
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:68
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:79
String manipulation buffer.
Definition: buffer.h:33
bool pat_not
do not match
Definition: regex3.h:91
A list of user hooks.
Definition: hook.c:66
char * command
Filename, command or pattern to execute.
Definition: hook.c:70
struct Regex regex
Regular expression.
Definition: hook.c:69
#define mutt_b2s(buf)
Definition: buffer.h:41
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: pattern.c:2122
#define SLIST_FIRST(head)
Definition: queue.h:228
#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: pattern.h:87
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:71
enum CommandResult mutt_parse_rc_line(char *line, struct Buffer *token, struct Buffer *err)
Parse a line of user config.
Definition: init.c:991
+ 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 629 of file hook.c.

631 {
632  struct Hook *hook = NULL;
633  struct PatternCache cache = { 0 };
634 
635  /* determine if a matching hook exists */
636  TAILQ_FOREACH(hook, &Hooks, entries)
637  {
638  if (!hook->command)
639  continue;
640 
641  if (hook->type & type)
642  {
643  struct Mailbox *m = ctx ? ctx->mailbox : NULL;
644  if ((mutt_pattern_exec(SLIST_FIRST(hook->pattern), 0, m, e, &cache) > 0) ^
645  hook->regex.pat_not)
646  {
647  mutt_make_string_flags(path, pathlen, 0, hook->command, ctx, m, e, MUTT_FORMAT_PLAIN);
648  return 0;
649  }
650  }
651  }
652 
653  return -1;
654 }
static struct HookList Hooks
Definition: hook.c:76
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
HookFlags type
Hook type.
Definition: hook.c:68
bool pat_not
do not match
Definition: regex3.h:91
A list of user hooks.
Definition: hook.c:66
char * command
Filename, command or pattern to execute.
Definition: hook.c:70
struct Mailbox * mailbox
Definition: context.h:51
void mutt_make_string_flags(char *buf, size_t buflen, int cols, const char *s, struct Context *ctx, struct Mailbox *m, struct Email *e, MuttFormatFlags flags)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1505
struct Regex regex
Regular expression.
Definition: hook.c:69
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: pattern.c:2122
#define SLIST_FIRST(head)
Definition: queue.h:228
A mailbox.
Definition: mailbox.h:81
#define MUTT_FORMAT_PLAIN
Do not prepend DISP_TO, DISP_CC ...
Definition: format_flags.h:38
Cache commonly-used patterns.
Definition: pattern.h:87
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:71
+ 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 662 of file hook.c.

663 {
664  *path = '\0';
665  if (addr_hook(path, pathlen, MUTT_SAVE_HOOK, Context, e) == 0)
666  return;
667 
668  struct Envelope *env = e->env;
669  const struct Address *from = TAILQ_FIRST(&env->from);
670  const struct Address *reply_to = TAILQ_FIRST(&env->reply_to);
671  const struct Address *to = TAILQ_FIRST(&env->to);
672  const struct Address *cc = TAILQ_FIRST(&env->cc);
673  const struct Address *addr = NULL;
674  bool from_me = mutt_addr_is_user(from);
675 
676  if (!from_me && reply_to && reply_to->mailbox)
677  addr = reply_to;
678  else if (!from_me && from && from->mailbox)
679  addr = from;
680  else if (to && to->mailbox)
681  addr = to;
682  else if (cc && cc->mailbox)
683  addr = cc;
684  else
685  addr = NULL;
686  if (addr)
687  {
688  struct Buffer *tmp = mutt_buffer_pool_get();
689  mutt_safe_path(tmp, addr);
690  snprintf(path, pathlen, "=%s", mutt_b2s(tmp));
692  }
693 }
The "current" mailbox.
Definition: context.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 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:629
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:89
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:844
#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:686
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 700 of file hook.c.

701 {
703 
704  if (addr_hook(path->data, path->dsize, MUTT_FCC_HOOK, NULL, e) != 0)
705  {
706  const struct Address *to = TAILQ_FIRST(&e->env->to);
707  const struct Address *cc = TAILQ_FIRST(&e->env->cc);
708  const struct Address *bcc = TAILQ_FIRST(&e->env->bcc);
709  if ((C_SaveName || C_ForceName) && (to || cc || bcc))
710  {
711  const struct Address *addr = to ? to : (cc ? cc : bcc);
712  struct Buffer *buf = mutt_buffer_pool_get();
713  mutt_safe_path(buf, addr);
716  if (!C_ForceName && (mx_access(mutt_b2s(path), W_OK) != 0))
718  }
719  else
721  }
722  else
723  mutt_buffer_fix_dptr(path);
724 
726 }
#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:629
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
WHERE char * C_Record
Config: Folder to save &#39;sent&#39; messages.
Definition: globals.h:132
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:689
size_t dsize
Length of data.
Definition: buffer.h:37
struct Envelope * env
Envelope information.
Definition: email.h:89
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:60
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:844
#define mutt_b2s(buf)
Definition: buffer.h:41
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: globals.h:121
#define PATH_MAX
Definition: mutt.h:44
char * data
Pointer to data.
Definition: buffer.h:35
bool C_SaveName
Config: Save outgoing message to mailbox of recipient&#39;s name if it exists.
Definition: hook.c:61
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
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:171
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 734 of file hook.c.

735 {
736  struct Hook *tmp = NULL;
737 
738  TAILQ_FOREACH(tmp, &Hooks, entries)
739  {
740  if ((tmp->type & hook) && mutt_regex_match(&tmp->regex, match))
741  {
743  }
744  }
745 }
static struct HookList Hooks
Definition: hook.c:76
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
HookFlags type
Hook type.
Definition: hook.c:68
A list of user hooks.
Definition: hook.c:66
char * command
Filename, command or pattern to execute.
Definition: hook.c:70
struct Regex regex
Regular expression.
Definition: hook.c:69
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:65
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:610
+ 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 754 of file hook.c.

755 {
756  list_hook(list, addr->mailbox, MUTT_CRYPT_HOOK);
757 }
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:734
#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 764 of file hook.c.

765 {
766  /* parsing commands with URLs in an account hook can cause a recursive
767  * call. We just skip processing if this occurs. Typically such commands
768  * belong in a folder-hook -- perhaps we should warn the user. */
769  static bool inhook = false;
770  if (inhook)
771  return;
772 
773  struct Hook *hook = NULL;
774  struct Buffer *err = mutt_buffer_pool_get();
775  struct Buffer *token = mutt_buffer_pool_get();
776 
777  TAILQ_FOREACH(hook, &Hooks, entries)
778  {
779  if (!(hook->command && (hook->type & MUTT_ACCOUNT_HOOK)))
780  continue;
781 
782  if (mutt_regex_match(&hook->regex, url))
783  {
784  inhook = true;
785  mutt_debug(LL_DEBUG1, "account-hook '%s' matches '%s'\n", hook->regex.pattern, url);
786  mutt_debug(LL_DEBUG5, " %s\n", hook->command);
787 
788  if (mutt_parse_rc_line(hook->command, token, err) == MUTT_CMD_ERROR)
789  {
790  mutt_buffer_pool_release(&token);
791  mutt_error("%s", mutt_b2s(err));
793 
794  inhook = false;
795  goto done;
796  }
797 
798  inhook = false;
799  }
800  }
801 done:
802  mutt_buffer_pool_release(&token);
804 }
static struct HookList Hooks
Definition: hook.c:76
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:68
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:66
char * command
Filename, command or pattern to execute.
Definition: hook.c:70
struct Regex regex
Regular expression.
Definition: hook.c:69
#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:610
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
char * pattern
printable version
Definition: regex3.h:89
Log at debug level 5.
Definition: logging.h:44
enum CommandResult mutt_parse_rc_line(char *line, struct Buffer *token, struct Buffer *err)
Parse a line of user config.
Definition: init.c:991
#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 813 of file hook.c.

814 {
815  struct Hook *hook = NULL;
816  struct Buffer token;
817  struct Buffer err;
818  char buf[256];
819 
820  mutt_buffer_init(&err);
821  err.data = buf;
822  err.dsize = sizeof(buf);
823  mutt_buffer_init(&token);
824 
825  TAILQ_FOREACH(hook, &Hooks, entries)
826  {
827  if (!(hook->command && (hook->type & MUTT_TIMEOUT_HOOK)))
828  continue;
829 
830  if (mutt_parse_rc_line(hook->command, &token, &err) == MUTT_CMD_ERROR)
831  {
832  mutt_error("%s", err.data);
833  mutt_buffer_reset(&err);
834 
835  /* The hooks should be independent of each other, so even though this on
836  * failed, we'll carry on with the others. */
837  }
838  }
839  FREE(&token.data);
840 
841  /* Delete temporary attachment files */
843 }
static struct HookList Hooks
Definition: hook.c:76
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:68
String manipulation buffer.
Definition: buffer.h:33
A list of user hooks.
Definition: hook.c:66
void mutt_unlink_temp_attachments(void)
Delete all temporary attachments.
Definition: mutt_attach.c:1230
char * command
Filename, command or pattern to execute.
Definition: hook.c:70
#define MUTT_TIMEOUT_HOOK
timeout-hook: run a command periodically
Definition: hook.h:63
#define mutt_error(...)
Definition: logging.h:84
#define FREE(x)
Definition: memory.h:40
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
enum CommandResult mutt_parse_rc_line(char *line, struct Buffer *token, struct Buffer *err)
Parse a line of user config.
Definition: init.c:991
+ 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 852 of file hook.c.

853 {
854  struct Hook *hook = NULL;
855  struct Buffer token = mutt_buffer_make(0);
856  struct Buffer err = mutt_buffer_make(0);
857  char buf[256];
858 
859  err.data = buf;
860  err.dsize = sizeof(buf);
861  mutt_buffer_init(&token);
862 
863  TAILQ_FOREACH(hook, &Hooks, entries)
864  {
865  if (!(hook->command && (hook->type & type)))
866  continue;
867 
868  if (mutt_parse_rc_line(hook->command, &token, &err) == MUTT_CMD_ERROR)
869  {
870  mutt_error("%s", err.data);
871  mutt_buffer_reset(&err);
872  }
873  }
874  FREE(&token.data);
875 }
static struct HookList Hooks
Definition: hook.c:76
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:68
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:66
char * command
Filename, command or pattern to execute.
Definition: hook.c:70
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
#define FREE(x)
Definition: memory.h:40
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
enum CommandResult mutt_parse_rc_line(char *line, struct Buffer *token, struct Buffer *err)
Parse a line of user config.
Definition: init.c:991
+ 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 885 of file hook.c.

886 {
887  if (!IdxFmtHooks)
888  return NULL;
889 
890  struct HookList *hl = mutt_hash_find(IdxFmtHooks, name);
891  if (!hl)
892  return NULL;
893 
895 
896  struct PatternCache cache = { 0 };
897  const char *fmtstring = NULL;
898  struct Hook *hook = NULL;
899 
900  TAILQ_FOREACH(hook, hl, entries)
901  {
902  struct Pattern *pat = SLIST_FIRST(hook->pattern);
903  if ((mutt_pattern_exec(pat, 0, m, e, &cache) > 0) ^ hook->regex.pat_not)
904  {
905  fmtstring = hook->command;
906  break;
907  }
908  }
909 
911 
912  return fmtstring;
913 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
void * mutt_hash_find(const struct Hash *table, const char *strkey)
Find the HashElem data in a Hash table element using a key.
Definition: hash.c:378
static HookFlags current_hook_type
Definition: hook.c:79
bool pat_not
do not match
Definition: regex3.h:91
A list of user hooks.
Definition: hook.c:66
#define MUTT_IDXFMTHOOK
index-format-hook: customise the format of the index
Definition: hook.h:62
A simple (non-regex) pattern.
Definition: pattern.h:50
char * command
Filename, command or pattern to execute.
Definition: hook.c:70
const char * name
Definition: pgpmicalg.c:46
struct Regex regex
Regular expression.
Definition: hook.c:69
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: pattern.c:2122
static struct Hash * IdxFmtHooks
Definition: hook.c:78
#define SLIST_FIRST(head)
Definition: queue.h:228
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:44
Cache commonly-used patterns.
Definition: pattern.h:87
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:71
+ 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 59 of file hook.c.

◆ C_ForceName

bool C_ForceName

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

Definition at line 60 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 61 of file hook.c.

◆ Hooks

struct HookList Hooks = TAILQ_HEAD_INITIALIZER(Hooks)
static

Definition at line 76 of file hook.c.

◆ IdxFmtHooks

struct Hash* IdxFmtHooks = NULL
static

Definition at line 78 of file hook.c.

◆ current_hook_type

HookFlags current_hook_type = MUTT_HOOK_NO_FLAGS
static

Definition at line 79 of file hook.c.