/* * ---------------------------------------------------------------- * Night Light IRC Proxy - Channel * ---------------------------------------------------------------- * Copyright (C) 1997-2006 Jonas Kvinge * All rights reserved. * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Last modified by: * Jonas Kvinge (24.08.2004) * */ #define CHAN_C #define NEED_SYS_TYPES_H 1 /* Extra types */ #define NEED_SYS_PARAM_H 1 /* Some systems need this */ #define NEED_LIMITS_H 1 /* Kernel limits */ #define NEED_STDARG_H 1 /* va_list, etc */ #define NEED_ERRNO_H 1 /* errno */ #define NEED_CTYPE_H 1 /* isdigit(), etc */ #define NEED_NETINET_IN_H 1 /* in_addr, sockaddr_in, etc */ #define NEED_ARPA_INET_H 0 /* inet_ntoa(), inet_aton(), etc */ #define NEED_STDIO_H 1 /* Standard C UNIX functions */ #define NEED_STDLIB_H 1 /* malloc(), exit(), atoi(), etc */ #define NEED_TIME_H 1 /* time(), etc */ #define NEED_SYSCTL_H 0 /* sysctl(), etc */ #define NEED_SYS_STAT_H 0 /* chmod(), mkdir(), etc */ #define NEED_SYS_UIO_H 0 /* iovec, etc */ #define NEED_FCNTL_H 1 /* open(), creat(), fcntl(), etc */ #define NEED_SYS_IOCTL_H 0 /* ioctl(), etc */ #define NEED_SYS_FILIO_H 0 /* Solaris need this for ioctl(), etc */ #define NEED_UNISTD_H 1 /* Unix standard functions */ #define NEED_STRING_H 1 /* C string functions */ #define NEED_SIGNAL_H 0 /* Signal functions */ #define NEED_SYS_SOCKET_H 0 /* Socket functions */ #define NEED_NETDB_H 0 /* Network database functions */ #define NEED_ARPA_NAMESER_H 0 /* Nameserver definitions */ #define NEED_GETUSERPW_HEADERS 0 /* Functions to retrive system passwords */ #define NEED_ARES 0 /* Functions needed for ares */ #define NEED_SSL 1 /* Needed for SSL support */ #include "includes.h" #include "irc.h" #include "conn.h" #include "chan.h" #include "chan_user.h" #include "chan_mode.h" /* VARIABLES - JONAS (30.07.2001) */ static CHAN_HASHMEMS Chan_Hash_Map[CHAN_HASHMAPSIZE]; static CHAN_HASHMEMS Chan_Hash_Weight_Table[CHAR_MAX - CHAR_MIN + 1]; /* CHAN_ADD FUNCTION - JONAS (30.07.2001) */ struct Chan_Struct *chan_add(struct Conn_Struct *ConnS, const char *const ChanPT) { struct Chan_Struct *ChanS = NULL; struct Chan_Struct *ChanS_NEW = NULL; CHAN_HASHREGS Hash = 0; assert(ConnS != NULL); assert(ChanPT != NULL); ChanS = chan_get(ConnS, ChanPT); if (ChanS != NULL) { aerrno = AEEXISTS; return(ChanS); } ChanS_NEW = malloc(sizeof(struct Chan_Struct)); if (ChanS_NEW == NULL) { aerrno = AEMALLOC; return(NULL); } memset(ChanS_NEW, 0, sizeof(struct Chan_Struct)); ChanS_NEW->Chan = strdup(ChanPT); if (ChanS_NEW->Chan == NULL) { free(ChanS_NEW); aerrno = AEMALLOC; return(NULL); } if (ConnS->Chan_Head == NULL) { ConnS->Chan_Head = ChanS_NEW; ConnS->Chan_Tail = ChanS_NEW; } else { ChanS = ConnS->Chan_Tail; ChanS->Next = ChanS_NEW; ChanS_NEW->Prev = ChanS; ConnS->Chan_Tail = ChanS_NEW; } Hash = chan_strhash(ChanS_NEW->Chan); ChanS = ConnS->Chan_Table[Hash]; if (ChanS != NULL) { ChanS->PrevH = ChanS_NEW; } ChanS_NEW->NextH = ChanS; ConnS->Chan_Table[Hash] = ChanS_NEW; ConnS->NumChans++; aerrno = AESUCCESS; return(ChanS_NEW); } /* CHAN_REM FUNCTION - JONAS (30.07.2001) */ void chan_rem(struct Conn_Struct *ConnS, struct Chan_Struct *ChanS) { CHAN_HASHREGS Hash = 0; struct Chan_Struct *ChanH = NULL; assert(ConnS != NULL); assert(ChanS != NULL); if (ChanS->Prev == NULL) { ConnS->Chan_Head = ChanS->Next; } else { ChanS->Prev->Next = ChanS->Next; } if (ChanS->Next == NULL) { ConnS->Chan_Tail = ChanS->Prev; } else { ChanS->Next->Prev = ChanS->Prev; } Hash = chan_strhash(ChanS->Chan); for (ChanH = ConnS->Chan_Table[Hash] ; ((ChanH != NULL) && (ChanH != ChanS)) ; ChanH = ChanH->NextH); assert(ChanH == ChanS); if (ChanH->PrevH != NULL) { ChanH->PrevH->NextH = ChanH->NextH; } if (ChanH->NextH != NULL) { ChanH->NextH->PrevH = ChanH->PrevH; } if (ConnS->Chan_Table[Hash] == ChanH) { ConnS->Chan_Table[Hash] = ChanH->NextH; } chan_init(ConnS, ChanS); free(ChanS); ConnS->NumChans--; } /* CHAN_GET FUNCTION - JONAS (30.07.2001) */ struct Chan_Struct *chan_get(struct Conn_Struct *ConnS, const char *const ChanPT) { CHAN_HASHREGS Hash = 0; struct Chan_Struct *ChanS = NULL; struct Chan_Struct *ChanH = NULL; assert(ConnS != NULL); assert(ChanPT != NULL); Hash = chan_strhash(ChanPT); for (ChanS = ConnS->Chan_Table[Hash] ; ((ChanS != NULL) && (strcasecmp(ChanPT, ChanS->Chan) != FALSE)) ; ChanS = ChanS->NextH); if (ChanS == NULL) { aerrno = AENOMATCH; return(NULL); } if (ChanS != ConnS->Chan_Table[Hash]) { if (ChanS->PrevH != NULL) { ChanS->PrevH->NextH = ChanS->NextH; } if (ChanS->NextH != NULL) { ChanS->NextH->PrevH = ChanS->PrevH; } ChanH = ConnS->Chan_Table[Hash]; ChanH->PrevH = ChanS; ChanS->PrevH = NULL; ChanS->NextH = ChanH; ConnS->Chan_Table[Hash] = ChanS; } aerrno = AESUCCESS; return(ChanS); } /* CHAN_HASH_INIT FUNCTION - JONAS (26.07.2001) */ void chan_hash_init(void) { signed short int Index1 = 0; signed short int Index2 = 0; unsigned long Count1 = 0; unsigned long Count2 = 0; for (Index1 = CHAR_MIN ; Index1 <= CHAR_MAX ; Index1++) { Chan_Hash_Weight(Index1) = (CHAN_HASHMEMS) (CHAN_HASHSTEP * ((char) Index1)); } for (Index1 = CHAR_MIN ; Index1 <= CHAR_MAX ; Index1++) { for (Index2 = CHAR_MIN ; Index2 < Index1 ; Index2++) { if (HASHEQ(Index1, Index2)) { Chan_Hash_Weight(Index1) = Chan_Hash_Weight(Index2); } } } for (Count1 = 0 ; Count1 < (unsigned long) CHAN_HASHMAPSIZE ; Count1++) { Count2 = Count1; Count2 *= (unsigned long) CHAN_HASHSHIFT; Count2 %= (unsigned long) CHAN_HASHSIZE; Chan_Hash_Map[Count1] = (CHAN_HASHMEMS) Count2; } } /* CHAN_STRHASH FUNCTION - JONAS (26.07.2001) */ static CHAN_HASHREGS chan_strhash(const char *ChanPT) { CHAN_HASHREGS Hash = Chan_Hash_Weight(*ChanPT); ChanPT++; while (*ChanPT != '\0') { Hash = Chan_Hash_Map[Hash] + Chan_Hash_Weight(*ChanPT); ChanPT++; } return(Chan_Hash_Map[Hash]); } /* CHAN_INIT FUNCTION - JONAS (30.06.2001) */ void chan_init(struct Conn_Struct *ConnS, struct Chan_Struct *ChanS) { assert(ConnS != NULL); assert(ChanS != NULL); chan_destroyusers(ConnS, ChanS); chan_destroysentmodes(ConnS, ChanS); chan_destroymodes(ConnS, ChanS); FREE(ChanS->Chan); } /* CHAN_DESTROY FUNCTION - JONAS (30.07.2001) */ void chan_destroy(struct Conn_Struct *ConnS) { assert(ConnS != NULL); while (ConnS->Chan_Head != NULL) { chan_rem(ConnS, ConnS->Chan_Head); } assert(ConnS->NumChans == 0); }