NeoMutt  2025-12-11-435-g4ac674
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
group.c
Go to the documentation of this file.
1
30
36
37#include "config.h"
38#include <stdio.h>
39#include "mutt/lib.h"
40#include "address/lib.h"
41#include "core/lib.h"
42#include "group.h"
43#include "parse/lib.h"
44#include "module_data.h"
45
56int parse_grouplist(struct GroupList *gl, struct Buffer *token, struct Buffer *line,
57 struct Buffer *err, struct HashTable *groups)
58{
59 while (mutt_istr_equal(token->data, "-group"))
60 {
61 if (!MoreArgs(line))
62 {
63 buf_strcpy(err, _("-group: no group name"));
64 return -1;
65 }
66
68
69 grouplist_add_group(gl, groups_get_group(groups, token->data));
70
71 if (!MoreArgs(line))
72 {
73 buf_strcpy(err, _("out of arguments"));
74 return -1;
75 }
76
78 }
79
80 return 0;
81}
82
90enum CommandResult parse_group(const struct Command *cmd, struct Buffer *line,
91 const struct ParseContext *pc, struct ParseError *pe)
92{
93 struct Buffer *err = pe->message;
94
95 if (!MoreArgs(line))
96 {
97 buf_printf(err, _("%s: too few arguments"), cmd->name);
98 return MUTT_CMD_WARNING;
99 }
100
101 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
102 enum GroupState gstate = GS_NONE;
103 struct Buffer *token = buf_pool_get();
105
106 do
107 {
109 if (parse_grouplist(&gl, token, line, err, NeoMutt->groups) == -1)
110 goto done;
111
112 if ((cmd->id == CMD_UNGROUP) && mutt_istr_equal(buf_string(token), "*"))
113 {
115 rc = MUTT_CMD_SUCCESS;
116 goto done;
117 }
118
119 if (mutt_istr_equal(buf_string(token), "-rx"))
120 {
121 gstate = GS_RX;
122 }
123 else if (mutt_istr_equal(buf_string(token), "-addr"))
124 {
125 gstate = GS_ADDR;
126 }
127 else
128 {
129 switch (gstate)
130 {
131 case GS_NONE:
132 buf_printf(err, _("%s: missing -rx or -addr"), cmd->name);
133 rc = MUTT_CMD_WARNING;
134 goto done;
135
136 case GS_RX:
137 if ((cmd->id == CMD_GROUP) &&
138 (grouplist_add_regex(&gl, buf_string(token), REG_ICASE, err) != 0))
139 {
140 goto done;
141 }
142 else if ((cmd->id == CMD_UNGROUP) &&
143 (groups_remove_regex(NeoMutt->groups, &gl, buf_string(token)) < 0))
144 {
145 goto done;
146 }
147 break;
148
149 case GS_ADDR:
150 {
151 char *estr = NULL;
152 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
153 mutt_addrlist_parse2(&al, buf_string(token));
154 if (TAILQ_EMPTY(&al))
155 goto done;
156 if (mutt_addrlist_to_intl(&al, &estr))
157 {
158 buf_printf(err, _("%s: warning: bad IDN '%s'"), cmd->name, estr);
160 FREE(&estr);
161 goto done;
162 }
163 if (cmd->id == CMD_GROUP)
164 grouplist_add_addrlist(&gl, &al);
165 else if (cmd->id == CMD_UNGROUP)
168 break;
169 }
170 }
171 }
172 } while (MoreArgs(line));
173
174 rc = MUTT_CMD_SUCCESS;
175
176done:
177 buf_pool_release(&token);
179 return rc;
180}
181
188enum CommandResult parse_lists(const struct Command *cmd, struct Buffer *line,
189 const struct ParseContext *pc, struct ParseError *pe)
190{
191 struct Buffer *err = pe->message;
192
193 if (!MoreArgs(line))
194 {
195 buf_printf(err, _("%s: too few arguments"), cmd->name);
196 return MUTT_CMD_WARNING;
197 }
198
199 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
200 struct Buffer *token = buf_pool_get();
202
204 ASSERT(md);
205
206 do
207 {
209
210 if (parse_grouplist(&gl, token, line, err, NeoMutt->groups) == -1)
211 goto done;
212
214
215 if (mutt_regexlist_add(&md->mail, buf_string(token), REG_ICASE, err) != 0)
216 goto done;
217
218 if (grouplist_add_regex(&gl, buf_string(token), REG_ICASE, err) != 0)
219 goto done;
220 } while (MoreArgs(line));
221
222 rc = MUTT_CMD_SUCCESS;
223
224done:
225 buf_pool_release(&token);
227 return rc;
228}
229
236enum CommandResult parse_subscribe(const struct Command *cmd, struct Buffer *line,
237 const struct ParseContext *pc, struct ParseError *pe)
238{
239 struct Buffer *err = pe->message;
240
241 if (!MoreArgs(line))
242 {
243 buf_printf(err, _("%s: too few arguments"), cmd->name);
244 return MUTT_CMD_WARNING;
245 }
246
247 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
248 struct Buffer *token = buf_pool_get();
250
252 ASSERT(md);
253
254 do
255 {
257
258 if (parse_grouplist(&gl, token, line, err, NeoMutt->groups) == -1)
259 goto done;
260
263
264 if (mutt_regexlist_add(&md->mail, buf_string(token), REG_ICASE, err) != 0)
265 goto done;
266
267 if (mutt_regexlist_add(&md->subscribed, buf_string(token), REG_ICASE, err) != 0)
268 goto done;
269
270 if (grouplist_add_regex(&gl, buf_string(token), REG_ICASE, err) != 0)
271 goto done;
272 } while (MoreArgs(line));
273
274 rc = MUTT_CMD_SUCCESS;
275
276done:
277 buf_pool_release(&token);
279 return rc;
280}
281
288enum CommandResult parse_unlists(const struct Command *cmd, struct Buffer *line,
289 const struct ParseContext *pc, struct ParseError *pe)
290{
291 struct Buffer *err = pe->message;
292
293 if (!MoreArgs(line))
294 {
295 buf_printf(err, _("%s: too few arguments"), cmd->name);
296 return MUTT_CMD_WARNING;
297 }
298
299 struct Buffer *token = buf_pool_get();
301
303 ASSERT(md);
304
306 do
307 {
311
312 if (!mutt_str_equal(buf_string(token), "*") &&
313 (mutt_regexlist_add(&md->unmail, buf_string(token), REG_ICASE, err) != 0))
314 {
315 goto done;
316 }
317 } while (MoreArgs(line));
318
319 rc = MUTT_CMD_SUCCESS;
320
321done:
322 buf_pool_release(&token);
323 return rc;
324}
325
332enum CommandResult parse_unsubscribe(const struct Command *cmd, struct Buffer *line,
333 const struct ParseContext *pc, struct ParseError *pe)
334{
335 struct Buffer *err = pe->message;
336
337 if (!MoreArgs(line))
338 {
339 buf_printf(err, _("%s: too few arguments"), cmd->name);
340 return MUTT_CMD_WARNING;
341 }
342
344 ASSERT(md);
345
346 struct Buffer *token = buf_pool_get();
348
350 do
351 {
354
355 if (!mutt_str_equal(buf_string(token), "*") &&
356 (mutt_regexlist_add(&md->unsubscribed, buf_string(token), REG_ICASE, err) != 0))
357 {
358 goto done;
359 }
360 } while (MoreArgs(line));
361
362 rc = MUTT_CMD_SUCCESS;
363
364done:
365 buf_pool_release(&token);
366 return rc;
367}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition address.c:1464
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition address.c:644
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition address.c:1297
int grouplist_add_regex(struct GroupList *gl, const char *str, uint16_t flags, struct Buffer *err)
Add matching Addresses to a GroupList.
Definition group.c:245
int groups_remove_addrlist(struct HashTable *groups, struct GroupList *gl, struct AddressList *al)
Remove an AddressList from a GroupList.
Definition group.c:337
void groups_remove_grouplist(struct HashTable *groups, struct GroupList *gl)
Clear a GroupList.
Definition group.c:312
int groups_remove_regex(struct HashTable *groups, struct GroupList *gl, const char *str)
Remove matching addresses from a GroupList.
Definition group.c:368
struct Group * groups_get_group(struct HashTable *groups, const char *name)
Get a Group by its name.
Definition group.c:291
void grouplist_add_addrlist(struct GroupList *gl, struct AddressList *al)
Add Address list to a GroupList.
Definition group.c:224
void grouplist_add_group(struct GroupList *gl, struct Group *g)
Add a Group to a GroupList.
Definition group.c:183
void grouplist_destroy(struct GroupList *gl)
Free a GroupList.
Definition group.c:203
Email Address Handling.
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
@ CMD_GROUP
:group
Definition command.h:79
@ CMD_UNGROUP
:ungroup
Definition command.h:130
CommandResult
Error codes for command_t parse functions.
Definition command.h:37
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition command.h:40
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition command.h:38
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition command.h:39
Convenience wrapper for the core headers.
int parse_grouplist(struct GroupList *gl, struct Buffer *token, struct Buffer *line, struct Buffer *err, struct HashTable *groups)
Parse a group context.
Definition group.c:56
Parse Group/Lists Commands.
GroupState
Type of email address group.
Definition group.h:38
@ GS_RX
Entry is a regular expression.
Definition group.h:40
@ GS_NONE
Group is missing an argument.
Definition group.h:39
@ GS_ADDR
Entry is an address.
Definition group.h:41
Email private Module data.
int parse_extract_token(struct Buffer *dest, struct Buffer *line, TokenFlags flags)
Extract one token from a string.
Definition extract.c:49
#define MoreArgs(buf)
Definition extract.h:31
#define TOKEN_NO_FLAGS
No flags are set.
Definition extract.h:45
enum CommandResult parse_subscribe(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse the 'subscribe' command - Implements Command::parse() -.
Definition group.c:236
enum CommandResult parse_unlists(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse the 'unlists' command - Implements Command::parse() -.
Definition group.c:288
enum CommandResult parse_lists(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse the 'lists' command - Implements Command::parse() -.
Definition group.c:188
enum CommandResult parse_group(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse the 'group' and 'ungroup' commands - Implements Command::parse() -.
Definition group.c:90
enum CommandResult parse_unsubscribe(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse the 'unsubscribe' command - Implements Command::parse() -.
Definition group.c:332
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition hash.c:459
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
@ MODULE_ID_EMAIL
ModuleEmail, Email code
Definition module_api.h:64
Convenience wrapper for the library headers.
#define _(a)
Definition message.h:28
int mutt_regexlist_add(struct RegexList *rl, const char *str, uint16_t flags, struct Buffer *err)
Compile a regex string and add it to a list.
Definition regex.c:140
int mutt_regexlist_remove(struct RegexList *rl, const char *str)
Remove a Regex from a list.
Definition regex.c:235
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:674
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:662
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:585
Text parsing functions.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
#define STAILQ_HEAD_INITIALIZER(head)
Definition queue.h:324
#define TAILQ_HEAD_INITIALIZER(head)
Definition queue.h:694
#define TAILQ_EMPTY(head)
Definition queue.h:778
#define ASSERT(COND)
Definition signal2.h:59
String manipulation buffer.
Definition buffer.h:36
char * data
Pointer to data.
Definition buffer.h:37
const char * name
Name of the Command.
Definition command.h:159
enum CommandId id
ID of the Command.
Definition command.h:160
Email private Module data.
Definition module_data.h:32
struct RegexList unsubscribed
Regexes to exclude false matches in subscribed.
Definition module_data.h:47
struct RegexList subscribed
Regexes to match subscribed mailing lists.
Definition module_data.h:42
struct RegexList unmail
Regexes to exclude false matches in mail.
Definition module_data.h:46
struct HashTable * auto_subscribe_cache
Hash Table: "mailto:" (no value)
Definition module_data.h:34
struct RegexList mail
Regexes to match mailing lists.
Definition module_data.h:38
A Hash Table.
Definition hash.h:99
Container for Accounts, Notifications.
Definition neomutt.h:41
struct HashTable * groups
Hash Table: "group-name" -> Group.
Definition neomutt.h:54
Context for config parsing (history/backtrace)
Definition pcontext.h:34
Detailed error information from config parsing.
Definition perror.h:34
struct Buffer * message
Error message.
Definition perror.h:35