NeoMutt  2023-05-17-33-gce4425
Teaching an old dog new tricks
DOXYGEN
init.c File Reference

Config/command parsing. More...

#include "config.h"
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/utsname.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 "conn/lib.h"
#include "gui/lib.h"
#include "init.h"
#include "color/lib.h"
#include "history/lib.h"
#include "notmuch/lib.h"
#include "parse/lib.h"
#include "commands.h"
#include "globals.h"
#include "hook.h"
#include "keymap.h"
#include "mutt_lua.h"
#include "menu/lib.h"
#include "muttlib.h"
#include "protos.h"
#include "sidebar/lib.h"
#include "compmbox/lib.h"
#include "imap/lib.h"
+ Include dependency graph for init.c:

Go to the source code of this file.

Functions

static int execute_commands (struct ListHead *p)
 Execute a set of NeoMutt commands. More...
 
static char * find_cfg (const char *home, const char *xdg_cfg_home)
 Find a config file. More...
 
static char * getmailname (void)
 Try to retrieve the FQDN from mailname files. More...
 
static bool get_hostname (struct ConfigSet *cs)
 Find the Fully-Qualified Domain Name. More...
 
void mutt_opts_free (void)
 Clean up before quitting. More...
 
int mutt_init (struct ConfigSet *cs, bool skip_sys_rc, struct ListHead *commands)
 Initialise NeoMutt. More...
 
int mutt_query_variables (struct ListHead *queries, bool show_docs)
 Implement the -Q command line flag. More...
 

Detailed Description

Config/command parsing.

Authors
  • Michael R. Elkins
  • 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 init.c.

Function Documentation

◆ execute_commands()

static int execute_commands ( struct ListHead *  p)
static

Execute a set of NeoMutt commands.

Parameters
pList of command strings
Return values
0Success, all the commands succeeded
-1Error

Definition at line 77 of file init.c.

78{
79 int rc = 0;
80 struct Buffer *err = buf_pool_get();
81
82 struct ListNode *np = NULL;
83 STAILQ_FOREACH(np, p, entries)
84 {
85 enum CommandResult rc2 = parse_rc_line(np->data, err);
86 if (rc2 == MUTT_CMD_ERROR)
87 mutt_error(_("Error in command line: %s"), buf_string(err));
88 else if (rc2 == MUTT_CMD_WARNING)
89 mutt_warning(_("Warning in command line: %s"), buf_string(err));
90
91 if ((rc2 == MUTT_CMD_ERROR) || (rc2 == MUTT_CMD_WARNING))
92 {
93 buf_pool_release(&err);
94 return -1;
95 }
96 }
97 buf_pool_release(&err);
98
99 return rc;
100}
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:78
CommandResult
Error codes for command_t parse functions.
Definition: command.h:36
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:37
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition: command.h:38
#define mutt_warning(...)
Definition: logging2.h:85
#define mutt_error(...)
Definition: logging2.h:87
#define _(a)
Definition: message.h:28
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:106
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:119
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
enum CommandResult parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: rc.c:108
String manipulation buffer.
Definition: buffer.h:34
A List node for strings.
Definition: list.h:35
char * data
String.
Definition: list.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ find_cfg()

static char * find_cfg ( const char *  home,
const char *  xdg_cfg_home 
)
static

Find a config file.

Parameters
homeUser's home directory
xdg_cfg_homeXDG home directory
Return values
ptrSuccess, first matching directory
NULLError, no matching directories

Definition at line 109 of file init.c.

110{
111 const char *names[] = {
112 "neomuttrc",
113 "muttrc",
114 NULL,
115 };
116
117 const char *locations[][2] = {
118 { xdg_cfg_home, "neomutt/" },
119 { xdg_cfg_home, "mutt/" },
120 { home, ".neomutt/" },
121 { home, ".mutt/" },
122 { home, "." },
123 { NULL, NULL },
124 };
125
126 for (int i = 0; locations[i][0] || locations[i][1]; i++)
127 {
128 if (!locations[i][0])
129 continue;
130
131 for (int j = 0; names[j]; j++)
132 {
133 char buf[256] = { 0 };
134
135 snprintf(buf, sizeof(buf), "%s/%s%s", locations[i][0], locations[i][1], names[j]);
136 if (access(buf, F_OK) == 0)
137 return mutt_str_dup(buf);
138 }
139 }
140
141 return NULL;
142}
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:

