#define _ARISA_FUNCTIONS_H

/* Begin: src/access.c */
int	access_check(access_t *acc, network_t *net, const char *host, 
				const char *hostmask, const char *nick);
int	access_check_channel(access_t *acc, network_t *net, channel_t *chan);
int	access_add_entry(access_t *acc, int flags, network_t *net,
				const char *host, channel_t *chan, int mode);
void	access_copy(access_t *dst, access_t *src);
int	access_del_entry(access_t *acc, access_entry_t *ent);
int	access_del_entry_no(access_t *acc, int no);
void	access_purge_channel(channel_t *chan);
void	access_purge_network(network_t *net);
void	access_verify_entries(access_t *acc);
/* End: src/access.c */

/* Begin: src/admin.c */
void	admin_begin(int sok, chat_t *chat);
void	admin_open(int sok, network_t *net, const char *host,
				const char *nick, user_t *user);
void	admin_purge(const time_t now);
void 	admin_nick_change(network_t *net, const char *onick, 
				const char *nnick);
int	admin_socket_open(const char *path);
int	admin_socket_poll(int sok, long sec, long usec);
void	admin_socket_close(const char *path, int sok);
int	admin_valid(chat_t *ac);
/* End: src/admin.c */

/* Begin: src/alloc.c */
inline void	*xalloc(size_t size);
inline void	*xalloc_zero(size_t size);
inline void	*xreloc(void *ptr, size_t size);
inline void	xfree(void *ptr);
inline char	*xstrdup(const char *s);
settings_t	*alloc_settings(void);
void		free_settings(settings_t *s);
netset_t	*alloc_netset(void);
void		free_netset(netset_t *n);
global_t	*alloc_global(void);
void		free_global(global_t *g);
netinfo_t	*alloc_netinfo(void);
void		free_netinfo(netinfo_t *n);
network_t	*alloc_network(netset_t *master_settings);
void		free_network(network_t *n);
channel_t	*alloc_channel(void);
void		free_channel(channel_t *c);
send_t		*alloc_send(void);
void		free_send(send_t *s);
interface_t	*alloc_interface(const interfacetype_t type);
void		free_interface(interface_t *i);
pool_t		*alloc_pool(void);
void		free_pool(pool_t *p);
queue_t		*alloc_queue(void);
void		free_queue(queue_t *q);
packlist_t	*alloc_packlist(void);
void		free_packlist(packlist_t *p);
pack_t		*alloc_pack(void);
void		free_pack(pack_t *p);
void		free_pack_real(pack_t *p);
chat_t		*alloc_chat(chattype_t type);
void		free_chat(chat_t *c);
help_t		*alloc_help(void);
void		free_help(help_t *h);
interpreter_t 	*alloc_interpreter(void);
void		free_interpreter(interpreter_t *i);
access_entry_t	*alloc_access_entry(void);
void		free_access_entry(access_entry_t *ent);
access_t	*alloc_access(void);
void		free_access(access_t *a);
/* End: src/alloc.c */

/* Begin: src/arisa.c */
void	arisa_signal_end(void);
/* End: src/arisa.c */

/* Begin: src/chat.c */
int	chat_list_cmd(chat_t *chat, char *buffer);
int	chat_list_open(network_t *net, const char *host, const char *hostmask,
				const char *nick, packlist_t *list);
/* End: src/chat.c */

/* Begin: src/dcc.c */
int	dcc_safe_fn(char *fn);
send_t	*dcc_send(network_t *net, const char *host, const char *hostmask,
				const char *nick, const char *cmd);
void	dcc_resume(network_t *net, const char *host, const char *nick,
				const char *cmd);
void	dcc_accept(network_t *net, const char *host, const char *nick,
				const char *cmd);
void	dcc_recv(network_t *net, const char *host, const char *nick, 
				const char *cmd);
void	dcc_cmd(network_t *net, const char *host, const char *hostmask,
				const char *nick, const char *cmd);
/* End: src/dcc.c */

/* Begin: src/dcc-eng.c */
void	*interface_thread(void *interface_ptr);
/* End: src/dcc-eng.c */

/* Begin: src/hashing.c */
void	strtomd5(char *md5, size_t md5len, char *str);
int	hash_request(pack_t *p);
void	*hash_thread(void *arg);
/* End: src/hashing.c */

/* Begin: src/ignore.c */
ignore_entry_t	*alloc_ignore_entry(void);
void		free_ignore_entry(ignore_entry_t *ent);
ignore_list_t	*alloc_ignore_list(void);
void		free_ignore_list(ignore_list_t *l);
int		ignore_test(ignore_list_t *l, const char *hostmask);
int		ignore_add(ignore_list_t *l, const char *hostmask, 
			int flags, time_t expires);
int		ignore_del(ignore_list_t *l, int pos, const char *hostmask);
void		ignore_wipe(ignore_list_t *l);
/* End: src/ignore.c */

/* Begin: src/interface.c */
int		interface_start(interface_t *in);	// needs locks
int		interface_add(interface_t *in);
interface_t	*interface_find(const char *name);
int		interface_del(interface_t *in);
void		interface_purge(const time_t now);
void 		interface_nick_change(interface_t *in, network_t *net,
					const char *onick, const char *nnick);
int 		interface_rename(interface_t *in, const char *name);
int 		interface_set_default(interface_t *in);
int 		interface_valid(interface_t *in);
int 		interface_chat_close(interface_t *in, const char *hostmask,
					network_t *net, const char *nick,
					chat_t *ptr, const char *reason);
int 		interface_upload_close(interface_t *in, const char *hostmask,
					network_t *net, const char *nick, 
					const char *file, send_t *ptr,
					const char *reason);
int 		interface_reset_counters(interface_t *in);
int		interface_apply_setting(interface_t *i,
					const char *name, const char *value);
int		interface_read_settings(interface_t *i, pqueue_t *out);
/* End: src/interface.c */

/* Begin: src/irc.c */
void		*irc_thread(void *arg);
int		irc_network_add(network_t *n);
int		irc_network_run(network_t *n);
thread_t	*irc_network_stop(network_t *n);
int		irc_network_del(network_t *n);
network_t	*irc_network_find(const char *name);
void		irc_networks_purge(const time_t now);
int		irc_channel_add(network_t *n, channel_t *c);
int		irc_channel_del(network_t *n, channel_t *c);
channel_t	*irc_channel_find(network_t *n, const char *name);
int		irc_send_raw(network_t *n, const char *msg);
int		irc_send_msg(network_t *n, const char *nick,
					const char *msg);
int		irc_send_notice(network_t *n, const char *nick,
					const char *msg);
int		irc_send_ctcp_msg(network_t *n, const char *nick,
					const char *msg);
int		irc_send_ctcp_notice(network_t *n, const char *nick,
					const char *msg);
int		irc_tolower(int c);
int		irc_strcasecmp(const char *s1, const char *s2);
int		irc_hostmask_match(const char *host, const char *mask);
void		irc_strip_colours(char *buffer);
int		irc_listen(network_t *n, channel_t *c, pqueue_t *msgq);
int		irc_unlisten(network_t *n, channel_t *c, pqueue_t *msgq);
int		irc_network_valid(network_t *n);
int		irc_network_rename(network_t *n, const char *name);
int		irc_channel_valid(network_t *n, channel_t *c);
int		irc_channel_rename(network_t *n, channel_t *c, 
					const char *name);
int		netset_apply(netset_t *ns, const char *name, 
					const char *value);
int		netset_read(netset_t *ns, pqueue_t *out);
int		network_apply_setting(network_t *n, const char *name,
					const char *value);
int		network_read_settings(network_t *n, pqueue_t *out);
int		channel_apply_setting(channel_t *c, const char *name,
					const char *value);
int		channel_read_settings(channel_t *c, pqueue_t *out);
/* End: src/irc.c */

/* Begin: src/loadsave.c */
global_t	*load_global(const char *filename, int sends);
int		save_global(global_t *gptr);
/* End: src/loadsave.c */

/* Begin: src/log.c */
void		arisa_log(const char *format, ...);
const char 	*log_title(void);
void		log_set_title(const char *fmt, ...);
void		log_subscribe(pqueue_t *q);
void		log_unsubscribe(pqueue_t *q);
//FILE		*log_open(const char *filename);
//void		log_close(FILE *fh);
//void		log_flush(pqueue_t *logq);
void		*log_thread(void *arg);
/* End: src/log.c */

