2 * ngIRCd -- The Next Generation IRC Daemon
3 * Copyright (c)2001-2005 Alexander Barton (alex@barton.de)
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.
11 * Management of IRC lists: ban, invite, ...
17 static char UNUSED id[] = "$Id: lists.c,v 1.21 2007/01/29 21:13:26 fw Exp $";
29 #include "irc-write.h"
38 #define MASK_LEN (2*CLIENT_HOST_LEN)
41 struct list_elem *next;
48 Lists_GetMask(const struct list_elem *e)
54 GLOBAL struct list_elem*
55 Lists_GetFirst(const struct list_head *h)
61 GLOBAL struct list_elem*
62 Lists_GetNext(const struct list_elem *e)
69 Lists_Add(struct list_head *header, const char *Mask, bool OnlyOnce )
71 struct list_elem *e, *newelem;
73 assert( header != NULL );
74 assert( Mask != NULL );
76 if (Lists_CheckDupeMask(header, Mask )) return true;
78 e = Lists_GetFirst(header);
80 newelem = malloc(sizeof(struct list_elem));
82 Log( LOG_EMERG, "Can't allocate memory for new Ban/Invite entry!" );
86 strlcpy( newelem->mask, Mask, sizeof( newelem->mask ));
87 newelem->onlyonce = OnlyOnce;
89 header->first = newelem;
91 LogDebug("Added \"%s\" to invite list", Mask);
97 Lists_Unlink(struct list_head *header, struct list_elem *p, struct list_elem *victim)
99 assert(victim != NULL);
100 assert(header != NULL);
102 if (p) p->next = victim->next;
103 else header->first = victim->next;
110 Lists_Del(struct list_head *header, const char *Mask)
112 struct list_elem *e, *last, *victim;
114 assert( header != NULL );
115 assert( Mask != NULL );
118 e = Lists_GetFirst(header);
120 if(strcasecmp( e->mask, Mask ) == 0 ) {
121 LogDebug("Deleted \"%s\" from list", e->mask);
124 Lists_Unlink(header, last, victim);
134 Lists_Free(struct list_head *head)
136 struct list_elem *e, *victim;
138 assert(head != NULL);
143 LogDebug("Deleted \"%s\" from invite list" , e->mask);
152 Lists_CheckDupeMask(const struct list_head *h, const char *Mask )
157 if (strcasecmp( e->mask, Mask ) == 0 )
166 Lists_MakeMask( char *Pattern )
168 /* This function generats a valid IRC mask of "any" string. This
169 * mask is only valid until the next call to Lists_MakeMask(),
170 * because a single global buffer is used. You have to copy the
171 * generated mask to some sane location yourself! */
173 static char TheMask[MASK_LEN];
176 assert( Pattern != NULL );
178 excl = strchr( Pattern, '!' );
179 at = strchr( Pattern, '@' );
181 if(( at ) && ( at < excl )) excl = NULL;
183 if(( ! at ) && ( ! excl ))
185 /* Neither "!" nor "@" found: use string as nick name */
186 strlcpy( TheMask, Pattern, sizeof( TheMask ) - 5 );
187 strlcat( TheMask, "!*@*", sizeof( TheMask ));
191 if(( ! at ) && ( excl ))
193 /* Domain part is missing */
194 strlcpy( TheMask, Pattern, sizeof( TheMask ) - 3 );
195 strlcat( TheMask, "@*", sizeof( TheMask ));
199 if(( at ) && ( ! excl ))
201 /* User name is missing */
203 strlcpy( TheMask, Pattern, sizeof( TheMask ) - 5 );
204 strlcat( TheMask, "!*@", sizeof( TheMask ));
205 strlcat( TheMask, at, sizeof( TheMask ));
209 /* All parts (nick, user and domain name) are given */
210 strlcpy( TheMask, Pattern, sizeof( TheMask ));
212 } /* Lists_MakeMask */
217 Lists_Check( struct list_head *header, CLIENT *Client)
219 struct list_elem *e, *last;
221 assert( header != NULL );
227 if( Match( e->mask, Client_Mask( Client ))) {
228 if( e->onlyonce ) { /* delete entry */
229 LogDebug("Deleted \"%s\" from list", e->mask);
230 Lists_Unlink(header, last, e);