NeoMutt  2025-01-09-144-gb44c67
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
main.c File Reference

Command line processing. More...

#include "config.h"
#include <errno.h>
#include <limits.h>
#include <locale.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include <time.h>
#include <unistd.h>
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "alias/lib.h"
#include "conn/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "attach/lib.h"
#include "browser/lib.h"
#include "cli/lib.h"
#include "color/lib.h"
#include "compmbox/lib.h"
#include "history/lib.h"
#include "imap/lib.h"
#include "index/lib.h"
#include "key/lib.h"
#include "menu/lib.h"
#include "ncrypt/lib.h"
#include "nntp/lib.h"
#include "notmuch/lib.h"
#include "parse/lib.h"
#include "pop/lib.h"
#include "postpone/lib.h"
#include "question/lib.h"
#include "send/lib.h"
#include "sidebar/lib.h"
#include "alternates.h"
#include "commands.h"
#include "external.h"
#include "globals.h"
#include "hook.h"
#include "mutt_logging.h"
#include "mutt_mailbox.h"
#include "muttlib.h"
#include "mx.h"
#include "nntp/adata.h"
#include "protos.h"
#include "subjectrx.h"
#include "version.h"
#include <libintl.h>
#include "autocrypt/lib.h"
#include "mutt_lua.h"

Go to the source code of this file.

Macros

#define GNULIB_defined_setlocale
 

Functions

void show_cli (enum HelpMode mode, bool use_color)
 Show Instructions on how to run NeoMutt.
 
static int execute_commands (struct StringArray *sa)
 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.
 
static int mutt_init (struct ConfigSet *cs, struct Buffer *dlevel, struct Buffer *dfile, bool skip_sys_rc, struct StringArray *user_files, struct StringArray *commands)
 Initialise NeoMutt.
 
static int get_elem_queries (struct StringArray *queries, struct HashElemArray *hea)
 Lookup the HashElems for a set of queries.
 
static void reset_tilde (struct ConfigSet *cs)
 Temporary measure.
 
static void localise_config (struct ConfigSet *cs)
 Localise some config.
 
static int start_curses (void)
 Start the Curses UI.
 
static void init_locale (void)
 Initialise the Locale/NLS settings.
 
static bool get_user_info (struct ConfigSet *cs)
 Find the user's name, home and shell.
 
static void log_translation (void)
 Log the translation being used.
 
static void log_gui (void)
 Log info about the GUI.
 
static int main_timeout_observer (struct NotifyCallback *nc)
 Notification that a timeout has occurred - Implements observer_t -.
 
static bool show_help (struct CliHelp *help)
 Show the Help.
 
static bool init_logging (struct CliShared *shared, struct ConfigSet *cs)
 Initialise the Logging.
 
static void init_nntp (struct Buffer *server, struct ConfigSet *cs)
 Initialise the NNTP config.
 
static bool dump_info (struct CliInfo *ci, struct ConfigSet *cs)
 Show config info.
 
int main (int argc, char *argv[], char *envp[])
 Start NeoMutt.
 

Variables

bool StartupComplete = false
 When the config has been read.
 

Detailed Description

Command line processing.

Authors
  • Michael R. Elkins
  • Thomas Roessler
  • g10 Code GmbH
  • Richard Russon
  • Pietro Cerutti
  • R Primus
  • Dennis Schön
  • Alejandro Colomar

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 main.c.

Macro Definition Documentation

◆ GNULIB_defined_setlocale

#define GNULIB_defined_setlocale

Definition at line 128 of file main.c.

Function Documentation

◆ show_cli()

void show_cli ( enum HelpMode  mode,
bool  use_color 
)

Show Instructions on how to run NeoMutt.

Parameters
modeDetails, e.g. HM_SHARED
use_colorHighlight parts of the text

Definition at line 332 of file usage.c.

333{
334 if (use_color)
335 printf("\033[38;5;255m%s\033[0m\n\n", mutt_make_version());
336 else
337 printf("%s\n\n", mutt_make_version());
338
339 switch (mode)
340 {
341 case HM_NONE:
342 {
343 show_cli_overview(use_color);
344 break;
345 }
346 case HM_SHARED:
347 {
348 show_cli_shared(use_color);
349 break;
350 }
351 case HM_HELP:
352 {
353 show_cli_help(use_color);
354 break;
355 }
356 case HM_INFO:
357 {
358 show_cli_info(use_color);
359 break;
360 }
361 case HM_SEND:
362 {
363 show_cli_send(use_color);
364 break;
365 }
366 case HM_TUI:
367 {
368 show_cli_tui(use_color);
369 break;
370 }
371 case HM_ALL:
372 {
373 printf("------------------------------------------------------------\n");
374 show_cli_shared(use_color);
375 printf("\n------------------------------------------------------------\n");
376 show_cli_help(use_color);
377 printf("\n------------------------------------------------------------\n");
378 show_cli_info(use_color);
379 printf("\n------------------------------------------------------------\n");
380 show_cli_send(use_color);
381 printf("\n------------------------------------------------------------\n");
382 show_cli_tui(use_color);
383 printf("\n------------------------------------------------------------\n");
384 break;
385 }
386 }
387}
@ HM_SEND
Help about sending email options.
Definition: objects.h:40
@ HM_ALL
Help about all options.
Definition: objects.h:42
@ HM_HELP
Help about help.
Definition: objects.h:38
@ HM_INFO
Help about info options.
Definition: objects.h:39
@ HM_TUI
Help about starting the tui options.
Definition: objects.h:41
@ HM_NONE
No extra help.
Definition: objects.h:36
@ HM_SHARED
Help about shared config options.
Definition: objects.h:37
static void show_cli_tui(bool use_color)
Show Command Line Help for Tui.
Definition: usage.c:290
static void show_cli_shared(bool use_color)
Show Command Line Help for Shared.
Definition: usage.c:124
static void show_cli_info(bool use_color)
Show Command Line Help for Info.
Definition: usage.c:207
static void show_cli_overview(bool use_color)
Display NeoMutt command line.
Definition: usage.c:54
static void show_cli_help(bool use_color)
Show Command Line Help for Help.
Definition: usage.c:180
static void show_cli_send(bool use_color)
Show Command Line Help for Send.
Definition: usage.c:246
const char * mutt_make_version(void)
Generate the NeoMutt version string.
Definition: version.c:295
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ execute_commands()

static int execute_commands ( struct StringArray *  sa)
static

Execute a set of NeoMutt commands.

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

Definition at line 209 of file main.c.

210{
211 int rc = 0;
212 struct Buffer *err = buf_pool_get();
213
214 char **cp = NULL;
215 ARRAY_FOREACH(cp, sa)
216 {
217 enum CommandResult rc2 = parse_rc_line(*cp, err);
218 if (rc2 == MUTT_CMD_ERROR)
219 mutt_error(_("Error in command line: %s"), buf_string(err));
220 else if (rc2 == MUTT_CMD_WARNING)
221 mutt_warning(_("Warning in command line: %s"), buf_string(err));
222
223 if ((rc2 == MUTT_CMD_ERROR) || (rc2 == MUTT_CMD_WARNING))
224 {
225 buf_pool_release(&err);
226 return -1;
227 }
228 }
229 buf_pool_release(&err);
230
231 return rc;
232}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:214
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
CommandResult
Error codes for command_t parse functions.
Definition: command.h:35
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:36
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition: command.h:37
#define mutt_warning(...)
Definition: logging2.h:91
#define mutt_error(...)
Definition: logging2.h:93
#define _(a)
Definition: message.h:28
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:96
enum CommandResult parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: rc.c:109
String manipulation buffer.
Definition: buffer.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 241 of file main.c.

242{
243 const char *names[] = {
244 "neomuttrc",
245 "muttrc",
246 NULL,
247 };
248
249 const char *locations[][2] = {
250 { xdg_cfg_home, "neomutt/" },
251 { xdg_cfg_home, "mutt/" },
252 { home, ".neomutt/" },
253 { home, ".mutt/" },
254 { home, "." },
255 { NULL, NULL },
256 };
257
258 struct Buffer *buf = buf_pool_get();
259 char *cfg = NULL;
260
261 for (int i = 0; locations[i][0] || locations[i][1]; i++)
262 {
263 if (!locations[i][0])
264 continue;
265
266 for (int j = 0; names[j]; j++)
267 {
268 buf_printf(buf, "%s/%s%s", locations[i][0], locations[i][1], names[j]);
269 if (access(buf_string(buf), F_OK) == 0)
270 {
271 cfg = buf_strdup(buf);
272 goto done;
273 }
274 }
275 }
276
277done:
278 buf_pool_release(&buf);
279 return cfg;
280}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:161
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:571
+ 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 288 of file main.c.

289{
290 char *mailname = NULL;
291 static const char *mn_files[] = { "/etc/mailname", "/etc/mail/mailname" };
292
293 for (size_t i = 0; i < mutt_array_size(mn_files); i++)
294 {
295 FILE *fp = mutt_file_fopen(mn_files[i], "r");
296 if (!fp)
297 continue;
298
299 size_t len = 0;
300 mailname = mutt_file_read_line(NULL, &len, fp, NULL, MUTT_RL_NO_FLAGS);
301 mutt_file_fclose(&fp);
302 if (mailname && *mailname)
303 break;
304
305 FREE(&mailname);
306 }
307
308 return mailname;
309}
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:685
#define mutt_file_fclose(FP)
Definition: file.h:139
#define mutt_file_fopen(PATH, MODE)
Definition: file.h:138
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition: file.h:40
#define FREE(x)
Definition: memory.h:55
#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 321 of file main.c.

322{
323 const char *short_host = NULL;
324 struct utsname utsname = { 0 };
325
326 const char *const c_hostname = cs_subset_string(NeoMutt->sub, "hostname");
327 if (c_hostname)
328 {
329 short_host = c_hostname;
330 }
331 else
332 {
333 /* The call to uname() shouldn't fail, but if it does, the system is horribly
334 * broken, and the system's networking configuration is in an unreliable
335 * state. We should bail. */
336 if ((uname(&utsname)) == -1)
337 {
338 mutt_perror(_("unable to determine nodename via uname()"));
339 return false; // TEST09: can't test
340 }
341
342 short_host = utsname.nodename;
343 }
344
345 /* some systems report the FQDN instead of just the hostname */
346 char *dot = strchr(short_host, '.');
347 if (dot)
348 ShortHostname = mutt_strn_dup(short_host, dot - short_host);
349 else
350 ShortHostname = mutt_str_dup(short_host);
351
352 // All the code paths from here alloc memory for the fqdn
353 char *fqdn = mutt_str_dup(c_hostname);
354 if (!fqdn)
355 {
356 mutt_debug(LL_DEBUG1, "Setting $hostname\n");
357 /* now get FQDN. Use configured domain first, DNS next, then uname */
358#ifdef DOMAIN
359 /* we have a compile-time domain name, use that for `$hostname` */
360 mutt_str_asprintf(&fqdn, "%s.%s", NONULL(ShortHostname), DOMAIN);
361#else
362 fqdn = getmailname();
363 if (!fqdn)
364 {
365 struct Buffer *domain = buf_pool_get();
366 if (getdnsdomainname(domain) == 0)
367 {
368 mutt_str_asprintf(&fqdn, "%s.%s", NONULL(ShortHostname), buf_string(domain));
369 }
370 else
371 {
372 /* DNS failed, use the nodename. Whether or not the nodename had a '.'
373 * in it, we can use the nodename as the FQDN. On hosts where DNS is
374 * not being used, e.g. small network that relies on hosts files, a
375 * short host name is all that is required for SMTP to work correctly.
376 * It could be wrong, but we've done the best we can, at this point the
377 * onus is on the user to provide the correct hostname if the nodename
378 * won't work in their network. */
379 fqdn = mutt_str_dup(utsname.nodename);
380 }
381 buf_pool_release(&domain);
382 mutt_debug(LL_DEBUG1, "Hostname: %s\n", NONULL(fqdn));
383 }
384#endif
385 }
386
387 if (fqdn)
388 {
389 config_str_set_initial(cs, "hostname", fqdn);
390 FREE(&fqdn);
391 }
392
393 return true;
394}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:291
bool config_str_set_initial(struct ConfigSet *cs, const char *name, const char *value)
Set the initial value of a Config Option.
Definition: helpers.c:332
int getdnsdomainname(struct Buffer *result)
Lookup the host's name using DNS.
Definition: getdomain.c:124
char * ShortHostname
Short version of the hostname.
Definition: globals.c:37
#define mutt_debug(LEVEL,...)
Definition: logging2.h:90
#define mutt_perror(...)
Definition: logging2.h:94
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:44
static char * getmailname(void)
Try to retrieve the FQDN from mailname files.
Definition: main.c:288
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:381
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:254
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition: string.c:804
#define NONULL(x)
Definition: string2.h:37
Container for Accounts, Notifications.
Definition: neomutt.h:43
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:47
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_init()

static int mutt_init ( struct ConfigSet cs,
struct Buffer dlevel,
struct Buffer dfile,
bool  skip_sys_rc,
struct StringArray *  user_files,
struct StringArray *  commands 
)
static

Initialise NeoMutt.

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

Definition at line 407 of file main.c.

410{
411 bool need_pause = false;
412 int rc = 1;
413 struct Buffer *err = buf_pool_get();
414 struct Buffer *buf = buf_pool_get();
415 char **cp = NULL;
416
417#ifdef NEOMUTT_DIRECT_COLORS
418 /* Test if we run in a terminal which supports direct colours.
419 *
420 * The user/terminal can indicate their capability independent of the
421 * terminfo file by setting the COLORTERM environment variable to "truecolor"
422 * or "24bit" (case sensitive).
423 *
424 * Note: This is to test is less about whether the terminal understands
425 * direct color commands but more about whether ncurses believes it can send
426 * them to the terminal, e.g. ncurses ignores COLORTERM.
427 */
428 if (COLORS == 16777216) // 2^24
429 {
430 /* Ncurses believes the Terminal supports it check the environment variable
431 * to respect the user's choice */
432 const char *env_colorterm = mutt_str_getenv("COLORTERM");
433 if (env_colorterm && (mutt_str_equal(env_colorterm, "truecolor") ||
434 mutt_str_equal(env_colorterm, "24bit")))
435 {
436 config_str_set_initial(cs, "color_directcolor", "yes");
437 }
438 }
439#endif
440
441 /* "$spool_file" precedence: config file, environment */
442 const char *p = mutt_str_getenv("MAIL");
443 if (!p)
444 p = mutt_str_getenv("MAILDIR");
445 if (!p)
446 {
447#ifdef HOMESPOOL
448 buf_concat_path(buf, NONULL(NeoMutt->home_dir), MAILPATH);
449#else
450 buf_concat_path(buf, MAILPATH, NONULL(NeoMutt->username));
451#endif
452 p = buf_string(buf);
453 }
454 config_str_set_initial(cs, "spool_file", p);
455
456 p = mutt_str_getenv("REPLYTO");
457 if (p)
458 {
459 struct Buffer *token = buf_pool_get();
460
461 buf_printf(buf, "Reply-To: %s", p);
462 buf_seek(buf, 0);
463 parse_my_hdr(token, buf, 0, err); /* adds to UserHeader */
464 buf_pool_release(&token);
465 }
466
467 p = mutt_str_getenv("EMAIL");
468 if (p)
469 config_str_set_initial(cs, "from", p);
470
471 /* "$mailcap_path" precedence: config file, environment, code */
472 struct Buffer *mc = buf_pool_get();
473 struct Slist *sl_mc = NULL;
474 const char *env_mc = mutt_str_getenv("MAILCAPS");
475 if (env_mc)
476 {
477 sl_mc = slist_parse(env_mc, D_SLIST_SEP_COLON);
478 }
479 else
480 {
481 cs_str_initial_get(cs, "mailcap_path", mc);
483 buf_reset(mc);
484 }
485 slist_to_buffer(sl_mc, mc);
486 config_str_set_initial(cs, "mailcap_path", buf_string(mc));
487 slist_free(&sl_mc);
488 buf_pool_release(&mc);
489
490 /* "$tmp_dir" precedence: config file, environment, code */
491 const char *env_tmp = mutt_str_getenv("TMPDIR");
492 if (env_tmp)
493 config_str_set_initial(cs, "tmp_dir", env_tmp);
494
495 /* "$visual", "$editor" precedence: config file, environment, code */
496 const char *env_ed = mutt_str_getenv("VISUAL");
497 if (!env_ed)
498 env_ed = mutt_str_getenv("EDITOR");
499 if (!env_ed)
500 env_ed = "vi";
501 config_str_set_initial(cs, "editor", env_ed);
502
503 const char *charset = mutt_ch_get_langinfo_charset();
504 config_str_set_initial(cs, "charset", charset);
505 mutt_ch_set_charset(charset);
506 FREE(&charset);
507
508 char name[256] = { 0 };
509 const char *c_real_name = cs_subset_string(NeoMutt->sub, "real_name");
510 if (!c_real_name)
511 {
512 struct passwd *pw = getpwuid(getuid());
513 if (pw)
514 {
515 c_real_name = mutt_gecos_name(name, sizeof(name), pw);
516 }
517 }
518 config_str_set_initial(cs, "real_name", c_real_name);
519
520#ifdef HAVE_GETSID
521 /* Unset suspend by default if we're the session leader */
522 if (getsid(0) == getpid())
523 config_str_set_initial(cs, "suspend", "no");
524#endif
525
526 /* RFC2368, "4. Unsafe headers"
527 * The creator of a mailto URL can't expect the resolver of a URL to
528 * understand more than the "subject" and "body" headers. Clients that
529 * resolve mailto URLs into mail messages should be able to correctly
530 * create RFC822-compliant mail messages using the "subject" and "body"
531 * headers. */
532 add_to_stailq(&MailToAllow, "body");
533 add_to_stailq(&MailToAllow, "subject");
534 /* Cc, In-Reply-To, and References help with not breaking threading on
535 * mailing lists, see https://github.com/neomutt/neomutt/issues/115 */
537 add_to_stailq(&MailToAllow, "in-reply-to");
538 add_to_stailq(&MailToAllow, "references");
539
540 if (ARRAY_EMPTY(user_files))
541 {
542 const char *xdg_cfg_home = mutt_str_getenv("XDG_CONFIG_HOME");
543
544 if (!xdg_cfg_home && NeoMutt->home_dir)
545 {
546 buf_printf(buf, "%s/.config", NeoMutt->home_dir);
547 xdg_cfg_home = buf_string(buf);
548 }
549
550 char *config = find_cfg(NeoMutt->home_dir, xdg_cfg_home);
551 if (config)
552 {
553 ARRAY_ADD(user_files, config);
554 }
555 }
556 else
557 {
558 ARRAY_FOREACH(cp, user_files)
559 {
560 buf_strcpy(buf, *cp);
561 FREE(cp);
562 buf_expand_path(buf);
563 ARRAY_SET(user_files, ARRAY_FOREACH_IDX_cp, buf_strdup(buf));
564 if (access(buf_string(buf), F_OK))
565 {
566 mutt_perror("%s", buf_string(buf));
567 goto done; // TEST10: neomutt -F missing
568 }
569 }
570 }
571
572 ARRAY_FOREACH(cp, user_files)
573 {
574 if (*cp && !mutt_str_equal(*cp, "/dev/null"))
575 {
576 cs_str_string_set(cs, "alias_file", *cp, NULL);
577 break;
578 }
579 }
580
581 /* Process the global rc file if it exists and the user hasn't explicitly
582 * requested not to via "-n". */
583 if (!skip_sys_rc)
584 {
585 do
586 {
588 break;
589
590 buf_printf(buf, "%s/neomuttrc", SYSCONFDIR);
591 if (access(buf_string(buf), F_OK) == 0)
592 break;
593
594 buf_printf(buf, "%s/Muttrc", SYSCONFDIR);
595 if (access(buf_string(buf), F_OK) == 0)
596 break;
597
598 buf_printf(buf, "%s/neomuttrc", PKGDATADIR);
599 if (access(buf_string(buf), F_OK) == 0)
600 break;
601
602 buf_printf(buf, "%s/Muttrc", PKGDATADIR);
603 } while (false);
604
605 if (access(buf_string(buf), F_OK) == 0)
606 {
607 if (source_rc(buf_string(buf), err) != 0)
608 {
609 mutt_error("%s", buf_string(err));
610 need_pause = true; // TEST11: neomutt (error in /etc/neomuttrc)
611 }
612 }
613 }
614
615 /* Read the user's initialization file. */
616 ARRAY_FOREACH(cp, user_files)
617 {
618 if (*cp)
619 {
620 if (source_rc(*cp, err) != 0)
621 {
622 mutt_error("%s", buf_string(err));
623 need_pause = true; // TEST12: neomutt (error in ~/.neomuttrc)
624 }
625 }
626 }
627
628 if (execute_commands(commands) != 0)
629 need_pause = true; // TEST13: neomutt -e broken
630
631 if (!get_hostname(cs))
632 goto done;
633
634 /* The command line overrides the config */
635 if (!buf_is_empty(dlevel))
636 cs_str_reset(cs, "debug_level", NULL);
637 if (!buf_is_empty(dfile))
638 cs_str_reset(cs, "debug_file", NULL);
639
640 if (mutt_log_start() < 0)
641 {
642 mutt_perror("log file");
643 goto done;
644 }
645
646 if (need_pause && !OptNoCurses)
647 {
649 if (mutt_any_key_to_continue(NULL) == 'q')
650 goto done; // TEST14: neomutt -e broken (press 'q')
651 }
652
653 const char *const c_tmp_dir = cs_subset_path(NeoMutt->sub, "tmp_dir");
654 if (mutt_file_mkdir(c_tmp_dir, S_IRWXU) < 0)
655 {
656 mutt_error(_("Can't create %s: %s"), c_tmp_dir, strerror(errno));
657 goto done;
658 }
659
660 rc = 0;
661
662done:
663 buf_pool_release(&err);
664 buf_pool_release(&buf);
665 return rc;
666}
#define ARRAY_SET(head, idx, elem)
Set an element in the array.
Definition: array.h:123
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition: array.h:156
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:74
void buf_seek(struct Buffer *buf, size_t offset)
Set current read/write position to offset from beginning.
Definition: buffer.c:622
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:76
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:291
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:395
size_t buf_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:509
int source_rc(const char *rcfile_path, struct Buffer *err)
Read an initialization file.
Definition: commands.c:219
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:168
int cs_str_initial_get(const struct ConfigSet *cs, const char *name, struct Buffer *result)
Get the initial, or parent, value of a config item.
Definition: set.c:593
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:446
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:668
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:174
struct ListHead MailToAllow
List of regexes to identify non-spam emails.
Definition: globals.c:42
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:851
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: globals.c:65
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:849
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:421
static char * find_cfg(const char *home, const char *xdg_cfg_home)
Find a config file.
Definition: main.c:241
static bool get_hostname(struct ConfigSet *cs)
Find the Fully-Qualified Domain Name.
Definition: main.c:321
static int execute_commands(struct StringArray *sa)
Execute a set of NeoMutt commands.
Definition: main.c:209
char * mutt_ch_get_langinfo_charset(void)
Get the user's choice of character set.
Definition: charset.c:486
void mutt_ch_set_charset(const char *charset)
Update the records for a new character set.
Definition: charset.c:1075
void log_queue_flush(log_dispatcher_t disp)
Replay the log queue.
Definition: logging.c:347
struct Slist * slist_parse(const char *str, uint32_t flags)
Parse a list of strings into a list.
Definition: slist.c:177
void slist_free(struct Slist **ptr)
Free an Slist object.
Definition: slist.c:124
int slist_to_buffer(const struct Slist *list, struct Buffer *buf)
Export an Slist to a Buffer.
Definition: slist.c:269
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:661
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition: string.c:727
int mutt_log_start(void)
Enable file logging.
Definition: mutt_logging.c:248
char * mutt_gecos_name(char *dest, size_t destlen, struct passwd *pw)
Lookup a user's real name in /etc/passwd.
Definition: muttlib.c:332
void add_to_stailq(struct ListHead *head, const char *str)
Add a string to a list.
Definition: muttlib.c:1039
int mutt_set_xdg_path(enum XdgType type, struct Buffer *buf)
Find an XDG path or its fallback.
Definition: muttlib.c:883
void buf_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:315
@ XDG_CONFIG_DIRS
XDG system dir: /etc/xdg.
Definition: protos.h:46
char * username
User's login name.
Definition: neomutt.h:54
char * home_dir
User's home directory.
Definition: neomutt.h:53
String list.
Definition: slist.h:37
#define D_SLIST_SEP_COLON
Slist items are colon-separated.
Definition: types.h:111
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_elem_queries()

