/* Prototypes and external variable declarations.
 *
 * 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 EXTERN_H
#define EXTERN_H


#define E extern	/* This is used in other files as well */


/**** actions.c ****/

E int actions_init(int ac, char **av);
E int bad_password(const char *service, User *u, const char *what);
E void clear_channel(const char *source, Channel *chan, int what,
		     const void *param);
E void kill_user(const char *source, const char *user, const char *reason);
E void set_topic(Channel *c, const char *topic, const char *setter,
		 time_t time);
E void set_cmode(const char *sender, Channel *channel, ...);


/**** channels.c ****/

E Channel *get_channel(const char *chan);
E Channel *first_channel(void);
E Channel *next_channel(void);

E int channel_init(int ac, char **av);
E void get_channel_stats(long *nrec, long *memuse);

E Channel *chan_adduser(User *user, const char *chan, int32 modes);
E void chan_deluser(User *user, Channel *c);
E int chan_has_ban(const char *chan, const char *ban);

E void do_cmode(const char *source, int ac, char **av);
E void do_topic(const char *source, int ac, char **av);


/**** compat.c ****/

#if !HAVE_HSTRERROR
# undef hstrerror
E const char *hstrerror(int h_errnum);
#endif
#if !HAVE_SNPRINTF
# if BAD_SNPRINTF
#  define snprintf my_snprintf
# endif
# define vsnprintf my_vsnprintf
E int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
E int snprintf(char *buf, size_t size, const char *fmt, ...);
#endif
#if !HAVE_STRTOK
# undef strtok
E char *strtok(char *str, const char *delim);
#endif
#if !HAVE_STRICMP && !HAVE_STRCASECMP
# undef stricmp
# undef strnicmp
E int stricmp(const char *s1, const char *s2);
E int strnicmp(const char *s1, const char *s2, size_t len);
#endif
#if !HAVE_STRDUP
# undef strdup
E char *strdup(const char *s);
#endif
#if !HAVE_STRSPN
# undef strspn
# undef strcspn
E size_t strspn(const char *s, const char *accept);
E size_t strcspn(const char *s, const char *reject);
#endif
#if !HAVE_STRERROR
# undef strerror
E char *strerror(int errnum);
#endif
#if !HAVE_STRSIGNAL
# undef strsignal
E char *strsignal(int signum);
#endif


/**** init.c ****/

E char **LoadModules;
E int    LoadModules_count;

E char * RemoteServer;
E int32  RemotePort;
E char * RemotePassword;
E char * LocalHost;
E int32  LocalPort;

E char * ServerName;
E char * ServerDesc;
E char * ServiceUser;
E char * ServiceHost;

E char * LogFilename;
E char * PIDFilename;
E char * MOTDFilename;
E char * LockFilename;

E int16  DefTimeZone;

E int    NoBouncyModes;
E int    NoSplitRecovery;
E int    StrictPasswords;
E int32  BadPassLimit;
E time_t BadPassTimeout;
E int32  BadPassWarning;
E time_t UpdateTimeout;
E time_t ExpireTimeout;
E time_t WarningTimeout;
E int32  ReadTimeout;
E int32  TimeoutCheck;
E time_t PingFrequency;
E int32  MergeChannelModes;
E int32  TotalNetBufferSize;
E int32  NetBufferSize;
E int32  NetBufferLimitInactive;
E int32  NetBufferLimitIgnore;

E char * GuestNickPrefix;
E int    LogMaxUsers;
E int    EnableGetpass;
E int    WallGetpass;
E int    WallSetpass;

E int introduce_user(const char *user);
E int init(int ac, char **av);
E int reconfigure(void);


/**** log.c ****/

E int open_log(void);
E void close_log(void);
E int reopen_log(void);
E int log_is_open(void);
E void log(const char *fmt, ...)		FORMAT(printf,1,2);
E void log_perror(const char *fmt, ...)		FORMAT(printf,1,2);
E void _module_log(const char *modname, const char *fmt, ...)
						FORMAT(printf,2,3);
E void _module_log_perror(const char *modname, const char *fmt, ...)
						FORMAT(printf,2,3);
E void fatal(const char *fmt, ...)		FORMAT(printf,1,2);
E void fatal_perror(const char *fmt, ...)	FORMAT(printf,1,2);

