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;
42 time_t valid_until; /** 0: unlimited; 1: once; t(>1): until t */
47 Lists_GetMask(const struct list_elem *e)
53 GLOBAL struct list_elem*
54 Lists_GetFirst(const struct list_head *h)
60 GLOBAL struct list_elem*
61 Lists_GetNext(const struct list_elem *e)
68 Lists_Add(struct list_head *header, const char *Mask, time_t ValidUntil )
70 struct list_elem *e, *newelem;
72 assert( header != NULL );
73 assert( Mask != NULL );
75 if (Lists_CheckDupeMask(header, Mask )) return true;
77 e = Lists_GetFirst(header);
79 newelem = malloc(sizeof(struct list_elem));
81 Log( LOG_EMERG, "Can't allocate memory for new Ban/Invite entry!" );
85 strlcpy( newelem->mask, Mask, sizeof( newelem->mask ));
86 newelem->valid_until = ValidUntil;
88 header->first = newelem;
95 Lists_Unlink(struct list_head *header, struct list_elem *p, struct list_elem *victim)
97 assert(victim != NULL);
98 assert(header != NULL);
100 if (p) p->next = victim->next;
101 else header->first = victim->next;
108 Lists_Del(struct list_head *header, const char *Mask)
110 struct list_elem *e, *last, *victim;
112 assert( header != NULL );
113 assert( Mask != NULL );
116 e = Lists_GetFirst(header);
118 if(strcasecmp( e->mask, Mask ) == 0 ) {
119 LogDebug("Deleted \"%s\" from list", e->mask);
122 Lists_Unlink(header, last, victim);
132 Lists_Free(struct list_head *head)
134 struct list_elem *e, *victim;
136 assert(head != NULL);
141 LogDebug("Deleted \"%s\" from invite list" , e->mask);
150 Lists_CheckDupeMask(const struct list_head *h, const char *Mask )
155 if (strcasecmp( e->mask, Mask ) == 0 )
164 Lists_MakeMask(const char *Pattern)
166 /* This function generats a valid IRC mask of "any" string. This
167 * mask is only valid until the next call to Lists_MakeMask(),
168 * because a single global buffer is used. You have to copy the
169 * generated mask to some sane location yourself! */
171 static char TheMask[MASK_LEN];
174 assert( Pattern != NULL );
176 excl = strchr( Pattern, '!' );
177 at = strchr( Pattern, '@' );
179 if(( at ) && ( at < excl )) excl = NULL;
181 if(( ! at ) && ( ! excl ))
183 /* Neither "!" nor "@" found: use string as nick name */
184 strlcpy( TheMask, Pattern, sizeof( TheMask ) - 5 );
185 strlcat( TheMask, "!*@*", sizeof( TheMask ));
189 if(( ! at ) && ( excl ))
191 /* Domain part is missing */
192 strlcpy( TheMask, Pattern, sizeof( TheMask ) - 3 );
193 strlcat( TheMask, "@*", sizeof( TheMask ));
197 if(( at ) && ( ! excl ))
199 /* User name is missing */
201 strlcpy( TheMask, Pattern, sizeof( TheMask ) - 5 );
202 strlcat( TheMask, "!*@", sizeof( TheMask ));
203 strlcat( TheMask, at, sizeof( TheMask ));
207 /* All parts (nick, user and domain name) are given */
208 strlcpy( TheMask, Pattern, sizeof( TheMask ));
210 } /* Lists_MakeMask */
214 Lists_Check( struct list_head *header, CLIENT *Client)
216 struct list_elem *e, *last, *next;
218 assert( header != NULL );
225 if (e->valid_until > 1 && e->valid_until < time(NULL)) {
226 /* Entry is expired, delete it */
227 LogDebug("Deleted \"%s\" from list (expired).",
229 Lists_Unlink(header, last, e);
233 if (Match(e->mask, Client_Mask(Client))) {
234 if (e->valid_until == 1 ) {
235 /* Entry is valid only once, delete it */
236 LogDebug("Deleted \"%s\" from list (used).",
238 Lists_Unlink(header, last, e);