static int get_elem_queries ( struct StringArray *  queries,
struct HashElemArray *  hea 
)
static

Lookup the HashElems for a set of queries.

Parameters
[in]queriesArray of query strings
[out]heaArray for Config HashElems
Return values
0Success, all queries exist
1Error

Definition at line 675 of file main.c.

676{
677 int rc = 0;
678 char **cp = NULL;
679 ARRAY_FOREACH(cp, queries)
680 {
681 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, *cp);
682 if (!he)
683 {
684 mutt_warning(_("Unknown option %s"), *cp);
685 rc = 1;
686 continue;
687 }
688
689 if (he->type & D_INTERNAL_DEPRECATED)
690 {
691 mutt_warning(_("Option %s is deprecated"), *cp);
692 rc = 1;
693 continue;
694 }
695
696 ARRAY_ADD(hea, he);
697 }
698
699 return rc; // TEST16: neomutt -Q charset
700}
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
struct HashElem * cs_subset_lookup(const struct ConfigSubset *sub, const char *name)
Find an inherited config item.
Definition: subset.c:189
#define D_INTERNAL_DEPRECATED
Config item shouldn't be used any more.
Definition: types.h:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reset_tilde()

static void reset_tilde ( struct ConfigSet cs)
static

Temporary measure.

Parameters
csConfig Set

Definition at line 706 of file main.c.

707{
708 static const char *names[] = { "folder", "mbox", "postponed", "record" };
709
710 struct Buffer *value = buf_pool_get();
711 for (size_t i = 0; i < mutt_array_size(names); i++)
712 {
713 struct HashElem *he = cs_get_elem(cs, names[i]);
714 if (!he)
715 continue;
716 buf_reset(value);
717 cs_he_initial_get(cs, he, value);
718 buf_expand_path_regex(value, false);
719 config_he_set_initial(cs, he, value->data);
720 }
721 buf_pool_release(&value);
722}
bool config_he_set_initial(struct ConfigSet *cs, struct HashElem *he, const char *value)
Set the initial value of a Config Option.
Definition: helpers.c:312
struct HashElem * cs_get_elem(const struct ConfigSet *cs, const char *name)
Get the HashElem representing a config item.
Definition: set.c:175
int cs_he_initial_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
Get the initial, or parent, value of a config item.
Definition: set.c:557
void buf_expand_path_regex(struct Buffer *buf, bool regex)
Create the canonical path (with regex char escaping)
Definition: muttlib.c:122
char * data
Pointer to data.
Definition: buffer.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ localise_config()

static void localise_config ( struct ConfigSet cs)
static

Localise some config.

Parameters
csConfig Set

Definition at line 729 of file main.c.

730{
731 struct Buffer *value = buf_pool_get();
732 struct HashElemArray hea = get_elem_list(NeoMutt->sub->cs, GEL_ALL_CONFIG);
733 struct HashElem **hep = NULL;
734
735 ARRAY_FOREACH(hep, &hea)
736 {
737 struct HashElem *he = *hep;
738 if (!(he->type & D_L10N_STRING))
739 continue;
740
741 buf_reset(value);
742 cs_he_initial_get(cs, he, value);
743
744 // Lookup the translation
745 const char *l10n = gettext(buf_string(value));
746 config_he_set_initial(cs, he, l10n);
747 }
748
749 ARRAY_FREE(&hea);
750 buf_pool_release(&value);
751}
#define ARRAY_FREE(head)
Release all memory.
Definition: array.h:204
struct ConfigSet * cs
Parent ConfigSet.
Definition: subset.h:50
struct HashElemArray get_elem_list(struct ConfigSet *cs, enum GetElemListFlags flags)
Create a sorted list of all config items.
Definition: subset.c:80
@ GEL_ALL_CONFIG
All the normal config (no synonyms or deprecated)
Definition: subset.h:81
#define D_L10N_STRING
String can be localised.
Definition: types.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ start_curses()

static int start_curses ( void  )
static

Start the Curses UI.

Return values
0Success
1Failure

Definition at line 759 of file main.c.

760{
761 km_init(); /* must come before mutt_init */
762
763 /* should come before initscr() so that ncurses 4.2 doesn't try to install
764 * its own SIGWINCH handler */
766
767 if (!initscr())
768 {
769 mutt_error(_("Error initializing terminal"));
770 return 1;
771 }
772
773 colors_init();
774 keypad(stdscr, true);
775 cbreak();
776 noecho();
777 nonl();
778 typeahead(-1); /* simulate smooth scrolling */
779 meta(stdscr, true);
781 /* Now that curses is set up, we drop back to normal screen mode.
782 * This simplifies displaying error messages to the user.
783 * The first call to refresh() will swap us back to curses screen mode. */
784 endwin();
785 return 0;
786}
void colors_init(void)
Initialize colours.
Definition: color.c:49
void km_init(void)
Initialise all the menu keybindings.
Definition: init.c:176
void init_extended_keys(void)
Initialise map of ncurses extended keys.
Definition: init.c:133
void mutt_signal_init(void)
Initialise the signal handling.
Definition: mutt_signal.c:135
int endwin(void)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_locale()

static void init_locale ( void  )
static

Initialise the Locale/NLS settings.

Definition at line 791 of file main.c.

792{
793 setlocale(LC_ALL, "");
794
795#ifdef ENABLE_NLS
796 const char *domdir = mutt_str_getenv("TEXTDOMAINDIR");
797 if (domdir)
798 bindtextdomain(PACKAGE, domdir);
799 else
800 bindtextdomain(PACKAGE, MUTTLOCALEDIR);
801 textdomain(PACKAGE);
802#endif
803#ifndef LOCALES_HACK
804 /* Do we have a locale definition? */
805 if (mutt_str_getenv("LC_ALL") || mutt_str_getenv("LANG") || mutt_str_getenv("LC_CTYPE"))
806 {
807 OptLocales = true;
808 }
809#endif
810}
bool OptLocales
(pseudo) set if user has valid locale definition
Definition: mbyte.c:44
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_user_info()

static bool get_user_info ( struct ConfigSet cs)
static

Find the user's name, home and shell.

Parameters
csConfig Set
Return values
trueSuccess

Find the login name, real name, home directory and shell.

Definition at line 819 of file main.c.

820{
821 const char *shell = mutt_str_getenv("SHELL");
822
823 /* Get some information about the user */
824 struct passwd *pw = getpwuid(getuid());
825 if (pw)
826 {
827 if (!NeoMutt->username)
828 NeoMutt->username = mutt_str_dup(pw->pw_name);
829 if (!NeoMutt->home_dir)
830 NeoMutt->home_dir = mutt_str_dup(pw->pw_dir);
831 if (!shell)
832 shell = pw->pw_shell;
833 }
834
835 if (!NeoMutt->username)
836 {
837 mutt_error(_("unable to determine username"));
838 return false; // TEST05: neomutt (unset $USER, delete user from /etc/passwd)
839 }
840
841 if (!NeoMutt->home_dir)
842 {
843 mutt_error(_("unable to determine home directory"));
844 return false; // TEST06: neomutt (unset $HOME, delete user from /etc/passwd)
845 }
846
847 if (shell)
848 config_str_set_initial(cs, "shell", shell);
849
850 return true;
851}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ log_translation()

static void log_translation ( void  )
static

Log the translation being used.

Read the header info from the translation file.

Note
Call bindtextdomain() first

Definition at line 860 of file main.c.

861{
862 const char *header = ""; // Do not merge these two lines
863 header = _(header); // otherwise the .po files will end up badly ordered
864 const char *label = "Language:"; // the start of the lookup/needle
865 const char *lang = mutt_istr_find(header, label);
866 int len = 64;
867 if (lang)
868 {
869 lang += strlen(label); // skip label
870 SKIPWS(lang);
871 char *nl = strchr(lang, '\n');
872 if (nl)
873 len = (nl - lang);
874 }
875 else
876 {
877 lang = "NONE";
878 }
879
880 mutt_debug(LL_DEBUG1, "Translation: %.*s\n", len, lang);
881}
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case)
Definition: string.c:522
#define SKIPWS(ch)
Definition: string2.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ log_gui()

static void log_gui ( void  )
static

Log info about the GUI.

Definition at line 886 of file main.c.

