X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Flists.c;h=363c62dbeae305cf460b3203bcf846afc2804037;hb=1fe17e246cba4ee2f4349196c544296790ab5d55;hp=a87625ba00e8147ac668ee483774642345424d95;hpb=9dc44d9babf9fe57f6123190369ceea27fdd7921;p=ngircd-alex.git diff --git a/src/ngircd/lists.c b/src/ngircd/lists.c index a87625ba..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.1 2002/05/27 11:22:39 alex Exp $ - * - * lists.c: Verwaltung der "IRC-Listen": Ban, Invite, ... + * Management of IRC lists: ban, invite, ... */ @@ -20,72 +17,222 @@ #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) + +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; - CLIENT *client; - CHANNEL *channel; -} 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(( CLIENT *Client, CHANNEL *Chan )); +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 */ + struct list_elem *e, *newelem; - My_Invites = My_Bans = NULL; -} /* Lists_Init */ + assert( header != NULL ); + assert( Mask != NULL ); + if (Lists_CheckDupeMask(header, Mask )) return true; -GLOBAL VOID -Lists_Exit( VOID ) -{ - /* Modul abmelden */ -} /* Lists_Exit */ + 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 BOOLEAN -Lists_CheckInvited( CLIENT *Client, CHANNEL *Chan ) -{ - assert( Client != NULL ); - assert( Chan != NULL ); + strlcpy( newelem->mask, Mask, sizeof( newelem->mask )); + newelem->onlyonce = OnlyOnce; + newelem->next = e; + header->first = newelem; - return FALSE; -} /* Lists_CheckInvited */ + LogDebug("Added \"%s\" to invite list", Mask); + 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); - return FALSE; -} /* Lists_CheckBanned */ + if (p) p->next = victim->next; + else header->first = victim->next; + free(victim); +} -LOCAL C2C * -New_C2C( CLIENT *Client, CHANNEL *Chan ) + +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; + 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) { - assert( Client != NULL ); - assert( Chan != NULL ); + struct list_elem *e, *victim; + + assert(head != NULL); + + e = head->first; + head->first = NULL; + while (e) { + LogDebug("Deleted \"%s\" from invite list" , e->mask); + victim = e; + e = e->next; + free( victim ); + } +} - return NULL; -} /* New_C2C */ +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- */