NeoMutt  2024-04-25-127-g771158
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
hook.c File Reference

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

#include "config.h"
#include <limits.h>
#include <stdbool.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 "hook.h"
#include "attach/lib.h"
#include "compmbox/lib.h"
#include "expando/lib.h"
#include "index/lib.h"
#include "ncrypt/lib.h"
#include "parse/lib.h"
#include "pattern/lib.h"
#include "commands.h"
#include "globals.h"
#include "hdrline.h"
#include "muttlib.h"
#include "mx.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)
 
static void hook_free (struct Hook **ptr)
 Free a Hook.
 
static struct Hookhook_new (void)
 Create a 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() -.
 
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() -.
 
void mutt_delete_hooks (HookFlags type)
 Delete matching hooks.
 
static void idxfmt_hashelem_free (int type, void *obj, intptr_t data)
 Free our hash table data - Implements hash_hdata_free_t -.
 
static void delete_idxfmt_hooks (void)
 Delete all the index-format-hooks.
 
static 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() -.
 
static HookFlags mutt_get_hook_type (const char *name)
 Find a hook by name.
 
static enum CommandResult mutt_parse_unhook (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unhook' command - Implements Command::parse() -.
 
void mutt_folder_hook (const char *path, const char *desc)
 Perform a folder hook.
 
char * mutt_find_hook (HookFlags type, const char *pat)
 Find a matching hook.
 
void mutt_message_hook (struct Mailbox *m, struct Email *e, HookFlags type)
 Perform a message hook.
 
static int addr_hook (struct Buffer *path, HookFlags type, struct Mailbox *m, struct Email *e)
 Perform an address hook (get a path)
 
void mutt_default_save (struct Buffer *path, struct Email *e)
 Find the default save path for an email.
 
void mutt_select_fcc (struct Buffer *path, struct Email *e)
 Select the FCC path for an email.
 
static void list_hook (struct ListHead *matches, const char *match, HookFlags type)
 Find hook strings matching.
 
void mutt_crypt_hook (struct ListHead *list, struct Address *addr)
 Find crypto hooks for an Address.
 
void mutt_account_hook (const char *url)
 Perform an account hook.
 
void mutt_timeout_hook (void)
 Execute any timeout hooks.
 
void mutt_startup_shutdown_hook (HookFlags type)
 Execute any startup/shutdown hooks.
 
const struct Expandomutt_idxfmt_hook (const char *name, struct Mailbox *m, struct Email *e)
 Get index-format-hook format string.
 
void hooks_init (void)
 Setup feature commands.
 

Variables

const struct ExpandoDefinition IndexFormatDef []
 Expando definitions.
 
static struct HookList Hooks = TAILQ_HEAD_INITIALIZER(Hooks)
 All simple hooks, e.g. MUTT_FOLDER_HOOK.
 
static struct HashTableIdxFmtHooks = NULL
 All Index Format hooks.
 
static HookFlags CurrentHookType = MUTT_HOOK_NO_FLAGS
 The type of the hook currently being executed, e.g. MUTT_SAVE_HOOK.
 
static const struct Command HookCommands []
 Hook Commands.
 

Detailed Description

Parse and execute user-defined hooks.

Authors
  • Michael R. Elkins, and others
  • Thomas Adam
  • Richard Russon
  • Pietro Cerutti
  • Federico Kircheis
  • Naveen Nathan
  • Oliver Bandel
  • Dennis Schön
  • Tóth János

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   
)

◆ hook_free()

static void hook_free ( struct Hook **  ptr)
static

Free a Hook.

Parameters
ptrHook to free

Definition at line 92 of file hook.c.

