NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
init.c
Go to the documentation of this file.
1 
30 #include "config.h"
31 #include <ctype.h>
32 #include <inttypes.h>
33 #include <pwd.h>
34 #include <stdbool.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/stat.h>
39 #include <sys/utsname.h>
40 #include <unistd.h>
41 #include "mutt/lib.h"
42 #include "address/lib.h"
43 #include "config/lib.h"
44 #include "email/lib.h"
45 #include "core/lib.h"
46 #include "alias/lib.h"
47 #include "conn/lib.h"
48 #include "gui/lib.h"
49 #include "mutt.h"
50 #include "init.h"
51 #include "compress/lib.h"
52 #include "hcache/lib.h"
53 #include "history/lib.h"
54 #include "notmuch/lib.h"
55 #include "store/lib.h"
56 #include "command_parse.h"
57 #include "context.h"
58 #include "functions.h"
59 #include "keymap.h"
60 #include "mutt_commands.h"
61 #include "mutt_globals.h"
62 #ifdef USE_LUA
63 #include "mutt_lua.h"
64 #endif
65 #include "mutt_menu.h"
66 #include "mutt_parse.h"
67 #include "muttlib.h"
68 #include "myvar.h"
69 #include "options.h"
70 #include "protos.h"
71 #include "sort.h"
72 #ifdef USE_SIDEBAR
73 #include "sidebar/lib.h"
74 #endif
75 #ifdef USE_COMP_MBOX
76 #include "compmbox/lib.h"
77 #endif
78 #ifdef USE_IMAP
79 #include "imap/lib.h"
80 #endif
81 
82 /* Initial string that starts completion. No telling how much the user has
83  * typed so far. Allocate 1024 just to be sure! */
84 static char UserTyped[1024] = { 0 };
85 
86 static int NumMatched = 0; /* Number of matches for completion */
87 static char Completed[256] = { 0 }; /* completed string (command or variable) */
88 static const char **Matches;
89 /* this is a lie until mutt_init runs: */
90 static int MatchesListsize = 512; // Enough space for all of the config items
91 
92 #ifdef USE_NOTMUCH
93 /* List of tags found in last call to mutt_nm_query_complete(). */
94 static char **nm_tags;
95 #endif
96 
101 static void matches_ensure_morespace(int current)
102 {
103  if (current <= (MatchesListsize - 2))
104  return;
105 
106  int base_space = 512; // Enough space for all of the config items
107  int extra_space = MatchesListsize - base_space;
108  extra_space *= 2;
109  const int space = base_space + extra_space;
110  mutt_mem_realloc(&Matches, space * sizeof(char *));
111  memset(&Matches[current + 1], 0, space - current);
112  MatchesListsize = space;
113 }
114 
124 static void candidate(char *user, const char *src, char *dest, size_t dlen)
125 {
126  if (!dest || !user || !src)
127  return;
128 
129  if (strstr(src, user) != src)
130  return;
131 
133  Matches[NumMatched++] = src;
134  if (dest[0] == '\0')
135  mutt_str_copy(dest, src, dlen);
136  else
137  {
138  int l;
139  for (l = 0; src[l] && src[l] == dest[l]; l++)
140  ; // do nothing
141 
142  dest[l] = '\0';
143  }
144 }
145 
146 #ifdef USE_NOTMUCH
147 
153 static int complete_all_nm_tags(const char *pt)
154 {
155  int tag_count_1 = 0;
156  int tag_count_2 = 0;
157 
158  NumMatched = 0;
159  mutt_str_copy(UserTyped, pt, sizeof(UserTyped));
160  memset(Matches, 0, MatchesListsize);
161  memset(Completed, 0, sizeof(Completed));
162 
164 
165  /* Work out how many tags there are. */
166  if (nm_get_all_tags(Context->mailbox, NULL, &tag_count_1) || (tag_count_1 == 0))
167  goto done;
168 
169  /* Free the old list, if any. */
170  if (nm_tags)
171  {
172  for (int i = 0; nm_tags[i]; i++)
173  FREE(&nm_tags[i]);
174  FREE(&nm_tags);
175  }
176  /* Allocate a new list, with sentinel. */
177  nm_tags = mutt_mem_malloc((tag_count_1 + 1) * sizeof(char *));
178  nm_tags[tag_count_1] = NULL;
179 
180  /* Get all the tags. */
181  if (nm_get_all_tags(Context->mailbox, nm_tags, &tag_count_2) || (tag_count_1 != tag_count_2))
182  {
183  FREE(&nm_tags);
184  nm_tags = NULL;
186  return -1;
187  }
188 
189  /* Put them into the completion machinery. */
190  for (int num = 0; num < tag_count_1; num++)
191  {
192  candidate(UserTyped, nm_tags[num], Completed, sizeof(Completed));
193  }
194 
197 
198 done:
200  return 0;
201 }
202 #endif
203 
210 static int execute_commands(struct ListHead *p)
211 {
212  int rc = 0;
213  struct Buffer *err = mutt_buffer_pool_get();
214 
215  struct ListNode *np = NULL;
216  STAILQ_FOREACH(np, p, entries)
217  {
218  enum CommandResult rc2 = mutt_parse_rc_line(np->data, err);
219  if (rc2 == MUTT_CMD_ERROR)
220  mutt_error(_("Error in command line: %s"), mutt_buffer_string(err));
221  else if (rc2 == MUTT_CMD_WARNING)
222  mutt_warning(_("Warning in command line: %s"), mutt_buffer_string(err));
223 
224  if ((rc2 == MUTT_CMD_ERROR) || (rc2 == MUTT_CMD_WARNING))
225  {
227  return -1;
228  }
229  }
231 
232  return rc;
233 }
234 
242 static char *find_cfg(const char *home, const char *xdg_cfg_home)
243 {
244  const char *names[] = {
245  "neomuttrc",
246  "muttrc",
247  NULL,
248  };
249 
250  const char *locations[][2] = {
251  { xdg_cfg_home, "neomutt/" },
252  { xdg_cfg_home, "mutt/" },
253  { home, ".neomutt/" },
254  { home, ".mutt/" },
255  { home, "." },
256  { NULL, NULL },
257  };
258 
259  for (int i = 0; locations[i][0] || locations[i][1]; i++)
260  {
261  if (!locations[i][0])
262  continue;
263 
264  for (int j = 0; names[j]; j++)
265  {
266  char buf[256];
267 
268  snprintf(buf, sizeof(buf), "%s/%s%s", locations[i][0], locations[i][1], names[j]);
269  if (access(buf, F_OK) == 0)
270  return mutt_str_dup(buf);
271  }
272  }
273 
274  return NULL;
275 }
276 
277 #ifndef DOMAIN
278 
283 static char *getmailname(void)
284 {
285  char *mailname = NULL;
286  static const char *mn_files[] = { "/etc/mailname", "/etc/mail/mailname" };
287 
288  for (size_t i = 0; i < mutt_array_size(mn_files); i++)
289  {
290  FILE *fp = mutt_file_fopen(mn_files[i], "r");
291  if (!fp)
292  continue;
293 
294  size_t len = 0;
295  mailname = mutt_file_read_line(NULL, &len, fp, NULL, MUTT_RL_NO_FLAGS);
296  mutt_file_fclose(&fp);
297  if (mailname && *mailname)
298  break;
299 
300  FREE(&mailname);
301  }
302 
303  return mailname;
304 }
305 #endif
306 
315 static bool get_hostname(struct ConfigSet *cs)
316 {
317  char *str = NULL;
318  struct utsname utsname;
319 
320  if (C_Hostname)
321  {
322  str = C_Hostname;
323  }
324  else
325  {
326  /* The call to uname() shouldn't fail, but if it does, the system is horribly
327  * broken, and the system's networking configuration is in an unreliable
328  * state. We should bail. */
329  if ((uname(&utsname)) == -1)
330  {
331  mutt_perror(_("unable to determine nodename via uname()"));
332  return false; // TEST09: can't test
333  }
334 
335  str = utsname.nodename;
336  }
337 
338  /* some systems report the FQDN instead of just the hostname */
339  char *dot = strchr(str, '.');
340  if (dot)
341  ShortHostname = mutt_strn_dup(str, dot - str);
342  else
344 
345  if (!C_Hostname)
346  {
347  /* now get FQDN. Use configured domain first, DNS next, then uname */
348 #ifdef DOMAIN
349  /* we have a compile-time domain name, use that for `$hostname` */
351  sprintf((char *) C_Hostname, "%s.%s", NONULL(ShortHostname), DOMAIN);
352 #else
354  if (!C_Hostname)
355  {
356  struct Buffer *domain = mutt_buffer_pool_get();
357  if (getdnsdomainname(domain) == 0)
358  {
359  C_Hostname =
361  sprintf((char *) C_Hostname, "%s.%s", NONULL(ShortHostname),
362  mutt_buffer_string(domain));
363  }
364  else
365  {
366  /* DNS failed, use the nodename. Whether or not the nodename had a '.'
367  * in it, we can use the nodename as the FQDN. On hosts where DNS is
368  * not being used, e.g. small network that relies on hosts files, a
369  * short host name is all that is required for SMTP to work correctly.
370  * It could be wrong, but we've done the best we can, at this point the
371  * onus is on the user to provide the correct hostname if the nodename
372  * won't work in their network. */
373  C_Hostname = mutt_str_dup(utsname.nodename);
374  }
375  mutt_buffer_pool_release(&domain);
376  }
377 #endif
378  }
379  if (C_Hostname)
380  cs_str_initial_set(cs, "hostname", C_Hostname, NULL);
381 
382  return true;
383 }
384 
393 int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
394 {
395  if (!dest || !tok)
396  return -1;
397 
398  char ch;
399  char qc = '\0'; /* quote char */
400  char *pc = NULL;
401 
402  /* Some callers used to rely on the (bad) assumption that dest->data would be
403  * non-NULL after calling this function. Perhaps I've missed a few cases, or
404  * a future caller might make the same mistake. */
405  if (!dest->data)
406  mutt_buffer_alloc(dest, 256);
407 
408  mutt_buffer_reset(dest);
409 
410  SKIPWS(tok->dptr);
411  while ((ch = *tok->dptr))
412  {
413  if (qc == '\0')
414  {
415  if ((IS_SPACE(ch) && !(flags & MUTT_TOKEN_SPACE)) ||
416  ((ch == '#') && !(flags & MUTT_TOKEN_COMMENT)) ||
417  ((ch == '+') && (flags & MUTT_TOKEN_PLUS)) ||
418  ((ch == '-') && (flags & MUTT_TOKEN_MINUS)) ||
419  ((ch == '=') && (flags & MUTT_TOKEN_EQUAL)) ||
420  ((ch == '?') && (flags & MUTT_TOKEN_QUESTION)) ||
421  ((ch == ';') && !(flags & MUTT_TOKEN_SEMICOLON)) ||
422  ((flags & MUTT_TOKEN_PATTERN) && strchr("~%=!|", ch)))
423  {
424  break;
425  }
426  }
427 
428  tok->dptr++;
429 
430  if (ch == qc)
431  qc = 0; /* end of quote */
432  else if (!qc && ((ch == '\'') || (ch == '"')) && !(flags & MUTT_TOKEN_QUOTE))
433  qc = ch;
434  else if ((ch == '\\') && (qc != '\''))
435  {
436  if (tok->dptr[0] == '\0')
437  return -1; /* premature end of token */
438  switch (ch = *tok->dptr++)
439  {
440  case 'c':
441  case 'C':
442  if (tok->dptr[0] == '\0')
443  return -1; /* premature end of token */
444  mutt_buffer_addch(dest, (toupper((unsigned char) tok->dptr[0]) - '@') & 0x7f);
445  tok->dptr++;
446  break;
447  case 'e':
448  mutt_buffer_addch(dest, '\033'); // Escape
449  break;
450  case 'f':
451  mutt_buffer_addch(dest, '\f');
452  break;
453  case 'n':
454  mutt_buffer_addch(dest, '\n');
455  break;
456  case 'r':
457  mutt_buffer_addch(dest, '\r');
458  break;
459  case 't':
460  mutt_buffer_addch(dest, '\t');
461  break;
462  default:
463  if (isdigit((unsigned char) ch) && isdigit((unsigned char) tok->dptr[0]) &&
464  isdigit((unsigned char) tok->dptr[1]))
465  {
466  mutt_buffer_addch(dest, (ch << 6) + (tok->dptr[0] << 3) + tok->dptr[1] - 3504);
467  tok->dptr += 2;
468  }
469  else
470  mutt_buffer_addch(dest, ch);
471  }
472  }
473  else if ((ch == '^') && (flags & MUTT_TOKEN_CONDENSE))
474  {
475  if (tok->dptr[0] == '\0')
476  return -1; /* premature end of token */
477  ch = *tok->dptr++;
478  if (ch == '^')
479  mutt_buffer_addch(dest, ch);
480  else if (ch == '[')
481  mutt_buffer_addch(dest, '\033'); // Escape
482  else if (isalpha((unsigned char) ch))
483  mutt_buffer_addch(dest, toupper((unsigned char) ch) - '@');
484  else
485  {
486  mutt_buffer_addch(dest, '^');
487  mutt_buffer_addch(dest, ch);
488  }
489  }
490  else if ((ch == '`') && (!qc || (qc == '"')))
491  {
492  FILE *fp = NULL;
493  pid_t pid;
494 
495  pc = tok->dptr;
496  do
497  {
498  pc = strpbrk(pc, "\\`");
499  if (pc)
500  {
501  /* skip any quoted chars */
502  if (*pc == '\\')
503  pc += 2;
504  }
505  } while (pc && (pc[0] != '`'));
506  if (!pc)
507  {
508  mutt_debug(LL_DEBUG1, "mismatched backticks\n");
509  return -1;
510  }
511  struct Buffer cmd;
512  mutt_buffer_init(&cmd);
513  *pc = '\0';
514  if (flags & MUTT_TOKEN_BACKTICK_VARS)
515  {
516  /* recursively extract tokens to interpolate variables */
517  mutt_extract_token(&cmd, tok,
520  }
521  else
522  {
523  cmd.data = mutt_str_dup(tok->dptr);
524  }
525  *pc = '`';
526  pid = filter_create(cmd.data, NULL, &fp, NULL);
527  if (pid < 0)
528  {
529  mutt_debug(LL_DEBUG1, "unable to fork command: %s\n", cmd.data);
530  FREE(&cmd.data);
531  return -1;
532  }
533  FREE(&cmd.data);
534 
535  tok->dptr = pc + 1;
536 
537  /* read line */
538  struct Buffer expn = mutt_buffer_make(0);
539  expn.data = mutt_file_read_line(NULL, &expn.dsize, fp, NULL, MUTT_RL_NO_FLAGS);
540  mutt_file_fclose(&fp);
541  filter_wait(pid);
542 
543  /* if we got output, make a new string consisting of the shell output
544  * plus whatever else was left on the original line */
545  /* BUT: If this is inside a quoted string, directly add output to
546  * the token */
547  if (expn.data)
548  {
549  if (qc)
550  {
551  mutt_buffer_addstr(dest, expn.data);
552  }
553  else
554  {
555  struct Buffer *copy = mutt_buffer_pool_get();
556  mutt_buffer_fix_dptr(&expn);
557  mutt_buffer_copy(copy, &expn);
558  mutt_buffer_addstr(copy, tok->dptr);
559  mutt_buffer_copy(tok, copy);
560  mutt_buffer_seek(tok, 0);
562  }
563  FREE(&expn.data);
564  }
565  }
566  else if ((ch == '$') && (!qc || (qc == '"')) &&
567  ((tok->dptr[0] == '{') || isalpha((unsigned char) tok->dptr[0])))
568  {
569  const char *env = NULL;
570  char *var = NULL;
571 
572  if (tok->dptr[0] == '{')
573  {
574  pc = strchr(tok->dptr, '}');
575  if (pc)
576  {
577  var = mutt_strn_dup(tok->dptr + 1, pc - (tok->dptr + 1));
578  tok->dptr = pc + 1;
579 
580  if ((flags & MUTT_TOKEN_NOSHELL))
581  {
582  mutt_buffer_addch(dest, ch);
583  mutt_buffer_addch(dest, '{');
584  mutt_buffer_addstr(dest, var);
585  mutt_buffer_addch(dest, '}');
586  FREE(&var);
587  }
588  }
589  }
590  else
591  {
592  for (pc = tok->dptr; isalnum((unsigned char) *pc) || (pc[0] == '_'); pc++)
593  ; // do nothing
594 
595  var = mutt_strn_dup(tok->dptr, pc - tok->dptr);
596  tok->dptr = pc;
597  }
598  if (var)
599  {
600  struct Buffer result;
601  mutt_buffer_init(&result);
602  int rc = cs_subset_str_string_get(NeoMutt->sub, var, &result);
603 
604  if (CSR_RESULT(rc) == CSR_SUCCESS)
605  {
606  mutt_buffer_addstr(dest, result.data);
607  FREE(&result.data);
608  }
609  else if ((env = myvar_get(var)))
610  {
611  mutt_buffer_addstr(dest, env);
612  }
613  else if (!(flags & MUTT_TOKEN_NOSHELL) && (env = mutt_str_getenv(var)))
614  {
615  mutt_buffer_addstr(dest, env);
616  }
617  else
618  {
619  mutt_buffer_addch(dest, ch);
620  mutt_buffer_addstr(dest, var);
621  }
622  FREE(&var);
623  }
624  }
625  else
626  mutt_buffer_addch(dest, ch);
627  }
628  mutt_buffer_addch(dest, 0); /* terminate the string */
629  SKIPWS(tok->dptr);
630  return 0;
631 }
632 
636 void mutt_opts_free(void)
637 {
639 
640  alias_shutdown();
641 #ifdef USE_SIDEBAR
642  sb_shutdown();
643 #endif
644 
645  mutt_regexlist_free(&Alternates);
649  mutt_regexlist_free(&UnAlternates);
652 
656 
657  /* Lists of strings */
658  mutt_list_free(&AlternativeOrderList);
659  mutt_list_free(&AutoViewList);
660  mutt_list_free(&HeaderOrderList);
663  mutt_list_free(&MimeLookupList);
664  mutt_list_free(&Muttrc);
666  mutt_list_free(&UserHeader);
667 
668  /* Lists of AttachMatch */
673 
675 
677  FREE(&HomeDir);
678  FREE(&LastFolder);
680  FREE(&Username);
681 
684 
686 
687  mutt_hist_free();
688  mutt_keys_free();
689 
692 }
693 
700 HookFlags mutt_get_hook_type(const char *name)
701 {
702  struct Command *c = NULL;
703  for (size_t i = 0, size = mutt_commands_array(&c); i < size; i++)
704  {
705  if (((c[i].parse == mutt_parse_hook) || (c[i].parse == mutt_parse_idxfmt_hook)) &&
706  mutt_istr_equal(c[i].name, name))
707  {
708  return c[i].data;
709  }
710  }
711  return MUTT_HOOK_NO_FLAGS;
712 }
713 
722 int mutt_init(struct ConfigSet *cs, bool skip_sys_rc, struct ListHead *commands)
723 {
724  int need_pause = 0;
725  int rc = 1;
726  struct Buffer err = mutt_buffer_make(256);
727  struct Buffer buf = mutt_buffer_make(256);
728 
730  alias_init();
732 #ifdef USE_COMP_MBOX
733  mutt_comp_init();
734 #endif
735 #ifdef USE_IMAP
736  imap_init();
737 #endif
738 #ifdef USE_LUA
739  mutt_lua_init();
740 #endif
743 
744  mutt_menu_init();
745 #ifdef USE_SIDEBAR
746  sb_init();
747 #endif
748 #ifdef USE_NOTMUCH
749  nm_init();
750 #endif
751 
752  snprintf(AttachmentMarker, sizeof(AttachmentMarker), "\033]9;%" PRIu64 "\a", // Escape
753  mutt_rand64());
754 
755  snprintf(ProtectedHeaderMarker, sizeof(ProtectedHeaderMarker), "\033]8;%lld\a", // Escape
756  (long long) mutt_date_epoch());
757 
758  /* "$spool_file" precedence: config file, environment */
759  const char *p = mutt_str_getenv("MAIL");
760  if (!p)
761  p = mutt_str_getenv("MAILDIR");
762  if (!p)
763  {
764 #ifdef HOMESPOOL
765  mutt_buffer_concat_path(&buf, NONULL(HomeDir), MAILPATH);
766 #else
767  mutt_buffer_concat_path(&buf, MAILPATH, NONULL(Username));
768 #endif
769  p = mutt_buffer_string(&buf);
770  }
771  cs_str_initial_set(cs, "spool_file", p, NULL);
772  cs_str_reset(cs, "spool_file", NULL);
773 
774  p = mutt_str_getenv("REPLYTO");
775  if (p)
776  {
777  struct Buffer token;
778 
779  mutt_buffer_printf(&buf, "Reply-To: %s", p);
780  mutt_buffer_init(&token);
781  parse_my_hdr(&token, &buf, 0, &err); /* adds to UserHeader */
782  FREE(&token.data);
783  }
784 
785  p = mutt_str_getenv("EMAIL");
786  if (p)
787  {
788  cs_str_initial_set(cs, "from", p, NULL);
789  cs_str_reset(cs, "from", NULL);
790  }
791 
792  /* "$mailcap_path" precedence: config file, environment, code */
793  const char *env_mc = mutt_str_getenv("MAILCAPS");
794  if (env_mc)
795  cs_str_string_set(cs, "mailcap_path", env_mc, NULL);
796 
797  /* "$tmpdir" precedence: config file, environment, code */
798  const char *env_tmp = mutt_str_getenv("TMPDIR");
799  if (env_tmp)
800  cs_str_string_set(cs, "tmpdir", env_tmp, NULL);
801 
802  /* "$visual", "$editor" precedence: config file, environment, code */
803  const char *env_ed = mutt_str_getenv("VISUAL");
804  if (!env_ed)
805  env_ed = mutt_str_getenv("EDITOR");
806  if (env_ed)
807  {
808  cs_str_string_set(cs, "editor", env_ed, NULL);
809  cs_str_string_set(cs, "visual", env_ed, NULL);
810  }
811 
813  cs_str_initial_set(cs, "charset", C_Charset, NULL);
815 
816  Matches = mutt_mem_calloc(MatchesListsize, sizeof(char *));
817 
819 
820 #ifdef HAVE_GETSID
821  /* Unset suspend by default if we're the session leader */
822  if (getsid(0) == getpid())
823  C_Suspend = false;
824 #endif
825 
826  /* RFC2368, "4. Unsafe headers"
827  * The creator of a mailto URL can't expect the resolver of a URL to
828  * understand more than the "subject" and "body" headers. Clients that
829  * resolve mailto URLs into mail messages should be able to correctly
830  * create RFC822-compliant mail messages using the "subject" and "body"
831  * headers. */
832  add_to_stailq(&MailToAllow, "body");
833  add_to_stailq(&MailToAllow, "subject");
834  /* Cc, In-Reply-To, and References help with not breaking threading on
835  * mailing lists, see https://github.com/neomutt/neomutt/issues/115 */
836  add_to_stailq(&MailToAllow, "cc");
837  add_to_stailq(&MailToAllow, "in-reply-to");
838  add_to_stailq(&MailToAllow, "references");
839 
840  if (STAILQ_EMPTY(&Muttrc))
841  {
842  const char *xdg_cfg_home = mutt_str_getenv("XDG_CONFIG_HOME");
843 
844  if (!xdg_cfg_home && HomeDir)
845  {
846  mutt_buffer_printf(&buf, "%s/.config", HomeDir);
847  xdg_cfg_home = mutt_buffer_string(&buf);
848  }
849 
850  char *config = find_cfg(HomeDir, xdg_cfg_home);
851  if (config)
852  {
853  mutt_list_insert_tail(&Muttrc, config);
854  }
855  }
856  else
857  {
858  struct ListNode *np = NULL;
859  STAILQ_FOREACH(np, &Muttrc, entries)
860  {
861  mutt_buffer_strcpy(&buf, np->data);
862  FREE(&np->data);
864  np->data = mutt_buffer_strdup(&buf);
865  if (access(np->data, F_OK))
866  {
867  mutt_perror(np->data);
868  goto done; // TEST10: neomutt -F missing
869  }
870  }
871  }
872 
873  if (!STAILQ_EMPTY(&Muttrc))
874  {
875  cs_str_string_set(cs, "alias_file", STAILQ_FIRST(&Muttrc)->data, NULL);
876  }
877 
878  /* Process the global rc file if it exists and the user hasn't explicitly
879  * requested not to via "-n". */
880  if (!skip_sys_rc)
881  {
882  do
883  {
885  break;
886 
887  mutt_buffer_printf(&buf, "%s/neomuttrc", SYSCONFDIR);
888  if (access(mutt_buffer_string(&buf), F_OK) == 0)
889  break;
890 
891  mutt_buffer_printf(&buf, "%s/Muttrc", SYSCONFDIR);
892  if (access(mutt_buffer_string(&buf), F_OK) == 0)
893  break;
894 
895  mutt_buffer_printf(&buf, "%s/neomuttrc", PKGDATADIR);
896  if (access(mutt_buffer_string(&buf), F_OK) == 0)
897  break;
898 
899  mutt_buffer_printf(&buf, "%s/Muttrc", PKGDATADIR);
900  } while (false);
901 
902  if (access(mutt_buffer_string(&buf), F_OK) == 0)
903  {
904  if (source_rc(mutt_buffer_string(&buf), &err) != 0)
905  {
906  mutt_error("%s", err.data);
907  need_pause = 1; // TEST11: neomutt (error in /etc/neomuttrc)
908  }
909  }
910  }
911 
912  /* Read the user's initialization file. */
913  struct ListNode *np = NULL;
914  STAILQ_FOREACH(np, &Muttrc, entries)
915  {
916  if (np->data)
917  {
918  if (source_rc(np->data, &err) != 0)
919  {
920  mutt_error("%s", err.data);
921  need_pause = 1; // TEST12: neomutt (error in ~/.neomuttrc)
922  }
923  }
924  }
925 
926  if (execute_commands(commands) != 0)
927  need_pause = 1; // TEST13: neomutt -e broken
928 
929  if (!get_hostname(cs))
930  goto done;
931 
932  if (!C_RealName)
933  {
934  struct passwd *pw = getpwuid(getuid());
935  if (pw)
936  {
937  char name[256];
938  C_RealName = mutt_str_dup(mutt_gecos_name(name, sizeof(name), pw));
939  }
940  }
941  cs_str_initial_set(cs, "real_name", C_RealName, NULL);
942 
943  if (need_pause && !OptNoCurses)
944  {
946  if (mutt_any_key_to_continue(NULL) == 'q')
947  goto done; // TEST14: neomutt -e broken (press 'q')
948  }
949 
950  mutt_file_mkdir(C_Tmpdir, S_IRWXU);
951 
952  mutt_hist_init();
954 
955 #ifdef USE_NOTMUCH
956  if (C_VirtualSpoolFile)
957  {
958  /* Find the first virtual folder and open it */
959  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
961  struct MailboxNode *mp = STAILQ_FIRST(&ml);
962  if (mp)
963  cs_str_string_set(cs, "spool_file", mailbox_path(mp->mailbox), NULL);
965  }
966 #endif
967  rc = 0;
968 
969 done:
970  mutt_buffer_dealloc(&err);
971  mutt_buffer_dealloc(&buf);
972  return rc;
973 }
974 
987  struct Buffer *token, struct Buffer *err)
988 {
989  if (mutt_buffer_len(line) == 0)
990  return 0;
991 
993 
994  mutt_buffer_reset(err);
995 
996  /* Read from the beginning of line->data */
997  mutt_buffer_seek(line, 0);
998 
999  SKIPWS(line->dptr);
1000  while (*line->dptr)
1001  {
1002  if (*line->dptr == '#')
1003  break; /* rest of line is a comment */
1004  if (*line->dptr == ';')
1005  {
1006  line->dptr++;
1007  continue;
1008  }
1010 
1011  struct Command *cmd = NULL;
1012  size_t size = mutt_commands_array(&cmd);
1013  size_t i;
1014  for (i = 0; i < size; i++)
1015  {
1016  if (mutt_str_equal(token->data, cmd[i].name))
1017  {
1018  rc = cmd[i].parse(token, line, cmd[i].data, err);
1019  if (rc != MUTT_CMD_SUCCESS)
1020  { /* -1 Error, +1 Finish */
1021  goto finish; /* Propagate return code */
1022  }
1023  notify_send(NeoMutt->notify, NT_COMMAND, i, (void *) cmd);
1024  break; /* Continue with next command */
1025  }
1026  }
1027  if (i == size)
1028  {
1029  mutt_buffer_printf(err, _("%s: unknown command"), NONULL(token->data));
1030  rc = MUTT_CMD_ERROR;
1031  break; /* Ignore the rest of the line */
1032  }
1033  }
1034 finish:
1035  return rc;
1036 }
1037 
1044 enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
1045 {
1046  if (!line || (*line == '\0'))
1047  return MUTT_CMD_ERROR;
1048 
1049  struct Buffer *line_buffer = mutt_buffer_pool_get();
1050  struct Buffer *token = mutt_buffer_pool_get();
1051 
1052  mutt_buffer_strcpy(line_buffer, line);
1053 
1054  enum CommandResult rc = mutt_parse_rc_buffer(line_buffer, token, err);
1055 
1056  mutt_buffer_pool_release(&line_buffer);
1057  mutt_buffer_pool_release(&token);
1058  return rc;
1059 }
1060 
1068 int mutt_query_variables(struct ListHead *queries, bool show_docs)
1069 {
1070  struct Buffer value = mutt_buffer_make(256);
1071  struct Buffer tmp = mutt_buffer_make(256);
1072  int rc = 0;
1073 
1074  struct ListNode *np = NULL;
1075  STAILQ_FOREACH(np, queries, entries)
1076  {
1077  mutt_buffer_reset(&value);
1078 
1079  struct HashElem *he = cs_subset_lookup(NeoMutt->sub, np->data);
1080  if (!he)
1081  {
1082  mutt_warning(_("No such variable: %s"), np->data);
1083  rc = 1;
1084  continue;
1085  }
1086 
1087  if (he->type & DT_DEPRECATED)
1088  {
1089  mutt_warning(_("Config variable '%s' is deprecated"), np->data);
1090  rc = 1;
1091  continue;
1092  }
1093 
1094  int rv = cs_subset_he_string_get(NeoMutt->sub, he, &value);
1095  if (CSR_RESULT(rv) != CSR_SUCCESS)
1096  {
1097  rc = 1;
1098  continue;
1099  }
1100 
1101  int type = DTYPE(he->type);
1102  if (type == DT_PATH)
1103  mutt_pretty_mailbox(value.data, value.dsize);
1104 
1105  if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) && (type != DT_QUAD))
1106  {
1107  mutt_buffer_reset(&tmp);
1108  pretty_var(value.data, &tmp);
1109  mutt_buffer_strcpy(&value, tmp.data);
1110  }
1111 
1112  dump_config_neo(NeoMutt->sub->cs, he, &value, NULL,
1113  show_docs ? CS_DUMP_SHOW_DOCS : CS_DUMP_NO_FLAGS, stdout);
1114  }
1115 
1116  mutt_buffer_dealloc(&value);
1117  mutt_buffer_dealloc(&tmp);
1118 
1119  return rc; // TEST16: neomutt -Q charset
1120 }
1121 
1131 int mutt_command_complete(char *buf, size_t buflen, int pos, int numtabs)
1132 {
1133  char *pt = buf;
1134  int spaces; /* keep track of the number of leading spaces on the line */
1135  struct MyVar *myv = NULL;
1136 
1137  SKIPWS(buf);
1138  spaces = buf - pt;
1139 
1140  pt = buf + pos - spaces;
1141  while ((pt > buf) && !isspace((unsigned char) *pt))
1142  pt--;
1143 
1144  if (pt == buf) /* complete cmd */
1145  {
1146  /* first TAB. Collect all the matches */
1147  if (numtabs == 1)
1148  {
1149  NumMatched = 0;
1150  mutt_str_copy(UserTyped, pt, sizeof(UserTyped));
1151  memset(Matches, 0, MatchesListsize);
1152  memset(Completed, 0, sizeof(Completed));
1153 
1154  struct Command *c = NULL;
1155  for (size_t num = 0, size = mutt_commands_array(&c); num < size; num++)
1156  candidate(UserTyped, c[num].name, Completed, sizeof(Completed));
1159 
1160  /* All matches are stored. Longest non-ambiguous string is ""
1161  * i.e. don't change 'buf'. Fake successful return this time */
1162  if (UserTyped[0] == '\0')
1163  return 1;
1164  }
1165 
1166  if ((Completed[0] == '\0') && (UserTyped[0] != '\0'))
1167  return 0;
1168 
1169  /* NumMatched will _always_ be at least 1 since the initial
1170  * user-typed string is always stored */
1171  if ((numtabs == 1) && (NumMatched == 2))
1172  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1173  else if ((numtabs > 1) && (NumMatched > 2))
1174  {
1175  /* cycle through all the matches */
1176  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1177  }
1178 
1179  /* return the completed command */
1180  strncpy(buf, Completed, buflen - spaces);
1181  }
1182  else if (mutt_str_startswith(buf, "set") || mutt_str_startswith(buf, "unset") ||
1183  mutt_str_startswith(buf, "reset") || mutt_str_startswith(buf, "toggle"))
1184  { /* complete variables */
1185  static const char *const prefixes[] = { "no", "inv", "?", "&", 0 };
1186 
1187  pt++;
1188  /* loop through all the possible prefixes (no, inv, ...) */
1189  if (mutt_str_startswith(buf, "set"))
1190  {
1191  for (int num = 0; prefixes[num]; num++)
1192  {
1193  if (mutt_str_startswith(pt, prefixes[num]))
1194  {
1195  pt += mutt_str_len(prefixes[num]);
1196  break;
1197  }
1198  }
1199  }
1200 
1201  /* first TAB. Collect all the matches */
1202  if (numtabs == 1)
1203  {
1204  NumMatched = 0;
1205  mutt_str_copy(UserTyped, pt, sizeof(UserTyped));
1206  memset(Matches, 0, MatchesListsize);
1207  memset(Completed, 0, sizeof(Completed));
1208 
1209  struct HashElem *he = NULL;
1210  struct HashElem **list = get_elem_list(NeoMutt->sub->cs);
1211  for (size_t i = 0; list[i]; i++)
1212  {
1213  he = list[i];
1214  const int type = DTYPE(he->type);
1215 
1216  if ((type == DT_SYNONYM) || (type & DT_DEPRECATED))
1217  continue;
1218 
1219  candidate(UserTyped, he->key.strkey, Completed, sizeof(Completed));
1220  }
1221  FREE(&list);
1222 
1223  TAILQ_FOREACH(myv, &MyVars, entries)
1224  {
1225  candidate(UserTyped, myv->name, Completed, sizeof(Completed));
1226  }
1229 
1230  /* All matches are stored. Longest non-ambiguous string is ""
1231  * i.e. don't change 'buf'. Fake successful return this time */
1232  if (UserTyped[0] == '\0')
1233  return 1;
1234  }
1235 
1236  if ((Completed[0] == 0) && UserTyped[0])
1237  return 0;
1238 
1239  /* NumMatched will _always_ be at least 1 since the initial
1240  * user-typed string is always stored */
1241  if ((numtabs == 1) && (NumMatched == 2))
1242  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1243  else if ((numtabs > 1) && (NumMatched > 2))
1244  {
1245  /* cycle through all the matches */
1246  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1247  }
1248 
1249  strncpy(pt, Completed, buf + buflen - pt - spaces);
1250  }
1251  else if (mutt_str_startswith(buf, "exec"))
1252  {
1253  const struct Binding *menu = km_get_table(CurrentMenu);
1254 
1255  if (!menu && (CurrentMenu != MENU_PAGER))
1256  menu = OpGeneric;
1257 
1258  pt++;
1259  /* first TAB. Collect all the matches */
1260  if (numtabs == 1)
1261  {
1262  NumMatched = 0;
1263  mutt_str_copy(UserTyped, pt, sizeof(UserTyped));
1264  memset(Matches, 0, MatchesListsize);
1265  memset(Completed, 0, sizeof(Completed));
1266  for (int num = 0; menu[num].name; num++)
1267  candidate(UserTyped, menu[num].name, Completed, sizeof(Completed));
1268  /* try the generic menu */
1269  if ((Completed[0] == '\0') && (CurrentMenu != MENU_PAGER))
1270  {
1271  menu = OpGeneric;
1272  for (int num = 0; menu[num].name; num++)
1273  candidate(UserTyped, menu[num].name, Completed, sizeof(Completed));
1274  }
1277 
1278  /* All matches are stored. Longest non-ambiguous string is ""
1279  * i.e. don't change 'buf'. Fake successful return this time */
1280  if (UserTyped[0] == '\0')
1281  return 1;
1282  }
1283 
1284  if ((Completed[0] == '\0') && (UserTyped[0] != '\0'))
1285  return 0;
1286 
1287  /* NumMatched will _always_ be at least 1 since the initial
1288  * user-typed string is always stored */
1289  if ((numtabs == 1) && (NumMatched == 2))
1290  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1291  else if ((numtabs > 1) && (NumMatched > 2))
1292  {
1293  /* cycle through all the matches */
1294  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1295  }
1296 
1297  strncpy(pt, Completed, buf + buflen - pt - spaces);
1298  }
1299  else
1300  return 0;
1301 
1302  return 1;
1303 }
1304 
1313 int mutt_label_complete(char *buf, size_t buflen, int numtabs)
1314 {
1315  char *pt = buf;
1316  int spaces; /* keep track of the number of leading spaces on the line */
1317 
1318  if (!Context || !Context->mailbox->label_hash)
1319  return 0;
1320 
1321  SKIPWS(buf);
1322  spaces = buf - pt;
1323 
1324  /* first TAB. Collect all the matches */
1325  if (numtabs == 1)
1326  {
1327  struct HashElem *entry = NULL;
1328  struct HashWalkState state = { 0 };
1329 
1330  NumMatched = 0;
1331  mutt_str_copy(UserTyped, buf, sizeof(UserTyped));
1332  memset(Matches, 0, MatchesListsize);
1333  memset(Completed, 0, sizeof(Completed));
1334  while ((entry = mutt_hash_walk(Context->mailbox->label_hash, &state)))
1335  candidate(UserTyped, entry->key.strkey, Completed, sizeof(Completed));
1337  qsort(Matches, NumMatched, sizeof(char *), (sort_t) mutt_istr_cmp);
1339 
1340  /* All matches are stored. Longest non-ambiguous string is ""
1341  * i.e. don't change 'buf'. Fake successful return this time */
1342  if (UserTyped[0] == '\0')
1343  return 1;
1344  }
1345 
1346  if ((Completed[0] == '\0') && (UserTyped[0] != '\0'))
1347  return 0;
1348 
1349  /* NumMatched will _always_ be at least 1 since the initial
1350  * user-typed string is always stored */
1351  if ((numtabs == 1) && (NumMatched == 2))
1352  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1353  else if ((numtabs > 1) && (NumMatched > 2))
1354  {
1355  /* cycle through all the matches */
1356  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1357  }
1358 
1359  /* return the completed label */
1360  strncpy(buf, Completed, buflen - spaces);
1361 
1362  return 1;
1363 }
1364 
1365 #ifdef USE_NOTMUCH
1366 
1377 bool mutt_nm_query_complete(char *buf, size_t buflen, int pos, int numtabs)
1378 {
1379  char *pt = buf;
1380  int spaces;
1381 
1382  SKIPWS(buf);
1383  spaces = buf - pt;
1384 
1385  pt = (char *) mutt_strn_rfind((char *) buf, pos, "tag:");
1386  if (pt)
1387  {
1388  pt += 4;
1389  if (numtabs == 1)
1390  {
1391  /* First TAB. Collect all the matches */
1393 
1394  /* All matches are stored. Longest non-ambiguous string is ""
1395  * i.e. don't change 'buf'. Fake successful return this time. */
1396  if (UserTyped[0] == '\0')
1397  return true;
1398  }
1399 
1400  if ((Completed[0] == '\0') && (UserTyped[0] != '\0'))
1401  return false;
1402 
1403  /* NumMatched will _always_ be at least 1 since the initial
1404  * user-typed string is always stored */
1405  if ((numtabs == 1) && (NumMatched == 2))
1406  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1407  else if ((numtabs > 1) && (NumMatched > 2))
1408  {
1409  /* cycle through all the matches */
1410  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1411  }
1412 
1413  /* return the completed query */
1414  strncpy(pt, Completed, buf + buflen - pt - spaces);
1415  }
1416  else
1417  return false;
1418 
1419  return true;
1420 }
1421 #endif
1422 
1423 #ifdef USE_NOTMUCH
1424 
1434 bool mutt_nm_tag_complete(char *buf, size_t buflen, int numtabs)
1435 {
1436  if (!buf)
1437  return false;
1438 
1439  char *pt = buf;
1440 
1441  /* Only examine the last token */
1442  char *last_space = strrchr(buf, ' ');
1443  if (last_space)
1444  pt = (last_space + 1);
1445 
1446  /* Skip the +/- */
1447  if ((pt[0] == '+') || (pt[0] == '-'))
1448  pt++;
1449 
1450  if (numtabs == 1)
1451  {
1452  /* First TAB. Collect all the matches */
1454 
1455  /* All matches are stored. Longest non-ambiguous string is ""
1456  * i.e. don't change 'buf'. Fake successful return this time. */
1457  if (UserTyped[0] == '\0')
1458  return true;
1459  }
1460 
1461  if ((Completed[0] == '\0') && (UserTyped[0] != '\0'))
1462  return false;
1463 
1464  /* NumMatched will _always_ be at least 1 since the initial
1465  * user-typed string is always stored */
1466  if ((numtabs == 1) && (NumMatched == 2))
1467  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1468  else if ((numtabs > 1) && (NumMatched > 2))
1469  {
1470  /* cycle through all the matches */
1471  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1472  }
1473 
1474  /* return the completed query */
1475  strncpy(pt, Completed, buf + buflen - pt);
1476 
1477  return true;
1478 }
1479 #endif
1480 
1487 int mutt_var_value_complete(char *buf, size_t buflen, int pos)
1488 {
1489  char *pt = buf;
1490 
1491  if (buf[0] == '\0')
1492  return 0;
1493 
1494  SKIPWS(buf);
1495  const int spaces = buf - pt;
1496 
1497  pt = buf + pos - spaces;
1498  while ((pt > buf) && !isspace((unsigned char) *pt))
1499  pt--;
1500  pt++; /* move past the space */
1501  if (*pt == '=') /* abort if no var before the '=' */
1502  return 0;
1503 
1504  if (mutt_str_startswith(buf, "set"))
1505  {
1506  const char *myvarval = NULL;
1507  char var[256];
1508  mutt_str_copy(var, pt, sizeof(var));
1509  /* ignore the trailing '=' when comparing */
1510  int vlen = mutt_str_len(var);
1511  if (vlen == 0)
1512  return 0;
1513 
1514  var[vlen - 1] = '\0';
1515 
1516  struct HashElem *he = cs_subset_lookup(NeoMutt->sub, var);
1517  if (!he)
1518  {
1519  myvarval = myvar_get(var);
1520  if (myvarval)
1521  {
1522  struct Buffer pretty = mutt_buffer_make(256);
1523  pretty_var(myvarval, &pretty);
1524  snprintf(pt, buflen - (pt - buf), "%s=%s", var, pretty.data);
1525  mutt_buffer_dealloc(&pretty);
1526  return 1;
1527  }
1528  return 0; /* no such variable. */
1529  }
1530  else
1531  {
1532  struct Buffer value = mutt_buffer_make(256);
1533  struct Buffer pretty = mutt_buffer_make(256);
1534  int rc = cs_subset_he_string_get(NeoMutt->sub, he, &value);
1535  if (CSR_RESULT(rc) == CSR_SUCCESS)
1536  {
1537  pretty_var(value.data, &pretty);
1538  snprintf(pt, buflen - (pt - buf), "%s=%s", var, pretty.data);
1539  mutt_buffer_dealloc(&value);
1540  mutt_buffer_dealloc(&pretty);
1541  return 0;
1542  }
1543  mutt_buffer_dealloc(&value);
1544  mutt_buffer_dealloc(&pretty);
1545  return 1;
1546  }
1547  }
1548  return 0;
1549 }
mutt_strn_rfind
const char * mutt_strn_rfind(const char *haystack, size_t haystack_length, const char *needle)
Find last instance of a substring.
Definition: string.c:920
log_queue_flush
void log_queue_flush(log_dispatcher_t disp)
Replay the log queue.
Definition: logging.c:348
lib.h
DT_QUAD
#define DT_QUAD
quad-option (no/yes/ask-no/ask-yes)
Definition: types.h:37
TagTransforms
struct HashTable * TagTransforms
Lookup table of alternative tag names.
Definition: tags.c:38
mutt_ch_set_charset
void mutt_ch_set_charset(const char *charset)
Update the records for a new character set.
Definition: charset.c:1003
find_cfg
static char * find_cfg(const char *home, const char *xdg_cfg_home)
Find a config file.
Definition: init.c:242
mutt_istr_cmp
int mutt_istr_cmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:580
UnSubscribedLists
struct RegexList UnSubscribedLists
List of regexes to blacklist false matches in SubscribedLists.
Definition: globals.c:49
alias_init
void alias_init(void)
Set up the Alias globals.
Definition: alias.c:662
Completed
static char Completed[256]
Definition: init.c:87
mutt_parse_rc_line
enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: init.c:1044
cs_subset_lookup
struct HashElem * cs_subset_lookup(const struct ConfigSubset *sub, const char *name)
Find an inherited config item.
Definition: subset.c:168
myvar.h
InlineAllow
struct ListHead InlineAllow
List of inline types to counted.
Definition: mutt_parse.c:41
mutt_hash_new
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition: hash.c:251
MUTT_TOKEN_PATTERN
#define MUTT_TOKEN_PATTERN
~%=!| are terms (for patterns)
Definition: mutt.h:75
mutt_hist_free
void mutt_hist_free(void)
Free all the history lists.
Definition: history.c:424
MailboxNode
List of Mailboxes.
Definition: mailbox.h:152
mutt_mem_calloc
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
MyVar
A user-set variable.
Definition: myvar.h:31
_
#define _(a)
Definition: message.h:28
NONULL
#define NONULL(x)
Definition: string2.h:37
C_Hostname
WHERE char * C_Hostname
Config: Fully-qualified domain name of this machine.
Definition: mutt_globals.h:91
MUTT_TOKEN_BACKTICK_VARS
#define MUTT_TOKEN_BACKTICK_VARS
Expand variables within backticks.
Definition: mutt.h:78
Binding
Mapping between a user key and a function.
Definition: keymap.h:120
C_RealName
WHERE char * C_RealName
Config: Real name of the user.
Definition: mutt_globals.h:105
MUTT_TOKEN_SEMICOLON
#define MUTT_TOKEN_SEMICOLON
Don't treat ; as special.
Definition: mutt.h:77
imap_init
void imap_init(void)
Setup feature commands.
Definition: imap.c:82
sb_shutdown
void sb_shutdown(void)
Clean up the Sidebar.
Definition: sidebar.c:199
DT_DEPRECATED
#define DT_DEPRECATED
Config item shouldn't be used any more.
Definition: types.h:79
HashElem::key
union HashKey key
Key representing the data.
Definition: hash.h:46
mutt_commands_array
size_t mutt_commands_array(struct Command **first)
Get Commands array.
Definition: mutt_commands.c:185
XDG_CONFIG_DIRS
@ XDG_CONFIG_DIRS
XDG system dir: /etc/xdg.
Definition: protos.h:48
MUTT_TOKEN_CONDENSE
#define MUTT_TOKEN_CONDENSE
^(char) to control chars (macros)
Definition: mutt.h:72
C_VirtualSpoolFile
bool C_VirtualSpoolFile
Config: (notmuch) Use the first virtual mailbox as a spool file.
Definition: config.c:51
ListNode
A List node for strings.
Definition: list.h:34
Buffer
String manipulation buffer.
Definition: buffer.h:33
source_rc
int source_rc(const char *rcfile_path, struct Buffer *err)
Read an initialization file.
Definition: command_parse.c:426
mutt_buffer_seek
void mutt_buffer_seek(struct Buffer *buf, size_t offset)
set current read/write position to offset from beginning
Definition: buffer.c:466
mutt_file_fclose
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
mutt_buffer_dealloc
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
km_get_table
const struct Binding * km_get_table(enum MenuType menu)
Lookup a menu's keybindings.
Definition: keymap.c:1306
CSR_SUCCESS
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
CSR_RESULT
#define CSR_RESULT(x)
Definition: set.h:52
sb_init
void sb_init(void)
Set up the Sidebar.
Definition: sidebar.c:188
NeoMutt::notify
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
alias_shutdown
void alias_shutdown(void)
Clean up the Alias globals.
Definition: alias.c:670
Ignore
struct ListHead Ignore
List of header patterns to ignore.
Definition: globals.c:45
mutt_grouplist_free
void mutt_grouplist_free(void)
Free GroupList singleton resource.
Definition: group.c:55
DTYPE
#define DTYPE(x)
Mask for the Data Type.
Definition: types.h:44
mutt_hist_read_file
void mutt_hist_read_file(void)
Read the History from a file.
Definition: history.c:568
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
mutt_buffer_init
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
neomutt_mailboxlist_get_all
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:160
MUTT_TOKEN_QUESTION
#define MUTT_TOKEN_QUESTION
Treat '?' as a special.
Definition: mutt.h:80
mutt_parse.h
lib.h
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_globals.h
candidate
static void candidate(char *user, const char *src, char *dest, size_t dlen)
helper function for completion
Definition: init.c:124
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
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
options.h
STAILQ_FIRST
#define STAILQ_FIRST(head)
Definition: queue.h:347
mutt_perror
#define mutt_perror(...)
Definition: logging.h:85
MUTT_TOKEN_NO_FLAGS
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:70
getdnsdomainname
int getdnsdomainname(struct Buffer *result)
Lookup the host's name using DNS.
Definition: getdomain.c:118
SubscribedLists
struct RegexList SubscribedLists
List of regexes to match subscribed mailing lists.
Definition: globals.c:52
dump_config_neo
void dump_config_neo(struct ConfigSet *cs, struct HashElem *he, struct Buffer *value, struct Buffer *initial, ConfigDumpFlags flags, FILE *fp)
Dump the config in the style of NeoMutt.
Definition: dump.c:106
Buffer::dptr
char * dptr
Current read/write position.
Definition: buffer.h:36
list_free_t
void(* list_free_t)(void **ptr)
Prototype for a function to free List data.
Definition: list.h:45
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
functions.h
MailboxNode::mailbox
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:154
OptNoCurses
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:48
mutt_buffer_reset
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
Binding::name
const char * name
name of the function
Definition: keymap.h:122
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
sort_t
int(* sort_t)(const void *a, const void *b)
Prototype for a function to compare two emails.
Definition: sort.h:50
myvar_get
const char * myvar_get(const char *var)
Get the value of a "my_" variable.
Definition: myvar.c:73
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
Mailbox::label_hash
struct HashTable * label_hash
Hash Table for x-labels.
Definition: mailbox.h:129
clear_source_stack
void clear_source_stack(void)
Free memory from the stack used for the souce command.
Definition: command_parse.c:2149
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
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_get_hook_type
HookFlags mutt_get_hook_type(const char *name)
Find a hook by name.
Definition: init.c:700
execute_commands
static int execute_commands(struct ListHead *p)
Execute a set of NeoMutt commands.
Definition: init.c:210
SKIPWS
#define SKIPWS(ch)
Definition: string2.h:46
mutt_istr_equal
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
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
get_elem_list
struct HashElem ** get_elem_list(struct ConfigSet *cs)
Create a sorted list of all config items.
Definition: subset.c:64
mutt_label_complete
int mutt_label_complete(char *buf, size_t buflen, int numtabs)
Complete a label name.
Definition: init.c:1313
lib.h
NoSpamList
struct RegexList NoSpamList
List of regexes to whitelist non-spam emails.
Definition: globals.c:43
MUTT_RL_NO_FLAGS
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition: file.h:39
command_parse.h
C_Suspend
WHERE bool C_Suspend
Config: Allow the user to suspend NeoMutt using '^Z'.
Definition: mutt_globals.h:165
protos.h
mutt_extract_token
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:393
mutt_comp_init
void mutt_comp_init(void)
Setup feature commands.
Definition: compress.c:66
mutt_any_key_to_continue
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:605
filter_create
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
Command
A user-callable command.
Definition: mutt_commands.h:45
mutt_buffer_addch
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
NT_COMMAND
@ NT_COMMAND
A Command has been executed, Command.
Definition: notify_type.h:36
AttachmentMarker
WHERE char AttachmentMarker[256]
Unique ANSI string to mark PGP messages in an email.
Definition: mutt_globals.h:46
HashKey::strkey
const char * strkey
String key.
Definition: hash.h:36
mutt_buffer_pool_get
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
MUTT_TOKEN_COMMENT
#define MUTT_TOKEN_COMMENT
Don't reap comments.
Definition: mutt.h:76
get_hostname
static bool get_hostname(struct ConfigSet *cs)
Find the Fully-Qualified Domain Name.
Definition: init.c:315
init.h
mutt_buffer_copy
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition: buffer.c:445
lib.h
keymap.h
DT_SYNONYM
#define DT_SYNONYM
synonym for another variable
Definition: types.h:42
lib.h
DT_NUMBER
#define DT_NUMBER
a number
Definition: types.h:35
muttlib.h
add_to_stailq
void add_to_stailq(struct ListHead *head, const char *str)
Add a string to a list.
Definition: muttlib.c:1704
mutt_command_complete
int mutt_command_complete(char *buf, size_t buflen, int pos, int numtabs)
Complete a command name.
Definition: init.c:1131
MailLists
struct RegexList MailLists
List of regexes to match mailing lists.
Definition: globals.c:50
InlineExclude
struct ListHead InlineExclude
List of inline types to ignore.
Definition: mutt_parse.c:42
TokenFlags
uint16_t TokenFlags
Flags for mutt_extract_token(), e.g. MUTT_TOKEN_EQUAL.
Definition: mutt.h:69
mutt_menu.h
mutt_nm_tag_complete
bool mutt_nm_tag_complete(char *buf, size_t buflen, int numtabs)
Complete to the nearest notmuch tag.
Definition: init.c:1434
lib.h
nm_tags
static char ** nm_tags
Definition: init.c:94
lib.h
mutt_parse_rc_buffer
enum CommandResult mutt_parse_rc_buffer(struct Buffer *line, struct Buffer *token, struct Buffer *err)
Parse a line of user config.
Definition: init.c:986
CurrentMenu
WHERE enum MenuType CurrentMenu
Current Menu, e.g. MENU_PAGER.
Definition: mutt_globals.h:77
LastFolder
WHERE char * LastFolder
Previously selected mailbox.
Definition: mutt_globals.h:55
ProtectedHeaderMarker
WHERE char ProtectedHeaderMarker[256]
Unique ANSI string to mark protected headers in an email.
Definition: mutt_globals.h:47
ConfigSubset::cs
struct ConfigSet * cs
Parent ConfigSet.
Definition: subset.h:51
DT_LONG
#define DT_LONG
a number (long)
Definition: types.h:33
pretty_var
size_t pretty_var(const char *str, struct Buffer *buf)
Escape and stringify a config item value.
Definition: dump.c:83
nm_db_longrun_init
void nm_db_longrun_init(struct Mailbox *m, bool writable)
Start a long transaction.
Definition: db.c:291
MUTT_NOTMUCH
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition: mailbox.h:54
DT_PATH
#define DT_PATH
a path to a file/directory
Definition: types.h:36
mutt_menu_init
void mutt_menu_init(void)
Initialise all the Menus.
Definition: menu.c:945
Colors
Definition: color.h:129
Context::mailbox
struct Mailbox * mailbox
Definition: context.h:50
mutt_list_free_type
void mutt_list_free_type(struct ListHead *h, list_free_t fn)
Free a List of type.
Definition: list.c:144
mutt_mem_realloc
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
nm_db_longrun_done
void nm_db_longrun_done(struct Mailbox *m)
Finish a long transaction.
Definition: db.c:306
mutt_buffer_concat_path
size_t mutt_buffer_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:374
nm_get_all_tags
int nm_get_all_tags(struct Mailbox *m, char **tag_list, int *tag_count)
Fill a list with all notmuch tags.
Definition: notmuch.c:2046
mutt_rand64
uint64_t mutt_rand64(void)
Create a 64-bit random number.
Definition: random.c:129
mutt_attachmatch_free
void mutt_attachmatch_free(struct AttachMatch **ptr)
Free an AttachMatch - Implements list_free_t.
Definition: mutt_parse.c:243
mutt_debug
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
HookFlags
uint32_t HookFlags
Flags for mutt_parse_hook(), e.g. MUTT_FOLDER_HOOK.
Definition: hook.h:43
mutt_hash_walk
struct HashElem * mutt_hash_walk(const struct HashTable *table, struct HashWalkState *state)
Iterate through all the HashElem's in a Hash Table.
Definition: hash.c:479
MUTT_CMD_SUCCESS
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: mutt_commands.h:38
HashElem::type
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:45
C_Tmpdir
char * C_Tmpdir
Config: Directory for temporary files.
Definition: file.c:56
mutt_colors_free
void mutt_colors_free(struct Colors **ptr)
Free all the colours.
Definition: color.c:356
MUTT_TOKEN_EQUAL
#define MUTT_TOKEN_EQUAL
Treat '=' as a special.
Definition: mutt.h:71
mutt_regexlist_free
void mutt_regexlist_free(struct RegexList *rl)
Free a RegexList object.
Definition: regex.c:171
mutt_buffer_expand_path
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:323
mutt_str_len
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
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
MUTT_CMD_ERROR
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: mutt_commands.h:36
HashWalkState
Cursor to iterate through a Hash Table.
Definition: hash.h:119
mutt_date_epoch
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:416
mutt_hist_init
void mutt_hist_init(void)
Create a set of empty History ring buffers.
Definition: history.c:447
Matches
static const char ** Matches
Definition: init.c:88
lib.h
filter_wait
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
UnMailLists
struct RegexList UnMailLists
List of regexes to blacklist false matches in MailLists.
Definition: globals.c:51
Command::data
intptr_t data
Data or flags to pass to the command.
Definition: mutt_commands.h:59
CommandResult
CommandResult
Error codes for command_t parse functions.
Definition: mutt_commands.h:34
DT_BOOL
#define DT_BOOL
boolean option
Definition: types.h:30
lib.h
mutt_commands_init
void mutt_commands_init(void)
mutt_file_mkdir
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:875
STAILQ_HEAD_INITIALIZER
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
mutt_nm_query_complete
bool mutt_nm_query_complete(char *buf, size_t buflen, int pos, int numtabs)
Complete to the nearest notmuch tag.
Definition: init.c:1377
lib.h
lib.h
mutt_commands_free
void mutt_commands_free(void)
Free Commands array.
Definition: mutt_commands.c:175
MUTT_HASH_NO_FLAGS
#define MUTT_HASH_NO_FLAGS
No flags are set.
Definition: hash.h:97
HashElem
The item stored in a Hash Table.
Definition: hash.h:43
mutt_set_xdg_path
int mutt_set_xdg_path(enum XdgType type, struct Buffer *buf)
Find an XDG path or its fallback.
Definition: muttlib.c:1501
MUTT_CMD_WARNING
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition: mutt_commands.h:37
parse_my_hdr
enum CommandResult parse_my_hdr(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'my_hdr' command - Implements Command::parse()
Definition: command_parse.c:1005
HomeDir
char * HomeDir
User's home directory.
Definition: mutt_globals.h:49
mutt_lua_init
void mutt_lua_init(void)
Setup feature commands.
Definition: mutt_lua.c:452
sort.h
MUTT_HASH_STRCASECMP
#define MUTT_HASH_STRCASECMP
use strcasecmp() to compare keys
Definition: hash.h:98
mutt_mem_malloc
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
ShortHostname
WHERE char * ShortHostname
Short version of the hostname.
Definition: mutt_globals.h:50
MailToAllow
struct ListHead MailToAllow
List of permitted fields in a mailto: url.
Definition: globals.c:47
mutt_buffer_fix_dptr
void mutt_buffer_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:181
mutt_strn_dup
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:548
MENU_MAIN
@ MENU_MAIN
Index panel (list of emails)
Definition: keymap.h:80
NeoMutt
Container for Accounts, Notifications.
Definition: neomutt.h:36
mutt.h
MUTT_TOKEN_QUOTE
#define MUTT_TOKEN_QUOTE
Don't interpret quotes.
Definition: mutt.h:74
mutt_parse_hook
enum CommandResult mutt_parse_hook(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'hook' family of commands - Implements Command::parse()
Definition: hook.c:85
cs_subset_he_string_get
int cs_subset_he_string_get(const struct ConfigSubset *sub, struct HashElem *he, struct Buffer *result)
Get a config item as a string.
Definition: subset.c:341
ConfigSet
Container for lots of config items.
Definition: set.h:228
mutt_lua.h
cs_subset_str_string_get
int cs_subset_str_string_get(const struct ConfigSubset *sub, const char *name, struct Buffer *result)
Get a config item as a string.
Definition: subset.c:357
MatchesListsize
static int MatchesListsize
Definition: init.c:90
mutt_buffer_len
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
mutt_gecos_name
char * mutt_gecos_name(char *dest, size_t destlen, struct passwd *pw)
Lookup a user's real name in /etc/passwd.
Definition: muttlib.c:362
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
nm_init
void nm_init(void)
Setup feature commands.
Definition: notmuch.c:91
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
CurrentFolder
WHERE char * CurrentFolder
Currently selected mailbox.
Definition: mutt_globals.h:54
Command::name
const char * name
Name of the command.
Definition: mutt_commands.h:47
CS_DUMP_SHOW_DOCS
#define CS_DUMP_SHOW_DOCS
Show one-liner documentation for the config item.
Definition: dump.h:45
mutt_delete_hooks
void mutt_delete_hooks(HookFlags type)
Delete matching hooks.
Definition: hook.c:307
MUTT_TOKEN_NOSHELL
#define MUTT_TOKEN_NOSHELL
Don't expand environment variables.
Definition: mutt.h:79
mutt_buffer_addstr
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
lib.h
matches_ensure_morespace
static void matches_ensure_morespace(int current)
Allocate more space for auto-completion.
Definition: init.c:101
mutt_var_value_complete
int mutt_var_value_complete(char *buf, size_t buflen, int pos)
Complete a variable/value.
Definition: init.c:1487
mutt_buffer_strdup
char * mutt_buffer_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:432
mutt_grouplist_init
void mutt_grouplist_init(void)
Initialize the GroupList singleton.
Definition: group.c:45
mutt_commands.h
getmailname
static char * getmailname(void)
Try to retrieve the FQDN from mailname files.
Definition: init.c:283
mailbox_path
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:206
mutt_ch_get_langinfo_charset
char * mutt_ch_get_langinfo_charset(void)
Get the user's choice of character set.
Definition: charset.c:462
TagFormats
WHERE struct HashTable * TagFormats
Hash Table of tag-formats (tag -> format string)
Definition: mutt_globals.h:59
lib.h
SpamList
struct ReplaceList SpamList
List of regexes and patterns to match spam emails.
Definition: globals.c:44
mutt_replacelist_free
void mutt_replacelist_free(struct ReplaceList *rl)
Free a ReplaceList object.
Definition: regex.c:448
C_Charset
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:53
mutt_pretty_mailbox
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:523
Buffer::data
char * data
Pointer to data.
Definition: buffer.h:35
IS_SPACE
#define IS_SPACE(ch)
Definition: string2.h:38
lib.h
mutt_str_startswith
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
UnIgnore
struct ListHead UnIgnore
List of header patterns to unignore (see)
Definition: globals.c:46
lib.h
MyVar::name
char * name
Name of user variable.
Definition: myvar.h:33
MyVars
struct MyVarList MyVars
List of all the user's custom config variables.
Definition: myvar.c:34
OpGeneric
const struct Binding OpGeneric[]
Key bindings for the generic menu.
Definition: functions.c:53
UserTyped
static char UserTyped[1024]
Definition: init.c:84
mutt_buffer_printf
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
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_warning
#define mutt_warning(...)
Definition: logging.h:82
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_TOKEN_MINUS
#define MUTT_TOKEN_MINUS
Treat '-' as a special.
Definition: mutt.h:82
SubjectRegexList
struct ReplaceList SubjectRegexList
List of regexes to tidy the view of the email's subject.
Definition: globals.c:53
MUTT_TOKEN_PLUS
#define MUTT_TOKEN_PLUS
Treat '+' as a special.
Definition: mutt.h:81
MENU_PAGER
@ MENU_PAGER
Pager pager (email viewer)
Definition: keymap.h:81
mutt_buffer_strcpy
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
NumMatched
static int NumMatched
Definition: init.c:86
AttachAllow
struct ListHead AttachAllow
List of attachment types to be counted.
Definition: mutt_parse.c:39
neomutt_mailboxlist_clear
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:137
lib.h
mutt_hash_free
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:447
MUTT_TOKEN_SPACE
#define MUTT_TOKEN_SPACE
Don't treat whitespace as a term.
Definition: mutt.h:73
Command::parse
enum CommandResult(* parse)(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Function to parse a command.
Definition: mutt_commands.h:57
mutt_parse_idxfmt_hook
enum CommandResult mutt_parse_idxfmt_hook(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'index-format-hook' command - Implements Command::parse()
Definition: hook.c:351
complete_all_nm_tags
static int complete_all_nm_tags(const char *pt)
Pass a list of Notmuch tags to the completion code.
Definition: init.c:153
MUTT_HOOK_NO_FLAGS
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:44
mutt_keys_free
void mutt_keys_free(void)
Free the key maps.
Definition: keymap.c:1698
mutt_error
#define mutt_error(...)
Definition: logging.h:84
AttachExclude
struct ListHead AttachExclude
List of attachment types to be ignored.
Definition: mutt_parse.c:40
mutt_file_read_line
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, ReadLineFlags flags)
Read a line from a file.
Definition: file.c:667
mutt_str_copy
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716