◆ getmailname()

static char * getmailname ( void  )
static

Try to retrieve the FQDN from mailname files.

Return values
ptrHeap allocated string with the FQDN
NULLNo valid mailname file could be read

Definition at line 150 of file init.c.

151{
152 char *mailname = NULL;
153 static const char *mn_files[] = { "/etc/mailname", "/etc/mail/mailname" };
154
155 for (size_t i = 0; i < mutt_array_size(mn_files); i++)
156 {
157 FILE *fp = mutt_file_fopen(mn_files[i], "r");
158 if (!fp)
159 continue;
160
161 size_t len = 0;
162 mailname = mutt_file_read_line(NULL, &len, fp, NULL, MUTT_RL_NO_FLAGS);
163 mutt_file_fclose(&fp);
164 if (mailname && *mailname)
165 break;
166
167 FREE(&mailname);
168 }
169
170 return mailname;
171}
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, ReadLineFlags flags)
Read a line from a file.
Definition: file.c:738
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:634
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:150
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition: file.h:39
#define FREE(x)
Definition: memory.h:43
#define mutt_array_size(x)
Definition: memory.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_hostname()

static bool get_hostname ( struct ConfigSet cs)
static

Find the Fully-Qualified Domain Name.

Parameters
csConfig Set
Return values
trueSuccess
falseError, failed to find any name

Use several methods to try to find the Fully-Qualified domain name of this host. If the user has already configured a hostname, this function will use it.

Definition at line 183 of file init.c.

184{
185 const char *short_host = NULL;
186 struct utsname utsname = { 0 };
187
188 const char *const c_hostname = cs_subset_string(NeoMutt->sub, "hostname");
189 if (c_hostname)
190 {
191 short_host = c_hostname;
192 }
193 else
194 {
195 /* The call to uname() shouldn't fail, but if it does, the system is horribly
196 * broken, and the system's networking configuration is in an unreliable
197 * state. We should bail. */
198 if ((uname(&utsname)) == -1)
199 {
200 mutt_perror(_("unable to determine nodename via uname()"));
201 return false; // TEST09: can't test
202 }
203
204 short_host = utsname.nodename;
205 }
206
207 /* some systems report the FQDN instead of just the hostname */
208 char *dot = strchr(short_host, '.');
209 if (dot)
210 ShortHostname = mutt_strn_dup(short_host, dot - short_host);
211 else
212 ShortHostname = mutt_str_dup(short_host);
213
214 // All the code paths from here alloc memory for the fqdn
215 char *fqdn = mutt_str_dup(c_hostname);
216 if (!fqdn)
217 {
218 mutt_debug(LL_DEBUG1, "Setting $hostname\n");
219 /* now get FQDN. Use configured domain first, DNS next, then uname */
220#ifdef DOMAIN
221 /* we have a compile-time domain name, use that for `$hostname` */
223 sprintf((char *) fqdn, "%s.%s", NONULL(ShortHostname), DOMAIN);
224#else
225 fqdn = getmailname();
226 if (!fqdn)
227 {
228 struct Buffer *domain = buf_pool_get();
229 if (getdnsdomainname(domain) == 0)
230 {
231 fqdn = mutt_mem_malloc(buf_len(domain) + mutt_str_len(ShortHostname) + 2);
232 sprintf((char *) fqdn, "%s.%s", NONULL(ShortHostname), buf_string(domain));
233 }
234 else
235 {
236 /* DNS failed, use the nodename. Whether or not the nodename had a '.'
237 * in it, we can use the nodename as the FQDN. On hosts where DNS is
238 * not being used, e.g. small network that relies on hosts files, a
239 * short host name is all that is required for SMTP to work correctly.
240 * It could be wrong, but we've done the best we can, at this point the
241 * onus is on the user to provide the correct hostname if the nodename
242 * won't work in their network. */
243 fqdn = mutt_str_dup(utsname.nodename);
244 }
245 buf_pool_release(&domain);
246 mutt_debug(LL_DEBUG1, "Hostname: %s\n", NONULL(fqdn));
247 }
248#endif
249 }
250
251 if (fqdn)
252 {
253 cs_str_initial_set(cs, "hostname", fqdn, NULL);
254 cs_str_reset(cs, "hostname", NULL);
255 FREE(&fqdn);
256 }
257
258 return true;
259}
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:414
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
int cs_str_initial_set(const struct ConfigSet *cs, const char *name, const char *value, struct Buffer *err)
Set the initial value of a config item.
Definition: set.c:502
int cs_str_reset(const struct ConfigSet *cs, const char *name, struct Buffer *err)
Reset a config item to its initial value.
Definition: set.c:437
int getdnsdomainname(struct Buffer *result)
Lookup the host's name using DNS.
Definition: getdomain.c:122
char * ShortHostname
Short version of the hostname.
Definition: globals.c:40
#define mutt_debug(LEVEL,...)
Definition: logging2.h:84
#define mutt_perror(...)
Definition: logging2.h:88
static char * getmailname(void)
Try to retrieve the FQDN from mailname files.
Definition: init.c:150
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:40
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:452
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:568
#define NONULL(x)
Definition: string2.h:37
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:

