2 * ngIRCd -- The Next Generation IRC Daemon
3 * Copyright (c)2001-2011 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.
28 #include "irc-write.h"
37 #define MASK_LEN (2*CLIENT_HOST_LEN)
40 struct list_elem *next; /** pointer to next list element */
41 char mask[MASK_LEN]; /** IRC mask */
42 char *reason; /** Optional "reason" text */
43 time_t valid_until; /** 0: unlimited; 1: once; t(>1): until t */
47 * Get IRC mask stored in list element.
49 * @param list_elem List element.
50 * @return Pointer to IRC mask
53 Lists_GetMask(const struct list_elem *e)
60 * Get optional "reason" text stored in list element.
62 * @param list_elem List element.
63 * @return Pointer to "reason" text or empty string ("").
66 Lists_GetReason(const struct list_elem *e)
69 return e->reason ? e->reason : "";
73 * Get "validity" value stored in list element.
75 * @param list_elem List element.
76 * @return Validity: 0=unlimited, 1=once, >1 until this time stamp.
79 Lists_GetValidity(const struct list_elem *e)
82 return e->valid_until;
86 * Get first list element of a list.
89 * @return Pointer to first list element.
91 GLOBAL struct list_elem*
92 Lists_GetFirst(const struct list_head *h)
99 * Get next list element of a list.
101 * @param e Current list element.
102 * @return Pointer to next list element.
104 GLOBAL struct list_elem*
105 Lists_GetNext(const struct list_elem *e)
112 * Add a new mask to a list.
114 * @param h List head.
115 * @param Mask The IRC mask to add to the list.
116 * @param ValidUntil 0: unlimited, 1: only once, t>1: until given time_t.
117 * @param Reason Reason string or NULL, if no reason should be saved.
118 * @return true on success, false otherwise.
121 Lists_Add(struct list_head *h, const char *Mask, time_t ValidUntil,
124 struct list_elem *e, *newelem;
127 assert(Mask != NULL);
129 e = Lists_CheckDupeMask(h, Mask);
131 e->valid_until = ValidUntil;
135 e->reason = strdup(Reason);
140 e = Lists_GetFirst(h);
142 newelem = malloc(sizeof(struct list_elem));
145 "Can't allocate memory for new list entry!");
149 strlcpy(newelem->mask, Mask, sizeof(newelem->mask));
151 newelem->reason = strdup(Reason);
152 if (!newelem->reason)
154 "Can't allocate memory for new list reason text!");
157 newelem->reason = NULL;
158 newelem->valid_until = ValidUntil;
166 * Delete a list element from a list.
168 * @param h List head.
169 * @param p Pointer to previous list element or NULL, if there is none.
170 * @param victim List element to delete.
173 Lists_Unlink(struct list_head *h, struct list_elem *p, struct list_elem *victim)
175 assert(victim != NULL);
179 p->next = victim->next;
181 h->first = victim->next;
184 free(victim->reason);
190 * Delete a given IRC mask from a list.
192 * @param h List head.
193 * @param Mask IRC mask to delete from the list.
196 Lists_Del(struct list_head *h, const char *Mask)
198 struct list_elem *e, *last, *victim;
201 assert(Mask != NULL);
204 e = Lists_GetFirst(h);
206 if (strcasecmp(e->mask, Mask) == 0) {
207 LogDebug("Deleted \"%s\" from list", e->mask);
210 Lists_Unlink(h, last, victim);
219 * Free a complete list.
221 * @param head List head.
224 Lists_Free(struct list_head *head)
226 struct list_elem *e, *victim;
228 assert(head != NULL);
233 LogDebug("Deleted \"%s\" from list" , e->mask);
237 free(victim->reason);
243 * Check if an IRC mask is already contained in a list.
245 * @param h List head.
246 * @param Mask IRC mask to test.
247 * @return true if mask is already stored in the list, false otherwise.
249 GLOBAL struct list_elem *
250 Lists_CheckDupeMask(const struct list_head *h, const char *Mask )
255 if (strcasecmp(e->mask, Mask) == 0)
263 * Generate a valid IRC mask from "any" string given.
265 * Attention: This mask is only valid until the next call to Lists_MakeMask(),
266 * because a single global buffer ist used! You have to copy the generated
267 * mask to some sane location yourself!
269 * @param Pattern Source string to generate an IRC mask for.
270 * @return Pointer to global result buffer.
273 Lists_MakeMask(const char *Pattern)
275 static char TheMask[MASK_LEN];
278 assert(Pattern != NULL);
280 excl = strchr(Pattern, '!');
281 at = strchr(Pattern, '@');
287 /* Neither "!" nor "@" found: use string as nickname */
288 strlcpy(TheMask, Pattern, sizeof(TheMask) - 5);
289 strlcat(TheMask, "!*@*", sizeof(TheMask));
294 /* Domain part is missing */
295 strlcpy(TheMask, Pattern, sizeof(TheMask) - 3);
296 strlcat(TheMask, "@*", sizeof(TheMask));
301 /* User name is missing */
303 strlcpy(TheMask, Pattern, sizeof(TheMask) - 5);
304 strlcat(TheMask, "!*@", sizeof(TheMask));
305 strlcat(TheMask, at, sizeof(TheMask));
309 /* All parts (nick, user and domain name) are given */
310 strlcpy(TheMask, Pattern, sizeof(TheMask));
312 } /* Lists_MakeMask */
315 * Check if a client is listed in a list.
317 * @param h List head.
318 * @param Client Client to check.
319 * @return true if client is listed, false if not.
322 Lists_Check(struct list_head *h, CLIENT *Client)
324 return Lists_CheckReason(h, Client, NULL, 0);
328 * Check if a client is listed in a list and store the reason if a buffer
331 * @param h List head.
332 * @param Client Client to check.
333 * @param reason Result buffer to store the reason.
334 * @param len Size of the buffer.
335 * @return true if client is listed, false if not.
338 Lists_CheckReason(struct list_head *h, CLIENT *Client, char *reason, size_t len)
340 struct list_elem *e, *last, *next;
349 if (Match(e->mask, Client_MaskCloaked(Client))) {
350 if (len && e->reason)
351 strlcpy(reason, e->reason, len);
352 if (e->valid_until == 1) {
353 /* Entry is valid only once, delete it */
354 LogDebug("Deleted \"%s\" from list (used).",
356 Lists_Unlink(h, last, e);
368 * Check list and purge expired entries.
370 * @param h List head.
373 Lists_Expire(struct list_head *h, const char *ListName)
375 struct list_elem *e, *last, *next;
386 if (e->valid_until > 1 && e->valid_until < now) {
387 /* Entry is expired, delete it */
390 "Deleted \"%s\" (\"%s\") from %s list (expired).",
391 e->mask, e->reason, ListName);
394 "Deleted \"%s\" from %s list (expired).",
396 Lists_Unlink(h, last, e);
406 * Return the number of entries of a list.
408 * @param h List head.
409 * @return Number of items.
412 Lists_Count(struct list_head *h)
415 unsigned long count = 0;