887{
888 const char *term = mutt_str_getenv("TERM");
889 const char *color_term = mutt_str_getenv("COLORTERM");
890 bool true_color = false;
891#ifdef NEOMUTT_DIRECT_COLORS
892 true_color = true;
893#endif
894
895 mutt_debug(LL_DEBUG1, "GUI:\n");
896 mutt_debug(LL_DEBUG1, " Curses: %s\n", curses_version());
897 mutt_debug(LL_DEBUG1, " COLORS=%d\n", COLORS);
898 mutt_debug(LL_DEBUG1, " COLOR_PAIRS=%d\n", COLOR_PAIRS);
899 mutt_debug(LL_DEBUG1, " TERM=%s\n", NONULL(term));
900 mutt_debug(LL_DEBUG1, " COLORTERM=%s\n", NONULL(color_term));
901 mutt_debug(LL_DEBUG1, " True color support: %s\n", true_color ? "YES" : "NO");
902 mutt_debug(LL_DEBUG1, " Screen: %dx%d\n", RootWindow->state.cols,
904}
struct MuttWindow * RootWindow
Parent of all Windows.
Definition: rootwin.c:106
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:127
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:61
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:62
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ show_help()

static bool show_help ( struct CliHelp help)
static

Show the Help.

Parameters
helpCommand Line Options
Return values
trueSuccess, continue

Definition at line 943 of file main.c.

944{
945 if (!help->is_set)
946 return true;
947
949
950 const bool tty = isatty(STDOUT_FILENO);
951
952 if (help->help)
953 {
954 show_cli(help->mode, tty);
955 }
956 else if (help->license)
957 {
959 }
960 else
961 {
962 print_version(stdout, tty);
963 }
964
965 return false; // Stop
966}
void show_cli(enum HelpMode mode, bool use_color)
Show Instructions on how to run NeoMutt.
Definition: usage.c:332
bool license
-vv Print license
Definition: objects.h:70
enum HelpMode mode
Display detailed help.
Definition: objects.h:72
bool help
-h Print help
Definition: objects.h:68
bool is_set
This struct has been used.
Definition: objects.h:67
bool print_copyright(void)
Print copyright message.
Definition: version.c:702
bool print_version(FILE *fp, bool use_ansi)
Print system and compile info to a file.
Definition: version.c:591
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_logging()

static bool init_logging ( struct CliShared shared,
struct ConfigSet cs 
)
static

Initialise the Logging.

Parameters
sharedShared Command line Options
csConfig Set
Return values
trueSucces

Definition at line 974 of file main.c.

975{
976 if (!shared->is_set)
977 return true;
978
979 if (!buf_is_empty(&shared->log_file))
980 config_str_set_initial(cs, "debug_file", buf_string(&shared->log_file));
981
982 if (!buf_is_empty(&shared->log_level))
983 {
984 const char *dlevel = buf_string(&shared->log_level);
985 short num = 0;
986 if (!mutt_str_atos_full(dlevel, &num) || (num < LL_MESSAGE) || (num >= LL_MAX))
987 {
988 mutt_error(_("Error: value '%s' is invalid for -d"), dlevel);
989 return false;
990 }
991
992 config_str_set_initial(cs, "debug_level", dlevel);
993 }
994
995 return true;
996}
@ LL_MESSAGE
Log informational message.
Definition: logging2.h:43
@ LL_MAX
Definition: logging2.h:51
struct Buffer log_level
-d Debug log level
Definition: objects.h:58
struct Buffer log_file
-l Debug log file
Definition: objects.h:59
bool is_set
This struct has been used.
Definition: objects.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_nntp()

static void init_nntp ( struct Buffer server,
struct ConfigSet cs 
)
static

Initialise the NNTP config.

Parameters
serverNNTP Server to use
csConfig Set

Definition at line 1003 of file main.c.

1004{
1005 const char *cli_nntp = NULL;
1006 if (!buf_is_empty(server))
1007 cli_nntp = buf_string(server);
1008
1009 /* "$news_server" precedence: command line, config file, environment, system file */
1010 if (cli_nntp)
1011 cli_nntp = cs_subset_string(NeoMutt->sub, "news_server");
1012
1013 if (!cli_nntp)
1014 cli_nntp = mutt_str_getenv("NNTPSERVER");
1015
1016 if (!cli_nntp)
1017 {
1018 char buf[1024] = { 0 };
1019 cli_nntp = mutt_file_read_keyword(SYSCONFDIR "/nntpserver", buf, sizeof(buf));
1020 }
1021
1022 if (cli_nntp)
1023 config_str_set_initial(cs, "news_server", cli_nntp);
1024}
char * mutt_file_read_keyword(const char *file, char *buf, size_t buflen)
Read a keyword from a file.
Definition: file.c:1299
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dump_info()

static bool dump_info ( struct CliInfo ci,
struct ConfigSet cs 
)
static

Show config info.

Parameters
ciCommand line Options
csConfig Set
Return values
trueSuccess

Definition at line 1032 of file main.c.

1033{
1034 if (!ci->is_set)
1035 return true;
1036
1037 if (ci->dump_config || !ARRAY_EMPTY(&ci->queries))
1038 {
1039 const bool tty = isatty(STDOUT_FILENO);
1040
1042 if (tty)
1043 cdflags |= CS_DUMP_LINK_DOCS;
1044 if (ci->hide_sensitive)
1045 cdflags |= CS_DUMP_HIDE_SENSITIVE;
1046 if (ci->show_help)
1047 cdflags |= CS_DUMP_SHOW_DOCS;
1048
1049 struct HashElemArray hea = ARRAY_HEAD_INITIALIZER;
1050 if (ci->dump_config)
1051 {
1053 hea = get_elem_list(cs, gel_flags);
1054 }
1055 else
1056 {
1057 get_elem_queries(&ci->queries, &hea);
1058 }
1059
1060 dump_config(cs, &hea, cdflags, stdout);
1061 ARRAY_FREE(&hea);
1062 }
1063 else if (!ARRAY_EMPTY(&ci->alias_queries))
1064 {
1065 char **cp = NULL;
1067 {
1068 struct AddressList *al = alias_lookup(*cp);
1069 if (al)
1070 {
1071 /* output in machine-readable form */
1072 mutt_addrlist_to_intl(al, NULL);
1073 struct Buffer *buf = buf_pool_get();
1074 mutt_addrlist_write(al, buf, false);
1075 printf("%s\n", buf_string(buf));
1076 buf_pool_release(&buf);
1077 }
1078 else
1079 {
1080 printf("%s\n", NONULL(*cp)); // TEST19: neomutt -A unknown
1081 }
1082 }
1083 }
1084
1085 return false; // Stop
1086}
size_t mutt_addrlist_write(const struct AddressList *al, struct Buffer *buf, bool display)
Write an Address to a buffer.
Definition: address.c:1206
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1293
struct AddressList * alias_lookup(const char *name)
Find an Alias.
Definition: alias.c:277
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition: array.h:58
bool dump_config(struct ConfigSet *cs, struct HashElemArray *hea, ConfigDumpFlags flags, FILE *fp)
Write all the config to a file.
Definition: dump.c:196
#define CS_DUMP_HIDE_SENSITIVE
Obscure sensitive information like passwords.
Definition: dump.h:38
uint16_t ConfigDumpFlags
Flags for dump_config(), e.g. CS_DUMP_ONLY_CHANGED.
Definition: dump.h:35
#define CS_DUMP_LINK_DOCS
Link to the online docs.
Definition: dump.h:47
#define CS_DUMP_NO_FLAGS
No flags are set.
Definition: dump.h:36
#define CS_DUMP_SHOW_DOCS
Show one-liner documentation for the config item.
Definition: dump.h:46
static int get_elem_queries(struct StringArray *queries, struct HashElemArray *hea)
Lookup the HashElems for a set of queries.
Definition: main.c:675
bool show_help
-O Show one-liner help
Definition: objects.h:83
bool is_set
This struct has been used.
Definition: objects.h:80
struct StringArray queries
-Q Query a config option
Definition: objects.h:87
struct StringArray alias_queries
-A Lookup an alias
Definition: objects.h:86
bool dump_config
-D Dump the config
Definition: objects.h:81
bool dump_changed
-DD Dump the changed config
Definition: objects.h:82
bool hide_sensitive
-S Hide sensitive config
Definition: objects.h:84
GetElemListFlags
Flags for get_elem_list()
Definition: subset.h:80
@ GEL_CHANGED_CONFIG
Only config that has been changed.
Definition: subset.h:82
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char *  argv[],
char *  envp[] 
)

Start NeoMutt.

Parameters
argcNumber of command line arguments
argvList of command line arguments
envpCopy of the environment
Return values
0Success
1Error

Definition at line 1096 of file main.c.

