NeoMutt  2022-04-29-70-g0c028c
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 "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "alias/lib.h"
#include "mutt.h"
#include "hook.h"
#include "attach/lib.h"
#include "index/lib.h"
#include "ncrypt/lib.h"
#include "pattern/lib.h"
#include "format_flags.h"
#include "hdrline.h"
#include "init.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_charset_iconv_hook (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse 'charset-hook' and 'iconv-hook' commands - Implements Command::parse() -. More...
 
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 idxfmt_hashelem_free (int type, void *obj, intptr_t data)
 Delete an 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 Mailbox *m, 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

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
  • Oliver Bandel

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   
)

◆ delete_hook()

static void delete_hook ( struct Hook h)
static

Delete a Hook.

Parameters
hHook to delete

Definition at line 342 of file hook.c.

343 {
344  FREE(&h->command);
345  FREE(&h->regex.pattern);
346  if (h->regex.regex)
347  {
348  regfree(h->regex.regex);
349  FREE(&h->regex.regex);
350  }
352  FREE(&h);
353 }
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: compile.c:1038
#define FREE(x)
Definition: memory.h:40
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:67
struct Regex regex
Regular expression.
Definition: hook.c:65
char * command
Filename, command or pattern to execute.
Definition: hook.c:66
char * pattern
printable version
Definition: regex3.h:90
regex_t * regex
compiled expression
Definition: regex3.h:91
+ 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 361 of file hook.c.

362 {
363  struct Hook *h = NULL;
364  struct Hook *tmp = NULL;
365 
366  TAILQ_FOREACH_SAFE(h, &Hooks, entries, tmp)
367  {
368  if ((type == MUTT_HOOK_NO_FLAGS) || (type == h->type))
369  {
370  TAILQ_REMOVE(&Hooks, h, entries);
371  delete_hook(h);
372  }
373  }
374 }
static struct HookList Hooks
Definition: hook.c:72
static void delete_hook(struct Hook *h)
Delete a Hook.
Definition: hook.c:342
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:37
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:735
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:841
A list of user hooks.
Definition: hook.c:63
HookFlags type
Hook type.
Definition: hook.c:64
+ 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 397 of file hook.c.

398 {
400 }
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:457
static struct HashTable * IdxFmtHooks
Definition: hook.c:74
+ 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 562 of file hook.c.

563 {
564  if (!path && !desc)
565  return;
566 
567  struct Hook *hook = NULL;
568  struct Buffer *err = mutt_buffer_pool_get();
569 
571 
572  TAILQ_FOREACH(hook, &Hooks, entries)
573  {
574  if (!hook->command)
575  continue;
576 
577  if (!(hook->type & MUTT_FOLDER_HOOK))
578  continue;
579 
580  const char *match = NULL;
581  if (mutt_regex_match(&hook->regex, path))
582  match = path;
583  else if (mutt_regex_match(&hook->regex, desc))
584  match = desc;
585 
586  if (match)
587  {
588  mutt_debug(LL_DEBUG1, "folder-hook '%s' matches '%s'\n", hook->regex.pattern, match);
589  mutt_debug(LL_DEBUG5, " %s\n", hook->command);
590  if (mutt_parse_rc_line(hook->command, err) == MUTT_CMD_ERROR)
591  {
592  mutt_error("%s", mutt_buffer_string(err));
593  break;
594  }
595  }
596  }
598 
600 }
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:35
#define mutt_error(...)
Definition: logging.h:87
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
static HookFlags current_hook_type
Definition: hook.c:75
#define MUTT_FOLDER_HOOK
folder-hook: when entering a mailbox
Definition: hook.h:38
enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: init.c:1041
@ LL_DEBUG5
Log at debug level 5.
Definition: logging.h:44
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:631
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
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:725
String manipulation buffer.
Definition: buffer.h:34
+ 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 610 of file hook.c.

611 {
612  struct Hook *tmp = NULL;
613 
614  TAILQ_FOREACH(tmp, &Hooks, entries)
615  {
616  if (tmp->type & type)
617  {
618  if (mutt_regex_match(&tmp->regex, pat))
619  return tmp->command;
620  }
621  }
622  return NULL;
623 }
+ 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
eEmail
typeHook type, see HookFlags