/* Begin: src/pack.c */
int		packlist_add(packlist_t *p);
void		packlist_purge(const time_t now);
int		packlist_del(packlist_t *p);
packlist_t	*packlist_find(const char *name);
pack_t		*pack_clone(pack_t *p);
void 		packlist_sort(packlist_t *l, int type);
//int		pack_add(packlist_t *l, pack_t *p);
int		pack_add_file(packlist_t *l, const char *file, 
					const char *label, void *edata,
					pack_t **ret);
int		pack_del(packlist_t *l, pack_t *p);
void		packlist_check(packlist_t *l);
void		packlist_scan(packlist_t *l, int scan_depth);
void		packlists_scan(const time_t now);
int		packlist_check_access(packlist_t *l, network_t *net,
					const char *host, const char *hostmask,
					const char *nick);
int		packlist_check_access_channel(packlist_t *l, network_t *net,
					channel_t *chan);
long		savgspeed(pool_t *p);
void		packlist_xdl_head(packlist_t *l, pqueue_t *q,
					colourtype_t colour,
					const char *prefix,
					const char *postfix,
					int addtail);
void		packlist_xdl_body(packlist_t *l, pqueue_t *q,
					colourtype_t colour,
					const char *prefix,
					const char *postfix);
void		packlist_xdl_tail(packlist_t *l, pqueue_t *q,
					colourtype_t colour,
					network_t *net, channel_t *chan,
					const char *prefix,
					const char *postfix);
int		pack_ref(pack_t *p);
int		pack_deref(pack_t *p);
int		packlist_valid(packlist_t *l);
int		pack_valid(packlist_t *l, pack_t *p);
int		packlist_rename(packlist_t *l, const char *name);
void		packlist_plist_generate(packlist_t *l, pqueue_t *pq,
					pformat_t pformat, 
					colourtype_t colour_type,
					network_t *net, channel_t *chan,
					const char *prefix, 
					const char *postfix);
void		packlist_xdl_generate(packlist_t *l, pqueue_t *pq,
					listtype_t type, 
					colourtype_t colour_type,
					network_t *net, channel_t *chan,
					const char *prefix, 
					const char *postfix);
int		packlist_apply_setting(packlist_t *p, const char *name, 
					const char *value);
int		packlist_read_settings(packlist_t *p, pqueue_t *out);
/* End: src/pack.c */

/* Begin: src/pool.c */
int	pool_add(interface_t *interface, pool_t *p);
void	pool_purge(interface_t *interface, const time_t now);
int	pool_del(interface_t *interface, pool_t *p);
pool_t	*pool_find(interface_t *interface, const char *name);
int	pool_add_send(pool_t *p, send_t *s, int flags, char **err);
//int	pool_close_send_no(pool_t *p, const int no);
void	pool_purge_sends(pool_t *p);
int 	send_matchs(send_t *s, const char *host, 
				network_t *net, const char *nick, 
				const char *file, const char *label);
void	pool_nick_change(pool_t *p, network_t *net, const char *onick, 
				const char *nnick);
int	pool_rename(interface_t *in, pool_t *p, const char *name);
int	pool_valid(interface_t *in, pool_t *p);
int	pool_send_close(pool_t *p, const char *hostmask, network_t *net, 
				const char *nick, const char *file, 
				send_t *ptr, const char *reason);
int	pool_reset_counters(pool_t *p);
int	pool_apply_setting(pool_t *p, const char *name, const char *value);
int	pool_read_settings(pool_t *p, pqueue_t *out);
/* End: src/pool.c */

/* Begin: src/queue.c */
int	queue_add(queue_t *q);
void	queue_purge(const time_t now);
int	queue_del(queue_t *q);
queue_t	*queue_find(const char *name);
int	queue_valid(queue_t *q);
int	queue_rename(queue_t *q, const char *name);
int	queue_enqueue(queue_t *q, send_t *s, int flags, char **err);
send_t	*queue_dequeue(pool_t *to_pool);
int	queue_remove_no(queue_t *q, const int no);
int	queue_remove(queue_t *q, const char *hostmask, network_t *net, 
				const char *nick, const char *file,
				const char *label, send_t *ptr);
int	queue_check_users(queue_t *q);
int	queue_notify_users(queue_t *q);
void	queue_notify(const time_t now);
void	queue_nick_change(queue_t *q, network_t *net,
				const char *onick, const char *nnick);
int 	queue_requeue(send_t *s);
int	queue_send_move(queue_t *q, int from_pos, int to_pos);
int	queue_send_swap(queue_t *q, int pos1, int pos2);
int	queue_send_force_no(queue_t *q, const int no);
int	queue_send_force(queue_t *q, const char *hostmask, network_t *net, 
				const char *nick, const char *file, 
				const char *label, send_t *ptr);
int	queue_set_pool(queue_t *q, pool_t *p);
int	queue_apply_setting(queue_t *q, const char *name, const char *value);
int	queue_read_settings(queue_t *q, pqueue_t *out);
/* End: src/queue.c */

/* Begin: src/script-eng.c */
void	se_global_start(void);
void	se_global_shutdown(pqueue_t *threads);
int	se_load_script(const char *script);
int 	se_reload_script(const char *script);
int	se_unload_script(const char *script);
int     se_ui_call(interpreter_t *intp, void *data);

#if defined(USE_PERL) || defined(_ARISA_SCRIPT_ENG_C)

void	se_irc_msg(network_t *network, char **data, int no_data);
void	se_notify_send(int dolock, interface_t *intf, send_t *s, int err);
void	se_notify_recv(int dolock, interface_t *intf, send_t *s, int err);
void	se_notify_enqueue(int dolock, queue_t *queue, send_t *s, int pos);
void	se_notify_dequeue(int dolock, queue_t *queue, send_t *s);
void	se_notify_pack_add(int dolock, packlist_t *list, pack_t *pack);
void	se_notify_pack_del(int dolock, packlist_t *list, pack_t *pack);
void	se_notify_pack_hashed(int dolock, pack_t *pack);
void	se_notify_packlist_add(packlist_t *list);
void	se_signal(int no);
void	se_notify_interface_add(interface_t *intf);
void	se_notify_pool_add(interface_t *intf, pool_t *p);
void	se_notify_queue_add(queue_t *q);
void	se_notify_network_add(network_t *net);
void	se_notify_channel_add(network_t *net, channel_t *chan);
void	se_notify_user_add(user_t *u);
void	se_notify_admin_logon(chat_t *ac, user_t *u);
void	se_notify_admin_logoff(user_t *u);

#else /* defined(USE_PERL) || defined(_ARISA_SCRIPT_ENG_C) */

#ifndef _NOP
#define _NOP do { } while (0)
#endif /* !_NOP */

#define se_irc_msg(x,y,z)		_NOP
#define se_notify_send(w,x,y,z)		_NOP
#define se_notify_recv(w,x,y,z) 	_NOP
#define se_notify_enqueue(w,x,y,z) 	_NOP
#define se_notify_dequeue(x,y,z)	_NOP
#define se_notify_pack_add(x,y,z)	_NOP
#define se_notify_pack_del(x,y,z)	_NOP
#define se_notify_pack_hashed(x,y)	_NOP
#define se_notify_packlist_add(x)	_NOP
#define se_signal(x)			_NOP
#define se_notify_interface_add(x)	_NOP
#define se_notify_pool_add(x,y)		_NOP
#define se_notify_queue_add(x)		_NOP
#define se_notify_network_add(x)	_NOP
#define se_notify_channel_add(x,y)	_NOP
#define se_notify_user_add(x)		_NOP
#define se_notify_admin_logon(x,y)	_NOP
#define se_notify_admin_logoff(x)	_NOP

#endif /* defined(USE_PERL) || defined(_ARISA_SCRIPT_ENG_C) */
/* End: src/script-eng.c */

/* Begin: src/settings.c */
int	global_apply_setting(const char *name, const char *value);
int	global_read_settings(pqueue_t *out);
/* End: src/settings.c */

/* Begin: src/tests.c */
void	testsuite(int argc, char *argv[]);
/* End: src/tests.c */

/* Begin: src/user.c */
user_t	*alloc_user(const char *username);
void	free_user(user_t *u);
int	user_add(user_t *u);
user_t	*user_find(const char *name);
int	user_del(user_t *u);
void	user_purge(const time_t now);
int	user_set_password(user_t *u, const char *password);
int	user_check_password(user_t *u, const char *password);
int	user_valid(user_t *u);
int	user_rename(user_t *u, const char *name);
int	user_apply_setting(user_t *u, const char *name, const char *value);
int	user_read_settings(user_t *u, pqueue_t *out);
/* End: src/user.c */

/* Begin: src/util.c */
inline time_t	xtime(void);
inline char	*xstrncpy(char *dst, const char *src, size_t n);
size_t 		xstrncpy_rpl(char *dst, const char *src, size_t len,
					const char *pattern, 
					const char *replace);
inline int	IMAX(int a, int b);
inline int	IMIN(int a, int b);
char		*readline_term(FILE *fp, char *buffer, size_t size);
char		*readline_file_nt(FILE *fp, char *buffer, size_t size, 
					size_t *ret_size);
char		*readline_file(FILE *fp, char *buffer, size_t size);
void		trim(char *str);
char		*readtline_term(FILE *fp, char *buffer, size_t size);
char		*readtline_file(FILE *fp, char *buffer, size_t size);
void		splitline(char *part1, char **part2);
int		lrand(int limit);
void		ptrarr_add(void ***arr, int *no_elem, void *ptr);
void		ptrarr_del(void ***arr, int *no_elem, void *ptr);
void		*ptrarr_dup(void **arr, int no_elem, int *ret_no_elem);
void		ptrarr_alloc(void ***arr, int *no_elem, int size);
//void		ptrarr_reduce(void ***arr, int *no_elem, int hint);
int		ptrarr_swap(void ***arr, int *no_elem, int elem1, int elem2);
int		ptrarr_move(void ***arr, int *no_elem, int from_pos, 
					int to_pos);
char		**strarr_dup(char **in, int no_in, int *no_out);
void		strarr_free(char ***arr, int *no_arr);
void		pathtofn(const char *path, char *fn, const size_t fn_len);
char		**split_opt(char *input, char *output, int *no_opt);
size_t		colourise(colourtype_t colour, char *buffer, int bufsize,
					const char *data);
size_t		quote_colours(char *buffer, size_t bufsize, const char *data);
char 		*lstrerror_r(int errnum, char *buffer, size_t bufsize);
char		*lctime_r(const time_t *timep, char *buf, size_t bufsize);
char		*timestr(time_t time, char *str, size_t strsize);
char		*etimestr(time_t sec, char *str, size_t strsize);
char		*clean_ds_path(const char *path, char *buffer, size_t bufsize);
char		*format_bytes(char *buffer, size_t bufsize,
					unsigned long long bytes, 
					int multiplier);
int 		diff_tv_usec(struct timeval *ti, struct timeval *tj);
inline int	nextspace(char *str, int pos);
inline int	nextchar(char *str, int pos);
int		max_sokbuf(int r1s0);
int		wild_match_cf(const char *str, const char *mask, 
					int (*tl)(int));
int		wild_match(const char *str, const char *mask);
void		antispin_init(antispin_t *as);
void		antispin_test_and_sleep(antispin_t *as, unsigned int max_loop);
char		*three_digit_size(char *buffer, off_t size);
off_t		expand_text_size(const char *str, int si);
int		test_timer(time_t now, time_t last, uint32_t interval);
int		test_update_timer(time_t now, time_t *last, uint32_t interval);
/* End: src/util.c */

/* Begin: src/xdcc.c */
void	xdcc_info(network_t *net, channel_t *chan, const char *host,
				const char *hostmask, const char *nick);
char	**xdcc_info_msgs(char **names, int no_names, int *no_ret,
				const char *info);
void	xdcc_remove(network_t *net, const char *nick, const char *label);
void	xdcc_list(network_t *net, packlist_t *list, const char *host,
				const char *hostmask, const char *nick);
void	xdcc_send(network_t *net, packlist_t *list, const char * host,
				const char *hostmask, const char *nick, 
				const char *pack);
void	xdcc_query(network_t *net, packlist_t *list, const char *host,
				const char *hostmask, const char *nick);
void	xdcc_admin(network_t *net, const char *host, const char *hostmask,
				const char *nick, const char *data);
void	xdcc_cmd(network_t *net, const char *host, const char *hostmask,
				const char *nick, const char *cmd);
/* End: src/xdcc.c */
