/*
 * ----------------------------------------------------------------
 * Night Light IRC Proxy - Channel Header
 * ----------------------------------------------------------------
 * 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.2006)
 *
 */

#ifdef CHAN_H
#warning "chan.h already included."
#else
#define CHAN_H

struct Conn_Struct;
struct Who_Struct;
struct ChanMode_Struct;

/* CHANNEL BIT MASKS - JONAS (22.07.2001) */

#define CHAN_BITMASK_MODES		1
#define CHAN_BITMASK_TOPIC		2
#define CHAN_BITMASK_NAMES		4
#define CHAN_BITMASK_WHO		8
#define CHAN_BITMASK_BANS		16
#define CHAN_BITMASK_SENTWHO		32
#define CHAN_BITMASK_SENTBANS		64
#define CHAN_BITMASK_SENTTOPIC		128
#define CHAN_BITMASK_SENTPART		256
#define CHAN_BITMASK_FD			512

/* CHANNEL MODE BIT MASKS - JONAS (24.06.2000) */

#define CHAN_BITMASK_ANONYMOUS		1
#define CHAN_BITMASK_INVITEONLY		2
#define CHAN_BITMASK_MODERATED		4
#define CHAN_BITMASK_NOOUTSIDE		8
#define CHAN_BITMASK_QUIET		16
#define CHAN_BITMASK_PRIVATE		32
#define CHAN_BITMASK_SECRET		64
#define CHAN_BITMASK_REOP		128
#define CHAN_BITMASK_ONLYOPTOPIC	256
#define CHAN_BITMASK_KEY		512
#define CHAN_BITMASK_LIMIT		1024

/* CHANNEL MACROS - JONAS (22.07.2001) */

#define Chan_SetModes(x)		((x)->Flags |= CHAN_BITMASK_MODES)
#define Chan_SetTopic(x)		((x)->Flags |= CHAN_BITMASK_TOPIC)
#define Chan_SetNames(x)		((x)->Flags |= CHAN_BITMASK_NAMES)
#define Chan_SetWho(x)			((x)->Flags |= CHAN_BITMASK_WHO)
#define Chan_SetBans(x)			((x)->Flags |= CHAN_BITMASK_BANS)
#define Chan_SetSentWho(x)		((x)->Flags |= CHAN_BITMASK_SENTWHO)
#define Chan_SetSentBans(x)		((x)->Flags |= CHAN_BITMASK_SENTBANS)
#define Chan_SetSentTopic(x)		((x)->Flags |= CHAN_BITMASK_SENTTOPIC)
#define Chan_SetSentPart(x)		((x)->Flags |= CHAN_BITMASK_SENTPART)

#define Chan_ClearModes(x)		((x)->Flags &= ~CHAN_BITMASK_MODES)
#define Chan_ClearTopic(x)		((x)->Flags &= ~CHAN_BITMASK_TOPIC)
#define Chan_ClearNames(x)		((x)->Flags &= ~CHAN_BITMASK_NAMES)
#define Chan_ClearWho(x)		((x)->Flags &= ~CHAN_BITMASK_WHO)
#define Chan_ClearBans(x)		((x)->Flags &= ~CHAN_BITMASK_BANS)
#define Chan_ClearSentWho(x)		((x)->Flags &= ~CHAN_BITMASK_SENTWHO)
#define Chan_ClearSentBans(x)		((x)->Flags &= ~CHAN_BITMASK_SENTBANS)
#define Chan_ClearSentTopic(x)		((x)->Flags &= ~CHAN_BITMASK_SENTTOPIC)
#define Chan_ClearSentPart(x)		((x)->Flags &= ~CHAN_BITMASK_SENTPART)

#define Chan_IsModes(x)			((x)->Flags & CHAN_BITMASK_MODES)
#define Chan_IsTopic(x)			((x)->Flags & CHAN_BITMASK_TOPIC)
#define Chan_IsNames(x)			((x)->Flags & CHAN_BITMASK_NAMES)
#define Chan_IsWho(x)			((x)->Flags & CHAN_BITMASK_WHO)
#define Chan_IsBans(x)			((x)->Flags & CHAN_BITMASK_BANS)
#define Chan_IsSentWho(x)		((x)->Flags & CHAN_BITMASK_SENTWHO)
#define Chan_IsSentBans(x)		((x)->Flags & CHAN_BITMASK_SENTBANS)
#define Chan_IsSentTopic(x)		((x)->Flags & CHAN_BITMASK_SENTTOPIC)
#define Chan_IsSentPart(x)		((x)->Flags & CHAN_BITMASK_SENTPART)

