2 * ngIRCd -- The Next Generation IRC Daemon
3 * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * Please read the file COPYING, README and AUTHORS for more information.
16 * Management of IRC lists: ban, invite, etc.
32 struct list_elem *next; /** pointer to next list element */
33 char mask[MASK_LEN]; /** IRC mask */
34 char *reason; /** Optional "reason" text */
35 time_t valid_until; /** 0: unlimited; t(>0): until t */
40 * Get IRC mask stored in list element.
42 * @param list_elem List element.
43 * @return Pointer to IRC mask
46 Lists_GetMask(const struct list_elem *e)
53 * Get optional "reason" text stored in list element.
55 * @param list_elem List element.
56 * @return Pointer to "reason" text or empty string ("").
59 Lists_GetReason(const struct list_elem *e)
62 return e->reason ? e->reason : "";
66 * Get "validity" value stored in list element.
68 * @param list_elem List element.
69 * @return Validity: 0=unlimited, >0 until this time stamp.
72 Lists_GetValidity(const struct list_elem *e)
75 return e->valid_until;
79 * Get "onlyonce" value stored in list element.
81 * @param list_elem List element.
82 * @return True if the element was stored for single use, false otherwise.
85 Lists_GetOnlyOnce(const struct list_elem *e)
92 * Get first list element of a list.
95 * @return Pointer to first list element.
97 GLOBAL struct list_elem*
98 Lists_GetFirst(const struct list_head *h)
105 * Get next list element of a list.
107 * @param e Current list element.
108 * @return Pointer to next list element.
110 GLOBAL struct list_elem*
111 Lists_GetNext(const struct list_elem *e)
118 * Add a new mask to a list.
120 * @param h List head.
121 * @param Mask The IRC mask to add to the list.
122 * @param ValidUntil 0: unlimited, 1: only once, t>1: until given time_t.
123 * @param Reason Reason string or NULL, if no reason should be saved.
124 * @return true on success, false otherwise.
127 Lists_Add(struct list_head *h, const char *Mask, time_t ValidUntil,
128 const char *Reason, bool OnlyOnce)
130 struct list_elem *e, *newelem;
133 assert(Mask != NULL);
135 e = Lists_CheckDupeMask(h, Mask);
137 e->valid_until = ValidUntil;
141 e->reason = strdup(Reason);
146 e = Lists_GetFirst(h);
148 newelem = malloc(sizeof(struct list_elem));
151 "Can't allocate memory for new list entry!");
155 strlcpy(newelem->mask, Mask, sizeof(newelem->mask));
157 newelem->reason = strdup(Reason);
158 if (!newelem->reason)
160 "Can't allocate memory for new list reason text!");
163 newelem->reason = NULL;
164 newelem->valid_until = ValidUntil;
165 newelem->onlyonce = OnlyOnce;
173 * Delete a list element from a list.
175 * @param h List head.
176 * @param p Pointer to previous list element or NULL, if there is none.
177 * @param victim List element to delete.
180 Lists_Unlink(struct list_head *h, struct list_elem *p, struct list_elem *victim)
182 assert(victim != NULL);
186 p->next = victim->next;
188 h->first = victim->next;
191 free(victim->reason);
197 * Delete a given IRC mask from a list.
199 * @param h List head.
200 * @param Mask IRC mask to delete from the list.
203 Lists_Del(struct list_head *h, const char *Mask)
205 struct list_elem *e, *last, *victim;
208 assert(Mask != NULL);
211 e = Lists_GetFirst(h);
213 if (strcasecmp(e->mask, Mask) == 0) {
214 LogDebug("Deleted \"%s\" from list", e->mask);
217 Lists_Unlink(h, last, victim);
226 * Free a complete list.
228 * @param head List head.
231 Lists_Free(struct list_head *head)
233 struct list_elem *e, *victim;
235 assert(head != NULL);
240 LogDebug("Deleted \"%s\" from list" , e->mask);
244 free(victim->reason);
250 * Check if an IRC mask is already contained in a list.
252 * @param h List head.
253 * @param Mask IRC mask to test.
254 * @return true if mask is already stored in the list, false otherwise.
256 GLOBAL struct list_elem *
257 Lists_CheckDupeMask(const struct list_head *h, const char *Mask )
262 if (strcasecmp(e->mask, Mask) == 0)
270 * Generate a valid IRC mask from "any" string given.
272 * @param Pattern Source string to generate an IRC mask for.
273 * @param mask Buffer to store the mask.
274 * @param len Size of the buffer.
277 Lists_MakeMask(const char *Pattern, char *mask, size_t len)
281 assert(Pattern != NULL);
283 excl = strchr(Pattern, '!');
284 at = strchr(Pattern, '@');
290 /* Neither "!" nor "@" found: use string as nickname */
291 strlcpy(mask, Pattern, len - 5);
292 strlcat(mask, "!*@*", len);
293 } else if (!at && excl) {
294 /* Domain part is missing */
295 strlcpy(mask, Pattern, len - 3);
296 strlcat(mask, "@*", len);
297 } else if (at && !excl) {
298 /* User name is missing */
300 strlcpy(mask, Pattern, len - 5);
301 strlcat(mask, "!*@", len);
302 strlcat(mask, at, len);
305 /* All parts (nick, user and domain name) are given */
306 strlcpy(mask, Pattern, len);
308 } /* Lists_MakeMask */
311 * Check if a client is listed in a list.
313 * @param h List head.
314 * @param Client Client to check.
315 * @return true if client is listed, false if not.
318 Lists_Check(struct list_head *h, CLIENT *Client)
320 return Lists_CheckReason(h, Client, NULL, 0);
324 * Check if a client is listed in a list and store the reason.
326 * @param h List head.
327 * @param Client Client to check.
328 * @param reason Buffer to store the reason.
329 * @param len Size of the buffer if reason should be saved.
330 * @return true if client is listed, false if not.
333 Lists_CheckReason(struct list_head *h, CLIENT *Client, char *reason, size_t len)
335 struct list_elem *e, *last, *next;
344 if (MatchCaseInsensitive(e->mask, Client_MaskCloaked(Client))) {
345 if (len && e->reason)
346 strlcpy(reason, e->reason, len);
347 if (e->valid_until == 1) {
348 /* Entry is valid only once, delete it */
349 LogDebug("Deleted \"%s\" from list (used).",
351 Lists_Unlink(h, last, e);
363 * Check list and purge expired entries.
365 * @param h List head.
368 Lists_Expire(struct list_head *h, const char *ListName)
370 struct list_elem *e, *last, *next;
381 if (e->valid_until > 0 && e->valid_until < now) {
382 /* Entry is expired, delete it */
385 "Deleted \"%s\" (\"%s\") from %s list (expired).",
386 e->mask, e->reason, ListName);
389 "Deleted \"%s\" from %s list (expired).",
391 Lists_Unlink(h, last, e);
401 * Return the number of entries of a list.
403 * @param h List head.
404 * @return Number of items.
407 Lists_Count(struct list_head *h)
410 unsigned long count = 0;