/*
* ----------------------------------------------------------------
* Night Light IRC Proxy - Channel
* ----------------------------------------------------------------
* Copyright (C) 1997-2006 Jonas Kvinge <jonas@night-light.net>
* 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);
}
syntax highlighted by Code2HTML, v. 0.9.1