93{
94 if (!ptr || !*ptr)
95 return;
96
97 struct Hook *h = *ptr;
98
99 FREE(&h->command);
100 FREE(&h->source_file);
101 FREE(&h->regex.pattern);
102 if (h->regex.regex)
103 {
104 regfree(h->regex.regex);
105 FREE(&h->regex.regex);
106 }
109 FREE(ptr);
110}
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: compile.c:778
void expando_free(struct Expando **ptr)
Free an Expando object.
Definition: expando.c:54
#define FREE(x)
Definition: memory.h:45
A list of user hooks.
Definition: hook.c:68
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:73
struct Regex regex
Regular expression.
Definition: hook.c:70
char * command
Filename, command or pattern to execute.
Definition: hook.c:71
struct Expando * expando
Used for format hooks.
Definition: hook.c:74
char * source_file
Used for relative-directory source.
Definition: hook.c:72
char * pattern
printable version
Definition: regex3.h:86
regex_t * regex
compiled expression
Definition: regex3.h:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ hook_new()

static struct Hook * hook_new ( void  )
static

Create a Hook.

Return values
ptrNew Hook

Definition at line 116 of file hook.c.

117{
118 return mutt_mem_calloc(1, sizeof(struct Hook));
119}
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
+ 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 MUTT_HOOK_NO_FLAGS is passed, all the hooks will be deleted.

Definition at line 391 of file hook.c.

392{
393 struct Hook *h = NULL;
394 struct Hook *tmp = NULL;
395
396 TAILQ_FOREACH_SAFE(h, &Hooks, entries, tmp)
397 {
398 if ((type == MUTT_HOOK_NO_FLAGS) || (type == h->type))
399 {
400 TAILQ_REMOVE(&Hooks, h, entries);
401 hook_free(&h);
402 }
403 }
404}
static void hook_free(struct Hook **ptr)
Free a Hook.
Definition: hook.c:92
static struct HookList Hooks
All simple hooks, e.g. MUTT_FOLDER_HOOK.
Definition: hook.c:80
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:36
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:735
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:841
HookFlags type
Hook type.
Definition: hook.c:69
+ 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 427 of file hook.c.

428{
430}
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:457
static struct HashTable * IdxFmtHooks
All Index Format hooks.
Definition: hook.c:83
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_get_hook_type()

static HookFlags mutt_get_hook_type ( const char *  name)
static

Find a hook by name.

Parameters
nameName to find
Return values
numHook ID, e.g. MUTT_FOLDER_HOOK
MUTT_HOOK_NO_FLAGSError, no matching hook

Definition at line 555 of file hook.c.

556{
557 struct Command *c = NULL;
558 for (size_t i = 0, size = commands_array(&c); i < size; i++)
559 {
560 if (((c[i].parse == mutt_parse_hook) || (c[i].parse == mutt_parse_idxfmt_hook)) &&
562 {
563 return c[i].data;
564 }
565 }
566 return MUTT_HOOK_NO_FLAGS;
567}
size_t commands_array(struct Command **first)
Get Commands array.
Definition: command.c:75
static 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: hook.c:435
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() -.
Definition: hook.c:167
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:672
enum CommandResult(* parse)(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Definition: command.h:65
intptr_t data
Data or flags to pass to the command.
Definition: command.h:67
const char * name
Name of the command.
Definition: command.h:52
+ Here is the call graph for this function:
+ Here is the caller 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 623 of file hook.c.

624{
625 if (!path && !desc)
626 return;
627
628 struct Hook *hook = NULL;
629 struct Buffer *err = buf_pool_get();
630
632
633 TAILQ_FOREACH(hook, &Hooks, entries)
634 {
635 if (!hook->command)
636 continue;
637
638 if (!(hook->type & MUTT_FOLDER_HOOK))
639 continue;
640
641 const char *match = NULL;
642 if (mutt_regex_match(&hook->regex, path))
643 match = path;
644 else if (mutt_regex_match(&hook->regex, desc))
645 match = desc;
646
647 if (match)
648 {
649 mutt_debug(LL_DEBUG1, "folder-hook '%s' matches '%s'\n", hook->regex.pattern, match);
650 mutt_debug(LL_DEBUG5, " %s\n", hook->command);
651 if (parse_rc_line_cwd(hook->command, hook->source_file, err) == MUTT_CMD_ERROR)
652 {
653 mutt_error("%s", buf_string(err));
654 break;
655 }
656 }
657 }
658 buf_pool_release(&err);
659
661}
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:37
enum CommandResult parse_rc_line_cwd(const char *line, char *cwd, struct Buffer *err)
Parse and run a muttrc line in a relative directory.
Definition: commands.c:165
#define mutt_error(...)
Definition: logging2.h:92
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
static HookFlags CurrentHookType
The type of the hook currently being executed, e.g. MUTT_SAVE_HOOK.
Definition: hook.c:86
#define MUTT_FOLDER_HOOK
folder-hook: when entering a mailbox
Definition: hook.h:37
@ LL_DEBUG5
Log at debug level 5.
Definition: logging2.h:47
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:614
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
String manipulation buffer.
Definition: buffer.h:36
+ 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 671 of file hook.c.

672{
673 struct Hook *tmp = NULL;
674
675 TAILQ_FOREACH(tmp, &Hooks, entries)
676 {
677 if (tmp->type & type)
678 {
679 if (mutt_regex_match(&tmp->regex, pat))
680 return tmp->command;
681 }
682 }
683 return NULL;
684}
+ 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 692 of file hook.c.

693{
694 struct Hook *hook = NULL;
695 struct PatternCache cache = { 0 };
696 struct Buffer *err = buf_pool_get();
697
698 CurrentHookType = type;
699
700 TAILQ_FOREACH(hook, &Hooks, entries)
701 {
702 if (!hook->command)
703 continue;
704
705 if (hook->type & type)
706 {
707 if ((mutt_pattern_exec(SLIST_FIRST(hook->pattern), 0, m, e, &cache) > 0) ^
708 hook->regex.pat_not)
709 {
710 if (parse_rc_line_cwd(hook->command, hook->source_file, err) == MUTT_CMD_ERROR)
711 {
712 mutt_error("%s", buf_string(err));
714 buf_pool_release(&err);
715
716 return;
717 }
718 /* Executing arbitrary commands could affect the pattern results,
719 * so the cache has to be wiped */
720 memset(&cache, 0, sizeof(cache));
721 }
722 }
723 }
724 buf_pool_release(&err);
725
727}
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:1149
#define SLIST_FIRST(head)
Definition: queue.h:229
Cache commonly-used patterns.
Definition: lib.h:117
bool pat_not
do not match
Definition: regex3.h:88
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ addr_hook()

static int addr_hook ( struct Buffer path,
HookFlags  type,
struct Mailbox m,
struct Email e 
)
static

Perform an address hook (get a path)

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

Definition at line 738 of file hook.c.

739{
740 struct Hook *hook = NULL;
741 struct PatternCache cache = { 0 };
742
743 /* determine if a matching hook exists */
744 TAILQ_FOREACH(hook, &Hooks, entries)
745 {
746 if (!hook->command)
747 continue;
748
749 if (hook->type & type)
750 {
751 if ((mutt_pattern_exec(SLIST_FIRST(hook->pattern), 0, m, e, &cache) > 0) ^
752 hook->regex.pat_not)
753 {
754 buf_alloc(path, PATH_MAX);
755 mutt_make_string(path, -1, hook->expando, m, -1, e, MUTT_FORMAT_PLAIN, NULL);
756 buf_fix_dptr(path);
757 return 0;
758 }
759 }
760 }
761
762 return -1;
763}
void buf_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:182
void buf_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:337
int mutt_make_string(struct Buffer *buf, size_t max_cols, const struct Expando *exp, struct Mailbox *m, int inpgr, struct Email *e, MuttFormatFlags flags, const char *progress)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1730
#define PATH_MAX
Definition: mutt.h:42
#define MUTT_FORMAT_PLAIN
Do not prepend DISP_TO, DISP_CC ...
Definition: render.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_default_save()

void mutt_default_save ( struct Buffer path,
struct Email e 
)

Find the default save path for an email.

Parameters
pathBuffer for the path
eEmail

Definition at line 770 of file hook.c.

771{
772 struct Mailbox *m_cur = get_current_mailbox();
773 if (addr_hook(path, MUTT_SAVE_HOOK, m_cur, e) == 0)
774 return;
775
776 struct Envelope *env = e->env;
777 const struct Address *from = TAILQ_FIRST(&env->from);
778 const struct Address *reply_to = TAILQ_FIRST(&env->reply_to);
779 const struct Address *to = TAILQ_FIRST(&env->to);
780 const struct Address *cc = TAILQ_FIRST(&env->cc);
781 const struct Address *addr = NULL;
782 bool from_me = mutt_addr_is_user(from);
783
784 if (!from_me && reply_to && reply_to->mailbox)
785 addr = reply_to;
786 else if (!from_me && from && from->mailbox)
787 addr = from;
788 else if (to && to->mailbox)
789 addr = to;
790 else if (cc && cc->mailbox)
791 addr = cc;
792 else
793 addr = NULL;
794 if (addr)
795 {
796 struct Buffer *tmp = buf_pool_get();
797 mutt_safe_path(tmp, addr);
798 buf_add_printf(path, "=%s", buf_string(tmp));
799 buf_pool_release(&tmp);
800 }
801}
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition: alias.c:600
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:204
static int addr_hook(struct Buffer *path, HookFlags type, struct Mailbox *m, struct Email *e)
Perform an address hook (get a path)
Definition: hook.c:738
#define MUTT_SAVE_HOOK
save-hook: set a default folder when saving an email
Definition: hook.h:41
struct Mailbox * get_current_mailbox(void)
Get the current Mailbox.
Definition: index.c:715
void mutt_safe_path(struct Buffer *dest, const struct Address *a)
Make a safe filename from an email address.
Definition: muttlib.c:683
#define TAILQ_FIRST(head)
Definition: queue.h:723
An email address.
Definition: address.h:36
struct Buffer * mailbox
Mailbox and host address.
Definition: address.h:38
struct Envelope * env
Envelope information.
Definition: email.h:68
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 808 of file hook.c.

809{
810 buf_alloc(path, PATH_MAX);
811
812 if (addr_hook(path, MUTT_FCC_HOOK, NULL, e) != 0)
813 {
814 const struct Address *to = TAILQ_FIRST(&e->env->to);
815 const struct Address *cc = TAILQ_FIRST(&e->env->cc);
816 const struct Address *bcc = TAILQ_FIRST(&e->env->bcc);
817 const bool c_save_name = cs_subset_bool(NeoMutt->sub, "save_name");
818 const bool c_force_name = cs_subset_bool(NeoMutt->sub, "force_name");
819 const char *const c_record = cs_subset_string(NeoMutt->sub, "record");
820 if ((c_save_name || c_force_name) && (to || cc || bcc))
821 {
822 const struct Address *addr = to ? to : (cc ? cc : bcc);
823 struct Buffer *buf = buf_pool_get();
824 mutt_safe_path(buf, addr);
825 const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
826 buf_concat_path(path, NONULL(c_folder), buf_string(buf));
827 buf_pool_release(&buf);
828 if (!c_force_name && (mx_access(buf_string(path), W_OK) != 0))
829 buf_strcpy(path, c_record);
830 }
831 else
832 {
833 buf_strcpy(path, c_record);
834 }
835 }
836 else
837 {
838 buf_fix_dptr(path);
839 }
840
841 buf_pretty_mailbox(path);
842}
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:395
size_t buf_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:509
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:291
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:47
#define MUTT_FCC_HOOK
fcc-hook: to save outgoing email
Definition: hook.h:40
void buf_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:519
int mx_access(const char *path, int flags)
Wrapper for access, checks permissions on a given mailbox.
Definition: mx.c:170
#define NONULL(x)
Definition: string2.h:37
struct AddressList bcc
Email's 'Bcc' list.
Definition: envelope.h:62
Container for Accounts, Notifications.
Definition: neomutt.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:46
+ 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  type 
)
static

Find hook strings matching.

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

Definition at line 850 of file hook.c.

851{
852 struct Hook *tmp = NULL;
853
854 TAILQ_FOREACH(tmp, &Hooks, entries)
855 {
856 if ((tmp->type & type) && mutt_regex_match(&tmp->regex, match))
857 {
859 }
860 }
861}
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_dup(const char *str)
Copy a string, safely.
Definition: string.c:253
+ 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 870 of file hook.c.

871{
873}
static void list_hook(struct ListHead *matches, const char *match, HookFlags type)
Find hook strings matching.
Definition: hook.c:850
#define MUTT_CRYPT_HOOK
crypt-hook: automatically select a PGP/SMIME key
Definition: hook.h:45
+ 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 879 of file hook.c.

880{
881 /* parsing commands with URLs in an account hook can cause a recursive
882 * call. We just skip processing if this occurs. Typically such commands
883 * belong in a folder-hook -- perhaps we should warn the user. */
884 static bool inhook = false;
885 if (inhook)
886 return;
887
888 struct Hook *hook = NULL;
889 struct Buffer *err = buf_pool_get();
890
891 TAILQ_FOREACH(hook, &Hooks, entries)
892 {
893 if (!(hook->command && (hook->type & MUTT_ACCOUNT_HOOK)))
894 continue;
895
896 if (mutt_regex_match(&hook->regex, url))
897 {
898 inhook = true;
899 mutt_debug(LL_DEBUG1, "account-hook '%s' matches '%s'\n", hook->regex.pattern, url);
900 mutt_debug(LL_DEBUG5, " %s\n", hook->command);
901
902 if (parse_rc_line_cwd(hook->command, hook->source_file, err) == MUTT_CMD_ERROR)
903 {
904 mutt_error("%s", buf_string(err));
905 buf_pool_release(&err);
906
907 inhook = false;
908 goto done;
909 }
910
911 inhook = false;
912 }
913 }
914done:
915 buf_pool_release(&err);
916}
#define MUTT_ACCOUNT_HOOK
account-hook: when changing between accounts
Definition: hook.h:46
+ 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 924 of file hook.c.

925{
926 struct Hook *hook = NULL;
927 struct Buffer *err = buf_pool_get();
928
929 TAILQ_FOREACH(hook, &Hooks, entries)
930 {
931 if (!(hook->command && (hook->type & MUTT_TIMEOUT_HOOK)))
932 continue;
933
934 if (parse_rc_line_cwd(hook->command, hook->source_file, err) == MUTT_CMD_ERROR)
935 {
936 mutt_error("%s", buf_string(err));
937 buf_reset(err);
938
939 /* The hooks should be independent of each other, so even though this on
940 * failed, we'll carry on with the others. */
941 }
942 }
943 buf_pool_release(&err);
944
945 /* Delete temporary attachment files */
947}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:76
#define MUTT_TIMEOUT_HOOK
timeout-hook: run a command periodically
Definition: hook.h:53
void mutt_temp_attachments_cleanup(void)
Delete all temporary attachments.
Definition: mutt_attach.c:1309
+ 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 956 of file hook.c.

957{
958 struct Hook *hook = NULL;
959 struct Buffer *err = buf_pool_get();
960
961 TAILQ_FOREACH(hook, &Hooks, entries)
962 {
963 if (!(hook->command && (hook->type & type)))
964 continue;
965
966 if (parse_rc_line_cwd(hook->command, hook->source_file, err) == MUTT_CMD_ERROR)
967 {
968 mutt_error("%s", buf_string(err));
969 buf_reset(err);
970 }
971 }
972 buf_pool_release(&err);
973}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_idxfmt_hook()

const struct Expando * 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
ptrExpando
NULLNo matching hook

Definition at line 983 of file hook.c.

984{
985 if (!IdxFmtHooks)
986 return NULL;
987
988 struct HookList *hl = mutt_hash_find(IdxFmtHooks, name);
989 if (!hl)
990 return NULL;
991
993
994 struct PatternCache cache = { 0 };
995 const struct Expando *exp = NULL;
996 struct Hook *hook = NULL;
997
998 TAILQ_FOREACH(hook, hl, entries)
999 {
1000 struct Pattern *pat = SLIST_FIRST(hook->pattern);
1001 if ((mutt_pattern_exec(pat, 0, m, e, &cache) > 0) ^ hook->regex.pat_not)
1002 {
1003 exp = hook->expando;
1004 break;
1005 }
1006 }
1007
1009
1010 return exp;
1011}
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:52
Parsed Expando trees.
Definition: expando.h:41
A simple (non-regex) pattern.
Definition: lib.h:77
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ hooks_init()

void hooks_init ( void  )

Setup feature commands.

Definition at line 1043 of file hook.c.

1044{
1046}
void commands_register(const struct Command *cmds, const size_t num_cmds)
Add commands to Commands array.
Definition: command.c:53
static const struct Command HookCommands[]
Hook Commands.
Definition: hook.c:1016
#define mutt_array_size(x)
Definition: memory.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ IndexFormatDef

const struct ExpandoDefinition IndexFormatDef
extern

Expando definitions.

Config:

  • $attribution_intro
  • $attribution_trailer
  • $forward_attribution_intro
  • $forward_attribution_trailer
  • $forward_format
  • $index_format
  • $message_format
  • $pager_format

Definition at line 295 of file mutt_config.c.

◆ Hooks

struct HookList Hooks = TAILQ_HEAD_INITIALIZER(Hooks)
static

All simple hooks, e.g. MUTT_FOLDER_HOOK.

Definition at line 80 of file hook.c.

◆ IdxFmtHooks

struct HashTable* IdxFmtHooks = NULL
static

All Index Format hooks.

Definition at line 83 of file hook.c.

◆ CurrentHookType

HookFlags CurrentHookType = MUTT_HOOK_NO_FLAGS
static

The type of the hook currently being executed, e.g. MUTT_SAVE_HOOK.

Definition at line 86 of file hook.c.

◆ HookCommands

const struct Command HookCommands[]
static
Initial value:
= {
{ "account-hook", mutt_parse_hook, MUTT_ACCOUNT_HOOK },
{ "crypt-hook", mutt_parse_hook, MUTT_CRYPT_HOOK },
{ "fcc-hook", mutt_parse_hook, MUTT_FCC_HOOK },
{ "fcc-save-hook", mutt_parse_hook, MUTT_FCC_HOOK | MUTT_SAVE_HOOK },
{ "folder-hook", mutt_parse_hook, MUTT_FOLDER_HOOK },
{ "index-format-hook", mutt_parse_idxfmt_hook, MUTT_IDXFMTHOOK },
{ "mbox-hook", mutt_parse_hook, MUTT_MBOX_HOOK },
{ "message-hook", mutt_parse_hook, MUTT_MESSAGE_HOOK },
{ "pgp-hook", mutt_parse_hook, MUTT_CRYPT_HOOK },
{ "reply-hook", mutt_parse_hook, MUTT_REPLY_HOOK },
{ "save-hook", mutt_parse_hook, MUTT_SAVE_HOOK },
{ "send-hook", mutt_parse_hook, MUTT_SEND_HOOK },
{ "send2-hook", mutt_parse_hook, MUTT_SEND2_HOOK },
{ "unhook", mutt_parse_unhook, 0 },
}
static 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: hook.c:572
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() -.
Definition: hook.c:124
#define MUTT_ICONV_HOOK
iconv-hook: create a system charset alias
Definition: hook.h:43
#define MUTT_SEND_HOOK
send-hook: when composing a new email
Definition: hook.h:39
#define MUTT_GLOBAL_HOOK
Hooks which don't take a regex.
Definition: hook.h:56
#define MUTT_STARTUP_HOOK
startup-hook: run when starting NeoMutt
Definition: hook.h:54
#define MUTT_SEND2_HOOK
send2-hook: when changing fields in the compose menu
Definition: hook.h:48
#define MUTT_MBOX_HOOK
mbox-hook: move messages after reading them
Definition: hook.h:38
#define MUTT_REPLY_HOOK
reply-hook: when replying to an email
Definition: hook.h:47
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:44
#define MUTT_SHUTDOWN_HOOK
shutdown-hook: run when leaving NeoMutt
Definition: hook.h:55
#define MUTT_CHARSET_HOOK
charset-hook: create a charset alias for malformed emails
Definition: hook.h:42

Hook Commands.

Definition at line 1016 of file hook.c.