summary refs log tree commit diff stats
path: root/src/common/xchat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/xchat.c')
-rw-r--r--src/common/xchat.c1207
1 files changed, 0 insertions, 1207 deletions
diff --git a/src/common/xchat.c b/src/common/xchat.c
deleted file mode 100644
index d1916384..00000000
--- a/src/common/xchat.c
+++ /dev/null
@@ -1,1207 +0,0 @@
-/* X-Chat
- * Copyright (C) 1998 Peter Zelezny.
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#define WANTSOCKET
-#include "inet.h"
-
-#ifdef WIN32
-#include <windows.h>
-#else
-#include <sys/wait.h>
-#include <signal.h>
-#include <unistd.h>
-#endif
-
-#include "xchat.h"
-#include "fe.h"
-#include "util.h"
-#include "cfgfiles.h"
-#include "chanopt.h"
-#include "ignore.h"
-#include "xchat-plugin.h"
-#include "plugin.h"
-#include "plugin-timer.h"
-#include "notify.h"
-#include "server.h"
-#include "servlist.h"
-#include "outbound.h"
-#include "text.h"
-#include "url.h"
-#include "xchatc.h"
-
-#ifdef USE_OPENSSL
-#include <openssl/ssl.h>		  /* SSL_() */
-#include "ssl.h"
-#endif
-
-#ifdef USE_MSPROXY
-#include "msproxy.h"
-#endif
-
-#ifdef USE_LIBPROXY
-#include <proxy.h>
-#endif
-
-GSList *popup_list = 0;
-GSList *button_list = 0;
-GSList *dlgbutton_list = 0;
-GSList *command_list = 0;
-GSList *ctcp_list = 0;
-GSList *replace_list = 0;
-GSList *sess_list = 0;
-GSList *dcc_list = 0;
-GSList *ignore_list = 0;
-GSList *usermenu_list = 0;
-GSList *urlhandler_list = 0;
-GSList *tabmenu_list = 0;
-
-static int in_xchat_exit = FALSE;
-int xchat_is_quitting = FALSE;
-/* command-line args */
-int arg_dont_autoconnect = FALSE;
-int arg_skip_plugins = FALSE;
-char *arg_url = NULL;
-char *arg_command = NULL;
-gint arg_existing = FALSE;
-
-#ifdef USE_DBUS
-#include "dbus/dbus-client.h"
-#include "dbus/dbus-plugin.h"
-#endif /* USE_DBUS */
-
-struct session *current_tab;
-struct session *current_sess = 0;
-struct hexchatprefs prefs;
-
-#ifdef USE_OPENSSL
-SSL_CTX *ctx = NULL;
-#endif
-
-#ifdef USE_LIBPROXY
-pxProxyFactory *libproxy_factory;
-#endif
-
-int
-is_session (session * sess)
-{
-	return g_slist_find (sess_list, sess) ? 1 : 0;
-}
-
-session *
-find_dialog (server *serv, char *nick)
-{
-	GSList *list = sess_list;
-	session *sess;
-
-	while (list)
-	{
-		sess = list->data;
-		if (sess->server == serv && sess->type == SESS_DIALOG)
-		{
-			if (!serv->p_cmp (nick, sess->channel))
-				return (sess);
-		}
-		list = list->next;
-	}
-	return 0;
-}
-
-session *
-find_channel (server *serv, char *chan)
-{
-	session *sess;
-	GSList *list = sess_list;
-	while (list)
-	{
-		sess = list->data;
-		if ((!serv || serv == sess->server) && sess->type != SESS_DIALOG)
-		{
-			if (!serv->p_cmp (chan, sess->channel))
-				return sess;
-		}
-		list = list->next;
-	}
-	return 0;
-}
-
-static void
-lagcheck_update (void)
-{
-	server *serv;
-	GSList *list = serv_list;
-	
-	if (!prefs.hex_gui_lagometer)
-		return;
-
-	while (list)
-	{
-		serv = list->data;
-		if (serv->lag_sent)
-			fe_set_lag (serv, -1);
-
-		list = list->next;
-	}
-}
-
-void
-lag_check (void)
-{
-	server *serv;
-	GSList *list = serv_list;
-	unsigned long tim;
-	char tbuf[128];
-	time_t now = time (0);
-	int lag;
-
-	tim = make_ping_time ();
-
-	while (list)
-	{
-		serv = list->data;
-		if (serv->connected && serv->end_of_motd)
-		{
-			lag = now - serv->ping_recv;
-			if (prefs.hex_net_ping_timeout && lag > prefs.hex_net_ping_timeout && lag > 0)
-			{
-				sprintf (tbuf, "%d", lag);
-				EMIT_SIGNAL (XP_TE_PINGTIMEOUT, serv->server_session, tbuf, NULL,
-								 NULL, NULL, 0);
-				if (prefs.hex_net_auto_reconnect)
-					serv->auto_reconnect (serv, FALSE, -1);
-			} else
-			{
-				snprintf (tbuf, sizeof (tbuf), "LAG%lu", tim);
-				serv->p_ping (serv, "", tbuf);
-				serv->lag_sent = tim;
-				fe_set_lag (serv, -1);
-			}
-		}
-		list = list->next;
-	}
-}
-
-static int
-away_check (void)
-{
-	session *sess;
-	GSList *list;
-	int full, sent, loop = 0;
-
-	if (!prefs.hex_away_track || prefs.hex_away_size_max < 1)
-		return 1;
-
-doover:
-	/* request an update of AWAY status of 1 channel every 30 seconds */
-	full = TRUE;
-	sent = 0;	/* number of WHOs (users) requested */
-	list = sess_list;
-	while (list)
-	{
-		sess = list->data;
-
-		if (sess->server->connected &&
-			 sess->type == SESS_CHANNEL &&
-			 sess->channel[0] &&
-			 sess->total <= prefs.hex_away_size_max)
-		{
-			if (!sess->done_away_check)
-			{
-				full = FALSE;
-
-				/* if we're under 31 WHOs, send another channels worth */
-				if (sent < 31 && !sess->doing_who)
-				{
-					sess->done_away_check = TRUE;
-					sess->doing_who = TRUE;
-					/* this'll send a WHO #channel */
-					sess->server->p_away_status (sess->server, sess->channel);
-					sent += sess->total;
-				}
-			}
-		}
-
-		list = list->next;
-	}
-
-	/* done them all, reset done_away_check to FALSE and start over */
-	if (full)
-	{
-		list = sess_list;
-		while (list)
-		{
-			sess = list->data;
-			sess->done_away_check = FALSE;
-			list = list->next;
-		}
-		loop++;
-		if (loop < 2)
-			goto doover;
-	}
-
-	return 1;
-}
-
-static int
-xchat_misc_checks (void)		/* this gets called every 1/2 second */
-{
-	static int count = 0;
-#ifdef USE_MSPROXY
-	static int count2 = 0;
-#endif
-
-	count++;
-
-	lagcheck_update ();			/* every 500ms */
-
-	if (count % 2)
-		dcc_check_timeouts ();	/* every 1 second */
-
-	if (count >= 60)				/* every 30 seconds */
-	{
-		if (prefs.hex_gui_lagometer)
-			lag_check ();
-		count = 0;
-	}
-
-#ifdef USE_MSPROXY	
-	count2++;
-	if (count2 >= 720)			/* 720 every 6 minutes */
-	{
-		msproxy_keepalive ();
-		count2 = 0;
-	}
-#endif
-
-	return 1;
-}
-
-/* executed when the first irc window opens */
-
-static void
-irc_init (session *sess)
-{
-	static int done_init = FALSE;
-	char buf[512];
-
-	if (done_init)
-		return;
-
-	done_init = TRUE;
-
-	plugin_add (sess, NULL, NULL, timer_plugin_init, NULL, NULL, FALSE);
-
-#ifdef USE_PLUGIN
-	if (!arg_skip_plugins)
-		plugin_auto_load (sess);	/* autoload ~/.xchat *.so */
-#endif
-
-#ifdef USE_DBUS
-	plugin_add (sess, NULL, NULL, dbus_plugin_init, NULL, NULL, FALSE);
-#endif
-
-	if (prefs.hex_notify_timeout)
-		notify_tag = fe_timeout_add (prefs.hex_notify_timeout * 1000,
-											  notify_checklist, 0);
-
-	fe_timeout_add (prefs.hex_away_timeout * 1000, away_check, 0);
-	fe_timeout_add (500, xchat_misc_checks, 0);
-
-	if (arg_url != NULL)
-	{
-		snprintf (buf, sizeof (buf), "server %s", arg_url);
-		handle_command (sess, buf, FALSE);
-		g_free (arg_url);	/* from GOption */
-	}
-
-	if (arg_command != NULL)
-	{
-		g_free (arg_command);
-	}
-
-	/* load -e ~/.xchat2/startup.txt */
-	snprintf (buf, sizeof (buf), "%s/%s", get_xdir_fs (), "startup.txt");
-	load_perform_file (sess, buf);
-}
-
-static session *
-session_new (server *serv, char *from, int type, int focus)
-{
-	session *sess;
-
-	sess = malloc (sizeof (struct session));
-	if (sess == NULL)
-	{
-		return NULL;
-	}
-	memset (sess, 0, sizeof (struct session));
-
-	sess->server = serv;
-	sess->logfd = -1;
-	sess->scrollfd = -1;
-	sess->type = type;
-
-	sess->alert_beep = SET_DEFAULT;
-	sess->alert_taskbar = SET_DEFAULT;
-	sess->alert_tray = SET_DEFAULT;
-
-	sess->text_hidejoinpart = SET_DEFAULT;
-	sess->text_logging = SET_DEFAULT;
-	sess->text_scrollback = SET_DEFAULT;
-
-	if (from != NULL)
-		safe_strcpy (sess->channel, from, CHANLEN);
-
-	sess_list = g_slist_prepend (sess_list, sess);
-
-	fe_new_window (sess, focus);
-
-	return sess;
-}
-
-session *
-new_ircwindow (server *serv, char *name, int type, int focus)
-{
-	session *sess;
-
-	switch (type)
-	{
-	case SESS_SERVER:
-		serv = server_new ();
-		if (prefs.hex_gui_tab_server)
-			sess = session_new (serv, name, SESS_SERVER, focus);
-		else
-			sess = session_new (serv, name, SESS_CHANNEL, focus);
-		serv->server_session = sess;
-		serv->front_session = sess;
-		break;
-	case SESS_DIALOG:
-		sess = session_new (serv, name, type, focus);
-		log_open_or_close (sess);
-		break;
-	default:
-/*	case SESS_CHANNEL:
-	case SESS_NOTICES:
-	case SESS_SNOTICES:*/
-		sess = session_new (serv, name, type, focus);
-		break;
-	}
-
-	irc_init (sess);
-	scrollback_load (sess);
-	chanopt_load (sess);
-	plugin_emit_dummy_print (sess, "Open Context");
-
-	return sess;
-}
-
-static void
-exec_notify_kill (session * sess)
-{
-#ifndef WIN32
-	struct nbexec *re;
-	if (sess->running_exec != NULL)
-	{
-		re = sess->running_exec;
-		sess->running_exec = NULL;
-		kill (re->childpid, SIGKILL);
-		waitpid (re->childpid, NULL, WNOHANG);
-		fe_input_remove (re->iotag);
-		close (re->myfd);
-		if (re->linebuf)
-			free(re->linebuf);
-		free (re);
-	}
-#endif
-}
-
-static void
-send_quit_or_part (session * killsess)
-{
-	int willquit = TRUE;
-	GSList *list;
-	session *sess;
-	server *killserv = killsess->server;
-
-	/* check if this is the last session using this server */
-	list = sess_list;
-	while (list)
-	{
-		sess = (session *) list->data;
-		if (sess->server == killserv && sess != killsess)
-		{
-			willquit = FALSE;
-			list = 0;
-		} else
-			list = list->next;
-	}
-
-	if (xchat_is_quitting)
-		willquit = TRUE;
-
-	if (killserv->connected)
-	{
-		if (willquit)
-		{
-			if (!killserv->sent_quit)
-			{
-				killserv->flush_queue (killserv);
-				server_sendquit (killsess);
-				killserv->sent_quit = TRUE;
-			}
-		} else
-		{
-			if (killsess->type == SESS_CHANNEL && killsess->channel[0] &&
-				 !killserv->sent_quit)
-			{
-				server_sendpart (killserv, killsess->channel, 0);
-			}
-		}
-	}
-}
-
-void
-session_free (session *killsess)
-{
-	server *killserv = killsess->server;
-	session *sess;
-	GSList *list;
-
-	plugin_emit_dummy_print (killsess, "Close Context");
-
-	if (current_tab == killsess)
-		current_tab = NULL;
-
-	if (killserv->server_session == killsess)
-		killserv->server_session = NULL;
-
-	if (killserv->front_session == killsess)
-	{
-		/* front_session is closed, find a valid replacement */
-		killserv->front_session = NULL;
-		list = sess_list;
-		while (list)
-		{
-			sess = (session *) list->data;
-			if (sess != killsess && sess->server == killserv)
-			{
-				killserv->front_session = sess;
-				if (!killserv->server_session)
-					killserv->server_session = sess;
-				break;
-			}
-			list = list->next;
-		}
-	}
-
-	if (!killserv->server_session)
-		killserv->server_session = killserv->front_session;
-
-	sess_list = g_slist_remove (sess_list, killsess);
-
-	if (killsess->type == SESS_CHANNEL)
-		userlist_free (killsess);
-
-	exec_notify_kill (killsess);
-
-	log_close (killsess);
-	scrollback_close (killsess);
-	chanopt_save (killsess);
-
-	send_quit_or_part (killsess);
-
-	history_free (&killsess->history);
-	if (killsess->topic)
-		free (killsess->topic);
-	if (killsess->current_modes)
-		free (killsess->current_modes);
-
-	fe_session_callback (killsess);
-
-	if (current_sess == killsess)
-	{
-		current_sess = NULL;
-		if (sess_list)
-			current_sess = sess_list->data;
-	}
-
-	free (killsess);
-
-	if (!sess_list && !in_xchat_exit)
-		xchat_exit ();						/* sess_list is empty, quit! */
-
-	list = sess_list;
-	while (list)
-	{
-		sess = (session *) list->data;
-		if (sess->server == killserv)
-			return;					  /* this server is still being used! */
-		list = list->next;
-	}
-
-	server_free (killserv);
-}
-
-static void
-free_sessions (void)
-{
-	GSList *list = sess_list;
-
-	while (list)
-	{
-		fe_close_window (list->data);
-		list = sess_list;
-	}
-}
-
-
-static char defaultconf_ctcp[] =
-	"NAME TIME\n"				"CMD nctcp %s TIME %t\n\n"\
-	"NAME PING\n"				"CMD nctcp %s PING %d\n\n";
-
-static char defaultconf_replace[] =
-	"NAME teh\n"				"CMD the\n\n";
-/*	"NAME r\n"					"CMD are\n\n"\
-	"NAME u\n"					"CMD you\n\n"*/
-
-static char defaultconf_commands[] =
-	"NAME ACTION\n"		"CMD me &2\n\n"\
-	"NAME AME\n"			"CMD allchan me &2\n\n"\
-	"NAME ANICK\n"			"CMD allserv nick &2\n\n"\
-	"NAME AMSG\n"			"CMD allchan say &2\n\n"\
-	"NAME BANLIST\n"		"CMD quote MODE %c +b\n\n"\
-	"NAME CHAT\n"			"CMD dcc chat %2\n\n"\
-	"NAME DIALOG\n"		"CMD query %2\n\n"\
-	"NAME DMSG\n"			"CMD msg =%2 &3\n\n"\
-	"NAME EXIT\n"			"CMD quit\n\n"\
-	"NAME GREP\n"			"CMD lastlog -r -- &2\n\n"\
-	"NAME IGNALL\n"			"CMD ignore %2!*@* ALL\n\n"\
-	"NAME J\n"				"CMD join &2\n\n"\
-	"NAME KILL\n"			"CMD quote KILL %2 :&3\n\n"\
-	"NAME LEAVE\n"			"CMD part &2\n\n"\
-	"NAME M\n"				"CMD msg &2\n\n"\
-	"NAME ONOTICE\n"		"CMD notice @%c &2\n\n"\
-	"NAME RAW\n"			"CMD quote &2\n\n"\
-	"NAME SERVHELP\n"		"CMD quote HELP\n\n"\
-	"NAME SPING\n"			"CMD ping\n\n"\
-	"NAME SQUERY\n"		"CMD quote SQUERY %2 :&3\n\n"\
-	"NAME SSLSERVER\n"	"CMD server -ssl &2\n\n"\
-	"NAME SV\n"				"CMD echo xchat %v %m\n\n"\
-	"NAME UMODE\n"			"CMD mode %n &2\n\n"\
-	"NAME UPTIME\n"		"CMD quote STATS u\n\n"\
-	"NAME VER\n"			"CMD ctcp %2 VERSION\n\n"\
-	"NAME VERSION\n"		"CMD ctcp %2 VERSION\n\n"\
-	"NAME WALLOPS\n"		"CMD quote WALLOPS :&2\n\n"\
-	"NAME WII\n"			"CMD quote WHOIS %2 %2\n\n";
-
-static char defaultconf_urlhandlers[] =
-		"NAME Open Link in Opera\n"		"CMD !opera -remote 'openURL(%s)'\n\n";
-
-#ifdef USE_SIGACTION
-/* Close and open log files on SIGUSR1. Usefull for log rotating */
-
-static void 
-sigusr1_handler (int signal, siginfo_t *si, void *un)
-{
-	GSList *list = sess_list;
-	session *sess;
-
-	while (list)
-	{
-		sess = list->data;
-		log_open_or_close (sess);
-		list = list->next;
-	}
-}
-
-/* Execute /SIGUSR2 when SIGUSR2 received */
-
-static void
-sigusr2_handler (int signal, siginfo_t *si, void *un)
-{
-	session *sess = current_sess;
-
-	if (sess)
-		handle_command (sess, "SIGUSR2", FALSE);
-}
-#endif
-
-static gint
-xchat_auto_connect (gpointer userdata)
-{
-	servlist_auto_connect (NULL);
-	return 0;
-}
-
-static void
-xchat_init (void)
-{
-	char buf[3068];
-	const char *cs = NULL;
-
-#ifdef WIN32
-	WSADATA wsadata;
-
-#ifdef USE_IPV6
-	if (WSAStartup(0x0202, &wsadata) != 0)
-	{
-		MessageBox (NULL, "Cannot find winsock 2.2+", "Error", MB_OK);
-		exit (0);
-	}
-#else
-	WSAStartup(0x0101, &wsadata);
-#endif	/* !USE_IPV6 */
-#endif	/* !WIN32 */
-
-#ifdef USE_SIGACTION
-	struct sigaction act;
-
-	/* ignore SIGPIPE's */
-	act.sa_handler = SIG_IGN;
-	act.sa_flags = 0;
-	sigemptyset (&act.sa_mask);
-	sigaction (SIGPIPE, &act, NULL);
-
-	/* Deal with SIGUSR1's & SIGUSR2's */
-	act.sa_sigaction = sigusr1_handler;
-	act.sa_flags = 0;
-	sigemptyset (&act.sa_mask);
-	sigaction (SIGUSR1, &act, NULL);
-
-	act.sa_sigaction = sigusr2_handler;
-	act.sa_flags = 0;
-	sigemptyset (&act.sa_mask);
-	sigaction (SIGUSR2, &act, NULL);
-#else
-#ifndef WIN32
-	/* good enough for these old systems */
-	signal (SIGPIPE, SIG_IGN);
-#endif
-#endif
-
-	if (g_get_charset (&cs))
-		prefs.utf8_locale = TRUE;
-
-	load_text_events ();
-	sound_load ();
-	notify_load ();
-	ignore_load ();
-
-	snprintf (buf, sizeof (buf),
-		"NAME %s~%s~\n"				"CMD query %%s\n\n"\
-		"NAME %s~%s~\n"				"CMD send %%s\n\n"\
-		"NAME %s~%s~\n"				"CMD whois %%s %%s\n\n"\
-		"NAME %s~%s~\n"				"CMD notify -n ASK %%s\n\n"\
-		"NAME %s~%s~\n"				"CMD ignore %%s!*@* ALL\n\n"\
-
-		"NAME SUB\n"					"CMD %s\n\n"\
-			"NAME %s\n"					"CMD op %%a\n\n"\
-			"NAME %s\n"					"CMD deop %%a\n\n"\
-			"NAME SEP\n"				"CMD \n\n"\
-			"NAME %s\n"					"CMD voice %%a\n\n"\
-			"NAME %s\n"					"CMD devoice %%a\n"\
-			"NAME SEP\n"				"CMD \n\n"\
-			"NAME SUB\n"				"CMD %s\n\n"\
-				"NAME %s\n"				"CMD kick %%s\n\n"\
-				"NAME %s\n"				"CMD ban %%s\n\n"\
-				"NAME SEP\n"			"CMD \n\n"\
-				"NAME %s *!*@*.host\n""CMD ban %%s 0\n\n"\
-				"NAME %s *!*@domain\n""CMD ban %%s 1\n\n"\
-				"NAME %s *!*user@*.host\n""CMD ban %%s 2\n\n"\
-				"NAME %s *!*user@domain\n""CMD ban %%s 3\n\n"\
-				"NAME SEP\n"			"CMD \n\n"\
-				"NAME %s *!*@*.host\n""CMD kickban %%s 0\n\n"\
-				"NAME %s *!*@domain\n""CMD kickban %%s 1\n\n"\
-				"NAME %s *!*user@*.host\n""CMD kickban %%s 2\n\n"\
-				"NAME %s *!*user@domain\n""CMD kickban %%s 3\n\n"\
-			"NAME ENDSUB\n"			"CMD \n\n"\
-		"NAME ENDSUB\n"				"CMD \n\n",
-
-		_("_Open Dialog Window"), "gtk-go-up",
-		_("_Send a File"), "gtk-floppy",
-		_("_User Info (WhoIs)"), "gtk-info",
-		_("_Add to Friends List"), "gtk-add",
-		_("_Ignore"), "gtk-stop",
-		_("O_perator Actions"),
-
-		_("Give Ops"),
-		_("Take Ops"),
-		_("Give Voice"),
-		_("Take Voice"),
-
-		_("Kick/Ban"),
-		_("Kick"),
-		_("Ban"),
-		_("Ban"),
-		_("Ban"),
-		_("Ban"),
-		_("Ban"),
-		_("KickBan"),
-		_("KickBan"),
-		_("KickBan"),
-		_("KickBan"));
-
-	list_loadconf ("popup.conf", &popup_list, buf);
-
-	snprintf (buf, sizeof (buf),
-		"NAME %s\n"				"CMD part\n\n"
-		"NAME %s\n"				"CMD getstr # join \"%s\"\n\n"
-		"NAME %s\n"				"CMD quote LINKS\n\n"
-		"NAME %s\n"				"CMD ping\n\n"
-		"NAME TOGGLE %s\n"	"CMD irc_hide_version\n\n",
-				_("Leave Channel"),
-				_("Join Channel..."),
-				_("Enter Channel to Join:"),
-				_("Server Links"),
-				_("Ping Server"),
-				_("Hide Version"));
-	list_loadconf ("usermenu.conf", &usermenu_list, buf);
-
-	snprintf (buf, sizeof (buf),
-		"NAME %s\n"		"CMD op %%a\n\n"
-		"NAME %s\n"		"CMD deop %%a\n\n"
-		"NAME %s\n"		"CMD ban %%s\n\n"
-		"NAME %s\n"		"CMD getstr \"%s\" \"kick %%s\" \"%s\"\n\n"
-		"NAME %s\n"		"CMD send %%s\n\n"
-		"NAME %s\n"		"CMD query %%s\n\n",
-				_("Op"),
-				_("DeOp"),
-				_("Ban"),
-				_("Kick"),
-				_("bye"),
-				_("Enter reason to kick %s:"),
-				_("Sendfile"),
-				_("Dialog"));
-	list_loadconf ("buttons.conf", &button_list, buf);
-
-	snprintf (buf, sizeof (buf),
-		"NAME %s\n"				"CMD whois %%s %%s\n\n"
-		"NAME %s\n"				"CMD send %%s\n\n"
-		"NAME %s\n"				"CMD dcc chat %%s\n\n"
-		"NAME %s\n"				"CMD clear\n\n"
-		"NAME %s\n"				"CMD ping %%s\n\n",
-				_("WhoIs"),
-				_("Send"),
-				_("Chat"),
-				_("Clear"),
-				_("Ping"));
-	list_loadconf ("dlgbuttons.conf", &dlgbutton_list, buf);
-
-	list_loadconf ("tabmenu.conf", &tabmenu_list, NULL);
-	list_loadconf ("ctcpreply.conf", &ctcp_list, defaultconf_ctcp);
-	list_loadconf ("commands.conf", &command_list, defaultconf_commands);
-	list_loadconf ("replace.conf", &replace_list, defaultconf_replace);
-	list_loadconf ("urlhandlers.conf", &urlhandler_list,
-						defaultconf_urlhandlers);
-
-	servlist_init ();							/* load server list */
-
-	/* if we got a URL, don't open the server list GUI */
-	if (!prefs.hex_gui_slist_skip && !arg_url)
-		fe_serverlist_open (NULL);
-
-	/* turned OFF via -a arg */
-	if (!arg_dont_autoconnect)
-	{
-		/* do any auto connects */
-		if (!servlist_have_auto ())	/* if no new windows open .. */
-		{
-			/* and no serverlist gui ... */
-			if (prefs.hex_gui_slist_skip || arg_url)
-				/* we'll have to open one. */
-				new_ircwindow (NULL, NULL, SESS_SERVER, 0);
-		} else
-		{
-			fe_idle_add (xchat_auto_connect, NULL);
-		}
-	} else
-	{
-		if (prefs.hex_gui_slist_skip || arg_url)
-			new_ircwindow (NULL, NULL, SESS_SERVER, 0);
-	}
-}
-
-void
-xchat_exit (void)
-{
-	xchat_is_quitting = TRUE;
-	in_xchat_exit = TRUE;
-	plugin_kill_all ();
-	fe_cleanup ();
-
-	save_config ();
-	if (prefs.save_pevents)
-	{
-		pevent_save (NULL);
-	}
-
-	sound_save ();
-	notify_save ();
-	ignore_save ();
-	free_sessions ();
-	chanopt_save_all ();
-	servlist_cleanup ();
-	fe_exit ();
-}
-
-#ifndef WIN32
-
-static int
-child_handler (gpointer userdata)
-{
-	int pid = GPOINTER_TO_INT (userdata);
-
-	if (waitpid (pid, 0, WNOHANG) == pid)
-		return 0;					  /* remove timeout handler */
-	return 1;						  /* keep the timeout handler */
-}
-
-#endif
-
-void
-xchat_exec (const char *cmd)
-{
-#ifdef WIN32
-	util_exec (cmd);
-#else
-	int pid = util_exec (cmd);
-	if (pid != -1)
-	/* zombie avoiding system. Don't ask! it has to be like this to work
-      with zvt (which overrides the default handler) */
-		fe_timeout_add (1000, child_handler, GINT_TO_POINTER (pid));
-#endif
-}
-
-void
-xchat_execv (char * const argv[])
-{
-#ifdef WIN32
-	util_execv (argv);
-#else
-	int pid = util_execv (argv);
-	if (pid != -1)
-	/* zombie avoiding system. Don't ask! it has to be like this to work
-      with zvt (which overrides the default handler) */
-		fe_timeout_add (1000, child_handler, GINT_TO_POINTER (pid));
-#endif
-}
-
-#ifdef WIN32
-static void
-xchat_restore_window (HWND xchat_window)
-{
-	/* ShowWindow (xchat_window, SW_RESTORE); another way, but works worse */
-	SendMessage (xchat_window, WM_SYSCOMMAND, SC_RESTORE, 0);
-	SetForegroundWindow (xchat_window);
-}
-
-BOOL CALLBACK
-enum_windows_impl (HWND current_window, LPARAM lParam)
-{
-	TCHAR window_name[8];
-	TCHAR module_path[1024];
-	ZeroMemory (&window_name, sizeof (window_name));
-
-	if (!current_window)
-	{
-		return TRUE;
-	}
-
-	GetWindowText (current_window, window_name, 8);		/* name length + 1 */
-	if (strcmp (window_name, "HexChat") == 0)
-	{
-		/* use a separate if block, this way we don't have to call GetWindowModuleFileName() for each hit */
-		ZeroMemory (&module_path, sizeof (module_path));
-		GetWindowModuleFileName (current_window, module_path, sizeof (module_path));
-
-		if (strstr (module_path, "hexchat.exe"))	/* We've found it, stop */
-		{
-			xchat_restore_window (current_window);
-			return FALSE;
-		}
-	}
-
-	return TRUE;								/* Keep searching */
-
-}
-#endif
-
-int
-main (int argc, char *argv[])
-{
-	int ret;
-
-#ifdef WIN32
-	char hexchat_lang[13];	/* LC_ALL= plus 5 chars of hex_gui_lang and trailing \0 */
-	HANDLE mutex;
-#endif
-
-	srand (time (0));	/* CL: do this only once! */
-
-	load_config ();
-
-#ifdef WIN32
-	/* we MUST do this after load_config () AND before fe_init (thus gtk_init) otherwise it will fail */
-	strcpy (hexchat_lang, "LC_ALL=");
-
-	/* this must be ordered EXACTLY as langsmenu[] */
-	switch (prefs.hex_gui_lang)
-	{
-		case 0:
-			strcat (hexchat_lang, "af");
-			break;
-		case 1:
-			strcat (hexchat_lang, "sq");
-			break;
-		case 2:
-			strcat (hexchat_lang, "am");
-			break;
-		case 3:
-			strcat (hexchat_lang, "ast");
-			break;
-		case 4:
-			strcat (hexchat_lang, "az");
-			break;
-		case 5:
-			strcat (hexchat_lang, "eu");
-			break;
-		case 6:
-			strcat (hexchat_lang, "be");
-			break;
-		case 7:
-			strcat (hexchat_lang, "bg");
-			break;
-		case 8:
-			strcat (hexchat_lang, "ca");
-			break;
-		case 9:
-			strcat (hexchat_lang, "zh_CN");
-			break;
-		case 10:
-			strcat (hexchat_lang, "zh_TW");
-			break;
-		case 11:
-			strcat (hexchat_lang, "cs");
-			break;
-		case 12:
-			strcat (hexchat_lang, "da");
-			break;
-		case 13:
-			strcat (hexchat_lang, "nl");
-			break;
-		case 14:
-			strcat (hexchat_lang, "en_GB");
-			break;
-		case 15:
-			strcat (hexchat_lang, "en");
-			break;
-		case 16:
-			strcat (hexchat_lang, "et");
-			break;
-		case 17:
-			strcat (hexchat_lang, "fi");
-			break;
-		case 18:
-			strcat (hexchat_lang, "fr");
-			break;
-		case 19:
-			strcat (hexchat_lang, "gl");
-			break;
-		case 20:
-			strcat (hexchat_lang, "de");
-			break;
-		case 21:
-			strcat (hexchat_lang, "el");
-			break;
-		case 22:
-			strcat (hexchat_lang, "gu");
-			break;
-		case 23:
-			strcat (hexchat_lang, "hi");
-			break;
-		case 24:
-			strcat (hexchat_lang, "hu");
-			break;
-		case 25:
-			strcat (hexchat_lang, "id");
-			break;
-		case 26:
-			strcat (hexchat_lang, "it");
-			break;
-		case 27:
-			strcat (hexchat_lang, "ja");
-			break;
-		case 28:
-			strcat (hexchat_lang, "kn");
-			break;
-		case 29:
-			strcat (hexchat_lang, "rw");
-			break;
-		case 30:
-			strcat (hexchat_lang, "ko");
-			break;
-		case 31:
-			strcat (hexchat_lang, "lv");
-			break;
-		case 32:
-			strcat (hexchat_lang, "lt");
-			break;
-		case 33:
-			strcat (hexchat_lang, "mk");
-			break;
-		case 34:
-			strcat (hexchat_lang, "ml");
-			break;
-		case 35:
-			strcat (hexchat_lang, "ms");
-			break;
-		case 36:
-			strcat (hexchat_lang, "nb");
-			break;
-		case 37:
-			strcat (hexchat_lang, "no");
-			break;
-		case 38:
-			strcat (hexchat_lang, "pl");
-			break;
-		case 39:
-			strcat (hexchat_lang, "pt");
-			break;
-		case 40:
-			strcat (hexchat_lang, "pt_BR");
-			break;
-		case 41:
-			strcat (hexchat_lang, "pa");
-			break;
-		case 42:
-			strcat (hexchat_lang, "ru");
-			break;
-		case 43:
-			strcat (hexchat_lang, "sr");
-			break;
-		case 44:
-			strcat (hexchat_lang, "sk");
-			break;
-		case 45:
-			strcat (hexchat_lang, "sl");
-			break;
-		case 46:
-			strcat (hexchat_lang, "es");
-			break;
-		case 47:
-			strcat (hexchat_lang, "sv");
-			break;
-		case 48:
-			strcat (hexchat_lang, "th");
-			break;
-		case 49:
-			strcat (hexchat_lang, "uk");
-			break;
-		case 50:
-			strcat (hexchat_lang, "vi");
-			break;
-		case 51:
-			strcat (hexchat_lang, "wa");
-			break;
-		default:
-			strcat (hexchat_lang, "en");
-			break;
-	}
-
-	putenv (hexchat_lang);
-
-	if (prefs.hex_gui_single && !portable_mode ())
-	{
-		DWORD error;
-
-		mutex = CreateMutex (NULL, TRUE, "Local\\hexchat");
-		error = GetLastError ();
-
-		if (error == ERROR_ALREADY_EXISTS || mutex == NULL)
-		{
-			/* restoring the XChat window from the tray via the taskbar icon
-			 * only works correctly when X-Tray is used, but it's not a big deal
-			 * since you can only minimize XChat to tray via the taskbar if you
-			 * use X-Tray*/
-			if (hextray_mode ())
-			{
-				/* FindWindow() doesn't support wildcards so we check all the open windows */
-				EnumWindows (enum_windows_impl, NULL);
-				return 0;
-			}
-			else
-			{
-				return 1;
-			}
-		}
-	}
-#endif
-
-#ifdef SOCKS
-	SOCKSinit (argv[0]);
-#endif
-
-	ret = fe_args (argc, argv);
-	if (ret != -1)
-		return ret;
-	
-#ifdef USE_DBUS
-	xchat_remote ();
-#endif
-
-#ifdef USE_LIBPROXY
-	libproxy_factory = px_proxy_factory_new();
-#endif
-
-	fe_init ();
-
-	xchat_init ();
-
-	fe_main ();
-
-#ifdef USE_LIBPROXY
-	px_proxy_factory_free(libproxy_factory);
-#endif
-
-#ifdef USE_OPENSSL
-	if (ctx)
-		_SSL_context_free (ctx);
-#endif
-
-#ifdef USE_DEBUG
-	xchat_mem_list ();
-#endif
-
-#ifdef WIN32
-	WSACleanup ();
-
-	if (prefs.hex_gui_single && !portable_mode ())
-	{
-		ReleaseMutex (mutex);
-		CloseHandle (mutex);
-	}
-#endif
-
-	return 0;
-}