NeoMutt
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 <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 "hook.h"
#include "attach/lib.h"
#include "index/lib.h"
#include "ncrypt/lib.h"
#include "parse/lib.h"
#include "pattern/lib.h"
#include "commands.h"
#include "format_flags.h"
#include "globals.h"
#include "hdrline.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() -.
 
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() -.
 
static void delete_hook (struct Hook *h)
 Delete a Hook.
 
void mutt_delete_hooks (HookFlags type)
 Delete matching hooks.
 
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 -.
 
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 (char *path, size_t pathlen, HookFlags type, struct Mailbox *m, struct Email *e)
 Perform an address hook (get a path)
 
void mutt_default_save (char *path, size_t pathlen, 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 char * mutt_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

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

347{
348 FREE(&h->command);
349 FREE(&h->source_file);
350 FREE(&h->regex.pattern);
351 if (h->regex.regex)
352 {
353 regfree(h->regex.regex);
354 FREE(&h->regex.regex);
355 }
357 FREE(&h);
358}
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: compile.c:778
#define FREE(x)
Definition: memory.h:45
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:68
struct Regex regex
Regular expression.
Definition: hook.c:65
char * command
Filename, command or pattern to execute.
Definition: hook.c:66
char * source_file
Used for relative-directory source.
Definition: hook.c:67
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 MUTT_HOOK_NO_FLAGS is passed, all the hooks will be deleted.

Definition at line 366 of file hook.c.

367{
368 struct Hook *h = NULL;
369 struct Hook *tmp = NULL;
370
371 TAILQ_FOREACH_SAFE(h, &Hooks, entries, tmp)
372 {
373 if ((type == MUTT_HOOK_NO_FLAGS) || (type == h->type))
374 {
375 TAILQ_REMOVE(&Hooks, h, entries);
376 delete_hook(h);
377 }
378 }
379}
static struct HookList Hooks
All simple hooks, e.g. MUTT_FOLDER_HOOK.
Definition: hook.c:74
static void delete_hook(struct Hook *h)
Delete a Hook.
Definition: hook.c:346
#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 402 of file hook.c.

403{
405}
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:77
+ 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 520 of file hook.c.

521{
522 struct Command *c = NULL;
523 for (size_t i = 0, size = commands_array(&c); i < size; i++)
524 {
525 if (((c[i].parse == mutt_parse_hook) || (c[i].parse == mutt_parse_idxfmt_hook)) &&
527 {
528 return c[i].data;
529 }
530 }
531 return MUTT_HOOK_NO_FLAGS;
532}
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:410
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:128
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:810
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 588 of file hook.c.

589{
590 if (!path && !desc)
591 return;
592
593 struct Hook *hook = NULL;
594 struct Buffer *err = buf_pool_get();
595
597
598 TAILQ_FOREACH(hook, &Hooks, entries)
599 {
600 if (!hook->command)
601 continue;
602
603 if (!(hook->type & MUTT_FOLDER_HOOK))
604 continue;
605
606 const char *match = NULL;
607 if (mutt_regex_match(&hook->regex, path))
608 match = path;
609 else if (mutt_regex_match(&hook->regex, desc))
610 match = desc;
611
612 if (match)
613 {
614 mutt_debug(LL_DEBUG1, "folder-hook '%s' matches '%s'\n", hook->regex.pattern, match);
615 mutt_debug(LL_DEBUG5, " %s\n", hook->command);
616 if (parse_rc_line_cwd(hook->command, hook->source_file, err) == MUTT_CMD_ERROR)
617 {
618 mutt_error("%s", buf_string(err));
619 break;
620 }
621 }
622 }
623 buf_pool_release(&err);
624
626}
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:93
@ 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:159
#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:80
#define MUTT_FOLDER_HOOK
folder-hook: when entering a mailbox
Definition: hook.h:38
@ 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:636
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: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 636 of file hook.c.

637{
638 struct Hook *tmp = NULL;
639
640 TAILQ_FOREACH(tmp, &Hooks, entries)
641 {
642 if (tmp->type & type)
643 {
644 if (mutt_regex_match(&tmp->regex, pat))
645 return tmp->command;
646 }
647 }
648 return NULL;
649}
+ 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 657 of file hook.c.

658{
659 struct Hook *hook = NULL;
660 struct PatternCache cache = { 0 };
661 struct Buffer *err = buf_pool_get();
662
663 CurrentHookType = type;
664
665 TAILQ_FOREACH(hook, &Hooks, entries)
666 {
667 if (!hook->command)
668 continue;
669
670 if (hook->type & type)
671 {
672 if ((mutt_pattern_exec(SLIST_FIRST(hook->pattern), 0, m, e, &cache) > 0) ^
673 hook->regex.pat_not)
674 {
675 if (parse_rc_line_cwd(hook->command, hook->source_file, err) == MUTT_CMD_ERROR)
676 {
677 mutt_error("%s", buf_string(err));
679 buf_pool_release(&err);
680
681 return;
682 }
683 /* Executing arbitrary commands could affect the pattern results,
684 * so the cache has to be wiped */
685 memset(&cache, 0, sizeof(cache));
686 }
687 }
688 }
689 buf_pool_release(&err);
690
692}
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:1137
#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: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 704 of file hook.c.

706{
707 struct Hook *hook = NULL;
708 struct PatternCache cache = { 0 };
709
710 /* determine if a matching hook exists */
711 TAILQ_FOREACH(hook, &Hooks, entries)
712 {
713 if (!hook->command)
714 continue;
715
716 if (hook->type & type)
717 {
718 if ((mutt_pattern_exec(SLIST_FIRST(hook->pattern), 0, m, e, &cache) > 0) ^
719 hook->regex.pat_not)
720 {
721 mutt_make_string(path, pathlen, 0, hook->command, m, -1, e, MUTT_FORMAT_PLAIN, NULL);
722 return 0;
723 }
724 }
725 }
726
727 return -1;
728}
#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:1426
+ 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 736 of file hook.c.

737{
738 *path = '\0';
739 struct Mailbox *m_cur = get_current_mailbox();
740 if (addr_hook(path, pathlen, MUTT_SAVE_HOOK, m_cur, e) == 0)
741 return;
742
743 struct Envelope *env = e->env;
744 const struct Address *from = TAILQ_FIRST(&env->from);
745 const struct Address *reply_to = TAILQ_FIRST(&env->reply_to);
746 const struct Address *to = TAILQ_FIRST(&env->to);
747 const struct Address *cc = TAILQ_FIRST(&env->cc);
748 const struct Address *addr = NULL;
749 bool from_me = mutt_addr_is_user(from);
750
751 if (!from_me && reply_to && reply_to->mailbox)
752 addr = reply_to;
753 else if (!from_me && from && from->mailbox)
754 addr = from;
755 else if (to && to->mailbox)
756 addr = to;
757 else if (cc && cc->mailbox)
758 addr = cc;
759 else
760 addr = NULL;
761 if (addr)
762 {
763 struct Buffer *tmp = buf_pool_get();
764 mutt_safe_path(tmp, addr);
765 snprintf(path, pathlen, "=%s", buf_string(tmp));
766 buf_pool_release(&tmp);
767 }
768}
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition: alias.c:570
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:704
#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:662
void mutt_safe_path(struct Buffer *dest, const struct Address *a)
Make a safe filename from an email address.
Definition: muttlib.c:726
#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: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 775 of file hook.c.

776{
777 buf_alloc(path, PATH_MAX);
778
779 if (addr_hook(path->data, path->dsize, MUTT_FCC_HOOK, NULL, e) != 0)
780 {
781 const struct Address *to = TAILQ_FIRST(&e->env->to);
782 const struct Address *cc = TAILQ_FIRST(&e->env->cc);
783 const struct Address *bcc = TAILQ_FIRST(&e->env->bcc);
784 const bool c_save_name = cs_subset_bool(NeoMutt->sub, "save_name");
785 const bool c_force_name = cs_subset_bool(NeoMutt->sub, "force_name");
786 const char *const c_record = cs_subset_string(NeoMutt->sub, "record");
787 if ((c_save_name || c_force_name) && (to || cc || bcc))
788 {
789 const struct Address *addr = to ? to : (cc ? cc : bcc);
790 struct Buffer *buf = buf_pool_get();
791 mutt_safe_path(buf, addr);
792 const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
793 buf_concat_path(path, NONULL(c_folder), buf_string(buf));
794 buf_pool_release(&buf);
795 if (!c_force_name && (mx_access(buf_string(path), W_OK) != 0))
796 buf_strcpy(path, c_record);
797 }
798 else
799 {
800 buf_strcpy(path, c_record);
801 }
802 }
803 else
804 {
805 buf_fix_dptr(path);
806 }
807
808 buf_pretty_mailbox(path);
809}
void buf_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:194
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:407
size_t buf_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:484
void buf_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:349
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:292
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:48
#define MUTT_FCC_HOOK
fcc-hook: to save outgoing email
Definition: hook.h:41
#define PATH_MAX
Definition: mutt.h:41
void buf_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:562
int mx_access(const char *path, int flags)
Wrapper for access, checks permissions on a given mailbox.
Definition: mx.c:182
#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:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45
+ 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 817 of file hook.c.

818{
819 struct Hook *tmp = NULL;
820
821 TAILQ_FOREACH(tmp, &Hooks, entries)
822 {
823 if ((tmp->type & type) && mutt_regex_match(&tmp->regex, match))
824 {
826 }
827 }
828}
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:251
+ 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 837 of file hook.c.

838{
840}
static void list_hook(struct ListHead *matches, const char *match, HookFlags type)
Find hook strings matching.
Definition: hook.c:817
#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 846 of file hook.c.

847{
848 /* parsing commands with URLs in an account hook can cause a recursive
849 * call. We just skip processing if this occurs. Typically such commands
850 * belong in a folder-hook -- perhaps we should warn the user. */
851 static bool inhook = false;
852 if (inhook)
853 return;
854
855 struct Hook *hook = NULL;
856 struct Buffer *err = buf_pool_get();
857
858 TAILQ_FOREACH(hook, &Hooks, entries)
859 {
860 if (!(hook->command && (hook->type & MUTT_ACCOUNT_HOOK)))
861 continue;
862
863 if (mutt_regex_match(&hook->regex, url))
864 {
865 inhook = true;
866 mutt_debug(LL_DEBUG1, "account-hook '%s' matches '%s'\n", hook->regex.pattern, url);
867 mutt_debug(LL_DEBUG5, " %s\n", hook->command);
868
869 if (parse_rc_line_cwd(hook->command, hook->source_file, err) == MUTT_CMD_ERROR)
870 {
871 mutt_error("%s", buf_string(err));
872 buf_pool_release(&err);
873
874 inhook = false;
875 goto done;
876 }
877
878 inhook = false;
879 }
880 }
881done:
882 buf_pool_release(&err);
883}
#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 891 of file hook.c.

892{
893 struct Hook *hook = NULL;
894 struct Buffer err;
895 char buf[256] = { 0 };
896
897 buf_init(&err);
898 err.data = buf;
899 err.dsize = sizeof(buf);
900
901 TAILQ_FOREACH(hook, &Hooks, entries)
902 {
903 if (!(hook->command && (hook->type & MUTT_TIMEOUT_HOOK)))
904 continue;
905
906 if (parse_rc_line_cwd(hook->command, hook->source_file, &err) == MUTT_CMD_ERROR)
907 {
908 mutt_error("%s", err.data);
909 buf_reset(&err);
910
911 /* The hooks should be independent of each other, so even though this on
912 * failed, we'll carry on with the others. */
913 }
914 }
915
916 /* Delete temporary attachment files */
918}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:88
struct Buffer * buf_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:55
#define MUTT_TIMEOUT_HOOK
timeout-hook: run a command periodically
Definition: hook.h:56
void mutt_temp_attachments_cleanup(void)
Delete all temporary attachments.
Definition: mutt_attach.c:1316
+ 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 927 of file hook.c.

928{
929 struct Hook *hook = NULL;
930 struct Buffer err = buf_make(0);
931 char buf[256] = { 0 };
932
933 err.data = buf;
934 err.dsize = sizeof(buf);
935
936 TAILQ_FOREACH(hook, &Hooks, entries)
937 {
938 if (!(hook->command && (hook->type & type)))
939 continue;
940
941 if (parse_rc_line_cwd(hook->command, hook->source_file, &err) == MUTT_CMD_ERROR)
942 {
943 mutt_error("%s", err.data);
944 buf_reset(&err);
945 }
946 }
947}
struct Buffer buf_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:70
+ 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 957 of file hook.c.

958{
959 if (!IdxFmtHooks)
960 return NULL;
961
962 struct HookList *hl = mutt_hash_find(IdxFmtHooks, name);
963 if (!hl)
964 return NULL;
965
967
968 struct PatternCache cache = { 0 };
969 const char *fmtstring = NULL;
970 struct Hook *hook = NULL;
971
972 TAILQ_FOREACH(hook, hl, entries)
973 {
974 struct Pattern *pat = SLIST_FIRST(hook->pattern);
975 if ((mutt_pattern_exec(pat, 0, m, e, &cache) > 0) ^ hook->regex.pat_not)
976 {
977 fmtstring = hook->command;
978 break;
979 }
980 }
981
983
984 return fmtstring;
985}
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: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 1017 of file hook.c.

1018{
1020}
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:990
#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

◆ Hooks

struct HookList Hooks = TAILQ_HEAD_INITIALIZER(Hooks)
static

All simple hooks, e.g. MUTT_FOLDER_HOOK.

Definition at line 74 of file hook.c.

◆ IdxFmtHooks

struct HashTable* IdxFmtHooks = NULL
static

All Index Format hooks.

Definition at line 77 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 80 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:537
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:85
#define MUTT_ICONV_HOOK
iconv-hook: create a system charset alias
Definition: hook.h:44
#define MUTT_SEND_HOOK
send-hook: when composing a new email
Definition: hook.h:40
#define MUTT_GLOBAL_HOOK
Hooks which don't take a regex.
Definition: hook.h:59
#define MUTT_STARTUP_HOOK
startup-hook: run when starting NeoMutt
Definition: hook.h:57
#define MUTT_SEND2_HOOK
send2-hook: when changing fields in the compose menu
Definition: hook.h:49
#define MUTT_MBOX_HOOK
mbox-hook: move messages after reading them
Definition: hook.h:39
#define MUTT_REPLY_HOOK
reply-hook: when replying to an email
Definition: hook.h:48
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:45
#define MUTT_SHUTDOWN_HOOK
shutdown-hook: run when leaving NeoMutt
Definition: hook.h:58
#define MUTT_CHARSET_HOOK
charset-hook: create a charset alias for malformed emails
Definition: hook.h:43

Hook Commands.

Definition at line 990 of file hook.c.