#define Chan_IsSynch(x)			(Chan_IsModes(x) && Chan_IsTopic(x) && Chan_IsNames(x) && Chan_IsWho(x) && Chan_IsBans(x))

/* CHANNEL MODE MACROS - JONAS (24.06.2000) */

#define Chan_SetAnonymous(x)		((x)->ModeFlags |= CHAN_BITMASK_ANONYMOUS)
#define Chan_SetInviteOnly(x)		((x)->ModeFlags |= CHAN_BITMASK_INVITEONLY)
#define Chan_SetModerated(x)		((x)->ModeFlags |= CHAN_BITMASK_MODERATED)
#define Chan_SetNoOutSide(x)		((x)->ModeFlags |= CHAN_BITMASK_NOOUTSIDE)
#define Chan_SetQuiet(x)		((x)->ModeFlags |= CHAN_BITMASK_QUIET)
#define Chan_SetPrivate(x)		((x)->ModeFlags |= CHAN_BITMASK_PRIVATE)
#define Chan_SetSecret(x)		((x)->ModeFlags |= CHAN_BITMASK_SECRET)
#define Chan_SetReOP(x)			((x)->ModeFlags |= CHAN_BITMASK_REOP)
#define Chan_SetOnlyOPTopic(x)		((x)->ModeFlags |= CHAN_BITMASK_ONLYOPTOPIC)
#define Chan_SetKey(x)			((x)->ModeFlags |= CHAN_BITMASK_KEY)
#define Chan_SetLimit(x)		((x)->ModeFlags |= CHAN_BITMASK_LIMIT)

#define Chan_ClearAnonymous(x)		((x)->ModeFlags &= ~CHAN_BITMASK_ANONYMOUS)
#define Chan_ClearInviteOnly(x)		((x)->ModeFlags &= ~CHAN_BITMASK_INVITEONLY)
#define Chan_ClearModerated(x)		((x)->ModeFlags &= ~CHAN_BITMASK_MODERATED)
#define Chan_ClearNoOutSide(x)		((x)->ModeFlags &= ~CHAN_BITMASK_NOOUTSIDE)
#define Chan_ClearQuiet(x)		((x)->ModeFlags &= ~CHAN_BITMASK_QUIET)
#define Chan_ClearPrivate(x)		((x)->ModeFlags &= ~CHAN_BITMASK_PRIVATE)
#define Chan_ClearSecret(x)		((x)->ModeFlags &= ~CHAN_BITMASK_SECRET)
#define Chan_ClearReOP(x)		((x)->ModeFlags &= ~CHAN_BITMASK_REOP)
#define Chan_ClearOnlyOPTopic(x)	((x)->ModeFlags &= ~CHAN_BITMASK_ONLYOPTOPIC)
#define Chan_ClearKey(x)		((x)->ModeFlags &= ~CHAN_BITMASK_KEY)
#define Chan_ClearLimit(x)		((x)->ModeFlags &= ~CHAN_BITMASK_LIMIT)

#define Chan_IsAnonymous(x)		((x)->ModeFlags & CHAN_BITMASK_ANONYMOUS)
#define Chan_IsInviteOnly(x)		((x)->ModeFlags & CHAN_BITMASK_INVITEONLY)
#define Chan_IsModerated(x)		((x)->ModeFlags & CHAN_BITMASK_MODERATED)
#define Chan_IsNoOutSide(x)		((x)->ModeFlags & CHAN_BITMASK_NOOUTSIDE)
#define Chan_IsQuiet(x)			((x)->ModeFlags & CHAN_BITMASK_QUIET)
#define Chan_IsPrivate(x)		((x)->ModeFlags & CHAN_BITMASK_PRIVATE)
#define Chan_IsSecret(x)		((x)->ModeFlags & CHAN_BITMASK_SECRET)
#define Chan_IsReOP(x)			((x)->ModeFlags & CHAN_BITMASK_REOP)
#define Chan_IsOnlyOPTopic(x)		((x)->ModeFlags & CHAN_BITMASK_ONLYOPTOPIC)
#define Chan_IsKey(x)			((x)->ModeFlags & CHAN_BITMASK_KEY)
#define Chan_IsLimit(x)			((x)->ModeFlags & CHAN_BITMASK_LIMIT)

/* STRUCTURES - JONAS (30.07.2001) */

struct Chan_Struct {

  char *Chan;
  struct ChanUser_Struct *Me;

  unsigned long int Flags;
  unsigned long int ModeFlags;

  unsigned short int Users;
  unsigned short int UserWhos;

  time_t CheckSentModesTime;
  time_t FlushModesTime;
  unsigned long int Modes;
  unsigned long int SentModes;

  struct ChanUser_Struct *User_Head;
  struct ChanUser_Struct *User_Tail;
  struct ChanUser_Struct *User_Table[CHANUSER_HASHSIZE];

  struct ChanMode_Struct *Mode_Head;
  struct ChanMode_Struct *Mode_Tail;

  struct ChanSentMode_Struct *SentMode_Head;
  struct ChanSentMode_Struct *SentMode_Tail;

  struct Who_Struct *Who_Head;

  struct Chan_Struct *Prev;
  struct Chan_Struct *Next;

  struct Chan_Struct *PrevH;
  struct Chan_Struct *NextH;

};

struct Who_Struct {

  struct Who_Struct *NextForChan;
  struct Who_Struct *PrevForChan;

  struct Who_Struct *NextForClient;
  struct Who_Struct *PrevForClient;

  struct Client_Struct *ClientS; /* Client that sent this Who command */

};

#ifdef CHAN_C

#ifndef CHAN_HASHSIZE
  #error "CHAN_HASHSIZE not defined!"
#endif

/*
 * HASH TABLE DEFINES - JONAS (30.07.2001)
 *
 * Taken from ircu, www.coder-com.undernet.org
 * Copyright (C) 1998 Andrea Cocito
 *
 */

#define CHAN_HASHSTEP 1
#define CHAN_HASHSHIFT 257

#if !(CHAN_HASHSHIFT > (CHAN_HASHSTEP * (CHAR_MAX-CHAR_MIN)))
  #error "Please make CHAN_HASHSHIFT a bigger prime!"
#endif
#if ((CHAN_HASHSIZE % CHAN_HASHSHIFT) == 0)
  #error "Please set CHAN_HASHSIZE to something not multiple of CHAN_HASHSHIFT"
#endif

#undef CHAN_HASHMEMS
#undef CHAN_HASHREGS

#if ((!defined(CHAN_HASHMEMS)) && (CHAN_HASHSIZE < (SHRT_MAX-CHAN_HASHSHIFT)))
  #define CHAN_HASHMEMS short
  #define CHAN_HASHREGS int
#endif

#if ((!defined(CHAN_HASHMEMS)) && (CHAN_HASHSIZE < (USHRT_MAX-CHAN_HASHSHIFT)))
  #define CHAN_HASHMEMS unsigned short
  #define CHAN_HASHREGS unsigned int
#endif

#if ((!defined(CHAN_HASHMEMS)) && (CHAN_HASHSIZE < (INT_MAX-CHAN_HASHSHIFT)))
  #define CHAN_HASHMEMS int
  #define CHAN_HASHREGS int
#endif

#if ((!defined(CHAN_HASHMEMS)) && (CHAN_HASHSIZE < (UINT_MAX-CHAN_HASHSHIFT)))
  #define CHAN_HASHMEMS unsigned int
  #define CHAN_HASHREGS unsigned int
#endif

#if ((!defined(CHAN_HASHMEMS)) && (CHAN_HASHSIZE < (LONG_MAX-CHAN_HASHSHIFT)))
  #define CHAN_HASHMEMS long
  #define CHAN_HASHREGS long
#endif

#if ((!defined(CHAN_HASHMEMS)) && (CHAN_HASHSIZE < (ULONG_MAX-CHAN_HASHSHIFT)))
  #define CHAN_HASHMEMS unsigned long
  #define CHAN_HASHREGS unsigned long
#endif

#if (!defined(CHAN_HASHMEMS))
  #error "CHAN_HASHSIZE to big."
#endif

#define CHAN_HASHMAPSIZE (CHAN_HASHSIZE + CHAN_HASHSHIFT + 1)

#define Chan_Hash_Weight(ch) Chan_Hash_Weight_Table[ch-CHAR_MIN]
#define HASHEQ(x,y) ((tolower(x)) == (tolower(y)))

#endif

/* FUNCTION PROTOTYPES - JONAS (30.07.2001) */

struct Chan_Struct *chan_add(struct Conn_Struct *ConnS, const char *const ChanPT);
void chan_rem(struct Conn_Struct *ConnS, struct Chan_Struct *ChanS);
struct Chan_Struct *chan_get(struct Conn_Struct *ConnS, const char *const ChanPT);
void chan_hash_init(void);
#ifdef CHAN_C
  static CHAN_HASHREGS chan_strhash(const char *ChanPT);
#endif

void chan_init(struct Conn_Struct *ConnS, struct Chan_Struct *ChanS);
void chan_destroy(struct Conn_Struct *Conn);

#endif


syntax highlighted by Code2HTML, v. 0.9.1