◆ mutt_opts_free()

void mutt_opts_free ( void  )

Clean up before quitting.

Definition at line 264 of file init.c.

265{
267
269#ifdef USE_SIDEBAR
270 sb_shutdown();
271#endif
272
278
281
282 /* Lists of strings */
292
294
296 FREE(&HomeDir);
299 FREE(&Username);
300
302
304
307
310}
void alias_shutdown(void)
Clean up the Alias globals.
Definition: alias.c:682
void mutt_colors_cleanup(void)
Cleanup all the colours.
Definition: color.c:72
void clear_source_stack(void)
Free memory from the stack used for the source command.
Definition: commands.c:1510
char * HomeDir
User's home directory.
Definition: globals.c:39
void commands_free(void)
Free Commands array.
Definition: command.c:65
struct ReplaceList SpamList
List of regexes to match subscribed mailing lists.
Definition: globals.c:45
struct RegexList SubscribedLists
List of header patterns to unignore (see)
Definition: globals.c:47
struct RegexList UnSubscribedLists
Definition: globals.c:53
struct RegexList UnMailLists
List of regexes to exclude false matches in SubscribedLists.
Definition: globals.c:51
struct RegexList MailLists
List of permitted fields in a mailto: url.
Definition: globals.c:39
struct ListHead MailToAllow
List of regexes to identify non-spam emails.
Definition: globals.c:41
struct ListHead Ignore
List of regexes to match mailing lists.
Definition: globals.c:37
struct RegexList NoSpamList
List of regexes and patterns to match spam emails.
Definition: globals.c:43
struct ListHead UnIgnore
List of regexes to exclude false matches in MailLists.
Definition: globals.c:49
char * LastFolder
Previously selected mailbox.
Definition: globals.c:45
struct ListHead MimeLookupList
List of mime types that that shouldn't use the mailcap entry.
Definition: globals.c:52
struct ListHead AlternativeOrderList
List of preferred mime types to display.
Definition: globals.c:49
struct ListHead AutoViewList
List of mime types to auto view.
Definition: globals.c:50
char * CurrentFolder
Currently selected mailbox.
Definition: globals.c:44
struct ListHead UserHeader
List of custom headers to add to outgoing emails.
Definition: globals.c:55
struct ListHead Muttrc
List of config files to read.
Definition: globals.c:53
char * Username
User's login name.
Definition: globals.c:42
struct ListHead HeaderOrderList
List of header fields in the order they should be displayed.
Definition: globals.c:51
void mutt_grouplist_free(void)
Free GroupList singleton resource.
Definition: group.c:107
void mutt_hist_free(void)
Free all the history lists.
Definition: history.c:440
void mutt_delete_hooks(HookFlags type)
Delete matching hooks.
Definition: hook.c:367
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:37
void mutt_keys_free(void)
Free the key maps.
Definition: keymap.c:1930
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
void mutt_regexlist_free(struct RegexList *rl)
Free a RegexList object.
Definition: regex.c:174
void mutt_replacelist_free(struct ReplaceList *rl)
Free a ReplaceList object.
Definition: regex.c:471
void sb_shutdown(void)
Clean up the Sidebar.
Definition: sidebar.c:213
void driver_tags_cleanup(void)
Deinitialize structures used for tags.
Definition: tags.c:230
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_init()