Definition at line 631 of file hook.c.

632 {
633  struct Hook *hook = NULL;
634  struct PatternCache cache = { 0 };
635  struct Buffer *err = mutt_buffer_pool_get();
636 
637  current_hook_type = type;
638 
639  TAILQ_FOREACH(hook, &Hooks, entries)
640  {
641  if (!hook->command)
642  continue;
643 
644  if (hook->type & type)
645  {
646  if ((mutt_pattern_exec(SLIST_FIRST(hook->pattern), 0, m, e, &cache) > 0) ^
647  hook->regex.pat_not)
648  {
649  if (mutt_parse_rc_line(hook->command, err) == MUTT_CMD_ERROR)
650  {
651  mutt_error("%s", mutt_buffer_string(err));
654 
655  return;
656  }
657  /* Executing arbitrary commands could affect the pattern results,
658  * so the cache has to be wiped */
659  memset(&cache, 0, sizeof(cache));
660  }
661  }
662  }
664 
666 }
bool mutt_pattern_exec(struct Pattern *pat, PatternExecFlags flags, struct Mailbox *m, struct Email *e, struct PatternCache *cache)
Match a pattern against an email header.
Definition: exec.c:1107
#define SLIST_FIRST(head)
Definition: queue.h:229
Cache commonly-used patterns.
Definition: lib.h:110
bool pat_not
do not match
Definition: regex3.h:92
+ 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 Mailbox m,
struct Email e 
)
static

Perform an address hook (get a path)

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

Definition at line 678 of file hook.c.

680 {
681  struct Hook *hook = NULL;
682  struct PatternCache cache = { 0 };
683 
684  /* determine if a matching hook exists */
685  TAILQ_FOREACH(hook, &Hooks, entries)
686  {
687  if (!hook->command)
688  continue;
689 
690  if (hook->type & type)
691  {
692  if ((mutt_pattern_exec(SLIST_FIRST(hook->pattern), 0, m, e, &cache) > 0) ^
693  hook->regex.pat_not)
694  {
695  mutt_make_string(path, pathlen, 0, hook->command, m, -1, e, MUTT_FORMAT_PLAIN, NULL);
696  return 0;
697  }
698  }
699  }
700 
701  return -1;
702 }
#define MUTT_FORMAT_PLAIN
Do not prepend DISP_TO, DISP_CC ...
Definition: format_flags.h:38
void mutt_make_string(char *buf, size_t buflen, int cols, const char *s, struct Mailbox *m, int inpgr, struct Email *e, MuttFormatFlags flags, const char *progress)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1405
+ 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 710 of file hook.c.

711 {
712  *path = '\0';
713  struct Mailbox *m_cur = get_current_mailbox();
714  if (addr_hook(path, pathlen, MUTT_SAVE_HOOK, m_cur, e) == 0)
715  return;
716 
717  struct Envelope *env = e->env;
718  const struct Address *from = TAILQ_FIRST(&env->from);
719  const struct Address *reply_to = TAILQ_FIRST(&env->reply_to);
720  const struct Address *to = TAILQ_FIRST(&env->to);
721  const struct Address *cc = TAILQ_FIRST(&env->cc);
722  const struct Address *addr = NULL;
723  bool from_me = mutt_addr_is_user(from);
724 
725  if (!from_me && reply_to && reply_to->mailbox)
726  addr = reply_to;
727  else if (!from_me && from && from->mailbox)
728  addr = from;
729  else if (to && to->mailbox)
730  addr = to;
731  else if (cc && cc->mailbox)
732  addr = cc;
733  else
734  addr = NULL;
735  if (addr)
736  {
737  struct Buffer *tmp = mutt_buffer_pool_get();
738  mutt_safe_path(tmp, addr);
739  snprintf(path, pathlen, "=%s", mutt_buffer_string(tmp));
741  }
742 }
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition: alias.c:573
static int addr_hook(char *path, size_t pathlen, HookFlags type, struct Mailbox *m, struct Email *e)
Perform an address hook (get a path)
Definition: hook.c:678
#define MUTT_SAVE_HOOK
save-hook: set a default folder when saving an email
Definition: hook.h:42
struct Mailbox * get_current_mailbox(void)
Get the current Mailbox.
Definition: index.c:603
void mutt_safe_path(struct Buffer *dest, const struct Address *a)
Make a safe filename from an email address.
Definition: muttlib.c:757
#define TAILQ_FIRST(head)
Definition: queue.h:723
An email address.
Definition: address.h:36
char * mailbox
Mailbox and host address.
Definition: address.h:38
struct Envelope * env
Envelope information.
Definition: email.h:66
The header of an Email.
Definition: envelope.h:57
struct AddressList to
Email's 'To' list.
Definition: envelope.h:60
struct AddressList reply_to
Email's 'reply-to'.
Definition: envelope.h:64
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:61
struct AddressList from
Email's 'From' list.
Definition: envelope.h:59
A mailbox.
Definition: mailbox.h:79
+ 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 749 of file hook.c.

750 {
752 
753  if (addr_hook(path->data, path->dsize, MUTT_FCC_HOOK, NULL, e) != 0)
754  {
755  const struct Address *to = TAILQ_FIRST(&e->env->to);
756  const struct Address *cc = TAILQ_FIRST(&e->env->cc);
757  const struct Address *bcc = TAILQ_FIRST(&e->env->bcc);
758  const bool c_save_name = cs_subset_bool(NeoMutt->sub, "save_name");
759  const bool c_force_name = cs_subset_bool(NeoMutt->sub, "force_name");
760  const char *const c_record = cs_subset_string(NeoMutt->sub, "record");
761  if ((c_save_name || c_force_name) && (to || cc || bcc))
762  {
763  const struct Address *addr = to ? to : (cc ? cc : bcc);
764  struct Buffer *buf = mutt_buffer_pool_get();
765  mutt_safe_path(buf, addr);
766  const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
767  mutt_buffer_concat_path(path, NONULL(c_folder), mutt_buffer_string(buf));
769  if (!c_force_name && (mx_access(mutt_buffer_string(path), W_OK) != 0))
770  mutt_buffer_strcpy(path, c_record);
771  }
772  else
773  mutt_buffer_strcpy(path, c_record);
774  }
775  else
776  mutt_buffer_fix_dptr(path);
777 
779 }
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
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
void mutt_buffer_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:181
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
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
#define MUTT_FCC_HOOK
fcc-hook: to save outgoing email
Definition: hook.h:41
#define PATH_MAX
Definition: mutt.h:40
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:598
int mx_access(const char *path, int flags)
Wrapper for access, checks permissions on a given mailbox.
Definition: mx.c:184
#define NONULL(x)
Definition: string2.h:37
size_t dsize
Length of data.
Definition: buffer.h:37
char * data
Pointer to data.
Definition: buffer.h:35
struct AddressList bcc
Email's 'Bcc' list.
Definition: envelope.h:62
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ 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 787 of file hook.c.

788 {
789  struct Hook *tmp = NULL;
790 
791  TAILQ_FOREACH(tmp, &Hooks, entries)
792  {
793  if ((tmp->type & hook) && mutt_regex_match(&tmp->regex, match))
794  {
796  }
797  }
798 }
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
+ 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 807 of file hook.c.

808 {
809  list_hook(list, addr->mailbox, MUTT_CRYPT_HOOK);
810 }
static void list_hook(struct ListHead *matches, const char *match, HookFlags hook)
Find hook strings matching.
Definition: hook.c:787
#define MUTT_CRYPT_HOOK
crypt-hook: automatically select a PGP/SMIME key
Definition: hook.h:46
+ 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 816 of file hook.c.

