NeoMutt  2022-04-29-70-g0c028c
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 "mutt_commands.h"
#include "mutt_globals.h"
#include "muttlib.h"
#include "mx.h"
#include "myvar.h"
#include "options.h"
#include "version.h"
#include "monitor.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() -. 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() -. 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() -. 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() -. 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() -. 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() -. 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() -. 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() -. More...
 
void clear_source_stack (void)
 Free memory from the stack used for the source 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 69 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 74 of file command_parse.c.

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

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 87 of file command_parse.c.

88 {
89  for (size_t i = 0; MenuNames[i].name; i++)
90  {
91  const struct MenuFuncOp *fns = km_get_table(MenuNames[i].value);
92  if (!fns)
93  continue;
94 
95  for (int j = 0; fns[j].name; j++)
96  if (mutt_str_equal(name, fns[j].name))
97  return true;
98  }
99  return false;
100 }
const struct MenuFuncOp * km_get_table(enum MenuType mtype)
Lookup a Menu's functions.
Definition: keymap.c:1231
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:784
const char * name
String value.
Definition: mapping.h:33
Mapping between a function and an operation.
Definition: keymap.h:92
const char * name
Name of the function.
Definition: keymap.h:93
const struct Mapping MenuNames[]
Menu name lookup table.
Definition: type.c:31
+ Here is the call 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 111 of file command_parse.c.

113 {
114  while (mutt_istr_equal(buf->data, "-group"))
115  {
116  if (!MoreArgs(s))
117  {
118  mutt_buffer_strcpy(err, _("-group: no group name"));
119  return -1;
120  }
121 
123 
125 
126  if (!MoreArgs(s))
127  {
128  mutt_buffer_strcpy(err, _("out of arguments"));
129  return -1;
130  }
131 
133  }
134 
135  return 0;
136 }
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
#define MoreArgs(buf)
Definition: buffer.h:40
void mutt_grouplist_add(struct GroupList *gl, struct Group *group)
Add a Group to a GroupList.
Definition: group.c:181
struct Group * mutt_pattern_group(const char *pat)
Match a pattern to a Group.
Definition: group.c:112
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:398
#define _(a)
Definition: message.h:28
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:796
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:66
char * data
Pointer to data.
Definition: buffer.h:35
+ 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 144 of file command_parse.c.

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

1491 {
1492 #ifdef USE_INOTIFY
1494 #endif
1495  m->visible = false;
1496  m->gen = -1;
1497  if (m->opened)
1498  {
1499  struct EventMailbox ev_m = { NULL };
1500  mutt_debug(LL_NOTIFY, "NT_MAILBOX_CHANGE: NULL\n");
1502  }
1503  else
1504  {
1506  mailbox_free(&m);
1507  }
1508 }
bool account_mailbox_remove(struct Account *a, struct Mailbox *m)
Remove a Mailbox from an Account.
Definition: account.c:96
@ LL_NOTIFY
Log of notifications.
Definition: logging.h:45
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:87
@ NT_MAILBOX_CHANGE
Mailbox has been changed.
Definition: mailbox.h:173
int mutt_monitor_remove(struct Mailbox *m)
Remove a watch for a mailbox.
Definition: monitor.c:526
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
@ NT_MAILBOX
Mailbox has changed, NotifyMailbox, EventMailbox.
Definition: notify_type.h:49
An Event that happened to a Mailbox.
Definition: mailbox.h:187
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:128
bool visible
True if a result of "mailboxes".
Definition: mailbox.h:131
int opened
Number of times mailbox is opened.
Definition: mailbox.h:129
int gen
Generation number, for sorting.
Definition: mailbox.h:147
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
+ 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 1513 of file command_parse.c.

1514 {
1515  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
1517  struct MailboxNode *np = NULL;
1518  struct MailboxNode *nptmp = NULL;
1519  STAILQ_FOREACH_SAFE(np, &ml, entries, nptmp)
1520  {
1521  do_unmailboxes(np->mailbox);
1522  }
1524 }
static void do_unmailboxes(struct Mailbox *m)
Remove a Mailbox from the Sidebar/notifications.
@ MUTT_MAILBOX_ANY
Match any Mailbox type.
Definition: mailbox.h:42
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:141
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
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
List of Mailboxes.
Definition: mailbox.h:154
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:155
+ Here is the call graph for this function:

◆ clear_source_stack()

void clear_source_stack ( void  )

Free memory from the stack used for the source command.

Definition at line 1698 of file command_parse.c.

1699 {
1701 }
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
+ 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 1 of file command_parse.c.