NeoMutt  2022-04-29-215-gc12b98
Teaching an old dog new tricks
DOXYGEN
init.h File Reference

Config/command parsing. More...

#include <stdbool.h>
#include "core/lib.h"
#include "mutt.h"
+ Include dependency graph for init.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void init_config (struct ConfigSet *cs)
 Initialise the config system. More...
 
int mutt_extract_token (struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
 Extract one token from a string. More...
 
int mutt_init (struct ConfigSet *cs, bool skip_sys_rc, struct ListHead *commands)
 Initialise NeoMutt. More...
 
void mutt_opts_free (void)
 Clean up before quitting. More...
 
enum CommandResult mutt_parse_rc_buffer (struct Buffer *line, struct Buffer *token, struct Buffer *err)
 Parse a line of user config. More...
 
enum CommandResult mutt_parse_rc_line (const char *line, struct Buffer *err)
 Parse a line of user config. 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
  • g10 Code GmbH

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.h.

Function Documentation

◆ init_config()

void init_config ( struct ConfigSet cs)

Initialise the config system.

Parameters
csConfig items

Definition at line 785 of file mutt_config.c.

786{
787 init_types(cs);
788 init_variables(cs);
789}
static void init_types(struct ConfigSet *cs)
Create the config types.
Definition: mutt_config.c:720
static void init_variables(struct ConfigSet *cs)
Define the config variables.
Definition: mutt_config.c:740
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_extract_token()

int mutt_extract_token ( struct Buffer dest,
struct Buffer tok,
TokenFlags  flags 
)

Extract one token from a string.

Parameters
destBuffer for the result
tokBuffer containing tokens
flagsFlags, see TokenFlags
Return values
0Success
-1Error

Definition at line 273 of file init.c.

274{
275 if (!dest || !tok)
276 return -1;
277
278 char ch;
279 char qc = '\0'; /* quote char */
280 char *pc = NULL;
281
282 /* Some callers used to rely on the (bad) assumption that dest->data would be
283 * non-NULL after calling this function. Perhaps I've missed a few cases, or
284 * a future caller might make the same mistake. */
285 if (!dest->data)
286 mutt_buffer_alloc(dest, 256);
287
288 mutt_buffer_reset(dest);
289
290 SKIPWS(tok->dptr);
291 while ((ch = *tok->dptr))
292 {
293 if (qc == '\0')
294 {
295 if ((IS_SPACE(ch) && !(flags & MUTT_TOKEN_SPACE)) ||
296 ((ch == '#') && !(flags & MUTT_TOKEN_COMMENT)) ||
297 ((ch == '+') && (flags & MUTT_TOKEN_PLUS)) ||
298 ((ch == '-') && (flags & MUTT_TOKEN_MINUS)) ||
299 ((ch == '=') && (flags & MUTT_TOKEN_EQUAL)) ||
300 ((ch == '?') && (flags & MUTT_TOKEN_QUESTION)) ||
301 ((ch == ';') && !(flags & MUTT_TOKEN_SEMICOLON)) ||
302 ((flags & MUTT_TOKEN_PATTERN) && strchr("~%=!|", ch)))
303 {
304 break;
305 }
306 }
307
308 tok->dptr++;
309
310 if (ch == qc)
311 qc = 0; /* end of quote */
312 else if (!qc && ((ch == '\'') || (ch == '"')) && !(flags & MUTT_TOKEN_QUOTE))
313 qc = ch;
314 else if ((ch == '\\') && (qc != '\''))
315 {
316 if (tok->dptr[0] == '\0')
317 return -1; /* premature end of token */
318 switch (ch = *tok->dptr++)
319 {
320 case 'c':
321 case 'C':
322 if (tok->dptr[0] == '\0')
323 return -1; /* premature end of token */
324 mutt_buffer_addch(dest, (toupper((unsigned char) tok->dptr[0]) - '@') & 0x7f);
325 tok->dptr++;
326 break;
327 case 'e':
328 mutt_buffer_addch(dest, '\033'); // Escape
329 break;
330 case 'f':
331 mutt_buffer_addch(dest, '\f');
332 break;
333 case 'n':
334 mutt_buffer_addch(dest, '\n');
335 break;
336 case 'r':
337 mutt_buffer_addch(dest, '\r');
338 break;
339 case 't':
340 mutt_buffer_addch(dest, '\t');
341 break;
342 default:
343 if (isdigit((unsigned char) ch) && isdigit((unsigned char) tok->dptr[0]) &&
344 isdigit((unsigned char) tok->dptr[1]))
345 {
346 mutt_buffer_addch(dest, (ch << 6) + (tok->dptr[0] << 3) + tok->dptr[1] - 3504);
347 tok->dptr += 2;
348 }
349 else
350 mutt_buffer_addch(dest, ch);
351 }
352 }
353 else if ((ch == '^') && (flags & MUTT_TOKEN_CONDENSE))
354 {
355 if (tok->dptr[0] == '\0')
356 return -1; /* premature end of token */
357 ch = *tok->dptr++;
358 if (ch == '^')
359 mutt_buffer_addch(dest, ch);
360 else if (ch == '[')
361 mutt_buffer_addch(dest, '\033'); // Escape
362 else if (isalpha((unsigned char) ch))
363 mutt_buffer_addch(dest, toupper((unsigned char) ch) - '@');
364 else
365 {
366 mutt_buffer_addch(dest, '^');
367 mutt_buffer_addch(dest, ch);
368 }
369 }
370 else if ((ch == '`') && (!qc || (qc == '"')))
371 {
372 FILE *fp = NULL;
373 pid_t pid;
374
375 pc = tok->dptr;
376 do
377 {
378 pc = strpbrk(pc, "\\`");
379 if (pc)
380 {
381 /* skip any quoted chars */
382 if (*pc == '\\')
383 pc += 2;
384 }
385 } while (pc && (pc[0] != '`'));
386 if (!pc)
387 {
388 mutt_debug(LL_DEBUG1, "mismatched backticks\n");
389 return -1;
390 }
391 struct Buffer cmd;
392 mutt_buffer_init(&cmd);
393 *pc = '\0';
394 if (flags & MUTT_TOKEN_BACKTICK_VARS)
395 {
396 /* recursively extract tokens to interpolate variables */
397 mutt_extract_token(&cmd, tok,
400 }
401 else
402 {
403 cmd.data = mutt_str_dup(tok->dptr);
404 }
405 *pc = '`';
406 pid = filter_create(cmd.data, NULL, &fp, NULL);
407 if (pid < 0)
408 {
409 mutt_debug(LL_DEBUG1, "unable to fork command: %s\n", cmd.data);
410 FREE(&cmd.data);
411 return -1;
412 }
413
414 tok->dptr = pc + 1;
415
416 /* read line */
417 struct Buffer expn = mutt_buffer_make(0);
418 expn.data = mutt_file_read_line(NULL, &expn.dsize, fp, NULL, MUTT_RL_NO_FLAGS);
419 mutt_file_fclose(&fp);
420 int rc = filter_wait(pid);
421 if (rc != 0)
422 mutt_debug(LL_DEBUG1, "backticks exited code %d for command: %s\n", rc,
423 mutt_buffer_string(&cmd));
424 FREE(&cmd.data);
425
426 /* if we got output, make a new string consisting of the shell output
427 * plus whatever else was left on the original line */
428 /* BUT: If this is inside a quoted string, directly add output to
429 * the token */
430 if (expn.data)
431 {
432 if (qc)
433 {
434 mutt_buffer_addstr(dest, expn.data);
435 }
436 else
437 {
438 struct Buffer *copy = mutt_buffer_pool_get();
440 mutt_buffer_copy(copy, &expn);
441 mutt_buffer_addstr(copy, tok->dptr);
442 mutt_buffer_copy(tok, copy);
443 mutt_buffer_seek(tok, 0);
445 }
446 FREE(&expn.data);
447 }
448 }
449 else if ((ch == '$') && (!qc || (qc == '"')) &&
450 ((tok->dptr[0] == '{') || isalpha((unsigned char) tok->dptr[0])))
451 {
452 const char *env = NULL;
453 char *var = NULL;
454
455 if (tok->dptr[0] == '{')
456 {
457 pc = strchr(tok->dptr, '}');
458 if (pc)
459 {
460 var = mutt_strn_dup(tok->dptr + 1, pc - (tok->dptr + 1));
461 tok->dptr = pc + 1;
462
463 if ((flags & MUTT_TOKEN_NOSHELL))
464 {
465 mutt_buffer_addch(dest, ch);
466 mutt_buffer_addch(dest, '{');
467 mutt_buffer_addstr(dest, var);
468 mutt_buffer_addch(dest, '}');
469 FREE(&var);
470 }
471 }
472 }
473 else
474 {
475 for (pc = tok->dptr; isalnum((unsigned char) *pc) || (pc[0] == '_'); pc++)
476 ; // do nothing
477
478 var = mutt_strn_dup(tok->dptr, pc - tok->dptr);
479 tok->dptr = pc;
480 }
481 if (var)
482 {
483 struct Buffer result;
484 mutt_buffer_init(&result);
485 int rc = cs_subset_str_string_get(NeoMutt->sub, var, &result);
486
487 if (CSR_RESULT(rc) == CSR_SUCCESS)
488 {
489 mutt_buffer_addstr(dest, result.data);
490 FREE(&result.data);
491 }
492 else if ((env = myvar_get(var)))
493 {
494 mutt_buffer_addstr(dest, env);
495 }
496 else if (!(flags & MUTT_TOKEN_NOSHELL) && (env = mutt_str_getenv(var)))
497 {
498 mutt_buffer_addstr(dest, env);
499 }
500 else
501 {
502 mutt_buffer_addch(dest, ch);
503 mutt_buffer_addstr(dest, var);
504 }
505 FREE(&var);
506 }
507 }
508 else
509 mutt_buffer_addch(dest, ch);
510 }
511 mutt_buffer_addch(dest, 0); /* terminate the string */
512 SKIPWS(tok->dptr);
513 return 0;
514}
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:67
void mutt_buffer_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:275
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:52
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:248
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:233
void mutt_buffer_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:189
void mutt_buffer_seek(struct Buffer *buf, size_t offset)
Set current read/write position to offset from beginning.
Definition: buffer.c:483
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition: buffer.c:462
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:85
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
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:720
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:38
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:273
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
#define FREE(x)
Definition: memory.h:43
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:451
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition: string.c:927
#define MUTT_TOKEN_CONDENSE
^(char) to control chars (macros)
Definition: mutt.h:69
#define MUTT_TOKEN_BACKTICK_VARS
Expand variables within backticks.
Definition: mutt.h:75
#define MUTT_TOKEN_MINUS
Treat '-' as a special.
Definition: mutt.h:79
#define MUTT_TOKEN_PLUS
Treat '+' as a special.
Definition: mutt.h:78
#define MUTT_TOKEN_COMMENT
Don't reap comments.
Definition: mutt.h:73
#define MUTT_TOKEN_QUOTE
Don't interpret quotes.
Definition: mutt.h:71
#define MUTT_TOKEN_NOSHELL
Don't expand environment variables.
Definition: mutt.h:76
#define MUTT_TOKEN_SPACE
Don't treat whitespace as a term.
Definition: mutt.h:70
#define MUTT_TOKEN_SEMICOLON
Don't treat ; as special.
Definition: mutt.h:74
#define MUTT_TOKEN_PATTERN
~%=!| are terms (for patterns)
Definition: mutt.h:72
#define MUTT_TOKEN_EQUAL
Treat '=' as a special.
Definition: mutt.h:68
#define MUTT_TOKEN_QUESTION
Treat '?' as a special.
Definition: mutt.h:77
const char * myvar_get(const char *var)
Get the value of a "my_" variable.
Definition: myvar.c:92
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
#define IS_SPACE(ch)
Definition: string2.h:38
#define SKIPWS(ch)
Definition: string2.h:46
String manipulation buffer.
Definition: buffer.h:34
char * dptr
Current read/write position.
Definition: buffer.h:36
size_t dsize
Length of data.
Definition: buffer.h:37
char * data
Pointer to data.
Definition: buffer.h:35
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int cs_subset_str_string_get(const struct ConfigSubset *sub, const char *name, struct Buffer *result)
Get a config item as a string.
Definition: subset.c:370
+ Here is the call 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 575 of file init.c.

576{
577 int need_pause = 0;
578 int rc = 1;
579 struct Buffer err = mutt_buffer_make(256);
580 struct Buffer buf = mutt_buffer_make(256);
581
583 alias_init();
585#ifdef USE_COMP_MBOX
587#endif
588#ifdef USE_IMAP
589 imap_init();
590#endif
591#ifdef USE_LUA
593#endif
595
596 menu_init();
597#ifdef USE_SIDEBAR
598 sb_init();
599#endif
600#ifdef USE_NOTMUCH
601 nm_init();
602#endif
603
604 /* "$spool_file" precedence: config file, environment */
605 const char *p = mutt_str_getenv("MAIL");
606 if (!p)
607 p = mutt_str_getenv("MAILDIR");
608 if (!p)
609 {
610#ifdef HOMESPOOL
611 mutt_buffer_concat_path(&buf, NONULL(HomeDir), MAILPATH);
612#else
613 mutt_buffer_concat_path(&buf, MAILPATH, NONULL(Username));
614#endif
615 p = mutt_buffer_string(&buf);
616 }
617 cs_str_initial_set(cs, "spool_file", p, NULL);
618 cs_str_reset(cs, "spool_file", NULL);
619
620 p = mutt_str_getenv("REPLYTO");
621 if (p)
622 {
623 struct Buffer token;
624
625 mutt_buffer_printf(&buf, "Reply-To: %s", p);
626 mutt_buffer_init(&token);
627 parse_my_hdr(&token, &buf, 0, &err); /* adds to UserHeader */
628 FREE(&token.data);
629 }
630
631 p = mutt_str_getenv("EMAIL");
632 if (p)
633 {
634 cs_str_initial_set(cs, "from", p, NULL);
635 cs_str_reset(cs, "from", NULL);
636 }
637
638 /* "$mailcap_path" precedence: config file, environment, code */
639 const char *env_mc = mutt_str_getenv("MAILCAPS");
640 if (env_mc)
641 cs_str_string_set(cs, "mailcap_path", env_mc, NULL);
642
643 /* "$tmpdir" precedence: config file, environment, code */
644 const char *env_tmp = mutt_str_getenv("TMPDIR");
645 if (env_tmp)
646 cs_str_string_set(cs, "tmpdir", env_tmp, NULL);
647
648 /* "$visual", "$editor" precedence: config file, environment, code */
649 const char *env_ed = mutt_str_getenv("VISUAL");
650 if (!env_ed)
651 env_ed = mutt_str_getenv("EDITOR");
652 if (!env_ed)
653 env_ed = "vi";
654 cs_str_initial_set(cs, "editor", env_ed, NULL);
655
656 const char *const c_editor = cs_subset_string(NeoMutt->sub, "editor");
657 if (!c_editor)
658 cs_str_reset(cs, "editor", NULL);
659
660 const char *charset = mutt_ch_get_langinfo_charset();
661 cs_str_initial_set(cs, "charset", charset, NULL);
662 cs_str_reset(cs, "charset", NULL);
663 mutt_ch_set_charset(charset);
664 FREE(&charset);
665
666#ifdef HAVE_GETSID
667 /* Unset suspend by default if we're the session leader */
668 if (getsid(0) == getpid())
669 cs_subset_str_native_set(NeoMutt->sub, "suspend", false, NULL);
670#endif
671
672 /* RFC2368, "4. Unsafe headers"
673 * The creator of a mailto URL can't expect the resolver of a URL to
674 * understand more than the "subject" and "body" headers. Clients that
675 * resolve mailto URLs into mail messages should be able to correctly
676 * create RFC822-compliant mail messages using the "subject" and "body"
677 * headers. */
678 add_to_stailq(&MailToAllow, "body");
679 add_to_stailq(&MailToAllow, "subject");
680 /* Cc, In-Reply-To, and References help with not breaking threading on
681 * mailing lists, see https://github.com/neomutt/neomutt/issues/115 */
683 add_to_stailq(&MailToAllow, "in-reply-to");
684 add_to_stailq(&MailToAllow, "references");
685
686 if (STAILQ_EMPTY(&Muttrc))
687 {
688 const char *xdg_cfg_home = mutt_str_getenv("XDG_CONFIG_HOME");
689
690 if (!xdg_cfg_home && HomeDir)
691 {
692 mutt_buffer_printf(&buf, "%s/.config", HomeDir);
693 xdg_cfg_home = mutt_buffer_string(&buf);
694 }
695
696 char *config = find_cfg(HomeDir, xdg_cfg_home);
697 if (config)
698 {
700 }
701 }
702 else
703 {
704 struct ListNode *np = NULL;
705 STAILQ_FOREACH(np, &Muttrc, entries)
706 {
707 mutt_buffer_strcpy(&buf, np->data);
708 FREE(&np->data);
710 np->data = mutt_buffer_strdup(&buf);
711 if (access(np->data, F_OK))
712 {
713 mutt_perror(np->data);
714 goto done; // TEST10: neomutt -F missing
715 }
716 }
717 }
718
719 if (!STAILQ_EMPTY(&Muttrc))
720 {
721 cs_str_string_set(cs, "alias_file", STAILQ_FIRST(&Muttrc)->data, NULL);
722 }
723
724 /* Process the global rc file if it exists and the user hasn't explicitly
725 * requested not to via "-n". */
726 if (!skip_sys_rc)
727 {
728 do
729 {
731 break;
732
733 mutt_buffer_printf(&buf, "%s/neomuttrc", SYSCONFDIR);
734 if (access(mutt_buffer_string(&buf), F_OK) == 0)
735 break;
736
737 mutt_buffer_printf(&buf, "%s/Muttrc", SYSCONFDIR);
738 if (access(mutt_buffer_string(&buf), F_OK) == 0)
739 break;
740
741 mutt_buffer_printf(&buf, "%s/neomuttrc", PKGDATADIR);
742 if (access(mutt_buffer_string(&buf), F_OK) == 0)
743 break;
744
745 mutt_buffer_printf(&buf, "%s/Muttrc", PKGDATADIR);
746 } while (false);
747
748 if (access(mutt_buffer_string(&buf), F_OK) == 0)
749 {
750 if (source_rc(mutt_buffer_string(&buf), &err) != 0)
751 {
752 mutt_error("%s", err.data);
753 need_pause = 1; // TEST11: neomutt (error in /etc/neomuttrc)
754 }
755 }
756 }
757
758 /* Read the user's initialization file. */
759 struct ListNode *np = NULL;
760 STAILQ_FOREACH(np, &Muttrc, entries)
761 {
762 if (np->data)
763 {
764 if (source_rc(np->data, &err) != 0)
765 {
766 mutt_error("%s", err.data);
767 need_pause = 1; // TEST12: neomutt (error in ~/.neomuttrc)
768 }
769 }
770 }
771
772 if (execute_commands(commands) != 0)
773 need_pause = 1; // TEST13: neomutt -e broken
774
775 if (!get_hostname(cs))
776 goto done;
777
778 {
779 char name[256] = { 0 };
780 const char *c_real_name = cs_subset_string(NeoMutt->sub, "real_name");
781 if (!c_real_name)
782 {
783 struct passwd *pw = getpwuid(getuid());
784 if (pw)
785 c_real_name = mutt_gecos_name(name, sizeof(name), pw);
786 }
787 cs_str_initial_set(cs, "real_name", c_real_name, NULL);
788 cs_str_reset(cs, "real_name", NULL);
789 }
790
791 if (need_pause && !OptNoCurses)
792 {
794 if (mutt_any_key_to_continue(NULL) == 'q')
795 goto done; // TEST14: neomutt -e broken (press 'q')
796 }
797
798 const char *const c_tmpdir = cs_subset_path(NeoMutt->sub, "tmpdir");
799 mutt_file_mkdir(c_tmpdir, S_IRWXU);
800
803
804#ifdef USE_NOTMUCH
805 const bool c_virtual_spool_file = cs_subset_bool(NeoMutt->sub, "virtual_spool_file");
806 if (c_virtual_spool_file)
807 {
808 /* Find the first virtual folder and open it */
809 struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
811 struct MailboxNode *mp = STAILQ_FIRST(&ml);
812 if (mp)
813 cs_str_string_set(cs, "spool_file", mailbox_path(mp->mailbox), NULL);
815 }
816#endif
817 rc = 0;
818
819done:
822 return rc;
823}
void alias_init(void)
Set up the Alias globals.
Definition: alias.c:679
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:327
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:309
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:168
char * mutt_buffer_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:447
size_t mutt_buffer_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:389
int source_rc(const char *rcfile_path, struct Buffer *err)
Read an initialization file.
void mutt_comp_init(void)
Setup feature commands.
Definition: compress.c:70
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
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
char * HomeDir
User's home directory.
Definition: mutt_globals.h:49
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:387
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:930
struct ListHead MailToAllow
List of permitted fields in a mailto: url.
Definition: globals.c:37
void mutt_grouplist_init(void)
Initialize the GroupList singleton.
Definition: group.c:90
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() -.
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
#define mutt_error(...)
Definition: logging.h:87
#define mutt_perror(...)
Definition: logging.h:88
void mutt_hist_read_file(void)
Read the History from a file.
Definition: history.c:593
void mutt_hist_init(void)
Create a set of empty History ring buffers.
Definition: history.c:465
void imap_init(void)
Setup feature commands.
Definition: imap.c:84
static char * find_cfg(const char *home, const char *xdg_cfg_home)
Find a config file.
Definition: init.c:114
static int execute_commands(struct ListHead *p)
Execute a set of NeoMutt commands.
Definition: init.c:82
static bool get_hostname(struct ConfigSet *cs)
Find the Fully-Qualified Domain Name.
Definition: init.c:187
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:210
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition: mailbox.h:51
void menu_init(void)
Initialise all the Menus.
Definition: menu.c:74
char * mutt_ch_get_langinfo_charset(void)
Get the user's choice of character set.
Definition: charset.c:461
void mutt_ch_set_charset(const char *charset)
Update the records for a new character set.
Definition: charset.c:1002
void mutt_commands_init(void)
Initialize commands array and register default commands.
struct CommandArray commands
struct ListHead Muttrc
List of config files to read.
Definition: mutt_globals.h:64
char * Username
User's login name.
Definition: mutt_globals.h:52
void mutt_lua_init(void)
Setup feature commands.
Definition: mutt_lua.c:469
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:322
char * mutt_gecos_name(char *dest, size_t destlen, struct passwd *pw)
Lookup a user's real name in /etc/passwd.
Definition: muttlib.c:361
void add_to_stailq(struct ListHead *head, const char *str)
Add a string to a list.
Definition: muttlib.c:1719
int mutt_set_xdg_path(enum XdgType type, struct Buffer *buf)
Find an XDG path or its fallback.
Definition: muttlib.c:1510
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:99
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:53
@ 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_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_EMPTY(head)
Definition: queue.h:348
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:458
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:393
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:595
void sb_init(void)
Set up the Sidebar.
Definition: sidebar.c:196
#define NONULL(x)
Definition: string2.h:37
A List node for strings.
Definition: list.h:35
char * data
String.
Definition: list.h:36
List of Mailboxes.
Definition: mailbox.h:153
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:154
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:305
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_opts_free()

void mutt_opts_free ( void  )

Clean up before quitting.

Definition at line 519 of file init.c.

520{
522
524#ifdef USE_SIDEBAR
525 sb_shutdown();
526#endif
527
533
536
537 /* Lists of strings */
547
549
551 FREE(&HomeDir);
554 FREE(&Username);
555
557
559
562
565}
void alias_shutdown(void)
Clean up the Alias globals.
Definition: alias.c:687
void mutt_colors_cleanup(void)
Cleanup all the colours.
Definition: color.c:70
void clear_source_stack(void)
Free memory from the stack used for the source command.
struct ReplaceList SpamList
List of regexes and patterns to match spam emails.
Definition: globals.c:34
struct RegexList SubscribedLists
List of regexes to match subscribed mailing lists.
Definition: globals.c:43
struct RegexList UnSubscribedLists
List of regexes to blacklist false matches in SubscribedLists.
Definition: globals.c:40
struct RegexList UnMailLists
List of regexes to blacklist false matches in MailLists.
Definition: globals.c:42
struct RegexList MailLists
List of regexes to match mailing lists.
Definition: globals.c:41
struct ListHead Ignore
List of header patterns to ignore.
Definition: globals.c:35
struct RegexList NoSpamList
List of regexes to whitelist non-spam emails.
Definition: globals.c:33
struct ListHead UnIgnore
List of header patterns to unignore (see)
Definition: globals.c:36
void mutt_grouplist_free(void)
Free GroupList singleton resource.
Definition: group.c:102
void mutt_hist_free(void)
Free all the history lists.
Definition: history.c:438
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:1668
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:467
void mutt_commands_free(void)
Free Commands array.
char * LastFolder
Previously selected mailbox.
Definition: mutt_globals.h:55
char * ShortHostname
Short version of the hostname.
Definition: mutt_globals.h:50
struct ListHead MimeLookupList
List of mime types that that shouldn't use the mailcap entry.
Definition: mutt_globals.h:63
struct ListHead AlternativeOrderList
List of preferred mime types to display.
Definition: mutt_globals.h:60
struct ListHead AutoViewList
List of mime types to auto view.
Definition: mutt_globals.h:61
char * CurrentFolder
Currently selected mailbox.
Definition: mutt_globals.h:54
struct ListHead UserHeader
List of custom headers to add to outgoing emails.
Definition: mutt_globals.h:66
struct ListHead HeaderOrderList
List of header fields in the order they should be displayed.
Definition: mutt_globals.h:62
void sb_shutdown(void)
Clean up the Sidebar.
Definition: sidebar.c:208
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_parse_rc_buffer()

enum CommandResult mutt_parse_rc_buffer ( struct Buffer line,
struct Buffer token,
struct Buffer err 
)

Parse a line of user config.

Parameters
lineconfig line to read
tokenscratch buffer to be used by parser
errwhere to write error messages
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

The reason for token is to avoid having to allocate and deallocate a lot of memory if we are parsing many lines. the caller can pass in the memory to use, which avoids having to create new space for every call to this function.

Definition at line 836 of file init.c.

838{
839 if (mutt_buffer_len(line) == 0)
840 return 0;
841
843
845
846 /* Read from the beginning of line->data */
847 mutt_buffer_seek(line, 0);
848
849 SKIPWS(line->dptr);
850 while (*line->dptr)
851 {
852 if (*line->dptr == '#')
853 break; /* rest of line is a comment */
854 if (*line->dptr == ';')
855 {
856 line->dptr++;
857 continue;
858 }
860
861 struct Command *cmd = NULL;
862 size_t size = mutt_commands_array(&cmd);
863 size_t i;
864 for (i = 0; i < size; i++)
865 {
866 if (mutt_str_equal(token->data, cmd[i].name))
867 {
868 mutt_debug(LL_DEBUG1, "NT_COMMAND: %s\n", cmd[i].name);
869 rc = cmd[i].parse(token, line, cmd[i].data, err);
870 if ((rc == MUTT_CMD_ERROR) || (rc == MUTT_CMD_FINISH))
871 goto finish; /* Propagate return code */
872
873 notify_send(NeoMutt->notify, NT_COMMAND, i, (void *) cmd);
874 break; /* Continue with next command */
875 }
876 }
877 if (i == size)
878 {
879 mutt_buffer_printf(err, _("%s: unknown command"), NONULL(token->data));
880 rc = MUTT_CMD_ERROR;
881 break; /* Ignore the rest of the line */
882 }
883 }
884finish:
885 return rc;
886}
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:371
CommandResult
Error codes for command_t parse functions.
Definition: command.h:34
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:37
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:35
@ MUTT_CMD_FINISH
Finish: Stop processing this file.
Definition: command.h:38
#define _(a)
Definition: message.h:28
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:171
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:807
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:67
size_t mutt_commands_array(struct Command **first)
Get Commands array.
@ NT_COMMAND
A Command has been executed, Command.
Definition: notify_type.h:42
enum CommandResult(* parse)(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Definition: command.h:63
intptr_t data
Data or flags to pass to the command.
Definition: command.h:65
const char * name
Name of the command.
Definition: command.h:50
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_parse_rc_line()

enum CommandResult mutt_parse_rc_line ( const char *  line,
struct Buffer err 
)

Parse a line of user config.

Parameters
lineConfig line to read
errWhere to write error messages
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

Definition at line 894 of file init.c.

895{
896 if (!line || (*line == '\0'))
897 return MUTT_CMD_ERROR;
898
899 struct Buffer *line_buffer = mutt_buffer_pool_get();
900 struct Buffer *token = mutt_buffer_pool_get();
901
902 mutt_buffer_strcpy(line_buffer, line);
903
904 enum CommandResult rc = mutt_parse_rc_buffer(line_buffer, token, err);
905
906 mutt_buffer_pool_release(&line_buffer);
908 return rc;
909}
enum CommandResult mutt_parse_rc_buffer(struct Buffer *line, struct Buffer *token, struct Buffer *err)
Parse a line of user config.
Definition: init.c:836
+ 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 918 of file init.c.

919{
920 struct Buffer value = mutt_buffer_make(256);
921 struct Buffer tmp = mutt_buffer_make(256);
922 int rc = 0;
923
924 struct ListNode *np = NULL;
925 STAILQ_FOREACH(np, queries, entries)
926 {
927 mutt_buffer_reset(&value);
928
929 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, np->data);
930 if (!he)
931 {
932 mutt_warning(_("No such variable: %s"), np->data);
933 rc = 1;
934 continue;
935 }
936
937 if (he->type & DT_DEPRECATED)
938 {
939 mutt_warning(_("Config variable '%s' is deprecated"), np->data);
940 rc = 1;
941 continue;
942 }
943
944 int rv = cs_subset_he_string_get(NeoMutt->sub, he, &value);
945 if (CSR_RESULT(rv) != CSR_SUCCESS)
946 {
947 rc = 1;
948 continue;
949 }
950
951 int type = DTYPE(he->type);
952 if (type == DT_PATH)
953 mutt_pretty_mailbox(value.data, value.dsize);
954
955 if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) && (type != DT_QUAD))
956 {
957 mutt_buffer_reset(&tmp);
958 pretty_var(value.data, &tmp);
959 mutt_buffer_strcpy(&value, tmp.data);
960 }
961
962 dump_config_neo(NeoMutt->sub->cs, he, &value, NULL,
963 show_docs ? CS_DUMP_SHOW_DOCS : CS_DUMP_NO_FLAGS, stdout);
964 }
965
966 mutt_buffer_dealloc(&value);
968
969 return rc; // TEST16: neomutt -Q charset
970}
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:522
#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 mutt_warning(...)
Definition: logging.h:85
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:354
struct HashElem * cs_subset_lookup(const struct ConfigSubset *sub, const char *name)
Find an inherited config item.
Definition: subset.c:179
#define DTYPE(x)
Mask for the Data Type.
Definition: types.h:44
#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: