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"
38 struct list_elem *next; /** pointer to next list element */
39 char mask[MASK_LEN]; /** IRC mask */
40 char *reason; /** Optional "reason" text */
41 time_t valid_until; /** 0: unlimited; 1: once; t(>1): until t */
45 * Get IRC mask stored in list element.
47 * @param list_elem List element.
48 * @return Pointer to IRC mask
51 Lists_GetMask(const struct list_elem *e)
58 * Get optional "reason" text stored in list element.
60 * @param list_elem List element.
61 * @return Pointer to "reason" text or empty string ("").
64 Lists_GetReason(const struct list_elem *e)
67 return e->reason ? e->reason : "";
71 * Get "validity" value stored in list element.
73 * @param list_elem List element.
74 * @return Validity: 0=unlimited, 1=once, >1 until this time stamp.
77 Lists_GetValidity(const struct list_elem *e)
80 return e->valid_until;
84 * Get first list element of a list.
87 * @return Pointer to first list element.
89 GLOBAL struct list_elem*
90 Lists_GetFirst(const struct list_head *h)
97 * Get next list element of a list.
99 * @param e Current list element.
100 * @return Pointer to next list element.
102 GLOBAL struct list_elem*
103 Lists_GetNext(const struct list_elem *e)
110 * Add a new mask to a list.
112 * @param h List head.
113 * @param Mask The IRC mask to add to the list.
114 * @param ValidUntil 0: unlimited, 1: only once, t>1: until given time_t.
115 * @param Reason Reason string or NULL, if no reason should be saved.
116 * @return true on success, false otherwise.
119 Lists_Add(struct list_head *h, const char *Mask, time_t ValidUntil,
122 struct list_elem *e, *newelem;
125 assert(Mask != NULL);
127 e = Lists_CheckDupeMask(h, Mask);
129 e->valid_until = ValidUntil;
133 e->reason = strdup(Reason);
138 e = Lists_GetFirst(h);
140 newelem = malloc(sizeof(struct list_elem));
143 "Can't allocate memory for new list entry!");
147 strlcpy(newelem->mask, Mask, sizeof(newelem->mask));
149 newelem->reason = strdup(Reason);
150 if (!newelem->reason)
152 "Can't allocate memory for new list reason text!");
155 newelem->reason = NULL;
156 newelem->valid_until = ValidUntil;
164 * Delete a list element from a list.
166 * @param h List head.
167 * @param p Pointer to previous list element or NULL, if there is none.
168 * @param victim List element to delete.
171 Lists_Unlink(struct list_head *h, struct list_elem *p, struct list_elem *victim)
173 assert(victim != NULL);
177 p->next = victim->next;
179 h->first = victim->next;
182 free(victim->reason);
188 * Delete a given IRC mask from a list.
190 * @param h List head.
191 * @param Mask IRC mask to delete from the list.
194 Lists_Del(struct list_head *h, const char *Mask)
196 struct list_elem *e, *last, *victim;
199 assert(Mask != NULL);
202 e = Lists_GetFirst(h);
204 if (strcasecmp(e->mask, Mask) == 0) {
205 LogDebug("Deleted \"%s\" from list", e->mask);
208 Lists_Unlink(h, last, victim);
217 * Free a complete list.
219 * @param head List head.
222 Lists_Free(struct list_head *head)
224 struct list_elem *e, *victim;
226 assert(head != NULL);
231 LogDebug("Deleted \"%s\" from list" , e->mask);
235 free(victim->reason);
241 * Check if an IRC mask is already contained in a list.
243 * @param h List head.
244 * @param Mask IRC mask to test.
245 * @return true if mask is already stored in the list, false otherwise.
247 GLOBAL struct list_elem *
248 Lists_CheckDupeMask(const struct list_head *h, const char *Mask )
253 if (strcasecmp(e->mask, Mask) == 0)
261 * Generate a valid IRC mask from "any" string given.
263 * @param Pattern Source string to generate an IRC mask for.
264 * @param mask Buffer to store the mask.
265 * @param len Size of the buffer.
268 Lists_MakeMask(const char *Pattern, char *mask, size_t len)
272 assert(Pattern != NULL);
274 excl = strchr(Pattern, '!');
275 at = strchr(Pattern, '@');
281 /* Neither "!" nor "@" found: use string as nickname */
282 strlcpy(mask, Pattern, len - 5);
283 strlcat(mask, "!*@*", len);
284 } else if (!at && excl) {
285 /* Domain part is missing */
286 strlcpy(mask, Pattern, len - 3);
287 strlcat(mask, "@*", len);
288 } else if (at && !excl) {
289 /* User name is missing */
291 strlcpy(mask, Pattern, len - 5);
292 strlcat(mask, "!*@", len);
293 strlcat(mask, at, len);
295 /* All parts (nick, user and domain name) are given */
296 strlcpy(mask, Pattern, len);
298 } /* Lists_MakeMask */
301 * Check if a client is listed in a list.
303 * @param h List head.
304 * @param Client Client to check.
305 * @return true if client is listed, false if not.
308 Lists_Check(struct list_head *h, CLIENT *Client)
310 return Lists_CheckReason(h, Client, NULL, 0);
314 * Check if a client is listed in a list and store the reason.
316 * @param h List head.
317 * @param Client Client to check.
318 * @param reason Buffer to store the reason.
319 * @param len Size of the buffer if reason should be saved.
320 * @return true if client is listed, false if not.
323 Lists_CheckReason(struct list_head *h, CLIENT *Client, char *reason, size_t len)
325 struct list_elem *e, *last, *next;
334 if (Match(e->mask, Client_MaskCloaked(Client))) {
335 if (len && e->reason)
336 strlcpy(reason, e->reason, len);
337 if (e->valid_until == 1) {
338 /* Entry is valid only once, delete it */
339 LogDebug("Deleted \"%s\" from list (used).",
341 Lists_Unlink(h, last, e);
353 * Check list and purge expired entries.
355 * @param h List head.
358 Lists_Expire(struct list_head *h, const char *ListName)
360 struct list_elem *e, *last, *next;
371 if (e->valid_until > 1 && e->valid_until < now) {
372 /* Entry is expired, delete it */
375 "Deleted \"%s\" (\"%s\") from %s list (expired).",
376 e->mask, e->reason, ListName);
379 "Deleted \"%s\" from %s list (expired).",
381 Lists_Unlink(h, last, e);
391 * Return the number of entries of a list.
393 * @param h List head.
394 * @return Number of items.
397 Lists_Count(struct list_head *h)
400 unsigned long count = 0;