NeoMutt  2023-11-03-107-g582dc1
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
init.c File Reference

Config/command parsing. More...

#include "config.h"
#include <errno.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 "gui/lib.h"
#include "init.h"
#include "color/lib.h"
#include "compmbox/lib.h"
#include "history/lib.h"
#include "imap/lib.h"
#include "key/lib.h"
#include "menu/lib.h"
#include "notmuch/lib.h"
#include "parse/lib.h"
#include "sidebar/lib.h"
#include "commands.h"
#include "globals.h"
#include "hook.h"
#include "mutt_logging.h"
#include "muttlib.h"
#include "protos.h"
#include "conn/lib.h"
#include "mutt_lua.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.
 
static char * find_cfg (const char *home, const char *xdg_cfg_home)
 Find a config file.
 
static char * getmailname (void)
 Try to retrieve the FQDN from mailname files.
 
static bool get_hostname (struct ConfigSet *cs)
 Find the Fully-Qualified Domain Name.
 
void mutt_opts_cleanup (void)
 Clean up before quitting.
 
int mutt_init (struct ConfigSet *cs, const char *dlevel, const char *dfile, bool skip_sys_rc, struct ListHead *commands)
 Initialise NeoMutt.
 
int mutt_query_variables (struct ListHead *queries, bool show_docs)
 Implement the -Q command line flag.
 

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 75 of file init.c.

76{
77 int rc = 0;
78 struct Buffer *err = buf_pool_get();
79
80 struct ListNode *np = NULL;
81 STAILQ_FOREACH(np, p, entries)
82 {
83 enum CommandResult rc2 = parse_rc_line(np->data, err);
84 if (rc2 == MUTT_CMD_ERROR)
85 mutt_error(_("Error in command line: %s"), buf_string(err));
86 else if (rc2 == MUTT_CMD_WARNING)
87 mutt_warning(_("Warning in command line: %s"), buf_string(err));
88
89 if ((rc2 == MUTT_CMD_ERROR) || (rc2 == MUTT_CMD_WARNING))
90 {
91 buf_pool_release(&err);
92 return -1;
93 }
94 }
95 buf_pool_release(&err);
96
97 return rc;
98}
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:93
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:90
#define mutt_error(...)
Definition: logging2.h:92
#define _(a)
Definition: message.h:28
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 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:104
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 107 of file init.c.

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

149{
150 char *mailname = NULL;
151 static const char *mn_files[] = { "/etc/mailname", "/etc/mail/mailname" };
152
153 for (size_t i = 0; i < mutt_array_size(mn_files); i++)
154 {
155 FILE *fp = mutt_file_fopen(mn_files[i], "r");
156 if (!fp)
157 continue;
158
159 size_t len = 0;
160 mailname = mutt_file_read_line(NULL, &len, fp, NULL, MUTT_RL_NO_FLAGS);
161 mutt_file_fclose(&fp);
162 if (mailname && *mailname)
163 break;
164
165 FREE(&mailname);
166 }
167
168 return mailname;
169}
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:763
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:636
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition: file.h:39
#define FREE(x)
Definition: memory.h:45
#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:

◆ 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 181 of file init.c.

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

◆ mutt_opts_cleanup()

void mutt_opts_cleanup ( void  )

Clean up before quitting.

Definition at line 260 of file init.c.

