X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Flists.c;h=363c62dbeae305cf460b3203bcf846afc2804037;hp=d4b0a1430f17c8ef02ca093a80e5e312d919ff43;hb=a988bbc86aed404b7bcfdbceafc030ea4bc5ecab;hpb=31a8dd2f2fafe904970d9b63f0761503116b8b13 diff --git a/src/ngircd/lists.c b/src/ngircd/lists.c index d4b0a143..363c62db 100644 --- a/src/ngircd/lists.c +++ b/src/ngircd/lists.c @@ -1,17 +1,14 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de) + * Copyright (c)2001-2005 Alexander Barton (alex@barton.de) * - * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen - * der GNU General Public License (GPL), wie von der Free Software Foundation - * herausgegeben, weitergeben und/oder modifizieren, entweder unter Version 2 - * der Lizenz oder (wenn Sie es wuenschen) jeder spaeteren Version. - * Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste - * der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: lists.c,v 1.3 2002/06/09 13:18:23 alex Exp $ - * - * lists.c: Verwaltung der "IRC-Listen": Ban, Invite, ... + * Management of IRC lists: ban, invite, ... */ @@ -22,205 +19,220 @@ #include "defines.h" #include "conn.h" -#include "client.h" #include "channel.h" #include "log.h" +#include "match.h" +#include "messages.h" +#include "irc-write.h" #include #include +#include #include "exp.h" #include "lists.h" +#define MASK_LEN (2*CLIENT_HOST_LEN) -#define MASK_LEN CLIENT_ID_LEN+CLIENT_HOST_LEN +struct list_elem { + struct list_elem *next; + char mask[MASK_LEN]; + bool onlyonce; +}; -typedef struct _C2C +GLOBAL const char * +Lists_GetMask(const struct list_elem *e) { - struct _C2C *next; - CHAR mask[MASK_LEN]; - CHANNEL *channel; - BOOLEAN onlyonce; -} C2C; + return e->mask; +} -LOCAL C2C *My_Invites, *My_Bans; +GLOBAL struct list_elem* +Lists_GetFirst(const struct list_head *h) +{ + return h->first; +} -LOCAL C2C *New_C2C PARAMS(( CHAR *Mask, CHANNEL *Chan, BOOLEAN OnlyOnce )); +GLOBAL struct list_elem* +Lists_GetNext(const struct list_elem *e) +{ + return e->next; +} -GLOBAL VOID -Lists_Init( VOID ) +bool +Lists_Add(struct list_head *header, const char *Mask, bool OnlyOnce ) { - /* Modul initialisieren */ - - My_Invites = My_Bans = NULL; -} /* Lists_Init */ + struct list_elem *e, *newelem; + assert( header != NULL ); + assert( Mask != NULL ); -GLOBAL VOID -Lists_Exit( VOID ) -{ - /* Modul abmelden */ + if (Lists_CheckDupeMask(header, Mask )) return true; - C2C *c2c, *next; + e = Lists_GetFirst(header); - /* Invite-Lists freigeben */ - c2c = My_Invites; - while( c2c ) - { - next = c2c->next; - free( c2c ); - c2c = next; + newelem = malloc(sizeof(struct list_elem)); + if( ! newelem ) { + Log( LOG_EMERG, "Can't allocate memory for new Ban/Invite entry!" ); + return false; } - /* Ban-Lists freigeben */ - c2c = My_Bans; - while( c2c ) - { - next = c2c->next; - free( c2c ); - c2c = next; - } -} /* Lists_Exit */ + strlcpy( newelem->mask, Mask, sizeof( newelem->mask )); + newelem->onlyonce = OnlyOnce; + newelem->next = e; + header->first = newelem; + LogDebug("Added \"%s\" to invite list", Mask); + return true; +} -GLOBAL BOOLEAN -Lists_CheckInvited( CLIENT *Client, CHANNEL *Chan ) + +static void +Lists_Unlink(struct list_head *header, struct list_elem *p, struct list_elem *victim) { - C2C *c2c, *last; - - assert( Client != NULL ); - assert( Chan != NULL ); + assert(victim != NULL); + assert(header != NULL); + + if (p) p->next = victim->next; + else header->first = victim->next; + + free(victim); +} + + +GLOBAL void +Lists_Del(struct list_head *header, const char *Mask) +{ + struct list_elem *e, *last, *victim; + + assert( header != NULL ); + assert( Mask != NULL ); last = NULL; - c2c = My_Invites; - while( c2c ) - { - if( c2c->channel == Chan ) - { - /* Ok, richtiger Channel. Passt die Maske? */ - if( strcasecmp( Client_Mask( Client ), c2c->mask ) == 0 ) - { - /* Treffer! */ - if( c2c->onlyonce ) - { - /* Eintrag loeschen */ - if( last ) last->next = c2c->next; - else My_Invites = c2c->next; - free( c2c ); - } - return TRUE; - } + e = Lists_GetFirst(header); + while( e ) { + if(strcasecmp( e->mask, Mask ) == 0 ) { + LogDebug("Deleted \"%s\" from list", e->mask); + victim = e; + e = victim->next; + Lists_Unlink(header, last, victim); + continue; } - last = c2c; - c2c = c2c->next; + last = e; + e = e->next; } - - return FALSE; -} /* Lists_CheckInvited */ +} -GLOBAL VOID -Lists_AddInvited( CHAR *Pattern, CHANNEL *Chan, BOOLEAN OnlyOnce ) +GLOBAL void +Lists_Free(struct list_head *head) { - C2C *c2c; + struct list_elem *e, *victim; - assert( Pattern != NULL ); - assert( Chan != NULL ); + assert(head != NULL); - c2c = New_C2C( Pattern, Chan, OnlyOnce ); - if( ! c2c ) - { - Log( LOG_ERR, "Can't add new invite list entry!" ); - return; + e = head->first; + head->first = NULL; + while (e) { + LogDebug("Deleted \"%s\" from invite list" , e->mask); + victim = e; + e = e->next; + free( victim ); } +} - /* verketten */ - c2c->next = My_Invites; - My_Invites = c2c; - Log( LOG_DEBUG, "Added \"%s\" to invite list for \"%s\".", Pattern, Channel_Name( Chan )); -} /* Lists_AddInvited */ +GLOBAL bool +Lists_CheckDupeMask(const struct list_head *h, const char *Mask ) +{ + struct list_elem *e; + e = h->first; + while (e) { + if (strcasecmp( e->mask, Mask ) == 0 ) + return true; + e = e->next; + } + return false; +} -GLOBAL BOOLEAN -Lists_CheckBanned( CLIENT *Client, CHANNEL *Chan ) +GLOBAL const char * +Lists_MakeMask(const char *Pattern) { - assert( Client != NULL ); - assert( Chan != NULL ); + /* This function generats a valid IRC mask of "any" string. This + * mask is only valid until the next call to Lists_MakeMask(), + * because a single global buffer is used. You have to copy the + * generated mask to some sane location yourself! */ - return FALSE; -} /* Lists_CheckBanned */ + static char TheMask[MASK_LEN]; + char *excl, *at; + assert( Pattern != NULL ); -GLOBAL VOID -Lists_DeleteChannel( CHANNEL *Chan ) -{ - /* Channel wurde geloescht, Invite- und Ban-Lists aufraeumen */ + excl = strchr( Pattern, '!' ); + at = strchr( Pattern, '@' ); - C2C *c2c, *last, *next; + if(( at ) && ( at < excl )) excl = NULL; - /* Invite-List */ - last = NULL; - c2c = My_Invites; - while( c2c ) + if(( ! at ) && ( ! excl )) { - next = c2c->next; - if( c2c->channel == Chan ) - { - /* dieser Eintrag muss geloescht werden */ - if( last ) last->next = next; - else My_Invites = next; - free( c2c ); - } - else last = c2c; - c2c = next; + /* Neither "!" nor "@" found: use string as nick name */ + strlcpy( TheMask, Pattern, sizeof( TheMask ) - 5 ); + strlcat( TheMask, "!*@*", sizeof( TheMask )); + return TheMask; } - /* Ban-List */ - last = NULL; - c2c = My_Bans; - while( c2c ) + if(( ! at ) && ( excl )) { - next = c2c->next; - if( c2c->channel == Chan ) - { - /* dieser Eintrag muss geloescht werden */ - if( last ) last->next = next; - else My_Bans = next; - free( c2c ); - } - else last = c2c; - c2c = next; + /* Domain part is missing */ + strlcpy( TheMask, Pattern, sizeof( TheMask ) - 3 ); + strlcat( TheMask, "@*", sizeof( TheMask )); + return TheMask; + } + + if(( at ) && ( ! excl )) + { + /* User name is missing */ + *at = '\0'; at++; + strlcpy( TheMask, Pattern, sizeof( TheMask ) - 5 ); + strlcat( TheMask, "!*@", sizeof( TheMask )); + strlcat( TheMask, at, sizeof( TheMask )); + return TheMask; } -} /* Lists_DeleteChannel */ + /* All parts (nick, user and domain name) are given */ + strlcpy( TheMask, Pattern, sizeof( TheMask )); + return TheMask; +} /* Lists_MakeMask */ -LOCAL C2C * -New_C2C( CHAR *Mask, CHANNEL *Chan, BOOLEAN OnlyOnce ) + + +bool +Lists_Check( struct list_head *header, CLIENT *Client) { - C2C *c2c; - - assert( Mask != NULL ); - assert( Chan != NULL ); + struct list_elem *e, *last; - /* Speicher fuer Eintrag anfordern */ - c2c = malloc( sizeof( C2C )); - if( ! c2c ) - { - Log( LOG_EMERG, "Can't allocate memory! [New_C2C]" ); - return NULL; - } + assert( header != NULL ); - strncpy( c2c->mask, Mask, MASK_LEN ); - c2c->channel = Chan; - c2c->onlyonce = OnlyOnce; - - return c2c; -} /* New_C2C */ + e = header->first; + last = NULL; + + while( e ) { + if( Match( e->mask, Client_Mask( Client ))) { + if( e->onlyonce ) { /* delete entry */ + LogDebug("Deleted \"%s\" from list", e->mask); + Lists_Unlink(header, last, e); + } + return true; + } + last = e; + e = e->next; + } + return false; +} /* -eof- */