NeoMutt  2021-10-29-43-g6b8931
Teaching an old dog new tricks
DOXYGEN
commands.c
Go to the documentation of this file.
1 
29 #include "config.h"
30 #include <stdint.h>
31 #include <stdio.h>
32 #include "mutt/lib.h"
33 #include "address/lib.h"
34 #include "config/lib.h"
35 #include "core/lib.h"
36 #include "mutt.h"
37 #include "lib.h"
38 #include "alias.h"
39 #include "command_parse.h"
40 #include "init.h"
41 #include "reverse.h"
42 
48 enum CommandResult parse_alias(struct Buffer *buf, struct Buffer *s,
49  intptr_t data, struct Buffer *err)
50 {
51  struct Alias *tmp = NULL;
52  struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
53  enum NotifyAlias event;
54 
55  if (!MoreArgs(s))
56  {
57  mutt_buffer_strcpy(err, _("alias: no address"));
58  return MUTT_CMD_WARNING;
59  }
60 
61  /* name */
63  mutt_debug(LL_DEBUG5, "First token is '%s'\n", buf->data);
64  if (parse_grouplist(&gl, buf, s, err) == -1)
65  {
66  return MUTT_CMD_ERROR;
67  }
68  char *name = mutt_str_dup(buf->data);
69 
70  /* address list */
72  mutt_debug(LL_DEBUG5, "Second token is '%s'\n", buf->data);
73  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
74  int parsed = mutt_addrlist_parse2(&al, buf->data);
75  if (parsed == 0)
76  {
77  mutt_buffer_printf(err, _("Warning: Bad address '%s' in alias '%s'"), buf->data, name);
78  FREE(&name);
79  goto bail;
80  }
81 
82  /* IDN */
83  char *estr = NULL;
84  if (mutt_addrlist_to_intl(&al, &estr))
85  {
86  mutt_buffer_printf(err, _("Warning: Bad IDN '%s' in alias '%s'"), estr, name);
87  FREE(&name);
88  FREE(&estr);
89  goto bail;
90  }
91 
92  /* check to see if an alias with this name already exists */
93  TAILQ_FOREACH(tmp, &Aliases, entries)
94  {
95  if (mutt_istr_equal(tmp->name, name))
96  break;
97  }
98 
99  if (tmp)
100  {
101  FREE(&name);
103  /* override the previous value */
104  mutt_addrlist_clear(&tmp->addr);
105  FREE(&tmp->comment);
106  event = NT_ALIAS_CHANGE;
107  }
108  else
109  {
110  /* create a new alias */
111  tmp = alias_new();
112  tmp->name = name;
113  TAILQ_INSERT_TAIL(&Aliases, tmp, entries);
114  event = NT_ALIAS_ADD;
115  }
116  tmp->addr = al;
117 
118  mutt_grouplist_add_addrlist(&gl, &tmp->addr);
119 
120  const short c_debug_level = cs_subset_number(NeoMutt->sub, "debug_level");
121  if (c_debug_level > LL_DEBUG4)
122  {
123  /* A group is terminated with an empty address, so check a->mailbox */
124  struct Address *a = NULL;
125  TAILQ_FOREACH(a, &tmp->addr, entries)
126  {
127  if (!a->mailbox)
128  break;
129 
130  if (a->group)
131  mutt_debug(LL_DEBUG5, " Group %s\n", a->mailbox);
132  else
133  mutt_debug(LL_DEBUG5, " %s\n", a->mailbox);
134  }
135  }
137  if (!MoreArgs(s) && (s->dptr[0] == '#'))
138  {
139  char *comment = s->dptr + 1;
140  SKIPWS(comment);
141  tmp->comment = mutt_str_dup(comment);
142  }
143 
144  alias_reverse_add(tmp);
145 
146  mutt_debug(LL_NOTIFY, "%s: %s\n",
147  (event == NT_ALIAS_ADD) ? "NT_ALIAS_ADD" : "NT_ALIAS_CHANGE", tmp->name);
148  struct EventAlias ev_a = { tmp };
149  notify_send(NeoMutt->notify, NT_ALIAS, event, &ev_a);
150 
151  return MUTT_CMD_SUCCESS;
152 
153 bail:
155  return MUTT_CMD_ERROR;
156 }
157 
161 enum CommandResult parse_unalias(struct Buffer *buf, struct Buffer *s,
162  intptr_t data, struct Buffer *err)
163 {
164  do
165  {
167 
168  struct Alias *np = NULL;
169  if (mutt_str_equal("*", buf->data))
170  {
171  TAILQ_FOREACH(np, &Aliases, entries)
172  {
174  }
175 
177  return MUTT_CMD_SUCCESS;
178  }
179 
180  TAILQ_FOREACH(np, &Aliases, entries)
181  {
182  if (!mutt_istr_equal(buf->data, np->name))
183  continue;
184 
185  TAILQ_REMOVE(&Aliases, np, entries);
187  alias_free(&np);
188  break;
189  }
190  } while (MoreArgs(s));
191  return MUTT_CMD_SUCCESS;
192 }
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1470
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:616
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1305
Email Address Handling.
void alias_free(struct Alias **ptr)
Free an Alias.
Definition: alias.c:628
struct AliasList Aliases
List of all the user's email aliases.
Definition: alias.c:57
struct Alias * alias_new(void)
Create a new Alias.
Definition: alias.c:617
void aliaslist_free(struct AliasList *al)
Free a List of Aliases.
Definition: alias.c:649
Representation of a single alias to an email address.
NotifyAlias
Alias notification types.
Definition: alias.h:53
@ NT_ALIAS_ADD
Alias has been added.
Definition: alias.h:54
@ NT_ALIAS_CHANGE
Alias has been changed.
Definition: alias.h:57
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
#define MoreArgs(buf)
Definition: buffer.h:40
CommandResult
Error codes for command_t parse functions.
Definition: command.h:34
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:37
@ 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
int parse_grouplist(struct GroupList *gl, struct Buffer *buf, struct Buffer *s, struct Buffer *err)
Parse a group context.
Functions to parse commands in a config file.
Convenience wrapper for the config headers.
Convenience wrapper for the core headers.
void mutt_grouplist_destroy(struct GroupList *gl)
Free a GroupList.
Definition: group.c:201
void mutt_grouplist_add_addrlist(struct GroupList *gl, struct AddressList *al)
Add Address list to a GroupList.
Definition: group.c:270
enum CommandResult parse_alias(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'alias' command - Implements Command::parse() -.
Definition: commands.c:48
enum CommandResult parse_unalias(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unalias' command - Implements Command::parse() -.
Definition: commands.c:161
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:406
Config/command parsing.
@ LL_DEBUG4
Log at debug level 4.
Definition: logging.h:43
@ LL_DEBUG5
Log at debug level 5.
Definition: logging.h:44
@ LL_NOTIFY
Log of notifications.
Definition: logging.h:45
#define FREE(x)
Definition: memory.h:40
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
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
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:727
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:181
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:715
Many unsorted constants and some structs.
#define MUTT_TOKEN_QUOTE
Don't interpret quotes.
Definition: mutt.h:70
#define MUTT_TOKEN_SPACE
Don't treat whitespace as a term.
Definition: mutt.h:69
#define MUTT_TOKEN_SEMICOLON
Don't treat ; as special.
Definition: mutt.h:73
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:66
@ NT_ALIAS
Alias has changed, NotifyAlias, EventAlias.
Definition: notify_type.h:35
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:809
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:841
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:637
void alias_reverse_add(struct Alias *alias)
Add an email address lookup for an Alias.
Definition: reverse.c:61
void alias_reverse_delete(struct Alias *alias)
Remove an email address lookup for an Alias.
Definition: reverse.c:83
Manage alias reverse lookups.
Key value store.
#define SKIPWS(ch)
Definition: string2.h:46
An email address.
Definition: address.h:36
bool group
Group mailbox?
Definition: address.h:39
char * mailbox
Mailbox and host address.
Definition: address.h:38
A shortcut for an email address or addresses.
Definition: alias.h:34
char * comment
Free-form comment string.
Definition: alias.h:37
char * name
Short name.
Definition: alias.h:35
struct AddressList addr
List of Addresses the Alias expands to.
Definition: alias.h:36
String manipulation buffer.
Definition: buffer.h:34
char * dptr
Current read/write position.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:35
An alias-change event.
Definition: alias.h:64
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39