int mutt_init ( struct ConfigSet cs,
bool  skip_sys_rc,
struct ListHead *  commands 
)

Initialise NeoMutt.

Parameters
csConfig Set
skip_sys_rcIf true, don't read the system config file
commandsList of config commands to execute
Return values
0Success
1Error

Definition at line 320 of file init.c.

321{
322 int need_pause = 0;
323 int rc = 1;
324 struct Buffer err = buf_make(256);
325 struct Buffer buf = buf_make(256);
326
328 alias_init();
330 hooks_init();
331#ifdef USE_COMP_MBOX
333#endif
334#ifdef USE_IMAP
335 imap_init();
336#endif
337#ifdef USE_LUA
339#endif
341
342 menu_init();
343#ifdef USE_SIDEBAR
344 sb_init();
345#endif
346#ifdef USE_NOTMUCH
347 nm_init();
348#endif
349
350#ifdef NEOMUTT_DIRECT_COLORS
351 /* Test if we run in a terminal which supports direct colours.
352 *
353 * The user/terminal can indicate their capability independent of the
354 * terminfo file by setting the COLORTERM environment variable to "truecolor"
355 * or "24bit" (case sensitive).
356 *
357 * Note: This is to test is less about whether the terminal understands
358 * direct color commands but more about whether ncurses believes it can send
359 * them to the terminal, e.g. ncurses ignores COLORTERM.
360 */
361 if (COLORS == 16777216) // 2^24
362 {
363 /* Ncurses believes the Terminal supports it check the environment variable
364 * to respect the user's choice */
365 const char *env_colorterm = mutt_str_getenv("COLORTERM");
366 if (env_colorterm && (mutt_str_equal(env_colorterm, "truecolor") ||
367 mutt_str_equal(env_colorterm, "24bit")))
368 {
369 cs_subset_str_native_set(NeoMutt->sub, "color_directcolor", true, NULL);
370 }
371 }
372#endif
373
374 /* "$spool_file" precedence: config file, environment */
375 const char *p = mutt_str_getenv("MAIL");
376 if (!p)
377 p = mutt_str_getenv("MAILDIR");
378 if (!p)
379 {
380#ifdef HOMESPOOL
381 buf_concat_path(&buf, NONULL(HomeDir), MAILPATH);
382#else
383 buf_concat_path(&buf, MAILPATH, NONULL(Username));
384#endif
385 p = buf_string(&buf);
386 }
387 cs_str_initial_set(cs, "spool_file", p, NULL);
388 cs_str_reset(cs, "spool_file", NULL);
389
390 p = mutt_str_getenv("REPLYTO");
391 if (p)
392 {
393 struct Buffer token;
394
395 buf_printf(&buf, "Reply-To: %s", p);
396 buf_init(&token);
397 parse_my_hdr(&token, &buf, 0, &err); /* adds to UserHeader */
398 FREE(&token.data);
399 }
400
401 p = mutt_str_getenv("EMAIL");
402 if (p)
403 {
404 cs_str_initial_set(cs, "from", p, NULL);
405 cs_str_reset(cs, "from", NULL);
406 }
407
408 /* "$mailcap_path" precedence: config file, environment, code */
409 const char *env_mc = mutt_str_getenv("MAILCAPS");
410 if (env_mc)
411 {
412 cs_str_initial_set(cs, "mailcap_path", env_mc, NULL);
413 cs_str_reset(cs, "mailcap_path", NULL);
414 }
415
416 /* "$tmp_dir" precedence: config file, environment, code */
417 const char *env_tmp = mutt_str_getenv("TMPDIR");
418 if (env_tmp)
419 {
420 cs_str_initial_set(cs, "tmp_dir", env_tmp, NULL);
421 cs_str_reset(cs, "tmp_dir", NULL);
422 }
423
424 /* "$visual", "$editor" precedence: config file, environment, code */
425 const char *env_ed = mutt_str_getenv("VISUAL");
426 if (!env_ed)
427 env_ed = mutt_str_getenv("EDITOR");
428 if (!env_ed)
429 env_ed = "vi";
430 cs_str_initial_set(cs, "editor", env_ed, NULL);
431
432 const char *const c_editor = cs_subset_string(NeoMutt->sub, "editor");
433 if (!c_editor)
434 cs_str_reset(cs, "editor", NULL);
435
436 const char *charset = mutt_ch_get_langinfo_charset();
437 cs_str_initial_set(cs, "charset", charset, NULL);
438 cs_str_reset(cs, "charset", NULL);
439 mutt_ch_set_charset(charset);
440 FREE(&charset);
441
442#ifdef HAVE_GETSID
443 /* Unset suspend by default if we're the session leader */
444 if (getsid(0) == getpid())
445 {
446 cs_str_initial_set(cs, "suspend", "no", NULL);
447 cs_str_reset(cs, "suspend", NULL);
448 }
449#endif
450
451 /* RFC2368, "4. Unsafe headers"
452 * The creator of a mailto URL can't expect the resolver of a URL to
453 * understand more than the "subject" and "body" headers. Clients that
454 * resolve mailto URLs into mail messages should be able to correctly
455 * create RFC822-compliant mail messages using the "subject" and "body"
456 * headers. */
457 add_to_stailq(&MailToAllow, "body");
458 add_to_stailq(&MailToAllow, "subject");
459 /* Cc, In-Reply-To, and References help with not breaking threading on
460 * mailing lists, see https://github.com/neomutt/neomutt/issues/115 */
462 add_to_stailq(&MailToAllow, "in-reply-to");
463 add_to_stailq(&MailToAllow, "references");
464
465 if (STAILQ_EMPTY(&Muttrc))
466 {
467 const char *xdg_cfg_home = mutt_str_getenv("XDG_CONFIG_HOME");
468
469 if (!xdg_cfg_home && HomeDir)
470 {
471 buf_printf(&buf, "%s/.config", HomeDir);
472 xdg_cfg_home = buf_string(&buf);
473 }
474
475 char *config = find_cfg(HomeDir, xdg_cfg_home);
476 if (config)
477 {
479 }
480 }
481 else
482 {
483 struct ListNode *np = NULL;
484 STAILQ_FOREACH(np, &Muttrc, entries)
485 {
486 buf_strcpy(&buf, np->data);
487 FREE(&np->data);
488 buf_expand_path(&buf);
489 np->data = buf_strdup(&buf);
490 if (access(np->data, F_OK))
491 {
492 mutt_perror(np->data);
493 goto done; // TEST10: neomutt -F missing
494 }
495 }
496 }
497
498 if (!STAILQ_EMPTY(&Muttrc))
499 {
500 cs_str_string_set(cs, "alias_file", STAILQ_FIRST(&Muttrc)->data, NULL);
501 }
502
503 /* Process the global rc file if it exists and the user hasn't explicitly
504 * requested not to via "-n". */
505 if (!skip_sys_rc)
506 {
507 do
508 {
510 break;
511
512 buf_printf(&buf, "%s/neomuttrc", SYSCONFDIR);
513 if (access(buf_string(&buf), F_OK) == 0)
514 break;
515
516 buf_printf(&buf, "%s/Muttrc", SYSCONFDIR);
517 if (access(buf_string(&buf), F_OK) == 0)
518 break;
519
520 buf_printf(&buf, "%s/neomuttrc", PKGDATADIR);
521 if (access(buf_string(&buf), F_OK) == 0)
522 break;
523
524 buf_printf(&buf, "%s/Muttrc", PKGDATADIR);
525 } while (false);
526
527 if (access(buf_string(&buf), F_OK) == 0)
528 {
529 if (source_rc(buf_string(&buf), &err) != 0)
530 {
531 mutt_error("%s", err.data);
532 need_pause = 1; // TEST11: neomutt (error in /etc/neomuttrc)
533 }
534 }
535 }
536
537 /* Read the user's initialization file. */
538 struct ListNode *np = NULL;
539 STAILQ_FOREACH(np, &Muttrc, entries)
540 {
541 if (np->data)
542 {
543 if (source_rc(np->data, &err) != 0)
544 {
545 mutt_error("%s", err.data);
546 need_pause = 1; // TEST12: neomutt (error in ~/.neomuttrc)
547 }
548 }
549 }
550
551 if (execute_commands(commands) != 0)
552 need_pause = 1; // TEST13: neomutt -e broken
553
554 if (!get_hostname(cs))
555 goto done;
556
557 {
558 char name[256] = { 0 };
559 const char *c_real_name = cs_subset_string(NeoMutt->sub, "real_name");
560 if (!c_real_name)
561 {
562 struct passwd *pw = getpwuid(getuid());
563 if (pw)
564 {
565 c_real_name = mutt_gecos_name(name, sizeof(name), pw);
566 }
567 }
568 cs_str_initial_set(cs, "real_name", c_real_name, NULL);
569 cs_str_reset(cs, "real_name", NULL);
570 }
571
572 if (need_pause && !OptNoCurses)
573 {
575 if (mutt_any_key_to_continue(NULL) == 'q')
576 goto done; // TEST14: neomutt -e broken (press 'q')
577 }
578
579 const char *const c_tmp_dir = cs_subset_path(NeoMutt->sub, "tmp_dir");
580 mutt_file_mkdir(c_tmp_dir, S_IRWXU);
581
584
585#ifdef USE_NOTMUCH
586 const bool c_virtual_spool_file = cs_subset_bool(NeoMutt->sub, "virtual_spool_file");
587 if (c_virtual_spool_file)
588 {
589 /* Find the first virtual folder and open it */
590 struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
592 struct MailboxNode *mp = STAILQ_FIRST(&ml);
593 if (mp)
594 cs_str_string_set(cs, "spool_file", mailbox_path(mp->mailbox), NULL);
596 }
597#endif
598 rc = 0;
599
600done:
601 buf_dealloc(&err);
602 buf_dealloc(&buf);
603 return rc;
604}
void alias_init(void)
Set up the Alias globals.
Definition: alias.c:674
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:171
void buf_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:352
struct Buffer buf_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:68
struct Buffer * buf_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:53
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:370
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:490
size_t buf_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:432
void commands_init(void)
Initialize commands array and register default commands.
Definition: commands.c:1586
int source_rc(const char *rcfile_path, struct Buffer *err)
Read an initialization file.
Definition: commands.c:191
void mutt_comp_init(void)
Setup feature commands.
Definition: compress.c:72
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
int cs_str_string_set(const struct ConfigSet *cs, const char *name, const char *value, struct Buffer *err)
Set a config item by string.
Definition: set.c:639
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:388
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:952
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: globals.c:82
void mutt_grouplist_init(void)
Initialize the GroupList singleton.
Definition: group.c:95
enum CommandResult parse_my_hdr(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'my_hdr' command - Implements Command::parse() -.
Definition: commands.c:697
int log_disp_terminal(time_t stamp, const char *file, int line, const char *function, enum LogLevel level,...)
Save a log line to the terminal - Implements log_dispatcher_t -.
Definition: logging.c:440
void mutt_hist_read_file(void)
Read the History from a file.
Definition: history.c:595
void mutt_hist_init(void)
Create a set of empty History ring buffers.
Definition: history.c:467
void hooks_init(void)
Setup feature commands.
Definition: hook.c:1018
void imap_init(void)
Setup feature commands.
Definition: imap.c:88
static char * find_cfg(const char *home, const char *xdg_cfg_home)
Find a config file.
Definition: init.c:109
static int execute_commands(struct ListHead *p)
Execute a set of NeoMutt commands.
Definition: init.c:77
static bool get_hostname(struct ConfigSet *cs)
Find the Fully-Qualified Domain Name.
Definition: init.c:183
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
void log_queue_flush(log_dispatcher_t disp)
Replay the log queue.
Definition: logging.c:346
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:209
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition: mailbox.h:51
void menu_init(void)
Initialise all the Menus.
Definition: menu.c:75
char * mutt_ch_get_langinfo_charset(void)
Get the user's choice of character set.
Definition: charset.c:477
void mutt_ch_set_charset(const char *charset)
Update the records for a new character set.
Definition: charset.c:1069
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:798
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition: string.c:918
void mutt_lua_init(void)
Setup feature commands.
Definition: mutt_lua.c:465
char * mutt_gecos_name(char *dest, size_t destlen, struct passwd *pw)
Lookup a user's real name in /etc/passwd.
Definition: muttlib.c:372
void add_to_stailq(struct ListHead *head, const char *str)
Add a string to a list.
Definition: muttlib.c:1693
int mutt_set_xdg_path(enum XdgType type, struct Buffer *buf)
Find an XDG path or its fallback.
Definition: muttlib.c:1478
void buf_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:333
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:141
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:164
void nm_init(void)
Setup feature commands.
Definition: notmuch.c:103
@ XDG_CONFIG_DIRS
XDG system dir: /etc/xdg.
Definition: protos.h:44
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
#define STAILQ_FIRST(head)
Definition: queue.h:350
#define STAILQ_EMPTY(head)
Definition: queue.h:348
void sb_init(void)
Set up the Sidebar.
Definition: sidebar.c:201
char * data
Pointer to data.
Definition: buffer.h:35
List of Mailboxes.
Definition: mailbox.h:152
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:153
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:310
void driver_tags_init(void)
Initialize structures used for tags.
Definition: tags.c:218
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_query_variables()

int mutt_query_variables ( struct ListHead *  queries,
bool  show_docs 
)

Implement the -Q command line flag.

Parameters
queriesList of query strings
show_docsIf true, show one-liner docs for the config item
Return values
0Success, all queries exist
1Error

Definition at line 613 of file init.c.

614{
615 struct Buffer value = buf_make(256);
616 struct Buffer tmp = buf_make(256);
617 int rc = 0;
618
619 struct ListNode *np = NULL;
620 STAILQ_FOREACH(np, queries, entries)
621 {
622 buf_reset(&value);
623
624 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, np->data);
625 if (he)
626 {
627 if (he->type & DT_DEPRECATED)
628 {
629 mutt_warning(_("Config variable '%s' is deprecated"), np->data);
630 rc = 1;
631 continue;
632 }
633
634 int rv = cs_subset_he_string_get(NeoMutt->sub, he, &value);
635 if (CSR_RESULT(rv) != CSR_SUCCESS)
636 {
637 rc = 1;
638 continue;
639 }
640
641 int type = DTYPE(he->type);
642 if (type == DT_PATH)
643 mutt_pretty_mailbox(value.data, value.dsize);
644
645 if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) && (type != DT_QUAD))
646 {
647 buf_reset(&tmp);
648 pretty_var(value.data, &tmp);
649 buf_strcpy(&value, tmp.data);
650 }
651
652 dump_config_neo(NeoMutt->sub->cs, he, &value, NULL,
653 show_docs ? CS_DUMP_SHOW_DOCS : CS_DUMP_NO_FLAGS, stdout);
654 continue;
655 }
656
657 mutt_warning(_("No such variable: %s"), np->data);
658 rc = 1;
659 }
660
661 buf_dealloc(&value);
662 buf_dealloc(&tmp);
663
664 return rc; // TEST16: neomutt -Q charset
665}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:86
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
size_t pretty_var(const char *str, struct Buffer *buf)
Escape and stringify a config item value.
Definition: dump.c:83
void dump_config_neo(struct ConfigSet *cs, struct HashElem *he, struct Buffer *value, struct Buffer *initial, ConfigDumpFlags flags, FILE *fp)
Dump the config in the style of NeoMutt.
Definition: dump.c:106
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:481
#define CS_DUMP_NO_FLAGS
No flags are set.
Definition: dump.h:35
#define CS_DUMP_SHOW_DOCS
Show one-liner documentation for the config item.
Definition: dump.h:45
size_t dsize
Length of data.
Definition: buffer.h:37
struct ConfigSet * cs
Parent ConfigSet.
Definition: subset.h:51
The item stored in a Hash Table.
Definition: hash.h:44
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:45
int cs_subset_he_string_get(const struct ConfigSubset *sub, struct HashElem *he, struct Buffer *result)
Get a config item as a string.
Definition: subset.c:359
struct HashElem * cs_subset_lookup(const struct ConfigSubset *sub, const char *name)
Find an inherited config item.
Definition: subset.c:184
#define DTYPE(x)
Mask for the Data Type.
Definition: types.h:45
#define DT_QUAD
quad-option (no/yes/ask-no/ask-yes)
Definition: types.h:37
#define DT_LONG
a number (long)
Definition: types.h:33
#define DT_BOOL
boolean option
Definition: types.h:30
#define DT_DEPRECATED
Config item shouldn't be used any more.
Definition: types.h:77
#define DT_PATH
a path to a file/directory
Definition: types.h:36
#define DT_NUMBER
a number
Definition: types.h:35
+ Here is the call graph for this function:
+ Here is the caller graph for this function: