X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Flists.c;h=cde928f6bf9c0301b260d5fb25b1cf89b2dbfaca;hp=cc50dc1202ff0667399071f52bb131db4c713f34;hb=03628dbeaf40a9de34b3eb6d5bf6dd34eed8248c;hpb=6d28127154459360f55337ebc9dcc070e9ebf0b5 diff --git a/src/ngircd/lists.c b/src/ngircd/lists.c index cc50dc12..cde928f6 100644 --- a/src/ngircd/lists.c +++ b/src/ngircd/lists.c @@ -1,97 +1,240 @@ /* * 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. - * - * $Id: lists.c,v 1.2 2002/06/02 15:23:16 alex Exp $ - * - * lists.c: Verwaltung der "IRC-Listen": Ban, Invite, ... + * 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. */ #include "portab.h" +/** + * @file + * Management of IRC lists: ban, invite, etc. + */ + #include "imp.h" #include +#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) -typedef struct _C2C -{ - struct _C2C *next; - CLIENT *client; - CHANNEL *channel; -} C2C; +struct list_elem { + struct list_elem *next; + char mask[MASK_LEN]; + bool onlyonce; +}; -LOCAL C2C *My_Invites, *My_Bans; +GLOBAL const char * +Lists_GetMask(const struct list_elem *e) +{ + return e->mask; +} -LOCAL C2C *New_C2C PARAMS(( CLIENT *Client, CHANNEL *Chan )); +GLOBAL struct list_elem* +Lists_GetFirst(const struct list_head *h) +{ + return h->first; +} -GLOBAL VOID -Lists_Init( VOID ) +GLOBAL struct list_elem* +Lists_GetNext(const struct list_elem *e) { - /* Modul initialisieren */ + return e->next; +} - My_Invites = My_Bans = NULL; -} /* Lists_Init */ - -GLOBAL VOID -Lists_Exit( VOID ) +bool +Lists_Add(struct list_head *header, const char *Mask, bool OnlyOnce ) { - /* Modul abmelden */ -} /* Lists_Exit */ + struct list_elem *e, *newelem; + assert( header != NULL ); + assert( Mask != NULL ); -GLOBAL BOOLEAN -Lists_CheckInvited( CLIENT *Client, CHANNEL *Chan ) -{ - assert( Client != NULL ); - assert( Chan != NULL ); + if (Lists_CheckDupeMask(header, Mask )) return true; - return FALSE; -} /* Lists_CheckInvited */ + e = Lists_GetFirst(header); + newelem = malloc(sizeof(struct list_elem)); + if( ! newelem ) { + Log( LOG_EMERG, "Can't allocate memory for new Ban/Invite entry!" ); + return false; + } -GLOBAL VOID -Lists_AddInvited( CHAR *Pattern, CHANNEL *Chan ) -{ -} /* Lists_AddInvited */ + strlcpy( newelem->mask, Mask, sizeof( newelem->mask )); + newelem->onlyonce = OnlyOnce; + newelem->next = e; + header->first = newelem; + + return true; +} -GLOBAL BOOLEAN -Lists_CheckBanned( CLIENT *Client, CHANNEL *Chan ) +static void +Lists_Unlink(struct list_head *header, struct list_elem *p, struct list_elem *victim) { - assert( Client != NULL ); - assert( Chan != NULL ); + assert(victim != NULL); + assert(header != NULL); + + if (p) p->next = victim->next; + else header->first = victim->next; - return FALSE; -} /* Lists_CheckBanned */ + free(victim); +} -LOCAL C2C * -New_C2C( CLIENT *Client, CHANNEL *Chan ) +GLOBAL void +Lists_Del(struct list_head *header, const char *Mask) { - assert( Client != NULL ); - assert( Chan != NULL ); + struct list_elem *e, *last, *victim; + + assert( header != NULL ); + assert( Mask != NULL ); + + last = NULL; + 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 = e; + e = e->next; + } +} + + +GLOBAL void +Lists_Free(struct list_head *head) +{ + struct list_elem *e, *victim; + + assert(head != NULL); - return NULL; -} /* New_C2C */ + e = head->first; + head->first = NULL; + while (e) { + LogDebug("Deleted \"%s\" from invite list" , e->mask); + victim = e; + e = e->next; + free( victim ); + } +} +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 const char * +Lists_MakeMask(const char *Pattern) +{ + /* 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! */ + + static char TheMask[MASK_LEN]; + char *excl, *at; + + assert( Pattern != NULL ); + + excl = strchr( Pattern, '!' ); + at = strchr( Pattern, '@' ); + + if(( at ) && ( at < excl )) excl = NULL; + + if(( ! at ) && ( ! excl )) + { + /* Neither "!" nor "@" found: use string as nick name */ + strlcpy( TheMask, Pattern, sizeof( TheMask ) - 5 ); + strlcat( TheMask, "!*@*", sizeof( TheMask )); + return TheMask; + } + + if(( ! at ) && ( excl )) + { + /* 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; + } + + /* All parts (nick, user and domain name) are given */ + strlcpy( TheMask, Pattern, sizeof( TheMask )); + return TheMask; +} /* Lists_MakeMask */ + + + +bool +Lists_Check( struct list_head *header, CLIENT *Client) +{ + struct list_elem *e, *last; + + assert( header != NULL ); + + 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- */