NeoMutt  2023-05-17-56-ga67199
Teaching an old dog new tricks
DOXYGEN
group.c File Reference

Handling for email address groups. More...

#include "config.h"
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include "group.h"
#include "address.h"
+ Include dependency graph for group.c:

Go to the source code of this file.

Functions

static void group_free (struct Group **ptr)
 Free an Address Group. More...
 
static struct Groupgroup_new (const char *pat)
 Create a new Address Group. More...
 
static void group_hash_free (int type, void *obj, intptr_t data)
 Free our hash table data - Implements hash_hdata_free_t -. More...
 
void mutt_grouplist_init (void)
 Initialize the GroupList singleton. More...
 
void mutt_grouplist_free (void)
 Free GroupList singleton resource. More...
 
struct Groupmutt_pattern_group (const char *pat)
 Match a pattern to a Group. More...
 
static void group_remove (struct Group *g)
 Remove a Group from the Hash Table. More...
 
void mutt_grouplist_clear (struct GroupList *gl)
 Clear a GroupList. More...
 
static bool empty_group (struct Group *g)
 Is a Group empty? More...
 
void mutt_grouplist_add (struct GroupList *gl, struct Group *group)
 Add a Group to a GroupList. More...
 
void mutt_grouplist_destroy (struct GroupList *gl)
 Free a GroupList. More...
 
static void group_add_addrlist (struct Group *g, const struct AddressList *al)
 Add an Address List to a Group. More...
 
static int group_add_regex (struct Group *g, const char *s, uint16_t flags, struct Buffer *err)
 Add a Regex to a Group. More...
 
static int group_remove_regex (struct Group *g, const char *s)
 Remove a Regex from a Group. More...
 
void mutt_grouplist_add_addrlist (struct GroupList *gl, struct AddressList *al)
 Add Address list to a GroupList. More...
 
int mutt_grouplist_remove_addrlist (struct GroupList *gl, struct AddressList *al)
 Remove an AddressList from a GroupList. More...
 
int mutt_grouplist_add_regex (struct GroupList *gl, const char *s, uint16_t flags, struct Buffer *err)
 Add matching Addresses to a GroupList. More...
 
int mutt_grouplist_remove_regex (struct GroupList *gl, const char *s)
 Remove matching addresses from a GroupList. More...
 
bool mutt_group_match (struct Group *g, const char *s)
 Does a string match an entry in a Group? More...
 

Variables

static struct HashTableGroups = NULL
 Hash Table: "group-name" -> Group. More...
 

Detailed Description

Handling for email address groups.

Authors
  • Thomas Roessler
  • Rocco Rutte
  • 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 group.c.

Function Documentation

◆ group_free()

static void group_free ( struct Group **  ptr)
static

Free an Address Group.

Parameters
ptrGroup to free

Definition at line 49 of file group.c.

50{
51 if (!ptr || !*ptr)
52 return;
53
54 struct Group *g = *ptr;
55
58 FREE(&g->name);
59
60 FREE(ptr);
61}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1449
#define FREE(x)
Definition: memory.h:43
void mutt_regexlist_free(struct RegexList *rl)
Free a RegexList object.
Definition: regex.c:174
A set of email addresses.
Definition: group.h:40
char * name
Name of Group.
Definition: group.h:43
struct AddressList al
List of Addresses.
Definition: group.h:41
struct RegexList rs
Group Regex patterns.
Definition: group.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ group_new()

static struct Group * group_new ( const char *  pat)
static

Create a new Address Group.

Parameters
patPattern
Return values
ptrNew Address Group
Note
The pattern will be copied

Definition at line 70 of file group.c.

71{
72 struct Group *g = mutt_mem_calloc(1, sizeof(struct Group));
73
74 g->name = mutt_str_dup(pat);
75 STAILQ_INIT(&g->rs);
76 TAILQ_INIT(&g->al);
77
78 return g;
79}
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:251
#define STAILQ_INIT(head)
Definition: queue.h:372
#define TAILQ_INIT(head)
Definition: queue.h:765
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_grouplist_init()

void mutt_grouplist_init ( void  )

Initialize the GroupList singleton.

This is called once from init.c when initializing the global structures.

Definition at line 95 of file group.c.

96{
98
100}
static struct HashTable * Groups
Hash Table: "group-name" -> Group.
Definition: group.c:43
static void group_hash_free(int type, void *obj, intptr_t data)
Free our hash table data - Implements hash_hdata_free_t -.
Definition: group.c:84
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition: hash.c:259
void mutt_hash_set_destructor(struct HashTable *table, hash_hdata_free_t fn, intptr_t fn_data)
Set the destructor for a Hash Table.
Definition: hash.c:301
#define MUTT_HASH_NO_FLAGS
No flags are set.
Definition: hash.h:110
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_grouplist_free()

void mutt_grouplist_free ( void  )

Free GroupList singleton resource.

This is called once from init.c when deinitializing the global resources.

Definition at line 107 of file group.c.

108{
110}
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:457
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pattern_group()

struct Group * mutt_pattern_group ( const char *  pat)

