NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
main.c
Go to the documentation of this file.
1 
33 #define MAIN_C 1
34 #define GNULIB_defined_setlocale
35 
36 #include "config.h"
37 #include <errno.h>
38 #include <getopt.h>
39 #include <limits.h>
40 #include <locale.h>
41 #include <pwd.h>
42 #include <stdbool.h>
43 #include <stdint.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <sys/stat.h>
48 #include <unistd.h>
49 #include "mutt/lib.h"
50 #include "address/lib.h"
51 #include "config/lib.h"
52 #include "email/lib.h"
53 #include "core/lib.h"
54 #include "alias/lib.h"
55 #include "conn/lib.h"
56 #include "gui/lib.h"
57 #include "debug/lib.h"
58 #include "index/lib.h"
59 #include "ncrypt/lib.h"
60 #include "send/lib.h"
61 #include "browser.h"
62 #include "commands.h"
63 #include "context.h"
64 #include "hook.h"
65 #include "init.h"
66 #include "keymap.h"
67 #include "mutt_attach.h"
68 #include "mutt_globals.h"
69 #include "mutt_history.h"
70 #include "mutt_logging.h"
71 #include "mutt_mailbox.h"
72 #include "mutt_menu.h"
73 #include "muttlib.h"
74 #include "mx.h"
75 #include "myvar.h"
76 #include "options.h"
77 #include "protos.h"
78 #include "version.h"
79 #ifdef ENABLE_NLS
80 #include <libintl.h>
81 #endif
82 #ifdef USE_IMAP
83 #include "imap/lib.h"
84 #endif
85 #ifdef USE_POP
86 #include "pop/lib.h"
87 #endif
88 #ifdef USE_NNTP
89 #include "nntp/lib.h"
90 #include "nntp/adata.h"
91 #include "nntp/mdata.h"
92 #endif
93 #ifdef USE_AUTOCRYPT
94 #include "autocrypt/lib.h"
95 #endif
96 
97 /* These Config Variables are only used in main.c */
99 
100 // clang-format off
101 typedef uint8_t CliFlags;
102 #define MUTT_CLI_NO_FLAGS 0
103 #define MUTT_CLI_IGNORE (1 << 0)
104 #define MUTT_CLI_MAILBOX (1 << 1)
105 #define MUTT_CLI_NOSYSRC (1 << 2)
106 #define MUTT_CLI_RO (1 << 3)
107 #define MUTT_CLI_SELECT (1 << 4)
108 #ifdef USE_NNTP
109 #define MUTT_CLI_NEWS (1 << 5)
110 #endif
111 // clang-format on
112 
117 static void reset_tilde(struct ConfigSet *cs)
118 {
119  static const char *names[] = { "folder", "mbox", "postponed", "record" };
120 
121  struct Buffer value = mutt_buffer_make(256);
122  for (size_t i = 0; i < mutt_array_size(names); i++)
123  {
124  struct HashElem *he = cs_get_elem(cs, names[i]);
125  if (!he)
126  continue;
127  mutt_buffer_reset(&value);
128  cs_he_initial_get(cs, he, &value);
129  mutt_buffer_expand_path_regex(&value, false);
130  cs_he_initial_set(cs, he, value.data, NULL);
131  cs_he_reset(cs, he, NULL);
132  }
133  mutt_buffer_dealloc(&value);
134 }
135 
140 void mutt_exit(int code)
141 {
142  mutt_endwin();
143 #ifdef HAVE_LIBUNWIND
144  if (code != 0)
145  show_backtrace();
146 #endif
147  exit(code);
148 }
149 
150 // clang-format off
154 static void usage(void)
155 {
156  puts(mutt_make_version());
157 
158  /* L10N: Try to limit to 80 columns */
159  puts(_("usage:"));
160  puts(_(" neomutt [-Enx] [-e <command>] [-F <config>] [-H <draft>] [-i <include>]\n"
161  " [-b <address>] [-c <address>] [-s <subject>] [-a <file> [...] --]\n"
162  " <address> [...]"));
163  puts(_(" neomutt [-nx] [-e <command>] [-F <config>] [-b <address>] [-c <address>]\n"
164  " [-s <subject>] [-a <file> [...] --] <address> [...] < message"));
165  puts(_(" neomutt [-nRy] [-e <command>] [-F <config>] [-f <mailbox>] [-m <type>]"));
166  puts(_(" neomutt [-n] [-e <command>] [-F <config>] -A <alias>"));
167  puts(_(" neomutt [-n] [-e <command>] [-F <config>] -B"));
168  puts(_(" neomutt [-n] [-e <command>] [-F <config>] -D [-S] [-O]"));
169  puts(_(" neomutt [-n] [-e <command>] [-F <config>] -d <level> -l <file>"));
170  puts(_(" neomutt [-n] [-e <command>] [-F <config>] -G"));
171  puts(_(" neomutt [-n] [-e <command>] [-F <config>] -g <server>"));
172  puts(_(" neomutt [-n] [-e <command>] [-F <config>] -p"));
173  puts(_(" neomutt [-n] [-e <command>] [-F <config>] -Q <variable> [-O]"));
174  puts(_(" neomutt [-n] [-e <command>] [-F <config>] -Z"));
175  puts(_(" neomutt [-n] [-e <command>] [-F <config>] -z [-f <mailbox>]"));
176  puts(_(" neomutt -v[v]\n"));
177 
178  /* L10N: Try to limit to 80 columns. If more space is needed add an indented line */
179  puts(_("options:"));
180  puts(_(" -- Special argument forces NeoMutt to stop option parsing and treat\n"
181  " remaining arguments as addresses even if they start with a dash"));
182  puts(_(" -A <alias> Print an expanded version of the given alias to stdout and exit"));
183  puts(_(" -a <file> Attach one or more files to a message (must be the last option)\n"
184  " Add any addresses after the '--' argument"));
185  puts(_(" -B Run in batch mode (do not start the ncurses UI)"));
186  puts(_(" -b <address> Specify a blind carbon copy (Bcc) recipient"));
187  puts(_(" -c <address> Specify a carbon copy (Cc) recipient"));
188  puts(_(" -D Dump all config variables as 'name=value' pairs to stdout"));
189  puts(_(" -D -O Like -D, but show one-liner documentation"));
190  puts(_(" -D -S Like -D, but hide the value of sensitive variables"));
191  puts(_(" -d <level> Log debugging output to a file (default is \"~/.neomuttdebug0\")\n"
192  " The level can range from 1-5 and affects verbosity"));
193  puts(_(" -E Edit draft (-H) or include (-i) file during message composition"));
194  puts(_(" -e <command> Specify a command to be run after reading the config files"));
195  puts(_(" -F <config> Specify an alternative initialization file to read"));
196  puts(_(" -f <mailbox> Specify a mailbox (as defined with 'mailboxes' command) to load"));
197  puts(_(" -G Start NeoMutt with a listing of subscribed newsgroups"));
198  puts(_(" -g <server> Like -G, but start at specified news server"));
199  puts(_(" -H <draft> Specify a draft file with header and body for message composing"));
200  puts(_(" -h Print this help message and exit"));
201  puts(_(" -i <include> Specify an include file to be embedded in the body of a message"));
202  puts(_(" -l <file> Specify a file for debugging output (default \"~/.neomuttdebug0\")"));
203  puts(_(" -m <type> Specify a default mailbox format type for newly created folders\n"
204  " The type is either MH, MMDF, Maildir or mbox (case-insensitive)"));
205  puts(_(" -n Do not read the system-wide configuration file"));
206  puts(_(" -p Resume a prior postponed message, if any"));
207  puts(_(" -Q <variable> Query a configuration variable and print its value to stdout\n"
208  " (after the config has been read and any commands executed)\n"
209  " Add -O for one-liner documentation"));
210  puts(_(" -R Open mailbox in read-only mode"));
211  puts(_(" -s <subject> Specify a subject (must be enclosed in quotes if it has spaces)"));
212  puts(_(" -v Print the NeoMutt version and compile-time definitions and exit"));
213  puts(_(" -vv Print the NeoMutt license and copyright information and exit"));
214  puts(_(" -y Start NeoMutt with a listing of all defined mailboxes"));
215  puts(_(" -Z Open the first mailbox with new message or exit immediately with\n"
216  " exit code 1 if none is found in all defined mailboxes"));
217  puts(_(" -z Open the first or specified (-f) mailbox if it holds any message\n"
218  " or exit immediately with exit code 1 otherwise"));
219 }
220 // clang-format on
221 
227 static int start_curses(void)
228 {
229  km_init(); /* must come before mutt_init */
230 
231 #ifdef USE_SLANG_CURSES
232  SLtt_Ignore_Beep = 1; /* don't do that #*$@^! annoying visual beep! */
233  SLsmg_Display_Eight_Bit = 128; /* characters above this are printable */
234  SLtt_set_color(0, NULL, "default", "default");
235 #if (SLANG_VERSION >= 20000)
236  SLutf8_enable(-1);
237 #endif
238 #else
239  /* should come before initscr() so that ncurses 4.2 doesn't try to install
240  * its own SIGWINCH handler */
242 #endif
243  if (!initscr())
244  {
245  mutt_error(_("Error initializing terminal"));
246  return 1;
247  }
248  /* slang requires the signal handlers to be set after initializing */
251  keypad(stdscr, true);
252  cbreak();
253  noecho();
254  nonl();
255 #ifdef HAVE_TYPEAHEAD
256  typeahead(-1); /* simulate smooth scrolling */
257 #endif
258 #ifdef HAVE_META
259  meta(stdscr, true);
260 #endif
262  /* Now that curses is set up, we drop back to normal screen mode.
263  * This simplifies displaying error messages to the user.
264  * The first call to refresh() will swap us back to curses screen mode. */
265  endwin();
266  return 0;
267 }
268 
272 static void init_locale(void)
273 {
274  setlocale(LC_ALL, "");
275 
276 #ifdef ENABLE_NLS
277  const char *domdir = mutt_str_getenv("TEXTDOMAINDIR");
278  if (domdir)
279  bindtextdomain(PACKAGE, domdir);
280  else
281  bindtextdomain(PACKAGE, MUTTLOCALEDIR);
282  textdomain(PACKAGE);
283 #endif
284 #ifndef LOCALES_HACK
285  /* Do we have a locale definition? */
286  if (mutt_str_getenv("LC_ALL") || mutt_str_getenv("LANG") || mutt_str_getenv("LC_CTYPE"))
287  {
288  OptLocales = true;
289  }
290 #endif
291 }
292 
300 static bool get_user_info(struct ConfigSet *cs)
301 {
302  const char *shell = mutt_str_getenv("SHELL");
303  if (shell)
304  cs_str_initial_set(cs, "shell", shell, NULL);
305 
306  /* Get some information about the user */
307  struct passwd *pw = getpwuid(getuid());
308  if (pw)
309  {
310  if (!Username)
311  Username = mutt_str_dup(pw->pw_name);
312  if (!HomeDir)
313  HomeDir = mutt_str_dup(pw->pw_dir);
314  if (!shell)
315  cs_str_initial_set(cs, "shell", pw->pw_shell, NULL);
316  }
317 
318  if (!Username)
319  {
320  mutt_error(_("unable to determine username"));
321  return false; // TEST05: neomutt (unset $USER, delete user from /etc/passwd)
322  }
323 
324  if (!HomeDir)
325  {
326  mutt_error(_("unable to determine home directory"));
327  return false; // TEST06: neomutt (unset $HOME, delete user from /etc/passwd)
328  }
329 
330  cs_str_reset(cs, "shell", NULL);
331  return true;
332 }
333 
341 static void log_translation(void)
342 {
343  const char *header = ""; // Do not merge these two lines
344  header = _(header); // otherwise the .po files will end up badly ordered
345  const char *lang = strcasestr(header, "Language:");
346  int len = 64;
347  if (lang)
348  {
349  lang += 9; // skip label
350  SKIPWS(lang);
351  char *nl = strchr(lang, '\n');
352  if (nl)
353  len = (nl - lang);
354  }
355  else
356  {
357  lang = "NONE";
358  }
359 
360  mutt_debug(LL_DEBUG1, "Translation: %.*s\n", len, lang);
361 }
362 
371 int main(int argc, char *argv[], char *envp[])
372 {
373  char *subject = NULL;
374  char *include_file = NULL;
375  char *draft_file = NULL;
376  char *new_type = NULL;
377  char *dlevel = NULL;
378  char *dfile = NULL;
379 #ifdef USE_NNTP
380  char *cli_nntp = NULL;
381 #endif
382  struct Email *e = NULL;
383  struct ListHead attach = STAILQ_HEAD_INITIALIZER(attach);
384  struct ListHead commands = STAILQ_HEAD_INITIALIZER(commands);
385  struct ListHead queries = STAILQ_HEAD_INITIALIZER(queries);
386  struct ListHead alias_queries = STAILQ_HEAD_INITIALIZER(alias_queries);
387  struct ListHead cc_list = STAILQ_HEAD_INITIALIZER(cc_list);
388  struct ListHead bcc_list = STAILQ_HEAD_INITIALIZER(bcc_list);
389  SendFlags sendflags = SEND_NO_FLAGS;
390  CliFlags flags = MUTT_CLI_NO_FLAGS;
391  int version = 0;
392  int i;
393  bool explicit_folder = false;
394  bool dump_variables = false;
395  bool one_liner = false;
396  bool hide_sensitive = false;
397  bool batch_mode = false;
398  bool edit_infile = false;
399 #ifdef USE_DEBUG_PARSE_TEST
400  bool test_config = false;
401 #endif
402  int double_dash = argc, nargc = 1;
403  int rc = 1;
404  bool repeat_error = false;
405  struct Buffer folder = mutt_buffer_make(0);
406  struct Buffer expanded_infile = mutt_buffer_make(0);
407  struct Buffer tempfile = mutt_buffer_make(0);
408  struct ConfigSet *cs = NULL;
409 
411 
412  /* sanity check against stupid administrators */
413  if (getegid() != getgid())
414  {
415  mutt_error("%s: I don't want to run with privileges!", argv[0]);
416  goto main_exit; // TEST01: neomutt (as root, chgrp mail neomutt; chmod +s neomutt)
417  }
418 
419  init_locale();
420 
421  umask(077);
422 
423  mutt_envlist_init(envp);
424  for (optind = 1; optind < double_dash;)
425  {
426  /* We're getopt'ing POSIXLY, so we'll be here every time getopt()
427  * encounters a non-option. That could be a file to attach
428  * (all non-options between -a and --) or it could be an address
429  * (which gets collapsed to the front of argv). */
430  for (; optind < argc; optind++)
431  {
432  if ((argv[optind][0] == '-') && (argv[optind][1] != '\0'))
433  {
434  if ((argv[optind][1] == '-') && (argv[optind][2] == '\0'))
435  double_dash = optind; /* quit outer loop after getopt */
436  break; /* drop through to getopt */
437  }
438 
439  /* non-option, either an attachment or address */
440  if (!STAILQ_EMPTY(&attach))
441  mutt_list_insert_tail(&attach, mutt_str_dup(argv[optind]));
442  else
443  argv[nargc++] = argv[optind];
444  }
445 
446  /* USE_NNTP 'g:G' */
447  i = getopt(argc, argv, "+A:a:Bb:F:f:c:Dd:l:Ee:g:GH:i:hm:nOpQ:RSs:TvxyzZ");
448  if (i != EOF)
449  {
450  switch (i)
451  {
452  case 'A':
453  mutt_list_insert_tail(&alias_queries, mutt_str_dup(optarg));
454  break;
455  case 'a':
456  mutt_list_insert_tail(&attach, mutt_str_dup(optarg));
457  break;
458  case 'B':
459  batch_mode = true;
460  break;
461  case 'b':
462  mutt_list_insert_tail(&bcc_list, mutt_str_dup(optarg));
463  break;
464  case 'c':
465  mutt_list_insert_tail(&cc_list, mutt_str_dup(optarg));
466  break;
467  case 'D':
468  dump_variables = true;
469  break;
470  case 'd':
471  dlevel = optarg;
472  break;
473  case 'E':
474  edit_infile = true;
475  break;
476  case 'e':
477  mutt_list_insert_tail(&commands, mutt_str_dup(optarg));
478  break;
479  case 'F':
480  mutt_list_insert_tail(&Muttrc, mutt_str_dup(optarg));
481  break;
482  case 'f':
483  mutt_buffer_strcpy(&folder, optarg);
484  explicit_folder = true;
485  break;
486 #ifdef USE_NNTP
487  case 'g': /* Specify a news server */
488  cli_nntp = optarg;
489  /* fallthrough */
490  case 'G': /* List of newsgroups */
491  flags |= MUTT_CLI_SELECT | MUTT_CLI_NEWS;
492  break;
493 #endif
494  case 'H':
495  draft_file = optarg;
496  break;
497  case 'i':
498  include_file = optarg;
499  break;
500  case 'l':
501  dfile = optarg;
502  break;
503  case 'm':
504  new_type = optarg;
505  break;
506  case 'n':
507  flags |= MUTT_CLI_NOSYSRC;
508  break;
509  case 'O':
510  one_liner = true;
511  break;
512  case 'p':
513  sendflags |= SEND_POSTPONED;
514  break;
515  case 'Q':
516  mutt_list_insert_tail(&queries, mutt_str_dup(optarg));
517  break;
518  case 'R':
519  flags |= MUTT_CLI_RO; /* read-only mode */
520  break;
521  case 'S':
522  hide_sensitive = true;
523  break;
524  case 's':
525  subject = optarg;
526  break;
527 #ifdef USE_DEBUG_PARSE_TEST
528  case 'T':
529  test_config = true;
530  break;
531 #endif
532  case 'v':
533  version++;
534  break;
535  case 'y': /* My special hack mode */
536  flags |= MUTT_CLI_SELECT;
537  break;
538  case 'Z':
540  break;
541  case 'z':
542  flags |= MUTT_CLI_IGNORE;
543  break;
544  default:
545  usage();
546  OptNoCurses = true;
547  goto main_ok; // TEST03: neomutt -9
548  }
549  }
550  }
551 
552  /* collapse remaining argv */
553  while (optind < argc)
554  argv[nargc++] = argv[optind++];
555  optind = 1;
556  argc = nargc;
557 
558  if (version > 0)
559  {
561  if (version == 1)
562  print_version(stdout);
563  else
564  print_copyright();
565  OptNoCurses = true;
566  goto main_ok; // TEST04: neomutt -v
567  }
568 
571 
572  cs = init_config(500);
573  if (!cs)
574  goto main_curses;
575  NeoMutt = neomutt_new(cs);
576 
577 #ifdef USE_DEBUG_NOTIFY
579 #endif
580 
581  if (!get_user_info(cs))
582  goto main_exit;
583 
584 #ifdef USE_DEBUG_PARSE_TEST
585  if (test_config)
586  {
587  cs_str_initial_set(cs, "from", "rich@flatcap.org", NULL);
588  cs_str_reset(cs, "from", NULL);
589  myvar_set("my_var", "foo");
590  test_parse_set();
591  goto main_ok;
592  }
593 #endif
594 
595  reset_tilde(cs);
596 
597  if (dfile)
598  {
599  cs_str_initial_set(cs, "debug_file", dfile, NULL);
600  cs_str_reset(cs, "debug_file", NULL);
601  }
602 
603  if (dlevel)
604  {
605  short num = 0;
606  if ((mutt_str_atos(dlevel, &num) < 0) || (num < LL_MESSAGE) || (num >= LL_MAX))
607  {
608  mutt_error(_("Error: value '%s' is invalid for -d"), dlevel);
609  goto main_exit; // TEST07: neomutt -d xyz
610  }
611  cs_str_initial_set(cs, "debug_level", dlevel, NULL);
612  cs_str_reset(cs, "debug_level", NULL);
613  }
614 
615  mutt_log_prep();
616  if (dlevel)
617  mutt_log_start();
618 
620 
621  log_translation();
622 
623  if (!STAILQ_EMPTY(&cc_list) || !STAILQ_EMPTY(&bcc_list))
624  {
625  e = email_new();
626  e->env = mutt_env_new();
627 
628  struct ListNode *np = NULL;
629  STAILQ_FOREACH(np, &bcc_list, entries)
630  {
631  mutt_addrlist_parse(&e->env->bcc, np->data);
632  }
633 
634  STAILQ_FOREACH(np, &cc_list, entries)
635  {
636  mutt_addrlist_parse(&e->env->cc, np->data);
637  }
638 
639  mutt_list_free(&bcc_list);
640  mutt_list_free(&cc_list);
641  }
642 
643  /* Check for a batch send. */
644  if (!isatty(0) || !STAILQ_EMPTY(&queries) || !STAILQ_EMPTY(&alias_queries) ||
645  dump_variables || batch_mode)
646  {
647  OptNoCurses = true;
648  sendflags = SEND_BATCH;
651  }
652 
653  /* Always create the mutt_windows because batch mode has some shared code
654  * paths that end up referencing them. */
656 
657  /* This must come before mutt_init() because curses needs to be started
658  * before calling the init_pair() function to set the color scheme. */
659  if (!OptNoCurses)
660  {
661  int crc = start_curses();
662  if (crc != 0)
663  goto main_curses; // TEST08: can't test -- fake term?
664 
665  /* check whether terminal status is supported (must follow curses init) */
667  mutt_window_set_root(COLS, LINES);
668  }
669 
670  /* set defaults and read init files */
671  int rc2 = mutt_init(cs, flags & MUTT_CLI_NOSYSRC, &commands);
672  mutt_list_free(&commands);
673  if (rc2 != 0)
674  goto main_curses;
675 
677 
678  /* The command line overrides the config */
679  if (dlevel)
680  cs_str_reset(cs, "debug_level", NULL);
681  if (dfile)
682  cs_str_reset(cs, "debug_file", NULL);
683 
684  if (mutt_log_start() < 0)
685  {
686  mutt_perror("log file");
687  goto main_exit;
688  }
689 
690 #ifdef USE_NNTP
691  /* "$news_server" precedence: command line, config file, environment, system file */
692  if (cli_nntp)
693  cs_str_string_set(cs, "news_server", cli_nntp, NULL);
694  if (!C_NewsServer)
695  {
696  const char *env_nntp = mutt_str_getenv("NNTPSERVER");
697  cs_str_string_set(cs, "news_server", env_nntp, NULL);
698  }
699  if (!C_NewsServer)
700  {
701  char buf[1024];
702  char *server = mutt_file_read_keyword(SYSCONFDIR "/nntpserver", buf, sizeof(buf));
703  cs_str_string_set(cs, "news_server", server, NULL);
704  }
705  if (C_NewsServer)
706  cs_str_initial_set(cs, "news_server", C_NewsServer, NULL);
707 #endif
708 
709  /* Initialize crypto backends. */
710  crypt_init();
711 
712  if (new_type)
713  {
714  struct Buffer err = mutt_buffer_make(0);
715  int r = cs_str_initial_set(cs, "mbox_type", new_type, &err);
716  if (CSR_RESULT(r) != CSR_SUCCESS)
717  {
718  mutt_error(err.data);
719  mutt_buffer_dealloc(&err);
720  goto main_curses;
721  }
722  cs_str_reset(cs, "mbox_type", NULL);
723  }
724 
725  if (!STAILQ_EMPTY(&queries))
726  {
727  rc = mutt_query_variables(&queries, one_liner);
728  goto main_curses;
729  }
730 
731  if (dump_variables)
732  {
734  if (hide_sensitive)
735  cdflags |= CS_DUMP_HIDE_SENSITIVE;
736  if (one_liner)
737  cdflags |= CS_DUMP_SHOW_DOCS;
738  dump_config(cs, cdflags, stdout);
739  goto main_ok; // TEST18: neomutt -D
740  }
741 
742  if (!STAILQ_EMPTY(&alias_queries))
743  {
744  rc = 0;
745  for (; optind < argc; optind++)
746  mutt_list_insert_tail(&alias_queries, mutt_str_dup(argv[optind]));
747  struct ListNode *np = NULL;
748  STAILQ_FOREACH(np, &alias_queries, entries)
749  {
750  struct AddressList *al = alias_lookup(np->data);
751  if (al)
752  {
753  /* output in machine-readable form */
754  mutt_addrlist_to_intl(al, NULL);
755  mutt_addrlist_write_file(al, stdout, 0, false);
756  }
757  else
758  {
759  rc = 1;
760  printf("%s\n", np->data); // TEST19: neomutt -A unknown
761  }
762  }
763  mutt_list_free(&alias_queries);
764  goto main_curses; // TEST20: neomutt -A alias
765  }
766 
767  if (!OptNoCurses)
768  {
770  clear();
774  }
775 
776 #ifdef USE_AUTOCRYPT
777  /* Initialize autocrypt after curses messages are working,
778  * because of the initial account setup screens. */
779  if (C_Autocrypt)
780  mutt_autocrypt_init(NULL, !(sendflags & SEND_BATCH));
781 #endif
782 
783  /* Create the `$folder` directory if it doesn't exist. */
784  if (!OptNoCurses && C_Folder)
785  {
786  struct stat sb;
787  struct Buffer *fpath = mutt_buffer_pool_get();
788 
791  bool skip = false;
792 #ifdef USE_IMAP
793  /* we're not connected yet - skip mail folder creation */
794  skip |= (imap_path_probe(mutt_buffer_string(fpath), NULL) == MUTT_IMAP);
795 #endif
796 #ifdef USE_POP
797  skip |= (pop_path_probe(mutt_buffer_string(fpath), NULL) == MUTT_POP);
798 #endif
799 #ifdef USE_NNTP
800  skip |= (nntp_path_probe(mutt_buffer_string(fpath), NULL) == MUTT_NNTP);
801 #endif
802  if (!skip && (stat(mutt_buffer_string(fpath), &sb) == -1) && (errno == ENOENT))
803  {
804  char msg2[256];
805  snprintf(msg2, sizeof(msg2), _("%s does not exist. Create it?"), C_Folder);
806  if (mutt_yesorno(msg2, MUTT_YES) == MUTT_YES)
807  {
808  if ((mkdir(mutt_buffer_string(fpath), 0700) == -1) && (errno != EEXIST))
809  mutt_error(_("Can't create %s: %s"), C_Folder, strerror(errno)); // TEST21: neomutt -n -F /dev/null (and ~/Mail doesn't exist)
810  }
811  }
812  mutt_buffer_pool_release(&fpath);
813  }
814 
815  if (batch_mode)
816  {
817  goto main_ok; // TEST22: neomutt -B
818  }
819 
824  if (Colors)
826 
827  if (sendflags & SEND_POSTPONED)
828  {
829  if (!OptNoCurses)
830  mutt_flushinp();
831  if (mutt_send_message(SEND_POSTPONED, NULL, NULL, NULL, NULL, NeoMutt->sub) == 0)
832  rc = 0;
833  // TEST23: neomutt -p (postponed message, cancel)
834  // TEST24: neomutt -p (no postponed message)
835  log_queue_empty();
836  repeat_error = true;
837  goto main_curses;
838  }
839  else if (subject || e || sendflags || draft_file || include_file ||
840  !STAILQ_EMPTY(&attach) || (optind < argc))
841  {
842  FILE *fp_in = NULL;
843  FILE *fp_out = NULL;
844  char *infile = NULL;
845  char *bodytext = NULL;
846  const char *bodyfile = NULL;
847  int rv = 0;
848 
849  if (!OptNoCurses)
850  mutt_flushinp();
851 
852  if (!e)
853  e = email_new();
854  if (!e->env)
855  e->env = mutt_env_new();
856 
857  for (i = optind; i < argc; i++)
858  {
859  if (url_check_scheme(argv[i]) == U_MAILTO)
860  {
861  if (!mutt_parse_mailto(e->env, &bodytext, argv[i]))
862  {
863  mutt_error(_("Failed to parse mailto: link"));
864  email_free(&e);
865  goto main_curses; // TEST25: neomutt mailto:?
866  }
867  }
868  else
869  mutt_addrlist_parse(&e->env->to, argv[i]);
870  }
871 
872  if (!draft_file && C_AutoEdit && TAILQ_EMPTY(&e->env->to) &&
873  TAILQ_EMPTY(&e->env->cc))
874  {
875  mutt_error(_("No recipients specified"));
876  email_free(&e);
877  goto main_curses; // TEST26: neomutt -s test (with auto_edit=yes)
878  }
879 
880  if (subject)
881  e->env->subject = mutt_str_dup(subject);
882 
883  if (draft_file)
884  {
885  infile = draft_file;
886  include_file = NULL;
887  }
888  else if (include_file)
889  infile = include_file;
890  else
891  edit_infile = false;
892 
893  if (infile || bodytext)
894  {
895  /* Prepare fp_in and expanded_infile. */
896  if (infile)
897  {
898  if (mutt_str_equal("-", infile))
899  {
900  if (edit_infile)
901  {
902  mutt_error(_("Can't use -E flag with stdin"));
903  email_free(&e);
904  goto main_curses; // TEST27: neomutt -E -H -
905  }
906  fp_in = stdin;
907  }
908  else
909  {
910  mutt_buffer_strcpy(&expanded_infile, infile);
911  mutt_buffer_expand_path(&expanded_infile);
912  fp_in = fopen(mutt_buffer_string(&expanded_infile), "r");
913  if (!fp_in)
914  {
915  mutt_perror(mutt_buffer_string(&expanded_infile));
916  email_free(&e);
917  goto main_curses; // TEST28: neomutt -E -H missing
918  }
919  }
920  }
921 
922  /* Copy input to a tempfile, and re-point fp_in to the tempfile.
923  * Note: stdin is always copied to a tempfile, ensuring draft_file
924  * can stat and get the correct st_size below. */
925  if (!edit_infile)
926  {
927  mutt_buffer_mktemp(&tempfile);
928 
929  fp_out = mutt_file_fopen(mutt_buffer_string(&tempfile), "w");
930  if (!fp_out)
931  {
932  mutt_file_fclose(&fp_in);
933  mutt_perror(mutt_buffer_string(&tempfile));
934  email_free(&e);
935  goto main_curses; // TEST29: neomutt -H existing-file (where tmpdir=/path/to/FILE blocking tmpdir)
936  }
937  if (fp_in)
938  {
939  mutt_file_copy_stream(fp_in, fp_out);
940  if (fp_in != stdin)
941  mutt_file_fclose(&fp_in);
942  }
943  else if (bodytext)
944  fputs(bodytext, fp_out);
945  mutt_file_fclose(&fp_out);
946 
947  fp_in = fopen(mutt_buffer_string(&tempfile), "r");
948  if (!fp_in)
949  {
950  mutt_perror(mutt_buffer_string(&tempfile));
951  email_free(&e);
952  goto main_curses; // TEST30: can't test
953  }
954  }
955  /* If editing the infile, keep it around afterwards so
956  * it doesn't get unlinked, and we can rebuild the draft_file */
957  else
958  sendflags |= SEND_NO_FREE_HEADER;
959 
960  /* Parse the draft_file into the full Email/Body structure.
961  * Set SEND_DRAFT_FILE so mutt_send_message doesn't overwrite
962  * our e->body. */
963  if (draft_file)
964  {
965  struct Envelope *opts_env = e->env;
966  struct stat st;
967 
968  sendflags |= SEND_DRAFT_FILE;
969 
970  /* Set up a tmp Email with just enough information so that
971  * mutt_prepare_template() can parse the message in fp_in. */
972  struct Email *e_tmp = email_new();
973  e_tmp->offset = 0;
974  e_tmp->body = mutt_body_new();
975  if (fstat(fileno(fp_in), &st) != 0)
976  {
977  mutt_perror(draft_file);
978  email_free(&e);
979  email_free(&e_tmp);
980  goto main_curses; // TEST31: can't test
981  }
982  e_tmp->body->length = st.st_size;
983 
984  if (mutt_prepare_template(fp_in, NULL, e, e_tmp, false) < 0)
985  {
986  mutt_error(_("Can't parse message template: %s"), draft_file);
987  email_free(&e);
988  email_free(&e_tmp);
989  goto main_curses;
990  }
991 
992  /* Scan for neomutt header to set `$resume_draft_files` */
993  struct ListNode *np = NULL, *tmp = NULL;
994  STAILQ_FOREACH_SAFE(np, &e->env->userhdrs, entries, tmp)
995  {
996  if (mutt_istr_startswith(np->data, "X-Mutt-Resume-Draft:"))
997  {
999  cs_str_native_set(cs, "resume_draft_files", true, NULL);
1000 
1001  STAILQ_REMOVE(&e->env->userhdrs, np, ListNode, entries);
1002  FREE(&np->data);
1003  FREE(&np);
1004  }
1005  }
1006 
1007  mutt_addrlist_copy(&e->env->to, &opts_env->to, false);
1008  mutt_addrlist_copy(&e->env->cc, &opts_env->cc, false);
1009  mutt_addrlist_copy(&e->env->bcc, &opts_env->bcc, false);
1010  if (opts_env->subject)
1011  mutt_str_replace(&e->env->subject, opts_env->subject);
1012 
1013  mutt_env_free(&opts_env);
1014  email_free(&e_tmp);
1015  }
1016  /* Editing the include_file: pass it directly in.
1017  * Note that SEND_NO_FREE_HEADER is set above so it isn't unlinked. */
1018  else if (edit_infile)
1019  bodyfile = mutt_buffer_string(&expanded_infile);
1020  // For bodytext and unedited include_file: use the tempfile.
1021  else
1022  bodyfile = mutt_buffer_string(&tempfile);
1023 
1024  mutt_file_fclose(&fp_in);
1025  }
1026 
1027  FREE(&bodytext);
1028 
1029  if (!STAILQ_EMPTY(&attach))
1030  {
1031  struct Body *b = e->body;
1032 
1033  while (b && b->next)
1034  b = b->next;
1035 
1036  struct ListNode *np = NULL;
1037  STAILQ_FOREACH(np, &attach, entries)
1038  {
1039  if (b)
1040  {
1042  b = b->next;
1043  }
1044  else
1045  {
1047  e->body = b;
1048  }
1049  if (!b)
1050  {
1051  mutt_error(_("%s: unable to attach file"), np->data);
1052  mutt_list_free(&attach);
1053  email_free(&e);
1054  goto main_curses; // TEST32: neomutt john@example.com -a missing
1055  }
1056  }
1057  mutt_list_free(&attach);
1058  }
1059 
1060  rv = mutt_send_message(sendflags, e, bodyfile, NULL, NULL, NeoMutt->sub);
1061  /* We WANT the "Mail sent." and any possible, later error */
1062  log_queue_empty();
1063  if (ErrorBufMessage)
1064  mutt_message("%s", ErrorBuf);
1065 
1066  if (edit_infile)
1067  {
1068  if (include_file)
1069  e->body->unlink = false;
1070  else if (draft_file)
1071  {
1072  if (truncate(mutt_buffer_string(&expanded_infile), 0) == -1)
1073  {
1074  mutt_perror(mutt_buffer_string(&expanded_infile));
1075  email_free(&e);
1076  goto main_curses; // TEST33: neomutt -H read-only -s test john@example.com -E
1077  }
1078  fp_out = mutt_file_fopen(mutt_buffer_string(&expanded_infile), "a");
1079  if (!fp_out)
1080  {
1081  mutt_perror(mutt_buffer_string(&expanded_infile));
1082  email_free(&e);
1083  goto main_curses; // TEST34: can't test
1084  }
1085 
1086  /* If the message was sent or postponed, these will already
1087  * have been done. */
1088  if (rv < 0)
1089  {
1090  if (e->body->next)
1091  e->body = mutt_make_multipart(e->body);
1093  mutt_prepare_envelope(e->env, false, NeoMutt->sub);
1094  mutt_env_to_intl(e->env, NULL, NULL);
1095  }
1096 
1098  fp_out, e->env, e->body, MUTT_WRITE_HEADER_POSTPONE, false,
1100  NeoMutt->sub);
1102  fprintf(fp_out, "X-Mutt-Resume-Draft: 1\n");
1103  fputc('\n', fp_out);
1104  if ((mutt_write_mime_body(e->body, fp_out, NeoMutt->sub) == -1))
1105  {
1106  mutt_file_fclose(&fp_out);
1107  email_free(&e);
1108  goto main_curses; // TEST35: can't test
1109  }
1110  mutt_file_fclose(&fp_out);
1111  }
1112 
1113  email_free(&e);
1114  }
1115 
1116  /* !edit_infile && draft_file will leave the tempfile around */
1117  if (!mutt_buffer_is_empty(&tempfile))
1118  unlink(mutt_buffer_string(&tempfile));
1119 
1121 
1122  if (rv != 0)
1123  goto main_curses; // TEST36: neomutt -H existing -s test john@example.com -E (cancel sending)
1124  }
1125  else
1126  {
1127  if (flags & MUTT_CLI_MAILBOX)
1128  {
1129  struct Mailbox *m = ctx_mailbox(Context);
1130 #ifdef USE_IMAP
1131  bool passive = C_ImapPassive;
1132  C_ImapPassive = false;
1133 #endif
1134  if (mutt_mailbox_check(m, 0) == 0)
1135  {
1136  mutt_message(_("No mailbox with new mail"));
1137  goto main_curses; // TEST37: neomutt -Z (no new mail)
1138  }
1139  mutt_buffer_reset(&folder);
1140  mutt_mailbox_next(m, &folder);
1141 #ifdef USE_IMAP
1142  C_ImapPassive = passive;
1143 #endif
1144  }
1145  else if (flags & MUTT_CLI_SELECT)
1146  {
1147 #ifdef USE_NNTP
1148  if (flags & MUTT_CLI_NEWS)
1149  {
1150  OptNews = true;
1151  CurrentNewsSrv =
1153  if (!CurrentNewsSrv)
1154  goto main_curses; // TEST38: neomutt -G (unset news_server)
1155  }
1156  else
1157 #endif
1158  if (TAILQ_EMPTY(&NeoMutt->accounts))
1159  {
1160  mutt_error(_("No incoming mailboxes defined"));
1161  goto main_curses; // TEST39: neomutt -n -F /dev/null -y
1162  }
1163  mutt_buffer_reset(&folder);
1165  ctx_mailbox(Context), NULL, NULL);
1166  if (mutt_buffer_is_empty(&folder))
1167  {
1168  goto main_ok; // TEST40: neomutt -y (quit selection)
1169  }
1170  }
1171 
1172  if (mutt_buffer_is_empty(&folder))
1173  {
1174  if (C_SpoolFile)
1175  {
1176  // Check if `$spool_file` corresponds a mailboxes' description.
1177  struct Mailbox *m_desc = mailbox_find_name(C_SpoolFile);
1178  if (m_desc)
1179  mutt_buffer_strcpy(&folder, m_desc->realpath);
1180  else
1181  mutt_buffer_strcpy(&folder, C_SpoolFile);
1182  }
1183  else if (C_Folder)
1184  mutt_buffer_strcpy(&folder, C_Folder);
1185  /* else no folder */
1186  }
1187 
1188 #ifdef USE_NNTP
1189  if (OptNews)
1190  {
1191  OptNews = false;
1192  mutt_buffer_alloc(&folder, PATH_MAX);
1193  nntp_expand_path(folder.data, folder.dsize, &CurrentNewsSrv->conn->account);
1194  }
1195  else
1196 #endif
1197  mutt_buffer_expand_path(&folder);
1198 
1201 
1202  if (flags & MUTT_CLI_IGNORE)
1203  {
1204  /* check to see if there are any messages in the folder */
1205  switch (mx_path_is_empty(mutt_buffer_string(&folder)))
1206  {
1207  case -1:
1208  mutt_perror(mutt_buffer_string(&folder));
1209  goto main_curses; // TEST41: neomutt -z -f missing
1210  case 1:
1211  mutt_error(_("Mailbox is empty"));
1212  goto main_curses; // TEST42: neomutt -z -f /dev/null
1213  }
1214  }
1215 
1216  mutt_folder_hook(mutt_buffer_string(&folder), NULL);
1219 
1220  repeat_error = true;
1221  struct Mailbox *m = mx_resolve(mutt_buffer_string(&folder));
1223  if (!Context)
1224  {
1225  if (m->account)
1227 
1228  mailbox_free(&m);
1229  mutt_error(_("Unable to open mailbox %s"), mutt_buffer_string(&folder));
1230  repeat_error = false;
1231  }
1232  if (Context || !explicit_folder)
1233  {
1234  struct MuttWindow *dlg = index_pager_init();
1235  dialog_push(dlg);
1236 
1237  struct EventMailbox em = { Context ? Context->mailbox : NULL };
1239 
1240  mutt_index_menu(dlg);
1241  dialog_pop();
1242  index_pager_shutdown(dlg);
1243  mutt_window_free(&dlg);
1244  ctx_free(&Context);
1245  log_queue_empty();
1246  repeat_error = false;
1247  }
1248 #ifdef USE_IMAP
1249  imap_logout_all();
1250 #endif
1251 #ifdef USE_SASL
1252  mutt_sasl_done();
1253 #endif
1254 #ifdef USE_AUTOCRYPT
1256 #endif
1257  // TEST43: neomutt (no change to mailbox)
1258  // TEST44: neomutt (change mailbox)
1259  }
1260 
1261 main_ok:
1262  rc = 0;
1263 main_curses:
1264  mutt_endwin();
1266  /* Repeat the last message to the user */
1267  if (repeat_error && ErrorBufMessage)
1268  puts(ErrorBuf);
1269 main_exit:
1271  mutt_buffer_dealloc(&folder);
1272  mutt_buffer_dealloc(&expanded_infile);
1273  mutt_buffer_dealloc(&tempfile);
1274  mutt_list_free(&queries);
1281  crypt_cleanup();
1282  mutt_opts_free();
1283  mutt_keys_free();
1285  mutt_prex_free();
1287  cs_free(&cs);
1289  log_queue_empty();
1290  mutt_log_stop();
1291  return rc;
1292 }
log_queue_flush
void log_queue_flush(log_dispatcher_t disp)
Replay the log queue.
Definition: logging.c:348
ctx_free
void ctx_free(struct Context **ptr)
Free a Context.
Definition: context.c:50
lib.h
Envelope
The header of an Email.
Definition: envelope.h:54
mutt_str_atos
int mutt_str_atos(const char *str, short *dst)
Convert ASCII string to a short.
Definition: string.c:222
mutt_endwin
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:572
neomutt_free
void neomutt_free(struct NeoMutt **ptr)
Free a NeoMutt.
Definition: neomutt.c:64
SendFlags
uint16_t SendFlags
Flags for mutt_send_message(), e.g. SEND_REPLY.
Definition: send.h:37
Envelope::subject
char * subject
Email's subject.
Definition: envelope.h:66
Envelope::bcc
struct AddressList bcc
Email's 'Bcc' list.
Definition: envelope.h:60
dialog_pop
void dialog_pop(void)
Hide a Window from the user.
Definition: dialog.c:98
lib.h
mutt_init_abort_key
void mutt_init_abort_key(void)
Parse the abort_key config string.
Definition: keymap.c:866
lib.h
log_translation
static void log_translation(void)
Log the translation being used.
Definition: main.c:341
MUTT_READONLY
#define MUTT_READONLY
Open in read-only mode.
Definition: mx.h:54
myvar.h
NeoMutt::accounts
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
_
#define _(a)
Definition: message.h:28
Mailbox
A mailbox.
Definition: mailbox.h:81
MUTT_CLI_NO_FLAGS
#define MUTT_CLI_NO_FLAGS
No flags are set.
Definition: main.c:102
SEND_BATCH
#define SEND_BATCH
Send email in batch mode (without user interaction)
Definition: send.h:46
crypto_module_free
void crypto_module_free(void)
Clean up the crypto modules.
Definition: crypt_mod.c:81
nntp_expand_path
void nntp_expand_path(char *buf, size_t buflen, struct ConnAccount *acct)
Make fully qualified url from newsgroup name.
Definition: newsrc.c:560
NT_CONFIG
@ NT_CONFIG
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:37
mutt_env_to_intl
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:309
U_MAILTO
@ U_MAILTO
Url is mailto://.
Definition: url.h:44
ListNode
A List node for strings.
Definition: list.h:34
Buffer
String manipulation buffer.
Definition: buffer.h:33
test_parse_set
void test_parse_set(void)
Test the config parsing.
Definition: parse_test.c:39
mutt_addrlist_to_intl
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1304
ConfigDumpFlags
uint16_t ConfigDumpFlags
Flags for dump_config(), e.g. CS_DUMP_ONLY_CHANGED.
Definition: dump.h:32
NT_GLOBAL_STARTUP
@ NT_GLOBAL_STARTUP
NeoMutt is initialised.
Definition: neomutt.h:50
Connection::account
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
STAILQ_REMOVE
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:399
ctx_mailbox
struct Mailbox * ctx_mailbox(struct Context *ctx)
wrapper to get the mailbox in a Context, or NULL
Definition: context.c:429
crypt_init
void crypt_init(void)
Initialise the crypto backends.
Definition: cryptglue.c:95
cs_he_initial_set
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:431
mutt_file_fclose
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
log_queue_set_max_size
void log_queue_set_max_size(int size)
Set a upper limit for the queue length.
Definition: logging.c:314
Body::next
struct Body * next
next attachment in the list
Definition: body.h:53
mutt_buffer_is_empty
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
index_pager_init
struct MuttWindow * index_pager_init(void)
Allocate the Windows for the Index/Pager.
Definition: index.c:4187
mutt_buffer_dealloc
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
url_check_scheme
enum UrlScheme url_check_scheme(const char *str)
Check the protocol of a URL.
Definition: url.c:221
Body
The body of an email.
Definition: body.h:34
NT_ALL
@ NT_ALL
Register for all notifications.
Definition: notify_type.h:33
dialog_push
void dialog_push(struct MuttWindow *dlg)
Display a Window to the user.
Definition: dialog.c:66
CSR_SUCCESS
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
CliFlags
uint8_t CliFlags
Flags for command line options, e.g. MUTT_CLI_IGNORE.
Definition: main.c:101
NT_GLOBAL
@ NT_GLOBAL
Not object-related, NotifyGlobal.
Definition: notify_type.h:40
CSR_RESULT
#define CSR_RESULT(x)
Definition: set.h:52
main
int main(int argc, char *argv[], char *envp[])
Start NeoMutt.
Definition: main.c:371
MUTT_POP
@ MUTT_POP
'POP3' Mailbox type
Definition: mailbox.h:55
NeoMutt::notify
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
mutt_buffer_mktemp
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
MuttWindow
A division of the screen.
Definition: mutt_window.h:115
mutt_folder_hook
void mutt_folder_hook(const char *path, const char *desc)
Perform a folder hook.
Definition: hook.c:505
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:714
Email::offset
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:84
mutt_log_start
int mutt_log_start(void)
Enable file logging.
Definition: mutt_logging.c:282
mutt_window_free_all
void mutt_window_free_all(void)
Free all the default Windows.
Definition: mutt_window.c:304
mutt_prepare_envelope
void mutt_prepare_envelope(struct Envelope *env, bool final, struct ConfigSubset *sub)
Prepare an email header.
Definition: sendlib.c:1238
MUTT_WRITE_HEADER_POSTPONE
@ MUTT_WRITE_HEADER_POSTPONE
A postponed Email, just the envelope info.
Definition: header.h:42
mutt_make_multipart
struct Body * mutt_make_multipart(struct Body *b)
Create a multipart email.
Definition: multipart.c:100
mutt_envlist_init
void mutt_envlist_init(char *envp[])
Create a copy of the environment.
Definition: envlist.c:56
MUTT_YES
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:40
MUTT_CLI_SELECT
#define MUTT_CLI_SELECT
-y Start with a list of all mailboxes
Definition: main.c:107
Context
The "current" mailbox.
Definition: context.h:38
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
mutt_menu_color_observer
int mutt_menu_color_observer(struct NotifyCallback *nc)
Listen for colour changes affecting the menu - Implements observer_t.
Definition: menu.c:1570
mutt_globals.h
mutt_file_fopen
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:589
LL_DEBUG1
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
Mailbox::flags
uint8_t flags
e.g. MB_NORMAL
Definition: mailbox.h:134
km_init
void km_init(void)
Initialise all the menu keybindings.
Definition: keymap.c:1010
mutt_query_variables
int mutt_query_variables(struct ListHead *queries, bool show_docs)
Implement the -Q command line flag.
Definition: init.c:1068
FREE
#define FREE(x)
Definition: memory.h:40
mutt_should_hide_protected_subject
bool mutt_should_hide_protected_subject(struct Email *e)
Should NeoMutt hide the protected subject?
Definition: crypt.c:1076
C_Autocrypt
bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: config.c:37
options.h
log_queue_empty
void log_queue_empty(void)
Free the contents of the queue.
Definition: logging.c:326
mutt_perror
#define mutt_perror(...)
Definition: logging.h:85
mutt_addrlist_parse
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:458
C_ReadOnly
WHERE bool C_ReadOnly
Config: Open folders in read-only mode.
Definition: mutt_globals.h:154
lib.h
mutt_history.h
Buffer::dsize
size_t dsize
Length of data.
Definition: buffer.h:37
cs_str_initial_set
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:473
mutt_opts_free
void mutt_opts_free(void)
clean up before quitting
Definition: init.c:636
lib.h
PATH_MAX
#define PATH_MAX
Definition: mutt.h:44
mutt_parse_mailto
bool mutt_parse_mailto(struct Envelope *e, char **body, const char *src)
Parse a mailto:// url.
Definition: parse.c:1593
SEND_DRAFT_FILE
#define SEND_DRAFT_FILE
Used by the -H flag.
Definition: send.h:51
mutt_window_init
void mutt_window_init(void)
Create the default Windows.
Definition: mutt_window.c:339
OptNoCurses
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:48
version.h
mutt_buffer_reset
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
mutt_mailbox_next
struct Mailbox * mutt_mailbox_next(struct Mailbox *m_cur, struct Buffer *s)
incoming folders completion routine
Definition: mutt_mailbox.c:312
mutt_buffer_pool_release
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
STAILQ_EMPTY
#define STAILQ_EMPTY(head)
Definition: queue.h:345
Username
WHERE char * Username
User's login name.
Definition: mutt_globals.h:52
mailbox_free
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:71
MUTT_CLI_NOSYSRC
#define MUTT_CLI_NOSYSRC
-n Do not read the system-wide config file
Definition: main.c:105
MUTT_CLI_IGNORE
#define MUTT_CLI_IGNORE
-z Open first mailbox if it has mail
Definition: main.c:103
email_new
struct Email * email_new(void)
Create a new Email.
Definition: email.c:72
MUTT_STARTUP_HOOK
#define MUTT_STARTUP_HOOK
startup-hook: run when starting NeoMutt
Definition: hook.h:64
mutt_menu_config_observer
int mutt_menu_config_observer(struct NotifyCallback *nc)
Listen for config changes affecting the menu - Implements observer_t.
Definition: menu.c:1614
mutt_list_insert_tail
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
mutt_array_size
#define mutt_array_size(x)
Definition: memory.h:33
STAILQ_FOREACH
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
log_disp_terminal
int log_disp_terminal(time_t stamp, const char *file, int line, const char *function, enum LogLevel level,...)
Save a log line to the terminal - Implements log_dispatcher_t.
Definition: logging.c:441
LL_MAX
@ LL_MAX
Definition: logging.h:47
MT_COLOR_NORMAL
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:77
mutt_buffer_alloc
void mutt_buffer_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:265
notify_send
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:152
mutt_autocrypt_cleanup
void mutt_autocrypt_cleanup(void)
Shutdown Autocrypt.
Definition: autocrypt.c:135
NntpAccountData::conn
struct Connection * conn
Definition: adata.h:60
C_CryptProtectedHeadersRead
bool C_CryptProtectedHeadersRead
Config: Display protected headers (Memory Hole) in the pager.
Definition: config.c:56
SKIPWS
#define SKIPWS(ch)
Definition: string2.h:46
myvarlist_free
void myvarlist_free(struct MyVarList *list)
Free a List of MyVars.
Definition: myvar.c:131
CS_DUMP_NO_FLAGS
#define CS_DUMP_NO_FLAGS
No flags are set.
Definition: dump.h:35
mutt_str_equal
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
EventMailbox
An Event that happened to a Mailbox.
Definition: mailbox.h:183
lib.h
mutt_buffer_expand_path_regex
void mutt_buffer_expand_path_regex(struct Buffer *buf, bool regex)
Create the canonical path (with regex char escaping)
Definition: muttlib.c:140
mutt_file_read_keyword
char * mutt_file_read_keyword(const char *file, char *buf, size_t buflen)
Read a keyword from a file.
Definition: file.c:1382
init_locale
static void init_locale(void)
Initialise the Locale/NLS settings.
Definition: main.c:272
protos.h
mutt_rfc822_write_header
int mutt_rfc822_write_header(FILE *fp, struct Envelope *env, struct Body *attach, enum MuttWriteHeaderMode mode, bool privacy, bool hide_protected_subject, struct ConfigSubset *sub)
Write out one RFC822 header line.
Definition: header.c:574
NT_MAILBOX
@ NT_MAILBOX
Mailbox has changed, NotifyMailbox, EventMailbox.
Definition: notify_type.h:42
mutt_commands_cleanup
void mutt_commands_cleanup(void)
Clean up commands globals.
Definition: commands.c:101
cs_he_reset
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:356
Envelope::cc
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:59
MUTT_CLI_MAILBOX
#define MUTT_CLI_MAILBOX
-Z Open first mailbox if is has new mail
Definition: main.c:104
mutt_body_new
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
mutt_env_free
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:96
mutt_buffer_pool_get
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
ErrorBuf
WHERE char ErrorBuf[256]
Copy of the last error message.
Definition: mutt_globals.h:45
MUTT_NNTP
@ MUTT_NNTP
'NNTP' (Usenet) Mailbox type
Definition: mailbox.h:52
nntp_path_probe
enum MailboxType nntp_path_probe(const char *path, const struct stat *st)
Is this an NNTP Mailbox? - Implements MxOps::path_probe()
Definition: nntp.c:2685
MuttWindow::notify
struct Notify * notify
Notifications system.
Definition: mutt_window.h:131
init.h
LL_MESSAGE
@ LL_MESSAGE
Log informational message.
Definition: logging.h:39
SEND_POSTPONED
#define SEND_POSTPONED
Recall a postponed email.
Definition: send.h:45
mutt_make_file_attach
struct Body * mutt_make_file_attach(const char *path, struct ConfigSubset *sub)
Create a file attachment.
Definition: sendlib.c:1083
dump_config
bool dump_config(struct ConfigSet *cs, ConfigDumpFlags flags, FILE *fp)
Write all the config to a file.
Definition: dump.c:165
keymap.h
lib.h
mutt_abort_key_config_observer
int mutt_abort_key_config_observer(struct NotifyCallback *nc)
Listen for abort_key config changes - Implements observer_t.
Definition: keymap.c:887
usage
static void usage(void)
Display NeoMutt command line.
Definition: main.c:154
mutt_file_copy_stream
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:271
muttlib.h
C_Folder
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: mutt_globals.h:96
mutt_write_mime_body
int mutt_write_mime_body(struct Body *a, FILE *fp, struct ConfigSubset *sub)
Write a MIME part.
Definition: body.c:314
mutt_sasl_done
void mutt_sasl_done(void)
Invoke when processing is complete.
Definition: sasl.c:779
Body::length
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
MUTT_SEL_FOLDER
#define MUTT_SEL_FOLDER
Select a local directory.
Definition: browser.h:44
mutt_menu.h
Mailbox::account
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
imap_logout_all
void imap_logout_all(void)
close all open connections
Definition: imap.c:560
lib.h
lib.h
mutt_mailbox_check
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:141
LastFolder
WHERE char * LastFolder
Previously selected mailbox.
Definition: mutt_globals.h:55
mdata.h
mutt_startup_shutdown_hook
void mutt_startup_shutdown_hook(HookFlags type)
Execute any startup/shutdown hooks.
Definition: hook.c:837
mutt_send_message
int mutt_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile, struct Context *ctx, struct EmailList *el, struct ConfigSubset *sub)
Send an email.
Definition: send.c:2012
mutt_signal_init
void mutt_signal_init(void)
Initialise the signal handling.
Definition: mutt_signal.c:132
NT_MAILBOX_SWITCH
@ NT_MAILBOX_SWITCH
Current Mailbox has changed.
Definition: mailbox.h:175
mutt_encode_descriptions
void mutt_encode_descriptions(struct Body *b, bool recurse, struct ConfigSubset *sub)
rfc2047 encode the content-descriptions
Definition: send.c:1462
MUTT_IMAP
@ MUTT_IMAP
'IMAP' Mailbox type
Definition: mailbox.h:53
Envelope::to
struct AddressList to
Email's 'To' list.
Definition: envelope.h:58
Colors
Definition: color.h:129
mutt_exit
void mutt_exit(int code)
Leave NeoMutt NOW.
Definition: main.c:140
Context::mailbox
struct Mailbox * mailbox
Definition: context.h:50
init_extended_keys
void init_extended_keys(void)
Initialise map of ncurses extended keys.
Definition: keymap.c:981
Email::env
struct Envelope * env
Envelope information.
Definition: email.h:90
mutt_debug
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
crypt_cleanup
void crypt_cleanup(void)
Clean up backend.
Definition: cryptglue.c:140
MUTT_OPEN_NO_FLAGS
#define MUTT_OPEN_NO_FLAGS
No flags are set.
Definition: mx.h:51
CS_DUMP_HIDE_SENSITIVE
#define CS_DUMP_HIDE_SENSITIVE
Obscure sensitive information like passwords.
Definition: dump.h:37
mutt_window_set_root
void mutt_window_set_root(int cols, int rows)
Set the dimensions of the Root Window.
Definition: mutt_window.c:624
MUTT_CLI_RO
#define MUTT_CLI_RO
-R Open mailbox in read-only mode
Definition: main.c:106
mx_path_is_empty
int mx_path_is_empty(const char *path)
Is the mailbox empty.
Definition: mx.c:1265
Colors::notify
struct Notify * notify
Notifications system.
Definition: color.h:149
notify_observer_add
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:169
SEND_NO_FLAGS
#define SEND_NO_FLAGS
No flags are set.
Definition: send.h:40
Mailbox::realpath
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
mutt_buffer_expand_path
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:323
nntp_select_server
struct NntpAccountData * nntp_select_server(struct Mailbox *m, const char *server, bool leave_lock)
Open a connection to an NNTP server.
Definition: newsrc.c:1012
C_AutoEdit
WHERE bool C_AutoEdit
Config: Skip the initial compose menu and edit the email.
Definition: mutt_globals.h:136
mutt_prepare_template
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:664
mutt_str_getenv
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition: string.c:991
mutt_buffer_string
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
STAILQ_FOREACH_SAFE
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:359
CurrentNewsSrv
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:79
mutt_mailbox.h
mutt_env_new
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
pop_path_probe
enum MailboxType pop_path_probe(const char *path, const struct stat *st)
Is this a POP Mailbox? - Implements MxOps::path_probe()
Definition: pop.c:1149
mutt_str_replace
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
lib.h
reset_tilde
static void reset_tilde(struct ConfigSet *cs)
Temporary measure.
Definition: main.c:117
mutt_buffer_pool_free
void mutt_buffer_pool_free(void)
Release the Buffer pool.
Definition: pool.c:87
mutt_logging.h
print_copyright
void print_copyright(void)
Print copyright message.
Definition: version.c:541
mutt_flushinp
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:923
mutt_buffer_select_file
void mutt_buffer_select_file(struct Buffer *file, SelectFileFlags flags, struct Mailbox *m, char ***files, int *numfiles)
Let the user select a file.
Definition: browser.c:1142
lib.h
lib.h
mutt_autocrypt_init
int mutt_autocrypt_init(struct Mailbox *m, bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:95
STAILQ_HEAD_INITIALIZER
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
get_user_info
static bool get_user_info(struct ConfigSet *cs)
Find the user's name, home and shell.
Definition: main.c:300
C_ResumeEditedDraftFiles
bool C_ResumeEditedDraftFiles
Config: Resume editing previously saved draft files.
Definition: main.c:98
HashElem
The item stored in a Hash Table.
Definition: hash.h:43
C_ImapPassive
bool C_ImapPassive
Config: (imap) Reuse an existing IMAP connection to check for new mail.
Definition: config.c:54
lib.h
Envelope::userhdrs
struct ListHead userhdrs
user defined headers
Definition: envelope.h:83
mailbox_find_name
struct Mailbox * mailbox_find_name(const char *name)
Find the mailbox with a given name.
Definition: mailbox.c:140
mutt_colors_new
struct Colors * mutt_colors_new(void)
Create new colours.
Definition: color.c:374
cs_str_native_set
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:761
HomeDir
char * HomeDir
User's home directory.
Definition: mutt_globals.h:49
mutt_log_stop
void mutt_log_stop(void)
Close the log file.
Definition: mutt_logging.c:223
C_NewsServer
char * C_NewsServer
Config: (nntp) Url of the news server.
Definition: config.c:41
adata.h
mutt_unlink_temp_attachments
void mutt_unlink_temp_attachments(void)
Delete all temporary attachments.
Definition: mutt_attach.c:1266
log_disp_queue
int log_disp_queue(time_t stamp, const char *file, int line, const char *function, enum LogLevel level,...)
Save a log line to an internal queue - Implements log_dispatcher_t.
Definition: logging.c:400
alias_lookup
struct AddressList * alias_lookup(const char *name)
Find an Alias.
Definition: alias.c:276
TsSupported
bool TsSupported
Terminal Setting is supported.
Definition: terminal.c:43
C_SpoolFile
WHERE char * C_SpoolFile
Config: Inbox.
Definition: mutt_globals.h:108
NeoMutt
Container for Accounts, Notifications.
Definition: neomutt.h:36
neomutt_new
struct NeoMutt * neomutt_new(struct ConfigSet *cs)
Create the main NeoMutt object.
Definition: neomutt.c:44
start_curses
static int start_curses(void)
Start the curses or slang UI.
Definition: main.c:227
mutt_istr_startswith
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:172
show_backtrace
void show_backtrace(void)
Log the program's call stack.
Definition: backtrace.c:39
MUTT_SEL_MAILBOX
#define MUTT_SEL_MAILBOX
Select a mailbox.
Definition: browser.h:42
init_config
struct ConfigSet * init_config(size_t size)
Initialise the config system.
Definition: mutt_config.c:818
mutt_prex_free
void mutt_prex_free(void)
mx_mbox_open
struct Context * mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:309
OptLocales
bool OptLocales
(pseudo) set if user has valid locale definition
Definition: mbyte.c:44
ConfigSet
Container for lots of config items.
Definition: set.h:228
debug_notify_observer
int debug_notify_observer(struct NotifyCallback *nc)
Definition: notify.c:321
mutt_curses_set_color
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:57
imap_path_probe
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2372
mutt_addrlist_write_file
void mutt_addrlist_write_file(const struct AddressList *al, FILE *fp, int start_col, bool display)
Wrapper for mutt_write_address()
Definition: address.c:1231
cs_str_reset
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:408
ListNode::data
char * data
String.
Definition: list.h:36
context.h
mutt_log_prep
void mutt_log_prep(void)
Prepare to log.
Definition: mutt_logging.c:213
mutt_init
int mutt_init(struct ConfigSet *cs, bool skip_sys_rc, struct ListHead *commands)
Initialise NeoMutt.
Definition: init.c:722
NeoMutt::sub
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
ErrorBufMessage
WHERE bool ErrorBufMessage
true if the last message was an error
Definition: mutt_globals.h:44
browser.h
mx_resolve
struct Mailbox * mx_resolve(const char *path_or_name)
Get a Mailbox from either a path or name.
Definition: mx.c:1750
cs_he_initial_get
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:499
CurrentFolder
WHERE char * CurrentFolder
Currently selected mailbox.
Definition: mutt_globals.h:54
CS_DUMP_SHOW_DOCS
#define CS_DUMP_SHOW_DOCS
Show one-liner documentation for the config item.
Definition: dump.h:45
email_free
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:43
MuttLogger
log_dispatcher_t MuttLogger
The log dispatcher.
Definition: logging.c:52
mutt_envlist_free
void mutt_envlist_free(void)
Free the private copy of the environment.
Definition: envlist.c:41
cs_get_elem
struct HashElem * cs_get_elem(const struct ConfigSet *cs, const char *name)
Get the HashElem representing a config item.
Definition: set.c:214
Body::unlink
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
mutt_log_observer
int mutt_log_observer(struct NotifyCallback *nc)
Listen for config changes affecting the log file - Implements observer_t.
Definition: mutt_logging.c:317
mx.h
account_mailbox_remove
bool account_mailbox_remove(struct Account *a, struct Mailbox *m)
Remove a Mailbox from an Account.
Definition: account.c:94
commands.h
print_version
void print_version(FILE *fp)
Print system and compile info to a file.
Definition: version.c:424
lib.h
lib.h
mutt_yesorno
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:380
Buffer::data
char * data
Pointer to data.
Definition: buffer.h:35
Email
The envelope/body of an email.
Definition: email.h:37
lib.h
mutt_ts_capability
bool mutt_ts_capability(void)
Check terminal capabilities.
Definition: terminal.c:55
mutt_message
#define mutt_message(...)
Definition: logging.h:83
mutt_attach.h
log_disp_curses
int log_disp_curses(time_t stamp, const char *file, int line, const char *function, enum LogLevel level,...)
Display a log line in the message line - Implements log_dispatcher_t.
Definition: mutt_logging.c:127
MyVars
struct MyVarList MyVars
List of all the user's custom config variables.
Definition: myvar.c:34
mutt_make_version
const char * mutt_make_version(void)
Generate the NeoMutt version string.
Definition: muttlib.c:1462
mutt_addrlist_copy
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:737
cs_str_string_set
int cs_str_string_set(const struct ConfigSet *cs, const char *name, const char *value, struct Buffer *err)
Set a config item by string.
Definition: set.c:613
mutt_buffer_make
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
mutt_list_free
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
mutt_browser_cleanup
void mutt_browser_cleanup(void)
Clean up working Buffers.
Definition: browser.c:126
hook.h
mutt_buffer_strcpy
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
index_pager_shutdown
void index_pager_shutdown(struct MuttWindow *dlg)
Clear up any non-Window parts.
Definition: index.c:4205
myvar_set
void myvar_set(const char *var, const char *val)
Set the value of a "my_" variable.
Definition: myvar.c:91
MUTT_CLI_NEWS
#define MUTT_CLI_NEWS
-g/-G Start with a list of all newsgroups
Definition: main.c:109
cs_free
void cs_free(struct ConfigSet **ptr)
Free a Config Set.
Definition: set.c:180
SEND_NO_FREE_HEADER
#define SEND_NO_FREE_HEADER
Used by the -E flag.
Definition: send.h:50
Email::body
struct Body * body
List of MIME parts.
Definition: email.h:91
mutt_index_menu
int mutt_index_menu(struct MuttWindow *dlg)
Display a list of emails.
Definition: index.c:1160
OptNews
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:45
mutt_keys_free
void mutt_keys_free(void)
Free the key maps.
Definition: keymap.c:1698
mutt_window_free
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
Definition: mutt_window.c:186
mutt_error
#define mutt_error(...)
Definition: logging.h:84
mutt_hist_observer
int mutt_hist_observer(struct NotifyCallback *nc)
Listen for config changes affecting the history - Implements observer_t.
Definition: mutt_history.c:59