1097{
1098 struct Email *e = NULL;
1099 SendFlags sendflags = SEND_NO_FLAGS;
1100 int rc = 1;
1101 bool repeat_error = false;
1102 struct Buffer *expanded_infile = buf_pool_get();
1103 struct Buffer *tempfile = buf_pool_get();
1104 struct ConfigSet *cs = NULL;
1105 struct CommandLine *cli = command_line_new();
1106
1108
1109 /* sanity check against stupid administrators */
1110 if (getegid() != getgid())
1111 {
1112 mutt_error("%s: I don't want to run with privileges!", (argc != 0) ? argv[0] : "neomutt");
1113 goto main_exit; // TEST01: neomutt (as root, chgrp mail neomutt; chmod +s neomutt)
1114 }
1115
1116 init_locale();
1117
1118 cs = cs_new(500);
1119 if (!cs)
1120 goto main_curses;
1121
1122 NeoMutt = neomutt_new(cs);
1123
1124 NeoMutt->env = envlist_init(envp);
1127
1128 init_config(cs);
1129
1130 cli_parse(argc, argv, cli);
1131
1132 if (!show_help(&cli->help))
1133 goto main_ok;
1134
1135 // Change the current umask, and save the original one
1136 NeoMutt->user_default_umask = umask(077);
1137 subjrx_init();
1138 attach_init();
1140
1141#ifdef USE_DEBUG_NOTIFY
1143#endif
1144
1145 if (!get_user_info(cs))
1146 goto main_exit;
1147
1148 reset_tilde(cs);
1149#ifdef ENABLE_NLS
1150 localise_config(cs);
1151#endif
1152
1153 if (!init_logging(&cli->shared, cs))
1154 goto main_exit;
1155
1156 mutt_log_prep();
1159 mutt_debug(LL_DEBUG1, "user's umask %03o\n", NeoMutt->user_default_umask);
1160 mutt_debug(LL_DEBUG3, "umask set to 077\n");
1161
1162 /* Check for a batch send. */
1163 if (!isatty(STDIN_FILENO) || !ARRAY_EMPTY(&cli->info.queries) ||
1165 {
1166 OptNoCurses = true;
1167 sendflags |= SEND_BATCH;
1170 }
1171
1172 /* Check to make sure stdout is available in curses mode. */
1173 if (!OptNoCurses && !isatty(STDOUT_FILENO))
1174 goto main_curses;
1175
1176 /* This must come before mutt_init() because curses needs to be started
1177 * before calling the init_pair() function to set the color scheme. */
1178 if (!OptNoCurses)
1179 {
1180 int crc = start_curses();
1181 if (crc != 0)
1182 goto main_curses; // TEST08: can't test -- fake term?
1183 }
1184
1185 /* Always create the mutt_windows because batch mode has some shared code
1186 * paths that end up referencing them. */
1187 rootwin_new();
1188
1189 if (!OptNoCurses)
1190 {
1191 /* check whether terminal status is supported (must follow curses init) */
1194 log_gui();
1195 }
1196
1198 alias_init();
1199 commands_init();
1200 hooks_init();
1202 imap_init();
1203#ifdef USE_LUA
1204 mutt_lua_init();
1205#endif
1207
1208 menu_init();
1209 sb_init();
1210#ifdef USE_NOTMUCH
1211 nm_init();
1212#endif
1213
1214 /* set defaults and read init files */
1215 int rc2 = mutt_init(cs, &cli->shared.log_level, &cli->shared.log_file,
1217 &cli->shared.commands);
1218 if (rc2 != 0)
1219 goto main_curses;
1220
1223
1224#ifdef USE_NOTMUCH
1225 const bool c_virtual_spool_file = cs_subset_bool(NeoMutt->sub, "virtual_spool_file");
1226 if (c_virtual_spool_file)
1227 {
1228 /* Find the first virtual folder and open it */
1229 struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
1231 struct MailboxNode *mp = STAILQ_FIRST(&ml);
1232 if (mp)
1233 cs_str_string_set(cs, "spool_file", mailbox_path(mp->mailbox), NULL);
1235 }
1236#endif
1237
1239
1240 init_nntp(&cli->tui.nntp_server, cs);
1241
1242 /* Initialize crypto backends. */
1243 crypt_init();
1244
1245 if (!buf_is_empty(&cli->shared.mbox_type) &&
1246 !config_str_set_initial(cs, "mbox_type", buf_string(&cli->shared.mbox_type)))
1247 {
1248 goto main_curses;
1249 }
1250
1251 if (!dump_info(&cli->info, cs))
1252 goto main_curses;
1253
1254 if (!OptNoCurses)
1255 {
1257 clear();
1261 }
1262
1263#ifdef USE_AUTOCRYPT
1264 /* Initialize autocrypt after curses messages are working,
1265 * because of the initial account setup screens. */
1266 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
1267 if (c_autocrypt)
1268 mutt_autocrypt_init(!(sendflags & SEND_BATCH));
1269#endif
1270
1271 /* Create the `$folder` directory if it doesn't exist. */
1272 const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
1273 if (!OptNoCurses && c_folder)
1274 {
1275 struct stat st = { 0 };
1276 struct Buffer *fpath = buf_pool_get();
1277
1278 buf_strcpy(fpath, c_folder);
1279 buf_expand_path(fpath);
1280 bool skip = false;
1281 /* we're not connected yet - skip mail folder creation */
1282 skip |= (imap_path_probe(buf_string(fpath), NULL) == MUTT_IMAP);
1283 skip |= (pop_path_probe(buf_string(fpath), NULL) == MUTT_POP);
1284 skip |= (nntp_path_probe(buf_string(fpath), NULL) == MUTT_NNTP);
1285 if (!skip && (stat(buf_string(fpath), &st) == -1) && (errno == ENOENT))
1286 {
1287 char msg2[256] = { 0 };
1288 snprintf(msg2, sizeof(msg2), _("%s does not exist. Create it?"), c_folder);
1289 if (query_yesorno(msg2, MUTT_YES) == MUTT_YES)
1290 {
1291 if ((mkdir(buf_string(fpath), 0700) == -1) && (errno != EEXIST))
1292 mutt_error(_("Can't create %s: %s"), c_folder, strerror(errno)); // TEST21: neomutt -n -F /dev/null (and ~/Mail doesn't exist)
1293 }
1294 }
1295 buf_pool_release(&fpath);
1296 }
1297
1298 StartupComplete = true;
1299
1304
1305 if (cli->tui.start_postponed)
1306 {
1307 if (!OptNoCurses)
1308 mutt_flushinp();
1309 if (mutt_send_message(SEND_POSTPONED, NULL, NULL, NULL, NULL, NeoMutt->sub) == 0)
1310 rc = 0;
1311 // TEST23: neomutt -p (postponed message, cancel)
1312 // TEST24: neomutt -p (no postponed message)
1314 repeat_error = true;
1315 goto main_curses;
1316 }
1317 else if (cli->send.is_set)
1318 {
1319 FILE *fp_in = NULL;
1320 FILE *fp_out = NULL;
1321 const char *infile = NULL;
1322 char *bodytext = NULL;
1323 const char *bodyfile = NULL;
1324 int rv = 0;
1325
1326 if (!OptNoCurses)
1327 mutt_flushinp();
1328
1329 e = email_new();
1330 e->env = mutt_env_new();
1331
1332 char **cp = NULL;
1333 ARRAY_FOREACH(cp, &cli->send.bcc_list)
1334 {
1335 mutt_addrlist_parse(&e->env->bcc, *cp);
1336 }
1337
1338 ARRAY_FOREACH(cp, &cli->send.cc_list)
1339 {
1340 mutt_addrlist_parse(&e->env->cc, *cp);
1341 }
1342
1343 ARRAY_FOREACH(cp, &cli->send.addresses)
1344 {
1345 if (url_check_scheme(*cp) == U_MAILTO)
1346 {
1347 if (!mutt_parse_mailto(e->env, &bodytext, *cp))
1348 {
1349 mutt_error(_("Failed to parse mailto: link"));
1350 email_free(&e);
1351 goto main_curses; // TEST25: neomutt mailto:?
1352 }
1353 }
1354 else
1355 {
1356 mutt_addrlist_parse(&e->env->to, *cp);
1357 }
1358 }
1359
1360 const bool c_auto_edit = cs_subset_bool(NeoMutt->sub, "auto_edit");
1361 if (buf_is_empty(&cli->send.draft_file) && c_auto_edit &&
1362 TAILQ_EMPTY(&e->env->to) && TAILQ_EMPTY(&e->env->cc))
1363 {
1364 mutt_error(_("No recipients specified"));
1365 email_free(&e);
1366 goto main_curses; // TEST26: neomutt -s test (with auto_edit=yes)
1367 }
1368
1369 if (!buf_is_empty(&cli->send.subject))
1370 {
1371 /* prevent header injection */
1374 }
1375
1376 if (!buf_is_empty(&cli->send.draft_file))
1377 {
1378 infile = buf_string(&cli->send.draft_file);
1379 }
1380 else if (!buf_is_empty(&cli->send.include_file))
1381 {
1382 infile = buf_string(&cli->send.include_file);
1383 }
1384 else
1385 {
1386 cli->send.edit_infile = false;
1387 }
1388
1389 if (infile || bodytext)
1390 {
1391 /* Prepare fp_in and expanded_infile. */
1392 if (infile)
1393 {
1394 if (mutt_str_equal("-", infile))
1395 {
1396 if (cli->send.edit_infile)
1397 {
1398 mutt_error(_("Can't use -E flag with stdin"));
1399 email_free(&e);
1400 goto main_curses; // TEST27: neomutt -E -H -
1401 }
1402 fp_in = stdin;
1403 }
1404 else
1405 {
1406 buf_strcpy(expanded_infile, infile);
1407 buf_expand_path(expanded_infile);
1408 fp_in = mutt_file_fopen(buf_string(expanded_infile), "r");
1409 if (!fp_in)
1410 {
1411 mutt_perror("%s", buf_string(expanded_infile));
1412 email_free(&e);
1413 goto main_curses; // TEST28: neomutt -E -H missing
1414 }
1415 }
1416 }
1417
1418 if (cli->send.edit_infile)
1419 {
1420 /* If editing the infile, keep it around afterwards so
1421 * it doesn't get unlinked, and we can rebuild the draft_file */
1422 sendflags |= SEND_NO_FREE_HEADER;
1423 }
1424 else
1425 {
1426 /* Copy input to a tempfile, and re-point fp_in to the tempfile.
1427 * Note: stdin is always copied to a tempfile, ensuring draft_file
1428 * can stat and get the correct st_size below. */
1429 buf_mktemp(tempfile);
1430
1431 fp_out = mutt_file_fopen(buf_string(tempfile), "w");
1432 if (!fp_out)
1433 {
1434 mutt_file_fclose(&fp_in);
1435 mutt_perror("%s", buf_string(tempfile));
1436 email_free(&e);
1437 goto main_curses; // TEST29: neomutt -H existing-file (where tmpdir=/path/to/FILE blocking tmpdir)
1438 }
1439 if (fp_in)
1440 {
1441 mutt_file_copy_stream(fp_in, fp_out);
1442 if (fp_in == stdin)
1443 sendflags |= SEND_CONSUMED_STDIN;
1444 else
1445 mutt_file_fclose(&fp_in);
1446 }
1447 else if (bodytext)
1448 {
1449 fputs(bodytext, fp_out);
1450 }
1451 mutt_file_fclose(&fp_out);
1452
1453 fp_in = mutt_file_fopen(buf_string(tempfile), "r");
1454 if (!fp_in)
1455 {
1456 mutt_perror("%s", buf_string(tempfile));
1457 email_free(&e);
1458 goto main_curses; // TEST30: can't test
1459 }
1460 }
1461
1462 /* Parse the draft_file into the full Email/Body structure.
1463 * Set SEND_DRAFT_FILE so mutt_send_message doesn't overwrite
1464 * our e->body. */
1465 if (!buf_is_empty(&cli->send.draft_file))
1466 {
1467 struct Envelope *opts_env = e->env;
1468 struct stat st = { 0 };
1469
1470 sendflags |= SEND_DRAFT_FILE;
1471
1472 /* Set up a tmp Email with just enough information so that
1473 * mutt_prepare_template() can parse the message in fp_in. */
1474 struct Email *e_tmp = email_new();
1475 e_tmp->offset = 0;
1476 e_tmp->body = mutt_body_new();
1477 if (fstat(fileno(fp_in), &st) != 0)
1478 {
1479 mutt_perror("%s", buf_string(&cli->send.draft_file));
1480 email_free(&e);
1481 email_free(&e_tmp);
1482 goto main_curses; // TEST31: can't test
1483 }
1484 e_tmp->body->length = st.st_size;
1485
1486 if (mutt_prepare_template(fp_in, NULL, e, e_tmp, false) < 0)
1487 {
1488 mutt_error(_("Can't parse message template: %s"),
1489 buf_string(&cli->send.draft_file));
1490 email_free(&e);
1491 email_free(&e_tmp);
1492 goto main_curses;
1493 }
1494
1495 /* Scan for neomutt header to set `$resume_draft_files` */
1496 struct ListNode *tmp = NULL;
1497 const bool c_resume_edited_draft_files = cs_subset_bool(NeoMutt->sub, "resume_edited_draft_files");
1498 struct ListNode *np = NULL;
1499 STAILQ_FOREACH_SAFE(np, &e->env->userhdrs, entries, tmp)
1500 {
1501 if (mutt_istr_startswith(np->data, "X-Mutt-Resume-Draft:"))
1502 {
1503 if (c_resume_edited_draft_files)
1504 cs_str_native_set(cs, "resume_draft_files", true, NULL);
1505
1506 STAILQ_REMOVE(&e->env->userhdrs, np, ListNode, entries);
1507 FREE(&np->data);
1508 FREE(&np);
1509 }
1510 }
1511
1512 mutt_addrlist_copy(&e->env->to, &opts_env->to, false);
1513 mutt_addrlist_copy(&e->env->cc, &opts_env->cc, false);
1514 mutt_addrlist_copy(&e->env->bcc, &opts_env->bcc, false);
1515 if (opts_env->subject)
1516 mutt_env_set_subject(e->env, opts_env->subject);
1517
1518 mutt_env_free(&opts_env);
1519 email_free(&e_tmp);
1520 }
1521 else if (cli->send.edit_infile)
1522 {
1523 /* Editing the include_file: pass it directly in.
1524 * Note that SEND_NO_FREE_HEADER is set above so it isn't unlinked. */
1525 bodyfile = buf_string(expanded_infile);
1526 }
1527 else
1528 {
1529 // For bodytext and unedited include_file: use the tempfile.
1530 bodyfile = buf_string(tempfile);
1531 }
1532
1533 mutt_file_fclose(&fp_in);
1534 }
1535
1536 FREE(&bodytext);
1537
1538 if (!ARRAY_EMPTY(&cli->send.attach))
1539 {
1540 struct Body *b = e->body;
1541
1542 while (b && b->next)
1543 b = b->next;
1544
1545 ARRAY_FOREACH(cp, &cli->send.attach)
1546 {
1547 if (b)
1548 {
1550 b = b->next;
1551 }
1552 else
1553 {
1555 e->body = b;
1556 }
1557 if (!b)
1558 {
1559 mutt_error(_("%s: unable to attach file"), *cp);
1560 email_free(&e);
1561 goto main_curses; // TEST32: neomutt john@example.com -a missing
1562 }
1563 }
1564 }
1565
1566 rv = mutt_send_message(sendflags, e, bodyfile, NULL, NULL, NeoMutt->sub);
1567 /* We WANT the "Mail sent." and any possible, later error */
1569 if (ErrorBufMessage)
1570 mutt_message("%s", ErrorBuf);
1571
1572 if (cli->send.edit_infile)
1573 {
1574 if (!buf_is_empty(&cli->send.draft_file))
1575 {
1576 if (truncate(buf_string(expanded_infile), 0) == -1)
1577 {
1578 mutt_perror("%s", buf_string(expanded_infile));
1579 email_free(&e);
1580 goto main_curses; // TEST33: neomutt -H read-only -s test john@example.com -E
1581 }
1582 fp_out = mutt_file_fopen(buf_string(expanded_infile), "a");
1583 if (!fp_out)
1584 {
1585 mutt_perror("%s", buf_string(expanded_infile));
1586 email_free(&e);
1587 goto main_curses; // TEST34: can't test
1588 }
1589
1590 /* If the message was sent or postponed, these will already
1591 * have been done. */
1592 if (rv < 0)
1593 {
1594 if (e->body->next)
1595 e->body = mutt_make_multipart(e->body);
1597 mutt_prepare_envelope(e->env, false, NeoMutt->sub);
1598 mutt_env_to_intl(e->env, NULL, NULL);
1599 }
1600
1601 const bool c_crypt_protected_headers_read = cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_read");
1603 c_crypt_protected_headers_read &&
1605 NeoMutt->sub);
1606 const bool c_resume_edited_draft_files = cs_subset_bool(NeoMutt->sub, "resume_edited_draft_files");
1607 if (c_resume_edited_draft_files)
1608 fprintf(fp_out, "X-Mutt-Resume-Draft: 1\n");
1609 fputc('\n', fp_out);
1610 if ((mutt_write_mime_body(e->body, fp_out, NeoMutt->sub) == -1))
1611 {
1612 mutt_file_fclose(&fp_out);
1613 email_free(&e);
1614 goto main_curses; // TEST35: can't test
1615 }
1616 mutt_file_fclose(&fp_out);
1617 }
1618
1619 email_free(&e);
1620 }
1621
1622 /* !edit_infile && draft_file will leave the tempfile around */
1623 if (!buf_is_empty(tempfile))
1624 unlink(buf_string(tempfile));
1625
1627
1628 if (rv != 0)
1629 goto main_curses; // TEST36: neomutt -H existing -s test john@example.com -E (cancel sending)
1630 }
1631 else if (sendflags & SEND_BATCH)
1632 {
1633 /* This guards against invoking `neomutt < /dev/null` and accidentally
1634 * sending an email due to a my_hdr or other setting. */
1635 mutt_error(_("No recipients specified"));
1636 goto main_curses;
1637 }
1638 else
1639 {
1640 struct Buffer *folder = &cli->tui.folder;
1641 if (cli->tui.start_new_mail)
1642 {
1643 const bool c_imap_passive = cs_subset_bool(NeoMutt->sub, "imap_passive");
1644 cs_subset_str_native_set(NeoMutt->sub, "imap_passive", false, NULL);
1646 if (mutt_mailbox_check(NULL, csflags) == 0)
1647 {
1648 mutt_message(_("No mailbox with new mail"));
1649 repeat_error = true;
1650 goto main_curses; // TEST37: neomutt -Z (no new mail)
1651 }
1652 buf_reset(folder);
1653 mutt_mailbox_next(NULL, folder);
1654 cs_subset_str_native_set(NeoMutt->sub, "imap_passive", c_imap_passive, NULL);
1655 }
1656 else if (cli->tui.start_nntp || cli->tui.start_browser)
1657 {
1658 if (cli->tui.start_nntp)
1659 {
1660 const char *const c_news_server = cs_subset_string(NeoMutt->sub, "news_server");
1661 OptNews = true;
1662 CurrentNewsSrv = nntp_select_server(NULL, c_news_server, false);
1663 if (!CurrentNewsSrv)
1664 goto main_curses; // TEST38: neomutt -G (unset news_server)
1665 }
1666 else if (TAILQ_EMPTY(&NeoMutt->accounts))
1667 {
1668 mutt_error(_("No incoming mailboxes defined"));
1669 goto main_curses; // TEST39: neomutt -n -F /dev/null -y
1670 }
1671 buf_reset(folder);
1672 dlg_browser(folder, MUTT_SEL_FOLDER | MUTT_SEL_MAILBOX, NULL, NULL, NULL);
1673 if (buf_is_empty(folder))
1674 {
1675 goto main_ok; // TEST40: neomutt -y (quit selection)
1676 }
1677 }
1678
1679 if (buf_is_empty(folder))
1680 {
1681 const char *const c_spool_file = cs_subset_string(NeoMutt->sub, "spool_file");
1682 if (c_spool_file)
1683 {
1684 // Check if `$spool_file` corresponds a mailboxes' description.
1685 struct Mailbox *m_desc = mailbox_find_name(c_spool_file);
1686 if (m_desc)
1687 buf_strcpy(folder, m_desc->realpath);
1688 else
1689 buf_strcpy(folder, c_spool_file);
1690 }
1691 else if (c_folder)
1692 {
1693 buf_strcpy(folder, c_folder);
1694 }
1695 /* else no folder */
1696 }
1697
1698 if (OptNews)
1699 {
1700 OptNews = false;
1701 buf_alloc(folder, PATH_MAX);
1702 nntp_expand_path(folder->data, folder->dsize, &CurrentNewsSrv->conn->account);
1703 }
1704 else
1705 {
1706 buf_expand_path(folder);
1707 }
1708
1711
1712 if (cli->tui.start_any_mail || cli->tui.start_new_mail)
1713 {
1714 /* check to see if there are any messages in the folder */
1715 switch (mx_path_is_empty(folder))
1716 {
1717 case -1:
1718 mutt_perror("%s", buf_string(folder));
1719 goto main_curses; // TEST41: neomutt -z -f missing
1720 case 1:
1721 mutt_error(_("Mailbox is empty"));
1722 goto main_curses; // TEST42: neomutt -z -f /dev/null
1723 }
1724 }
1725
1726 struct Mailbox *m_cur = mailbox_find(buf_string(folder));
1727 // Take a copy of the name just in case the hook alters m_cur
1728 const char *name = m_cur ? mutt_str_dup(m_cur->name) : NULL;
1730 FREE(&name);
1732 mutt_debug(LL_NOTIFY, "NT_GLOBAL_STARTUP\n");
1734
1736 window_redraw(NULL);
1737
1738 repeat_error = true;
1739 struct Mailbox *m = mx_resolve(buf_string(folder));
1740 const bool c_read_only = cs_subset_bool(NeoMutt->sub, "read_only");
1741 if (!mx_mbox_open(m, (cli->tui.read_only || c_read_only) ? MUTT_READONLY : MUTT_OPEN_NO_FLAGS))
1742 {
1743 if (m->account)
1745
1746 mailbox_free(&m);
1747 mutt_error(_("Unable to open mailbox %s"), buf_string(folder));
1748 repeat_error = false;
1749 }
1750 if (m || buf_is_empty(folder))
1751 {
1752 struct MuttWindow *dlg = index_pager_init();
1753 dialog_push(dlg);
1754
1756 m = dlg_index(dlg, m);
1758 mailbox_free(&m);
1759
1760 dialog_pop();
1761 mutt_window_free(&dlg);
1763 repeat_error = false;
1764 }
1766#ifdef USE_SASL_CYRUS
1768#endif
1769#ifdef USE_SASL_GNU
1771#endif
1772#ifdef USE_AUTOCRYPT
1774#endif
1775 // TEST43: neomutt (no change to mailbox)
1776 // TEST44: neomutt (change mailbox)
1777 }
1778
1779main_ok:
1780 rc = 0;
1781main_curses:
1782 mutt_endwin();
1784 /* Repeat the last message to the user */
1785 if (repeat_error && ErrorBufMessage)
1786 puts(ErrorBuf);
1787main_exit:
1788 if (NeoMutt && NeoMutt->sub)
1789 {
1794 }
1796 buf_pool_release(&expanded_infile);
1797 buf_pool_release(&tempfile);
1801 if (NeoMutt)
1805 menu_cleanup();
1806 crypt_cleanup();
1808 command_line_free(&cli);
1809
1811
1812 alias_cleanup();
1813 sb_cleanup();
1814
1820
1823
1824 /* Lists of strings */
1833
1835
1837 FREE(&LastFolder);
1839
1841
1843
1846
1848 if (NeoMutt)
1850
1858 cs_free(&cs);
1860 mutt_log_stop();
1861 return rc;
1862}
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:765
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:480
void alias_cleanup(void)
Clean up the Alias globals.
Definition: alias.c:719
void alias_init(void)
Set up the Alias globals.
Definition: alias.c:711
void alternates_cleanup(void)
Free the alternates lists.
Definition: alternates.c:49
void alternates_init(void)
Set up the alternates lists.
Definition: alternates.c:60
void attach_init(void)
Set up the attachments lists.
Definition: attachments.c:106
void attach_cleanup(void)
Free the attachments lists.
Definition: attachments.c:92
void mutt_autocrypt_cleanup(void)
Shutdown Autocrypt.
Definition: autocrypt.c:129
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:99
#define MUTT_SEL_MAILBOX
Select a mailbox.
Definition: lib.h:58
#define MUTT_SEL_FOLDER
Select a local directory.
Definition: lib.h:60
void buf_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:337
bool cli_parse(int argc, char **argv, struct CommandLine *cli)
Parse the Command Line.
Definition: parse.c:93
void colors_cleanup(void)
Cleanup all the colours.
Definition: color.c:84
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:54
void source_stack_cleanup(void)
Free memory from the stack used for the source command.
Definition: commands.c:1671
bool commands_init(void)
Initialize commands array and register default commands.
Definition: commands.c:1748
void mutt_comp_init(void)
Setup Compressed Mailbox commands.
Definition: compress.c:90
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:47
void cs_free(struct ConfigSet **ptr)
Free a Config Set.
Definition: set.c:141
struct ConfigSet * cs_new(size_t size)
Create a new Config Set.
Definition: set.c:127
int cs_str_native_set(const struct ConfigSet *cs, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: set.c:788
void config_cache_cleanup(void)
Cleanup the cache of charset config variables.
Definition: config_cache.c:145
bool account_mailbox_remove(struct Account *a, struct Mailbox *m)
Remove a Mailbox from an Account.
Definition: account.c:98
void commands_clear(struct CommandArray *ca)
Clear an Array of Commands.
Definition: command.c:70
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:89
struct Mailbox * mailbox_find_name(const char *name)
Find the mailbox with a given name.
Definition: mailbox.c:187
struct Mailbox * mailbox_find(const char *path)
Find the mailbox with a given path.
Definition: mailbox.c:150
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:223
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition: mailbox.h:51
@ MUTT_POP
'POP3' Mailbox type
Definition: mailbox.h:52
@ MUTT_NNTP
'NNTP' (Usenet) Mailbox type
Definition: mailbox.h:49
@ MUTT_IMAP
'IMAP' Mailbox type
Definition: mailbox.h:50
bool mutt_should_hide_protected_subject(struct Email *e)
Should NeoMutt hide the protected subject?
Definition: crypt.c:1100
void crypto_module_cleanup(void)
Clean up the crypto modules.
Definition: crypt_mod.c:84
void crypt_cleanup(void)
Clean up backend.
Definition: cryptglue.c:141
void crypt_init(void)
Initialise the crypto backends.
Definition: cryptglue.c:93
void mutt_endwin(void)
Shutdown curses.
Definition: curs_lib.c:152
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: get.c:58
int debug_all_observer(struct NotifyCallback *nc)
Definition: notify.c:196
void dialog_push(struct MuttWindow *dlg)
Display a Window to the user.
Definition: dialog.c:109
void dialog_pop(void)
Hide a Window from the user.
Definition: dialog.c:142
void mutt_browser_cleanup(void)
Clean up working Buffers.
Definition: dlg_browser.c:159
struct MuttWindow * index_pager_init(void)
Allocate the Windows for the Index/Pager.
Definition: dlg_index.c:1437
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:44
struct Email * email_new(void)
Create a new Email.
Definition: email.c:77
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:46
struct ReplaceList SpamList
List of regexes to match subscribed mailing lists.
Definition: globals.c:46
struct RegexList SubscribedLists
List of header patterns to unignore (see)
Definition: globals.c:48
struct RegexList UnSubscribedLists
Definition: globals.c:54
struct RegexList UnMailLists
List of regexes to exclude false matches in SubscribedLists.
Definition: globals.c:52
struct RegexList MailLists
List of permitted fields in a mailto: url.
Definition: globals.c:40
struct ListHead Ignore
List of regexes to match mailing lists.
Definition: globals.c:38
struct RegexList NoSpamList
List of regexes and patterns to match spam emails.
Definition: globals.c:44
struct ListHead UnIgnore
List of regexes to exclude false matches in MailLists.
Definition: globals.c:50
bool mutt_parse_mailto(struct Envelope *env, char **body, const char *src)
Parse a mailto:// url.
Definition: parse.c:1754
void mutt_filter_commandline_header_value(char *header)
Sanitise characters in a header value.
Definition: parse.c:93
int mutt_env_to_intl(struct Envelope *env, const char **tag, char **err)
Convert an Envelope's Address fields to Punycode format.
Definition: envelope.c:355
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:126
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:46
void mutt_env_set_subject(struct Envelope *env, const char *subj)
Set both subject and real_subj to subj.
Definition: envelope.c:69
void envlist_free(char ***envp)
Free the private copy of the environment.
Definition: envlist.c:42
char ** envlist_init(char **envp)
Create a copy of the environment.
Definition: envlist.c:58
void external_cleanup(void)
Clean up commands globals.
Definition: external.c:80
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:225
bool OptNews
(pseudo) used to change reader mode
Definition: globals.c:63
char * LastFolder
Previously selected mailbox.
Definition: globals.c:40
struct ListHead MimeLookupList
List of mime types that that shouldn't use the mailcap entry.
Definition: globals.c:47
struct ListHead AlternativeOrderList
List of preferred mime types to display.
Definition: globals.c:44
struct ListHead AutoViewList
List of mime types to auto view.
Definition: globals.c:45
char ErrorBuf[1024]
Copy of the last error message.
Definition: globals.c:35
bool ErrorBufMessage
true if the last message was an error
Definition: globals.c:34
char * CurrentFolder
Currently selected mailbox.
Definition: globals.c:39
struct ListHead UserHeader
List of custom headers to add to outgoing emails.
Definition: globals.c:49
struct ListHead HeaderOrderList
List of header fields in the order they should be displayed.
Definition: globals.c:46
void mutt_grouplist_init(void)
Initialize the GroupList singleton.
Definition: group.c:95
void mutt_grouplist_cleanup(void)
Free GroupList singleton resource.
Definition: group.c:107
void dlg_browser(struct Buffer *file, SelectFileFlags flags, struct Mailbox *m, char ***files, int *numfiles)
Let the user select a file -.
Definition: dlg_browser.c:853
struct Mailbox * dlg_index(struct MuttWindow *dlg, struct Mailbox *m_init)
Display a list of emails -.
Definition: dlg_index.c:1100
int log_disp_queue(time_t stamp, const char *file, int line, const char *function, enum LogLevel level, const char *format,...)
Save a log line to an internal queue - Implements log_dispatcher_t -.
Definition: logging.c:378
int log_disp_curses(time_t stamp, const char *file, int line, const char *function, enum LogLevel level, const char *format,...)
Display a log line in the message line - Implements log_dispatcher_t -.
Definition: mutt_logging.c:88
#define mutt_message(...)
Definition: logging2.h:92
enum MailboxType nntp_path_probe(const char *path, const struct stat *st)
Is this an NNTP Mailbox? - Implements MxOps::path_probe() -.
Definition: nntp.c:2786
enum MailboxType pop_path_probe(const char *path, const struct stat *st)
Is this a POP Mailbox? - Implements MxOps::path_probe() -.
Definition: pop.c:1156
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe() -.
Definition: imap.c:2348
int main_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition: init.c:250
int main_hist_observer(struct NotifyCallback *nc)
Notification that a Config Variable has change - Implements observer_t -.
Definition: history.c:709
static int main_timeout_observer(struct NotifyCallback *nc)
Notification that a timeout has occurred - Implements observer_t -.
Definition: main.c:909
int main_log_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition: mutt_logging.c:284
void mutt_gsasl_cleanup(void)
Shutdown GNU SASL library.
Definition: gsasl.c:149
int mutt_rfc822_write_header(FILE *fp, struct Envelope *env, struct Body *b, enum MuttWriteHeaderMode mode, bool privacy, bool hide_protected_subject, struct ConfigSubset *sub)
Write out one RFC822 header line.
Definition: header.c:577
@ MUTT_WRITE_HEADER_POSTPONE
A postponed Email, just the envelope info.
Definition: header.h:42
void mutt_hist_read_file(void)
Read the History from a file.
Definition: history.c:600
void mutt_hist_init(void)
Create a set of empty History ring buffers.
Definition: history.c:472
void mutt_hist_cleanup(void)
Free all the history lists.
Definition: history.c:445
void mutt_startup_shutdown_hook(HookFlags type)
Execute any startup/shutdown hooks.
Definition: hook.c:965
void mutt_delete_hooks(HookFlags type)
Delete matching hooks.
Definition: hook.c:398
void mutt_folder_hook(const char *path, const char *desc)
Perform a folder hook.
Definition: hook.c:632
void hooks_init(void)
Setup feature commands.
Definition: hook.c:1053
#define MUTT_STARTUP_HOOK
startup-hook: run when starting NeoMutt
Definition: hook.h:54
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:36
void imap_logout_all(void)
Close all open connections.
Definition: imap.c:557
void imap_init(void)
Setup feature commands.
Definition: imap.c:96
void mutt_keys_cleanup(void)
Free the key maps.
Definition: init.c:215
void mutt_init_abort_key(void)
Parse the abort_key config string.
Definition: init.c:228
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:123
int(*) log_dispatcher_ MuttLogger)
@ LL_DEBUG3
Log at debug level 3.
Definition: logging2.h:46
@ LL_NOTIFY
Log of notifications.
Definition: logging2.h:49
static void init_locale(void)
Initialise the Locale/NLS settings.
Definition: main.c:791
static void localise_config(struct ConfigSet *cs)
Localise some config.
Definition: main.c:729
static bool init_logging(struct CliShared *shared, struct ConfigSet *cs)
Initialise the Logging.
Definition: main.c:974
static void log_translation(void)
Log the translation being used.
Definition: main.c:860
static void log_gui(void)
Log info about the GUI.
Definition: main.c:886
static void reset_tilde(struct ConfigSet *cs)
Temporary measure.
Definition: main.c:706
static void init_nntp(struct Buffer *server, struct ConfigSet *cs)
Initialise the NNTP config.
Definition: main.c:1003
static bool show_help(struct CliHelp *help)
Show the Help.
Definition: main.c:943
static int start_curses(void)
Start the Curses UI.
Definition: main.c:759
static bool dump_info(struct CliInfo *ci, struct ConfigSet *cs)
Show config info.
Definition: main.c:1032
bool StartupComplete
When the config has been read.
Definition: main.c:199
static bool get_user_info(struct ConfigSet *cs)
Find the user's name, home and shell.
Definition: main.c:819
static int mutt_init(struct ConfigSet *cs, struct Buffer *dlevel, struct Buffer *dfile, bool skip_sys_rc, struct StringArray *user_files, struct StringArray *commands)
Initialise NeoMutt.
Definition: main.c:407
void menu_init(void)
Initialise all the Menus.
Definition: menu.c:79
void menu_cleanup(void)
Free the saved Menu searches.
Definition: menu.c:70
struct Body * mutt_make_multipart(struct Body *b)
Create a multipart email.
Definition: multipart.c:100
void mutt_ch_cache_cleanup(void)
Clean up the cached iconv handles and charset strings.
Definition: charset.c:1175
void log_queue_empty(void)
Free the contents of the queue.
Definition: logging.c:325
void log_queue_set_max_size(int size)
Set a upper limit for the queue length.
Definition: logging.c:313
bool notify_observer_remove(struct Notify *notify, const observer_t callback, const void *global_data)
Remove an observer from an object.
Definition: notify.c:230
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:191
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:173
void mutt_regexlist_free(struct RegexList *rl)
Free a RegexList object.
Definition: regex.c:179
void mutt_replacelist_free(struct ReplaceList *rl)
Free a ReplaceList object.
Definition: regex.c:450
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:243
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:281
#define PATH_MAX
Definition: mutt.h:42
void mutt_temp_attachments_cleanup(void)
Delete all temporary attachments.
Definition: mutt_attach.c:1305
void init_config(struct ConfigSet *cs)
Initialise the config system.
Definition: mutt_config.c:930
enum MuttCursorState mutt_curses_set_cursor(enum MuttCursorState state)
Set the cursor state.
Definition: mutt_curses.c:94
const struct AttrColor * mutt_curses_set_color_by_id(enum ColorId cid)
Set the colour and attributes by the Colour ID.
Definition: mutt_curses.c:79
void mutt_resize_screen(void)
Update NeoMutt's opinion about the window size.
Definition: resize.c:76
@ MUTT_CURSOR_INVISIBLE
Hide the cursor.
Definition: mutt_curses.h:65
@ MUTT_CURSOR_VISIBLE
Display a normal cursor.
Definition: mutt_curses.h:66
void mutt_log_stop(void)
Close the log file.
Definition: mutt_logging.c:181
void mutt_log_prep(void)
Prepare to log.
Definition: mutt_logging.c:171
void mutt_lua_init(void)
Setup feature commands.
Definition: mutt_lua.c:469
int mutt_mailbox_check(struct Mailbox *m_cur, CheckStatsFlags flags)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:169
struct Mailbox * mutt_mailbox_next(struct Mailbox *m_cur, struct Buffer *s)
Incoming folders completion routine.
Definition: mutt_mailbox.c:361
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:599
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
Definition: mutt_window.c:205
bool mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:288
struct Mailbox * mx_resolve(const char *path_or_name)
Get a Mailbox from either a path or name.
Definition: mx.c:1710
int mx_path_is_empty(struct Buffer *path)
Is the mailbox empty.
Definition: mx.c:1257
#define MUTT_READONLY
Open in read-only mode.
Definition: mxapi.h:43
#define MUTT_MAILBOX_CHECK_IMMEDIATE
Don't postpone the actual checking.
Definition: mxapi.h:53
#define MUTT_OPEN_NO_FLAGS
No flags are set.
Definition: mxapi.h:40
uint8_t CheckStatsFlags
Flags for mutt_mailbox_check.
Definition: mxapi.h:49
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:173
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:196
struct NeoMutt * neomutt_new(struct ConfigSet *cs)
Create the main NeoMutt object.
Definition: neomutt.c:50
void neomutt_free(struct NeoMutt **ptr)
Free a NeoMutt.
Definition: neomutt.c:86
@ NT_GLOBAL_STARTUP
NeoMutt is initialised.
Definition: neomutt.h:67
void nntp_expand_path(char *buf, size_t buflen, struct ConnAccount *acct)
Make fully qualified url from newsgroup name.
Definition: newsrc.c:556
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:77
struct NntpAccountData * nntp_select_server(struct Mailbox *m, const char *server, bool leave_lock)
Open a connection to an NNTP server.
Definition: newsrc.c:945
@ NT_TIMEOUT
Timeout has occurred.
Definition: notify_type.h:56
@ NT_CONFIG
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:43
@ NT_ALL
Register for all notifications.
Definition: notify_type.h:35
@ NT_GLOBAL
Not object-related, NotifyGlobal.
Definition: notify_type.h:46
@ NT_RESIZE
Window has been resized.
Definition: notify_type.h:52
void nm_init(void)
Setup feature commands.
Definition: notmuch.c:109
struct CommandLine * command_line_new(void)
Create a new CommandLine.
Definition: objects.c:105
void command_line_free(struct CommandLine **ptr)
Free a CommandLine.
Definition: objects.c:114
void buf_pool_cleanup(void)
Release the Buffer pool.
Definition: pool.c:68
int mutt_prepare_template(FILE *fp, struct Mailbox *m, struct Email *e_new, struct Email *e, bool resend)
Prepare a message template.
Definition: postpone.c:487
void mutt_prex_cleanup(void)
Cleanup heap memory allocated by compiled regexes.
Definition: prex.c:339
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:39
enum QuadOption query_yesorno(const char *prompt, enum QuadOption def)
Ask the user a Yes/No question.
Definition: question.c:327
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:441
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
#define STAILQ_FIRST(head)
Definition: queue.h:388
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:400
#define TAILQ_EMPTY(head)
Definition: queue.h:778
void rootwin_cleanup(void)
Free all the default Windows.
Definition: rootwin.c:202
void rootwin_new(void)
Create the default Windows.
Definition: rootwin.c:214
void mutt_sasl_cleanup(void)
Invoke when processing is complete.
Definition: sasl.c:786
int mutt_write_mime_body(struct Body *b, FILE *fp, struct ConfigSubset *sub)
Write a MIME part.
Definition: body.c:300
void mutt_encode_descriptions(struct Body *b, bool recurse, struct ConfigSubset *sub)
RFC2047 encode the content-descriptions.
Definition: send.c:1489
int mutt_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile, struct Mailbox *m, struct EmailArray *ea, struct ConfigSubset *sub)
Send an email.
Definition: send.c:2034
#define SEND_BATCH
Send email in batch mode (without user interaction)
Definition: send.h:47
#define SEND_NO_FREE_HEADER
Used by the -E flag.
Definition: send.h:51
#define SEND_DRAFT_FILE
Used by the -H flag.
Definition: send.h:52
uint32_t SendFlags
Flags for mutt_send_message(), e.g. SEND_REPLY.
Definition: send.h:40
#define SEND_POSTPONED
Recall a postponed email.
Definition: send.h:46
#define SEND_CONSUMED_STDIN
stdin has been read; don't read it twice
Definition: send.h:57
#define SEND_NO_FLAGS
No flags are set.
Definition: send.h:41
struct Body * mutt_make_file_attach(const char *path, struct ConfigSubset *sub)
Create a file attachment.
Definition: sendlib.c:607
void mutt_prepare_envelope(struct Envelope *env, bool final, struct ConfigSubset *sub)
Prepare an email header.
Definition: sendlib.c:780
void sb_init(void)
Set up the Sidebar.
Definition: sidebar.c:204
void sb_cleanup(void)
Clean up the Sidebar.
Definition: sidebar.c:220
The body of an email.
Definition: body.h:36
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:68
LOFF_T length
length (in bytes) of attachment
Definition: body.h:53
struct Body * next
next attachment in the list
Definition: body.h:72
size_t dsize
Length of data.
Definition: buffer.h:39
struct Buffer draft_file
-H Use this draft file
Definition: objects.h:104
bool is_set
This struct has been used.
Definition: objects.h:95
struct Buffer include_file
-i Use this include file
Definition: objects.h:105
struct StringArray cc_list
-c Add a Cc:
Definition: objects.h:101
struct StringArray attach
-a Attach a file
Definition: objects.h:99
bool edit_infile
-E Edit the draft/include
Definition: objects.h:97
struct StringArray bcc_list
-b Add a Bcc:
Definition: objects.h:100
struct StringArray addresses
Send to these addresses.
Definition: objects.h:102
struct Buffer subject
-s Use this Subject:
Definition: objects.h:106
struct StringArray commands
-e Run these commands
Definition: objects.h:55
bool disable_system
-n Don't read the system config file
Definition: objects.h:53
struct StringArray user_files
-F Use these user config files
Definition: objects.h:52
struct Buffer mbox_type
-m Set the default Mailbox type
Definition: objects.h:56
bool read_only
-R Open Mailbox read-only
Definition: objects.h:115
bool start_any_mail
-z Check for Any Mail
Definition: objects.h:120
bool start_nntp
-G Open an NNTP Mailbox
Definition: objects.h:118
struct Buffer nntp_server
-g Open this NNTP Mailbox
Definition: objects.h:123
struct Buffer folder
-f Open this Mailbox
Definition: objects.h:122
bool start_postponed
-p Open Postponed emails
Definition: objects.h:116
bool start_new_mail
-Z Check for New Mail
Definition: objects.h:119
bool start_browser
-y Open the Mailbox Browser
Definition: objects.h:117
Command Line options.
Definition: objects.h:130
struct CliSend send
Send Mode command line options.
Definition: objects.h:134
struct CliShared shared
Shared command line options.
Definition: objects.h:131
struct CliHelp help
Help Mode command line options.
Definition: objects.h:132
struct CliInfo info
Info Mode command line options.
Definition: objects.h:133
struct CliTui tui
Tui Mode command line options.
Definition: objects.h:135
Container for lots of config items.
Definition: set.h:248
struct Notify * notify
Notifications: NotifyConfig, EventConfig.
Definition: subset.h:51
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:49
The envelope/body of an email.
Definition: email.h:39
struct Envelope * env
Envelope information.
Definition: email.h:68
struct Body * body
List of MIME parts.
Definition: email.h:69
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:71
The header of an Email.
Definition: envelope.h:57
struct ListHead userhdrs
user defined headers
Definition: envelope.h:85
char *const subject
Email's subject.
Definition: envelope.h:70
struct AddressList to
Email's 'To' list.
Definition: envelope.h:60
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:61
struct AddressList bcc
Email's 'Bcc' list.
Definition: envelope.h:62
A List node for strings.
Definition: list.h:37
char * data
String.
Definition: list.h:38
List of Mailboxes.
Definition: mailbox.h:166
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:167
A mailbox.
Definition: mailbox.h:79
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:81
char * name
A short name for the Mailbox.
Definition: mailbox.h:82
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:127
struct CommandArray commands
NeoMutt commands.
Definition: neomutt.h:51
struct Notify * notify_resize
Window resize notifications handler.
Definition: neomutt.h:45
char ** env
Private copy of the environment variables.
Definition: neomutt.h:55
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:48
mode_t user_default_umask
User's default file writing permissions (inferred from umask)
Definition: neomutt.h:50
struct Notify * notify
Notifications handler.
Definition: neomutt.h:44
struct Connection * conn
Connection to NNTP Server.
Definition: adata.h:62
void subjrx_init(void)
Create new Subject Regex List.
Definition: subjectrx.c:55
void subjrx_cleanup(void)
Free the Subject Regex List.
Definition: subjectrx.c:46
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:299
void driver_tags_cleanup(void)
Deinitialize structures used for tags.
Definition: tags.c:245
void driver_tags_init(void)
Initialize structures used for tags.
Definition: tags.c:233
bool TsSupported
Terminal Setting is supported.
Definition: terminal.c:42
bool mutt_ts_capability(void)
Check terminal capabilities.
Definition: terminal.c:72
#define buf_mktemp(buf)
Definition: tmp.h:33
enum UrlScheme url_check_scheme(const char *str)
Check the protocol of a URL.
Definition: url.c:226
@ U_MAILTO
Url is mailto://.
Definition: url.h:45

Variable Documentation

◆ StartupComplete

bool StartupComplete = false

When the config has been read.

Definition at line 199 of file main.c.