NeoMutt  2024-04-25-76-g20fe7b
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 "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 132 of file main.c.

◆ MUTT_CLI_NO_FLAGS

#define MUTT_CLI_NO_FLAGS   0

No flags are set.

Definition at line 196 of file main.c.

◆ MUTT_CLI_IGNORE

#define MUTT_CLI_IGNORE   (1 << 0)

-z Open first mailbox if it has mail

Definition at line 197 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 198 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 199 of file main.c.

◆ MUTT_CLI_RO

#define MUTT_CLI_RO   (1 << 3)

-R Open mailbox in read-only mode

Definition at line 200 of file main.c.

◆ MUTT_CLI_SELECT

#define MUTT_CLI_SELECT   (1 << 4)

-y Start with a list of all mailboxes

Definition at line 201 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 202 of file main.c.

Typedef Documentation

◆ CliFlags

typedef uint8_t CliFlags

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

Definition at line 195 of file main.c.

Function Documentation

◆ reset_tilde()

static void reset_tilde ( struct ConfigSet cs)
static

Temporary measure.

Parameters
csConfig Set

Definition at line 209 of file main.c.

210{
211 static const char *names[] = { "folder", "mbox", "postponed", "record" };
212
213 struct Buffer *value = buf_pool_get();
214 for (size_t i = 0; i < mutt_array_size(names); i++)
215 {
216 struct HashElem *he = cs_get_elem(cs, names[i]);
217 if (!he)
218 continue;
219 buf_reset(value);
220 cs_he_initial_get(cs, he, value);
221 buf_expand_path_regex(value, false);
222 cs_he_initial_set(cs, he, value->data, NULL);
223 cs_he_reset(cs, he, NULL);
224 }
225 buf_pool_release(&value);
226}
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:135
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
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 233 of file main.c.

234{
235 static const char *names[] = {
236 "attribution_intro",
237 "compose_format",
238 "forward_attribution_intro",
239 "forward_attribution_trailer",
240 "reply_regex",
241 "status_format",
242 "ts_icon_format",
243 "ts_status_format",
244 };
245
246 struct Buffer *value = buf_pool_get();
247 for (size_t i = 0; i < mutt_array_size(names); i++)
248 {
249 struct HashElem *he = cs_get_elem(cs, names[i]);
250 if (!he)
251 continue;
252 buf_reset(value);
253 cs_he_initial_get(cs, he, value);
254
255 // Lookup the translation
256 const char *l10n = gettext(buf_string(value));
257
258 cs_he_initial_set(cs, he, l10n, NULL);
259 cs_he_reset(cs, he, NULL);
260 }
261 buf_pool_release(&value);
262}
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 269 of file main.c.

270{
271 mutt_endwin();
272#ifdef USE_DEBUG_BACKTRACE
273 if (code != 0)
275#endif
276 exit(code);
277}
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 283 of file main.c.

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

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

394{
395 setlocale(LC_ALL, "");
396
397#ifdef ENABLE_NLS
398 const char *domdir = mutt_str_getenv("TEXTDOMAINDIR");
399 if (domdir)
400 bindtextdomain(PACKAGE, domdir);
401 else
402 bindtextdomain(PACKAGE, MUTTLOCALEDIR);
403 textdomain(PACKAGE);
404#endif
405#ifndef LOCALES_HACK
406 /* Do we have a locale definition? */
407 if (mutt_str_getenv("LC_ALL") || mutt_str_getenv("LANG") || mutt_str_getenv("LC_CTYPE"))
408 {
409 OptLocales = true;
410 }
411#endif
412}
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 421 of file main.c.

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

463{
464 const char *header = ""; // Do not merge these two lines
465 header = _(header); // otherwise the .po files will end up badly ordered
466 const char *label = "Language:"; // the start of the lookup/needle
467 const char *lang = mutt_istr_find(header, label);
468 int len = 64;
469 if (lang)
470 {
471 lang += strlen(label); // skip label
472 SKIPWS(lang);
473 char *nl = strchr(lang, '\n');
474 if (nl)
475 len = (nl - lang);
476 }
477 else
478 {
479 lang = "NONE";
480 }
481
482 mutt_debug(LL_DEBUG1, "Translation: %.*s\n", len, lang);
483}
#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 488 of file main.c.

489{
490 const char *term = mutt_str_getenv("TERM");
491 const char *color_term = mutt_str_getenv("COLORTERM");
492 bool true_color = false;
493#ifdef NEOMUTT_DIRECT_COLORS
494 true_color = true;
495#endif
496
497 mutt_debug(LL_DEBUG1, "GUI:\n");
498 mutt_debug(LL_DEBUG1, " Curses: %s\n", curses_version());
499 mutt_debug(LL_DEBUG1, " COLORS=%d\n", COLORS);
500 mutt_debug(LL_DEBUG1, " COLOR_PAIRS=%d\n", COLOR_PAIRS);
501 mutt_debug(LL_DEBUG1, " TERM=%s\n", NONULL(term));
502 mutt_debug(LL_DEBUG1, " COLORTERM=%s\n", NONULL(color_term));
503 mutt_debug(LL_DEBUG1, " True color support: %s\n", true_color ? "YES" : "NO");
504 mutt_debug(LL_DEBUG1, " Screen: %dx%d\n", RootWindow->state.cols,
506}
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:60
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:61
+ 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 552 of file main.c.

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

Variable Documentation

◆ StartupComplete

bool StartupComplete = false

When the config has been read.

Definition at line 192 of file main.c.