261{
263
265 sb_cleanup();
266
272
275
276 /* Lists of strings */
286
288
290 FREE(&HomeDir);
293 FREE(&Username);
294
296
298
301
304}
void alias_cleanup(void)
Clean up the Alias globals.
Definition: alias.c:689
void mutt_colors_cleanup(void)
Cleanup all the colours.
Definition: color.c:63
void source_stack_cleanup(void)
Free memory from the stack used for the source command.
Definition: commands.c:1621
char * HomeDir
User's home directory.
Definition: globals.c:39
void commands_cleanup(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_cleanup(void)
Free GroupList singleton resource.
Definition: group.c:107
void mutt_hist_cleanup(void)
Free all the history lists.
Definition: history.c:440
void mutt_delete_hooks(HookFlags type)
Delete matching hooks.
Definition: hook.c:375
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:36
void mutt_keys_cleanup(void)
Free the key maps.
Definition: init.c:230
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:175
void mutt_replacelist_free(struct ReplaceList *rl)
Free a ReplaceList object.
Definition: regex.c:472
void sb_cleanup(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,
const char *  dlevel,
const char *  dfile,
bool  skip_sys_rc,
struct ListHead *  commands 
)

Initialise NeoMutt.

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

Definition at line 316 of file init.c.

318{
319 bool need_pause = false;
320 int rc = 1;
321 struct Buffer err = buf_make(256);
322 struct Buffer buf = buf_make(256);
323
325 alias_init();
327 hooks_init();
329 imap_init();
330#ifdef USE_LUA
332#endif
334
335 menu_init();
336 sb_init();
337#ifdef USE_NOTMUCH
338 nm_init();
339#endif
340
341#ifdef NEOMUTT_DIRECT_COLORS
342 /* Test if we run in a terminal which supports direct colours.
343 *
344 * The user/terminal can indicate their capability independent of the
345 * terminfo file by setting the COLORTERM environment variable to "truecolor"
346 * or "24bit" (case sensitive).
347 *
348 * Note: This is to test is less about whether the terminal understands
349 * direct color commands but more about whether ncurses believes it can send
350 * them to the terminal, e.g. ncurses ignores COLORTERM.
351 */
352 if (COLORS == 16777216) // 2^24
353 {
354 /* Ncurses believes the Terminal supports it check the environment variable
355 * to respect the user's choice */
356 const char *env_colorterm = mutt_str_getenv("COLORTERM");
357 if (env_colorterm && (mutt_str_equal(env_colorterm, "truecolor") ||
358 mutt_str_equal(env_colorterm, "24bit")))
359 {
360 cs_str_initial_set(cs, "color_directcolor", "yes", NULL);
361 cs_str_reset(cs, "color_directcolor", NULL);
362 }
363 }
364#endif
365
366 /* "$spool_file" precedence: config file, environment */
367 const char *p = mutt_str_getenv("MAIL");
368 if (!p)
369 p = mutt_str_getenv("MAILDIR");
370 if (!p)
371 {
372#ifdef HOMESPOOL
373 buf_concat_path(&buf, NONULL(HomeDir), MAILPATH);
374#else
375 buf_concat_path(&buf, MAILPATH, NONULL(Username));
376#endif
377 p = buf_string(&buf);
378 }
379 cs_str_initial_set(cs, "spool_file", p, NULL);
380 cs_str_reset(cs, "spool_file", NULL);
381
382 p = mutt_str_getenv("REPLYTO");
383 if (p)
384 {
385 struct Buffer *token = buf_pool_get();
386
387 buf_printf(&buf, "Reply-To: %s", p);
388 parse_my_hdr(token, &buf, 0, &err); /* adds to UserHeader */
389 buf_pool_release(&token);
390 }
391
392 p = mutt_str_getenv("EMAIL");
393 if (p)
394 {
395 cs_str_initial_set(cs, "from", p, NULL);
396 cs_str_reset(cs, "from", NULL);
397 }
398
399 /* "$mailcap_path" precedence: config file, environment, code */
400 const char *env_mc = mutt_str_getenv("MAILCAPS");
401 if (env_mc)
402 {
403 cs_str_initial_set(cs, "mailcap_path", env_mc, NULL);
404 cs_str_reset(cs, "mailcap_path", NULL);
405 }
406
407 /* "$tmp_dir" precedence: config file, environment, code */
408 const char *env_tmp = mutt_str_getenv("TMPDIR");
409 if (env_tmp)
410 {
411 cs_str_initial_set(cs, "tmp_dir", env_tmp, NULL);
412 cs_str_reset(cs, "tmp_dir", NULL);
413 }
414
415 /* "$visual", "$editor" precedence: config file, environment, code */
416 const char *env_ed = mutt_str_getenv("VISUAL");
417 if (!env_ed)
418 env_ed = mutt_str_getenv("EDITOR");
419 if (!env_ed)
420 env_ed = "vi";
421 cs_str_initial_set(cs, "editor", env_ed, NULL);
422
423 const char *const c_editor = cs_subset_string(NeoMutt->sub, "editor");
424 if (!c_editor)
425 cs_str_reset(cs, "editor", NULL);
426
427 const char *charset = mutt_ch_get_langinfo_charset();
428 cs_str_initial_set(cs, "charset", charset, NULL);
429 cs_str_reset(cs, "charset", NULL);
430 mutt_ch_set_charset(charset);
431 FREE(&charset);
432
433#ifdef HAVE_GETSID
434 /* Unset suspend by default if we're the session leader */
435 if (getsid(0) == getpid())
436 {
437 cs_str_initial_set(cs, "suspend", "no", NULL);
438 cs_str_reset(cs, "suspend", NULL);
439 }
440#endif
441
442 /* RFC2368, "4. Unsafe headers"
443 * The creator of a mailto URL can't expect the resolver of a URL to
444 * understand more than the "subject" and "body" headers. Clients that
445 * resolve mailto URLs into mail messages should be able to correctly
446 * create RFC822-compliant mail messages using the "subject" and "body"
447 * headers. */
448 add_to_stailq(&MailToAllow, "body");
449 add_to_stailq(&MailToAllow, "subject");
450 /* Cc, In-Reply-To, and References help with not breaking threading on
451 * mailing lists, see https://github.com/neomutt/neomutt/issues/115 */
453 add_to_stailq(&MailToAllow, "in-reply-to");
454 add_to_stailq(&MailToAllow, "references");
455
456 if (STAILQ_EMPTY(&Muttrc))
457 {
458 const char *xdg_cfg_home = mutt_str_getenv("XDG_CONFIG_HOME");
459
460 if (!xdg_cfg_home && HomeDir)
461 {
462 buf_printf(&buf, "%s/.config", HomeDir);
463 xdg_cfg_home = buf_string(&buf);
464 }
465
466 char *config = find_cfg(HomeDir, xdg_cfg_home);
467 if (config)
468 {
470 }
471 }
472 else
473 {
474 struct ListNode *np = NULL;
475 STAILQ_FOREACH(np, &Muttrc, entries)
476 {
477 buf_strcpy(&buf, np->data);
478 FREE(&np->data);
479 buf_expand_path(&buf);
480 np->data = buf_strdup(&buf);
481 if (access(np->data, F_OK))
482 {
483 mutt_perror("%s", np->data);
484 goto done; // TEST10: neomutt -F missing
485 }
486 }
487 }
488
489 if (!STAILQ_EMPTY(&Muttrc))
490 {
491 cs_str_string_set(cs, "alias_file", STAILQ_FIRST(&Muttrc)->data, NULL);
492 }
493
494 /* Process the global rc file if it exists and the user hasn't explicitly
495 * requested not to via "-n". */
496 if (!skip_sys_rc)
497 {
498 do
499 {
501 break;
502
503 buf_printf(&buf, "%s/neomuttrc", SYSCONFDIR);
504 if (access(buf_string(&buf), F_OK) == 0)
505 break;
506
507 buf_printf(&buf, "%s/Muttrc", SYSCONFDIR);
508 if (access(buf_string(&buf), F_OK) == 0)
509 break;
510
511 buf_printf(&buf, "%s/neomuttrc", PKGDATADIR);
512 if (access(buf_string(&buf), F_OK) == 0)
513 break;
514
515 buf_printf(&buf, "%s/Muttrc", PKGDATADIR);
516 } while (false);
517
518 if (access(buf_string(&buf), F_OK) == 0)
519 {
520 if (source_rc(buf_string(&buf), &err) != 0)
521 {
522 mutt_error("%s", err.data);
523 need_pause = true; // TEST11: neomutt (error in /etc/neomuttrc)
524 }
525 }
526 }
527
528 /* Read the user's initialization file. */
529 struct ListNode *np = NULL;
530 STAILQ_FOREACH(np, &Muttrc, entries)
531 {
532 if (np->data)
533 {
534 if (source_rc(np->data, &err) != 0)
535 {
536 mutt_error("%s", err.data);
537 need_pause = true; // TEST12: neomutt (error in ~/.neomuttrc)
538 }
539 }
540 }
541
542 if (execute_commands(commands) != 0)
543 need_pause = true; // TEST13: neomutt -e broken
544
545 if (!get_hostname(cs))
546 goto done;
547
548 char name[256] = { 0 };
549 const char *c_real_name = cs_subset_string(NeoMutt->sub, "real_name");
550 if (!c_real_name)
551 {
552 struct passwd *pw = getpwuid(getuid());
553 if (pw)
554 {
555 c_real_name = mutt_gecos_name(name, sizeof(name), pw);
556 }
557 }
558 cs_str_initial_set(cs, "real_name", c_real_name, NULL);
559 cs_str_reset(cs, "real_name", NULL);
560
561 /* The command line overrides the config */
562 if (dlevel)
563 cs_str_reset(cs, "debug_level", NULL);
564 if (dfile)
565 cs_str_reset(cs, "debug_file", NULL);
566
567 if (mutt_log_start() < 0)
568 {
569 mutt_perror("log file");
570 goto done;
571 }
572
573 if (need_pause && !OptNoCurses)
574 {
576 if (mutt_any_key_to_continue(NULL) == 'q')
577 goto done; // TEST14: neomutt -e broken (press 'q')
578 }
579
580 const char *const c_tmp_dir = cs_subset_path(NeoMutt->sub, "tmp_dir");
581 if (mutt_file_mkdir(c_tmp_dir, S_IRWXU) < 0)
582 {
583 mutt_error(_("Can't create %s: %s"), c_tmp_dir, strerror(errno));
584 goto done;
585 }
586
589
590#ifdef USE_NOTMUCH
591 const bool c_virtual_spool_file = cs_subset_bool(NeoMutt->sub, "virtual_spool_file");
592 if (c_virtual_spool_file)
593 {
594 /* Find the first virtual folder and open it */
595 struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
597 struct MailboxNode *mp = STAILQ_FIRST(&ml);
598 if (mp)
599 cs_str_string_set(cs, "spool_file", mailbox_path(mp->mailbox), NULL);
601 }
602#endif
603 rc = 0;
604
605done:
606 buf_dealloc(&err);
607 buf_dealloc(&buf);
608 return rc;
609}
void alias_init(void)
Set up the Alias globals.
Definition: alias.c:681
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:173
void buf_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:389
struct Buffer buf_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:70
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:407
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:542
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 commands_init(void)
Initialize commands array and register default commands.
Definition: commands.c:1697
int source_rc(const char *rcfile_path, struct Buffer *err)
Read an initialization file.
Definition: commands.c:199
void mutt_comp_init(void)
Setup feature commands.
Definition: compress.c:73
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:169
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:48
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:184
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:977
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: globals.c:77
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:808
int log_disp_terminal(time_t stamp, const char *file, int line, const char *function, enum LogLevel level, const char *format,...)
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:1020
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:107
static int execute_commands(struct ListHead *p)
Execute a set of NeoMutt commands.
Definition: init.c:75
static bool get_hostname(struct ConfigSet *cs)
Find the Fully-Qualified Domain Name.
Definition: init.c:181
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:210
@ 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:481
void mutt_ch_set_charset(const char *charset)
Update the records for a new character set.
Definition: charset.c:1073
void log_queue_flush(log_dispatcher_t disp)
Replay the log queue.
Definition: logging.c:345
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:763
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition: string.c:862
int mutt_log_start(void)
Enable file logging.
Definition: mutt_logging.c:247
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:368
void add_to_stailq(struct ListHead *head, const char *str)
Add a string to a list.
Definition: muttlib.c:1687
int mutt_set_xdg_path(enum XdgType type, struct Buffer *buf)
Find an XDG path or its fallback.
Definition: muttlib.c:1472
void buf_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:329
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:162
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:185
void nm_init(void)
Setup feature commands.
Definition: notmuch.c:100
@ 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:153
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:154
void driver_tags_init(void)
Initialize structures used for tags.
Definition: tags.c:218
+ 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 618 of file init.c.

619{
620 struct Buffer value = buf_make(256);
621 struct Buffer tmp = buf_make(256);
622 int rc = 0;
623
624 struct ListNode *np = NULL;
625 STAILQ_FOREACH(np, queries, entries)
626 {
627 buf_reset(&value);
628
629 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, np->data);
630 if (he)
631 {
632 if (he->type & DT_DEPRECATED)
633 {
634 mutt_warning(_("Config variable '%s' is deprecated"), np->data);
635 rc = 1;
636 continue;
637 }
638
639 int rv = cs_subset_he_string_get(NeoMutt->sub, he, &value);
640 if (CSR_RESULT(rv) != CSR_SUCCESS)
641 {
642 rc = 1;
643 continue;
644 }
645
646 int type = DTYPE(he->type);
647 if (type == DT_PATH)
648 mutt_pretty_mailbox(value.data, value.dsize);
649
650 if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) && (type != DT_QUAD))
651 {
652 buf_reset(&tmp);
653 pretty_var(value.data, &tmp);
654 buf_strcpy(&value, tmp.data);
655 }
656
657 dump_config_neo(NeoMutt->sub->cs, he, &value, NULL,
658 show_docs ? CS_DUMP_SHOW_DOCS : CS_DUMP_NO_FLAGS, stdout);
659 continue;
660 }
661
662 mutt_warning(_("No such variable: %s"), np->data);
663 rc = 1;
664 }
665
666 buf_dealloc(&value);
667 buf_dealloc(&tmp);
668
669 return rc; // TEST16: neomutt -Q charset
670}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:88
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:477
#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
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
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:353
struct HashElem * cs_subset_lookup(const struct ConfigSubset *sub, const char *name)
Find an inherited config item.
Definition: subset.c:178
#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:78
#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: