NeoMutt  2021-10-22-8-g9cb437
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 "ncrypt/lib.h"
#include "pattern/lib.h"
#include "context.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_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

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 308 of file hook.c.

309 {
310  FREE(&h->command);
311  FREE(&h->regex.pattern);
312  if (h->regex.regex)
313  {
314  regfree(h->regex.regex);
315  FREE(&h->regex.regex);
316  }
318  FREE(&h);
319 }
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:66
struct Regex regex
Regular expression.
Definition: hook.c:64
char * command
Filename, command or pattern to execute.
Definition: hook.c:65
char * pattern
printable version
Definition: regex3.h:91
regex_t * regex
compiled expression
Definition: regex3.h:92
+ 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 327 of file hook.c.

328 {
329  struct Hook *h = NULL;
330  struct Hook *tmp = NULL;
331 
332  TAILQ_FOREACH_SAFE(h, &Hooks, entries, tmp)
333  {
334  if ((type == MUTT_HOOK_NO_FLAGS) || (type == h->type))
335  {
336  TAILQ_REMOVE(&Hooks, h, entries);
337  delete_hook(h);
338  }
339  }
340 }
static struct HookList Hooks
Definition: hook.c:71
static void delete_hook(struct Hook *h)
Delete a Hook.
Definition: hook.c:308
#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:62
HookFlags type
Hook type.
Definition: hook.c:63
+ 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 363 of file hook.c.

364 {
366 }
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:449
static struct HashTable * IdxFmtHooks
Definition: hook.c:73
+ 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 528 of file hook.c.

529 {
530  if (!path && !desc)
531  return;
532 
533  struct Hook *hook = NULL;
534  struct Buffer *err = mutt_buffer_pool_get();
535 
537 
538  TAILQ_FOREACH(hook, &Hooks, entries)
539  {
540  if (!hook->command)
541  continue;
542 
543  if (!(hook->type & MUTT_FOLDER_HOOK))
544  continue;
545 
546  const char *match = NULL;
547  if (mutt_regex_match(&hook->regex, path))
548  match = path;
549  else if (mutt_regex_match(&hook->regex, desc))
550  match = desc;
551 
552  if (match)
553  {
554  mutt_debug(LL_DEBUG1, "folder-hook '%s' matches '%s'\n", hook->regex.pattern, match);
555  mutt_debug(LL_DEBUG5, " %s\n", hook->command);
556  if (mutt_parse_rc_line(hook->command, err) == MUTT_CMD_ERROR)
557  {
558  mutt_error("%s", mutt_buffer_string(err));
559  break;
560  }
561  }
562  }
564 
566 }
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:74
#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:1043
@ 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:613
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 576 of file hook.c.

577 {
578  struct Hook *tmp = NULL;
579 
580  TAILQ_FOREACH(tmp, &Hooks, entries)
581  {
582  if (tmp->type & type)
583  {
584  if (mutt_regex_match(&tmp->regex, pat))
585  return tmp->command;
586  }
587  }
588  return NULL;
589 }
+ 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 597 of file hook.c.

598 {
599  struct Hook *hook = NULL;
600  struct PatternCache cache = { 0 };
601  struct Buffer *err = mutt_buffer_pool_get();
602 
603  current_hook_type = type;
604 
605  TAILQ_FOREACH(hook, &Hooks, entries)
606  {
607  if (!hook->command)
608  continue;
609 
610  if (hook->type & type)
611  {
612  if ((mutt_pattern_exec(SLIST_FIRST(hook->pattern), 0, m, e, &cache) > 0) ^
613  hook->regex.pat_not)
614  {
615  if (mutt_parse_rc_line(hook->command, err) == MUTT_CMD_ERROR)
616  {
617  mutt_error("%s", mutt_buffer_string(err));
620 
621  return;
622  }
623  /* Executing arbitrary commands could affect the pattern results,
624  * so the cache has to be wiped */
625  memset(&cache, 0, sizeof(cache));
626  }
627  }
628  }
630 
632 }
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:1099
#define SLIST_FIRST(head)
Definition: queue.h:229
Cache commonly-used patterns.
Definition: lib.h:106
bool pat_not
do not match
Definition: regex3.h:93
+ 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 644 of file hook.c.

646 {
647  struct Hook *hook = NULL;
648  struct PatternCache cache = { 0 };
649 
650  /* determine if a matching hook exists */
651  TAILQ_FOREACH(hook, &Hooks, entries)
652  {
653  if (!hook->command)
654  continue;
655 
656  if (hook->type & type)
657  {
658  if ((mutt_pattern_exec(SLIST_FIRST(hook->pattern), 0, m, e, &cache) > 0) ^
659  hook->regex.pat_not)
660  {
661  mutt_make_string(path, pathlen, 0, hook->command, m, -1, e, MUTT_FORMAT_PLAIN, NULL);
662  return 0;
663  }
664  }
665  }
666 
667  return -1;
668 }
#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:1410
+ 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 676 of file hook.c.

677 {
678  *path = '\0';
679  if (addr_hook(path, pathlen, MUTT_SAVE_HOOK, ctx_mailbox(Context), e) == 0)
680  return;
681 
682  struct Envelope *env = e->env;
683  const struct Address *from = TAILQ_FIRST(&env->from);
684  const struct Address *reply_to = TAILQ_FIRST(&env->reply_to);
685  const struct Address *to = TAILQ_FIRST(&env->to);
686  const struct Address *cc = TAILQ_FIRST(&env->cc);
687  const struct Address *addr = NULL;
688  bool from_me = mutt_addr_is_user(from);
689 
690  if (!from_me && reply_to && reply_to->mailbox)
691  addr = reply_to;
692  else if (!from_me && from && from->mailbox)
693  addr = from;
694  else if (to && to->mailbox)
695  addr = to;
696  else if (cc && cc->mailbox)
697  addr = cc;
698  else
699  addr = NULL;
700  if (addr)
701  {
702  struct Buffer *tmp = mutt_buffer_pool_get();
703  mutt_safe_path(tmp, addr);
704  snprintf(path, pathlen, "=%s", mutt_buffer_string(tmp));
706  }
707 }
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition: alias.c:562
struct Mailbox * ctx_mailbox(struct Context *ctx)
Wrapper to get the mailbox in a Context, or NULL.
Definition: context.c:444
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:644
#define MUTT_SAVE_HOOK
save-hook: set a default folder when saving an email
Definition: hook.h:42
void mutt_safe_path(struct Buffer *dest, const struct Address *a)
Make a safe filename from an email address.
Definition: muttlib.c:761
#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
The "current" mailbox.
Definition: context.h:38
struct Envelope * env
Envelope information.
Definition: email.h:66
The header of an Email.
Definition: envelope.h:55
struct AddressList to
Email's 'To' list.
Definition: envelope.h:58
struct AddressList reply_to
Email's 'reply-to'.
Definition: envelope.h:62
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:59
struct AddressList from
Email's 'From' list.
Definition: envelope.h:57
+ 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 714 of file hook.c.

715 {
717 
718  if (addr_hook(path->data, path->dsize, MUTT_FCC_HOOK, NULL, e) != 0)
719  {
720  const struct Address *to = TAILQ_FIRST(&e->env->to);
721  const struct Address *cc = TAILQ_FIRST(&e->env->cc);
722  const struct Address *bcc = TAILQ_FIRST(&e->env->bcc);
723  const bool c_save_name = cs_subset_bool(NeoMutt->sub, "save_name");
724  const bool c_force_name = cs_subset_bool(NeoMutt->sub, "force_name");
725  const char *const c_record = cs_subset_string(NeoMutt->sub, "record");
726  if ((c_save_name || c_force_name) && (to || cc || bcc))
727  {
728  const struct Address *addr = to ? to : (cc ? cc : bcc);
729  struct Buffer *buf = mutt_buffer_pool_get();
730  mutt_safe_path(buf, addr);
731  const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
732  mutt_buffer_concat_path(path, NONULL(c_folder), mutt_buffer_string(buf));
734  if (!c_force_name && (mx_access(mutt_buffer_string(path), W_OK) != 0))
735  mutt_buffer_strcpy(path, c_record);
736  }
737  else
738  mutt_buffer_strcpy(path, c_record);
739  }
740  else
741  mutt_buffer_fix_dptr(path);
742 
744 }
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:603
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:60
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 752 of file hook.c.