#define module_log(fmt,rest...) \
    _module_log(MODULE_NAME,fmt , ## rest )
#define module_log_perror(fmt,rest...) \
    _module_log_perror(MODULE_NAME,fmt , ## rest )


/**** main.c ****/

E char * services_dir;
E int    debug;
E int    readonly;
E int    nofork;
E int	 noexpire;
E int	 noakill;
E int    forceload;

E int    quitting;
E int    delayed_quit;
E char * quitmsg;
E char   inbuf[BUFSIZE];
E Socket *servsock;
E int    save_data;
E time_t start_time;
E int    openlog_failed, openlog_errno;
E int    cb_expire;
E int    cb_save_data;

E void connect_callback(Socket *s, void *param_unused);
E void disconnect_callback(Socket *s, void *param);
E void readfirstline_callback(Socket *s, void *param_unused);
E void readline_callback(Socket *s, void *param_unused);


/**** misc.c ****/

E unsigned char irc_lowertable[256];
E unsigned char irc_tolower(char c);
E int irc_stricmp(const char *s1, const char *s2);
E int irc_strnicmp(const char *s1, const char *s2, int max);
E char *strscpy(char *d, const char *s, size_t len);
E char *stristr(char *s1, char *s2);
E char *strupper(char *s);
E char *strlower(char *s);
E char *strnrepl(char *s, int32 size, const char *old, const char *new);
E char *strtok_remaining(void);

E char *merge_args(int argc, char **argv);

E int match_wild(const char *pattern, const char *str);
E int match_wild_nocase(const char *pattern, const char *str);

E unsigned char valid_nick_table[256];
E unsigned char valid_chan_table[256];
E int valid_nick(const unsigned char *str);
E int valid_chan(const unsigned char *str);
E int valid_domain(const char *str);
E int valid_email(const char *str);
E int valid_url(const char *str);

typedef int (*range_callback_t)(User *u, int num, va_list args);
E int process_numlist(const char *numstr, int *count_ret,
		range_callback_t callback, User *u, ...);

E uint32 time_msec(void);
E time_t strtotime(const char *str, char **endptr);
E int dotime(const char *s);

E uint8 *pack_ip(const char *ipaddr);
E char *unpack_ip(const uint8 *ip);

E int lock_data(void);
E int unlock_data(void);


/**** process.c ****/

E int split_buf(char *buf, char ***argv, int colon_special);
E int process_init(int ac, char **av);
E void process(void);


/**** send.c ****/

E time_t last_send;
E char *pseudoclient_modes;
E char *enforcer_modes;

/* Protocol information (set by protocol module): */
E const char *protocol_name;
E const char *protocol_version;
E uint32 protocol_features;
E int protocol_nickmax;

E int send_init(int ac, char **av);

E void send_cmd(const char *source, const char *fmt, ...)
	FORMAT(printf,2,3);
E void vsend_cmd(const char *source, const char *fmt, va_list args)
	FORMAT(printf,2,0);
E void send_error(const char *fmt, ...) FORMAT(printf,1,2);
E void notice(const char *source, const char *dest, const char *fmt, ...)
	FORMAT(printf,3,4);
E void notice_list(const char *source, const char *dest, const char **text);
E void notice_lang(const char *source, const User *dest, int message, ...);
E void notice_help(const char *source, const User *dest, int message, ...);
E void privmsg(const char *source, const char *dest, const char *fmt, ...)
	FORMAT(printf,3,4);

E_FUNCPTR(void, send_nick, (const char *nick, const char *user,
			    const char *host, const char *server,
			    const char *name, const char *modes));
E_FUNCPTR(void, send_nickchange, (const char *nick, const char *newnick));
E_FUNCPTR(void, send_namechange, (const char *nick, const char *newname));
E_FUNCPTR(void, send_server, (void));
E_FUNCPTR(void, send_server_remote, (const char *server, const char *reason));
E_FUNCPTR(void, wallops, (const char *source, const char *fmt, ...)
			 FORMAT(printf,2,3));
E_FUNCPTR(void, notice_all, (const char *source, const char *fmt, ...)
			    FORMAT(printf,2,3));
E_FUNCPTR(void, send_channel_cmd, (const char *source, const char *fmt, ...)
				  FORMAT(printf,2,3));
E_FUNCPTR(void, send_nickchange_remote,
		(const char *nick, const char *newnick));


/**** servers.c ****/

E Server *get_server(const char *servername);
E Server *first_server(void);
E Server *next_server(void);

E int server_init(int ac, char **av);
E void get_server_stats(long *nservers, long *memuse);
E void do_server(const char *source, int ac, char **av);
E void do_squit(const char *source, int ac, char **av);


/**** signals.c ****/

E void init_signals(void);
E void do_sigsetjmp(sigjmp_buf *bufptr);
E void enable_signals(void);
E void disable_signals(void);


/**** users.c ****/

E int32 usercnt, opcnt, maxusercnt;
E time_t maxusertime;

E User *get_user(const char *nick);
E User *first_user(void);
E User *next_user(void);

E void quit_user(User *user, const char *quitmsg, int is_kill);
E int user_init(int ac, char **av);
E void get_user_stats(long *nusers, long *memuse);

E int do_nick(const char *source, int ac, char **av);
E void do_join(const char *source, int ac, char **av);
E void do_part(const char *source, int ac, char **av);
E void do_kick(const char *source, int ac, char **av);
E void do_umode(const char *source, int ac, char **av);
E void do_quit(const char *source, int ac, char **av);
E void do_kill(const char *source, int ac, char **av);

E Channel *join_channel(User *user, const char *channel, int32 modes);
E int part_channel(User *user, const char *channel, int callback,
		   const char *param);
E void part_all_channels(User *user);

E int is_oper(const User *user);
E Channel *is_on_chan(const User *user, const char *chan);
E int is_chanop(const User *user, const char *chan);
E int is_voiced(const User *user, const char *chan);

E int match_usermask(const char *mask, const User *user);
E void split_usermask(const char *mask, char **nick, char **user, char **host);
E char *create_mask(User *u, int use_fakehost);

E char *make_guest_nick(void);
E int is_guest_nick(const char *nick);



#endif	/* EXTERN_H */
