/* ChanServ-related structures.
 *
 * IRC Services is copyright (c) 1996-2002 Andrew Church.
 *     E-mail: <achurch@achurch.org>
 * Parts written by Andrew Kempe and others.
 * This program is free but copyrighted software; see the file COPYING for
 * details.
 */

#ifndef CHANSERV_H
#define CHANSERV_H

#ifndef MEMOSERV_H
# include "../memoserv/memoserv.h"
#endif

#ifndef NICKSERV_H
# include "../nickserv/nickserv.h"
#endif

/*************************************************************************/

/* Access levels for users. */
typedef struct {
    uint32 nickgroup;	/* Zero if entry is not in use */
    int16 level;
} ChanAccess;

/* Note that these two levels also serve as exclusive boundaries for valid
 * access levels.  ACCLEV_FOUNDER may be assumed to be strictly greater
 * than any valid access level, and ACCLEV_INVALID may be assumed to be
 * strictly less than any valid access level.
 */
#define ACCLEV_FOUNDER	1000	/* Numeric level indicating founder access */
#define ACCLEV_INVALID	-1000	/* Used in levels[] for disabled settings */

/* Access levels used to represent AOP's, SOP's and VOP's in channel access
 * lists. */

#define ACCLEV_SOP	100
#define ACCLEV_AOP	50
#define ACCLEV_HOP	40
#define ACCLEV_VOP	30

/*************************************************************************/

/* AutoKick data. */
typedef struct {
    char *mask;		/* NULL if not in use */
    char *reason;
    char who[NICKMAX];
    time_t set;
    time_t lastused;
} AutoKick;

/*************************************************************************/

/* Data for a registered channel. */

struct channelinfo_ {
    ChannelInfo *next, *prev;
    int modified;
    int locked;

    char name[CHANMAX];
    uint32 founder;
    uint32 successor;		/* Who gets the channel if founder nick
				 * group is dropped or expires */
    char founderpass[PASSMAX];
    char *desc;
    char *url;
    char *email;

    time_t time_registered;
    time_t last_used;
    char *last_topic;		/* Last topic on the channel */
    char last_topic_setter[NICKMAX];	/* Who set the last topic */
    time_t last_topic_time;	/* When the last topic was set */

    int32 flags;		/* See below */
    SuspendInfo *suspendinfo;	/* Non-NULL iff suspended */

    int16 *levels;		/* Access levels for commands */

    ChanAccess *access;		/* List of authorized users */
    int16 access_count;
    AutoKick *akick;		/* List of users to kickban */
    int16 akick_count;

#ifdef CONVERT_DB
    char *mlock_on, *mlock_off;	/* Strings of mode characters */
#else
    int32 mlock_on, mlock_off;	/* See channel modes below */
#endif
    int32 mlock_limit;		/* 0 if no limit */
    char *mlock_key;		/* NULL if no key */
    char *mlock_link;		/* +L (Unreal) */
    char *mlock_flood;		/* +f (Unreal) */

    char *entry_message;	/* Notice sent on entering channel */

    MemoInfo memos;

    /* Online-only data: */

    struct channel_ *c;		/* Pointer to channel record (if   *
				 *    channel is currently in use) */
    int bad_passwords;		/* # of bad passwords since last good one */
    time_t last_sendpass;	/* Time of last SENDPASS for this channel */
};

/* Retain topic even after last person leaves channel */
#define CI_KEEPTOPIC	0x00000001
/* Don't allow non-authorized users to be opped */
#define CI_SECUREOPS	0x00000002
/* Hide channel from ChanServ LIST command */
#define CI_PRIVATE	0x00000004
/* Topic can only be changed by SET TOPIC */
#define CI_TOPICLOCK	0x00000008
/* Those not allowed ops are kickbanned */
#define CI_RESTRICTED	0x00000010
/* Don't auto-deop anyone */
#define CI_LEAVEOPS	0x00000020
/* Don't allow any privileges unless a user is IDENTIFY'd with NickServ */
#define CI_SECURE	0x00000040
/* Don't allow the channel to be registered or used */
#define CI_VERBOTEN	0x00000080
/* Channel does not expire */
#define CI_NOEXPIRE	0x00000200
/* Channel memo limit may not be changed */
#define CI_MEMO_HARDMAX	0x00000400
/* Send notice to channel on use of OP/DEOP */
#define CI_OPNOTICE	0x00000800
/* Enforce +o, +v modes (don't allow deopping) */
#define CI_ENFORCE	0x00001000
/* Hide E-mail address from INFO */
#define CI_HIDE_EMAIL	0x00002000
/* Hide last topic from INFO */
#define CI_HIDE_TOPIC	0x00004000
/* Hide mode lock from INFO */
#define CI_HIDE_MLOCK	0x00008000

/*************************************************************************/

/* Indices for ci->levels[]: (DO NOT REORDER THESE unless you hack
 * database modules to deal with them) */
#define CA_INVITE	0
#define CA_AKICK	1
#define CA_SET		2	/* but not FOUNDER or PASSWORD */
#define CA_UNBAN	3
#define CA_AUTOOP	4
#define CA_AUTODEOP	5	/* Maximum, not minimum */
#define CA_AUTOVOICE	6
#define CA_OPDEOP	7	/* ChanServ commands OP and DEOP */
#define CA_ACCESS_LIST	8
#define CA_CLEAR	9
#define CA_NOJOIN	10	/* Maximum */
#define CA_ACCESS_CHANGE 11
#define CA_MEMO		12
#define CA_VOICE	13	/* VOICE/DEVOICE commands */
#define CA_AUTOHALFOP	14
#define CA_HALFOP	15	/* HALFOP/DEHALFOP commands */
#define CA_AUTOPROTECT	16
#define CA_PROTECT	17
#define CA_AUTOOWNER	18	/* dummy entry for auto +q */
#define CA_KICK		19
#define CA_STATUS	20
#define CA_TOPIC	21

#define CA_SIZE		22

/*************************************************************************/

/* Prototypes for imported/exported variables and functions. */

/* Imports: */

E ChannelInfo *add_channelinfo(ChannelInfo *ci);
E void del_channelinfo(ChannelInfo *ci);
E ChannelInfo *get_channelinfo(const char *chan);
E void put_channelinfo(ChannelInfo *ci);
E ChannelInfo *first_channelinfo(void);
E ChannelInfo *next_channelinfo(void);
E int open_channel_db(const char *dbname);
E int sync_channel_db(const char *dbname);
E int close_channel_db(const char *dbname);

/* Exports: */

E char *s_ChanServ;
E int32 CSMaxReg;

E void free_channelinfo(ChannelInfo *ci);
E int check_expire_channel(ChannelInfo *ci);
E int check_access(User *user, ChannelInfo *ci, int what);
E int check_access_if_idented(User *user, ChannelInfo *ci, int what);
E int check_access_cmd(User *user, ChannelInfo *ci, const char *command,
		       const char *subcommand);
E int check_access_cumode(User *user, ChannelInfo *ci, int32 newmodes,
			  int32 changemask);
E int check_channel_limit(NickGroupInfo *ngi, int *max_ret);
E void reset_levels(ChannelInfo *ci, int set);

/*************************************************************************/

#endif	/* CHANSERV_H */