753 {
754  struct Hook *tmp = NULL;
755 
756  TAILQ_FOREACH(tmp, &Hooks, entries)
757  {
758  if ((tmp->type & hook) && mutt_regex_match(&tmp->regex, match))
759  {
761  }
762  }
763 }
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:370
+ 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 772 of file hook.c.

773 {
774  list_hook(list, addr->mailbox, MUTT_CRYPT_HOOK);
775 }
static void list_hook(struct ListHead *matches, const char *match, HookFlags hook)
Find hook strings matching.
Definition: hook.c:752
#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 781 of file hook.c.

782 {
783  /* parsing commands with URLs in an account hook can cause a recursive
784  * call. We just skip processing if this occurs. Typically such commands
785  * belong in a folder-hook -- perhaps we should warn the user. */
786  static bool inhook = false;
787  if (inhook)
788  return;
789 
790  struct Hook *hook = NULL;
791  struct Buffer *err = mutt_buffer_pool_get();
792 
793  TAILQ_FOREACH(hook, &Hooks, entries)
794  {
795  if (!(hook->command && (hook->type & MUTT_ACCOUNT_HOOK)))
796  continue;
797 
798  if (mutt_regex_match(&hook->regex, url))
799  {
800  inhook = true;
801  mutt_debug(LL_DEBUG1, "account-hook '%s' matches '%s'\n", hook->regex.pattern, url);
802  mutt_debug(LL_DEBUG5, " %s\n", hook->command);
803 
804  if (mutt_parse_rc_line(hook->command, err) == MUTT_CMD_ERROR)
805  {
806  mutt_error("%s", mutt_buffer_string(err));
808 
809  inhook = false;
810  goto done;
811  }
812 
813  inhook = false;
814  }
815  }
816 done:
818 }
#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 826 of file hook.c.

827 {
828  struct Hook *hook = NULL;
829  struct Buffer err;
830  char buf[256];
831 
832  mutt_buffer_init(&err);
833  err.data = buf;
834  err.dsize = sizeof(buf);
835 
836  TAILQ_FOREACH(hook, &Hooks, entries)
837  {
838  if (!(hook->command && (hook->type & MUTT_TIMEOUT_HOOK)))
839  continue;
840 
841  if (mutt_parse_rc_line(hook->command, &err) == MUTT_CMD_ERROR)
842  {
843  mutt_error("%s", err.data);
844  mutt_buffer_reset(&err);
845 
846  /* The hooks should be independent of each other, so even though this on
847  * failed, we'll carry on with the others. */
848  }
849  }
850 
851  /* Delete temporary attachment files */
853 }
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:1285
+ 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 862 of file hook.c.

863 {
864  struct Hook *hook = NULL;
865  struct Buffer err = mutt_buffer_make(0);
866  char buf[256];
867 
868  err.data = buf;
869  err.dsize = sizeof(buf);
870 
871  TAILQ_FOREACH(hook, &Hooks, entries)
872  {
873  if (!(hook->command && (hook->type & type)))
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  }
882 }
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 892 of file hook.c.

893 {
894  if (!IdxFmtHooks)
895  return NULL;
896 
897  struct HookList *hl = mutt_hash_find(IdxFmtHooks, name);
898  if (!hl)
899  return NULL;
900 
902 
903  struct PatternCache cache = { 0 };
904  const char *fmtstring = NULL;
905  struct Hook *hook = NULL;
906 
907  TAILQ_FOREACH(hook, hl, entries)
908  {
909  struct Pattern *pat = SLIST_FIRST(hook->pattern);
910  if ((mutt_pattern_exec(pat, 0, m, e, &cache) > 0) ^ hook->regex.pat_not)
911  {
912  fmtstring = hook->command;
913  break;
914  }
915  }
916 
918 
919  return fmtstring;
920 }
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 MUTT_IDXFMTHOOK
index-format-hook: customise the format of the index
Definition: hook.h:55
A simple (non-regex) pattern.
Definition: lib.h:69
+ 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 69 of file hook.c.

◆ IdxFmtHooks

struct HashTable* IdxFmtHooks = NULL
static

Definition at line 73 of file hook.c.

◆ current_hook_type

HookFlags current_hook_type = MUTT_HOOK_NO_FLAGS
static

Definition at line 74 of file hook.c.