NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
command_parse.c File Reference

Functions to parse commands in a config file. More...

#include "config.h"
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.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 "gui/lib.h"
#include "mutt.h"
#include "command_parse.h"
#include "imap/lib.h"
#include "menu/lib.h"
#include "init.h"
#include "keymap.h"
#include "monitor.h"
#include "mutt_commands.h"
#include "mutt_globals.h"
#include "muttlib.h"
#include "mx.h"
#include "myvar.h"
#include "options.h"
#include "version.h"
#include <libintl.h>
+ Include dependency graph for command_parse.c:

Go to the source code of this file.

Macros

#define MAX_ERRS   128
 

Enumerations

enum  GroupState { GS_NONE, GS_RX, GS_ADDR }
 Type of email address group. More...
 

Functions

static bool is_function (const char *name)
 Is the argument a neomutt function? More...
 
int parse_grouplist (struct GroupList *gl, struct Buffer *buf, struct Buffer *s, struct Buffer *err)
 Parse a group context. More...
 
int source_rc (const char *rcfile_path, struct Buffer *err)
 Read an initialization file. More...
 
enum CommandResult parse_cd (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'cd' command - Implements Command::parse() -. More...
 
enum CommandResult parse_echo (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'echo' command - Implements Command::parse() -. More...
 
enum CommandResult parse_finish (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'finish' command - Implements Command::parse() -. More...
 
enum CommandResult parse_group (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'group' and 'ungroup' commands - Implements Command::parse() -. More...
 
enum CommandResult parse_ifdef (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'ifdef' and 'ifndef' commands - Implements Command::parse() -The 'ifdef' command allows conditional elements in the config file. More...
 
enum CommandResult parse_ignore (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'ignore' command - Implements Command::parse() -. More...
 
enum CommandResult parse_lists (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'lists' command - Implements Command::parse() -. More...
 
enum CommandResult parse_mailboxes (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'mailboxes' command - Implements Command::parse() -This is also used by 'virtual-mailboxes'. More...
 
enum CommandResult parse_my_hdr (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'my_hdr' command - Implements Command::parse() -. More...
 
enum CommandResult parse_set (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'set' family of commands - Implements Command::parse() -This is used by 'reset', 'set', 'toggle' and 'unset'. More...
 
enum CommandResult parse_setenv (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'setenv' and 'unsetenv' commands - Implements Command::parse() -. More...
 
enum CommandResult parse_source (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'source' command - Implements Command::parse() -. More...
 
enum CommandResult parse_spam_list (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'spam' and 'nospam' commands - Implements Command::parse() -. More...
 
enum CommandResult parse_stailq (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse a list command - Implements Command::parse() -This is used by 'alternative_order', 'auto_view' and several others. More...
 
enum CommandResult parse_subscribe (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'subscribe' command - Implements Command::parse() -. More...
 
enum CommandResult parse_subscribe_to (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'subscribe-to' command - Implements Command::parse() -The 'subscribe-to' command allows to subscribe to an IMAP-Mailbox. More...
 
enum CommandResult parse_tag_formats (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'tag-formats' command - Implements Command::parse() -. More...
 
enum CommandResult parse_tag_transforms (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'tag-transforms' command - Implements Command::parse() -. More...
 
enum CommandResult parse_unignore (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unignore' command - Implements Command::parse() -. More...
 
enum CommandResult parse_unlists (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unlists' command - Implements Command::parse() -. More...
 
static void do_unmailboxes (struct Mailbox *m)
 Remove a Mailbox from the Sidebar/notifications. More...
 
static void do_unmailboxes_star (void)
 Remove all Mailboxes from the Sidebar/notifications. More...
 
enum CommandResult parse_unmailboxes (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unmailboxes' command - Implements Command::parse() -This is also used by 'unvirtual-mailboxes'. More...
 
enum CommandResult parse_unmy_hdr (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unmy_hdr' command - Implements Command::parse() -. More...
 
enum CommandResult parse_unstailq (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse an unlist command - Implements Command::parse() -This is used by 'unalternative_order', 'unauto_view' and several others. More...
 
enum CommandResult parse_unsubscribe (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unsubscribe' command - Implements Command::parse() -. More...
 
enum CommandResult parse_unsubscribe_from (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unsubscribe-from' command - Implements Command::parse() -The 'unsubscribe-from' command allows to unsubscribe from an IMAP-Mailbox. More...
 
void clear_source_stack (void)
 Free memory from the stack used for the souce command. More...
 

Variables

static struct ListHead MuttrcStack = STAILQ_HEAD_INITIALIZER(MuttrcStack)
 

Detailed Description

Functions to parse commands in a config file.

Authors
  • Michael R. Elkins
  • g10 Code GmbH
  • R Primus

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 command_parse.c.

Macro Definition Documentation

◆ MAX_ERRS

#define MAX_ERRS   128

Definition at line 67 of file command_parse.c.

Enumeration Type Documentation

◆ GroupState

enum GroupState

Type of email address group.

Enumerator
GS_NONE 

Group is missing an argument.

GS_RX 

Entry is a regular expression.

GS_ADDR 

Entry is an address.

Definition at line 72 of file command_parse.c.

73 {
74  GS_NONE,
75  GS_RX,
76  GS_ADDR,
77 };
Entry is an address.
Definition: command_parse.c:76
Group is missing an argument.
Definition: command_parse.c:74
Entry is a regular expression.
Definition: command_parse.c:75

Function Documentation

◆ is_function()

static bool is_function ( const char *  name)
static

Is the argument a neomutt function?

Parameters
nameCommand name to be searched for
Return values
trueFunction found
falseFunction not found

Definition at line 85 of file command_parse.c.

86 {
87  for (size_t i = 0; MenuNames[i].name; i++)
88  {
89  const struct Binding *b = km_get_table(MenuNames[i].value);
90  if (!b)
91  continue;
92 
93  for (int j = 0; b[j].name; j++)
94  if (mutt_str_equal(name, b[j].name))
95  return true;
96  }
97  return false;
98 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
const char * name
name of the function
Definition: keymap.h:93
const struct Binding * km_get_table(enum MenuType mtype)
Lookup a menu&#39;s keybindings.
Definition: keymap.c:1313
const struct Mapping MenuNames[]
Menu name lookup table.
Definition: type.c:31
const char * name
Definition: mapping.h:33
Mapping between a user key and a function.
Definition: keymap.h:91
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_grouplist()

int parse_grouplist ( struct GroupList *  gl,
struct Buffer buf,
struct Buffer s,
struct Buffer err 
)

Parse a group context.

Parameters
glGroupList to add to
bufTemporary Buffer space
sBuffer containing string to be parsed
errBuffer for error messages
Return values
0Success
-1Error

Definition at line 109 of file command_parse.c.

111 {
112  while (mutt_istr_equal(buf->data, "-group"))
113  {
114  if (!MoreArgs(s))
115  {
116  mutt_buffer_strcpy(err, _("-group: no group name"));
117  return -1;
118  }
119 
121 
123 
124  if (!MoreArgs(s))
125  {
126  mutt_buffer_strcpy(err, _("out of arguments"));
127  return -1;
128  }
129 
131  }
132 
133  return 0;
134 }
void mutt_grouplist_add(struct GroupList *gl, struct Group *group)
Add a Group to a GroupList.
Definition: group.c:137
#define _(a)
Definition: message.h:28
#define MoreArgs(buf)
Definition: buffer.h:40
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:916
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:395
char * data
Pointer to data.
Definition: buffer.h:35
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
struct Group * mutt_pattern_group(const char *pat)
Match a pattern to a Group.
Definition: group.c:65
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:66
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ source_rc()

int source_rc ( const char *  rcfile_path,
struct Buffer err 
)

Read an initialization file.

Parameters
rcfile_pathPath to initialization file
errBuffer for error messages
Return values
<0NeoMutt should pause to let the user know

Definition at line 142 of file command_parse.c.

143 {
144  int lineno = 0, rc = 0, warnings = 0;
145  enum CommandResult line_rc;
146  struct Buffer *token = NULL, *linebuf = NULL;
147  char *line = NULL;
148  char *currentline = NULL;
149  char rcfile[PATH_MAX];
150  size_t linelen = 0;
151  pid_t pid;
152 
153  mutt_str_copy(rcfile, rcfile_path, sizeof(rcfile));
154 
155  size_t rcfilelen = mutt_str_len(rcfile);
156  if (rcfilelen == 0)
157  return -1;
158 
159  bool ispipe = rcfile[rcfilelen - 1] == '|';
160 
161  if (!ispipe)
162  {
163  struct ListNode *np = STAILQ_FIRST(&MuttrcStack);
164  if (!mutt_path_to_absolute(rcfile, np ? NONULL(np->data) : ""))
165  {
166  mutt_error(_("Error: Can't build path of '%s'"), rcfile_path);
167  return -1;
168  }
169 
170  STAILQ_FOREACH(np, &MuttrcStack, entries)
171  {
172  if (mutt_str_equal(np->data, rcfile))
173  {
174  break;
175  }
176  }
177  if (np)
178  {
179  mutt_error(_("Error: Cyclic sourcing of configuration file '%s'"), rcfile);
180  return -1;
181  }
182 
184  }
185 
186  mutt_debug(LL_DEBUG2, "Reading configuration file '%s'\n", rcfile);
187 
188  FILE *fp = mutt_open_read(rcfile, &pid);
189  if (!fp)
190  {
191  mutt_buffer_printf(err, "%s: %s", rcfile, strerror(errno));
192  return -1;
193  }
194 
195  token = mutt_buffer_pool_get();
196  linebuf = mutt_buffer_pool_get();
197 
198  while ((line = mutt_file_read_line(line, &linelen, fp, &lineno, MUTT_RL_CONT)) != NULL)
199  {
200  const char *const c_config_charset =
201  cs_subset_string(NeoMutt->sub, "config_charset");
202  const char *const c_charset = cs_subset_string(NeoMutt->sub, "charset");
203  const bool conv = c_config_charset && c_charset;
204  if (conv)
205  {
206  currentline = mutt_str_dup(line);
207  if (!currentline)
208  continue;
209  mutt_ch_convert_string(&currentline, c_config_charset, c_charset, MUTT_ICONV_NO_FLAGS);
210  }
211  else
212  currentline = line;
213 
214  mutt_buffer_strcpy(linebuf, currentline);
215 
216  mutt_buffer_reset(err);
217  line_rc = mutt_parse_rc_buffer(linebuf, token, err);
218  if (line_rc == MUTT_CMD_ERROR)
219  {
220  mutt_error(_("Error in %s, line %d: %s"), rcfile, lineno, err->data);
221  if (--rc < -MAX_ERRS)
222  {
223  if (conv)
224  FREE(&currentline);
225  break;
226  }
227  }
228  else if (line_rc == MUTT_CMD_WARNING)
229  {
230  /* Warning */
231  mutt_warning(_("Warning in %s, line %d: %s"), rcfile, lineno, err->data);
232  warnings++;
233  }
234  else if (line_rc == MUTT_CMD_FINISH)
235  {
236  break; /* Found "finish" command */
237  }
238  else
239  {
240  if (rc < 0)
241  rc = -1;
242  }
243  if (conv)
244  FREE(&currentline);
245  }
246 
247  FREE(&line);
248  mutt_file_fclose(&fp);
249  if (pid != -1)
250  filter_wait(pid);
251 
252  if (rc)
253  {
254  /* the neomuttrc source keyword */
255  mutt_buffer_reset(err);
256  mutt_buffer_printf(err, (rc >= -MAX_ERRS) ? _("source: errors in %s") : _("source: reading aborted due to too many errors in %s"),
257  rcfile);
258  rc = -1;
259  }
260  else
261  {
262  /* Don't alias errors with warnings */
263  if (warnings > 0)
264  {
265  mutt_buffer_printf(err, ngettext("source: %d warning in %s", "source: %d warnings in %s", warnings),
266  warnings, rcfile);
267  rc = -2;
268  }
269  }
270 
271  if (!ispipe && !STAILQ_EMPTY(&MuttrcStack))
272  {
273  struct ListNode *np = STAILQ_FIRST(&MuttrcStack);
274  STAILQ_REMOVE_HEAD(&MuttrcStack, entries);
275  FREE(&np->data);
276  FREE(&np);
277  }
278 
279  mutt_buffer_pool_release(&token);
280  mutt_buffer_pool_release(&linebuf);
281  return rc;
282 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
#define NONULL(x)
Definition: string2.h:37
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
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:34
#define MUTT_RL_CONT
-continuation
Definition: file.h:39
Error: Can&#39;t help the user.
Definition: mutt_commands.h:36
#define mutt_error(...)
Definition: logging.h:88
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:370
#define _(a)
Definition: message.h:28
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition: charset.c:758
#define MUTT_ICONV_NO_FLAGS
No flags are set.
Definition: charset.h:71
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, ReadLineFlags flags)
Read a line from a file.
Definition: file.c:667
#define STAILQ_REMOVE_HEAD(head, field)
Definition: queue.h:422
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
Log at debug level 2.
Definition: logging.h:41
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
#define mutt_warning(...)
Definition: logging.h:86
#define PATH_MAX
Definition: mutt.h:40
char * data
Pointer to data.
Definition: buffer.h:35
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
bool mutt_path_to_absolute(char *path, const char *reference)
Convert relative filepath to an absolute path.
Definition: path.c:397
struct ListNode * mutt_list_insert_head(struct ListHead *h, char *s)
Insert a string at the beginning of a List.
Definition: list.c:45
enum CommandResult mutt_parse_rc_buffer(struct Buffer *line, struct Buffer *token, struct Buffer *err)
Parse a line of user config.
Definition: init.c:980
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
char * data
String.
Definition: list.h:36
Warning: Help given to the user.
Definition: mutt_commands.h:37
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:749
Finish: Stop processing this file.
Definition: mutt_commands.h:39
#define MAX_ERRS
Definition: command_parse.c:67
#define FREE(x)
Definition: memory.h:40
static struct ListHead MuttrcStack
Definition: command_parse.c:65
#define STAILQ_EMPTY(head)
Definition: queue.h:348
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
A List node for strings.
Definition: list.h:34
FILE * mutt_open_read(const char *path, pid_t *thepid)
Run a command to read from.
Definition: muttlib.c:1315
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
#define STAILQ_FIRST(head)
Definition: queue.h:350
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ do_unmailboxes()

static void do_unmailboxes ( struct Mailbox m)
static

Remove a Mailbox from the Sidebar/notifications.

Parameters
mMailbox to unmailboxes

Definition at line 1478 of file command_parse.c.

1479 {
1480 #ifdef USE_INOTIFY
1482 #endif
1483  m->flags = MB_HIDDEN;
1484  m->gen = -1;
1485  if (m->opened)
1486  {
1487  struct EventMailbox ev_m = { NULL };
1488  mutt_debug(LL_NOTIFY, "NT_MAILBOX_SWITCH: NULL\n");
1490  }
1491  else
1492  {
1494  mailbox_free(&m);
1495  }
1496 }
Log of notifications.
Definition: logging.h:45
int mutt_monitor_remove(struct Mailbox *m)
Remove a watch for a mailbox.
Definition: monitor.c:526
An Event that happened to a Mailbox.
Definition: mailbox.h:190
Container for Accounts, Notifications.
Definition: neomutt.h:36
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:87
int opened
Number of times mailbox is opened.
Definition: mailbox.h:132
#define MB_HIDDEN
Definition: mailbox.h:38
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
uint8_t flags
e.g. MB_NORMAL
Definition: mailbox.h:134
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
Current Mailbox has changed.
Definition: mailbox.h:182
bool account_mailbox_remove(struct Account *a, struct Mailbox *m)
Remove a Mailbox from an Account.
Definition: account.c:95
Mailbox has changed, NotifyMailbox, EventMailbox.
Definition: notify_type.h:48
int gen
Generation number, for sorting.
Definition: mailbox.h:150
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:171
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ do_unmailboxes_star()

static void do_unmailboxes_star ( void  )
static

Remove all Mailboxes from the Sidebar/notifications.

Definition at line 1501 of file command_parse.c.

1502 {
1503  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
1505  struct MailboxNode *np = NULL;
1506  struct MailboxNode *nptmp = NULL;
1507  STAILQ_FOREACH_SAFE(np, &ml, entries, nptmp)
1508  {
1509  do_unmailboxes(np->mailbox);
1510  }
1512 }
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:141
Match any Mailbox type.
Definition: mailbox.h:45
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:164
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
static void do_unmailboxes(struct Mailbox *m)
Remove a Mailbox from the Sidebar/notifications.
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
List of Mailboxes.
Definition: mailbox.h:156
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:158
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ clear_source_stack()

void clear_source_stack ( void  )

Free memory from the stack used for the souce command.

Definition at line 1686 of file command_parse.c.

1687 {
1689 }
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
static struct ListHead MuttrcStack
Definition: command_parse.c:65
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ MuttrcStack

struct ListHead MuttrcStack = STAILQ_HEAD_INITIALIZER(MuttrcStack)
static

Definition at line 65 of file command_parse.c.