NeoMutt  2025-12-11-911-gd8d604
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
dump.c
Go to the documentation of this file.
1
22
28
29#include "config.h"
30#include <stdbool.h>
31#include <stdio.h>
32#include "mutt/lib.h"
33#include "config/lib.h"
34#include "core/lib.h"
35#include "mutt.h"
36#include "commands/lib.h"
37#include "expando/lib.h"
38#include "pager/lib.h"
39#include "parse/lib.h"
40#include "hook.h"
41#include "module_data.h"
42#include "muttlib.h"
43
50static void hooks_dump_one(struct Hook *hook, const struct Command *cmd, struct Buffer *buf)
51{
52 struct Buffer *pretty = buf_pool_get();
53
54 buf_add_printf(buf, "%s ", cmd->name);
55
56 if (hook->regex.pattern)
57 {
58 if (hook->regex.pat_not)
59 buf_addch(pretty, '!');
60
61 if ((hook->id == CMD_FOLDER_HOOK) || (hook->id == CMD_MBOX_HOOK))
62 {
63 buf_addstr(pretty, hook->regex.pattern);
64 pretty_mailbox(pretty);
65 buf_add_printf(buf, "\"%s\" ", buf_string(pretty));
66 }
67 else
68 {
69 buf_addstr(pretty, hook->regex.pattern);
70 pretty_var(buf_string(pretty), buf);
71 buf_addch(buf, ' ');
72 }
73 }
74
75 if ((hook->id == CMD_FCC_HOOK) || (hook->id == CMD_MBOX_HOOK) || (hook->id == CMD_SAVE_HOOK))
76 {
77 buf_strcpy(pretty, hook->command);
78 pretty_mailbox(pretty);
79 buf_add_printf(buf, "\"%s\"\n", buf_string(pretty));
80 }
81 else
82 {
83 pretty_var(hook->command, buf);
84 buf_addch(buf, '\n');
85 }
86
87 buf_pool_release(&pretty);
88}
89
94static void hooks_dump_simple(struct Buffer *buf)
95{
97 // Dump all the Hooks, except: CMD_CHARSET_HOOK, CMD_ICONV_HOOK, CMD_INDEX_FORMAT_HOOK
98 static const enum CommandId hook_ids[] = {
103 };
104
105 for (size_t i = 0; i < countof(hook_ids); i++)
106 {
107 const struct Command *hook_cmd = command_find_by_id(&NeoMutt->commands, hook_ids[i]);
108 enum CommandId id = hook_ids[i];
109 bool found_header = false;
110 struct Hook *hook = NULL;
111
112 TAILQ_FOREACH(hook, &mod_data->hooks, entries)
113 {
114 if (hook->id != id)
115 continue;
116
117 if (!found_header)
118 {
119 buf_add_printf(buf, "# %s\n", hook_cmd->help);
120 found_header = true;
121 }
122
123 hooks_dump_one(hook, hook_cmd, buf);
124 }
125
126 if (found_header)
127 buf_addstr(buf, "\n");
128 }
129}
130
135static void hooks_dump_index(struct Buffer *buf)
136{
138 if (!mod_data->idx_fmt_hooks)
139 return;
140
141 struct HashWalkState hws = { 0 };
142 struct HashElem *he = NULL;
143 bool found_header = false;
144
145 while ((he = mutt_hash_walk(mod_data->idx_fmt_hooks, &hws)))
146 {
147 const char *name = he->key.strkey;
148 struct HookList *hl = he->data;
149 struct Hook *hook = NULL;
150
151 TAILQ_FOREACH(hook, hl, entries)
152 {
153 if (!found_header)
154 {
155 const struct Command *hook_cmd = command_find_by_id(&NeoMutt->commands,
157 buf_add_printf(buf, "# %s\n", hook_cmd->help);
158 found_header = true;
159 }
160
161 const char *exp_str = hook->expando ? hook->expando->string : "";
162 buf_add_printf(buf, "index-format-hook '%s' %s'%s' '%s'\n", name,
163 hook->regex.pat_not ? "! " : "",
164 NONULL(hook->regex.pattern), NONULL(exp_str));
165 }
166 }
167
168 if (found_header)
169 buf_addstr(buf, "\n");
170}
171
176static void hooks_dump_charset(struct Buffer *buf)
177{
178 struct Lookup *l = NULL;
179 struct Buffer *charset = buf_pool_get();
180 struct Buffer *iconv = buf_pool_get();
181
182 TAILQ_FOREACH(l, &Lookups, entries)
183 {
184 if (l->type == MUTT_LOOKUP_CHARSET)
185 {
186 buf_addstr(charset, "charset-hook ");
187 pretty_var(l->regex.pattern, charset);
188 buf_addch(charset, ' ');
189 pretty_var(l->replacement, charset);
190 buf_addch(charset, '\n');
191 }
192 else if (l->type == MUTT_LOOKUP_ICONV)
193 {
194 buf_addstr(iconv, "iconv-hook ");
195 pretty_var(l->regex.pattern, iconv);
196 buf_addch(iconv, ' ');
197 pretty_var(l->replacement, iconv);
198 buf_addch(iconv, '\n');
199 }
200 }
201
202 const struct Command *cmd = NULL;
203 if (!buf_is_empty(charset))
204 {
205 cmd = command_find_by_name(&NeoMutt->commands, "charset-hook");
206 buf_add_printf(buf, "# %s\n", cmd->help);
207 buf_add_printf(buf, "%s\n", buf_string(charset));
208 }
209
210 if (!buf_is_empty(iconv))
211 {
212 cmd = command_find_by_name(&NeoMutt->commands, "iconv-hook");
213 buf_add_printf(buf, "# %s\n", cmd->help);
214 buf_add_printf(buf, "%s\n", buf_string(iconv));
215 }
216
217 buf_pool_release(&iconv);
218 buf_pool_release(&charset);
219}
220
227enum CommandResult parse_hooks(const struct Command *cmd, struct Buffer *line,
228 const struct ParseContext *pc, struct ParseError *pe)
229{
230 struct Buffer *err = pe->message;
231
232 if (MoreArgs(line))
233 {
234 buf_printf(err, _("%s: too many arguments"), cmd->name);
235 return MUTT_CMD_WARNING;
236 }
237
238 if (!StartupComplete)
239 return MUTT_CMD_SUCCESS;
240
242 if (TAILQ_EMPTY(&mod_data->hooks))
243 {
244 buf_printf(err, _("%s: No Hooks are configured"), cmd->name);
245 return MUTT_CMD_WARNING;
246 }
247
248 struct Buffer *tempfile = buf_pool_get();
249 buf_mktemp(tempfile);
250
251 FILE *fp = mutt_file_fopen(buf_string(tempfile), "w");
252 if (!fp)
253 {
254 mutt_error(_("Could not create temporary file %s"), buf_string(tempfile));
255 buf_pool_release(&tempfile);
256 return MUTT_CMD_ERROR;
257 }
258
259 struct Buffer *buf = buf_pool_get();
260
262 hooks_dump_index(buf);
264
266 mutt_file_fclose(&fp);
267 buf_pool_release(&buf);
268
269 struct PagerData pdata = { 0 };
270 struct PagerView pview = { &pdata };
271
272 pdata.fname = buf_string(tempfile);
273
274 pview.banner = "hooks";
275 pview.flags = MUTT_PAGER_NONE;
276 pview.mode = PAGER_MODE_OTHER;
277
278 mutt_do_pager(&pview, NULL);
279 buf_pool_release(&tempfile);
280 return MUTT_CMD_SUCCESS;
281}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition buffer.c:204
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:291
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition buffer.c:241
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:226
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
CommandId
ID of Command.
Definition command.h:61
@ CMD_CLOSE_HOOK
:close-hook
Definition command.h:73
@ CMD_SEND_HOOK
:send-hook
Definition command.h:110
@ CMD_INDEX_FORMAT_HOOK
:index-format-hook
Definition command.h:89
@ CMD_SHUTDOWN_HOOK
:shutdown-hook
Definition command.h:113
@ CMD_FCC_HOOK
:fcc-hook
Definition command.h:78
@ CMD_MESSAGE_HOOK
:message-hook
Definition command.h:97
@ CMD_SEND2_HOOK
:send2-hook
Definition command.h:109
@ CMD_REPLY_HOOK
:reply-hook
Definition command.h:105
@ CMD_STARTUP_HOOK
:startup-hook
Definition command.h:118
@ CMD_SAVE_HOOK
:save-hook
Definition command.h:107
@ CMD_TIMEOUT_HOOK
:timeout-hook
Definition command.h:124
@ CMD_ACCOUNT_HOOK
:account-hook
Definition command.h:63
@ CMD_CRYPT_HOOK
:crypt-hook
Definition command.h:75
@ CMD_MBOX_HOOK
:mbox-hook
Definition command.h:96
@ CMD_FOLDER_HOOK
:folder-hook
Definition command.h:81
@ CMD_OPEN_HOOK
:open-hook
Definition command.h:103
@ CMD_APPEND_HOOK
:append-hook
Definition command.h:67
CommandResult
Error codes for command_t parse functions.
Definition command.h:37
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition command.h:40
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition command.h:38
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition command.h:39
const struct Command * command_find_by_name(const struct CommandArray *ca, const char *name)
Find a NeoMutt Command by its name.
Definition commands.c:145
const struct Command * command_find_by_id(const struct CommandArray *ca, enum CommandId id)
Find a NeoMutt Command by its CommandId.
Definition commands.c:120
NeoMutt Commands.
size_t pretty_var(const char *str, struct Buffer *buf)
Escape and stringify a config item value.
Definition dump.c:87
Convenience wrapper for the config headers.
bool StartupComplete
When the config has been read.
Definition address.c:11
Convenience wrapper for the core headers.
int mutt_do_pager(struct PagerView *pview, struct Email *e)
Display some page-able text to the user (help or attachment)
Definition do_pager.c:122
Parse Expando string.
#define MoreArgs(buf)
Definition extract.h:31
size_t mutt_file_save_str(FILE *fp, const char *str)
Save a string to a file.
Definition file.c:1574
#define mutt_file_fclose(FP)
Definition file.h:144
#define mutt_file_fopen(PATH, MODE)
Definition file.h:143
enum CommandResult parse_hooks(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse the 'hooks' command - Implements Command::parse() -.
Definition dump.c:227
#define mutt_error(...)
Definition logging2.h:94
struct HashElem * mutt_hash_walk(const struct HashTable *table, struct HashWalkState *state)
Iterate through all the HashElem's in a Hash Table.
Definition hash.c:491
User-defined Hooks.
static void hooks_dump_charset(struct Buffer *buf)
Dump the Charset Hooks.
Definition dump.c:176
static void hooks_dump_index(struct Buffer *buf)
Dump the Index Format Hooks.
Definition dump.c:135
static void hooks_dump_one(struct Hook *hook, const struct Command *cmd, struct Buffer *buf)
Dump a single hook to the buffer.
Definition dump.c:50
static void hooks_dump_simple(struct Buffer *buf)
Dump the simple Hooks.
Definition dump.c:94
Hooks private Module data.
#define countof(x)
Definition memory.h:49
@ MODULE_ID_HOOKS
ModuleHooks, Hook Commands
Definition module_api.h:70
struct LookupList Lookups
Lookup table of preferred character set names.
Definition charset.c:69
@ MUTT_LOOKUP_ICONV
Character set conversion.
Definition charset.h:63
@ MUTT_LOOKUP_CHARSET
Alias for another character set.
Definition charset.h:62
Convenience wrapper for the library headers.
#define _(a)
Definition message.h:28
Many unsorted constants and some structs.
void pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using '~' or '='.
Definition muttlib.c:428
Some miscellaneous functions.
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:663
GUI display a file/email/help in a viewport with paging.
#define MUTT_PAGER_NONE
No flags are set.
Definition lib.h:63
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition lib.h:143
Text parsing functions.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:782
#define TAILQ_EMPTY(head)
Definition queue.h:778
#define NONULL(x)
Definition string2.h:44
String manipulation buffer.
Definition buffer.h:36
const char * help
One-line description of the Command.
Definition command.h:183
const char * name
Name of the Command.
Definition command.h:162
const char * string
Pointer to the parsed string.
Definition expando.h:42
The item stored in a Hash Table.
Definition hash.h:44
union HashKey key
Key representing the data.
Definition hash.h:46
void * data
User-supplied data.
Definition hash.h:47
Cursor to iterate through a Hash Table.
Definition hash.h:140
A list of user hooks.
Definition hook.h:33
struct Regex regex
Regular expression.
Definition hook.h:35
char * command
Filename, command or pattern to execute.
Definition hook.h:36
struct Expando * expando
Used for format hooks.
Definition hook.h:39
enum CommandId id
Hook CommandId, e.g. CMD_FOLDER_HOOK.
Definition hook.h:34
Hooks private Module data.
Definition module_data.h:33
struct HashTable * idx_fmt_hooks
All Index Format hooks.
Definition module_data.h:36
struct HookList hooks
All simple hooks, e.g. CMD_FOLDER_HOOK.
Definition module_data.h:35
Regex to String lookup table.
Definition charset.h:75
char * replacement
Alternative charset to use.
Definition charset.h:78
enum LookupType type
Lookup type.
Definition charset.h:76
struct Regex regex
Regular expression.
Definition charset.h:77
Container for Accounts, Notifications.
Definition neomutt.h:41
struct CommandArray commands
NeoMutt commands.
Definition neomutt.h:53
Data to be displayed by PagerView.
Definition lib.h:162
const char * fname
Name of the file to read.
Definition lib.h:166
Paged view into some data.
Definition lib.h:173
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition lib.h:174
enum PagerMode mode
Pager mode.
Definition lib.h:175
PagerFlags flags
Additional settings to tweak pager's function.
Definition lib.h:176
const char * banner
Title to display in status bar.
Definition lib.h:177
Context for config parsing (history/backtrace)
Definition pcontext.h:34
Detailed error information from config parsing.
Definition perror.h:34
struct Buffer * message
Error message.
Definition perror.h:35
char * pattern
printable version
Definition regex3.h:86
bool pat_not
do not match
Definition regex3.h:88
#define buf_mktemp(buf)
Definition tmp.h:33
const char * strkey
String key.
Definition hash.h:36