NeoMutt  2024-12-12-19-ge4b57e
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 <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.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 "color/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 "pop/lib.h"
#include "postpone/lib.h"
#include "question/lib.h"
#include "send/lib.h"
#include "alternates.h"
#include "external.h"
#include "globals.h"
#include "hook.h"
#include "init.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"

Go to the source code of this file.

Macros

#define GNULIB_defined_setlocale
 
#define MUTT_CLI_NO_FLAGS   0
 No flags are set.
 
#define MUTT_CLI_IGNORE   (1 << 0)
 -z Open first mailbox if it has mail
 
#define MUTT_CLI_MAILBOX   (1 << 1)
 -Z Open first mailbox if is has new mail
 
#define MUTT_CLI_NOSYSRC   (1 << 2)
 -n Do not read the system-wide config file
 
#define MUTT_CLI_RO   (1 << 3)
 -R Open mailbox in read-only mode
 
#define MUTT_CLI_SELECT   (1 << 4)
 -y Start with a list of all mailboxes
 
#define MUTT_CLI_NEWS   (1 << 5)
 -g/-G Start with a list of all newsgroups
 

Typedefs

typedef uint8_t CliFlags
 Flags for command line options, e.g. MUTT_CLI_IGNORE.
 

Functions

static void reset_tilde (struct ConfigSet *cs)
 Temporary measure.
 
static void localise_config (struct ConfigSet *cs)
 Localise some config.
 
void mutt_exit (int code)
 Leave NeoMutt NOW.
 
static bool usage (void)
 Display NeoMutt command line.
 
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.
 
int main_timeout_observer (struct NotifyCallback *nc)
 Notification that a timeout has occurred - Implements observer_t -.
 
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.

◆ MUTT_CLI_NO_FLAGS

#define MUTT_CLI_NO_FLAGS   0

No flags are set.

Definition at line 193 of file main.c.

◆ MUTT_CLI_IGNORE

#define MUTT_CLI_IGNORE   (1 << 0)

-z Open first mailbox if it has mail

Definition at line 194 of file main.c.

◆ MUTT_CLI_MAILBOX

#define MUTT_CLI_MAILBOX   (1 << 1)

-Z Open first mailbox if is has new mail

Definition at line 195 of file main.c.

◆ MUTT_CLI_NOSYSRC

#define MUTT_CLI_NOSYSRC   (1 << 2)

-n Do not read the system-wide config file

Definition at line 196 of file main.c.

◆ MUTT_CLI_RO

#define MUTT_CLI_RO   (1 << 3)

-R Open mailbox in read-only mode

Definition at line 197 of file main.c.

◆ MUTT_CLI_SELECT

#define MUTT_CLI_SELECT   (1 << 4)

-y Start with a list of all mailboxes

Definition at line 198 of file main.c.

◆ MUTT_CLI_NEWS

#define MUTT_CLI_NEWS   (1 << 5)

-g/-G Start with a list of all newsgroups

Definition at line 199 of file main.c.

Typedef Documentation

◆ CliFlags

typedef uint8_t CliFlags

Flags for command line options, e.g. MUTT_CLI_IGNORE.

Definition at line 192 of file main.c.

Function Documentation

◆ reset_tilde()

static void reset_tilde ( struct ConfigSet cs)
static

Temporary measure.

Parameters
csConfig Set

Definition at line 206 of file main.c.

207{
208 static const char *names[] = { "folder", "mbox", "postponed", "record" };
209
210 struct Buffer *value = buf_pool_get();
211 for (size_t i = 0; i < mutt_array_size(names); i++)
212 {
213 struct HashElem *he = cs_get_elem(cs, names[i]);
214 if (!he)
215 continue;
216 buf_reset(value);
217 cs_he_initial_get(cs, he, value);
218 buf_expand_path_regex(value, false);
219 cs_he_initial_set(cs, he, value->data, NULL);
220 cs_he_reset(cs, he, NULL);
221 }
222 buf_pool_release(&value);
223}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:76
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_reset(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err)
Reset a config item to its initial value.
Definition: set.c:391
int cs_he_initial_set(const struct ConfigSet *cs, struct HashElem *he, const char *value, struct Buffer *err)
Set the initial value of a config item.
Definition: set.c:461
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:529
#define mutt_array_size(x)
Definition: memory.h:38
void buf_expand_path_regex(struct Buffer *buf, bool regex)
Create the canonical path (with regex char escaping)
Definition: muttlib.c:122
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
String manipulation buffer.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:37
The item stored in a Hash Table.
Definition: hash.h:43
+ 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 230 of file main.c.

231{
232 static const char *names[] = {
233 "attribution_intro",
234 "compose_format",
235 "forward_attribution_intro",
236 "forward_attribution_trailer",
237 "reply_regex",
238 "status_format",
239 "ts_icon_format",
240 "ts_status_format",
241 };
242
243 struct Buffer *value = buf_pool_get();
244 for (size_t i = 0; i < mutt_array_size(names); i++)
245 {
246 struct HashElem *he = cs_get_elem(cs, names[i]);
247 if (!he)
248 continue;
249 buf_reset(value);
250 cs_he_initial_get(cs, he, value);
251
252 // Lookup the translation
253 const char *l10n = gettext(buf_string(value));
254
255 cs_he_initial_set(cs, he, l10n, NULL);
256 cs_he_reset(cs, he, NULL);
257 }
258 buf_pool_release(&value);
259}
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_exit()

void mutt_exit ( int  code)

Leave NeoMutt NOW.

Parameters
codeValue to return to the calling environment

Definition at line 266 of file main.c.

267{
268 mutt_endwin();
269#ifdef USE_DEBUG_BACKTRACE
270 if (code != 0)
272#endif
273 exit(code);
274}
void show_backtrace(void)
Log the program's call stack.
Definition: backtrace.c:39
void mutt_endwin(void)
Shutdown curses.
Definition: curs_lib.c:151
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ usage()

static bool usage ( void  )
static

Display NeoMutt command line.

Return values
trueText displayed

Definition at line 280 of file main.c.

281{
282 puts(mutt_make_version());
283
284 // clang-format off
285 /* L10N: Try to limit to 80 columns */
286 puts(_("usage:"));
287 puts(_(" neomutt [-CEn] [-e <command>] [-F <config>] [-H <draft>] [-i <include>]\n"
288 " [-b <address>] [-c <address>] [-s <subject>] [-a <file> [...] --]\n"
289 " <address> [...]"));
290 puts(_(" neomutt [-Cn] [-e <command>] [-F <config>] [-b <address>] [-c <address>]\n"
291 " [-s <subject>] [-a <file> [...] --] <address> [...] < message"));
292 puts(_(" neomutt [-nRy] [-e <command>] [-F <config>] [-f <mailbox>] [-m <type>]"));
293 puts(_(" neomutt [-n] [-e <command>] [-F <config>] -A <alias>"));
294 puts(_(" neomutt [-n] [-e <command>] [-F <config>] -B"));
295 puts(_(" neomutt [-n] [-e <command>] [-F <config>] -D [-S] [-O]"));
296 puts(_(" neomutt [-n] [-e <command>] [-F <config>] -d <level> -l <file>"));
297 puts(_(" neomutt [-n] [-e <command>] [-F <config>] -G"));
298 puts(_(" neomutt [-n] [-e <command>] [-F <config>] -g <server>"));
299 puts(_(" neomutt [-n] [-e <command>] [-F <config>] -p"));
300 puts(_(" neomutt [-n] [-e <command>] [-F <config>] -Q <variable> [-O]"));
301 puts(_(" neomutt [-n] [-e <command>] [-F <config>] -Z"));
302 puts(_(" neomutt [-n] [-e <command>] [-F <config>] -z [-f <mailbox>]"));
303 puts(_(" neomutt -v[v]\n"));
304
305 /* L10N: Try to limit to 80 columns. If more space is needed add an indented line */
306 puts(_("options:"));
307 puts(_(" -- Special argument forces NeoMutt to stop option parsing and treat\n"
308 " remaining arguments as addresses even if they start with a dash"));
309 puts(_(" -A <alias> Print an expanded version of the given alias to stdout and exit"));
310 puts(_(" -a <file> Attach one or more files to a message (must be the last option)\n"
311 " Add any addresses after the '--' argument"));
312 puts(_(" -B Run in batch mode (do not start the ncurses UI)"));
313 puts(_(" -b <address> Specify a blind carbon copy (Bcc) recipient"));
314 puts(_(" -c <address> Specify a carbon copy (Cc) recipient"));
315 puts(_(" -C Enable Command-line Crypto (signing/encryption)"));
316 puts(_(" -D Dump all config variables as 'name=value' pairs to stdout"));
317 puts(_(" -D -O Like -D, but show one-liner documentation"));
318 puts(_(" -D -S Like -D, but hide the value of sensitive variables"));
319 puts(_(" -d <level> Log debugging output to a file (default is \"~/.neomuttdebug0\")\n"
320 " The level can range from 1-5 and affects verbosity"));
321 puts(_(" -E Edit draft (-H) or include (-i) file during message composition"));
322 puts(_(" -e <command> Specify a command to be run after reading the config files"));
323 puts(_(" -F <config> Specify an alternative initialization file to read"));
324 puts(_(" -f <mailbox> Specify a mailbox (as defined with 'mailboxes' command) to load"));
325 puts(_(" -G Start NeoMutt with a listing of subscribed newsgroups"));
326 puts(_(" -g <server> Like -G, but start at specified news server"));
327 puts(_(" -H <draft> Specify a draft file with header and body for message composing"));
328 puts(_(" -h Print this help message and exit"));
329 puts(_(" -i <include> Specify an include file to be embedded in the body of a message"));
330 puts(_(" -l <file> Specify a file for debugging output (default \"~/.neomuttdebug0\")"));
331 puts(_(" -m <type> Specify a default mailbox format type for newly created folders\n"
332 " The type is either MH, MMDF, Maildir or mbox (case-insensitive)"));
333 puts(_(" -n Do not read the system-wide configuration file"));
334 puts(_(" -p Resume a prior postponed message, if any"));
335 puts(_(" -Q <variable> Query a configuration variable and print its value to stdout\n"
336 " (after the config has been read and any commands executed)\n"
337 " Add -O for one-liner documentation"));
338 puts(_(" -R Open mailbox in read-only mode"));
339 puts(_(" -s <subject> Specify a subject (must be enclosed in quotes if it has spaces)"));
340 puts(_(" -v Print the NeoMutt version and compile-time definitions and exit"));
341 puts(_(" -vv Print the NeoMutt license and copyright information and exit"));
342 puts(_(" -y Start NeoMutt with a listing of all defined mailboxes"));
343 puts(_(" -Z Open the first mailbox with new message or exit immediately with\n"
344 " exit code 1 if none is found in all defined mailboxes"));
345 puts(_(" -z Open the first or specified (-f) mailbox if it holds any message\n"
346 " or exit immediately with exit code 1 otherwise"));
347 // clang-format on
348
349 fflush(stdout);
350 return !ferror(stdout);
351}
#define _(a)
Definition: message.h:28
const char * mutt_make_version(void)
Generate the NeoMutt version string.
Definition: muttlib.c:858
+ 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 358 of file main.c.

359{
360 km_init(); /* must come before mutt_init */
361
362 /* should come before initscr() so that ncurses 4.2 doesn't try to install
363 * its own SIGWINCH handler */
365
366 if (!initscr())
367 {
368 mutt_error(_("Error initializing terminal"));
369 return 1;
370 }
371
372 colors_init();
373 keypad(stdscr, true);
374 cbreak();
375 noecho();
376 nonl();
377 typeahead(-1); /* simulate smooth scrolling */
378 meta(stdscr, true);
380 /* Now that curses is set up, we drop back to normal screen mode.
381 * This simplifies displaying error messages to the user.
382 * The first call to refresh() will swap us back to curses screen mode. */
383 endwin();
384 return 0;
385}
void colors_init(void)
Initialize colours.
Definition: color.c:49
#define mutt_error(...)
Definition: logging2.h:92
void km_init(void)
Initialise all the menu keybindings.
Definition: init.c:177
void init_extended_keys(void)
Initialise map of ncurses extended keys.
Definition: init.c:134
void mutt_signal_init(void)
Initialise the signal handling.
Definition: mutt_signal.c:130
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 390 of file main.c.

391{
392 setlocale(LC_ALL, "");
393
394#ifdef ENABLE_NLS
395 const char *domdir = mutt_str_getenv("TEXTDOMAINDIR");
396 if (domdir)
397 bindtextdomain(PACKAGE, domdir);
398 else
399 bindtextdomain(PACKAGE, MUTTLOCALEDIR);
400 textdomain(PACKAGE);
401#endif
402#ifndef LOCALES_HACK
403 /* Do we have a locale definition? */
404 if (mutt_str_getenv("LC_ALL") || mutt_str_getenv("LANG") || mutt_str_getenv("LC_CTYPE"))
405 {
406 OptLocales = true;
407 }
408#endif
409}
bool OptLocales
(pseudo) set if user has valid locale definition
Definition: mbyte.c:44
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition: string.c:726
+ 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 418 of file main.c.

419{
420 const char *shell = mutt_str_getenv("SHELL");
421 if (shell)
422 cs_str_initial_set(cs, "shell", shell, NULL);
423
424 /* Get some information about the user */
425 struct passwd *pw = getpwuid(getuid());
426 if (pw)
427 {
428 if (!Username)
429 Username = mutt_str_dup(pw->pw_name);
430 if (!HomeDir)
431 HomeDir = mutt_str_dup(pw->pw_dir);
432 if (!shell)
433 cs_str_initial_set(cs, "shell", pw->pw_shell, NULL);
434 }
435
436 if (!Username)
437 {
438 mutt_error(_("unable to determine username"));
439 return false; // TEST05: neomutt (unset $USER, delete user from /etc/passwd)
440 }
441
442 if (!HomeDir)
443 {
444 mutt_error(_("unable to determine home directory"));
445 return false; // TEST06: neomutt (unset $HOME, delete user from /etc/passwd)
446 }
447
448 cs_str_reset(cs, "shell", NULL);
449 return true;
450}
char * HomeDir
User's home directory.
Definition: globals.c:37
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:503
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:438
char * Username
User's login name.
Definition: globals.c:40
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:253
+ 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 459 of file main.c.

460{
461 const char *header = ""; // Do not merge these two lines
462 header = _(header); // otherwise the .po files will end up badly ordered
463 const char *label = "Language:"; // the start of the lookup/needle
464 const char *lang = mutt_istr_find(header, label);
465 int len = 64;
466 if (lang)
467 {
468 lang += strlen(label); // skip label
469 SKIPWS(lang);
470 char *nl = strchr(lang, '\n');
471 if (nl)
472 len = (nl - lang);
473 }
474 else
475 {
476 lang = "NONE";
477 }
478
479 mutt_debug(LL_DEBUG1, "Translation: %.*s\n", len, lang);
480}
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case)
Definition: string.c:521
#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 485 of file main.c.

486{
487 const char *term = mutt_str_getenv("TERM");
488 const char *color_term = mutt_str_getenv("COLORTERM");
489 bool true_color = false;
490#ifdef NEOMUTT_DIRECT_COLORS
491 true_color = true;
492#endif
493
494 mutt_debug(LL_DEBUG1, "GUI:\n");
495 mutt_debug(LL_DEBUG1, " Curses: %s\n", curses_version());
496 mutt_debug(LL_DEBUG1, " COLORS=%d\n", COLORS);
497 mutt_debug(LL_DEBUG1, " COLOR_PAIRS=%d\n", COLOR_PAIRS);
498 mutt_debug(LL_DEBUG1, " TERM=%s\n", NONULL(term));
499 mutt_debug(LL_DEBUG1, " COLORTERM=%s\n", NONULL(color_term));
500 mutt_debug(LL_DEBUG1, " True color support: %s\n", true_color ? "YES" : "NO");
501 mutt_debug(LL_DEBUG1, " Screen: %dx%d\n", RootWindow->state.cols,
503}
struct MuttWindow * RootWindow
Parent of all Windows.
Definition: rootwin.c:106
#define NONULL(x)
Definition: string2.h:37
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:

◆ 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 549 of file main.c.

552{
553 char *subject = NULL;
554 char *include_file = NULL;
555 char *draft_file = NULL;
556 char *new_type = NULL;
557 char *dlevel = NULL;
558 char *dfile = NULL;
559 const char *cli_nntp = NULL;
560 struct Email *e = NULL;
561 struct ListHead attach = STAILQ_HEAD_INITIALIZER(attach);
562 struct ListHead commands = STAILQ_HEAD_INITIALIZER(commands);
563 struct ListHead queries = STAILQ_HEAD_INITIALIZER(queries);
564 struct ListHead alias_queries = STAILQ_HEAD_INITIALIZER(alias_queries);
565 struct ListHead cc_list = STAILQ_HEAD_INITIALIZER(cc_list);
566 struct ListHead bcc_list = STAILQ_HEAD_INITIALIZER(bcc_list);
567 SendFlags sendflags = SEND_NO_FLAGS;
569 int version = 0;
570 int i;
571 bool explicit_folder = false;
572 bool dump_variables = false;
573 bool one_liner = false;
574 bool hide_sensitive = false;
575 bool batch_mode = false;
576 bool edit_infile = false;
577 int double_dash = argc, nargc = 1;
578 int rc = 1;
579 bool repeat_error = false;
580 struct Buffer *folder = buf_pool_get();
581 struct Buffer *expanded_infile = buf_pool_get();
582 struct Buffer *tempfile = buf_pool_get();
583 struct ConfigSet *cs = NULL;
584
586
587 /* sanity check against stupid administrators */
588 if (getegid() != getgid())
589 {
590 mutt_error("%s: I don't want to run with privileges!", (argc != 0) ? argv[0] : "neomutt");
591 goto main_exit; // TEST01: neomutt (as root, chgrp mail neomutt; chmod +s neomutt)
592 }
593
594 init_locale();
595
596 EnvList = envlist_init(envp);
597 for (optind = 1; optind < double_dash;)
598 {
599 /* We're getopt'ing POSIXLY, so we'll be here every time getopt()
600 * encounters a non-option. That could be a file to attach
601 * (all non-options between -a and --) or it could be an address
602 * (which gets collapsed to the front of argv). */
603 for (; optind < argc; optind++)
604 {
605 if ((argv[optind][0] == '-') && (argv[optind][1] != '\0'))
606 {
607 if ((argv[optind][1] == '-') && (argv[optind][2] == '\0'))
608 double_dash = optind; /* quit outer loop after getopt */
609 break; /* drop through to getopt */
610 }
611
612 /* non-option, either an attachment or address */
613 if (!STAILQ_EMPTY(&attach))
614 mutt_list_insert_tail(&attach, mutt_str_dup(argv[optind]));
615 else
616 argv[nargc++] = argv[optind];
617 }
618
619 i = getopt(argc, argv, "+A:a:Bb:F:f:Cc:Dd:l:Ee:g:GH:i:hm:nOpQ:RSs:TvyzZ");
620 if (i != EOF)
621 {
622 switch (i)
623 {
624 case 'A':
625 mutt_list_insert_tail(&alias_queries, mutt_str_dup(optarg));
626 break;
627 case 'a':
628 mutt_list_insert_tail(&attach, mutt_str_dup(optarg));
629 break;
630 case 'B':
631 batch_mode = true;
632 break;
633 case 'b':
634 mutt_list_insert_tail(&bcc_list, mutt_str_dup(optarg));
635 break;
636 case 'C':
637 sendflags |= SEND_CLI_CRYPTO;
638 break;
639 case 'c':
640 mutt_list_insert_tail(&cc_list, mutt_str_dup(optarg));
641 break;
642 case 'D':
643 dump_variables = true;
644 break;
645 case 'd':
646 dlevel = optarg;
647 break;
648 case 'E':
649 edit_infile = true;
650 break;
651 case 'e':
652 mutt_list_insert_tail(&commands, mutt_str_dup(optarg));
653 break;
654 case 'F':
656 break;
657 case 'f':
658 buf_strcpy(folder, optarg);
659 explicit_folder = true;
660 break;
661 case 'g': /* Specify a news server */
662 cli_nntp = optarg;
664
665 case 'G': /* List of newsgroups */
667 break;
668 case 'H':
669 draft_file = optarg;
670 break;
671 case 'i':
672 include_file = optarg;
673 break;
674 case 'l':
675 dfile = optarg;
676 break;
677 case 'm':
678 new_type = optarg;
679 break;
680 case 'n':
681 flags |= MUTT_CLI_NOSYSRC;
682 break;
683 case 'O':
684 one_liner = true;
685 break;
686 case 'p':
687 sendflags |= SEND_POSTPONED;
688 break;
689 case 'Q':
690 mutt_list_insert_tail(&queries, mutt_str_dup(optarg));
691 break;
692 case 'R':
693 flags |= MUTT_CLI_RO; /* read-only mode */
694 break;
695 case 'S':
696 hide_sensitive = true;
697 break;
698 case 's':
699 subject = optarg;
700 break;
701 case 'v':
702 version++;
703 break;
704 case 'y': /* My special hack mode */
705 flags |= MUTT_CLI_SELECT;
706 break;
707 case 'Z':
709 break;
710 case 'z':
711 flags |= MUTT_CLI_IGNORE;
712 break;
713 default:
714 OptNoCurses = true;
715 if (usage())
716 goto main_ok; // TEST03: neomutt -9
717 else
718 goto main_curses;
719 }
720 }
721 }
722
723 /* collapse remaining argv */
724 while (optind < argc)
725 argv[nargc++] = argv[optind++];
726 optind = 1;
727 argc = nargc;
728
729 if (version > 0)
730 {
732 bool done;
733 if (version == 1)
734 done = print_version(stdout);
735 else
736 done = print_copyright();
737 OptNoCurses = true;
738 if (done)
739 goto main_ok; // TEST04: neomutt -v
740 else
741 goto main_curses;
742 }
743
746
747 cs = cs_new(500);
748 if (!cs)
749 goto main_curses;
750
751 NeoMutt = neomutt_new(cs);
752 init_config(cs);
753
754 // Change the current umask, and save the original one
755 NeoMutt->user_default_umask = umask(077);
756 subjrx_init();
757 attach_init();
759
760#ifdef USE_DEBUG_NOTIFY
762#endif
763
764 if (!get_user_info(cs))
765 goto main_exit;
766
767 reset_tilde(cs);
768#ifdef ENABLE_NLS
769 localise_config(cs);
770#endif
771
772 if (dfile)
773 {
774 cs_str_initial_set(cs, "debug_file", dfile, NULL);
775 cs_str_reset(cs, "debug_file", NULL);
776 }
777
778 if (dlevel)
779 {
780 short num = 0;
781 if (!mutt_str_atos_full(dlevel, &num) || (num < LL_MESSAGE) || (num >= LL_MAX))
782 {
783 mutt_error(_("Error: value '%s' is invalid for -d"), dlevel);
784 goto main_exit; // TEST07: neomutt -d xyz
785 }
786 cs_str_initial_set(cs, "debug_level", dlevel, NULL);
787 cs_str_reset(cs, "debug_level", NULL);
788 }
789
793 mutt_debug(LL_DEBUG1, "user's umask %03o\n", NeoMutt->user_default_umask);
794 mutt_debug(LL_DEBUG3, "umask set to 077\n");
795
796 if (!STAILQ_EMPTY(&cc_list) || !STAILQ_EMPTY(&bcc_list))
797 {
798 e = email_new();
799 e->env = mutt_env_new();
800
801 struct ListNode *np = NULL;
802 STAILQ_FOREACH(np, &bcc_list, entries)
803 {
804 mutt_addrlist_parse(&e->env->bcc, np->data);
805 }
806
807 STAILQ_FOREACH(np, &cc_list, entries)
808 {
809 mutt_addrlist_parse(&e->env->cc, np->data);
810 }
811
812 mutt_list_free(&bcc_list);
813 mutt_list_free(&cc_list);
814 }
815
816 /* Check for a batch send. */
817 if (!isatty(0) || !STAILQ_EMPTY(&queries) || !STAILQ_EMPTY(&alias_queries) ||
818 dump_variables || batch_mode)
819 {
820 OptNoCurses = true;
821 sendflags |= SEND_BATCH;
824 }
825
826 /* Check to make sure stdout is available in curses mode. */
827 if (!OptNoCurses && !isatty(1))
828 goto main_curses;
829
830 /* This must come before mutt_init() because curses needs to be started
831 * before calling the init_pair() function to set the color scheme. */
832 if (!OptNoCurses)
833 {
834 int crc = start_curses();
835 if (crc != 0)
836 goto main_curses; // TEST08: can't test -- fake term?
837 }
838
839 /* Always create the mutt_windows because batch mode has some shared code
840 * paths that end up referencing them. */
841 rootwin_new();
842
843 if (!OptNoCurses)
844 {
845 /* check whether terminal status is supported (must follow curses init) */
848 log_gui();
849 }
850
851 /* set defaults and read init files */
852 int rc2 = mutt_init(cs, dlevel, dfile, flags & MUTT_CLI_NOSYSRC, &commands);
853 if (rc2 != 0)
854 goto main_curses;
855
857
858 /* "$news_server" precedence: command line, config file, environment, system file */
859 if (!cli_nntp)
860 cli_nntp = cs_subset_string(NeoMutt->sub, "news_server");
861
862 if (!cli_nntp)
863 cli_nntp = mutt_str_getenv("NNTPSERVER");
864
865 if (!cli_nntp)
866 {
867 char buf[1024] = { 0 };
868 cli_nntp = mutt_file_read_keyword(SYSCONFDIR "/nntpserver", buf, sizeof(buf));
869 }
870
871 if (cli_nntp)
872 {
873 cs_str_initial_set(cs, "news_server", cli_nntp, NULL);
874 cs_str_reset(cs, "news_server", NULL);
875 }
876
877 /* Initialize crypto backends. */
878 crypt_init();
879
880 if (new_type)
881 {
882 struct Buffer *err = buf_pool_get();
883 int r = cs_str_initial_set(cs, "mbox_type", new_type, err);
884 if (CSR_RESULT(r) != CSR_SUCCESS)
885 {
886 mutt_error("%s", buf_string(err));
887 buf_pool_release(&err);
888 goto main_curses;
889 }
890 cs_str_reset(cs, "mbox_type", NULL);
891 }
892
893 if (!STAILQ_EMPTY(&queries))
894 {
895 rc = mutt_query_variables(&queries, one_liner);
896 goto main_curses;
897 }
898
899 if (dump_variables)
900 {
902 if (hide_sensitive)
903 cdflags |= CS_DUMP_HIDE_SENSITIVE;
904 if (one_liner)
905 cdflags |= CS_DUMP_SHOW_DOCS;
906 dump_config(cs, cdflags, stdout);
907 goto main_ok; // TEST18: neomutt -D
908 }
909
910 if (!STAILQ_EMPTY(&alias_queries))
911 {
912 rc = 0;
913 for (; optind < argc; optind++)
914 mutt_list_insert_tail(&alias_queries, mutt_str_dup(argv[optind]));
915 struct ListNode *np = NULL;
916 STAILQ_FOREACH(np, &alias_queries, entries)
917 {
918 struct AddressList *al = alias_lookup(np->data);
919 if (al)
920 {
921 /* output in machine-readable form */
922 mutt_addrlist_to_intl(al, NULL);
923 struct Buffer *buf = buf_pool_get();
924 mutt_addrlist_write(al, buf, false);
925 printf("%s\n", buf_string(buf));
926 buf_pool_release(&buf);
927 }
928 else
929 {
930 rc = 1;
931 printf("%s\n", NONULL(np->data)); // TEST19: neomutt -A unknown
932 }
933 }
934 mutt_list_free(&alias_queries);
935 goto main_curses; // TEST20: neomutt -A alias
936 }
937
938 if (!OptNoCurses)
939 {
941 clear();
945 }
946
947#ifdef USE_AUTOCRYPT
948 /* Initialize autocrypt after curses messages are working,
949 * because of the initial account setup screens. */
950 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
951 if (c_autocrypt)
952 mutt_autocrypt_init(!(sendflags & SEND_BATCH));
953#endif
954
955 /* Create the `$folder` directory if it doesn't exist. */
956 const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
957 if (!OptNoCurses && c_folder)
958 {
959 struct stat st = { 0 };
960 struct Buffer *fpath = buf_pool_get();
961
962 buf_strcpy(fpath, c_folder);
963 buf_expand_path(fpath);
964 bool skip = false;
965 /* we're not connected yet - skip mail folder creation */
966 skip |= (imap_path_probe(buf_string(fpath), NULL) == MUTT_IMAP);
967 skip |= (pop_path_probe(buf_string(fpath), NULL) == MUTT_POP);
968 skip |= (nntp_path_probe(buf_string(fpath), NULL) == MUTT_NNTP);
969 if (!skip && (stat(buf_string(fpath), &st) == -1) && (errno == ENOENT))
970 {
971 char msg2[256] = { 0 };
972 snprintf(msg2, sizeof(msg2), _("%s does not exist. Create it?"), c_folder);
973 if (query_yesorno(msg2, MUTT_YES) == MUTT_YES)
974 {
975 if ((mkdir(buf_string(fpath), 0700) == -1) && (errno != EEXIST))
976 mutt_error(_("Can't create %s: %s"), c_folder, strerror(errno)); // TEST21: neomutt -n -F /dev/null (and ~/Mail doesn't exist)
977 }
978 }
979 buf_pool_release(&fpath);
980 }
981
982 if (batch_mode)
983 {
984 goto main_ok; // TEST22: neomutt -B
985 }
986 StartupComplete = true;
987
992
993 if (sendflags & SEND_POSTPONED)
994 {
995 if (!OptNoCurses)
997 if (mutt_send_message(SEND_POSTPONED, NULL, NULL, NULL, NULL, NeoMutt->sub) == 0)
998 rc = 0;
999 // TEST23: neomutt -p (postponed message, cancel)
1000 // TEST24: neomutt -p (no postponed message)
1002 repeat_error = true;
1003 goto main_curses;
1004 }
1005 else if (subject || e || draft_file || include_file ||
1006 !STAILQ_EMPTY(&attach) || (optind < argc))
1007 {
1008 FILE *fp_in = NULL;
1009 FILE *fp_out = NULL;
1010 char *infile = NULL;
1011 char *bodytext = NULL;
1012 const char *bodyfile = NULL;
1013 int rv = 0;
1014
1015 if (!OptNoCurses)
1016 mutt_flushinp();
1017
1018 if (!e)
1019 e = email_new();
1020 if (!e->env)
1021 e->env = mutt_env_new();
1022
1023 for (i = optind; i < argc; i++)
1024 {
1025 if (url_check_scheme(argv[i]) == U_MAILTO)
1026 {
1027 if (!mutt_parse_mailto(e->env, &bodytext, argv[i]))
1028 {
1029 mutt_error(_("Failed to parse mailto: link"));
1030 email_free(&e);
1031 goto main_curses; // TEST25: neomutt mailto:?
1032 }
1033 }
1034 else
1035 {
1036 mutt_addrlist_parse(&e->env->to, argv[i]);
1037 }
1038 }
1039
1040 const bool c_auto_edit = cs_subset_bool(NeoMutt->sub, "auto_edit");
1041 if (!draft_file && c_auto_edit && TAILQ_EMPTY(&e->env->to) &&
1042 TAILQ_EMPTY(&e->env->cc))
1043 {
1044 mutt_error(_("No recipients specified"));
1045 email_free(&e);
1046 goto main_curses; // TEST26: neomutt -s test (with auto_edit=yes)
1047 }
1048
1049 if (subject)
1050 {
1051 /* prevent header injection */
1053 mutt_env_set_subject(e->env, subject);
1054 }
1055
1056 if (draft_file)
1057 {
1058 infile = draft_file;
1059 include_file = NULL;
1060 }
1061 else if (include_file)
1062 {
1063 infile = include_file;
1064 }
1065 else
1066 {
1067 edit_infile = false;
1068 }
1069
1070 if (infile || bodytext)
1071 {
1072 /* Prepare fp_in and expanded_infile. */
1073 if (infile)
1074 {
1075 if (mutt_str_equal("-", infile))
1076 {
1077 if (edit_infile)
1078 {
1079 mutt_error(_("Can't use -E flag with stdin"));
1080 email_free(&e);
1081 goto main_curses; // TEST27: neomutt -E -H -
1082 }
1083 fp_in = stdin;
1084 }
1085 else
1086 {
1087 buf_strcpy(expanded_infile, infile);
1088 buf_expand_path(expanded_infile);
1089 fp_in = mutt_file_fopen(buf_string(expanded_infile), "r");
1090 if (!fp_in)
1091 {
1092 mutt_perror("%s", buf_string(expanded_infile));
1093 email_free(&e);
1094 goto main_curses; // TEST28: neomutt -E -H missing
1095 }
1096 }
1097 }
1098
1099 if (edit_infile)
1100 {
1101 /* If editing the infile, keep it around afterwards so
1102 * it doesn't get unlinked, and we can rebuild the draft_file */
1103 sendflags |= SEND_NO_FREE_HEADER;
1104 }
1105 else
1106 {
1107 /* Copy input to a tempfile, and re-point fp_in to the tempfile.
1108 * Note: stdin is always copied to a tempfile, ensuring draft_file
1109 * can stat and get the correct st_size below. */
1110 buf_mktemp(tempfile);
1111
1112 fp_out = mutt_file_fopen(buf_string(tempfile), "w");
1113 if (!fp_out)
1114 {
1115 mutt_file_fclose(&fp_in);
1116 mutt_perror("%s", buf_string(tempfile));
1117 email_free(&e);
1118 goto main_curses; // TEST29: neomutt -H existing-file (where tmpdir=/path/to/FILE blocking tmpdir)
1119 }
1120 if (fp_in)
1121 {
1122 mutt_file_copy_stream(fp_in, fp_out);
1123 if (fp_in == stdin)
1124 sendflags |= SEND_CONSUMED_STDIN;
1125 else
1126 mutt_file_fclose(&fp_in);
1127 }
1128 else if (bodytext)
1129 {
1130 fputs(bodytext, fp_out);
1131 }
1132 mutt_file_fclose(&fp_out);
1133
1134 fp_in = mutt_file_fopen(buf_string(tempfile), "r");
1135 if (!fp_in)
1136 {
1137 mutt_perror("%s", buf_string(tempfile));
1138 email_free(&e);
1139 goto main_curses; // TEST30: can't test
1140 }
1141 }
1142
1143 /* Parse the draft_file into the full Email/Body structure.
1144 * Set SEND_DRAFT_FILE so mutt_send_message doesn't overwrite
1145 * our e->body. */
1146 if (draft_file)
1147 {
1148 struct Envelope *opts_env = e->env;
1149 struct stat st = { 0 };
1150
1151 sendflags |= SEND_DRAFT_FILE;
1152
1153 /* Set up a tmp Email with just enough information so that
1154 * mutt_prepare_template() can parse the message in fp_in. */
1155 struct Email *e_tmp = email_new();
1156 e_tmp->offset = 0;
1157 e_tmp->body = mutt_body_new();
1158 if (fstat(fileno(fp_in), &st) != 0)
1159 {
1160 mutt_perror("%s", draft_file);
1161 email_free(&e);
1162 email_free(&e_tmp);
1163 goto main_curses; // TEST31: can't test
1164 }
1165 e_tmp->body->length = st.st_size;
1166
1167 if (mutt_prepare_template(fp_in, NULL, e, e_tmp, false) < 0)
1168 {
1169 mutt_error(_("Can't parse message template: %s"), draft_file);
1170 email_free(&e);
1171 email_free(&e_tmp);
1172 goto main_curses;
1173 }
1174
1175 /* Scan for neomutt header to set `$resume_draft_files` */
1176 struct ListNode *np = NULL, *tmp = NULL;
1177 const bool c_resume_edited_draft_files = cs_subset_bool(NeoMutt->sub, "resume_edited_draft_files");
1178 STAILQ_FOREACH_SAFE(np, &e->env->userhdrs, entries, tmp)
1179 {
1180 if (mutt_istr_startswith(np->data, "X-Mutt-Resume-Draft:"))
1181 {
1182 if (c_resume_edited_draft_files)
1183 cs_str_native_set(cs, "resume_draft_files", true, NULL);
1184
1185 STAILQ_REMOVE(&e->env->userhdrs, np, ListNode, entries);
1186 FREE(&np->data);
1187 FREE(&np);
1188 }
1189 }
1190
1191 mutt_addrlist_copy(&e->env->to, &opts_env->to, false);
1192 mutt_addrlist_copy(&e->env->cc, &opts_env->cc, false);
1193 mutt_addrlist_copy(&e->env->bcc, &opts_env->bcc, false);
1194 if (opts_env->subject)
1195 mutt_env_set_subject(e->env, opts_env->subject);
1196
1197 mutt_env_free(&opts_env);
1198 email_free(&e_tmp);
1199 }
1200 /* Editing the include_file: pass it directly in.
1201 * Note that SEND_NO_FREE_HEADER is set above so it isn't unlinked. */
1202 else if (edit_infile)
1203 bodyfile = buf_string(expanded_infile);
1204 // For bodytext and unedited include_file: use the tempfile.
1205 else
1206 bodyfile = buf_string(tempfile);
1207
1208 mutt_file_fclose(&fp_in);
1209 }
1210
1211 FREE(&bodytext);
1212
1213 if (!STAILQ_EMPTY(&attach))
1214 {
1215 struct Body *b = e->body;
1216
1217 while (b && b->next)
1218 b = b->next;
1219
1220 struct ListNode *np = NULL;
1221 STAILQ_FOREACH(np, &attach, entries)
1222 {
1223 if (b)
1224 {
1226 b = b->next;
1227 }
1228 else
1229 {
1231 e->body = b;
1232 }
1233 if (!b)
1234 {
1235 mutt_error(_("%s: unable to attach file"), np->data);
1236 mutt_list_free(&attach);
1237 email_free(&e);
1238 goto main_curses; // TEST32: neomutt john@example.com -a missing
1239 }
1240 }
1241 mutt_list_free(&attach);
1242 }
1243
1244 rv = mutt_send_message(sendflags, e, bodyfile, NULL, NULL, NeoMutt->sub);
1245 /* We WANT the "Mail sent." and any possible, later error */
1247 if (ErrorBufMessage)
1248 mutt_message("%s", ErrorBuf);
1249
1250 if (edit_infile)
1251 {
1252 if (draft_file)
1253 {
1254 if (truncate(buf_string(expanded_infile), 0) == -1)
1255 {
1256 mutt_perror("%s", buf_string(expanded_infile));
1257 email_free(&e);
1258 goto main_curses; // TEST33: neomutt -H read-only -s test john@example.com -E
1259 }
1260 fp_out = mutt_file_fopen(buf_string(expanded_infile), "a");
1261 if (!fp_out)
1262 {
1263 mutt_perror("%s", buf_string(expanded_infile));
1264 email_free(&e);
1265 goto main_curses; // TEST34: can't test
1266 }
1267
1268 /* If the message was sent or postponed, these will already
1269 * have been done. */
1270 if (rv < 0)
1271 {
1272 if (e->body->next)
1273 e->body = mutt_make_multipart(e->body);
1275 mutt_prepare_envelope(e->env, false, NeoMutt->sub);
1276 mutt_env_to_intl(e->env, NULL, NULL);
1277 }
1278
1279 const bool c_crypt_protected_headers_read = cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_read");
1281 c_crypt_protected_headers_read &&
1283 NeoMutt->sub);
1284 const bool c_resume_edited_draft_files = cs_subset_bool(NeoMutt->sub, "resume_edited_draft_files");
1285 if (c_resume_edited_draft_files)
1286 fprintf(fp_out, "X-Mutt-Resume-Draft: 1\n");
1287 fputc('\n', fp_out);
1288 if ((mutt_write_mime_body(e->body, fp_out, NeoMutt->sub) == -1))
1289 {
1290 mutt_file_fclose(&fp_out);
1291 email_free(&e);
1292 goto main_curses; // TEST35: can't test
1293 }
1294 mutt_file_fclose(&fp_out);
1295 }
1296
1297 email_free(&e);
1298 }
1299
1300 /* !edit_infile && draft_file will leave the tempfile around */
1301 if (!buf_is_empty(tempfile))
1302 unlink(buf_string(tempfile));
1303
1305
1306 if (rv != 0)
1307 goto main_curses; // TEST36: neomutt -H existing -s test john@example.com -E (cancel sending)
1308 }
1309 else if (sendflags & SEND_BATCH)
1310 {
1311 /* This guards against invoking `neomutt < /dev/null` and accidentally
1312 * sending an email due to a my_hdr or other setting. */
1313 mutt_error(_("No recipients specified"));
1314 goto main_curses;
1315 }
1316 else
1317 {
1318 if (flags & MUTT_CLI_MAILBOX)
1319 {
1320 const bool c_imap_passive = cs_subset_bool(NeoMutt->sub, "imap_passive");
1321 cs_subset_str_native_set(NeoMutt->sub, "imap_passive", false, NULL);
1323 if (mutt_mailbox_check(NULL, csflags) == 0)
1324 {
1325 mutt_message(_("No mailbox with new mail"));
1326 repeat_error = true;
1327 goto main_curses; // TEST37: neomutt -Z (no new mail)
1328 }
1329 buf_reset(folder);
1330 mutt_mailbox_next(NULL, folder);
1331 cs_subset_str_native_set(NeoMutt->sub, "imap_passive", c_imap_passive, NULL);
1332 }
1333 else if (flags & MUTT_CLI_SELECT)
1334 {
1335 if (flags & MUTT_CLI_NEWS)
1336 {
1337 const char *const c_news_server = cs_subset_string(NeoMutt->sub, "news_server");
1338 OptNews = true;
1339 CurrentNewsSrv = nntp_select_server(NULL, c_news_server, false);
1340 if (!CurrentNewsSrv)
1341 goto main_curses; // TEST38: neomutt -G (unset news_server)
1342 }
1343 else if (TAILQ_EMPTY(&NeoMutt->accounts))
1344 {
1345 mutt_error(_("No incoming mailboxes defined"));
1346 goto main_curses; // TEST39: neomutt -n -F /dev/null -y
1347 }
1348 buf_reset(folder);
1349 dlg_browser(folder, MUTT_SEL_FOLDER | MUTT_SEL_MAILBOX, NULL, NULL, NULL);
1350 if (buf_is_empty(folder))
1351 {
1352 goto main_ok; // TEST40: neomutt -y (quit selection)
1353 }
1354 }
1355
1356 if (buf_is_empty(folder))
1357 {
1358 const char *const c_spool_file = cs_subset_string(NeoMutt->sub, "spool_file");
1359 if (c_spool_file)
1360 {
1361 // Check if `$spool_file` corresponds a mailboxes' description.
1362 struct Mailbox *m_desc = mailbox_find_name(c_spool_file);
1363 if (m_desc)
1364 buf_strcpy(folder, m_desc->realpath);
1365 else
1366 buf_strcpy(folder, c_spool_file);
1367 }
1368 else if (c_folder)
1369 {
1370 buf_strcpy(folder, c_folder);
1371 }
1372 /* else no folder */
1373 }
1374
1375 if (OptNews)
1376 {
1377 OptNews = false;
1378 buf_alloc(folder, PATH_MAX);
1379 nntp_expand_path(folder->data, folder->dsize, &CurrentNewsSrv->conn->account);
1380 }
1381 else
1382 {
1383 buf_expand_path(folder);
1384 }
1385
1388
1389 if (flags & MUTT_CLI_IGNORE)
1390 {
1391 /* check to see if there are any messages in the folder */
1392 switch (mx_path_is_empty(folder))
1393 {
1394 case -1:
1395 mutt_perror("%s", buf_string(folder));
1396 goto main_curses; // TEST41: neomutt -z -f missing
1397 case 1:
1398 mutt_error(_("Mailbox is empty"));
1399 goto main_curses; // TEST42: neomutt -z -f /dev/null
1400 }
1401 }
1402
1403 struct Mailbox *m_cur = mailbox_find(buf_string(folder));
1404 // Take a copy of the name just in case the hook alters m_cur
1405 const char *name = m_cur ? mutt_str_dup(m_cur->name) : NULL;
1407 FREE(&name);
1409 mutt_debug(LL_NOTIFY, "NT_GLOBAL_STARTUP\n");
1411
1413 window_redraw(NULL);
1414
1415 repeat_error = true;
1416 struct Mailbox *m = mx_resolve(buf_string(folder));
1417 const bool c_read_only = cs_subset_bool(NeoMutt->sub, "read_only");
1418 if (!mx_mbox_open(m, ((flags & MUTT_CLI_RO) || c_read_only) ? MUTT_READONLY : MUTT_OPEN_NO_FLAGS))
1419 {
1420 if (m->account)
1422
1423 mailbox_free(&m);
1424 mutt_error(_("Unable to open mailbox %s"), buf_string(folder));
1425 repeat_error = false;
1426 }
1427 if (m || !explicit_folder)
1428 {
1429 struct MuttWindow *dlg = index_pager_init();
1430 dialog_push(dlg);
1431
1433 m = dlg_index(dlg, m);
1435 mailbox_free(&m);
1436
1437 dialog_pop();
1438 mutt_window_free(&dlg);
1440 repeat_error = false;
1441 }
1443#ifdef USE_SASL_CYRUS
1445#endif
1446#ifdef USE_SASL_GNU
1448#endif
1449#ifdef USE_AUTOCRYPT
1451#endif
1452 // TEST43: neomutt (no change to mailbox)
1453 // TEST44: neomutt (change mailbox)
1454 }
1455
1456main_ok:
1457 rc = 0;
1458main_curses:
1459 mutt_endwin();
1461 /* Repeat the last message to the user */
1462 if (repeat_error && ErrorBufMessage)
1463 puts(ErrorBuf);
1464main_exit:
1465 if (NeoMutt && NeoMutt->sub)
1466 {
1471 }
1472 mutt_list_free(&commands);
1474 buf_pool_release(&folder);
1475 buf_pool_release(&expanded_infile);
1476 buf_pool_release(&tempfile);
1477 mutt_list_free(&queries);
1484 menu_cleanup();
1485 crypt_cleanup();
1495 cs_free(&cs);
1497 mutt_log_stop();
1498 return rc;
1499}
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
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_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:480
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
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
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
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
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:55
bool dump_config(struct ConfigSet *cs, ConfigDumpFlags flags, FILE *fp)
Write all the config to a file.
Definition: dump.c:167
#define CS_DUMP_HIDE_SENSITIVE
Obscure sensitive information like passwords.
Definition: dump.h:37
uint16_t ConfigDumpFlags
Flags for dump_config(), e.g. CS_DUMP_ONLY_CHANGED.
Definition: dump.h:34
#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
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:291
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:760
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
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 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
@ 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_flushinp(void)
Empty all the keyboard buffers.
Definition: get.c:58
int debug_all_observer(struct NotifyCallback *nc)
Definition: notify.c:205
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:1436
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
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:287
char * mutt_file_read_keyword(const char *file, char *buf, size_t buflen)
Read a keyword from a file.
Definition: file.c:1406
#define mutt_file_fclose(FP)
Definition: file.h:138
#define mutt_file_fopen(PATH, MODE)
Definition: file.h:137
bool OptNews
(pseudo) used to change reader mode
Definition: globals.c:67
char * LastFolder
Previously selected mailbox.
Definition: globals.c:43
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: globals.c:69
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:42
struct ListHead Muttrc
List of config files to read.
Definition: globals.c:51
char ** EnvList
Private copy of the environment variables.
Definition: globals.c:75
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:1099
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:398
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:441
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:91
#define mutt_perror(...)
Definition: logging2.h:93
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:2344
int main_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition: init.c:259
int main_hist_observer(struct NotifyCallback *nc)
Notification that a Config Variable has change - Implements observer_t -.
Definition: history.c:713
int main_timeout_observer(struct NotifyCallback *nc)
Notification that a timeout has occurred - Implements observer_t -.
Definition: main.c:508
int main_log_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition: mutt_logging.c:285
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_startup_shutdown_hook(HookFlags type)
Execute any startup/shutdown hooks.
Definition: hook.c:963
void mutt_folder_hook(const char *path, const char *desc)
Perform a folder hook.
Definition: hook.c:630
#define MUTT_STARTUP_HOOK
startup-hook: run when starting NeoMutt
Definition: hook.h:54
void imap_logout_all(void)
Close all open connections.
Definition: imap.c:553
int mutt_query_variables(struct ListHead *queries, bool show_docs)
Implement the -Q command line flag.
Definition: init.c:621
int mutt_init(struct ConfigSet *cs, const char *dlevel, const char *dfile, bool skip_sys_rc, struct ListHead *commands)
Initialise NeoMutt.
Definition: init.c:318
void mutt_opts_cleanup(void)
Clean up before quitting.
Definition: init.c:262
void init_config(struct ConfigSet *cs)
Initialise the config system.
Definition: mutt_config.c:932
void mutt_keys_cleanup(void)
Free the key maps.
Definition: init.c:224
void mutt_init_abort_key(void)
Parse the abort_key config string.
Definition: init.c:237
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:65
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:45
@ LL_MESSAGE
Log informational message.
Definition: logging2.h:42
@ LL_NOTIFY
Log of notifications.
Definition: logging2.h:48
@ LL_MAX
Definition: logging2.h:50
#define MUTT_CLI_SELECT
-y Start with a list of all mailboxes
Definition: main.c:198
static void init_locale(void)
Initialise the Locale/NLS settings.
Definition: main.c:390
static void localise_config(struct ConfigSet *cs)
Localise some config.
Definition: main.c:230
uint8_t CliFlags
Flags for command line options, e.g. MUTT_CLI_IGNORE.
Definition: main.c:192
static void log_translation(void)
Log the translation being used.
Definition: main.c:459
#define MUTT_CLI_MAILBOX
-Z Open first mailbox if is has new mail
Definition: main.c:195
static void log_gui(void)
Log info about the GUI.
Definition: main.c:485
static void reset_tilde(struct ConfigSet *cs)
Temporary measure.
Definition: main.c:206
static bool usage(void)
Display NeoMutt command line.
Definition: main.c:280
static int start_curses(void)
Start the Curses UI.
Definition: main.c:358
bool StartupComplete
When the config has been read.
Definition: main.c:189
static bool get_user_info(struct ConfigSet *cs)
Find the user's name, home and shell.
Definition: main.c:418
#define MUTT_CLI_RO
-R Open mailbox in read-only mode
Definition: main.c:197
#define MUTT_CLI_NO_FLAGS
No flags are set.
Definition: main.c:193
#define MUTT_CLI_IGNORE
-z Open first mailbox if it has mail
Definition: main.c:194
#define MUTT_CLI_NEWS
-g/-G Start with a list of all newsgroups
Definition: main.c:199
#define MUTT_CLI_NOSYSRC
-n Do not read the system-wide config file
Definition: main.c:196
#define FREE(x)
Definition: memory.h:55
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
#define FALLTHROUGH
Definition: lib.h:111
void log_queue_empty(void)
Free the contents of the queue.
Definition: logging.c:324
void log_queue_set_max_size(int size)
Set a upper limit for the queue length.
Definition: logging.c:312
void log_queue_flush(log_dispatcher_t disp)
Replay the log queue.
Definition: logging.c:346
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
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:660
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:242
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:280
#define PATH_MAX
Definition: mutt.h:42
void mutt_temp_attachments_cleanup(void)
Delete all temporary attachments.
Definition: mutt_attach.c:1310
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
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:634
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
Definition: mutt_window.c:202
void buf_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:315
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:1705
int mx_path_is_empty(struct Buffer *path)
Is the mailbox empty.
Definition: mx.c:1252
#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:56
#define MUTT_OPEN_NO_FLAGS
No flags are set.
Definition: mxapi.h:40
uint8_t CheckStatsFlags
Flags for mutt_mailbox_check.
Definition: mxapi.h:52
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:61
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 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:483
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:402
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_EMPTY(head)
Definition: queue.h:348
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
#define TAILQ_EMPTY(head)
Definition: queue.h:739
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:1488
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:2033
#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_CLI_CRYPTO
Enable message security in modes that by default don't enable it.
Definition: send.h:58
#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
The body of an email.
Definition: body.h:36
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
Container for lots of config items.
Definition: set.h:252
struct Notify * notify
Notifications: NotifyConfig, EventConfig.
Definition: subset.h:52
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
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
Container for Accounts, Notifications.
Definition: neomutt.h:42
struct Notify * notify_resize
Window resize notifications handler.
Definition: neomutt.h:44
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:47
mode_t user_default_umask
User's default file writing permissions (inferred from umask)
Definition: neomutt.h:49
struct Notify * notify
Notifications handler.
Definition: neomutt.h:43
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:46
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:297
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
bool print_copyright(void)
Print copyright message.
Definition: version.c:517
bool print_version(FILE *fp)
Print system and compile info to a file.
Definition: version.c:388

Variable Documentation

◆ StartupComplete

bool StartupComplete = false

When the config has been read.

Definition at line 189 of file main.c.