NeoMutt  2020-06-26-89-g172cd3
Teaching an old dog new tricks
DOXYGEN
init.c File Reference

Config/command parsing. More...

#include "config.h"
#include <ctype.h>
#include <inttypes.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include <unistd.h>
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "alias/lib.h"
#include "conn/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "init.h"
#include "command_parse.h"
#include "context.h"
#include "functions.h"
#include "keymap.h"
#include "mutt_commands.h"
#include "mutt_globals.h"
#include "mutt_menu.h"
#include "mutt_parse.h"
#include "muttlib.h"
#include "myvar.h"
#include "options.h"
#include "protos.h"
#include "sort.h"
#include "autocrypt/lib.h"
#include "compress/lib.h"
#include "hcache/lib.h"
#include "history/lib.h"
#include "imap/lib.h"
#include "maildir/lib.h"
#include "mbox/lib.h"
#include "ncrypt/lib.h"
#include "nntp/lib.h"
#include "notmuch/lib.h"
#include "pop/lib.h"
#include "send/lib.h"
#include "store/lib.h"
#include "sidebar/lib.h"
+ Include dependency graph for init.c:

Go to the source code of this file.

Functions

bool config_init_main (struct ConfigSet *cs)
 Register main config variables. More...
 
static void matches_ensure_morespace (int current)
 Allocate more space for auto-completion. More...
 
static void candidate (char *user, const char *src, char *dest, size_t dlen)
 helper function for completion More...
 
static int complete_all_nm_tags (const char *pt)
 Pass a list of Notmuch tags to the completion code. More...
 
static int execute_commands (struct ListHead *p)
 Execute a set of NeoMutt commands. More...
 
static char * find_cfg (const char *home, const char *xdg_cfg_home)
 Find a config file. More...
 
static char * getmailname (void)
 Try to retrieve the FQDN from mailname files. More...
 
static bool get_hostname (struct ConfigSet *cs)
 Find the Fully-Qualified Domain Name. More...
 
const struct Commandmutt_command_get (const char *s)
 Get a Command by its name. More...
 
void mutt_commands_apply (void *data, void(*application)(void *, const struct Command *))
 Run a callback function on every Command. More...
 