Match a pattern to a Group.

Parameters
patPattern to match
Return values
ptrMatching Group, or new Group (if no match)

Definition at line 117 of file group.c.

118{
119 if (!pat)
120 return NULL;
121
122 struct Group *g = mutt_hash_find(Groups, pat);
123 if (!g)
124 {
125 mutt_debug(LL_DEBUG2, "Creating group %s\n", pat);
126 g = group_new(pat);
128 }
129
130 return g;
131}
static struct Group * group_new(const char *pat)
Create a new Address Group.
Definition: group.c:70
#define mutt_debug(LEVEL,...)
Definition: logging2.h:87
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
Definition: hash.c:335
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
Definition: hash.c:362
@ LL_DEBUG2
Log at debug level 2.
Definition: logging2.h:44
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ group_remove()

static void group_remove ( struct Group g)
static

Remove a Group from the Hash Table.

Parameters
gGroup to remove

Definition at line 137 of file group.c.

138{
139 if (!g)
140 return;
142}
void mutt_hash_delete(struct HashTable *table, const char *strkey, const void *data)
Remove an element from a Hash Table.
Definition: hash.c:427
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_grouplist_clear()

void mutt_grouplist_clear ( struct GroupList *  gl)

Clear a GroupList.

Parameters
glGroupList to clear

Definition at line 148 of file group.c.

149{
150 if (!gl)
151 return;
152
153 struct GroupNode *np = STAILQ_FIRST(gl);
154 struct GroupNode *next = NULL;
155 while (np)
156 {
157 group_remove(np->group);
158 next = STAILQ_NEXT(np, entries);
159 FREE(&np);
160 np = next;
161 }
162 STAILQ_INIT(gl);
163}
static void group_remove(struct Group *g)
Remove a Group from the Hash Table.
Definition: group.c:137
#define STAILQ_FIRST(head)
Definition: queue.h:350
#define STAILQ_NEXT(elm, field)
Definition: queue.h:400
An element in a GroupList.
Definition: group.h:50
struct Group * group
Address Group.
Definition: group.h:51
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ empty_group()

static bool empty_group ( struct Group g)
static

Is a Group empty?

Parameters
gGroup to test
Return values
trueThe Group is empty

Definition at line 170 of file group.c.

171{
172 if (!g)
173 return true;
174 return TAILQ_EMPTY(&g->al) && STAILQ_EMPTY(&g->rs);
175}
#define STAILQ_EMPTY(head)
Definition: queue.h:348
#define TAILQ_EMPTY(head)
Definition: queue.h:721
+ Here is the caller graph for this function:

◆ mutt_grouplist_add()

void mutt_grouplist_add ( struct GroupList *  gl,
struct Group group 
)

Add a Group to a GroupList.

Parameters
glGroupList to add to
groupGroup to add

Definition at line 182 of file group.c.

183{
184 if (!gl || !group)
185 return;
186
187 struct GroupNode *np = NULL;
188 STAILQ_FOREACH(np, gl, entries)
189 {
190 if (np->group == group)
191 return;
192 }
193 np = mutt_mem_calloc(1, sizeof(struct GroupNode));
194 np->group = group;
195 STAILQ_INSERT_TAIL(gl, np, entries);
196}
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:389
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_grouplist_destroy()

void mutt_grouplist_destroy ( struct GroupList *  gl)

Free a GroupList.

Parameters
glGroupList to free

Definition at line 202 of file group.c.

203{
204 if (!gl)
205 return;
206
207 struct GroupNode *np = STAILQ_FIRST(gl);
208 struct GroupNode *next = NULL;
209 while (np)
210 {
211 next = STAILQ_NEXT(np, entries);
212 FREE(&np);
213 np = next;
214 }
215 STAILQ_INIT(gl);
216}
+ Here is the caller graph for this function:

◆ group_add_addrlist()

static void group_add_addrlist ( struct Group g,
const struct AddressList *  al 
)
static

Add an Address List to a Group.

Parameters
gGroup to add to
alAddress List

Definition at line 223 of file group.c.

224{
225 if (!g || !al)
226 return;
227
228 struct AddressList al_new = TAILQ_HEAD_INITIALIZER(al_new);
229 mutt_addrlist_copy(&al_new, al, false);
230 mutt_addrlist_remove_xrefs(&g->al, &al_new);
231 struct Address *a = NULL, *tmp = NULL;
232 TAILQ_FOREACH_SAFE(a, &al_new, entries, tmp)
233 {
234 TAILQ_REMOVE(&al_new, a, entries);
235 mutt_addrlist_append(&g->al, a);
236 }
237 assert(TAILQ_EMPTY(&al_new));
238}
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:750
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition: address.c:1469
void mutt_addrlist_remove_xrefs(const struct AddressList *a, struct AddressList *b)
Remove cross-references.
Definition: address.c:1422
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:735
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:841
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:637
An email address.
Definition: address.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ group_add_regex()

static int group_add_regex ( struct Group g,
const char *  s,
uint16_t  flags,
struct Buffer err 
)
static

Add a Regex to a Group.

Parameters
gGroup to add to
sRegex string to add
flagsFlags, e.g. REG_ICASE
errBuffer for error message
Return values
0Success
-1Error

Definition at line 249 of file group.c.

250{
251 return mutt_regexlist_add(&g->rs, s, flags, err);
252}
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:135
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ group_remove_regex()

static int group_remove_regex ( struct Group g,
const char *  s 
)
static

Remove a Regex from a Group.

Parameters
gGroup to modify
sRegex string to match
Return values
0Success
-1Error

Definition at line 261 of file group.c.

262{
263 return mutt_regexlist_remove(&g->rs, s);
264}
int mutt_regexlist_remove(struct RegexList *rl, const char *str)
Remove a Regex from a list.
Definition: regex.c:230
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_grouplist_add_addrlist()

void mutt_grouplist_add_addrlist ( struct GroupList *  gl,
struct AddressList *  al 
)

Add Address list to a GroupList.

Parameters
glGroupList to add to
alAddress list to add

Definition at line 271 of file group.c.

272{
273 if (!gl || !al)
274 return;
275
276 struct GroupNode *np = NULL;
277 STAILQ_FOREACH(np, gl, entries)
278 {
279 group_add_addrlist(np->group, al);
280 }
281}
static void group_add_addrlist(struct Group *g, const struct AddressList *al)
Add an Address List to a Group.
Definition: group.c:223
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_grouplist_remove_addrlist()

int mutt_grouplist_remove_addrlist ( struct GroupList *  gl,
struct AddressList *  al 
)

Remove an AddressList from a GroupList.

Parameters
glGroupList to remove from
alAddressList to remove
Return values
0Success
-1Error

Definition at line 290 of file group.c.

291{
292 if (!gl || !al)
293 return -1;
294
295 struct GroupNode *gnp = NULL;
296 STAILQ_FOREACH(gnp, gl, entries)
297 {
298 struct Address *a = NULL;
299 TAILQ_FOREACH(a, al, entries)
300 {
302 }
303 if (empty_group(gnp->group))
304 {
305 group_remove(gnp->group);
306 }
307 }
308
309 return 0;
310}
int mutt_addrlist_remove(struct AddressList *al, const char *mailbox)
Remove an Address from a list.
Definition: address.c:427
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:90
static bool empty_group(struct Group *g)
Is a Group empty?
Definition: group.c:170
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
struct Buffer * mailbox
Mailbox and host address.
Definition: address.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_grouplist_add_regex()

int mutt_grouplist_add_regex ( struct GroupList *  gl,
const char *  s,
uint16_t  flags,
struct Buffer err 
)

Add matching Addresses to a GroupList.

Parameters
glGroupList to add to
sAddress to match
flagsFlags, e.g. REG_ICASE
errBuffer for error message
Return values
0Success
-1Error

Definition at line 321 of file group.c.

323{
324 if (!gl || !s)
325 return -1;
326
327 int rc = 0;
328
329 struct GroupNode *np = NULL;
330 STAILQ_FOREACH(np, gl, entries)
331 {
332 rc = group_add_regex(np->group, s, flags, err);
333 if (rc)
334 return rc;
335 }
336 return rc;
337}
static int group_add_regex(struct Group *g, const char *s, uint16_t flags, struct Buffer *err)
Add a Regex to a Group.
Definition: group.c:249
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_grouplist_remove_regex()

int mutt_grouplist_remove_regex ( struct GroupList *  gl,
const char *  s 
)

Remove matching addresses from a GroupList.

Parameters
glGroupList to remove from
sAddress to match
Return values
0Success
-1Error

Definition at line 346 of file group.c.

347{
348 if (!gl || !s)
349 return -1;
350
351 int rc = 0;
352 struct GroupNode *np = NULL;
353 STAILQ_FOREACH(np, gl, entries)
354 {
355 rc = group_remove_regex(np->group, s);
356 if (empty_group(np->group))
357 group_remove(np->group);
358 if (rc)
359 return rc;
360 }
361 return rc;
362}
static int group_remove_regex(struct Group *g, const char *s)
Remove a Regex from a Group.
Definition: group.c:261
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_group_match()

bool mutt_group_match ( struct Group g,
const char *  s 
)

Does a string match an entry in a Group?

Parameters
gGroup to match against
sString to match
Return values
trueThere's a match

Definition at line 370 of file group.c.

371{
372 if (!g || !s)
373 return false;
374
375 if (mutt_regexlist_match(&g->rs, s))
376 return true;
377 struct Address *a = NULL;
378 TAILQ_FOREACH(a, &g->al, entries)
379 {
380 if (a->mailbox && mutt_istr_equal(s, buf_string(a->mailbox)))
381 return true;
382 }
383
384 return false;
385}
bool mutt_regexlist_match(struct RegexList *rl, const char *str)
Does a string match any Regex in the list?
Definition: regex.c:195
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:810
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ Groups

struct HashTable* Groups = NULL
static

Hash Table: "group-name" -> Group.

A set of all the Address Groups.

Definition at line 43 of file group.c.