817 {
818  /* parsing commands with URLs in an account hook can cause a recursive
819  * call. We just skip processing if this occurs. Typically such commands
820  * belong in a folder-hook -- perhaps we should warn the user. */
821  static bool inhook = false;
822  if (inhook)
823  return;
824 
825  struct Hook *hook = NULL;
826  struct Buffer *err = mutt_buffer_pool_get();
827 
828  TAILQ_FOREACH(hook, &Hooks, entries)
829  {
830  if (!(hook->command && (hook->type & MUTT_ACCOUNT_HOOK)))
831  continue;
832 
833  if (mutt_regex_match(&hook->regex, url))
834  {
835  inhook = true;
836  mutt_debug(LL_DEBUG1, "account-hook '%s' matches '%s'\n", hook->regex.pattern, url);
837  mutt_debug(LL_DEBUG5, " %s\n", hook->command);
838 
839  if (mutt_parse_rc_line(hook->command, err) == MUTT_CMD_ERROR)
840  {
841  mutt_error("%s", mutt_buffer_string(err));
843 
844  inhook = false;
845  goto done;
846  }
847 
848  inhook = false;
849  }
850  }
851 done:
853 }
#define MUTT_ACCOUNT_HOOK
account-hook: when changing between accounts
Definition: hook.h:47
+ 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 861 of file hook.c.

862 {
863  struct Hook *hook = NULL;
864  struct Buffer err;
865  char buf[256];
866 
867  mutt_buffer_init(&err);
868  err.data = buf;
869  err.dsize = sizeof(buf);
870 
871  TAILQ_FOREACH(hook, &Hooks, entries)
872  {
873  if (!(hook->command && (hook->type & MUTT_TIMEOUT_HOOK)))
874  continue;
875 
876  if (mutt_parse_rc_line(hook->command, &err) == MUTT_CMD_ERROR)
877  {
878  mutt_error("%s", err.data);
879  mutt_buffer_reset(&err);
880 
881  /* The hooks should be independent of each other, so even though this on
882  * failed, we'll carry on with the others. */
883  }
884  }
885 
886  /* Delete temporary attachment files */
888 }
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
#define MUTT_TIMEOUT_HOOK
timeout-hook: run a command periodically
Definition: hook.h:56
void mutt_unlink_temp_attachments(void)
Delete all temporary attachments.
Definition: mutt_attach.c:1301
+ 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 897 of file hook.c.

898 {
899  struct Hook *hook = NULL;
900  struct Buffer err = mutt_buffer_make(0);
901  char buf[256];
902 
903  err.data = buf;
904  err.dsize = sizeof(buf);
905 
906  TAILQ_FOREACH(hook, &Hooks, entries)
907  {
908  if (!(hook->command && (hook->type & type)))
909  continue;
910 
911  if (mutt_parse_rc_line(hook->command, &err) == MUTT_CMD_ERROR)
912  {
913  mutt_error("%s", err.data);
914  mutt_buffer_reset(&err);
915  }
916  }
917 }
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
+ 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 927 of file hook.c.

928 {
929  if (!IdxFmtHooks)
930  return NULL;
931 
932  struct HookList *hl = mutt_hash_find(IdxFmtHooks, name);
933  if (!hl)
934  return NULL;
935 
937 
938  struct PatternCache cache = { 0 };
939  const char *fmtstring = NULL;
940  struct Hook *hook = NULL;
941 
942  TAILQ_FOREACH(hook, hl, entries)
943  {
944  struct Pattern *pat = SLIST_FIRST(hook->pattern);
945  if ((mutt_pattern_exec(pat, 0, m, e, &cache) > 0) ^ hook->regex.pat_not)
946  {
947  fmtstring = hook->command;
948  break;
949  }
950  }
951 
953 
954  return fmtstring;
955 }
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:362
#define MUTT_IDXFMTHOOK
index-format-hook: customise the format of the index
Definition: hook.h:55
A simple (non-regex) pattern.
Definition: lib.h:70
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ Hooks

struct HookList Hooks = TAILQ_HEAD_INITIALIZER(Hooks)
static

Definition at line 70 of file hook.c.

◆ IdxFmtHooks

struct HashTable* IdxFmtHooks = NULL
static

Definition at line 74 of file hook.c.

◆ current_hook_type

HookFlags current_hook_type = MUTT_HOOK_NO_FLAGS
static

Definition at line 75 of file hook.c.