int mutt_extract_token (struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
 Extract one token from a string. More...
 
void mutt_opts_free (void)
 clean up before quitting More...
 
HookFlags mutt_get_hook_type (const char *name)
 Find a hook by name. More...
 
int mutt_init (struct ConfigSet *cs, bool skip_sys_rc, struct ListHead *commands)
 Initialise NeoMutt. More...
 
enum CommandResult mutt_parse_rc_buffer (struct Buffer *line, struct Buffer *token, struct Buffer *err)
 Parse a line of user config. More...
 
enum CommandResult mutt_parse_rc_line (const char *line, struct Buffer *err)
 Parse a line of user config. More...
 
int mutt_query_variables (struct ListHead *queries)
 Implement the -Q command line flag. More...
 
int mutt_command_complete (char *buf, size_t buflen, int pos, int numtabs)
 Complete a command name. More...
 
int mutt_label_complete (char *buf, size_t buflen, int numtabs)
 Complete a label name. More...
 
bool mutt_nm_query_complete (char *buf, size_t buflen, int pos, int numtabs)
 Complete to the nearest notmuch tag. More...
 
bool mutt_nm_tag_complete (char *buf, size_t buflen, int numtabs)
 Complete to the nearest notmuch tag. More...
 
int mutt_var_value_complete (char *buf, size_t buflen, int pos)
 Complete a variable/value. More...
 
struct ConfigSetinit_config (size_t size)
 Initialise the config system. More...
 
int charset_validator (const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
 Validate the "charset" config variable - Implements ConfigDef::validator() More...
 
int hcache_validator (const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
 Validate the "header_cache_backend" config variable - Implements ConfigDef::validator() More...
 
int compress_method_validator (const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
 Validate the "header_cache_compress_method" config variable - Implements ConfigDef::validator() More...
 
int compress_level_validator (const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
 Validate the "header_cache_compress_level" config variable - Implements ConfigDef::validator() More...
 
int pager_validator (const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
 Check for config variables that can't be set from the pager - Implements ConfigDef::validator() More...
 
int multipart_validator (const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
 Validate the "show_multipart_alternative" config variable - Implements ConfigDef::validator() More...
 
int reply_validator (const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
 Validate the "reply_regex" config variable - Implements ConfigDef::validator() More...
 

Variables

static char UserTyped [1024] = { 0 }
 
static int NumMatched = 0
 
static char Completed [256] = { 0 }
 
static const char ** Matches
 
static int MatchesListsize = 512
 
static char ** nm_tags
 

Detailed Description

Config/command parsing.

Authors
  • Michael R. Elkins
  • Pietro Cerutti

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file init.c.

Function Documentation

◆ config_init_main()

bool config_init_main ( struct ConfigSet cs)

Register main config variables.

Definition at line 305 of file mutt_config.c.

306 {
307  return cs_register_variables(cs, MainVars, 0);
308 }
struct ConfigDef MainVars[]
Definition: mutt_config.c:80
bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[], int flags)
Register a set of config items.
Definition: set.c:279
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ matches_ensure_morespace()

static void matches_ensure_morespace ( int  current)
static

Allocate more space for auto-completion.

Parameters
currentCurrent allocation

Definition at line 102 of file init.c.

103 {
104  if (current <= (MatchesListsize - 2))
105  return;
106 
107  int base_space = 512; // Enough space for all of the config items
108  int extra_space = MatchesListsize - base_space;
109  extra_space *= 2;
110  const int space = base_space + extra_space;
111  mutt_mem_realloc(&Matches, space * sizeof(char *));
112  memset(&Matches[current + 1], 0, space - current);
113  MatchesListsize = space;
114 }
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
static int MatchesListsize
Definition: init.c:89
static const char ** Matches
Definition: init.c:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ candidate()

static void candidate ( char *  user,
const char *  src,
char *  dest,
size_t  dlen 
)
static

helper function for completion

Parameters
userUser entered data for completion
srcCandidate for completion
destCompletion result gets here
dlenLength of dest buffer

Changes the dest buffer if necessary/possible to aid completion.

Definition at line 125 of file init.c.

126 {
127  if (!dest || !user || !src)
128  return;
129 
130  if (strstr(src, user) != src)
131  return;
132 
134  Matches[NumMatched++] = src;
135  if (dest[0] == '\0')
136  mutt_str_copy(dest, src, dlen);
137  else
138  {
139  int l;
140  for (l = 0; src[l] && src[l] == dest[l]; l++)
141  ; // do nothing
142 
143  dest[l] = '\0';
144  }
145 }
static int NumMatched
Definition: init.c:85
static void matches_ensure_morespace(int current)
Allocate more space for auto-completion.
Definition: init.c:102
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:721
static const char ** Matches
Definition: init.c:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ complete_all_nm_tags()

static int complete_all_nm_tags ( const char *  pt)
static

Pass a list of Notmuch tags to the completion code.

Parameters
ptList of all Notmuch tags
Return values
0Success
-1Error

Definition at line 154 of file init.c.

155 {
156  int tag_count_1 = 0;
157  int tag_count_2 = 0;
158 
159  NumMatched = 0;
160  mutt_str_copy(UserTyped, pt, sizeof(UserTyped));
161  memset(Matches, 0, MatchesListsize);
162  memset(Completed, 0, sizeof(Completed));
163 
165 
166  /* Work out how many tags there are. */
167  if (nm_get_all_tags(Context->mailbox, NULL, &tag_count_1) || (tag_count_1 == 0))
168  goto done;
169 
170  /* Free the old list, if any. */
171  if (nm_tags)
172  {
173  for (int i = 0; nm_tags[i]; i++)
174  FREE(&nm_tags[i]);
175  FREE(&nm_tags);
176  }
177  /* Allocate a new list, with sentinel. */
178  nm_tags = mutt_mem_malloc((tag_count_1 + 1) * sizeof(char *));
179  nm_tags[tag_count_1] = NULL;
180 
181  /* Get all the tags. */
182  if (nm_get_all_tags(Context->mailbox, nm_tags, &tag_count_2) || (tag_count_1 != tag_count_2))
183  {
184  FREE(&nm_tags);
185  nm_tags = NULL;
187  return -1;
188  }
189 
190  /* Put them into the completion machinery. */
191  for (int num = 0; num < tag_count_1; num++)
192  {
193  candidate(UserTyped, nm_tags[num], Completed, sizeof(Completed));
194  }
195 
198 
199 done:
201  return 0;
202 }
The "current" mailbox.
Definition: context.h:37
static int NumMatched
Definition: init.c:85
static char ** nm_tags
Definition: init.c:93
void nm_db_longrun_init(struct Mailbox *m, bool writable)
Start a long transaction.
Definition: db.c:289
struct Mailbox * mailbox
Definition: context.h:50
static char Completed[256]
Definition: init.c:86
static int MatchesListsize
Definition: init.c:89
static void matches_ensure_morespace(int current)
Allocate more space for auto-completion.
Definition: init.c:102
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
void nm_db_longrun_done(struct Mailbox *m)
Finish a long transaction.
Definition: db.c:304
int nm_get_all_tags(struct Mailbox *m, char **tag_list, int *tag_count)
Fill a list with all notmuch tags.
Definition: notmuch.c:2066
static char UserTyped[1024]
Definition: init.c:83
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:721
static const char ** Matches
Definition: init.c:87
#define FREE(x)
Definition: memory.h:40
static void candidate(char *user, const char *src, char *dest, size_t dlen)
helper function for completion
Definition: init.c:125
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ execute_commands()

static int execute_commands ( struct ListHead *  p)
static

Execute a set of NeoMutt commands.

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

Definition at line 211 of file init.c.

212 {
213  int rc = 0;
214  struct Buffer *err = mutt_buffer_pool_get();
215 
216  struct ListNode *np = NULL;
217  STAILQ_FOREACH(np, p, entries)
218  {
219  enum CommandResult rc2 = mutt_parse_rc_line(np->data, err);
220  if (rc2 == MUTT_CMD_ERROR)
221  mutt_error(_("Error in command line: %s"), mutt_b2s(err));
222  else if (rc2 == MUTT_CMD_WARNING)
223  mutt_warning(_("Warning in command line: %s"), mutt_b2s(err));
224 
225  if ((rc2 == MUTT_CMD_ERROR) || (rc2 == MUTT_CMD_WARNING))
226  {
228  return -1;
229  }
230  }
232 
233  return rc;
234 }
#define mutt_warning(...)
Definition: logging.h:82
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
CommandResult
Error codes for command_t parse functions.
Definition: mutt_commands.h:33
Error: Can&#39;t help the user.
Definition: mutt_commands.h:35
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: init.c:1049
#define _(a)
Definition: message.h:28
#define mutt_b2s(buf)
Definition: buffer.h:41
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
char * data
String.
Definition: list.h:36
Warning: Help given to the user.
Definition: mutt_commands.h:36
#define mutt_error(...)
Definition: logging.h:84
A List node for strings.
Definition: list.h:34
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ find_cfg()

static char* find_cfg ( const char *  home,
const char *  xdg_cfg_home 
)
static

Find a config file.

Parameters
homeUser's home directory
xdg_cfg_homeXDG home directory
Return values
ptrSuccess, first matching directory
NULLError, no matching directories

Definition at line 243 of file init.c.

244 {
245  const char *names[] = {
246  "neomuttrc",
247  "muttrc",
248  NULL,
249  };
250 
251  const char *locations[][2] = {
252  { xdg_cfg_home, "neomutt/" },
253  { xdg_cfg_home, "mutt/" },
254  { home, ".neomutt/" },
255  { home, ".mutt/" },
256  { home, "." },
257  { NULL, NULL },
258  };
259 
260  for (int i = 0; locations[i][0] || locations[i][1]; i++)
261  {
262  if (!locations[i][0])
263  continue;
264 
265  for (int j = 0; names[j]; j++)
266  {
267  char buf[256];
268 
269  snprintf(buf, sizeof(buf), "%s/%s%s", locations[i][0], locations[i][1], names[j]);
270  if (access(buf, F_OK) == 0)
271  return mutt_str_dup(buf);
272  }
273  }
274 
275  return NULL;
276 }
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getmailname()

static char* getmailname ( void  )
static

Try to retrieve the FQDN from mailname files.

Return values
ptrHeap allocated string with the FQDN
NULLif no valid mailname file could be read

Definition at line 284 of file init.c.

285 {
286  char *mailname = NULL;
287  static const char *mn_files[] = { "/etc/mailname", "/etc/mail/mailname" };
288 
289  for (size_t i = 0; i < mutt_array_size(mn_files); i++)
290  {
291  FILE *fp = mutt_file_fopen(mn_files[i], "r");
292  if (!fp)
293  continue;
294 
295  size_t len = 0;
296  mailname = mutt_file_read_line(NULL, &len, fp, NULL, 0);
297  mutt_file_fclose(&fp);
298  if (mailname && *mailname)
299  break;
300 
301  FREE(&mailname);
302  }
303 
304  return mailname;
305 }
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, int flags)
Read a line from a file.
Definition: file.c:667
#define mutt_array_size(x)
Definition: memory.h:33
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
#define FREE(x)
Definition: memory.h:40
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_hostname()

static bool get_hostname ( struct ConfigSet cs)
static

Find the Fully-Qualified Domain Name.

Return values
trueSuccess
falseError, failed to find any name

Use several methods to try to find the Fully-Qualified domain name of this host. If the user has already configured a hostname, this function will use it.

Definition at line 316 of file init.c.

317 {
318  char *str = NULL;
319  struct utsname utsname;
320 
321  if (C_Hostname)
322  {
323  str = C_Hostname;
324  }
325  else
326  {
327  /* The call to uname() shouldn't fail, but if it does, the system is horribly
328  * broken, and the system's networking configuration is in an unreliable
329  * state. We should bail. */
330  if ((uname(&utsname)) == -1)
331  {
332  mutt_perror(_("unable to determine nodename via uname()"));
333  return false; // TEST09: can't test
334  }
335 
336  str = utsname.nodename;
337  }
338 
339  /* some systems report the FQDN instead of just the hostname */
340  char *dot = strchr(str, '.');
341  if (dot)
342  ShortHostname = mutt_strn_dup(str, dot - str);
343  else
345 
346  if (!C_Hostname)
347  {
348  /* now get FQDN. Use configured domain first, DNS next, then uname */
349 #ifdef DOMAIN
350  /* we have a compile-time domain name, use that for C_Hostname */
352  sprintf((char *) C_Hostname, "%s.%s", NONULL(ShortHostname), DOMAIN);
353 #else
354  C_Hostname = getmailname();
355  if (!C_Hostname)
356  {
357  struct Buffer *domain = mutt_buffer_pool_get();
358  if (getdnsdomainname(domain) == 0)
359  {
360  C_Hostname =
362  sprintf((char *) C_Hostname, "%s.%s", NONULL(ShortHostname), mutt_b2s(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 }
#define NONULL(x)
Definition: string2.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_perror(...)
Definition: logging.h:85
static char * getmailname(void)
Try to retrieve the FQDN from mailname files.
Definition: init.c:284
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
#define _(a)
Definition: message.h:28
WHERE char * C_Hostname
Config: Fully-qualified domain name of this machine.
Definition: mutt_globals.h:94
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:460
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:553
#define mutt_b2s(buf)
Definition: buffer.h:41
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
WHERE char * ShortHostname
Short version of the hostname.
Definition: mutt_globals.h:51
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
int getdnsdomainname(struct Buffer *domain)
Lookup the host&#39;s name using DNS.
Definition: getdomain.c:44
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_command_get()

const struct Command* mutt_command_get ( const char *  s)

Get a Command by its name.

Parameters
sCommand string to lookup
Return values
ptrSuccess, Command
NULLError, no such command

Definition at line 391 of file init.c.

392 {
393  for (int i = 0; Commands[i].name; i++)
394  if (mutt_str_equal(s, Commands[i].name))
395  return &Commands[i];
396  return NULL;
397 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
const char * name
Name of the command.
Definition: mutt_commands.h:46
const struct Command Commands[]
Definition: mutt_commands.c:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_commands_apply()

void mutt_commands_apply ( void *  data,
void(*)(void *, const struct Command *)  application 
)

Run a callback function on every Command.

Parameters
dataData to pass to the callback function
applicationCallback function

This is used by Lua to expose all of NeoMutt's Commands.

Definition at line 407 of file init.c.

408 {
409  for (int i = 0; Commands[i].name; i++)
410  application(data, &Commands[i]);
411 }
const char * name
Name of the command.
Definition: mutt_commands.h:46
char * data
Pointer to data.
Definition: buffer.h:35
const struct Command Commands[]
Definition: mutt_commands.c:50
+ Here is the caller graph for this function:

◆ mutt_extract_token()

int mutt_extract_token ( struct Buffer dest,
struct Buffer tok,
TokenFlags  flags 
)

Extract one token from a string.

Parameters
destBuffer for the result
tokBuffer containing tokens
flagsFlags, see TokenFlags
Return values
0Success
-1Error

Definition at line 422 of file init.c.

423 {
424  if (!dest || !tok)
425  return -1;
426 
427  char ch;
428  char qc = '\0'; /* quote char */
429  char *pc = NULL;
430 
431  mutt_buffer_reset(dest);
432 
433  SKIPWS(tok->dptr);
434  while ((ch = *tok->dptr))
435  {
436  if (qc == '\0')
437  {
438  if ((IS_SPACE(ch) && !(flags & MUTT_TOKEN_SPACE)) ||
439  ((ch == '#') && !(flags & MUTT_TOKEN_COMMENT)) ||
440  ((ch == '+') && (flags & MUTT_TOKEN_PLUS)) ||
441  ((ch == '-') && (flags & MUTT_TOKEN_MINUS)) ||
442  ((ch == '=') && (flags & MUTT_TOKEN_EQUAL)) ||
443  ((ch == '?') && (flags & MUTT_TOKEN_QUESTION)) ||
444  ((ch == ';') && !(flags & MUTT_TOKEN_SEMICOLON)) ||
445  ((flags & MUTT_TOKEN_PATTERN) && strchr("~%=!|", ch)))
446  {
447  break;
448  }
449  }
450 
451  tok->dptr++;
452 
453  if (ch == qc)
454  qc = 0; /* end of quote */
455  else if (!qc && ((ch == '\'') || (ch == '"')) && !(flags & MUTT_TOKEN_QUOTE))
456  qc = ch;
457  else if ((ch == '\\') && (qc != '\''))
458  {
459  if (tok->dptr[0] == '\0')
460  return -1; /* premature end of token */
461  switch (ch = *tok->dptr++)
462  {
463  case 'c':
464  case 'C':
465  if (tok->dptr[0] == '\0')
466  return -1; /* premature end of token */
467  mutt_buffer_addch(dest, (toupper((unsigned char) tok->dptr[0]) - '@') & 0x7f);
468  tok->dptr++;
469  break;
470  case 'e':
471  mutt_buffer_addch(dest, '\033'); // Escape
472  break;
473  case 'f':
474  mutt_buffer_addch(dest, '\f');
475  break;
476  case 'n':
477  mutt_buffer_addch(dest, '\n');
478  break;
479  case 'r':
480  mutt_buffer_addch(dest, '\r');
481  break;
482  case 't':
483  mutt_buffer_addch(dest, '\t');
484  break;
485  default:
486  if (isdigit((unsigned char) ch) && isdigit((unsigned char) tok->dptr[0]) &&
487  isdigit((unsigned char) tok->dptr[1]))
488  {
489  mutt_buffer_addch(dest, (ch << 6) + (tok->dptr[0] << 3) + tok->dptr[1] - 3504);
490  tok->dptr += 2;
491  }
492  else
493  mutt_buffer_addch(dest, ch);
494  }
495  }
496  else if ((ch == '^') && (flags & MUTT_TOKEN_CONDENSE))
497  {
498  if (tok->dptr[0] == '\0')
499  return -1; /* premature end of token */
500  ch = *tok->dptr++;
501  if (ch == '^')
502  mutt_buffer_addch(dest, ch);
503  else if (ch == '[')
504  mutt_buffer_addch(dest, '\033'); // Escape
505  else if (isalpha((unsigned char) ch))
506  mutt_buffer_addch(dest, toupper((unsigned char) ch) - '@');
507  else
508  {
509  mutt_buffer_addch(dest, '^');
510  mutt_buffer_addch(dest, ch);
511  }
512  }
513  else if ((ch == '`') && (!qc || (qc == '"')))
514  {
515  FILE *fp = NULL;
516  pid_t pid;
517 
518  pc = tok->dptr;
519  do
520  {
521  pc = strpbrk(pc, "\\`");
522  if (pc)
523  {
524  /* skip any quoted chars */
525  if (*pc == '\\')
526  pc += 2;
527  }
528  } while (pc && (pc[0] != '`'));
529  if (!pc)
530  {
531  mutt_debug(LL_DEBUG1, "mismatched backticks\n");
532  return -1;
533  }
534  struct Buffer cmd;
535  mutt_buffer_init(&cmd);
536  *pc = '\0';
537  if (flags & MUTT_TOKEN_BACKTICK_VARS)
538  {
539  /* recursively extract tokens to interpolate variables */
540  mutt_extract_token(&cmd, tok,
541  MUTT_TOKEN_QUOTE | MUTT_TOKEN_SPACE | MUTT_TOKEN_COMMENT |
542  MUTT_TOKEN_SEMICOLON | MUTT_TOKEN_NOSHELL);
543  }
544  else
545  {
546  cmd.data = mutt_str_dup(tok->dptr);
547  }
548  *pc = '`';
549  pid = filter_create(cmd.data, NULL, &fp, NULL);
550  if (pid < 0)
551  {
552  mutt_debug(LL_DEBUG1, "unable to fork command: %s\n", cmd.data);
553  FREE(&cmd.data);
554  return -1;
555  }
556  FREE(&cmd.data);
557 
558  tok->dptr = pc + 1;
559 
560  /* read line */
561  struct Buffer expn = mutt_buffer_make(0);
562  expn.data = mutt_file_read_line(NULL, &expn.dsize, fp, NULL, 0);
563  mutt_file_fclose(&fp);
564  filter_wait(pid);
565 
566  /* if we got output, make a new string consisting of the shell output
567  * plus whatever else was left on the original line */
568  /* BUT: If this is inside a quoted string, directly add output to
569  * the token */
570  if (expn.data)
571  {
572  if (qc)
573  {
574  mutt_buffer_addstr(dest, expn.data);
575  }
576  else
577  {
578  struct Buffer *copy = mutt_buffer_pool_get();
579  mutt_buffer_fix_dptr(&expn);
580  mutt_buffer_copy(copy, &expn);
581  mutt_buffer_addstr(copy, tok->dptr);
582  mutt_buffer_copy(tok, copy);
583  tok->dptr = tok->data;
585  }
586  FREE(&expn.data);
587  }
588  }
589  else if ((ch == '$') && (!qc || (qc == '"')) &&
590  ((tok->dptr[0] == '{') || isalpha((unsigned char) tok->dptr[0])))
591  {
592  const char *env = NULL;
593  char *var = NULL;
594 
595  if (tok->dptr[0] == '{')
596  {
597  pc = strchr(tok->dptr, '}');
598  if (pc)
599  {
600  var = mutt_strn_dup(tok->dptr + 1, pc - (tok->dptr + 1));
601  tok->dptr = pc + 1;
602 
603  if ((flags & MUTT_TOKEN_NOSHELL))
604  {
605  mutt_buffer_addch(dest, ch);
606  mutt_buffer_addch(dest, '{');
607  mutt_buffer_addstr(dest, var);
608  mutt_buffer_addch(dest, '}');
609  FREE(&var);
610  }
611  }
612  }
613  else
614  {
615  for (pc = tok->dptr; isalnum((unsigned char) *pc) || (pc[0] == '_'); pc++)
616  ; // do nothing
617 
618  var = mutt_strn_dup(tok->dptr, pc - tok->dptr);
619  tok->dptr = pc;
620  }
621  if (var)
622  {
623  struct Buffer result;
624  mutt_buffer_init(&result);
625  int rc = cs_subset_str_string_get(NeoMutt->sub, var, &result);
626 
627  if (CSR_RESULT(rc) == CSR_SUCCESS)
628  {
629  mutt_buffer_addstr(dest, result.data);
630  FREE(&result.data);
631  }
632  else if ((env = myvar_get(var)))
633  {
634  mutt_buffer_addstr(dest, env);
635  }
636  else if (!(flags & MUTT_TOKEN_NOSHELL) && (env = mutt_str_getenv(var)))
637  {
638  mutt_buffer_addstr(dest, env);
639  }
640  else
641  {
642  mutt_buffer_addch(dest, ch);
643  mutt_buffer_addstr(dest, var);
644  }
645  FREE(&var);
646  }
647  }
648  else
649  mutt_buffer_addch(dest, ch);
650  }
651  mutt_buffer_addch(dest, 0); /* terminate the string */
652  SKIPWS(tok->dptr);
653  return 0;
654 }
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define CSR_RESULT(x)
Definition: set.h:52
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer&#39;s contents to another Buffer.
Definition: buffer.c:445
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
#define MUTT_TOKEN_COMMENT
Don&#39;t reap comments.
Definition: mutt.h:76
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
String manipulation buffer.
Definition: buffer.h:33
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, int flags)
Read a line from a file.
Definition: file.c:667
Container for Accounts, Notifications.
Definition: neomutt.h:36
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
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition: string.c:996
size_t dsize
Length of data.
Definition: buffer.h:37
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:553
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
#define SKIPWS(ch)
Definition: string2.h:46
#define MUTT_TOKEN_NOSHELL
Don&#39;t expand environment variables.
Definition: mutt.h:79
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
void mutt_buffer_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:181
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
#define MUTT_TOKEN_QUOTE
Don&#39;t interpret quotes.
Definition: mutt.h:74
#define MUTT_TOKEN_CONDENSE
^(char) to control chars (macros)
Definition: mutt.h:72
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:422
char * dptr
Current read/write position.
Definition: buffer.h:36
#define MUTT_TOKEN_SPACE
Don&#39;t treat whitespace as a term.
Definition: mutt.h:73
char * data
Pointer to data.
Definition: buffer.h:35
#define MUTT_TOKEN_PLUS
Treat &#39;+&#39; as a special.
Definition: mutt.h:81
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
const char * myvar_get(const char *var)
Get the value of a "my_" variable.
Definition: myvar.c:73
#define MUTT_TOKEN_SEMICOLON
Don&#39;t treat ; as special.
Definition: mutt.h:77
#define IS_SPACE(ch)
Definition: string2.h:38
Log at debug level 1.
Definition: logging.h:40
#define MUTT_TOKEN_MINUS
Treat &#39;-&#39; as a special.
Definition: mutt.h:82
#define MUTT_TOKEN_BACKTICK_VARS
Expand variables within backticks.
Definition: mutt.h:78
#define FREE(x)
Definition: memory.h:40
#define MUTT_TOKEN_EQUAL
Treat &#39;=&#39; as a special.
Definition: mutt.h:71
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
#define MUTT_TOKEN_PATTERN
~%=!| are terms (for patterns)
Definition: mutt.h:75
#define MUTT_TOKEN_QUESTION
Treat &#39;?&#39; as a special.
Definition: mutt.h:80

◆ mutt_opts_free()

void mutt_opts_free ( void  )

clean up before quitting

Definition at line 659 of file init.c.

660 {
662 
663  alias_shutdown();
664 #ifdef USE_SIDEBAR
665  sb_shutdown();
666 #endif
667 
668  mutt_regexlist_free(&Alternates);
672  mutt_regexlist_free(&UnAlternates);
675 
679 
680  /* Lists of strings */
681  mutt_list_free(&AlternativeOrderList);
682  mutt_list_free(&AutoViewList);
683  mutt_list_free(&HeaderOrderList);
686  mutt_list_free(&MimeLookupList);
687  mutt_list_free(&Muttrc);
689  mutt_list_free(&UserHeader);
690 
691  /* Lists of AttachMatch */
696 
698 
700  FREE(&HomeDir);
701  FREE(&LastFolder);
703  FREE(&Username);
704 
707 
709 
710  mutt_hist_free();
711  mutt_keys_free();
712 
714 }
struct RegexList SubscribedLists
List of regexes to match subscribed mailing lists.
Definition: globals.c:52
struct ReplaceList SubjectRegexList
List of regexes to tidy the view of the email&#39;s subject.
Definition: globals.c:53
struct ListHead InlineAllow
List of inline types to counted.
Definition: mutt_parse.c:40
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:447
void mutt_list_free_type(struct ListHead *h, list_free_t fn)
Free a List of type.
Definition: list.c:144
struct RegexList UnSubscribedLists
List of regexes to blacklist false matches in SubscribedLists.
Definition: globals.c:49
void mutt_delete_hooks(HookFlags type)
Delete matching hooks.
Definition: hook.c:307
struct RegexList MailLists
List of regexes to match mailing lists.
Definition: globals.c:50
void mutt_replacelist_free(struct ReplaceList *rl)
Free a ReplaceList object.
Definition: regex.c:446
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
char * HomeDir
User&#39;s home directory.
Definition: mutt_globals.h:50
WHERE char * Username
User&#39;s login name.
Definition: mutt_globals.h:53
void clear_source_stack(void)
Free memory from the stack used for the souce command.
void alias_shutdown(void)
Clean up the Alias globals.
Definition: alias.c:661
struct ListHead Ignore
List of header patterns to ignore.
Definition: globals.c:45
struct ListHead InlineExclude
List of inline types to ignore.
Definition: mutt_parse.c:41
struct RegexList NoSpamList
List of regexes to whitelist non-spam emails.
Definition: globals.c:43
void mutt_keys_free(void)
Free the key maps.
Definition: keymap.c:1644
WHERE char * ShortHostname
Short version of the hostname.
Definition: mutt_globals.h:51
struct ListHead MailToAllow
List of permitted fields in a mailto: url.
Definition: globals.c:47
struct HashTable * TagTransforms
Lookup table of alternative tag names.
Definition: tags.c:38
Definition: color.h:129
WHERE char * LastFolder
Previously selected mailbox.
Definition: mutt_globals.h:56
void mutt_colors_free(struct Colors **ptr)
Free all the colours.
Definition: color.c:355
struct ReplaceList SpamList
List of regexes and patterns to match spam emails.
Definition: globals.c:44
struct ListHead AttachExclude
List of attachment types to be ignored.
Definition: mutt_parse.c:39
struct ListHead UnIgnore
List of header patterns to unignore (see)
Definition: globals.c:46
WHERE char * CurrentFolder
Currently selected mailbox.
Definition: mutt_globals.h:55
struct RegexList UnMailLists
List of regexes to blacklist false matches in MailLists.
Definition: globals.c:51
#define FREE(x)
Definition: memory.h:40
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:44
void mutt_attachmatch_free(struct AttachMatch **ptr)
Free an AttachMatch - Implements list_free_t.
Definition: mutt_parse.c:240
void mutt_grouplist_free(void)
Free GroupList singleton resource.
Definition: group.c:55
WHERE struct HashTable * TagFormats
Hash Table of tag-formats (tag -> format string)
Definition: mutt_globals.h:60
struct ListHead AttachAllow
List of attachment types to be counted.
Definition: mutt_parse.c:38
void mutt_hist_free(void)
Free all the history lists.
Definition: history.c:424
void mutt_regexlist_free(struct RegexList *rl)
Free a RegexList object.
Definition: regex.c:169
void(* list_free_t)(void **ptr)
Prototype for a function to free List data.
Definition: list.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_get_hook_type()

HookFlags mutt_get_hook_type ( const char *  name)

Find a hook by name.

Parameters
nameName to find
Return values
numHook ID, e.g. MUTT_FOLDER_HOOK
MUTT_HOOK_NO_FLAGSError, no matching hook

Definition at line 722 of file init.c.

723 {
724  for (const struct Command *c = Commands; c->name; c++)
725  {
726  if (((c->parse == mutt_parse_hook) || (c->parse == mutt_parse_idxfmt_hook)) &&
727  mutt_istr_equal(c->name, name))
728  {
729  return c->data;
730  }
731  }
732  return MUTT_HOOK_NO_FLAGS;
733 }
enum CommandResult mutt_parse_hook(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the &#39;hook&#39; family of commands - Implements Command::parse()
Definition: hook.c:85
A user-callable command.
Definition: mutt_commands.h:44
const char * name
Name of the command.
Definition: mutt_commands.h:46
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:888
enum CommandResult mutt_parse_idxfmt_hook(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the &#39;index-format-hook&#39; command - Implements Command::parse()
Definition: hook.c:351
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:44
const struct Command Commands[]
Definition: mutt_commands.c:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_init()

int mutt_init ( struct ConfigSet cs,
bool  skip_sys_rc,
struct ListHead *  commands 
)

Initialise NeoMutt.

Parameters
csConfig Set
skip_sys_rcIf true, don't read the system config file
commandsList of config commands to execute
Return values
0Success
1Error

Definition at line 743 of file init.c.

744 {
745  int need_pause = 0;
746  int rc = 1;
747  struct Buffer err = mutt_buffer_make(256);
748  struct Buffer buf = mutt_buffer_make(256);
749 
751  alias_init();
754 
755  mutt_menu_init();
756 #ifdef USE_SIDEBAR
757  sb_init();
758 #endif
759 
760  snprintf(AttachmentMarker, sizeof(AttachmentMarker), "\033]9;%" PRIu64 "\a", // Escape
761  mutt_rand64());
762 
763  snprintf(ProtectedHeaderMarker, sizeof(ProtectedHeaderMarker), "\033]8;%lld\a", // Escape
764  (long long) mutt_date_epoch());
765 
766  /* "$spoolfile" precedence: config file, environment */
767  const char *p = mutt_str_getenv("MAIL");
768  if (!p)
769  p = mutt_str_getenv("MAILDIR");
770  if (!p)
771  {
772 #ifdef HOMESPOOL
773  mutt_buffer_concat_path(&buf, NONULL(HomeDir), MAILPATH);
774 #else
775  mutt_buffer_concat_path(&buf, MAILPATH, NONULL(Username));
776 #endif
777  p = mutt_b2s(&buf);
778  }
779  cs_str_initial_set(cs, "spoolfile", p, NULL);
780  cs_str_reset(cs, "spoolfile", NULL);
781 
782  p = mutt_str_getenv("REPLYTO");
783  if (p)
784  {
785  struct Buffer token;
786 
787  mutt_buffer_printf(&buf, "Reply-To: %s", p);
788  mutt_buffer_init(&token);
789  parse_my_hdr(&token, &buf, 0, &err); /* adds to UserHeader */
790  FREE(&token.data);
791  }
792 
793  p = mutt_str_getenv("EMAIL");
794  if (p)
795  {
796  cs_str_initial_set(cs, "from", p, NULL);
797  cs_str_reset(cs, "from", NULL);
798  }
799 
800  /* "$mailcap_path" precedence: config file, environment, code */
801  const char *env_mc = mutt_str_getenv("MAILCAPS");
802  if (env_mc)
803  cs_str_string_set(cs, "mailcap_path", env_mc, NULL);
804 
805  /* "$tmpdir" precedence: config file, environment, code */
806  const char *env_tmp = mutt_str_getenv("TMPDIR");
807  if (env_tmp)
808  cs_str_string_set(cs, "tmpdir", env_tmp, NULL);
809 
810  /* "$visual", "$editor" precedence: config file, environment, code */
811  const char *env_ed = mutt_str_getenv("VISUAL");
812  if (!env_ed)
813  env_ed = mutt_str_getenv("EDITOR");
814  if (env_ed)
815  {
816  cs_str_string_set(cs, "editor", env_ed, NULL);
817  cs_str_string_set(cs, "visual", env_ed, NULL);
818  }
819 
821  cs_str_initial_set(cs, "charset", C_Charset, NULL);
823 
824  Matches = mutt_mem_calloc(MatchesListsize, sizeof(char *));
825 
827 
828 #ifdef HAVE_GETSID
829  /* Unset suspend by default if we're the session leader */
830  if (getsid(0) == getpid())
831  C_Suspend = false;
832 #endif
833 
834  /* RFC2368, "4. Unsafe headers"
835  * The creator of a mailto URL can't expect the resolver of a URL to
836  * understand more than the "subject" and "body" headers. Clients that
837  * resolve mailto URLs into mail messages should be able to correctly
838  * create RFC822-compliant mail messages using the "subject" and "body"
839  * headers. */
840  add_to_stailq(&MailToAllow, "body");
841  add_to_stailq(&MailToAllow, "subject");
842  /* Cc, In-Reply-To, and References help with not breaking threading on
843  * mailing lists, see https://github.com/neomutt/neomutt/issues/115 */
844  add_to_stailq(&MailToAllow, "cc");
845  add_to_stailq(&MailToAllow, "in-reply-to");
846  add_to_stailq(&MailToAllow, "references");
847 
848  if (STAILQ_EMPTY(&Muttrc))
849  {
850  const char *xdg_cfg_home = mutt_str_getenv("XDG_CONFIG_HOME");
851 
852  if (!xdg_cfg_home && HomeDir)
853  {
854  mutt_buffer_printf(&buf, "%s/.config", HomeDir);
855  xdg_cfg_home = mutt_b2s(&buf);
856  }
857 
858  char *config = find_cfg(HomeDir, xdg_cfg_home);
859  if (config)
860  {
861  mutt_list_insert_tail(&Muttrc, config);
862  }
863  }
864  else
865  {
866  struct ListNode *np = NULL;
867  STAILQ_FOREACH(np, &Muttrc, entries)
868  {
869  mutt_buffer_strcpy(&buf, np->data);
870  FREE(&np->data);
872  np->data = mutt_buffer_strdup(&buf);
873  if (access(np->data, F_OK))
874  {
875  mutt_perror(np->data);
876  goto done; // TEST10: neomutt -F missing
877  }
878  }
879  }
880 
881  if (!STAILQ_EMPTY(&Muttrc))
882  {
883  cs_str_string_set(cs, "alias_file", STAILQ_FIRST(&Muttrc)->data, NULL);
884  }
885 
886  /* Process the global rc file if it exists and the user hasn't explicitly
887  * requested not to via "-n". */
888  if (!skip_sys_rc)
889  {
890  do
891  {
893  break;
894 
895  mutt_buffer_printf(&buf, "%s/neomuttrc", SYSCONFDIR);
896  if (access(mutt_b2s(&buf), F_OK) == 0)
897  break;
898 
899  mutt_buffer_printf(&buf, "%s/Muttrc", SYSCONFDIR);
900  if (access(mutt_b2s(&buf), F_OK) == 0)
901  break;
902 
903  mutt_buffer_printf(&buf, "%s/neomuttrc", PKGDATADIR);
904  if (access(mutt_b2s(&buf), F_OK) == 0)
905  break;
906 
907  mutt_buffer_printf(&buf, "%s/Muttrc", PKGDATADIR);
908  } while (false);
909 
910  if (access(mutt_b2s(&buf), F_OK) == 0)
911  {
912  if (source_rc(mutt_b2s(&buf), &err) != 0)
913  {
914  mutt_error("%s", err.data);
915  need_pause = 1; // TEST11: neomutt (error in /etc/neomuttrc)
916  }
917  }
918  }
919 
920  /* Read the user's initialization file. */
921  struct ListNode *np = NULL;
922  STAILQ_FOREACH(np, &Muttrc, entries)
923  {
924  if (np->data)
925  {
926  if (source_rc(np->data, &err) != 0)
927  {
928  mutt_error("%s", err.data);
929  need_pause = 1; // TEST12: neomutt (error in ~/.neomuttrc)
930  }
931  }
932  }
933 
934  if (execute_commands(commands) != 0)
935  need_pause = 1; // TEST13: neomutt -e broken
936 
937  if (!get_hostname(cs))
938  goto done;
939 
940  if (!C_Realname)
941  {
942  struct passwd *pw = getpwuid(getuid());
943  if (pw)
944  {
945  char name[256];
946  C_Realname = mutt_str_dup(mutt_gecos_name(name, sizeof(name), pw));
947  }
948  }
949  cs_str_initial_set(cs, "realname", C_Realname, NULL);
950 
951  if (need_pause && !OptNoCurses)
952  {
954  if (mutt_any_key_to_continue(NULL) == 'q')
955  goto done; // TEST14: neomutt -e broken (press 'q')
956  }
957 
958  mutt_file_mkdir(C_Tmpdir, S_IRWXU);
959 
960  mutt_hist_init();
962 
963 #ifdef USE_NOTMUCH
964  if (C_VirtualSpoolfile)
965  {
966  /* Find the first virtual folder and open it */
967  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
969  struct MailboxNode *mp = STAILQ_FIRST(&ml);
970  if (mp)
971  cs_str_string_set(cs, "spoolfile", mailbox_path(mp->mailbox), NULL);
973  }
974 #endif
975  rc = 0;
976 
977 done:
978  mutt_buffer_dealloc(&err);
979  mutt_buffer_dealloc(&buf);
980  return rc;
981 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:414
int source_rc(const char *rcfile_path, struct Buffer *err)
Read an initialization file.
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:196
#define NONULL(x)
Definition: string2.h:37
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define mutt_perror(...)
Definition: logging.h:85
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:597
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:137
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:450
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
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
char * mutt_buffer_strdup(struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
String manipulation buffer.
Definition: buffer.h:33
static int execute_commands(struct ListHead *p)
Execute a set of NeoMutt commands.
Definition: init.c:211
WHERE char * C_Realname
Config: Real name of the user.
Definition: mutt_globals.h:108
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
void alias_init(void)
Set up the Alias globals.
Definition: alias.c:651
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:48
Index panel (list of emails)
Definition: keymap.h:78
void mutt_ch_set_charset(const char *charset)
Update the records for a new character set.
Definition: charset.c:1003
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
void log_queue_flush(log_dispatcher_t disp)
Replay the log queue.
Definition: logging.c:357
static char * find_cfg(const char *home, const char *xdg_cfg_home)
Find a config file.
Definition: init.c:243
Container for Accounts, Notifications.
Definition: neomutt.h:36
char * HomeDir
User&#39;s home directory.
Definition: mutt_globals.h:50
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition: string.c:996
WHERE char ProtectedHeaderMarker[256]
Unique ANSI string to mark protected headers in an email.
Definition: mutt_globals.h:48
WHERE char * Username
User&#39;s login name.
Definition: mutt_globals.h:53
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:460
#define MUTT_HASH_STRCASECMP
use strcasecmp() to compare keys
Definition: hash.h:98
void mutt_hist_read_file(void)
Read the History from a file.
Definition: history.c:568
WHERE enum MenuType CurrentMenu
Current Menu, e.g. MENU_PAGER.
Definition: mutt_globals.h:78
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:875
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
#define mutt_b2s(buf)
Definition: buffer.h:41
void add_to_stailq(struct ListHead *head, const char *str)
Add a string to a list.
Definition: muttlib.c:1700
WHERE bool C_Suspend
Config: Allow the user to suspend NeoMutt using &#39;^Z&#39;.
Definition: mutt_globals.h:167
static int MatchesListsize
Definition: init.c:89
void mutt_grouplist_init(void)
Initialize the GroupList singleton.
Definition: group.c:45
uint64_t mutt_rand64(void)
Create a 64-bit random number.
Definition: random.c:128
WHERE char AttachmentMarker[256]
Unique ANSI string to mark PGP messages in an email.
Definition: mutt_globals.h:47
struct ListHead MailToAllow
List of permitted fields in a mailto: url.
Definition: globals.c:47
char * data
Pointer to data.
Definition: buffer.h:35
static bool get_hostname(struct ConfigSet *cs)
Find the Fully-Qualified Domain Name.
Definition: init.c:316
struct HashTable * TagTransforms
Lookup table of alternative tag names.
Definition: tags.c:38
char * mutt_ch_get_langinfo_charset(void)
Get the user&#39;s choice of character set.
Definition: charset.c:462
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
void mutt_hist_init(void)
Create a set of empty History ring buffers.
Definition: history.c:447
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:54
int mutt_set_xdg_path(enum XdgType type, struct Buffer *buf)
Find an XDG path or its fallback.
Definition: muttlib.c:1499
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:395
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:602
char * data
String.
Definition: list.h:36
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:323
char * mutt_gecos_name(char *dest, size_t destlen, struct passwd *pw)
Lookup a user&#39;s real name in /etc/passwd.
Definition: muttlib.c:362
#define mutt_error(...)
Definition: logging.h:84
char * C_Tmpdir
Config: Directory for temporary files.
Definition: file.c:56
static const char ** Matches
Definition: init.c:87
#define FREE(x)
Definition: memory.h:40
enum CommandResult parse_my_hdr(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the &#39;my_hdr&#39; command - Implements Command::parse()
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
#define STAILQ_EMPTY(head)
Definition: queue.h:345
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:53
List of Mailboxes.
Definition: mailbox.h:145
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
WHERE struct HashTable * TagFormats
Hash Table of tag-formats (tag -> format string)
Definition: mutt_globals.h:60
A List node for strings.
Definition: list.h:34
XDG system dir: /etc/xdg.
Definition: protos.h:48
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition: hash.c:251
#define STAILQ_FIRST(head)
Definition: queue.h:347
#define MUTT_HASH_NO_FLAGS
No flags are set.
Definition: hash.h:97
bool C_VirtualSpoolfile
Config: (notmuch) Use the first virtual mailbox as a spool file.
Definition: config.c:50
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:147
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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.

Parameters
lineconfig line to read
tokenscratch buffer to be used by parser
errwhere to write error messages
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

The reason for token is to avoid having to allocate and deallocate a lot of memory if we are parsing many lines. the caller can pass in the memory to use, which avoids having to create new space for every call to this function.

Definition at line 994 of file init.c.

996 {
997  if (mutt_buffer_len(line) == 0)
998  return 0;
999 
1000  int i;
1001  enum CommandResult rc = MUTT_CMD_SUCCESS;
1002 
1003  mutt_buffer_reset(err);
1004 
1005  /* Read from the beginning of line->data */
1006  line->dptr = line->data;
1007 
1008  SKIPWS(line->dptr);
1009  while (*line->dptr)
1010  {
1011  if (*line->dptr == '#')
1012  break; /* rest of line is a comment */
1013  if (*line->dptr == ';')
1014  {
1015  line->dptr++;
1016  continue;
1017  }
1019  for (i = 0; Commands[i].name; i++)
1020  {
1021  if (mutt_str_equal(token->data, Commands[i].name))
1022  {
1023  rc = Commands[i].parse(token, line, Commands[i].data, err);
1024  if (rc != MUTT_CMD_SUCCESS)
1025  { /* -1 Error, +1 Finish */
1026  goto finish; /* Propagate return code */
1027  }
1028  notify_send(NeoMutt->notify, NT_COMMAND, i, (void *) &Commands[i]);
1029  break; /* Continue with next command */
1030  }
1031  }
1032  if (!Commands[i].name)
1033  {
1034  mutt_buffer_printf(err, _("%s: unknown command"), NONULL(token->data));
1035  rc = MUTT_CMD_ERROR;
1036  break; /* Ignore the rest of the line */
1037  }
1038  }
1039 finish:
1040  return rc;
1041 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
#define NONULL(x)
Definition: string2.h:37
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
CommandResult
Error codes for command_t parse functions.
Definition: mutt_commands.h:33
Error: Can&#39;t help the user.
Definition: mutt_commands.h:35
#define _(a)
Definition: message.h:28
const char * name
Name of the command.
Definition: mutt_commands.h:46
A Command has been executed, Command.
Definition: notify_type.h:35
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
Container for Accounts, Notifications.
Definition: neomutt.h:36
enum CommandResult(* parse)(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Function to parse a command.
Definition: mutt_commands.h:56
#define SKIPWS(ch)
Definition: string2.h:46
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:422
char * dptr
Current read/write position.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:35
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
Success: Command worked.
Definition: mutt_commands.h:37
const struct Command Commands[]
Definition: mutt_commands.c:50
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:70
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:137
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_parse_rc_line()

enum CommandResult mutt_parse_rc_line ( const char *  line,
struct Buffer err 
)

Parse a line of user config.

Parameters
lineConfig line to read
errWhere to write error messages
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

Definition at line 1049 of file init.c.

1050 {
1051  if (!line || (*line == '\0'))
1052  return MUTT_CMD_ERROR;
1053 
1054  struct Buffer *line_buffer = mutt_buffer_pool_get();
1055  struct Buffer *token = mutt_buffer_pool_get();
1056 
1057  mutt_buffer_strcpy(line_buffer, line);
1058 
1059  enum CommandResult rc = mutt_parse_rc_buffer(line_buffer, token, err);
1060 
1061  mutt_buffer_pool_release(&line_buffer);
1062  mutt_buffer_pool_release(&token);
1063  return rc;
1064 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
CommandResult
Error codes for command_t parse functions.
Definition: mutt_commands.h:33
Error: Can&#39;t help the user.
Definition: mutt_commands.h:35
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
enum CommandResult mutt_parse_rc_buffer(struct Buffer *line, struct Buffer *token, struct Buffer *err)
Parse a line of user config.
Definition: init.c:994
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
int const char int line
Definition: acutest.h:617
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_query_variables()

int mutt_query_variables ( struct ListHead *  queries)

Implement the -Q command line flag.

Parameters
queriesList of query strings
Return values
0Success, all queries exist
1Error

Definition at line 1072 of file init.c.

1073 {
1074  struct Buffer value = mutt_buffer_make(256);
1075  struct Buffer tmp = mutt_buffer_make(256);
1076  int rc = 0;
1077 
1078  struct ListNode *np = NULL;
1079  STAILQ_FOREACH(np, queries, entries)
1080  {
1081  mutt_buffer_reset(&value);
1082 
1083  struct HashElem *he = cs_subset_lookup(NeoMutt->sub, np->data);
1084  if (!he)
1085  {
1086  rc = 1;
1087  continue;
1088  }
1089 
1090  int rv = cs_subset_he_string_get(NeoMutt->sub, he, &value);
1091  if (CSR_RESULT(rv) != CSR_SUCCESS)
1092  {
1093  rc = 1;
1094  continue;
1095  }
1096 
1097  int type = DTYPE(he->type);
1098  if (type == DT_PATH)
1099  mutt_pretty_mailbox(value.data, value.dsize);
1100 
1101  if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) && (type != DT_QUAD))
1102  {
1103  mutt_buffer_reset(&tmp);
1104  pretty_var(value.data, &tmp);
1105  mutt_buffer_strcpy(&value, tmp.data);
1106  }
1107 
1108  dump_config_neo(NeoMutt->sub->cs, he, &value, NULL, CS_DUMP_NO_FLAGS, stdout);
1109  }
1110 
1111  mutt_buffer_dealloc(&value);
1112  mutt_buffer_dealloc(&tmp);
1113 
1114  return rc; // TEST16: neomutt -Q charset
1115 }
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
#define DT_LONG
a number (long)
Definition: types.h:33
#define CSR_RESULT(x)
Definition: set.h:52
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
String manipulation buffer.
Definition: buffer.h:33
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
struct HashElem * cs_subset_lookup(const struct ConfigSubset *sub, const char *name)
Find an inherited config item.
Definition: subset.c:168
#define DT_QUAD
quad-option (no/yes/ask-no/ask-yes)
Definition: types.h:37
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define DTYPE(x)
Mask for the Data Type.
Definition: types.h:44
size_t dsize
Length of data.
Definition: buffer.h:37
struct ConfigSet * cs
Parent ConfigSet.
Definition: subset.h:51
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
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
#define DT_PATH
a path to a file/directory
Definition: types.h:36
#define CS_DUMP_NO_FLAGS
No flags are set.
Definition: dump.h:35
char * data
Pointer to data.
Definition: buffer.h:35
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:522
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
size_t pretty_var(const char *str, struct Buffer *buf)
Escape and stringify a config item value.
Definition: dump.c:83
char * data
String.
Definition: list.h:36
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:45
The item stored in a Hash Table.
Definition: hash.h:43
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
A List node for strings.
Definition: list.h:34
#define DT_NUMBER
a number
Definition: types.h:35
#define DT_BOOL
boolean option
Definition: types.h:30
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_command_complete()

int mutt_command_complete ( char *  buf,
size_t  buflen,
int  pos,
int  numtabs 
)

Complete a command name.

Parameters
bufBuffer for the result
buflenLength of the buffer
posCursor position in the buffer
numtabsNumber of times the user has hit 'tab'
Return values
1Success, a match
0Error, no match

Definition at line 1126 of file init.c.

1127 {
1128  char *pt = buf;
1129  int num;
1130  int spaces; /* keep track of the number of leading spaces on the line */
1131  struct MyVar *myv = NULL;
1132 
1133  SKIPWS(buf);
1134  spaces = buf - pt;
1135 
1136  pt = buf + pos - spaces;
1137  while ((pt > buf) && !isspace((unsigned char) *pt))
1138  pt--;
1139 
1140  if (pt == buf) /* complete cmd */
1141  {
1142  /* first TAB. Collect all the matches */
1143  if (numtabs == 1)
1144  {
1145  NumMatched = 0;
1146  mutt_str_copy(UserTyped, pt, sizeof(UserTyped));
1147  memset(Matches, 0, MatchesListsize);
1148  memset(Completed, 0, sizeof(Completed));
1149  for (num = 0; Commands[num].name; num++)
1153 
1154  /* All matches are stored. Longest non-ambiguous string is ""
1155  * i.e. don't change 'buf'. Fake successful return this time */
1156  if (UserTyped[0] == '\0')
1157  return 1;
1158  }
1159 
1160  if ((Completed[0] == '\0') && (UserTyped[0] != '\0'))
1161  return 0;
1162 
1163  /* NumMatched will _always_ be at least 1 since the initial
1164  * user-typed string is always stored */
1165  if ((numtabs == 1) && (NumMatched == 2))
1166  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1167  else if ((numtabs > 1) && (NumMatched > 2))
1168  {
1169  /* cycle through all the matches */
1170  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1171  }
1172 
1173  /* return the completed command */
1174  strncpy(buf, Completed, buflen - spaces);
1175  }
1176  else if (mutt_str_startswith(buf, "set") || mutt_str_startswith(buf, "unset") ||
1177  mutt_str_startswith(buf, "reset") || mutt_str_startswith(buf, "toggle"))
1178  { /* complete variables */
1179  static const char *const prefixes[] = { "no", "inv", "?", "&", 0 };
1180 
1181  pt++;
1182  /* loop through all the possible prefixes (no, inv, ...) */
1183  if (mutt_str_startswith(buf, "set"))
1184  {
1185  for (num = 0; prefixes[num]; num++)
1186  {
1187  if (mutt_str_startswith(pt, prefixes[num]))
1188  {
1189  pt += mutt_str_len(prefixes[num]);
1190  break;
1191  }
1192  }
1193  }
1194 
1195  /* first TAB. Collect all the matches */
1196  if (numtabs == 1)
1197  {
1198  NumMatched = 0;
1199  mutt_str_copy(UserTyped, pt, sizeof(UserTyped));
1200  memset(Matches, 0, MatchesListsize);
1201  memset(Completed, 0, sizeof(Completed));
1202 
1203  struct HashElem *he = NULL;
1204  struct HashElem **list = get_elem_list(NeoMutt->sub->cs);
1205  for (size_t i = 0; list[i]; i++)
1206  {
1207  he = list[i];
1208  const int type = DTYPE(he->type);
1209 
1210  if ((type == DT_SYNONYM) || (type & DT_DEPRECATED))
1211  continue;
1212 
1213  candidate(UserTyped, he->key.strkey, Completed, sizeof(Completed));
1214  }
1215  FREE(&list);
1216 
1217  TAILQ_FOREACH(myv, &MyVars, entries)
1218  {
1219  candidate(UserTyped, myv->name, Completed, sizeof(Completed));
1220  }
1223 
1224  /* All matches are stored. Longest non-ambiguous string is ""
1225  * i.e. don't change 'buf'. Fake successful return this time */
1226  if (UserTyped[0] == '\0')
1227  return 1;
1228  }
1229 
1230  if ((Completed[0] == 0) && UserTyped[0])
1231  return 0;
1232 
1233  /* NumMatched will _always_ be at least 1 since the initial
1234  * user-typed string is always stored */
1235  if ((numtabs == 1) && (NumMatched == 2))
1236  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1237  else if ((numtabs > 1) && (NumMatched > 2))
1238  {
1239  /* cycle through all the matches */
1240  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1241  }
1242 
1243  strncpy(pt, Completed, buf + buflen - pt - spaces);
1244  }
1245  else if (mutt_str_startswith(buf, "exec"))
1246  {
1247  const struct Binding *menu = km_get_table(CurrentMenu);
1248 
1249  if (!menu && (CurrentMenu != MENU_PAGER))
1250  menu = OpGeneric;
1251 
1252  pt++;
1253  /* first TAB. Collect all the matches */
1254  if (numtabs == 1)
1255  {
1256  NumMatched = 0;
1257  mutt_str_copy(UserTyped, pt, sizeof(UserTyped));
1258  memset(Matches, 0, MatchesListsize);
1259  memset(Completed, 0, sizeof(Completed));
1260  for (num = 0; menu[num].name; num++)
1261  candidate(UserTyped, menu[num].name, Completed, sizeof(Completed));
1262  /* try the generic menu */
1263  if ((Completed[0] == '\0') && (CurrentMenu != MENU_PAGER))
1264  {
1265  menu = OpGeneric;
1266  for (num = 0; menu[num].name; num++)
1267  candidate(UserTyped, menu[num].name, Completed, sizeof(Completed));
1268  }
1271 
1272  /* All matches are stored. Longest non-ambiguous string is ""
1273  * i.e. don't change 'buf'. Fake successful return this time */
1274  if (UserTyped[0] == '\0')
1275  return 1;
1276  }
1277 
1278  if ((Completed[0] == '\0') && (UserTyped[0] != '\0'))
1279  return 0;
1280 
1281  /* NumMatched will _always_ be at least 1 since the initial
1282  * user-typed string is always stored */
1283  if ((numtabs == 1) && (NumMatched == 2))
1284  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1285  else if ((numtabs > 1) && (NumMatched > 2))
1286  {
1287  /* cycle through all the matches */
1288  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1289  }
1290 
1291  strncpy(pt, Completed, buf + buflen - pt - spaces);
1292  }
1293  else
1294  return 0;
1295 
1296  return 1;
1297 }
union HashKey key
Key representing the data.
Definition: hash.h:46
struct HashElem ** get_elem_list(struct ConfigSet *cs)
Create a sorted list of all config items.
Definition: subset.c:64
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
static int NumMatched
Definition: init.c:85
const char * name
Name of the command.
Definition: mutt_commands.h:46
char * name
Name of user variable.
Definition: myvar.h:33
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define DTYPE(x)
Mask for the Data Type.
Definition: types.h:44
Pager pager (email viewer)
Definition: keymap.h:79
struct ConfigSet * cs
Parent ConfigSet.
Definition: subset.h:51
WHERE enum MenuType CurrentMenu
Current Menu, e.g. MENU_PAGER.
Definition: mutt_globals.h:78
const struct Binding OpGeneric[]
Key bindings for the generic menu.
Definition: functions.c:55
A user-set variable.
Definition: myvar.h:31
struct MyVarList MyVars
List of all the user&#39;s custom config variables.
Definition: myvar.c:34
const char * name
name of the function
Definition: keymap.h:120
#define SKIPWS(ch)
Definition: string2.h:46
static char Completed[256]
Definition: init.c:86
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:165
static int MatchesListsize
Definition: init.c:89
static void matches_ensure_morespace(int current)
Allocate more space for auto-completion.
Definition: init.c:102
#define DT_DEPRECATED
Config item shouldn&#39;t be used any more.
Definition: types.h:79
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
#define DT_SYNONYM
synonym for another variable
Definition: types.h:42
static char UserTyped[1024]
Definition: init.c:83
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:721
const char * strkey
String key.
Definition: hash.h:36
static const char ** Matches
Definition: init.c:87
const struct Binding * km_get_table(enum MenuType menu)
Lookup a menu&#39;s keybindings.
Definition: keymap.c:1265
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:45
#define FREE(x)
Definition: memory.h:40
The item stored in a Hash Table.
Definition: hash.h:43
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Mapping between a user key and a function.
Definition: keymap.h:118
const struct Command Commands[]
Definition: mutt_commands.c:50
static void candidate(char *user, const char *src, char *dest, size_t dlen)
helper function for completion
Definition: init.c:125
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_label_complete()

int mutt_label_complete ( char *  buf,
size_t  buflen,
int  numtabs 
)

Complete a label name.

Parameters
bufBuffer for the result
buflenLength of the buffer
numtabsNumber of times the user has hit 'tab'
Return values
1Success, a match
0Error, no match

Definition at line 1307 of file init.c.

1308 {
1309  char *pt = buf;
1310  int spaces; /* keep track of the number of leading spaces on the line */
1311 
1312  if (!Context || !Context->mailbox->label_hash)
1313  return 0;
1314 
1315  SKIPWS(buf);
1316  spaces = buf - pt;
1317 
1318  /* first TAB. Collect all the matches */
1319  if (numtabs == 1)
1320  {
1321  struct HashElem *entry = NULL;
1322  struct HashWalkState state = { 0 };
1323 
1324  NumMatched = 0;
1325  mutt_str_copy(UserTyped, buf, sizeof(UserTyped));
1326  memset(Matches, 0, MatchesListsize);
1327  memset(Completed, 0, sizeof(Completed));
1328  while ((entry = mutt_hash_walk(Context->mailbox->label_hash, &state)))
1329  candidate(UserTyped, entry->key.strkey, Completed, sizeof(Completed));
1331  qsort(Matches, NumMatched, sizeof(char *), (sort_t) mutt_istr_cmp);
1333 
1334  /* All matches are stored. Longest non-ambiguous string is ""
1335  * i.e. don't change 'buf'. Fake successful return this time */
1336  if (UserTyped[0] == '\0')
1337  return 1;
1338  }
1339 
1340  if ((Completed[0] == '\0') && (UserTyped[0] != '\0'))
1341  return 0;
1342 
1343  /* NumMatched will _always_ be at least 1 since the initial
1344  * user-typed string is always stored */
1345  if ((numtabs == 1) && (NumMatched == 2))
1346  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1347  else if ((numtabs > 1) && (NumMatched > 2))
1348  {
1349  /* cycle through all the matches */
1350  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1351  }
1352 
1353  /* return the completed label */
1354  strncpy(buf, Completed, buflen - spaces);
1355 
1356  return 1;
1357 }
int mutt_istr_cmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:585
The "current" mailbox.
Definition: context.h:37
union HashKey key
Key representing the data.
Definition: hash.h:46
static int NumMatched
Definition: init.c:85
struct HashTable * label_hash
Hash Table for x-labels.
Definition: mailbox.h:129
Cursor to iterate through a Hash Table.
Definition: hash.h:119
struct Mailbox * mailbox
Definition: context.h:50
#define SKIPWS(ch)
Definition: string2.h:46
static char Completed[256]
Definition: init.c:86
int(* sort_t)(const void *a, const void *b)
Prototype for a function to compare two emails.
Definition: sort.h:48
static int MatchesListsize
Definition: init.c:89
static void matches_ensure_morespace(int current)
Allocate more space for auto-completion.
Definition: init.c:102
static char UserTyped[1024]
Definition: init.c:83
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:721
const char * strkey
String key.
Definition: hash.h:36
static const char ** Matches
Definition: init.c:87
struct HashElem * mutt_hash_walk(const struct HashTable *table, struct HashWalkState *state)
Iterate through all the HashElem&#39;s in a Hash Table.
Definition: hash.c:479
The item stored in a Hash Table.
Definition: hash.h:43
static void candidate(char *user, const char *src, char *dest, size_t dlen)
helper function for completion
Definition: init.c:125
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_nm_query_complete()

bool mutt_nm_query_complete ( char *  buf,
size_t  buflen,
int  pos,
int  numtabs 
)

Complete to the nearest notmuch tag.

Parameters
bufBuffer for the result
buflenLength of the buffer
posCursor position in the buffer
numtabsNumber of times the user has hit 'tab'
Return values
trueSuccess, a match
falseError, no match

Complete the nearest "tag:"-prefixed string previous to pos.

Definition at line 1371 of file init.c.

1372 {
1373  char *pt = buf;
1374  int spaces;
1375 
1376  SKIPWS(buf);
1377  spaces = buf - pt;
1378 
1379  pt = (char *) mutt_strn_rfind((char *) buf, pos, "tag:");
1380  if (pt)
1381  {
1382  pt += 4;
1383  if (numtabs == 1)
1384  {
1385  /* First TAB. Collect all the matches */
1387 
1388  /* All matches are stored. Longest non-ambiguous string is ""
1389  * i.e. don't change 'buf'. Fake successful return this time. */
1390  if (UserTyped[0] == '\0')
1391  return true;
1392  }
1393 
1394  if ((Completed[0] == '\0') && (UserTyped[0] != '\0'))
1395  return false;
1396 
1397  /* NumMatched will _always_ be at least 1 since the initial
1398  * user-typed string is always stored */
1399  if ((numtabs == 1) && (NumMatched == 2))
1400  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1401  else if ((numtabs > 1) && (NumMatched > 2))
1402  {
1403  /* cycle through all the matches */
1404  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1405  }
1406 
1407  /* return the completed query */
1408  strncpy(pt, Completed, buf + buflen - pt - spaces);
1409  }
1410  else
1411  return false;
1412 
1413  return true;
1414 }
static int NumMatched
Definition: init.c:85
#define SKIPWS(ch)
Definition: string2.h:46
static char Completed[256]
Definition: init.c:86
static int complete_all_nm_tags(const char *pt)
Pass a list of Notmuch tags to the completion code.
Definition: init.c:154
static char UserTyped[1024]
Definition: init.c:83
static const char ** Matches
Definition: init.c:87
const char * mutt_strn_rfind(const char *haystack, size_t haystack_length, const char *needle)
Find last instance of a substring.
Definition: string.c:925
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_nm_tag_complete()

bool mutt_nm_tag_complete ( char *  buf,
size_t  buflen,
int  numtabs 
)

Complete to the nearest notmuch tag.

Parameters
bufBuffer for the result
buflenLength of the buffer
numtabsNumber of times the user has hit 'tab'
Return values
trueSuccess, a match
falseError, no match

Complete the nearest "+" or "-" -prefixed string previous to pos.

Definition at line 1428 of file init.c.

1429 {
1430  if (!buf)
1431  return false;
1432 
1433  char *pt = buf;
1434 
1435  /* Only examine the last token */
1436  char *last_space = strrchr(buf, ' ');
1437  if (last_space)
1438  pt = (last_space + 1);
1439 
1440  /* Skip the +/- */
1441  if ((pt[0] == '+') || (pt[0] == '-'))
1442  pt++;
1443 
1444  if (numtabs == 1)
1445  {
1446  /* First TAB. Collect all the matches */
1448 
1449  /* All matches are stored. Longest non-ambiguous string is ""
1450  * i.e. don't change 'buf'. Fake successful return this time. */
1451  if (UserTyped[0] == '\0')
1452  return true;
1453  }
1454 
1455  if ((Completed[0] == '\0') && (UserTyped[0] != '\0'))
1456  return false;
1457 
1458  /* NumMatched will _always_ be at least 1 since the initial
1459  * user-typed string is always stored */
1460  if ((numtabs == 1) && (NumMatched == 2))
1461  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1462  else if ((numtabs > 1) && (NumMatched > 2))
1463  {
1464  /* cycle through all the matches */
1465  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1466  }
1467 
1468  /* return the completed query */
1469  strncpy(pt, Completed, buf + buflen - pt);
1470 
1471  return true;
1472 }
static int NumMatched
Definition: init.c:85
static char Completed[256]
Definition: init.c:86
static int complete_all_nm_tags(const char *pt)
Pass a list of Notmuch tags to the completion code.
Definition: init.c:154
static char UserTyped[1024]
Definition: init.c:83
static const char ** Matches
Definition: init.c:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_var_value_complete()

int mutt_var_value_complete ( char *  buf,
size_t  buflen,
int  pos 
)

Complete a variable/value.

Parameters
bufBuffer for the result
buflenLength of the buffer
posCursor position in the buffer

Definition at line 1481 of file init.c.

1482 {
1483  char *pt = buf;
1484 
1485  if (buf[0] == '\0')
1486  return 0;
1487 
1488  SKIPWS(buf);
1489  const int spaces = buf - pt;
1490 
1491  pt = buf + pos - spaces;
1492  while ((pt > buf) && !isspace((unsigned char) *pt))
1493  pt--;
1494  pt++; /* move past the space */
1495  if (*pt == '=') /* abort if no var before the '=' */
1496  return 0;
1497 
1498  if (mutt_str_startswith(buf, "set"))
1499  {
1500  const char *myvarval = NULL;
1501  char var[256];
1502  mutt_str_copy(var, pt, sizeof(var));
1503  /* ignore the trailing '=' when comparing */
1504  int vlen = mutt_str_len(var);
1505  if (vlen == 0)
1506  return 0;
1507 
1508  var[vlen - 1] = '\0';
1509 
1510  struct HashElem *he = cs_subset_lookup(NeoMutt->sub, var);
1511  if (!he)
1512  {
1513  myvarval = myvar_get(var);
1514  if (myvarval)
1515  {
1516  struct Buffer pretty = mutt_buffer_make(256);
1517  pretty_var(myvarval, &pretty);
1518  snprintf(pt, buflen - (pt - buf), "%s=%s", var, pretty.data);
1519  mutt_buffer_dealloc(&pretty);
1520  return 1;
1521  }
1522  return 0; /* no such variable. */
1523  }
1524  else
1525  {
1526  struct Buffer value = mutt_buffer_make(256);
1527  struct Buffer pretty = mutt_buffer_make(256);
1528  int rc = cs_subset_he_string_get(NeoMutt->sub, he, &value);
1529  if (CSR_RESULT(rc) == CSR_SUCCESS)
1530  {
1531  pretty_var(value.data, &pretty);
1532  snprintf(pt, buflen - (pt - buf), "%s=%s", var, pretty.data);
1533  mutt_buffer_dealloc(&value);
1534  mutt_buffer_dealloc(&pretty);
1535  return 0;
1536  }
1537  mutt_buffer_dealloc(&value);
1538  mutt_buffer_dealloc(&pretty);
1539  return 1;
1540  }
1541  }
1542  return 0;
1543 }
#define CSR_RESULT(x)
Definition: set.h:52
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
String manipulation buffer.
Definition: buffer.h:33
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
struct HashElem * cs_subset_lookup(const struct ConfigSubset *sub, const char *name)
Find an inherited config item.
Definition: subset.c:168
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define SKIPWS(ch)
Definition: string2.h:46
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:165
char * data
Pointer to data.
Definition: buffer.h:35
const char * myvar_get(const char *var)
Get the value of a "my_" variable.
Definition: myvar.c:73
size_t pretty_var(const char *str, struct Buffer *buf)
Escape and stringify a config item value.
Definition: dump.c:83
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
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:721
The item stored in a Hash Table.
Definition: hash.h:43
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_config()

struct ConfigSet* init_config ( size_t  size)

Initialise the config system.

Parameters
sizeSize for Config Hash Table
Return values
ptrNew Config Set

Definition at line 1550 of file init.c.

1551 {
1552  typedef bool (*config_init_t)(struct ConfigSet * cs);
1553 
1554  static config_init_t config_list[] = {
1560  };
1561 
1562  struct ConfigSet *cs = cs_new(size);
1563 
1564  // Define the config types
1565  address_init(cs);
1566  bool_init(cs);
1567  enum_init(cs);
1568  long_init(cs);
1569  mbtable_init(cs);
1570  number_init(cs);
1571  path_init(cs);
1572  quad_init(cs);
1573  regex_init(cs);
1574  slist_init(cs);
1575  sort_init(cs);
1576  string_init(cs);
1577 
1578  for (size_t i = 0; config_list[i]; i++)
1579  {
1580  if (!config_list[i](cs))
1581  {
1582  cs_free(&cs);
1583  return NULL;
1584  }
1585  }
1586 
1587  return cs;
1588 }
bool config_init_mbox(struct ConfigSet *cs)
Register mbox config variables.
Definition: config.c:48
Container for lots of config items.
Definition: set.h:227
void quad_init(struct ConfigSet *cs)
Register the Quad-option config type.
Definition: quad.c:184
void bool_init(struct ConfigSet *cs)
Register the Bool config type.
Definition: bool.c:182
bool config_init_imap(struct ConfigSet *cs)
Register imap config variables.
Definition: config.c:93
void number_init(struct ConfigSet *cs)
Register the Number config type.
Definition: number.c:258
bool config_init_send(struct ConfigSet *cs)
Register send config variables.
Definition: config.c:226
bool config_init_conn(struct ConfigSet *cs)
Register conn config variables.
Definition: config.c:123
bool config_init_autocrypt(struct ConfigSet *cs)
Register autocrypt config variables.
Definition: config.c:59
void sort_init(struct ConfigSet *cs)
Register the Sort config type.
Definition: sort.c:369
bool config_init_nntp(struct ConfigSet *cs)
Register nntp config variables.
Definition: config.c:86
void enum_init(struct ConfigSet *cs)
Register the Enumeration config type.
Definition: enum.c:190
bool config_init_pop(struct ConfigSet *cs)
Register pop config variables.
Definition: config.c:67
bool config_init_hcache(struct ConfigSet *cs)
Register hcache config variables.
Definition: config.c:73
void mbtable_init(struct ConfigSet *cs)
Register the MbTable config type.
Definition: mbtable.c:281
bool config_init_maildir(struct ConfigSet *cs)
Register maildir config variables.
Definition: config.c:61
void slist_init(struct ConfigSet *cs)
Register the Slist config type.
Definition: slist.c:238
bool config_init_main(struct ConfigSet *cs)
Register main config variables.
Definition: mutt_config.c:305
void address_init(struct ConfigSet *cs)
Register the Address config type.
Definition: address.c:236
void string_init(struct ConfigSet *cs)
Register the String config type.
Definition: string.c:226
bool config_init_ncrypt(struct ConfigSet *cs)
Register ncrypt config variables.
Definition: config.c:220
bool config_init_notmuch(struct ConfigSet *cs)
Register notmuch config variables.
Definition: config.c:79
void cs_free(struct ConfigSet **ptr)
Free a Config Set.
Definition: set.c:172
struct ConfigSet * cs_new(size_t size)
Create a new Config Set.
Definition: set.c:158
void long_init(struct ConfigSet *cs)
Register the Long config type.
Definition: long.c:239
void regex_init(struct ConfigSet *cs)
Register the Regex config type.
Definition: regex.c:302
bool config_init_history(struct ConfigSet *cs)
Register history config variables.
Definition: config.c:55
void path_init(struct ConfigSet *cs)
Register the Path config type.
Definition: path.c:248
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ charset_validator()

int charset_validator ( const struct ConfigSet cs,
const struct ConfigDef cdef,
intptr_t  value,
struct Buffer err 
)

Validate the "charset" config variable - Implements ConfigDef::validator()

Definition at line 1593 of file init.c.

1595 {
1596  if (value == 0)
1597  return CSR_SUCCESS;
1598 
1599  const char *str = (const char *) value;
1600 
1601  if ((strcmp(cdef->name, "charset") == 0) && strchr(str, ':'))
1602  {
1604  err, _("'charset' must contain exactly one character set name"));
1605  return CSR_ERR_INVALID;
1606  }
1607 
1608  int rc = CSR_SUCCESS;
1609  bool strict = (strcmp(cdef->name, "send_charset") == 0);
1610  char *q = NULL;
1611  char *s = mutt_str_dup(str);
1612 
1613  for (char *p = strtok_r(s, ":", &q); p; p = strtok_r(NULL, ":", &q))
1614  {
1615  if (*p == '\0')
1616  continue;
1617  if (!mutt_ch_check_charset(p, strict))
1618  {
1619  rc = CSR_ERR_INVALID;
1620  mutt_buffer_printf(err, _("Invalid value for option %s: %s"), cdef->name, p);
1621  break;
1622  }
1623  }
1624 
1625  FREE(&s);
1626  return rc;
1627 }
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
#define _(a)
Definition: message.h:28
bool mutt_ch_check_charset(const char *cs, bool strict)
Does iconv understand a character set?
Definition: charset.c:818
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
const char * name
User-visible name.
Definition: set.h:65
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:38
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:

◆ hcache_validator()

int hcache_validator ( const struct ConfigSet cs,
const struct ConfigDef cdef,
intptr_t  value,
struct Buffer err 
)

Validate the "header_cache_backend" config variable - Implements ConfigDef::validator()

Definition at line 1633 of file init.c.

1635 {
1636  if (value == 0)
1637  return CSR_SUCCESS;
1638 
1639  const char *str = (const char *) value;
1640 
1641  if (store_is_valid_backend(str))
1642  return CSR_SUCCESS;
1643 
1644  mutt_buffer_printf(err, _("Invalid value for option %s: %s"), cdef->name, str);
1645  return CSR_ERR_INVALID;
1646 }
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
const char * name
User-visible name.
Definition: set.h:65
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:38
bool store_is_valid_backend(const char *str)
Is the string a valid Store backend.
Definition: store.c:129
+ Here is the call graph for this function:

◆ compress_method_validator()

int compress_method_validator ( const struct ConfigSet cs,
const struct ConfigDef cdef,
intptr_t  value,
struct Buffer err 
)

Validate the "header_cache_compress_method" config variable - Implements ConfigDef::validator()

Definition at line 1652 of file init.c.

1654 {
1655  if (value == 0)
1656  return CSR_SUCCESS;
1657 
1658  const char *str = (const char *) value;
1659 
1660  if (compress_get_ops(str))
1661  return CSR_SUCCESS;
1662 
1663  mutt_buffer_printf(err, _("Invalid value for option %s: %s"), cdef->name, str);
1664  return CSR_ERR_INVALID;
1665 }
const struct ComprOps * compress_get_ops(const char *compr)
Get the API functions for a compress backend.
Definition: compress.c:81
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
const char * name
User-visible name.
Definition: set.h:65
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:38
+ Here is the call graph for this function:

◆ compress_level_validator()

int compress_level_validator ( const struct ConfigSet cs,
const struct ConfigDef cdef,
intptr_t  value,
struct Buffer err 
)

Validate the "header_cache_compress_level" config variable - Implements ConfigDef::validator()

Definition at line 1669 of file init.c.

1671 {
1673  {
1674  mutt_buffer_printf(err, _("Set option %s before setting %s"),
1675  "header_cache_compress_method", cdef->name);
1676  return CSR_ERR_INVALID;
1677  }
1678 
1680  if (!cops)
1681  {
1682  mutt_buffer_printf(err, _("Invalid value for option %s: %s"),
1683  "header_cache_compress_method", C_HeaderCacheCompressMethod);
1684  return CSR_ERR_INVALID;
1685  }
1686 
1687  if ((value < cops->min_level) || (value > cops->max_level))
1688  {
1689  // L10N: This applies to the "$header_cache_compress_level" config variable.
1690  // It shows the minimum and maximum values, e.g. 'between 1 and 22'
1691  mutt_buffer_printf(err, _("Option %s must be between %d and %d inclusive"),
1692  cdef->name, cops->min_level, cops->max_level);
1693  return CSR_ERR_INVALID;
1694  }
1695 
1696  return CSR_SUCCESS;
1697 }
char * C_HeaderCacheCompressMethod
Config: (hcache) Enable generic hcache database compression.
Definition: config.c:41
const struct ComprOps * compress_get_ops(const char *compr)
Get the API functions for a compress backend.
Definition: compress.c:81
short max_level
Maximum compression level.
Definition: lib.h:59
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
const char * name
User-visible name.
Definition: set.h:65
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:38
Header Cache Compression API.
Definition: lib.h:55
short min_level
Minimum compression level.
Definition: lib.h:58
+ Here is the call graph for this function:

◆ pager_validator()

int pager_validator ( const struct ConfigSet cs,
const struct ConfigDef cdef,
intptr_t  value,
struct Buffer err 
)

Check for config variables that can't be set from the pager - Implements ConfigDef::validator()

Definition at line 1704 of file init.c.

1706 {
1707  if (CurrentMenu == MENU_PAGER)
1708  {
1709  mutt_buffer_printf(err, _("Option %s may not be set or reset from the pager"),
1710  cdef->name);
1711  return CSR_ERR_INVALID;
1712  }
1713 
1714  return CSR_SUCCESS;
1715 }
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
Pager pager (email viewer)
Definition: keymap.h:79
WHERE enum MenuType CurrentMenu
Current Menu, e.g. MENU_PAGER.
Definition: mutt_globals.h:78
const char * name
User-visible name.
Definition: set.h:65
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ multipart_validator()

int multipart_validator ( const struct ConfigSet cs,
const struct ConfigDef cdef,
intptr_t  value,
struct Buffer err 
)

Validate the "show_multipart_alternative" config variable - Implements ConfigDef::validator()

Definition at line 1720 of file init.c.

1722 {
1723  if (value == 0)
1724  return CSR_SUCCESS;
1725 
1726  const char *str = (const char *) value;
1727 
1728  if (mutt_str_equal(str, "inline") || mutt_str_equal(str, "info"))
1729  return CSR_SUCCESS;
1730 
1731  mutt_buffer_printf(err, _("Invalid value for option %s: %s"), cdef->name, str);
1732  return CSR_ERR_INVALID;
1733 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
const char * name
User-visible name.
Definition: set.h:65
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:38
+ Here is the call graph for this function:

◆ reply_validator()

int reply_validator ( const struct ConfigSet cs,
const struct ConfigDef cdef,
intptr_t  value,
struct Buffer err 
)

Validate the "reply_regex" config variable - Implements ConfigDef::validator()

Definition at line 1738 of file init.c.

1740 {
1741  if (pager_validator(cs, cdef, value, err) != CSR_SUCCESS)
1742  return CSR_ERR_INVALID;
1743 
1744  if (!OptAttachMsg)
1745  return CSR_SUCCESS;
1746 
1747  mutt_buffer_printf(err, _("Option %s may not be set when in attach-message mode"),
1748  cdef->name);
1749  return CSR_ERR_INVALID;
1750 }
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
const char * name
User-visible name.
Definition: set.h:65
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
WHERE bool OptAttachMsg
(pseudo) used by attach-message
Definition: options.h:31
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:38
int pager_validator(const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Check for config variables that can&#39;t be set from the pager - Implements ConfigDef::validator() ...
Definition: init.c:1704
+ Here is the call graph for this function:

Variable Documentation

◆ UserTyped

char UserTyped[1024] = { 0 }
static

Definition at line 83 of file init.c.

◆ NumMatched

int NumMatched = 0
static

Definition at line 85 of file init.c.

◆ Completed

char Completed[256] = { 0 }
static

Definition at line 86 of file init.c.

◆ Matches

const char** Matches
static

Definition at line 87 of file init.c.

◆ MatchesListsize

int MatchesListsize = 512
static

Definition at line 89 of file init.c.

◆ nm_tags

char** nm_tags
static

Definition at line 93 of file init.c.