NeoMutt  2020-03-20-65-g141838
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 "conn/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "init.h"
#include "alias.h"
#include "command_parse.h"
#include "context.h"
#include "functions.h"
#include "globals.h"
#include "keymap.h"
#include "mutt_commands.h"
#include "mutt_config.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 "compress/lib.h"
#include "history/lib.h"
#include "store/lib.h"
#include "hcache/lib.h"
#include "notmuch/lib.h"
+ Include dependency graph for init.c:

Go to the source code of this file.

Functions

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_line (char *line, struct Buffer *token, struct Buffer *err)
 Parse a line of user config. More...
 
int mutt_query_variables (struct ListHead *queries)
 Implement the -Q command line flag. More...
 
enum QuadOption query_quadoption (enum QuadOption opt, const char *prompt)
 Ask the user a quad-question. 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_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 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...
 
int wrapheaders_validator (const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
 Validate the "wrap_headers" 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

◆ matches_ensure_morespace()

static void matches_ensure_morespace ( int  current)
static

Allocate more space for auto-completion.

Parameters
currentCurrent allocation

Definition at line 94 of file init.c.

95 {
96  if (current <= (MatchesListsize - 2))
97  return;
98 
99  int base_space = 512; // Enough space for all of the config items
100  int extra_space = MatchesListsize - base_space;
101  extra_space *= 2;
102  const int space = base_space + extra_space;
103  mutt_mem_realloc(&Matches, space * sizeof(char *));
104  memset(&Matches[current + 1], 0, space - current);
105  MatchesListsize = space;
106 }
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:83
static const char ** Matches
Definition: init.c:81
+ 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 117 of file init.c.

118 {
119  if (!dest || !user || !src)
120  return;
121 
122  if (strstr(src, user) != src)
123  return;
124 
126  Matches[NumMatched++] = src;
127  if (dest[0] == '\0')
128  mutt_str_strfcpy(dest, src, dlen);
129  else
130  {
131  int l;
132  for (l = 0; src[l] && src[l] == dest[l]; l++)
133  ;
134  dest[l] = '\0';
135  }
136 }
static int NumMatched
Definition: init.c:79
static void matches_ensure_morespace(int current)
Allocate more space for auto-completion.
Definition: init.c:94
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
static const char ** Matches
Definition: init.c:81
+ 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 145 of file init.c.

146 {
147  int tag_count_1 = 0;
148  int tag_count_2 = 0;
149 
150  NumMatched = 0;
151  mutt_str_strfcpy(UserTyped, pt, sizeof(UserTyped));
152  memset(Matches, 0, MatchesListsize);
153  memset(Completed, 0, sizeof(Completed));
154 
156 
157  /* Work out how many tags there are. */
158  if (nm_get_all_tags(Context->mailbox, NULL, &tag_count_1) || (tag_count_1 == 0))
159  goto done;
160 
161  /* Free the old list, if any. */
162  if (nm_tags)
163  {
164  for (int i = 0; nm_tags[i]; i++)
165  FREE(&nm_tags[i]);
166  FREE(&nm_tags);
167  }
168  /* Allocate a new list, with sentinel. */
169  nm_tags = mutt_mem_malloc((tag_count_1 + 1) * sizeof(char *));
170  nm_tags[tag_count_1] = NULL;
171 
172  /* Get all the tags. */
173  if (nm_get_all_tags(Context->mailbox, nm_tags, &tag_count_2) || (tag_count_1 != tag_count_2))
174  {
175  FREE(&nm_tags);
176  nm_tags = NULL;
178  return -1;
179  }
180 
181  /* Put them into the completion machinery. */
182  for (int num = 0; num < tag_count_1; num++)
183  {
184  candidate(UserTyped, nm_tags[num], Completed, sizeof(Completed));
185  }
186 
189 
190 done:
192  return 0;
193 }
The "current" mailbox.
Definition: context.h:37
static int NumMatched
Definition: init.c:79
static char ** nm_tags
Definition: init.c:87
struct Mailbox * mailbox
Definition: context.h:51
static char Completed[256]
Definition: init.c:80
static int MatchesListsize
Definition: init.c:83
static void matches_ensure_morespace(int current)
Allocate more space for auto-completion.
Definition: init.c:94
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
int nm_get_all_tags(struct Mailbox *m, char **tag_list, int *tag_count)
Fill a list with all notmuch tags.
static char UserTyped[1024]
Definition: init.c:77
static const char ** Matches
Definition: init.c:81
void nm_db_longrun_done(struct Mailbox *m)
Finish a long transaction.
Definition: nm_db.c:304
#define FREE(x)
Definition: memory.h:40
void nm_db_longrun_init(struct Mailbox *m, bool writable)
Start a long transaction.
Definition: nm_db.c:289
static void candidate(char *user, const char *src, char *dest, size_t dlen)
helper function for completion
Definition: init.c:117
+ 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 202 of file init.c.

203 {
204  int rc = 0;
205  struct Buffer *err = mutt_buffer_pool_get();
206  struct Buffer *token = mutt_buffer_pool_get();
207 
208  struct ListNode *np = NULL;
209  STAILQ_FOREACH(np, p, entries)
210  {
211  enum CommandResult rc2 = mutt_parse_rc_line(np->data, token, err);
212  if (rc2 == MUTT_CMD_ERROR)
213  mutt_error(_("Error in command line: %s"), mutt_b2s(err));
214  else if (rc2 == MUTT_CMD_WARNING)
215  mutt_warning(_("Warning in command line: %s"), mutt_b2s(err));
216 
217  if ((rc2 == MUTT_CMD_ERROR) || (rc2 == MUTT_CMD_WARNING))
218  {
219  mutt_buffer_pool_release(&token);
221  return -1;
222  }
223  }
224  mutt_buffer_pool_release(&token);
226 
227  return rc;
228 }
#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
#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:35
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:33
enum CommandResult mutt_parse_rc_line(char *line, struct Buffer *token, struct Buffer *err)
Parse a line of user config.
Definition: init.c:991
+ 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 237 of file init.c.

238 {
239  const char *names[] = {
240  "neomuttrc",
241  "muttrc",
242  NULL,
243  };
244 
245  const char *locations[][2] = {
246  { xdg_cfg_home, "neomutt/" },
247  { xdg_cfg_home, "mutt/" },
248  { home, ".neomutt/" },
249  { home, ".mutt/" },
250  { home, "." },
251  { NULL, NULL },
252  };
253 
254  for (int i = 0; locations[i][0] || locations[i][1]; i++)
255  {
256  if (!locations[i][0])
257  continue;
258 
259  for (int j = 0; names[j]; j++)
260  {
261  char buf[256];
262 
263  snprintf(buf, sizeof(buf), "%s/%s%s", locations[i][0], locations[i][1], names[j]);
264  if (access(buf, F_OK) == 0)
265  return mutt_str_strdup(buf);
266  }
267  }
268 
269  return NULL;
270 }
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
+ 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 278 of file init.c.

279 {
280  char *mailname = NULL;
281  static const char *mn_files[] = { "/etc/mailname", "/etc/mail/mailname" };
282 
283  for (size_t i = 0; i < mutt_array_size(mn_files); i++)
284  {
285  FILE *fp = mutt_file_fopen(mn_files[i], "r");
286  if (!fp)
287  continue;
288 
289  size_t len = 0;
290  mailname = mutt_file_read_line(NULL, &len, fp, NULL, 0);
291  mutt_file_fclose(&fp);
292  if (mailname && *mailname)
293  break;
294 
295  FREE(&mailname);
296  }
297 
298  return mailname;
299 }
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 310 of file init.c.

311 {
312  char *str = NULL;
313  struct utsname utsname;
314 
315  if (C_Hostname)
316  {
317  str = C_Hostname;
318  }
319  else
320  {
321  /* The call to uname() shouldn't fail, but if it does, the system is horribly
322  * broken, and the system's networking configuration is in an unreliable
323  * state. We should bail. */
324  if ((uname(&utsname)) == -1)
325  {
326  mutt_perror(_("unable to determine nodename via uname()"));
327  return false; // TEST09: can't test
328  }
329 
330  str = utsname.nodename;
331  }
332 
333  /* some systems report the FQDN instead of just the hostname */
334  char *dot = strchr(str, '.');
335  if (dot)
337  else
339 
340  if (!C_Hostname)
341  {
342  /* now get FQDN. Use configured domain first, DNS next, then uname */
343 #ifdef DOMAIN
344  /* we have a compile-time domain name, use that for C_Hostname */
345  C_Hostname =
347  sprintf((char *) C_Hostname, "%s.%s", NONULL(ShortHostname), DOMAIN);
348 #else
349  C_Hostname = getmailname();
350  if (!C_Hostname)
351  {
352  char buffer[1024];
353  if (getdnsdomainname(buffer, sizeof(buffer)) == 0)
354  {
355  C_Hostname = mutt_mem_malloc(mutt_str_strlen(buffer) +
357  sprintf((char *) C_Hostname, "%s.%s", NONULL(ShortHostname), buffer);
358  }
359  else
360  {
361  /* DNS failed, use the nodename. Whether or not the nodename had a '.'
362  * in it, we can use the nodename as the FQDN. On hosts where DNS is
363  * not being used, e.g. small network that relies on hosts files, a
364  * short host name is all that is required for SMTP to work correctly.
365  * It could be wrong, but we've done the best we can, at this point the
366  * onus is on the user to provide the correct hostname if the nodename
367  * won't work in their network. */
368  C_Hostname = mutt_str_strdup(utsname.nodename);
369  }
370  }
371 #endif
372  }
373  if (C_Hostname)
374  cs_str_initial_set(cs, "hostname", C_Hostname, NULL);
375 
376  return true;
377 }
#define NONULL(x)
Definition: string2.h:37
#define mutt_perror(...)
Definition: logging.h:85
static char * getmailname(void)
Try to retrieve the FQDN from mailname files.
Definition: init.c:278
#define _(a)
Definition: message.h:28
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
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:453
static int const char char buffer[256]
Definition: acutest.h:474
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
WHERE char * ShortHostname
Short version of the hostname.
Definition: globals.h:50
WHERE char * C_Hostname
Config: Fully-qualified domain name of this machine.
Definition: globals.h:113
char * mutt_str_substr_dup(const char *begin, const char *end)
Duplicate a sub-string.
Definition: string.c:602
int getdnsdomainname(char *buf, size_t buflen)
Lookup the host&#39;s name using DNS.
Definition: getdomain.c:45
+ 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 385 of file init.c.

386 {
387  for (int i = 0; Commands[i].name; i++)
388  if (mutt_str_strcmp(s, Commands[i].name) == 0)
389  return &Commands[i];
390  return NULL;
391 }
const char * name
Name of the command.
Definition: mutt_commands.h:46
const char * name
Definition: pgpmicalg.c:46
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
const struct Command Commands[]
Definition: mutt_commands.c:46
+ 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 401 of file init.c.

402 {
403  for (int i = 0; Commands[i].name; i++)
404  application(data, &Commands[i]);
405 }
const char * name
Name of the command.
Definition: mutt_commands.h:46
const struct Command Commands[]
Definition: mutt_commands.c:46
+ 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 416 of file init.c.

417 {
418  if (!dest || !tok)
419  return -1;
420 
421  char ch;
422  char qc = '\0'; /* quote char */
423  char *pc = NULL;
424 
425  mutt_buffer_reset(dest);
426 
427  SKIPWS(tok->dptr);
428  while ((ch = *tok->dptr))
429  {
430  if (qc == '\0')
431  {
432  if ((IS_SPACE(ch) && !(flags & MUTT_TOKEN_SPACE)) ||
433  ((ch == '#') && !(flags & MUTT_TOKEN_COMMENT)) ||
434  ((ch == '=') && (flags & MUTT_TOKEN_EQUAL)) ||
435  ((ch == '?') && (flags & MUTT_TOKEN_QUESTION)) ||
436  ((ch == ';') && !(flags & MUTT_TOKEN_SEMICOLON)) ||
437  ((flags & MUTT_TOKEN_PATTERN) && strchr("~%=!|", ch)))
438  {
439  break;
440  }
441  }
442 
443  tok->dptr++;
444 
445  if (ch == qc)
446  qc = 0; /* end of quote */
447  else if (!qc && ((ch == '\'') || (ch == '"')) && !(flags & MUTT_TOKEN_QUOTE))
448  qc = ch;
449  else if ((ch == '\\') && (qc != '\''))
450  {
451  if (tok->dptr[0] == '\0')
452  return -1; /* premature end of token */
453  switch (ch = *tok->dptr++)
454  {
455  case 'c':
456  case 'C':
457  if (tok->dptr[0] == '\0')
458  return -1; /* premature end of token */
459  mutt_buffer_addch(dest, (toupper((unsigned char) tok->dptr[0]) - '@') & 0x7f);
460  tok->dptr++;
461  break;
462  case 'e':
463  mutt_buffer_addch(dest, '\033'); // Escape
464  break;
465  case 'f':
466  mutt_buffer_addch(dest, '\f');
467  break;
468  case 'n':
469  mutt_buffer_addch(dest, '\n');
470  break;
471  case 'r':
472  mutt_buffer_addch(dest, '\r');
473  break;
474  case 't':
475  mutt_buffer_addch(dest, '\t');
476  break;
477  default:
478  if (isdigit((unsigned char) ch) && isdigit((unsigned char) tok->dptr[0]) &&
479  isdigit((unsigned char) tok->dptr[1]))
480  {
481  mutt_buffer_addch(dest, (ch << 6) + (tok->dptr[0] << 3) + tok->dptr[1] - 3504);
482  tok->dptr += 2;
483  }
484  else
485  mutt_buffer_addch(dest, ch);
486  }
487  }
488  else if ((ch == '^') && (flags & MUTT_TOKEN_CONDENSE))
489  {
490  if (tok->dptr[0] == '\0')
491  return -1; /* premature end of token */
492  ch = *tok->dptr++;
493  if (ch == '^')
494  mutt_buffer_addch(dest, ch);
495  else if (ch == '[')
496  mutt_buffer_addch(dest, '\033'); // Escape
497  else if (isalpha((unsigned char) ch))
498  mutt_buffer_addch(dest, toupper((unsigned char) ch) - '@');
499  else
500  {
501  mutt_buffer_addch(dest, '^');
502  mutt_buffer_addch(dest, ch);
503  }
504  }
505  else if ((ch == '`') && (!qc || (qc == '"')))
506  {
507  FILE *fp = NULL;
508  pid_t pid;
509  int line = 0;
510 
511  pc = tok->dptr;
512  do
513  {
514  pc = strpbrk(pc, "\\`");
515  if (pc)
516  {
517  /* skip any quoted chars */
518  if (*pc == '\\')
519  pc += 2;
520  }
521  } while (pc && (pc[0] != '`'));
522  if (!pc)
523  {
524  mutt_debug(LL_DEBUG1, "mismatched backticks\n");
525  return -1;
526  }
527  struct Buffer cmd;
528  mutt_buffer_init(&cmd);
529  *pc = '\0';
530  if (flags & MUTT_TOKEN_BACKTICK_VARS)
531  {
532  /* recursively extract tokens to interpolate variables */
533  mutt_extract_token(&cmd, tok,
534  MUTT_TOKEN_QUOTE | MUTT_TOKEN_SPACE | MUTT_TOKEN_COMMENT |
535  MUTT_TOKEN_SEMICOLON | MUTT_TOKEN_NOSHELL);
536  }
537  else
538  {
539  cmd.data = mutt_str_strdup(tok->dptr);
540  }
541  *pc = '`';
542  pid = filter_create(cmd.data, NULL, &fp, NULL);
543  if (pid < 0)
544  {
545  mutt_debug(LL_DEBUG1, "unable to fork command: %s\n", cmd.data);
546  FREE(&cmd.data);
547  return -1;
548  }
549  FREE(&cmd.data);
550 
551  tok->dptr = pc + 1;
552 
553  /* read line */
554  struct Buffer expn = mutt_buffer_make(0);
555  expn.data = mutt_file_read_line(NULL, &expn.dsize, fp, &line, 0);
556  mutt_file_fclose(&fp);
557  filter_wait(pid);
558 
559  /* if we got output, make a new string consisting of the shell output
560  * plus whatever else was left on the original line */
561  /* BUT: If this is inside a quoted string, directly add output to
562  * the token */
563  if (expn.data)
564  {
565  if (qc)
566  {
567  mutt_buffer_addstr(dest, expn.data);
568  }
569  else
570  {
571  struct Buffer *copy = mutt_buffer_pool_get();
572  mutt_buffer_fix_dptr(&expn);
573  mutt_buffer_copy(copy, &expn);
574  mutt_buffer_addstr(copy, tok->dptr);
575  mutt_buffer_copy(tok, copy);
576  tok->dptr = tok->data;
578  }
579  FREE(&expn.data);
580  }
581  }
582  else if ((ch == '$') && (!qc || (qc == '"')) &&
583  ((tok->dptr[0] == '{') || isalpha((unsigned char) tok->dptr[0])))
584  {
585  const char *env = NULL;
586  char *var = NULL;
587 
588  if (tok->dptr[0] == '{')
589  {
590  pc = strchr(tok->dptr, '}');
591  if (pc)
592  {
593  var = mutt_str_substr_dup(tok->dptr + 1, pc);
594  tok->dptr = pc + 1;
595 
596  if ((flags & MUTT_TOKEN_NOSHELL))
597  {
598  mutt_buffer_addch(dest, ch);
599  mutt_buffer_addch(dest, '{');
600  mutt_buffer_addstr(dest, var);
601  mutt_buffer_addch(dest, '}');
602  FREE(&var);
603  }
604  }
605  }
606  else
607  {
608  for (pc = tok->dptr; isalnum((unsigned char) *pc) || (pc[0] == '_'); pc++)
609  ;
610  var = mutt_str_substr_dup(tok->dptr, pc);
611  tok->dptr = pc;
612  }
613  if (var)
614  {
615  struct Buffer result;
616  mutt_buffer_init(&result);
617  int rc = cs_subset_str_string_get(NeoMutt->sub, var, &result);
618 
619  if (CSR_RESULT(rc) == CSR_SUCCESS)
620  {
621  mutt_buffer_addstr(dest, result.data);
622  FREE(&result.data);
623  }
624  else if ((env = myvar_get(var)))
625  {
626  mutt_buffer_addstr(dest, env);
627  }
628  else if (!(flags & MUTT_TOKEN_NOSHELL) && (env = mutt_str_getenv(var)))
629  {
630  mutt_buffer_addstr(dest, env);
631  }
632  else
633  {
634  mutt_buffer_addch(dest, ch);
635  mutt_buffer_addstr(dest, var);
636  }
637  FREE(&var);
638  }
639  }
640  else
641  mutt_buffer_addch(dest, ch);
642  }
643  mutt_buffer_addch(dest, 0); /* terminate the string */
644  SKIPWS(tok->dptr);
645  return 0;
646 }
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_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:35
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:1071
size_t dsize
Length of data.
Definition: buffer.h:37
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
#define SKIPWS(ch)
Definition: string2.h:47
#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:36
#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:416
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
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
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#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:38
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
int const char int line
Definition: acutest.h:602
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
char * mutt_str_substr_dup(const char *begin, const char *end)
Duplicate a sub-string.
Definition: string.c:602
#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 651 of file init.c.

652 {
654 
655  mutt_aliaslist_free(&Aliases);
656 
657  mutt_regexlist_free(&Alternates);
661  mutt_regexlist_free(&UnAlternates);
664 
669 
670  /* Lists of strings */
671  mutt_list_free(&AlternativeOrderList);
672  mutt_list_free(&AutoViewList);
673  mutt_list_free(&HeaderOrderList);
676  mutt_list_free(&MimeLookupList);
677  mutt_list_free(&Muttrc);
678 #ifdef USE_SIDEBAR
679  mutt_list_free(&SidebarWhitelist);
680 #endif
682  mutt_list_free(&UserHeader);
683 
684  /* Lists of AttachMatch */
689 
691 
693  FREE(&HomeDir);
694  FREE(&LastFolder);
696  FREE(&Username);
697 
700 
702 
703  mutt_hist_free();
704  mutt_keys_free();
705 
707 }
WHERE char * Username
User&#39;s login name.
Definition: globals.h:52
void mutt_aliaslist_free(struct AliasList *a_list)
Free a List of Aliases.
Definition: alias.c:762
struct Hash * TagTransforms
Lookup table of alternative tag names.
Definition: tags.c:38
struct ListHead InlineAllow
List of inline types to counted.
Definition: mutt_parse.c:41
struct ReplaceList SpamList
List of regexes and patterns to match spam emails.
Definition: email_globals.c:44
void mutt_list_free_type(struct ListHead *h, list_free_t fn)
Free a List of type.
Definition: list.c:145
struct ListHead MailToAllow
List of permitted fields in a mailto: url.
Definition: email_globals.c:47
WHERE struct Hash * TagFormats
Hash table of tag-formats (tag -> format string)
Definition: globals.h:60
void mutt_delete_hooks(HookFlags type)
Delete matching hooks.
Definition: hook.c:308
WHERE char * LastFolder
Previously selected mailbox.
Definition: globals.h:55
struct ListHead UnIgnore
List of header patterns to unignore (see)
Definition: email_globals.c:46
void mutt_replacelist_free(struct ReplaceList *rl)
Free a ReplaceList object.
Definition: regex.c:447
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:123
char * HomeDir
User&#39;s home directory.
Definition: globals.h:49
void clear_source_stack(void)
Free memory from the stack used for the souce command.
WHERE char * CurrentFolder
Currently selected mailbox.
Definition: globals.h:54
struct ListHead InlineExclude
List of inline types to ignore.
Definition: mutt_parse.c:42
void mutt_keys_free(void)
Free the key maps.
Definition: keymap.c:1643
struct RegexList MailLists
List of regexes to match mailing lists.
Definition: email_globals.c:50
struct RegexList SubscribedLists
List of regexes to match subscribed mailing lists.
Definition: email_globals.c:52
Definition: color.h:130
WHERE struct Hash * ReverseAliases
Hash table of aliases (email address -> alias)
Definition: globals.h:59
void mutt_colors_free(struct Colors **ptr)
Free all the colours.
Definition: color.c:356
struct ListHead AttachExclude
List of attachment types to be ignored.
Definition: mutt_parse.c:40
WHERE char * ShortHostname
Short version of the hostname.
Definition: globals.h:50
#define FREE(x)
Definition: memory.h:40
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:44
struct RegexList UnMailLists
List of regexes to blacklist false matches in MailLists.
Definition: email_globals.c:51
void mutt_attachmatch_free(struct AttachMatch **ptr)
Free an AttachMatch - Implements list_free_t.
Definition: mutt_parse.c:241
void mutt_grouplist_free(void)
Free GroupList singleton resource.
Definition: group.c:55
void mutt_hash_free(struct Hash **ptr)
Free a hash table.
Definition: hash.c:471
struct ListHead AttachAllow
List of attachment types to be counted.
Definition: mutt_parse.c:39
struct RegexList NoSpamList
List of regexes to whitelist non-spam emails.
Definition: email_globals.c:43
void mutt_hist_free(void)
Free all the history lists.
Definition: history.c:430
struct ListHead Ignore
List of header patterns to ignore.
Definition: email_globals.c:45
void mutt_regexlist_free(struct RegexList *rl)
Free a RegexList object.
Definition: regex.c:170
void(* list_free_t)(void **ptr)
Prototype for a function to free List data.
Definition: list.h:44
struct RegexList UnSubscribedLists
List of regexes to blacklist false matches in SubscribedLists.
Definition: email_globals.c:49
struct ReplaceList SubjectRegexList
List of regexes to tidy the view of the email&#39;s subject.
Definition: email_globals.c:53
+ 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 715 of file init.c.

716 {
717  for (const struct Command *c = Commands; c->name; c++)
718  {
719  if (((c->parse == mutt_parse_hook) || (c->parse == mutt_parse_idxfmt_hook)) &&
720  (mutt_str_strcasecmp(c->name, name) == 0))
721  {
722  return c->data;
723  }
724  }
725  return MUTT_HOOK_NO_FLAGS;
726 }
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:86
A user-callable command.
Definition: mutt_commands.h:44
const char * name
Name of the command.
Definition: mutt_commands.h:46
const char * name
Definition: pgpmicalg.c:46
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
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:355
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:44
const struct Command Commands[]
Definition: mutt_commands.c:46
+ 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 736 of file init.c.

737 {
738  char buf[1024];
739  int need_pause = 0;
740  int rc = 1;
741  struct Buffer err = mutt_buffer_make(256);
742 
744  /* reverse alias keys need to be strdup'ed because of idna conversions */
749 
750  mutt_menu_init();
751 
752  snprintf(AttachmentMarker, sizeof(AttachmentMarker), "\033]9;%" PRIu64 "\a", // Escape
753  mutt_rand64());
754 
755  snprintf(ProtectedHeaderMarker, sizeof(ProtectedHeaderMarker), "\033]8;%lld\a", // Escape
756  (long long) mutt_date_epoch());
757 
758  /* "$spoolfile" precedence: config file, environment */
759  const char *p = mutt_str_getenv("MAIL");
760  if (!p)
761  p = mutt_str_getenv("MAILDIR");
762  if (!p)
763  {
764 #ifdef HOMESPOOL
765  mutt_path_concat(buf, NONULL(HomeDir), MAILPATH, sizeof(buf));
766 #else
767  mutt_path_concat(buf, MAILPATH, NONULL(Username), sizeof(buf));
768 #endif
769  p = buf;
770  }
771  cs_str_initial_set(cs, "spoolfile", p, NULL);
772  cs_str_reset(cs, "spoolfile", NULL);
773 
774  p = mutt_str_getenv("REPLYTO");
775  if (p)
776  {
777  struct Buffer tmp, token;
778 
779  snprintf(buf, sizeof(buf), "Reply-To: %s", p);
780 
781  mutt_buffer_init(&tmp);
782  tmp.data = buf;
783  tmp.dptr = buf;
784  tmp.dsize = mutt_str_strlen(buf);
785 
786  mutt_buffer_init(&token);
787  parse_my_hdr(&token, &tmp, 0, &err); /* adds to UserHeader */
788  FREE(&token.data);
789  }
790 
791  p = mutt_str_getenv("EMAIL");
792  if (p)
793  {
794  cs_str_initial_set(cs, "from", p, NULL);
795  cs_str_reset(cs, "from", NULL);
796  }
797 
798  /* "$mailcap_path" precedence: config file, environment, code */
799  const char *env_mc = mutt_str_getenv("MAILCAPS");
800  if (env_mc)
801  cs_str_string_set(cs, "mailcap_path", env_mc, NULL);
802 
803  /* "$tmpdir" precedence: config file, environment, code */
804  const char *env_tmp = mutt_str_getenv("TMPDIR");
805  if (env_tmp)
806  cs_str_string_set(cs, "tmpdir", env_tmp, NULL);
807 
808  /* "$visual", "$editor" precedence: config file, environment, code */
809  const char *env_ed = mutt_str_getenv("VISUAL");
810  if (!env_ed)
811  env_ed = mutt_str_getenv("EDITOR");
812  if (env_ed)
813  {
814  cs_str_string_set(cs, "editor", env_ed, NULL);
815  cs_str_string_set(cs, "visual", env_ed, NULL);
816  }
817 
819  cs_str_initial_set(cs, "charset", C_Charset, NULL);
821 
822  Matches = mutt_mem_calloc(MatchesListsize, sizeof(char *));
823 
825 
826 #ifdef HAVE_GETSID
827  /* Unset suspend by default if we're the session leader */
828  if (getsid(0) == getpid())
829  C_Suspend = false;
830 #endif
831 
832  /* RFC2368, "4. Unsafe headers"
833  * The creator of a mailto URL can't expect the resolver of a URL to
834  * understand more than the "subject" and "body" headers. Clients that
835  * resolve mailto URLs into mail messages should be able to correctly
836  * create RFC822-compliant mail messages using the "subject" and "body"
837  * headers. */
838  add_to_stailq(&MailToAllow, "body");
839  add_to_stailq(&MailToAllow, "subject");
840  /* Cc, In-Reply-To, and References help with not breaking threading on
841  * mailing lists, see https://github.com/neomutt/neomutt/issues/115 */
842  add_to_stailq(&MailToAllow, "cc");
843  add_to_stailq(&MailToAllow, "in-reply-to");
844  add_to_stailq(&MailToAllow, "references");
845 
846  if (STAILQ_EMPTY(&Muttrc))
847  {
848  const char *xdg_cfg_home = mutt_str_getenv("XDG_CONFIG_HOME");
849 
850  if (!xdg_cfg_home && HomeDir)
851  {
852  snprintf(buf, sizeof(buf), "%s/.config", HomeDir);
853  xdg_cfg_home = buf;
854  }
855 
856  char *config = find_cfg(HomeDir, xdg_cfg_home);
857  if (config)
858  {
859  mutt_list_insert_tail(&Muttrc, config);
860  }
861  }
862  else
863  {
864  struct ListNode *np = NULL;
865  STAILQ_FOREACH(np, &Muttrc, entries)
866  {
867  mutt_str_strfcpy(buf, np->data, sizeof(buf));
868  FREE(&np->data);
869  mutt_expand_path(buf, sizeof(buf));
870  np->data = mutt_str_strdup(buf);
871  if (access(np->data, F_OK))
872  {
873  mutt_perror(np->data);
874  goto done; // TEST10: neomutt -F missing
875  }
876  }
877  }
878 
879  if (!STAILQ_EMPTY(&Muttrc))
880  {
881  cs_str_string_set(cs, "alias_file", STAILQ_FIRST(&Muttrc)->data, NULL);
882  }
883 
884  /* Process the global rc file if it exists and the user hasn't explicitly
885  * requested not to via "-n". */
886  if (!skip_sys_rc)
887  {
888  do
889  {
890  if (mutt_set_xdg_path(XDG_CONFIG_DIRS, buf, sizeof(buf)))
891  break;
892 
893  snprintf(buf, sizeof(buf), "%s/neomuttrc", SYSCONFDIR);
894  if (access(buf, F_OK) == 0)
895  break;
896 
897  snprintf(buf, sizeof(buf), "%s/Muttrc", SYSCONFDIR);
898  if (access(buf, F_OK) == 0)
899  break;
900 
901  snprintf(buf, sizeof(buf), "%s/neomuttrc", PKGDATADIR);
902  if (access(buf, F_OK) == 0)
903  break;
904 
905  snprintf(buf, sizeof(buf), "%s/Muttrc", PKGDATADIR);
906  } while (false);
907 
908  if (access(buf, F_OK) == 0)
909  {
910  if (source_rc(buf, &err) != 0)
911  {
912  mutt_error("%s", err.data);
913  need_pause = 1; // TEST11: neomutt (error in /etc/neomuttrc)
914  }
915  }
916  }
917 
918  /* Read the user's initialization file. */
919  struct ListNode *np = NULL;
920  STAILQ_FOREACH(np, &Muttrc, entries)
921  {
922  if (np->data)
923  {
924  if (source_rc(np->data, &err) != 0)
925  {
926  mutt_error("%s", err.data);
927  need_pause = 1; // TEST12: neomutt (error in ~/.neomuttrc)
928  }
929  }
930  }
931 
932  if (execute_commands(commands) != 0)
933  need_pause = 1; // TEST13: neomutt -e broken
934 
935  if (!get_hostname(cs))
936  goto done;
937 
938  if (!C_Realname)
939  {
940  struct passwd *pw = getpwuid(getuid());
941  if (pw)
942  {
943  char name[256];
944  C_Realname = mutt_str_strdup(mutt_gecos_name(name, sizeof(name), pw));
945  }
946  }
947  cs_str_initial_set(cs, "realname", C_Realname, NULL);
948 
949  if (need_pause && !OptNoCurses)
950  {
952  if (mutt_any_key_to_continue(NULL) == 'q')
953  goto done; // TEST14: neomutt -e broken (press 'q')
954  }
955 
956  mutt_file_mkdir(C_Tmpdir, S_IRWXU);
957 
958  mutt_hist_init();
960 
961 #ifdef USE_NOTMUCH
962  if (C_VirtualSpoolfile)
963  {
964  /* Find the first virtual folder and open it */
965  struct MailboxList ml = neomutt_mailboxlist_get_all(NeoMutt, MUTT_NOTMUCH);
966  struct MailboxNode *mp = STAILQ_FIRST(&ml);
967  if (mp)
968  cs_str_string_set(cs, "spoolfile", mailbox_path(mp->mailbox), NULL);
970  }
971 #endif
972  rc = 0;
973 
974 done:
975  FREE(&err.data);
976  return rc;
977 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:411
WHERE char * Username
User&#39;s login name.
Definition: globals.h:52
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:192
#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
struct Hash * TagTransforms
Lookup table of alternative tag names.
Definition: tags.c:38
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:591
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:135
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
WHERE char AttachmentMarker[256]
Unique ANSI string to mark PGP messages in an email.
Definition: globals.h:46
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
WHERE enum MenuType CurrentMenu
Current Menu, e.g. MENU_PAGER.
Definition: globals.h:82
struct ListHead MailToAllow
List of permitted fields in a mailto: url.
Definition: email_globals.c:47
String manipulation buffer.
Definition: buffer.h:33
static int execute_commands(struct ListHead *p)
Execute a set of NeoMutt commands.
Definition: init.c:202
WHERE struct Hash * TagFormats
Hash table of tag-formats (tag -> format string)
Definition: globals.h:60
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:49
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
Index panel (list of emails)
Definition: keymap.h:77
void mutt_ch_set_charset(const char *charset)
Update the records for a new character set.
Definition: charset.c:997
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:237
Container for Accounts, Notifications.
Definition: neomutt.h:35
char * HomeDir
User&#39;s home directory.
Definition: globals.h:49
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition: string.c:1071
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:453
#define MUTT_HASH_STRCASECMP
use strcasecmp() to compare keys
Definition: hash.h:75
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:133
void mutt_hist_read_file(void)
Read the History from a file.
Definition: history.c:574
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:876
const char * name
Definition: pgpmicalg.c:46
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:65
void add_to_stailq(struct ListHead *head, const char *str)
Add a string to a list.
Definition: muttlib.c:1792
#define MUTT_HASH_ALLOW_DUPS
allow duplicate keys to be inserted
Definition: hash.h:77
static int MatchesListsize
Definition: init.c:83
void mutt_grouplist_init(void)
Initialize the GroupList singleton.
Definition: group.c:45
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:310
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
struct Hash * mutt_hash_new(size_t nelem, HashFlags flags)
Create a new Hash table (with string keys)
Definition: hash.c:275
char * mutt_ch_get_langinfo_charset(void)
Get the user&#39;s choice of character set.
Definition: charset.c:456
#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:453
uint64_t mutt_rand64(void)
Create a 64-bit random number.
Definition: muttlib.c:541
int mutt_set_xdg_path(enum XdgType type, char *buf, size_t bufsize)
Find an XDG path or its fallback.
Definition: muttlib.c:1589
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:54
WHERE char ProtectedHeaderMarker[256]
Unique ANSI string to mark protected headers in an email.
Definition: globals.h:47
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:390
WHERE struct Hash * ReverseAliases
Hash table of aliases (email address -> alias)
Definition: globals.h:59
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:580
struct MailboxList neomutt_mailboxlist_get_all(struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:157
char * data
String.
Definition: list.h:35
WHERE bool C_Suspend
Config: Allow the user to suspend NeoMutt using &#39;^Z&#39;.
Definition: globals.h:253
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:367
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#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:81
#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()
#define STAILQ_EMPTY(head)
Definition: queue.h:345
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:54
char * mutt_path_concat(char *d, const char *dir, const char *fname, size_t l)
Join a directory name and a filename.
Definition: path.c:351
List of Mailboxes.
Definition: mailbox.h:145
WHERE char * C_Realname
Config: Real name of the user.
Definition: globals.h:139
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
#define MUTT_HASH_STRDUP_KEYS
make a copy of the keys
Definition: hash.h:76
A List node for strings.
Definition: list.h:33
XDG system dir: /etc/xdg.
Definition: protos.h:50
#define STAILQ_FIRST(head)
Definition: queue.h:347
#define MUTT_HASH_NO_FLAGS
No flags are set.
Definition: hash.h:74
WHERE bool C_VirtualSpoolfile
Config: (notmuch) Use the first virtual mailbox as a spool file.
Definition: globals.h:287
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_line()

enum CommandResult mutt_parse_rc_line ( char *  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

Caller should free token->data when finished. the reason for this variable 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 991 of file init.c.

993 {
994  if (!line || !*line)
995  return 0;
996 
997  int i;
999 
1000  struct Buffer expn = mutt_buffer_make(128);
1001  mutt_buffer_addstr(&expn, line);
1002  expn.dptr = expn.data;
1003 
1004  *err->data = 0;
1005 
1006  SKIPWS(expn.dptr);
1007  while (*expn.dptr != '\0')
1008  {
1009  if (*expn.dptr == '#')
1010  break; /* rest of line is a comment */
1011  if (*expn.dptr == ';')
1012  {
1013  expn.dptr++;
1014  continue;
1015  }
1016  mutt_extract_token(token, &expn, MUTT_TOKEN_NO_FLAGS);
1017  for (i = 0; Commands[i].name; i++)
1018  {
1019  if (mutt_str_strcmp(token->data, Commands[i].name) == 0)
1020  {
1021  rc = Commands[i].parse(token, &expn, Commands[i].data, err);
1022  if (rc != MUTT_CMD_SUCCESS)
1023  { /* -1 Error, +1 Finish */
1024  goto finish; /* Propagate return code */
1025  }
1026  notify_send(NeoMutt->notify, NT_COMMAND, i, (void *) &Commands[i]);
1027  break; /* Continue with next command */
1028  }
1029  }
1030  if (!Commands[i].name)
1031  {
1032  mutt_buffer_printf(err, _("%s: unknown command"), NONULL(token->data));
1033  rc = MUTT_CMD_ERROR;
1034  break; /* Ignore the rest of the line */
1035  }
1036  }
1037 finish:
1038  mutt_buffer_dealloc(&expn);
1039  return rc;
1040 }
#define NONULL(x)
Definition: string2.h:37
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
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
#define _(a)
Definition: message.h:28
const char * name
Name of the command.
Definition: mutt_commands.h:46
A Command has been executed.
Definition: notify_type.h:33
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:35
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
const char * name
Definition: pgpmicalg.c:46
#define SKIPWS(ch)
Definition: string2.h:47
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:416
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:37
Success: Command worked.
Definition: mutt_commands.h:37
int const char int line
Definition: acutest.h:602
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
const struct Command Commands[]
Definition: mutt_commands.c:46
#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_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 1048 of file init.c.

1049 {
1050  struct Buffer value = mutt_buffer_make(256);
1051  struct Buffer tmp = mutt_buffer_make(256);
1052  int rc = 0;
1053 
1054  struct ListNode *np = NULL;
1055  STAILQ_FOREACH(np, queries, entries)
1056  {
1057  mutt_buffer_reset(&value);
1058 
1059  struct HashElem *he = cs_subset_lookup(NeoMutt->sub, np->data);
1060  if (!he)
1061  {
1062  rc = 1;
1063  continue;
1064  }
1065 
1066  int rv = cs_subset_he_string_get(NeoMutt->sub, he, &value);
1067  if (CSR_RESULT(rv) != CSR_SUCCESS)
1068  {
1069  rc = 1;
1070  continue;
1071  }
1072 
1073  int type = DTYPE(he->type);
1074  if (type == DT_PATH)
1075  mutt_pretty_mailbox(value.data, value.dsize);
1076 
1077  if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) && (type != DT_QUAD))
1078  {
1079  mutt_buffer_reset(&tmp);
1080  pretty_var(value.data, &tmp);
1081  mutt_buffer_strcpy(&value, tmp.data);
1082  }
1083 
1084  dump_config_neo(NeoMutt->sub->cs, he, &value, NULL, CS_DUMP_NO_FLAGS, stdout);
1085  }
1086 
1087  mutt_buffer_dealloc(&value);
1088  mutt_buffer_dealloc(&tmp);
1089 
1090  return rc; // TEST16: neomutt -Q charset
1091 }
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:35
#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:36
#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:613
#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:35
int type
Definition: hash.h:44
The item stored in a Hash Table.
Definition: hash.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:38
A List node for strings.
Definition: list.h:33
#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:

◆ query_quadoption()

enum QuadOption query_quadoption ( enum QuadOption  opt,
const char *  prompt 
)

Ask the user a quad-question.

Parameters
optOption to use
promptMessage to show to the user
Return values
QuadOptionResult, e.g. MUTT_NO

Definition at line 1099 of file init.c.

1100 {
1101  switch (opt)
1102  {
1103  case MUTT_YES:
1104  case MUTT_NO:
1105  return opt;
1106 
1107  default:
1108  opt = mutt_yesorno(prompt, (opt == MUTT_ASKYES) ? MUTT_YES : MUTT_NO);
1110  return opt;
1111  }
1112 
1113  /* not reached */
1114 }
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
Ask the user, defaulting to &#39;Yes&#39;.
Definition: quad.h:42
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:378
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:112
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:46
+ 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 1125 of file init.c.

1126 {
1127  char *pt = buf;
1128  int num;
1129  int spaces; /* keep track of the number of leading spaces on the line */
1130  struct MyVar *myv = NULL;
1131 
1132  SKIPWS(buf);
1133  spaces = buf - pt;
1134 
1135  pt = buf + pos - spaces;
1136  while ((pt > buf) && !isspace((unsigned char) *pt))
1137  pt--;
1138 
1139  if (pt == buf) /* complete cmd */
1140  {
1141  /* first TAB. Collect all the matches */
1142  if (numtabs == 1)
1143  {
1144  NumMatched = 0;
1145  mutt_str_strfcpy(UserTyped, pt, sizeof(UserTyped));
1146  memset(Matches, 0, MatchesListsize);
1147  memset(Completed, 0, sizeof(Completed));
1148  for (num = 0; Commands[num].name; num++)
1152 
1153  /* All matches are stored. Longest non-ambiguous string is ""
1154  * i.e. don't change 'buf'. Fake successful return this time */
1155  if (UserTyped[0] == '\0')
1156  return 1;
1157  }
1158 
1159  if ((Completed[0] == '\0') && (UserTyped[0] != '\0'))
1160  return 0;
1161 
1162  /* NumMatched will _always_ be at least 1 since the initial
1163  * user-typed string is always stored */
1164  if ((numtabs == 1) && (NumMatched == 2))
1165  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1166  else if ((numtabs > 1) && (NumMatched > 2))
1167  {
1168  /* cycle through all the matches */
1169  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1170  }
1171 
1172  /* return the completed command */
1173  strncpy(buf, Completed, buflen - spaces);
1174  }
1175  else if (mutt_str_startswith(buf, "set", CASE_MATCH) ||
1176  mutt_str_startswith(buf, "unset", CASE_MATCH) ||
1177  mutt_str_startswith(buf, "reset", CASE_MATCH) ||
1178  mutt_str_startswith(buf, "toggle", CASE_MATCH))
1179  { /* complete variables */
1180  static const char *const prefixes[] = { "no", "inv", "?", "&", 0 };
1181 
1182  pt++;
1183  /* loop through all the possible prefixes (no, inv, ...) */
1184  if (mutt_str_startswith(buf, "set", CASE_MATCH))
1185  {
1186  for (num = 0; prefixes[num]; num++)
1187  {
1188  if (mutt_str_startswith(pt, prefixes[num], CASE_MATCH))
1189  {
1190  pt += mutt_str_strlen(prefixes[num]);
1191  break;
1192  }
1193  }
1194  }
1195 
1196  /* first TAB. Collect all the matches */
1197  if (numtabs == 1)
1198  {
1199  NumMatched = 0;
1200  mutt_str_strfcpy(UserTyped, pt, sizeof(UserTyped));
1201  memset(Matches, 0, MatchesListsize);
1202  memset(Completed, 0, sizeof(Completed));
1203  for (num = 0; MuttVars[num].name; num++)
1204  candidate(UserTyped, MuttVars[num].name, Completed, sizeof(Completed));
1205  TAILQ_FOREACH(myv, &MyVars, entries)
1206  {
1207  candidate(UserTyped, myv->name, Completed, sizeof(Completed));
1208  }
1211 
1212  /* All matches are stored. Longest non-ambiguous string is ""
1213  * i.e. don't change 'buf'. Fake successful return this time */
1214  if (UserTyped[0] == '\0')
1215  return 1;
1216  }
1217 
1218  if ((Completed[0] == 0) && UserTyped[0])
1219  return 0;
1220 
1221  /* NumMatched will _always_ be at least 1 since the initial
1222  * user-typed string is always stored */
1223  if ((numtabs == 1) && (NumMatched == 2))
1224  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1225  else if ((numtabs > 1) && (NumMatched > 2))
1226  {
1227  /* cycle through all the matches */
1228  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1229  }
1230 
1231  strncpy(pt, Completed, buf + buflen - pt - spaces);
1232  }
1233  else if (mutt_str_startswith(buf, "exec", CASE_MATCH))
1234  {
1235  const struct Binding *menu = km_get_table(CurrentMenu);
1236 
1237  if (!menu && (CurrentMenu != MENU_PAGER))
1238  menu = OpGeneric;
1239 
1240  pt++;
1241  /* first TAB. Collect all the matches */
1242  if (numtabs == 1)
1243  {
1244  NumMatched = 0;
1245  mutt_str_strfcpy(UserTyped, pt, sizeof(UserTyped));
1246  memset(Matches, 0, MatchesListsize);
1247  memset(Completed, 0, sizeof(Completed));
1248  for (num = 0; menu[num].name; num++)
1249  candidate(UserTyped, menu[num].name, Completed, sizeof(Completed));
1250  /* try the generic menu */
1251  if ((Completed[0] == '\0') && (CurrentMenu != MENU_PAGER))
1252  {
1253  menu = OpGeneric;
1254  for (num = 0; menu[num].name; num++)
1255  candidate(UserTyped, menu[num].name, Completed, sizeof(Completed));
1256  }
1259 
1260  /* All matches are stored. Longest non-ambiguous string is ""
1261  * i.e. don't change 'buf'. Fake successful return this time */
1262  if (UserTyped[0] == '\0')
1263  return 1;
1264  }
1265 
1266  if ((Completed[0] == '\0') && (UserTyped[0] != '\0'))
1267  return 0;
1268 
1269  /* NumMatched will _always_ be at least 1 since the initial
1270  * user-typed string is always stored */
1271  if ((numtabs == 1) && (NumMatched == 2))
1272  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1273  else if ((numtabs > 1) && (NumMatched > 2))
1274  {
1275  /* cycle through all the matches */
1276  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1277  }
1278 
1279  strncpy(pt, Completed, buf + buflen - pt - spaces);
1280  }
1281  else
1282  return 0;
1283 
1284  return 1;
1285 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
static int NumMatched
Definition: init.c:79
WHERE enum MenuType CurrentMenu
Current Menu, e.g. MENU_PAGER.
Definition: globals.h:82
const char * name
Name of the command.
Definition: mutt_commands.h:46
Match case when comparing strings.
Definition: string2.h:67
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
char * name
Name of user variable.
Definition: myvar.h:33
Pager pager (email viewer)
Definition: keymap.h:78
const char * name
Definition: pgpmicalg.c:46
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:119
#define SKIPWS(ch)
Definition: string2.h:47
static char Completed[256]
Definition: init.c:80
const char * name
User-visible name.
Definition: set.h:65
static int MatchesListsize
Definition: init.c:83
static void matches_ensure_morespace(int current)
Allocate more space for auto-completion.
Definition: init.c:94
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
static char UserTyped[1024]
Definition: init.c:77
static const char ** Matches
Definition: init.c:81
const struct Binding * km_get_table(enum MenuType menu)
Lookup a menu&#39;s keybindings.
Definition: keymap.c:1264
Mapping between a user key and a function.
Definition: keymap.h:117
const struct Command Commands[]
Definition: mutt_commands.c:46
static void candidate(char *user, const char *src, char *dest, size_t dlen)
helper function for completion
Definition: init.c:117
struct ConfigDef MuttVars[]
Definition: mutt_config.c:97
+ 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 1295 of file init.c.

1296 {
1297  char *pt = buf;
1298  int spaces; /* keep track of the number of leading spaces on the line */
1299 
1300  if (!Context || !Context->mailbox->label_hash)
1301  return 0;
1302 
1303  SKIPWS(buf);
1304  spaces = buf - pt;
1305 
1306  /* first TAB. Collect all the matches */
1307  if (numtabs == 1)
1308  {
1309  struct HashElem *entry = NULL;
1310  struct HashWalkState state = { 0 };
1311 
1312  NumMatched = 0;
1313  mutt_str_strfcpy(UserTyped, buf, sizeof(UserTyped));
1314  memset(Matches, 0, MatchesListsize);
1315  memset(Completed, 0, sizeof(Completed));
1316  while ((entry = mutt_hash_walk(Context->mailbox->label_hash, &state)))
1317  candidate(UserTyped, entry->key.strkey, Completed, sizeof(Completed));
1319  qsort(Matches, NumMatched, sizeof(char *), (sort_t) mutt_str_strcasecmp);
1321 
1322  /* All matches are stored. Longest non-ambiguous string is ""
1323  * i.e. don't change 'buf'. Fake successful return this time */
1324  if (UserTyped[0] == '\0')
1325  return 1;
1326  }
1327 
1328  if ((Completed[0] == '\0') && (UserTyped[0] != '\0'))
1329  return 0;
1330 
1331  /* NumMatched will _always_ be at least 1 since the initial
1332  * user-typed string is always stored */
1333  if ((numtabs == 1) && (NumMatched == 2))
1334  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1335  else if ((numtabs > 1) && (NumMatched > 2))
1336  {
1337  /* cycle through all the matches */
1338  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1339  }
1340 
1341  /* return the completed label */
1342  strncpy(buf, Completed, buflen - spaces);
1343 
1344  return 1;
1345 }
The "current" mailbox.
Definition: context.h:37
union HashKey key
Definition: hash.h:45
static int NumMatched
Definition: init.c:79
Cursor to iterate through a Hash Table.
Definition: hash.h:96
struct Mailbox * mailbox
Definition: context.h:51
#define SKIPWS(ch)
Definition: string2.h:47
static char Completed[256]
Definition: init.c:80
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:83
static void matches_ensure_morespace(int current)
Allocate more space for auto-completion.
Definition: init.c:94
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
struct HashElem * mutt_hash_walk(const struct Hash *table, struct HashWalkState *state)
Iterate through all the HashElem&#39;s in a Hash table.
Definition: hash.c:503
static char UserTyped[1024]
Definition: init.c:77
const char * strkey
Definition: hash.h:35
static const char ** Matches
Definition: init.c:81
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
The item stored in a Hash Table.
Definition: hash.h:42
struct Hash * label_hash
Hash table for x-labels.
Definition: mailbox.h:129
static void candidate(char *user, const char *src, char *dest, size_t dlen)
helper function for completion
Definition: init.c:117
+ 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 1359 of file init.c.

1360 {
1361  char *pt = buf;
1362  int spaces;
1363 
1364  SKIPWS(buf);
1365  spaces = buf - pt;
1366 
1367  pt = (char *) mutt_str_rstrnstr((char *) buf, pos, "tag:");
1368  if (pt)
1369  {
1370  pt += 4;
1371  if (numtabs == 1)
1372  {
1373  /* First TAB. Collect all the matches */
1375 
1376  /* All matches are stored. Longest non-ambiguous string is ""
1377  * i.e. don't change 'buf'. Fake successful return this time. */
1378  if (UserTyped[0] == '\0')
1379  return true;
1380  }
1381 
1382  if ((Completed[0] == '\0') && (UserTyped[0] != '\0'))
1383  return false;
1384 
1385  /* NumMatched will _always_ be at least 1 since the initial
1386  * user-typed string is always stored */
1387  if ((numtabs == 1) && (NumMatched == 2))
1388  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1389  else if ((numtabs > 1) && (NumMatched > 2))
1390  {
1391  /* cycle through all the matches */
1392  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1393  }
1394 
1395  /* return the completed query */
1396  strncpy(pt, Completed, buf + buflen - pt - spaces);
1397  }
1398  else
1399  return false;
1400 
1401  return true;
1402 }
static int NumMatched
Definition: init.c:79
#define SKIPWS(ch)
Definition: string2.h:47
static char Completed[256]
Definition: init.c:80
static int complete_all_nm_tags(const char *pt)
Pass a list of Notmuch tags to the completion code.
Definition: init.c:145
static char UserTyped[1024]
Definition: init.c:77
static const char ** Matches
Definition: init.c:81
const char * mutt_str_rstrnstr(const char *haystack, size_t haystack_length, const char *needle)
Find last instance of a substring.
Definition: string.c:961
+ 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 1416 of file init.c.

1417 {
1418  if (!buf)
1419  return false;
1420 
1421  char *pt = buf;
1422 
1423  /* Only examine the last token */
1424  char *last_space = strrchr(buf, ' ');
1425  if (last_space)
1426  pt = (last_space + 1);
1427 
1428  /* Skip the +/- */
1429  if ((pt[0] == '+') || (pt[0] == '-'))
1430  pt++;
1431 
1432  if (numtabs == 1)
1433  {
1434  /* First TAB. Collect all the matches */
1436 
1437  /* All matches are stored. Longest non-ambiguous string is ""
1438  * i.e. don't change 'buf'. Fake successful return this time. */
1439  if (UserTyped[0] == '\0')
1440  return true;
1441  }
1442 
1443  if ((Completed[0] == '\0') && (UserTyped[0] != '\0'))
1444  return false;
1445 
1446  /* NumMatched will _always_ be at least 1 since the initial
1447  * user-typed string is always stored */
1448  if ((numtabs == 1) && (NumMatched == 2))
1449  snprintf(Completed, sizeof(Completed), "%s", Matches[0]);
1450  else if ((numtabs > 1) && (NumMatched > 2))
1451  {
1452  /* cycle through all the matches */
1453  snprintf(Completed, sizeof(Completed), "%s", Matches[(numtabs - 2) % NumMatched]);
1454  }
1455 
1456  /* return the completed query */
1457  strncpy(pt, Completed, buf + buflen - pt);
1458 
1459  return true;
1460 }
static int NumMatched
Definition: init.c:79
static char Completed[256]
Definition: init.c:80
static int complete_all_nm_tags(const char *pt)
Pass a list of Notmuch tags to the completion code.
Definition: init.c:145
static char UserTyped[1024]
Definition: init.c:77
static const char ** Matches
Definition: init.c:81
+ 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 1469 of file init.c.

1470 {
1471  char *pt = buf;
1472 
1473  if (buf[0] == '\0')
1474  return 0;
1475 
1476  SKIPWS(buf);
1477  const int spaces = buf - pt;
1478 
1479  pt = buf + pos - spaces;
1480  while ((pt > buf) && !isspace((unsigned char) *pt))
1481  pt--;
1482  pt++; /* move past the space */
1483  if (*pt == '=') /* abort if no var before the '=' */
1484  return 0;
1485 
1486  if (mutt_str_startswith(buf, "set", CASE_MATCH))
1487  {
1488  const char *myvarval = NULL;
1489  char var[256];
1490  mutt_str_strfcpy(var, pt, sizeof(var));
1491  /* ignore the trailing '=' when comparing */
1492  int vlen = mutt_str_strlen(var);
1493  if (vlen == 0)
1494  return 0;
1495 
1496  var[vlen - 1] = '\0';
1497 
1498  struct HashElem *he = cs_subset_lookup(NeoMutt->sub, var);
1499  if (!he)
1500  {
1501  myvarval = myvar_get(var);
1502  if (myvarval)
1503  {
1504  struct Buffer pretty = mutt_buffer_make(256);
1505  pretty_var(myvarval, &pretty);
1506  snprintf(pt, buflen - (pt - buf), "%s=%s", var, pretty.data);
1507  mutt_buffer_dealloc(&pretty);
1508  return 1;
1509  }
1510  return 0; /* no such variable. */
1511  }
1512  else
1513  {
1514  struct Buffer value = mutt_buffer_make(256);
1515  struct Buffer pretty = mutt_buffer_make(256);
1516  int rc = cs_subset_he_string_get(NeoMutt->sub, he, &value);
1517  if (CSR_RESULT(rc) == CSR_SUCCESS)
1518  {
1519  pretty_var(value.data, &pretty);
1520  snprintf(pt, buflen - (pt - buf), "%s=%s", var, pretty.data);
1521  mutt_buffer_dealloc(&value);
1522  mutt_buffer_dealloc(&pretty);
1523  return 0;
1524  }
1525  mutt_buffer_dealloc(&value);
1526  mutt_buffer_dealloc(&pretty);
1527  return 1;
1528  }
1529  }
1530  return 0;
1531 }
#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
Match case when comparing strings.
Definition: string2.h:67
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
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:35
#define SKIPWS(ch)
Definition: string2.h:47
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:36
char * data
Pointer to data.
Definition: buffer.h:35
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
const char * myvar_get(const char *var)
Get the value of a "my_" variable.
Definition: myvar.c:73
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
size_t pretty_var(const char *str, struct Buffer *buf)
Escape and stringify a config item value.
Definition: dump.c:83
The item stored in a Hash Table.
Definition: hash.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:38
+ 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 1538 of file init.c.

1539 {
1540  struct ConfigSet *cs = cs_new(size);
1541 
1542  address_init(cs);
1543  bool_init(cs);
1544  enum_init(cs);
1545  long_init(cs);
1546  mbtable_init(cs);
1547  number_init(cs);
1548  path_init(cs);
1549  quad_init(cs);
1550  regex_init(cs);
1551  slist_init(cs);
1552  sort_init(cs);
1553  string_init(cs);
1554 
1555  if (!cs_register_variables(cs, MuttVars, 0))
1556  {
1557  mutt_error("cs_register_variables() failed");
1558  cs_free(&cs);
1559  return NULL;
1560  }
1561 
1562  return cs;
1563 }
Container for lots of config items.
Definition: set.h:166
void quad_init(struct ConfigSet *cs)
Register the Quad-option config type.
Definition: quad.c:192
void bool_init(struct ConfigSet *cs)
Register the Bool config type.
Definition: bool.c:190
void number_init(struct ConfigSet *cs)
Register the Number config type.
Definition: number.c:192
void sort_init(struct ConfigSet *cs)
Register the Sort config type.
Definition: sort.c:381
void enum_init(struct ConfigSet *cs)
Register the Enumeration config type.
Definition: enum.c:218
void mbtable_init(struct ConfigSet *cs)
Register the MbTable config type.
Definition: mbtable.c:294
void slist_init(struct ConfigSet *cs)
Register the Slist config type.
Definition: slist.c:267
void address_init(struct ConfigSet *cs)
Register the Address config type.
Definition: address.c:249
void string_init(struct ConfigSet *cs)
Register the String config type.
Definition: string.c:240
void cs_free(struct ConfigSet **ptr)
Free a Config Set.
Definition: set.c:168
struct ConfigSet * cs_new(size_t size)
Create a new Config Set.
Definition: set.c:154
void long_init(struct ConfigSet *cs)
Register the Long config type.
Definition: long.c:173
#define mutt_error(...)
Definition: logging.h:84
void regex_init(struct ConfigSet *cs)
Register the Regex config type.
Definition: regex.c:316
bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[], int flags)
Register a set of config items.
Definition: set.c:275
void path_init(struct ConfigSet *cs)
Register the Path config type.
Definition: path.c:261
struct ConfigDef MuttVars[]
Definition: mutt_config.c:97
+ 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 1568 of file init.c.

1570 {
1571  if (value == 0)
1572  return CSR_SUCCESS;
1573 
1574  const char *str = (const char *) value;
1575 
1576  if ((strcmp(cdef->name, "charset") == 0) && strchr(str, ':'))
1577  {
1579  err, _("'charset' must contain exactly one character set name"));
1580  return CSR_ERR_INVALID;
1581  }
1582 
1583  int rc = CSR_SUCCESS;
1584  bool strict = (strcmp(cdef->name, "send_charset") == 0);
1585  char *q = NULL;
1586  char *s = mutt_str_strdup(str);
1587 
1588  for (char *p = strtok_r(s, ":", &q); p; p = strtok_r(NULL, ":", &q))
1589  {
1590  if (!*p)
1591  continue;
1592  if (!mutt_ch_check_charset(p, strict))
1593  {
1594  rc = CSR_ERR_INVALID;
1595  mutt_buffer_printf(err, _("Invalid value for option %s: %s"), cdef->name, p);
1596  break;
1597  }
1598  }
1599 
1600  FREE(&s);
1601  return rc;
1602 }
#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:812
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:36
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:39
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#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 1608 of file init.c.

1610 {
1611  if (value == 0)
1612  return CSR_SUCCESS;
1613 
1614  const char *str = (const char *) value;
1615 
1616  if (store_is_valid_backend(str))
1617  return CSR_SUCCESS;
1618 
1619  mutt_buffer_printf(err, _("Invalid value for option %s: %s"), cdef->name, str);
1620  return CSR_ERR_INVALID;
1621 }
#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:36
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:39
bool store_is_valid_backend(const char *str)
Is the string a valid Store backend.
Definition: store.c:125
+ Here is the call graph for this function:

◆ compress_validator()

int compress_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 1627 of file init.c.

1629 {
1630  if (value == 0)
1631  return CSR_SUCCESS;
1632 
1633  const char *str = (const char *) value;
1634 
1635  if (compress_get_ops(str))
1636  return CSR_SUCCESS;
1637 
1638  mutt_buffer_printf(err, _("Invalid value for option %s: %s"), cdef->name, str);
1639  return CSR_ERR_INVALID;
1640 }
const struct ComprOps * compress_get_ops(const char *compr)
Get the API functions for a compress backend.
Definition: compress.c:87
#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:36
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:39
+ 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 1647 of file init.c.

1649 {
1650  if (CurrentMenu == MENU_PAGER)
1651  {
1652  mutt_buffer_printf(err, _("Option %s may not be set or reset from the pager"),
1653  cdef->name);
1654  return CSR_ERR_INVALID;
1655  }
1656 
1657  return CSR_SUCCESS;
1658 }
WHERE enum MenuType CurrentMenu
Current Menu, e.g. MENU_PAGER.
Definition: globals.h:82
#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:78
const char * name
User-visible name.
Definition: set.h:65
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:36
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:39
+ 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 1663 of file init.c.

1665 {
1666  if (value == 0)
1667  return CSR_SUCCESS;
1668 
1669  const char *str = (const char *) value;
1670 
1671  if ((mutt_str_strcmp(str, "inline") == 0) || (mutt_str_strcmp(str, "info") == 0))
1672  return CSR_SUCCESS;
1673 
1674  mutt_buffer_printf(err, _("Invalid value for option %s: %s"), cdef->name, str);
1675  return CSR_ERR_INVALID;
1676 }
#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:36
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:39
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
+ 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 1681 of file init.c.

1683 {
1684  if (pager_validator(cs, cdef, value, err) != CSR_SUCCESS)
1685  return CSR_ERR_INVALID;
1686 
1687  if (!OptAttachMsg)
1688  return CSR_SUCCESS;
1689 
1690  mutt_buffer_printf(err, _("Option %s may not be set when in attach-message mode"),
1691  cdef->name);
1692  return CSR_ERR_INVALID;
1693 }
#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:36
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:39
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:1647
+ Here is the call graph for this function:

◆ wrapheaders_validator()

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

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

Definition at line 1698 of file init.c.

1700 {
1701  if ((value >= 78) && (value <= 998)) // Recommendation from RFC5233
1702  return CSR_SUCCESS;
1703 
1704  // L10N: This applies to the "$wrap_headers" config variable
1705  mutt_buffer_printf(err, _("Option %s must between 78 and 998 inclusive"), cdef->name);
1706  return CSR_ERR_INVALID;
1707 }
#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:36
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:39
+ Here is the call graph for this function:

Variable Documentation

◆ UserTyped

char UserTyped[1024] = { 0 }
static

Definition at line 77 of file init.c.

◆ NumMatched

int NumMatched = 0
static

Definition at line 79 of file init.c.

◆ Completed

char Completed[256] = { 0 }
static

Definition at line 80 of file init.c.

◆ Matches

const char** Matches
static

Definition at line 81 of file init.c.

◆ MatchesListsize

int MatchesListsize = 512
static

Definition at line 83 of file init.c.

◆ nm_tags

char** nm_tags
static

Definition at line 87 of file init.c.