1 /* HexChat
2  * Copyright (C) 1998-2010 Peter Zelezny.
3  * Copyright (C) 2009-2013 Berke Viktor.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 #include "config.h"
21 
22 #include <glib.h>
23 #include <glib/gstdio.h>
24 #include <glib/gi18n.h>
25 #include <gio/gio.h>
26 
27 #include <time.h>			/* need time_t */
28 
29 #ifndef HEXCHAT_H
30 #define HEXCHAT_H
31 
32 #ifdef USE_OPENSSL
33 #ifdef __APPLE__
34 #define __AVAILABILITYMACROS__
35 #define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
36 #endif
37 #endif
38 
39 #include "history.h"
40 #include "tree.h"
41 
42 #ifdef USE_OPENSSL
43 #include <openssl/ssl.h>		  /* SSL_() */
44 #endif
45 
46 #ifdef __EMX__						  /* for o/s 2 */
47 #define OFLAGS O_BINARY
48 #define g_ascii_strcasecmp stricmp
49 #define g_ascii_strncasecmp strnicmp
50 #define PATH_MAX MAXPATHLEN
51 #define FILEPATH_LEN_MAX MAXPATHLEN
52 #endif
53 
54 /* force a 32bit CMP.L */
55 #define WORDL(c0, c1, c2, c3) (guint32)(c0 | (c1 << 8) | (c2 << 16) | (c3 << 24))
56 
57 #ifdef WIN32						/* for win32 */
58 #define OFLAGS O_BINARY
59 #define sleep(t) Sleep(t*1000)
60 #include <direct.h>
61 #define	F_OK	0
62 #define	X_OK	1
63 #define	W_OK	2
64 #define	R_OK	4
65 #ifndef S_ISDIR
66 #define	S_ISDIR(m)	((m) & _S_IFDIR)
67 #endif
68 #define NETWORK_PRIVATE
69 #else									/* for unix */
70 #define OFLAGS 0
71 #endif
72 
73 #define FONTNAMELEN	127
74 #define PATHLEN		255
75 #define DOMAINLEN	100
76 #define NICKLEN		64				/* including the NULL, so 63 really */
77 #define CHANLEN		300
78 #define PDIWORDS	32
79 #define USERNAMELEN 10
80 #define HIDDEN_CHAR	8			/* invisible character for xtext */
81 
82 struct nbexec
83 {
84 	int myfd;
85 	int childpid;
86 	int tochannel;						/* making this int keeps the struct 4-byte aligned */
87 	int iotag;
88 	char *linebuf;
89 	int buffill;
90 	struct session *sess;
91 };
92 
93 struct hexchatprefs
94 {
95 	/* these are the rebranded, consistent, sorted hexchat variables */
96 
97 	/* BOOLEANS */
98 	unsigned int hex_away_auto_unmark;
99 	unsigned int hex_away_omit_alerts;
100 	unsigned int hex_away_show_once;
101 	unsigned int hex_away_track;
102 	unsigned int hex_completion_auto;
103 	unsigned int hex_dcc_auto_chat;
104 	unsigned int hex_dcc_auto_resume;
105 	unsigned int hex_dcc_fast_send;
106 	unsigned int hex_dcc_ip_from_server;
107 	unsigned int hex_dcc_remove;
108 	unsigned int hex_dcc_save_nick;
109 	unsigned int hex_dcc_send_fillspaces;
110 	unsigned int hex_gui_autoopen_chat;
111 	unsigned int hex_gui_autoopen_dialog;
112 	unsigned int hex_gui_autoopen_recv;
113 	unsigned int hex_gui_autoopen_send;
114 	unsigned int hex_gui_compact;
115 	unsigned int hex_gui_filesize_iec;
116 	unsigned int hex_gui_focus_omitalerts;
117 	unsigned int hex_gui_hide_menu;
118 	unsigned int hex_gui_input_attr;
119 	unsigned int hex_gui_input_icon;
120 	unsigned int hex_gui_input_nick;
121 	unsigned int hex_gui_input_spell;
122 	unsigned int hex_gui_input_style;
123 	unsigned int hex_gui_join_dialog;
124 	unsigned int hex_gui_mode_buttons;
125 	unsigned int hex_gui_quit_dialog;
126 	/* unsigned int hex_gui_single; */
127 	unsigned int hex_gui_slist_fav;
128 	unsigned int hex_gui_slist_skip;
129 	unsigned int hex_gui_tab_chans;
130 	unsigned int hex_gui_tab_dialogs;
131 	unsigned int hex_gui_tab_dots;
132 	unsigned int hex_gui_tab_icons;
133 	unsigned int hex_gui_tab_scrollchans;
134 	unsigned int hex_gui_tab_server;
135 	unsigned int hex_gui_tab_sort;
136 	unsigned int hex_gui_tab_utils;
137 	unsigned int hex_gui_topicbar;
138 	unsigned int hex_gui_tray;
139 	unsigned int hex_gui_tray_away;
140 	unsigned int hex_gui_tray_blink;
141 	unsigned int hex_gui_tray_close;
142 	unsigned int hex_gui_tray_minimize;
143 	unsigned int hex_gui_tray_quiet;
144 	unsigned int hex_gui_ulist_buttons;
145 	unsigned int hex_gui_ulist_color;
146 	unsigned int hex_gui_ulist_count;
147 	unsigned int hex_gui_ulist_hide;
148 	unsigned int hex_gui_ulist_icons;
149 	unsigned int hex_gui_ulist_show_hosts;
150 	unsigned int hex_gui_ulist_style;
151 	unsigned int hex_gui_usermenu;
152 	unsigned int hex_gui_win_modes;
153 	unsigned int hex_gui_win_save;
154 	unsigned int hex_gui_win_swap;
155 	unsigned int hex_gui_win_ucount;
156 	unsigned int hex_identd_server;
157 	unsigned int hex_input_balloon_chans;
158 	unsigned int hex_input_balloon_hilight;
159 	unsigned int hex_input_balloon_priv;
160 	unsigned int hex_input_beep_chans;
161 	unsigned int hex_input_beep_hilight;
162 	unsigned int hex_input_beep_priv;
163 	unsigned int hex_input_filter_beep;
164 	unsigned int hex_input_flash_chans;
165 	unsigned int hex_input_flash_hilight;
166 	unsigned int hex_input_flash_priv;
167 	unsigned int hex_input_perc_ascii;
168 	unsigned int hex_input_perc_color;
169 	unsigned int hex_input_tray_chans;
170 	unsigned int hex_input_tray_hilight;
171 	unsigned int hex_input_tray_priv;
172 	unsigned int hex_irc_auto_rejoin;
173 	unsigned int hex_irc_reconnect_rejoin;
174 	unsigned int hex_irc_conf_mode;
175 	unsigned int hex_irc_hidehost;
176 	unsigned int hex_irc_hide_nickchange;
177 	unsigned int hex_irc_hide_version;
178 	unsigned int hex_irc_invisible;
179 	unsigned int hex_irc_logging;
180 	unsigned int hex_irc_raw_modes;
181 	unsigned int hex_irc_servernotice;
182 	unsigned int hex_irc_skip_motd;
183 	unsigned int hex_irc_wallops;
184 	unsigned int hex_irc_who_join;
185 	unsigned int hex_irc_whois_front;
186 	unsigned int hex_irc_cap_server_time;
187 	unsigned int hex_net_auto_reconnect;
188 	unsigned int hex_net_auto_reconnectonfail;
189 	unsigned int hex_net_proxy_auth;
190 	unsigned int hex_net_throttle;
191 	unsigned int hex_notify_whois_online;
192 	unsigned int hex_perl_warnings;
193 	unsigned int hex_stamp_log;
194 	unsigned int hex_stamp_text;
195 	unsigned int hex_text_autocopy_color;
196 	unsigned int hex_text_autocopy_stamp;
197 	unsigned int hex_text_autocopy_text;
198 	unsigned int hex_text_color_nicks;
199 	unsigned int hex_text_indent;
200 	unsigned int hex_text_replay;
201 	unsigned int hex_text_search_case_match;
202 	unsigned int hex_text_search_highlight_all;
203 	unsigned int hex_text_search_follow;
204 	unsigned int hex_text_search_regexp;
205 	unsigned int hex_text_show_marker;
206 	unsigned int hex_text_show_sep;
207 	unsigned int hex_text_stripcolor_msg;
208 	unsigned int hex_text_stripcolor_replay;
209 	unsigned int hex_text_stripcolor_topic;
210 	unsigned int hex_text_thin_sep;
211 	unsigned int hex_text_transparent;
212 	unsigned int hex_text_wordwrap;
213 	unsigned int hex_url_grabber;
214 	unsigned int hex_url_logging;
215 
216 	/* NUMBERS */
217 	int hex_away_size_max;
218 	int hex_away_timeout;
219 	int hex_completion_amount;
220 	int hex_completion_sort;
221 	int hex_dcc_auto_recv;
222 	int hex_dcc_blocksize;
223 	int hex_dcc_global_max_get_cps;
224 	int hex_dcc_global_max_send_cps;
225 	int hex_dcc_max_get_cps;
226 	int hex_dcc_max_send_cps;
227 	int hex_dcc_permissions;
228 	int hex_dcc_port_first;
229 	int hex_dcc_port_last;
230 	int hex_dcc_stall_timeout;
231 	int hex_dcc_timeout;
232 	int hex_flood_ctcp_num;				/* flood */
233 	int hex_flood_ctcp_time;			/* seconds of floods */
234 	int hex_flood_msg_num;				/* same deal */
235 	int hex_flood_msg_time;
236 	int hex_gui_chanlist_maxusers;
237 	int hex_gui_chanlist_minusers;
238 	int hex_gui_dialog_height;
239 	int hex_gui_dialog_left;
240 	int hex_gui_dialog_top;
241 	int hex_gui_dialog_width;
242 	int hex_gui_lagometer;
243 	int hex_gui_lang;
244 	int hex_gui_pane_divider_position;
245 	int hex_gui_pane_left_size;
246 	int hex_gui_pane_right_size;
247 	int hex_gui_pane_right_size_min;
248 	int hex_gui_search_pos;
249 	int hex_gui_slist_select;
250 	int hex_gui_tab_layout;
251 	int hex_gui_tab_middleclose;
252 	int hex_gui_tab_newtofront;
253 	int hex_gui_tab_pos;
254 	int hex_gui_tab_small;
255 	int hex_gui_tab_trunc;
256 	int hex_gui_transparency;
257 	int hex_gui_throttlemeter;
258 	int hex_gui_ulist_pos;
259 	int hex_gui_ulist_sort;
260 	int hex_gui_url_mod;
261 	int hex_gui_win_height;
262 	int hex_gui_win_fullscreen;
263 	int hex_gui_win_left;
264 	int hex_gui_win_state;
265 	int hex_gui_win_top;
266 	int hex_gui_win_width;
267 	int hex_identd_port;
268 	int hex_irc_ban_type;
269 	int hex_irc_join_delay;
270 	int hex_irc_notice_pos;
271 	int hex_net_ping_timeout;
272 	int hex_net_proxy_port;
273 	int hex_net_proxy_type;				/* 0=disabled, 1=wingate 2=socks4, 3=socks5, 4=http */
274 	int hex_net_proxy_use;				/* 0=all 1=IRC_ONLY 2=DCC_ONLY */
275 	int hex_net_reconnect_delay;
276 	int hex_notify_timeout;
277 	int hex_text_max_indent;
278 	int hex_text_max_lines;
279 	int hex_url_grabber_limit;
280 
281 	/* STRINGS */
282 	char hex_away_reason[256];
283 	char hex_completion_suffix[4];		/* Only ever holds a one-character string. */
284 	char hex_dcc_completed_dir[PATHLEN + 1];
285 	char hex_dcc_dir[PATHLEN + 1];
286 	char hex_dcc_ip[DOMAINLEN + 1];
287 	char hex_gui_ulist_doubleclick[256];
288 	char hex_input_command_char[4];
289 	char hex_irc_extra_hilight[300];
290 	char hex_irc_id_ntext[64];
291 	char hex_irc_id_ytext[64];
292 	char hex_irc_logmask[256];
293 	char hex_irc_nick1[NICKLEN];
294 	char hex_irc_nick2[NICKLEN];
295 	char hex_irc_nick3[NICKLEN];
296 	char hex_irc_nick_hilight[300];
297 	char hex_irc_no_hilight[300];
298 	char hex_irc_part_reason[256];
299 	char hex_irc_quit_reason[256];
300 	char hex_irc_real_name[127];
301 	char hex_irc_user_name[127];
302 	char hex_net_bind_host[127];
303 	char hex_net_proxy_host[64];
304 	char hex_net_proxy_pass[256];
305 	char hex_net_proxy_user[256];
306 	char hex_stamp_log_format[64];
307 	char hex_stamp_text_format[64];
308 	char hex_text_background[PATHLEN + 1];
309 	char hex_text_font[4 * FONTNAMELEN + 1];
310 	char hex_text_font_main[FONTNAMELEN + 1];
311 	char hex_text_font_alternative[3 * FONTNAMELEN + 1];
312 	char hex_text_spell_langs[64];
313 
314 	/* these are the private variables */
315 	guint32 local_ip;
316 
317 	unsigned int wait_on_exit;	/* wait for logs to be flushed to disk IF we're connected */
318 
319 	/* Tells us if we need to save, only when they've been edited.
320 		This is so that we continue using internal defaults (which can
321 		change in the next release) until the user edits them. */
322 	unsigned int save_pevents:1;
323 };
324 
325 /* Session types */
326 #define SESS_SERVER	1
327 #define SESS_CHANNEL	2
328 #define SESS_DIALOG	3
329 #define SESS_NOTICES	4
330 #define SESS_SNOTICES	5
331 
332 /* Per-Channel Settings */
333 #define SET_OFF 0
334 #define SET_ON 1
335 #define SET_DEFAULT 2 /* use global setting */
336 
337 /* Priorities in the "interesting sessions" priority queue
338  * (see xchat.c:sess_list_by_lastact) */
339 #define LACT_NONE		-1		/* no queues */
340 #define LACT_QUERY_HI	0		/* query with hilight */
341 #define LACT_QUERY		1		/* query with messages */
342 #define LACT_CHAN_HI	2		/* channel with hilight */
343 #define LACT_CHAN		3		/* channel with messages */
344 #define LACT_CHAN_DATA	4		/* channel with other data */
345 
346 /* Moved from fe-gtk for use in outbound.c as well -- */
347 typedef enum gtk_xtext_search_flags_e {
348 	case_match = 1,
349 	backward = 2,
350 	highlight = 4,
351 	follow = 8,
352 	regexp = 16
353 } gtk_xtext_search_flags;
354 
355 typedef enum {
356 	TAB_STATE_NONE = 0,
357 	TAB_STATE_NEW_DATA = (1 << 0),
358 	TAB_STATE_NEW_MSG = (1 << 1),
359 	TAB_STATE_NEW_HILIGHT = (1 << 2),
360 } tab_state_flags;
361 
362 typedef struct session
363 {
364 	/* Per-Channel Alerts */
365 	/* use a byte, because we need a pointer to each element */
366 	guint8 alert_balloon;
367 	guint8 alert_beep;
368 	guint8 alert_taskbar;
369 	guint8 alert_tray;
370 
371 	/* Per-Channel Settings */
372 	guint8 text_hidejoinpart;
373 	guint8 text_logging;
374 	guint8 text_scrollback;
375 	guint8 text_strip;
376 
377 	struct server *server;
378 	tree *usertree;					/* alphabetical tree */
379 	struct User *me;					/* points to myself in the usertree */
380 	char channel[CHANLEN];
381 	char waitchannel[CHANLEN];		  /* waiting to join channel (/join sent) */
382 	char willjoinchannel[CHANLEN];	  /* will issue /join for this channel */
383 	char session_name[CHANLEN];		 /* the name of the session, should not modified */
384 	char channelkey[64];			  /* XXX correct max length? */
385 	int limit;						  /* channel user limit */
386 	int logfd;
387 
388 	GFile *scrollfile;							/* scrollback file */
389 	int scrollwritten;					/* number of lines written */
390 
391 	char lastnick[NICKLEN];			  /* last nick you /msg'ed */
392 
393 	struct history history;
394 
395 	int ops;								/* num. of ops in channel */
396 	int hops;						  /* num. of half-oped users */
397 	int voices;							/* num. of voiced people */
398 	int total;							/* num. of users in channel */
399 
400 	char *quitreason;
401 	char *topic;
402 	char *current_modes;					/* free() me */
403 
404 	int mode_timeout_tag;
405 
406 	struct session *lastlog_sess;
407 	struct nbexec *running_exec;
408 
409 	struct session_gui *gui;		/* initialized by fe_new_window */
410 	struct restore_gui *res;
411 
412 	int type;					/* SESS_* */
413 
414 	int lastact_idx;		/* the sess_list_by_lastact[] index of the list we're in.
415 							 * For valid values, see defines of LACT_*. */
416 
417 	int ignore_date:1;
418 	int ignore_mode:1;
419 	int ignore_names:1;
420 	int end_of_names:1;
421 	int doing_who:1;		/* /who sent on this channel */
422 	int done_away_check:1;	/* done checking for away status changes */
423 	tab_state_flags tab_state;
424 	tab_state_flags last_tab_state; /* before event is handled */
425 	gtk_xtext_search_flags lastlog_flags;
426 	void (*scrollback_replay_marklast) (struct session *sess);
427 } session;
428 
429 /* SASL Mechanisms */
430 #define MECH_PLAIN 0
431 #define MECH_EXTERNAL 1
432 
433 typedef struct server
434 {
435 	/*  server control operations (in server*.c) */
436 	void (*connect)(struct server *, char *hostname, int port, int no_login);
437 	void (*disconnect)(struct session *, int sendquit, int err);
438 	int  (*cleanup)(struct server *);
439 	void (*flush_queue)(struct server *);
440 	void (*auto_reconnect)(struct server *, int send_quit, int err);
441 	/* irc protocol functions (in proto*.c) */
442 	void (*p_inline)(struct server *, char *buf, int len);
443 	void (*p_invite)(struct server *, char *channel, char *nick);
444 	void (*p_cycle)(struct server *, char *channel, char *key);
445 	void (*p_ctcp)(struct server *, char *to, char *msg);
446 	void (*p_nctcp)(struct server *, char *to, char *msg);
447 	void (*p_quit)(struct server *, char *reason);
448 	void (*p_kick)(struct server *, char *channel, char *nick, char *reason);
449 	void (*p_part)(struct server *, char *channel, char *reason);
450 	void (*p_ns_identify)(struct server *, char *pass);
451 	void (*p_ns_ghost)(struct server *, char *usname, char *pass);
452 	void (*p_join)(struct server *, char *channel, char *key);
453 	void (*p_join_list)(struct server *, GSList *favorites);
454 	void (*p_login)(struct server *, char *user, char *realname);
455 	void (*p_join_info)(struct server *, char *channel);
456 	void (*p_mode)(struct server *, char *target, char *mode);
457 	void (*p_user_list)(struct server *, char *channel);
458 	void (*p_away_status)(struct server *, char *channel);
459 	void (*p_whois)(struct server *, char *nicks);
460 	void (*p_get_ip)(struct server *, char *nick);
461 	void (*p_get_ip_uh)(struct server *, char *nick);
462 	void (*p_set_back)(struct server *);
463 	void (*p_set_away)(struct server *, char *reason);
464 	void (*p_message)(struct server *, char *channel, char *text);
465 	void (*p_action)(struct server *, char *channel, char *act);
466 	void (*p_notice)(struct server *, char *channel, char *text);
467 	void (*p_topic)(struct server *, char *channel, char *topic);
468 	void (*p_list_channels)(struct server *, char *arg, int min_users);
469 	void (*p_change_nick)(struct server *, char *new_nick);
470 	void (*p_names)(struct server *, char *channel);
471 	void (*p_ping)(struct server *, char *to, char *timestring);
472 /*	void (*p_set_away)(struct server *);*/
473 	int (*p_raw)(struct server *, char *raw);
474 	int (*p_cmp)(const char *s1, const char *s2);
475 
476 	int port;
477 	int sok;					/* is equal to sok4 or sok6 (the one we are using) */
478 	int sok4;					/* tcp4 socket */
479 	int sok6;					/* tcp6 socket */
480 	int proxy_type;
481 	int proxy_sok;				/* Additional information for MS Proxy beast */
482 	int proxy_sok4;
483 	int proxy_sok6;
484 	int id;					/* unique ID number (for plugin API) */
485 
486 	/* dcc_ip moved from hexchatprefs to make it per-server */
487 	guint32 dcc_ip;
488 
489 #ifdef USE_OPENSSL
490 	SSL_CTX *ctx;
491 	SSL *ssl;
492 	int ssl_do_connect_tag;
493 #else
494 	void *ssl;
495 #endif
496 	int childread;
497 	int childwrite;
498 	int childpid;
499 	int iotag;
500 	int recondelay_tag;				/* reconnect delay timeout */
501 	int joindelay_tag;				/* waiting before we send JOIN */
502 	char hostname[128];				/* real ip number */
503 	char servername[128];			/* what the server says is its name */
504 	char password[86];
505 	char nick[NICKLEN];
506 	char linebuf[8704];				/* RFC says 512 chars including \r\n, IRCv3 message tags add 8191, plus the NUL byte */
507 	char *last_away_reason;
508 	int pos;								/* current position in linebuf */
509 	int nickcount;
510 	int loginmethod;					/* see login_types[] */
511 
512 	char *chantypes;					/* for 005 numeric - free me */
513 	char *chanmodes;					/* for 005 numeric - free me */
514 	char *nick_prefixes;				/* e.g. "*@%+" */
515 	char *nick_modes;					/* e.g. "aohv" */
516 	char *bad_nick_prefixes;		/* for ircd that doesn't give the modes */
517 	int modes_per_line;				/* 6 on undernet, 4 on efnet etc... */
518 
519 	void *network;						/* points to entry in servlist.c or NULL! */
520 
521 	GSList *outbound_queue;
522 	time_t next_send;						/* cptr->since in ircu */
523 	time_t prev_now;					/* previous now-time */
524 	int sendq_len;						/* queue size */
525 	int lag;								/* milliseconds */
526 
527 	struct session *front_session;	/* front-most window/tab */
528 	struct session *server_session;	/* server window/tab */
529 
530 	struct server_gui *gui;		  /* initialized by fe_new_server */
531 
532 	unsigned int ctcp_counter;	  /*flood */
533 	time_t ctcp_last_time;
534 
535 	unsigned int msg_counter;	  /*counts the msg tab opened in a certain time */
536 	time_t msg_last_time;
537 
538 	/*time_t connect_time;*/				/* when did it connect? */
539 	unsigned long lag_sent;   /* we are still waiting for this ping response*/
540 	time_t ping_recv;					/* when we last got a ping reply */
541 	time_t away_time;					/* when we were marked away */
542 
543 	char *encoding;
544 	GIConv read_converter;  /* iconv converter for converting from server encoding to UTF-8. */
545 	GIConv write_converter; /* iconv converter for converting from UTF-8 to server encoding. */
546 
547 	GSList *favlist;			/* list of channels & keys to join */
548 
549 	unsigned int motd_skipped:1;
550 	unsigned int connected:1;
551 	unsigned int connecting:1;
552 	unsigned int no_login:1;
553 	unsigned int skip_next_userhost:1;/* used for "get my ip from server" */
554 	unsigned int skip_next_whois:1;	/* hide whois output */
555 	unsigned int inside_whois:1;
556 	unsigned int doing_dns:1;			/* /dns has been done */
557 	unsigned int end_of_motd:1;		/* end of motd reached (logged in) */
558 	unsigned int sent_quit:1;			/* sent a QUIT already? */
559 	unsigned int use_listargs:1;		/* undernet and dalnet need /list >0,<10000 */
560 	unsigned int is_away:1;
561 	unsigned int reconnect_away:1;	/* whether to reconnect in is_away state */
562 	unsigned int dont_use_proxy:1;	/* to proxy or not to proxy */
563 	unsigned int supports_watch:1;	/* supports the WATCH command */
564 	unsigned int supports_monitor:1;	/* supports the MONITOR command */
565 	unsigned int bad_prefix:1;			/* gave us a bad PREFIX= 005 number */
566 	unsigned int have_namesx:1;		/* 005 tokens NAMESX and UHNAMES */
567 	unsigned int have_awaynotify:1;
568 	unsigned int have_uhnames:1;
569 	unsigned int have_whox:1;		/* have undernet's WHOX features */
570 	unsigned int have_idmsg:1;		/* cap solanum.chat/identify-msg */
571 	unsigned int have_accnotify:1; /* cap account-notify */
572 	unsigned int have_extjoin:1;	/* cap extended-join */
573 	unsigned int have_account_tag:1;	/* cap account-tag */
574 	unsigned int have_server_time:1;	/* cap server-time */
575 	unsigned int have_sasl:1;		/* SASL capability */
576 	unsigned int have_except:1;	/* ban exemptions +e */
577 	unsigned int have_invite:1;	/* invite exemptions +I */
578 	unsigned int have_cert:1;	/* have loaded a cert */
579 	unsigned int use_who:1;			/* whether to use WHO command to get dcc_ip */
580 	unsigned int sasl_mech;			/* mechanism for sasl auth */
581 	unsigned int sent_capend:1;	/* have sent CAP END yet */
582 	unsigned int waiting_on_cap:1;	/* waiting on another line of CAP LS */
583 	unsigned int waiting_on_sasl:1; /* waiting on sasl */
584 #ifdef USE_OPENSSL
585 	unsigned int use_ssl:1;				  /* is server SSL capable? */
586 	unsigned int accept_invalid_cert:1;/* ignore result of server's cert. verify */
587 #endif
588 } server;
589 
590 typedef int (*cmd_callback) (struct session * sess, char *tbuf, char *word[],
591 									  char *word_eol[]);
592 
593 struct commands
594 {
595 	char *name;
596 	cmd_callback callback;
597 	char needserver;
598 	char needchannel;
599 	gint16 handle_quotes;
600 	char *help;
601 };
602 
603 struct away_msg
604 {
605 	struct server *server;
606 	char nick[NICKLEN];
607 	char *message;
608 };
609 
610 /* not just for popups, but used for usercommands, ctcp replies,
611    userlist buttons etc */
612 
613 struct popup
614 {
615 	char *cmd;
616 	char *name;
617 };
618 
619 /* CL: get a random int in the range [0..n-1]. DON'T use rand() % n, it gives terrible results. */
620 #define RAND_INT(n) ((int)(rand() / (RAND_MAX + 1.0) * (n)))
621 
622 #endif
623