NeoMutt  2022-04-29-323-g5fcc6c
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 787 of file mutt_config.c.

788{
789 init_types(cs);
790 init_variables(cs);
791}
static void init_types(struct ConfigSet *cs)
Create the config types.
Definition: mutt_config.c:722
static void init_variables(struct ConfigSet *cs)
Define the config variables.
Definition: mutt_config.c:742
+ 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 272 of file init.c.

273{
274 if (!dest || !tok)
275 return -1;
276
277 char ch;
278 char qc = '\0'; /* quote char */
279 char *pc = NULL;
280
281 /* Some callers used to rely on the (bad) assumption that dest->data would be
282 * non-NULL after calling this function. Perhaps I've missed a few cases, or
283 * a future caller might make the same mistake. */
284 if (!dest->data)
285 mutt_buffer_alloc(dest, 256);
286
287 mutt_buffer_reset(dest);
288
289 SKIPWS(tok->dptr);
290 while ((ch = *tok->dptr))
291 {
292 if (qc == '\0')
293 {
294 if ((IS_SPACE(ch) && !(flags & MUTT_TOKEN_SPACE)) ||
295 ((ch == '#') && !(flags & MUTT_TOKEN_COMMENT)) ||
296 ((ch == '+') && (flags & MUTT_TOKEN_PLUS)) ||
297 ((ch == '-') && (flags & MUTT_TOKEN_MINUS)) ||
298 ((ch == '=') && (flags & MUTT_TOKEN_EQUAL)) ||
299 ((ch == '?') && (flags & MUTT_TOKEN_QUESTION)) ||
300 ((ch == ';') && !(flags & MUTT_TOKEN_SEMICOLON)) ||
301 ((flags & MUTT_TOKEN_PATTERN) && strchr("~%=!|", ch)))
302 {
303 break;
304 }
305 }
306
307 tok->dptr++;
308
309 if (ch == qc)
310 qc = 0; /* end of quote */
311 else if (!qc && ((ch == '\'') || (ch == '"')) && !(flags & MUTT_TOKEN_QUOTE))
312 qc = ch;
313 else if ((ch == '\\') && (qc != '\''))
314 {
315 if (tok->dptr[0] == '\0')
316 return -1; /* premature end of token */
317 switch (ch = *tok->dptr++)
318 {
319 case 'c':
320 case 'C':
321 if (tok->dptr[0] == '\0')
322 return -1; /* premature end of token */
323 mutt_buffer_addch(dest, (toupper((unsigned char) tok->dptr[0]) - '@') & 0x7f);
324 tok->dptr++;
325 break;
326 case 'e':
327 mutt_buffer_addch(dest, '\033'); // Escape
328 break;
329 case 'f':
330 mutt_buffer_addch(dest, '\f');
331 break;
332 case 'n':
333 mutt_buffer_addch(dest, '\n');
334 break;
335 case 'r':
336 mutt_buffer_addch(dest, '\r');
337 break;
338 case 't':
339 mutt_buffer_addch(dest, '\t');
340 break;
341 default:
342 if (isdigit((unsigned char) ch) && isdigit((unsigned char) tok->dptr[0]) &&
343 isdigit((unsigned char) tok->dptr[1]))
344 {
345 mutt_buffer_addch(dest, (ch << 6) + (tok->dptr[0] << 3) + tok->dptr[1] - 3504);
346 tok->dptr += 2;
347 }
348 else
349 mutt_buffer_addch(dest, ch);
350 }
351 }
352 else if ((ch == '^') && (flags & MUTT_TOKEN_CONDENSE))
353 {
354 if (tok->dptr[0] == '\0')
355 return -1; /* premature end of token */
356 ch = *tok->dptr++;
357 if (ch == '^')
358 mutt_buffer_addch(dest, ch);
359 else if (ch == '[')
360 mutt_buffer_addch(dest, '\033'); // Escape
361 else if (isalpha((unsigned char) ch))
362 mutt_buffer_addch(dest, toupper((unsigned char) ch) - '@');
363 else
364 {
365 mutt_buffer_addch(dest, '^');
366 mutt_buffer_addch(dest, ch);
367 }
368 }
369 else if ((ch == '`') && (!qc || (qc == '"')))
370 {
371 FILE *fp = NULL;
372 pid_t pid;
373
374 pc = tok->dptr;
375 do
376 {
377 pc = strpbrk(pc, "\\`");
378 if (pc)
379 {
380 /* skip any quoted chars */
381 if (*pc == '\\')
382 pc += 2;
383 }
384 } while (pc && (pc[0] != '`'));
385 if (!pc)
386 {
387 mutt_debug(LL_DEBUG1, "mismatched backticks\n");
388 return -1;
389 }
390 struct Buffer cmd;
391 mutt_buffer_init(&cmd);
392 *pc = '\0';
393 if (flags & MUTT_TOKEN_BACKTICK_VARS)
394 {
395 /* recursively extract tokens to interpolate variables */
396 mutt_extract_token(&cmd, tok,
399 }
400 else
401 {
402 cmd.data = mutt_str_dup(tok->dptr);
403 }
404 *pc = '`';
405 pid = filter_create(cmd.data, NULL, &fp, NULL);
406 if (pid < 0)
407 {
408 mutt_debug(LL_DEBUG1, "unable to fork command: %s\n", cmd.data);
409 FREE(&cmd.data);
410 return -1;
411 }
412
413 tok->dptr = pc + 1;
414
415 /* read line */
416 struct Buffer expn = mutt_buffer_make(0);
417 expn.data = mutt_file_read_line(NULL, &expn.dsize, fp, NULL, MUTT_RL_NO_FLAGS);
418 mutt_file_fclose(&fp);
419 int rc = filter_wait(pid);
420 if (rc != 0)
421 mutt_debug(LL_DEBUG1, "backticks exited code %d for command: %s\n", rc,
422 mutt_buffer_string(&cmd));
423 FREE(&cmd.data);
424
425 /* if we got output, make a new string consisting of the shell output
426 * plus whatever else was left on the original line */
427 /* BUT: If this is inside a quoted string, directly add output to
428 * the token */
429 if (expn.data)
430 {
431 if (qc)
432 {
433 mutt_buffer_addstr(dest, expn.data);
434 }
435 else
436 {
437 struct Buffer *copy = mutt_buffer_pool_get();
439 mutt_buffer_copy(copy, &expn);
440 mutt_buffer_addstr(copy, tok->dptr);
441 mutt_buffer_copy(tok, copy);
442 mutt_buffer_seek(tok, 0);
444 }
445 FREE(&expn.data);
446 }
447 }
448 else if ((ch == '$') && (!qc || (qc == '"')) &&
449 ((tok->dptr[0] == '{') || isalpha((unsigned char) tok->dptr[0])))
450 {
451 const char *env = NULL;
452 char *var = NULL;
453
454 if (tok->dptr[0] == '{')
455 {
456 pc = strchr(tok->dptr, '}');
457 if (pc)
458 {
459 var = mutt_strn_dup(tok->dptr + 1, pc - (tok->dptr + 1));
460 tok->dptr = pc + 1;
461
462 if ((flags & MUTT_TOKEN_NOSHELL))
463 {
464 mutt_buffer_addch(dest, ch);
465 mutt_buffer_addch(dest, '{');
466 mutt_buffer_addstr(dest, var);
467 mutt_buffer_addch(dest, '}');
468 FREE(&var);
469 }
470 }
471 }
472 else
473 {
474 for (pc = tok->dptr; isalnum((unsigned char) *pc) || (pc[0] == '_'); pc++)
475 ; // do nothing
476
477 var = mutt_strn_dup(tok->dptr, pc - tok->dptr);
478 tok->dptr = pc;
479 }
480 if (var)
481 {
482 struct Buffer result;
483 mutt_buffer_init(&result);
484 int rc = cs_subset_str_string_get(NeoMutt->sub, var, &result);
485
486 if (CSR_RESULT(rc) == CSR_SUCCESS)
487 {
488 mutt_buffer_addstr(dest, result.data);
489 FREE(&result.data);
490 }
491 else if ((env = myvar_get(var)))
492 {
493 mutt_buffer_addstr(dest, env);
494 }
495 else if (!(flags & MUTT_TOKEN_NOSHELL) && (env = mutt_str_getenv(var)))
496 {
497 mutt_buffer_addstr(dest, env);
498 }
499 else
500 {
501 mutt_buffer_addch(dest, ch);
502 mutt_buffer_addstr(dest, var);
503 }
504 FREE(&var);
505 }
506 }
507 else
508 mutt_buffer_addch(dest, ch);
509 }
510 mutt_buffer_addch(dest, 0); /* terminate the string */
511 SKIPWS(tok->dptr);
512 return 0;
513}
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:736
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:151
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition: file.h:39
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:272
@ 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 574 of file init.c.

575{
576 int need_pause = 0;
577 int rc = 1;
578 struct Buffer err = mutt_buffer_make(256);
579 struct Buffer buf = mutt_buffer_make(256);
580
582 alias_init();
584#ifdef USE_COMP_MBOX
586#endif
587#ifdef USE_IMAP
588 imap_init();
589#endif
590#ifdef USE_LUA
592#endif
594
595 menu_init();
596#ifdef USE_SIDEBAR
597 sb_init();
598#endif
599#ifdef USE_NOTMUCH
600 nm_init();
601#endif
602
603 /* "$spool_file" precedence: config file, environment */
604 const char *p = mutt_str_getenv("MAIL");
605 if (!p)
606 p = mutt_str_getenv("MAILDIR");
607 if (!p)
608 {
609#ifdef HOMESPOOL
610 mutt_buffer_concat_path(&buf, NONULL(HomeDir), MAILPATH);
611#else
612 mutt_buffer_concat_path(&buf, MAILPATH, NONULL(Username));
613#endif
614 p = mutt_buffer_string(&buf);
615 }
616 cs_str_initial_set(cs, "spool_file", p, NULL);
617 cs_str_reset(cs, "spool_file", NULL);
618
619 p = mutt_str_getenv("REPLYTO");
620 if (p)
621 {
622 struct Buffer token;
623
624 mutt_buffer_printf(&buf, "Reply-To: %s", p);
625 mutt_buffer_init(&token);
626 parse_my_hdr(&token, &buf, 0, &err); /* adds to UserHeader */
627 FREE(&token.data);
628 }
629
630 p = mutt_str_getenv("EMAIL");
631 if (p)
632 {
633 cs_str_initial_set(cs, "from", p, NULL);
634 cs_str_reset(cs, "from", NULL);
635 }
636
637 /* "$mailcap_path" precedence: config file, environment, code */
638 const char *env_mc = mutt_str_getenv("MAILCAPS");
639 if (env_mc)
640 cs_str_string_set(cs, "mailcap_path", env_mc, NULL);
641
642 /* "$tmpdir" precedence: config file, environment, code */
643 const char *env_tmp = mutt_str_getenv("TMPDIR");
644 if (env_tmp)
645 cs_str_string_set(cs, "tmpdir", env_tmp, NULL);
646
647 /* "$visual", "$editor" precedence: config file, environment, code */
648 const char *env_ed = mutt_str_getenv("VISUAL");
649 if (!env_ed)
650 env_ed = mutt_str_getenv("EDITOR");
651 if (!env_ed)
652 env_ed = "vi";
653 cs_str_initial_set(cs, "editor", env_ed, NULL);
654
655 const char *const c_editor = cs_subset_string(NeoMutt->sub, "editor");
656 if (!c_editor)
657 cs_str_reset(cs, "editor", NULL);
658
659 const char *charset = mutt_ch_get_langinfo_charset();
660 cs_str_initial_set(cs, "charset", charset, NULL);
661 cs_str_reset(cs, "charset", NULL);
662 mutt_ch_set_charset(charset);
663 FREE(&charset);
664
665#ifdef HAVE_GETSID
666 /* Unset suspend by default if we're the session leader */
667 if (getsid(0) == getpid())
668 cs_subset_str_native_set(NeoMutt->sub, "suspend", false, NULL);
669#endif
670
671 /* RFC2368, "4. Unsafe headers"
672 * The creator of a mailto URL can't expect the resolver of a URL to
673 * understand more than the "subject" and "body" headers. Clients that
674 * resolve mailto URLs into mail messages should be able to correctly
675 * create RFC822-compliant mail messages using the "subject" and "body"
676 * headers. */
677 add_to_stailq(&MailToAllow, "body");
678 add_to_stailq(&MailToAllow, "subject");
679 /* Cc, In-Reply-To, and References help with not breaking threading on
680 * mailing lists, see https://github.com/neomutt/neomutt/issues/115 */
682 add_to_stailq(&MailToAllow, "in-reply-to");
683 add_to_stailq(&MailToAllow, "references");
684
685 if (STAILQ_EMPTY(&Muttrc))
686 {
687 const char *xdg_cfg_home = mutt_str_getenv("XDG_CONFIG_HOME");
688
689 if (!xdg_cfg_home && HomeDir)
690 {
691 mutt_buffer_printf(&buf, "%s/.config", HomeDir);
692 xdg_cfg_home = mutt_buffer_string(&buf);
693 }
694
695 char *config = find_cfg(HomeDir, xdg_cfg_home);
696 if (config)
697 {
699 }
700 }
701 else
702 {
703 struct ListNode *np = NULL;
704 STAILQ_FOREACH(np, &Muttrc, entries)
705 {
706 mutt_buffer_strcpy(&buf, np->data);
707 FREE(&np->data);
709 np->data = mutt_buffer_strdup(&buf);
710 if (access(np->data, F_OK))
711 {
712 mutt_perror(np->data);
713 goto done; // TEST10: neomutt -F missing
714 }
715 }
716 }
717
718 if (!STAILQ_EMPTY(&Muttrc))
719 {
720 cs_str_string_set(cs, "alias_file", STAILQ_FIRST(&Muttrc)->data, NULL);
721 }
722
723 /* Process the global rc file if it exists and the user hasn't explicitly
724 * requested not to via "-n". */
725 if (!skip_sys_rc)
726 {
727 do
728 {
730 break;
731
732 mutt_buffer_printf(&buf, "%s/neomuttrc", SYSCONFDIR);
733 if (access(mutt_buffer_string(&buf), F_OK) == 0)
734 break;
735
736 mutt_buffer_printf(&buf, "%s/Muttrc", SYSCONFDIR);
737 if (access(mutt_buffer_string(&buf), F_OK) == 0)
738 break;
739
740 mutt_buffer_printf(&buf, "%s/neomuttrc", PKGDATADIR);
741 if (access(mutt_buffer_string(&buf), F_OK) == 0)
742 break;
743
744 mutt_buffer_printf(&buf, "%s/Muttrc", PKGDATADIR);
745 } while (false);
746
747 if (access(mutt_buffer_string(&buf), F_OK) == 0)
748 {
749 if (source_rc(mutt_buffer_string(&buf), &err) != 0)
750 {
751 mutt_error("%s", err.data);
752 need_pause = 1; // TEST11: neomutt (error in /etc/neomuttrc)
753 }
754 }
755 }
756
757 /* Read the user's initialization file. */
758 struct ListNode *np = NULL;
759 STAILQ_FOREACH(np, &Muttrc, entries)
760 {
761 if (np->data)
762 {
763 if (source_rc(np->data, &err) != 0)
764 {
765 mutt_error("%s", err.data);
766 need_pause = 1; // TEST12: neomutt (error in ~/.neomuttrc)
767 }
768 }
769 }
770
771 if (execute_commands(commands) != 0)
772 need_pause = 1; // TEST13: neomutt -e broken
773
774 if (!get_hostname(cs))
775 goto done;
776
777 {
778 char name[256] = { 0 };
779 const char *c_real_name = cs_subset_string(NeoMutt->sub, "real_name");
780 if (!c_real_name)
781 {
782 struct passwd *pw = getpwuid(getuid());
783 if (pw)
784 c_real_name = mutt_gecos_name(name, sizeof(name), pw);
785 }
786 cs_str_initial_set(cs, "real_name", c_real_name, NULL);
787 cs_str_reset(cs, "real_name", NULL);
788 }
789
790 if (need_pause && !OptNoCurses)
791 {
793 if (mutt_any_key_to_continue(NULL) == 'q')
794 goto done; // TEST14: neomutt -e broken (press 'q')
795 }
796
797 const char *const c_tmpdir = cs_subset_path(NeoMutt->sub, "tmpdir");
798 mutt_file_mkdir(c_tmpdir, S_IRWXU);
799
802
803#ifdef USE_NOTMUCH
804 const bool c_virtual_spool_file = cs_subset_bool(NeoMutt->sub, "virtual_spool_file");
805 if (c_virtual_spool_file)
806 {
807 /* Find the first virtual folder and open it */
808 struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
810 struct MailboxNode *mp = STAILQ_FIRST(&ml);
811 if (mp)
812 cs_str_string_set(cs, "spool_file", mailbox_path(mp->mailbox), NULL);
814 }
815#endif
816 rc = 0;
817
818done:
821 return rc;
822}
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:946
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:113
static int execute_commands(struct ListHead *p)
Execute a set of NeoMutt commands.
Definition: init.c:81
static bool get_hostname(struct ConfigSet *cs)
Find the Fully-Qualified Domain Name.
Definition: init.c:186
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 518 of file init.c.

519{
521
523#ifdef USE_SIDEBAR
524 sb_shutdown();
525#endif
526
532
535
536 /* Lists of strings */
546
548
550 FREE(&HomeDir);
553 FREE(&Username);
554
556
558
561
564}
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:71
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 835 of file init.c.

837{
838 if (mutt_buffer_len(line) == 0)
839 return 0;
840
842
844
845 /* Read from the beginning of line->data */
846 mutt_buffer_seek(line, 0);
847
848 SKIPWS(line->dptr);
849 while (*line->dptr)
850 {
851 if (*line->dptr == '#')
852 break; /* rest of line is a comment */
853 if (*line->dptr == ';')
854 {
855 line->dptr++;
856 continue;
857 }
859
860 struct Command *cmd = NULL;
861 size_t size = mutt_commands_array(&cmd);
862 size_t i;
863 for (i = 0; i < size; i++)
864 {
865 if (mutt_str_equal(token->data, cmd[i].name))
866 {
867 mutt_debug(LL_DEBUG1, "NT_COMMAND: %s\n", cmd[i].name);
868 rc = cmd[i].parse(token, line, cmd[i].data, err);
869 if ((rc == MUTT_CMD_WARNING) || (rc == MUTT_CMD_ERROR) || (rc == MUTT_CMD_FINISH))
870 goto finish; /* Propagate return code */
871
872 notify_send(NeoMutt->notify, NT_COMMAND, i, (void *) cmd);
873 break; /* Continue with next command */
874 }
875 }
876 if (i == size)
877 {
878 mutt_buffer_printf(err, _("%s: unknown command"), NONULL(token->data));
879 rc = MUTT_CMD_ERROR;
880 break; /* Ignore the rest of the line */
881 }
882 }
883finish:
884 return rc;
885}
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_WARNING
Warning: Help given to the user.
Definition: command.h:36
@ 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 893 of file init.c.

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

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