~aleteoryx/sexchat

a3400e0aa9f3b3835a0ba6312039ba515f6b8594 — Aleteoryx 4 months ago e08c803
remove all mentions of struct session from server.c
M src/common/chanopt.c => src/common/chanopt.c +3 -3
@@ 127,7 127,7 @@ chanopt_command (session *sess, char *tbuf, char *word[], char *word_eol[])
	if (!quiet)
		PrintTextf (sess, "\002%s\002: %s \002%s\002: %s\n",
						_("Network"),
						sess->server->network ? server_get_network (sess->server, TRUE) : _("<none>"),
						sess->server->network ? ircserver_get_network (sess->server, TRUE) : _("<none>"),
						_("Channel"),
						sess->session_name[0] ? sess->session_name : _("<none>"));



@@ 312,7 312,7 @@ chanopt_load (session *sess)
	if (sess->session_name[0] == 0)
		return;

	network = server_get_network (sess->server, FALSE);
	network = ircserver_get_network (sess->server, FALSE);
	if (!network)
		return;



@@ 348,7 348,7 @@ chanopt_save (session *sess)
	if (sess->session_name[0] == 0)
		return;

	network = server_get_network (sess->server, FALSE);
	network = ircserver_get_network (sess->server, FALSE);
	if (!network)
		return;


M src/common/ctcp.c => src/common/ctcp.c +1 -1
@@ 48,7 48,7 @@ ctcp_reply (session *sess, char *nick, char *word[], char *word_eol[],
	/* process %C %B etc */
	check_special_chars (conf, TRUE);
	auto_insert (tbuf, sizeof (tbuf), conf, word, word_eol, "", "", word_eol[5],
					 server_get_network (sess->server, TRUE), "", "", nick, "");
		     ircserver_get_network (sess->server, TRUE), "", "", nick, "");
	g_free (conf);
	handle_command (sess, tbuf, FALSE);
}

M src/common/hexchat.c => src/common/hexchat.c +1 -1
@@ 606,7 606,7 @@ send_quit_or_part (session * killsess)
			if (!killserv->sent_quit)
			{
				killserv->flush_queue (killserv);
				server_sendquit (killsess);
				killserv->p_quit (killserv);
				killserv->sent_quit = TRUE;
			}
		} else

M src/common/hexchat.h => src/common/hexchat.h +16 -3
@@ 436,18 436,29 @@ typedef struct session
typedef struct server
{
	/*  server control operations (in server*.c) */
	void (*connect)(struct server *, char *hostname, int port, int no_login);
	void (*disconnect)(struct session *, int sendquit, int err);
	int  (*cleanup)(struct server *);
	void (*flush_queue)(struct server *);
	void (*auto_reconnect)(struct server *, int send_quit, int err);
	
	void (*p_connected)(struct server *);
	void (*p_disconnected)(struct server *, int, int);
	void (*p_ssl_message)(struct server *, const char *);
	void (*p_serverlookup)(struct server *, const char *);
	void (*p_connfail)(struct server *, const char *);
	void (*p_connstop)(struct server *, const char *);
	void (*p_connecting)(struct server *, const char *, const char *, const char *);
	void (*p_unknhost)(struct server *);
	void (*p_readerr)(struct server *, int);
	void (*p_log)(struct server *, const char *);
	char *(*p_get_network)(struct server *, gboolean);
	
	/* irc protocol functions (in proto*.c) */
	void (*p_inline)(struct server *, char *buf, int len);
	void (*p_invite)(struct server *, char *channel, char *nick);
	void (*p_cycle)(struct server *, char *channel, char *key);
	void (*p_ctcp)(struct server *, char *to, char *msg);
	void (*p_nctcp)(struct server *, char *to, char *msg);
	void (*p_quit)(struct server *, char *reason);
	void (*p_quit)(struct server *);
	void (*p_kick)(struct server *, char *channel, char *nick, char *reason);
	void (*p_part)(struct server *, char *channel, char *reason);
	void (*p_ns_identify)(struct server *, char *pass);


@@ 527,6 538,8 @@ typedef struct server
	int sendq_len;						/* queue size */
	int lag;								/* milliseconds */

	char *quitreason;

	struct session *front_session;	/* front-most window/tab */
	struct session *server_session;	/* server window/tab */


M src/common/inbound.c => src/common/inbound.c +1 -1
@@ 1338,7 1338,7 @@ inbound_login_start (session *sess, char *nick, char *servname,
							const message_tags_data *tags_data)
{
	inbound_newnick (sess->server, sess->server->nick, nick, TRUE, tags_data);
	server_set_name (sess->server, servname);
	ircserver_set_name (sess->server, servname);
	if (sess->type == SESS_SERVER)
		log_open_or_close (sess);
	/* reset our away status */

M src/common/notify.c => src/common/notify.c +3 -3
@@ 66,7 66,7 @@ despacify_dup (char *str)
static int
notify_netcmp (char *str, void *serv)
{
	char *net = despacify_dup (server_get_network (serv, TRUE));
	char *net = despacify_dup (ircserver_get_network (serv, TRUE));

	if (rfc_casecmp (str, net) == 0)
	{


@@ 217,7 217,7 @@ notify_announce_offline (server * serv, struct notify_per_server *servnot,
	servnot->lastoff = time (0);
	if (!quiet)
		EMIT_SIGNAL_TAGS (XP_TE_NOTIFYOFFLINE, sess, nick, serv->servername,
				  server_get_network (serv, TRUE), NULL, 0, tags_data);
				  ircserver_get_network (serv, TRUE), NULL, 0, tags_data);
	fe_notify_update (nick);
	fe_notify_update (0);
}


@@ 237,7 237,7 @@ notify_announce_online (server * serv, struct notify_per_server *servnot,
	servnot->ison = TRUE;
	servnot->laston = time (0);
	EMIT_SIGNAL_TAGS (XP_TE_NOTIFYONLINE, sess, nick, serv->servername,
			  server_get_network (serv, TRUE), NULL, 0, tags_data);
			  ircserver_get_network (serv, TRUE), NULL, 0, tags_data);
	fe_notify_update (nick);
	fe_notify_update (0);


M src/common/outbound.c => src/common/outbound.c +13 -68
@@ 75,45 75,6 @@ notc_msg (struct session *sess)
	PrintText (sess, _("Not connected. Try /server <host> [<port>]\n"));
}

static char *
random_line (char *file_name)
{
	FILE *fh;
	char buf[512];
	int lines, ran;

	if (!file_name[0])
		goto nofile;

	fh = hexchat_fopen_file (file_name, "r", 0);
	if (!fh)
	{
	 nofile:
		/* reason is not a file, an actual reason! */
		return g_strdup (file_name);
	}

	/* count number of lines in file */
	lines = 0;
	while (fgets (buf, sizeof (buf), fh))
		lines++;

	if (lines < 1)
		goto nofile;

	/* go down a random number */
	rewind (fh);
	ran = RAND_INT (lines);
	do
	{
		fgets (buf, sizeof (buf), fh);
		lines--;
	}
	while (lines > ran);
	fclose (fh);
	return g_strdup (buf);
}

void
server_sendpart (server * serv, char *channel, char *reason)
{


@@ 130,26 91,6 @@ server_sendpart (server * serv, char *channel, char *reason)
}

void
server_sendquit (session * sess)
{
	char *rea, *colrea;

	if (!sess->quitreason)
	{
		colrea = g_strdup (prefs.hex_irc_quit_reason);
		check_special_chars (colrea, FALSE);
		rea = random_line (colrea);
		g_free (colrea);
		sess->server->p_quit (sess->server, rea);
		g_free (rea);
	} else
	{
		/* reason set by /quit, /close argument */
		sess->server->p_quit (sess->server, sess->quitreason);
	}
}

void
process_data_init (char *buf, char *cmd, char *word[],
		   char *word_eol[], gboolean handle_quotes,
		   gboolean allow_escape_quotes)


@@ 1414,7 1355,8 @@ cmd_devoice (struct session *sess, char *tbuf, char *word[], char *word_eol[])
static int
cmd_discon (struct session *sess, char *tbuf, char *word[], char *word_eol[])
{
	sess->server->disconnect (sess, TRUE, -1);
	if (server_disconnect (sess->server, TRUE, -1))
		notc_msg (sess);
	return TRUE;
}



@@ 1971,10 1913,13 @@ cmd_flushq (struct session *sess, char *tbuf, char *word[], char *word_eol[])
static int
cmd_quit (struct session *sess, char *tbuf, char *word[], char *word_eol[])
{
	server *serv = sess->server;

	if (*word_eol[2])
		sess->quitreason = word_eol[2];
	sess->server->disconnect (sess, TRUE, -1);
	sess->quitreason = NULL;
		serv->quitreason = word_eol[2];
	if (server_disconnect (serv, TRUE, -1))
		notc_msg (sess);
	serv->quitreason = NULL;
	return 2;
}



@@ 1991,9 1936,9 @@ cmd_gate (struct session *sess, char *tbuf, char *word[], char *word_eol[])
#endif
		server_fill_her_up (serv);
		if (*port)
			serv->connect (serv, server_name, atoi (port), TRUE);
			server_connect (serv, server_name, atoi (port), TRUE);
		else
			serv->connect (serv, server_name, 23, TRUE);
			server_connect (serv, server_name, 23, TRUE);
		return TRUE;
	}
	return FALSE;


@@ 3565,11 3510,11 @@ cmd_server (struct session *sess, char *tbuf, char *word[], char *word_eol[])

	if (*port)
	{
		serv->connect (serv, server_name, atoi (port), FALSE);
		server_connect (serv, server_name, atoi (port), FALSE);
	} else
	{
		/* -1 for default port */
		serv->connect (serv, server_name, -1, FALSE);
		server_connect (serv, server_name, -1, FALSE);
	}

	/* try to associate this connection with a listed network */


@@ 4564,7 4509,7 @@ user_command (session * sess, char *tbuf, char *cmd, char *word[],
				  char *word_eol[])
{
	if (!auto_insert (tbuf, 2048, cmd, word, word_eol, "", sess->channel, "",
							server_get_network (sess->server, TRUE), "",
							ircserver_get_network (sess->server, TRUE), "",
							sess->server->nick, "", ""))
	{
		PrintText (sess, _("Bad arguments for user command.\n"));

M src/common/outbound.h => src/common/outbound.h +0 -1
@@ 34,7 34,6 @@ void handle_multiline (session *sess, char *cmd, int history, int nocommand);
void check_special_chars (char *cmd, int do_ascii);
void notc_msg (session *sess);
void server_sendpart (server * serv, char *channel, char *reason);
void server_sendquit (session * sess);
int menu_streq (const char *s1, const char *s2, int def);
session *open_query (server *serv, char *nick, gboolean focus_existing);
gboolean load_perform_file (session *sess, char *file);

M src/common/plugin.c => src/common/plugin.c +3 -3
@@ 918,7 918,7 @@ plugin_find_context (const char *servname, const char *channel, server *current_
	while (slist)
	{
		serv = slist->data;
		netname = server_get_network (serv, TRUE);
		netname = ircserver_get_network (serv, TRUE);

		if (servname == NULL ||
			 rfc_casecmp (servname, serv->servername) == 0 ||


@@ 1207,7 1207,7 @@ hexchat_get_info (hexchat_plugin *ph, const char *id)
		return sess->current_modes;

	case 0x6de15a2e:	/* network */
		return server_get_network (sess->server, FALSE);
		return ircserver_get_network (sess->server, FALSE);

	case 0x339763: /* nick */
		return sess->server->nick;


@@ 1483,7 1483,7 @@ hexchat_list_str (hexchat_plugin *ph, hexchat_list *xlist, const char *name)
		case 0x38b735af: /* context */
			return data;	/* this is a session * */
		case 0x6de15a2e: /* network */
			return server_get_network (((session *)data)->server, FALSE);
			return ircserver_get_network (((session *)data)->server, FALSE);
		case 0x8455e723: /* nickprefixes */
			return ((session *)data)->server->nick_prefixes;
		case 0x829689ad: /* nickmodes */

M src/common/proto-irc.c => src/common/proto-irc.c +313 -2
@@ 24,6 24,10 @@
#include <ctype.h>
#include <stdarg.h>

#define WANTSOCKET
#define WANTARPA
#include "inet.h"

#ifndef WIN32
#include <unistd.h>
#endif


@@ 235,12 239,28 @@ irc_part (server *serv, char *channel, char *reason)
}

static void
irc_quit (server *serv, char *reason)
irc_quit (server *serv)
{
	char *reason, *colrea = NULL;

	if (!serv->quitreason)
	{
		colrea = g_strdup (prefs.hex_irc_quit_reason);
		check_special_chars (colrea, FALSE);
		reason = random_line (colrea);
	} else /* reason set by /quit, /close argument */
		reason = serv->quitreason;

	if (reason[0])
		tcp_sendf (serv, "QUIT :%s\r\n", reason);
	else
		tcp_send_len (serv, "QUIT\r\n", 6);
	
	if (colrea)
	{
		g_free (colrea);
		g_free (reason);
	}
}

static void


@@ 1661,17 1681,308 @@ message_tags_data_free (message_tags_data *tags_data)
{
	g_clear_pointer (&tags_data->account, g_free);
	g_clear_pointer (&tags_data->msgid, g_free);
	g_clear_pointer (&tags_data->batchref, g_free);
}


char *
ircserver_get_network (server *serv, gboolean fallback)
{
	/* check the network list */
	if (serv->network)
		return ((ircnet *)serv->network)->name;

	/* check the network name given in 005 NETWORK=... */
	if (serv->server_session && *serv->server_session->channel)
		return serv->server_session->channel;

	if (fallback)
		return serv->servername;

	return NULL;
}

void
ircserver_set_name (server *serv, char *name)
{
	GSList *list = sess_list;
	session *sess;

	if (name[0] == 0)
		name = serv->hostname;

	/* strncpy parameters must NOT overlap */
	if (name != serv->servername)
	{
		safe_strcpy (serv->servername, name, sizeof (serv->servername));
	}

	while (list)
	{
		sess = (session *) list->data;
		if (sess->server == serv)
			fe_set_title (sess);
		list = list->next;
	}

	if (serv->server_session->type == SESS_SERVER)
	{
		if (serv->network)
		{
			safe_strcpy (serv->server_session->channel, ((ircnet *)serv->network)->name, CHANLEN);
		} else
		{
			safe_strcpy (serv->server_session->channel, name, CHANLEN);
		}
		fe_set_channel (serv->server_session);
	}
}


static void
irc_connected (server *serv)
{
	{ /* FIXME: UGLY HACK!! should be handled with a hook or something. */
		struct sockaddr_storage addr;
		int addr_len = sizeof (addr);
		guint16 port;
		ircnet *net = serv->network;
		char outbuf[512];

		if (!getsockname (serv->sok, (struct sockaddr *)&addr, &addr_len))
		{
			if (addr.ss_family == AF_INET)
				port = ntohs(((struct sockaddr_in *)&addr)->sin_port);
			else
				port = ntohs(((struct sockaddr_in6 *)&addr)->sin6_port);

			g_snprintf (outbuf, sizeof (outbuf), "IDENTD %"G_GUINT16_FORMAT" ", port);
			if (net && net->user && !(net->flags & FLAG_USE_GLOBAL))
				g_strlcat (outbuf, net->user, sizeof (outbuf));
			else
				g_strlcat (outbuf, prefs.hex_irc_user_name, sizeof (outbuf));

			handle_command (serv->server_session, outbuf, FALSE);
		}
	}

	if (!serv->no_login)
	{
		EMIT_SIGNAL (XP_TE_CONNECTED, serv->server_session, NULL, NULL, NULL,
						 NULL, 0);
		if (serv->network)
		{
			irc_login (serv,
				   (!(((ircnet *)serv->network)->flags & FLAG_USE_GLOBAL) &&
				   (((ircnet *)serv->network)->user)) ?
				     (((ircnet *)serv->network)->user) :
				     prefs.hex_irc_user_name,
				   (!(((ircnet *)serv->network)->flags & FLAG_USE_GLOBAL) &&
				   (((ircnet *)serv->network)->real)) ?
				     (((ircnet *)serv->network)->real) :
				     prefs.hex_irc_real_name);
		} else
		{
			irc_login (serv, prefs.hex_irc_user_name, prefs.hex_irc_real_name);
		}
	} else
	{
		EMIT_SIGNAL (XP_TE_SERVERCONNECTED, serv->server_session, NULL, NULL,
			     NULL, NULL, 0);
	}
	
	ircserver_set_name (serv, serv->servername);
}

static void
irc_disconnected (server *serv, int shutup, int err)
{
	GSList *list;
	session *sess;

	fe_server_event (serv, FE_SE_DISCONNECT, 0);
	
	list = sess_list;
	while (list)
	{
		sess = (struct session *) list->data;
		if (sess->server == serv)
		{
			if (!shutup || sess->type == SESS_SERVER)
				/* print "Disconnected" to each window using this server */
				EMIT_SIGNAL (XP_TE_DISCON, sess, errorstring (err), NULL, NULL, NULL, 0);

			if (!sess->channel[0] || sess->type == SESS_CHANNEL)
				clear_channel (sess);
		}
		list = list->next;
	}
}

static void
irc_ssl_message (server *serv, const char *msg)
{
	EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, (char *)msg, NULL, NULL, NULL, 0);
}

static void
irc_serverlookup (server *serv, const char *msg)
{
	fe_progressbar_start (serv->server_session);
	EMIT_SIGNAL (XP_TE_SERVERLOOKUP, serv->server_session, (char *)msg, NULL, NULL, NULL, 0);
}

static int
timeout_auto_reconnect (server *serv)
{
	if (is_server (serv))  /* make sure it hasnt been closed during the delay */
	{
		serv->recondelay_tag = 0;
							  // afaict this check will never fail
		if (!serv->connected && !serv->connecting /*&& serv->server_session*/)
		{
			server_connect (serv, serv->hostname, serv->port, FALSE);
		}
	}
	return 0;			  /* returning 0 should remove the timeout handler */
}

static void
auto_reconnect (server *serv, int send_quit, int err)
{
	session *s;
	int del;

	if (serv->server_session == NULL)
		return;

	if (prefs.hex_irc_reconnect_rejoin)
	{
		GSList *list;
		list = sess_list;
		while (list)				  /* make sure auto rejoin can work */
		{
			s = list->data;
			if (s->type == SESS_CHANNEL && s->channel[0])
			{
				strcpy (s->waitchannel, s->channel);
				strcpy (s->willjoinchannel, s->channel);
			}
			list = list->next;
		}
	}

	if (serv->connected)
		server_disconnect (serv, send_quit, err);

	del = prefs.hex_net_reconnect_delay * 1000;
	if (del < 1000)
		del = 500;				  /* so it doesn't block the gui */

#ifndef WIN32
	if (err == -1 || err == 0 || err == ECONNRESET || err == ETIMEDOUT)
#else
	if (err == -1 || err == 0 || err == WSAECONNRESET || err == WSAETIMEDOUT)
#endif
		serv->reconnect_away = serv->is_away;

	/* is this server in a reconnect delay? remove it! */
	if (serv->recondelay_tag)
	{
		fe_timeout_remove (serv->recondelay_tag);
		serv->recondelay_tag = 0;
	}

	serv->recondelay_tag = fe_timeout_add (del, timeout_auto_reconnect, serv);
	fe_server_event (serv, FE_SE_RECONDELAY, del);
}

static void
irc_connfail (server *serv, const char *msg)
{
	EMIT_SIGNAL (XP_TE_CONNFAIL, serv->server_session, (char *)msg, NULL, NULL, NULL, 0);
	
	if (!servlist_cycle (serv))
		if (prefs.hex_net_auto_reconnectonfail)
			auto_reconnect (serv, FALSE, -1);
}

static void
irc_connstop (server *serv, const char *msg)
{
	EMIT_SIGNAL (XP_TE_STOPCONNECT, serv->server_session, (char *)msg, NULL, NULL, NULL, 0);
}

static void
irc_connecting (server *serv, const char *host, const char *ip, const char *port)
{
	serv->end_of_motd = FALSE;

	EMIT_SIGNAL (XP_TE_CONNECT, serv->server_session,
		     (char *)host, (char *)ip, (char *)port, NULL, 0);
}

static void
irc_unknhost (server *serv)
{
	EMIT_SIGNAL (XP_TE_UKNHOST, serv->server_session, NULL, NULL, NULL, NULL, 0);

	if (!servlist_cycle (serv))
		if (prefs.hex_net_auto_reconnectonfail)
			auto_reconnect (serv, FALSE, -1);
}

static void
irc_readerr (server *serv, int error)
{
	if (!serv->end_of_motd)
	{
		server_disconnect (serv, FALSE, error);
		if (!servlist_cycle (serv))
		{
			if (prefs.hex_net_auto_reconnect)
				auto_reconnect (serv, FALSE, error);
		}
	} else
	{
		if (prefs.hex_net_auto_reconnect)
			auto_reconnect (serv, FALSE, error);
		else
			server_disconnect (serv, FALSE, error);
	}
}

static void
irc_serverlog (server *serv, const char *msg)
{
	PrintText (serv->server_session, (char *)msg);
}

void
proto_fill_her_up (server *serv)
{
	serv->auto_reconnect = auto_reconnect;

	serv->p_connected = irc_connected;
	serv->p_disconnected = irc_disconnected;
	serv->p_ssl_message = irc_ssl_message;
	serv->p_serverlookup = irc_serverlookup;
	serv->p_connfail = irc_connfail;
	serv->p_connstop = irc_connstop;
	serv->p_connecting = irc_connecting;
	serv->p_unknhost = irc_unknhost;
	serv->p_readerr = irc_readerr;
	serv->p_log = irc_serverlog;

	serv->p_get_network = ircserver_get_network;

	serv->p_quit = irc_quit;
	serv->p_inline = irc_inline;

	serv->p_invite = irc_invite;
	serv->p_cycle = irc_cycle;
	serv->p_ctcp = irc_ctcp;
	serv->p_nctcp = irc_nctcp;
	serv->p_quit = irc_quit;
	serv->p_kick = irc_kick;
	serv->p_part = irc_part;
	serv->p_ns_identify = irc_ns_identify;

M src/common/server.c => src/common/server.c +78 -310
@@ 63,16 63,13 @@

#ifdef USE_OPENSSL
/* local variables */
static struct session *g_sess = NULL;
static struct server *g_serv = NULL;
#endif

static GSList *away_list = NULL;
GSList *serv_list = NULL;

static void auto_reconnect (server *serv, int send_quit, int err);
static void server_disconnect (session * sess, int sendquit, int err);
static int server_cleanup (server * serv);
static void server_connect (server *serv, char *hostname, int port, int no_login);
static int  server_cleanup (server * serv);

static void
write_error (char *message, GError **error)


@@ 323,21 320,7 @@ server_read (GIOChannel *source, GIOCondition condition, server *serv)
					return TRUE;
				error = sock_error ();
			}
			if (!serv->end_of_motd)
			{
				server_disconnect (serv->server_session, FALSE, error);
				if (!servlist_cycle (serv))
				{
					if (prefs.hex_net_auto_reconnect)
						auto_reconnect (serv, FALSE, error);
				}
			} else
			{
				if (prefs.hex_net_auto_reconnect)
					auto_reconnect (serv, FALSE, error);
				else
					server_disconnect (serv->server_session, FALSE, error);
			}
			serv->p_readerr (serv, error);
			return TRUE;
		}



@@ 362,7 345,7 @@ server_read (GIOChannel *source, GIOCondition condition, server *serv)
				serv->linebuf[serv->pos] = lbuf[i];
				if (serv->pos >= (sizeof (serv->linebuf) - 1))
					fprintf (stderr,
								"*** HEXCHAT WARNING: Buffer overflow - non-compliant server!\n");
						 "*** HEXCHAT WARNING: Buffer overflow - non-compliant server!\n");
				else
					serv->pos++;
			}


@@ 372,7 355,7 @@ server_read (GIOChannel *source, GIOCondition condition, server *serv)
}

static void
server_connected (server * serv)
server_connected (server *serv)
{
	prefs.wait_on_exit = TRUE;
	serv->ping_recv = time (0);


@@ 380,32 363,9 @@ server_connected (server * serv)
	serv->connected = TRUE;
	set_nonblocking (serv->sok);
	serv->iotag = fe_input_add (serv->sok, FIA_READ|FIA_EX, server_read, serv);
	if (!serv->no_login)
	{
		EMIT_SIGNAL (XP_TE_CONNECTED, serv->server_session, NULL, NULL, NULL,
						 NULL, 0);
		if (serv->network)
		{
			serv->p_login (serv,
								(!(((ircnet *)serv->network)->flags & FLAG_USE_GLOBAL) &&
								 (((ircnet *)serv->network)->user)) ?
								(((ircnet *)serv->network)->user) :
								prefs.hex_irc_user_name,
								(!(((ircnet *)serv->network)->flags & FLAG_USE_GLOBAL) &&
								 (((ircnet *)serv->network)->real)) ?
								(((ircnet *)serv->network)->real) :
								prefs.hex_irc_real_name);
		} else
		{
			serv->p_login (serv, prefs.hex_irc_user_name, prefs.hex_irc_real_name);
		}
	} else
	{
		EMIT_SIGNAL (XP_TE_SERVERCONNECTED, serv->server_session, NULL, NULL,
						 NULL, NULL, 0);
	}

	server_set_name (serv, serv->servername);
	serv->p_connected(serv);

	fe_server_event (serv, FE_SE_CONNECT, 0);
}



@@ 473,7 433,7 @@ server_stopconnecting (server * serv)
#ifdef USE_OPENSSL
#define	SSLTMOUT	90				  /* seconds */
static void
ssl_cb_info (SSL * s, int where, int ret)
ssl_cb_info (SSL *s, int where, int ret)
{
/*	char buf[128];*/



@@ 481,14 441,14 @@ ssl_cb_info (SSL * s, int where, int ret)
	return;							  /* FIXME: make debug level adjustable in serverlist or settings */

/*	g_snprintf (buf, sizeof (buf), "%s (%d)", SSL_state_string_long (s), where);
	if (g_sess)
		EMIT_SIGNAL (XP_TE_SSLMESSAGE, g_sess, buf, NULL, NULL, NULL, 0);
	if (g_serv)
		g_serv->p_ssl_message (g_serv, buf);
	else
		fprintf (stderr, "%s\n", buf);*/
}

static int
ssl_cb_verify (int ok, X509_STORE_CTX * ctx)
ssl_cb_verify (int ok, X509_STORE_CTX *ctx)
{
	char subject[256];
	char issuer[256];


@@ 504,19 464,19 @@ ssl_cb_verify (int ok, X509_STORE_CTX * ctx)
	                   issuer, sizeof (issuer));

	g_snprintf (buf, sizeof (buf), "* Subject: %s", subject);
	EMIT_SIGNAL (XP_TE_SSLMESSAGE, g_sess, buf, NULL, NULL, NULL, 0);
	g_serv->p_ssl_message (g_serv, buf);
	g_snprintf (buf, sizeof (buf), "* Issuer: %s", issuer);
	EMIT_SIGNAL (XP_TE_SSLMESSAGE, g_sess, buf, NULL, NULL, NULL, 0);
	g_serv->p_ssl_message (g_serv, buf);

	return TRUE;
}

static int
ssl_do_connect (server * serv)
ssl_do_connect (server *serv)
{
	char buf[256]; // ERR_error_string() MUST have this size

	g_sess = serv->server_session;
	g_serv = serv;

	/* Set SNI hostname before connect */
	SSL_set_tlsext_host_name(serv->ssl, serv->hostname);


@@ 526,26 486,23 @@ ssl_do_connect (server * serv)
		char err_buf[128];
		int err;

		g_sess = NULL;
		g_serv = NULL;
		if ((err = ERR_get_error ()) > 0)
		{
			server_cleanup (serv);

			ERR_error_string (err, err_buf);
			g_snprintf (buf, sizeof (buf), "(%d) %s", err, err_buf);
			EMIT_SIGNAL (XP_TE_CONNFAIL, serv->server_session, buf, NULL,
							 NULL, NULL, 0);
			serv->p_connfail (serv, buf);

			if (ERR_GET_REASON (err) == SSL_R_WRONG_VERSION_NUMBER)
				PrintText (serv->server_session, _("Are you sure this is a SSL capable server and port?\n"));

			server_cleanup (serv);
				serv->p_log (serv, _("Are you sure this is a SSL capable server and port?\n"));

			if (prefs.hex_net_auto_reconnectonfail)
				auto_reconnect (serv, FALSE, -1);

			return (0);				  /* remove it (0) */
		}
	}
	g_sess = NULL;
	g_serv = NULL;

	if (SSL_is_init_finished (serv->ssl))
	{


@@ 557,46 514,37 @@ ssl_do_connect (server * serv)
		if (!_SSL_get_cert_info (&cert_info, serv->ssl))
		{
			g_snprintf (buf, sizeof (buf), "* Certification info:");
			EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL,
							 NULL, 0);
			serv->p_ssl_message (serv, buf);
			g_snprintf (buf, sizeof (buf), "  Subject:");
			EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL,
							 NULL, 0);
			serv->p_ssl_message (serv, buf);
			for (i = 0; cert_info.subject_word[i]; i++)
			{
				g_snprintf (buf, sizeof (buf), "    %s", cert_info.subject_word[i]);
				EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL,
								 NULL, 0);
				serv->p_ssl_message (serv, buf);
			}
			g_snprintf (buf, sizeof (buf), "  Issuer:");
			EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL,
							 NULL, 0);
			serv->p_ssl_message (serv, buf);
			for (i = 0; cert_info.issuer_word[i]; i++)
			{
				g_snprintf (buf, sizeof (buf), "    %s", cert_info.issuer_word[i]);
				EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL,
								 NULL, 0);
				serv->p_ssl_message (serv, buf);
			}
			g_snprintf (buf, sizeof (buf), "  Public key algorithm: %s (%d bits)",
						 cert_info.algorithm, cert_info.algorithm_bits);
			EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL,
							 NULL, 0);
			serv->p_ssl_message (serv, buf);
			/*if (cert_info.rsa_tmp_bits)
			{
				g_snprintf (buf, sizeof (buf),
							 "  Public key algorithm uses ephemeral key with %d bits",
							 cert_info.rsa_tmp_bits);
				EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL,
								 NULL, 0);
					    "  Public key algorithm uses ephemeral key with %d bits",
					    cert_info.rsa_tmp_bits);
				serv->p_ssl_message (serv, buf)
			}*/
			g_snprintf (buf, sizeof (buf), "  Sign algorithm %s",
						 cert_info.sign_algorithm/*, cert_info.sign_algorithm_bits*/);
			EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL,
							 NULL, 0);
			serv->p_ssl_message (serv, buf);
			g_snprintf (buf, sizeof (buf), "  Valid since %s to %s",
						 cert_info.notbefore, cert_info.notafter);
			EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL,
							 NULL, 0);
			serv->p_ssl_message (serv, buf);
		} else
		{
			g_snprintf (buf, sizeof (buf), "No Certificate");


@@ 605,14 553,12 @@ ssl_do_connect (server * serv)

		chiper_info = _SSL_get_cipher_info (serv->ssl);	/* static buffer */
		g_snprintf (buf, sizeof (buf), "* Cipher info:");
		EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL,
						 0);
		serv->p_ssl_message (serv, buf);
		g_snprintf (buf, sizeof (buf), "  Version: %s, cipher %s (%u bits)",
					 chiper_info->version, chiper_info->chiper,
					 chiper_info->chiper_bits);
		EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL,
						 0);

		serv->p_ssl_message (serv, buf);
		
		verify_error = SSL_get_verify_result (serv->ssl);
		switch (verify_error)
		{


@@ 625,14 571,14 @@ ssl_do_connect (server * serv)
					g_snprintf (buf, sizeof (buf), "* Verify E: Failed to validate hostname? (%d)%s",
							 hostname_err, serv->accept_invalid_cert ? " -- Ignored" : "");
					if (serv->accept_invalid_cert)
						EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0);
						serv->p_ssl_message (serv, buf);
					else
						goto conn_fail;
				}
				break;
			}
			/* g_snprintf (buf, sizeof (buf), "* Verify OK (?)"); */
			/* EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0); */
			/* serv->p_ssl_message (serv, buf); */
		case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
		case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
		case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:


@@ 643,8 589,7 @@ ssl_do_connect (server * serv)
				g_snprintf (buf, sizeof (buf), "* Verify E: %s.? (%d) -- Ignored",
							 X509_verify_cert_error_string (verify_error),
							 verify_error);
				EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL,
								 NULL, 0);
				serv->p_ssl_message (serv, buf);
				break;
			}
		default:


@@ 652,9 597,7 @@ ssl_do_connect (server * serv)
						 X509_verify_cert_error_string (verify_error),
						 verify_error);
conn_fail:
			EMIT_SIGNAL (XP_TE_CONNFAIL, serv->server_session, buf, NULL, NULL,
							 NULL, 0);

			serv->p_connfail (serv, buf);
			server_cleanup (serv);

			return (0);


@@ 672,13 615,9 @@ conn_fail:
		if (session && SSL_SESSION_get_time (session) + SSLTMOUT < time (NULL))
		{
			g_snprintf (buf, sizeof (buf), "SSL handshake timed out");
			EMIT_SIGNAL (XP_TE_CONNFAIL, serv->server_session, buf, NULL,
							 NULL, NULL, 0);
			serv->p_connfail (serv, buf);
			server_cleanup (serv); /* ->connecting = FALSE */

			if (prefs.hex_net_auto_reconnectonfail)
				auto_reconnect (serv, FALSE, -1);

			return (0);				  /* remove it (0) */
		}



@@ 687,70 626,6 @@ conn_fail:
}
#endif

static int
timeout_auto_reconnect (server *serv)
{
	if (is_server (serv))  /* make sure it hasnt been closed during the delay */
	{
		serv->recondelay_tag = 0;
		if (!serv->connected && !serv->connecting && serv->server_session)
		{
			server_connect (serv, serv->hostname, serv->port, FALSE);
		}
	}
	return 0;			  /* returning 0 should remove the timeout handler */
}

static void
auto_reconnect (server *serv, int send_quit, int err)
{
	session *s;
	int del;

	if (serv->server_session == NULL)
		return;

	if (prefs.hex_irc_reconnect_rejoin)
	{
		GSList *list;
		list = sess_list;
		while (list)				  /* make sure auto rejoin can work */
		{
			s = list->data;
			if (s->type == SESS_CHANNEL && s->channel[0])
			{
				strcpy (s->waitchannel, s->channel);
				strcpy (s->willjoinchannel, s->channel);
			}
			list = list->next;
		}
	}

	if (serv->connected)
		server_disconnect (serv->server_session, send_quit, err);

	del = prefs.hex_net_reconnect_delay * 1000;
	if (del < 1000)
		del = 500;				  /* so it doesn't block the gui */

#ifndef WIN32
	if (err == -1 || err == 0 || err == ECONNRESET || err == ETIMEDOUT)
#else
	if (err == -1 || err == 0 || err == WSAECONNRESET || err == WSAETIMEDOUT)
#endif
		serv->reconnect_away = serv->is_away;

	/* is this server in a reconnect delay? remove it! */
	if (serv->recondelay_tag)
	{
		fe_timeout_remove (serv->recondelay_tag);
		serv->recondelay_tag = 0;
	}

	serv->recondelay_tag = fe_timeout_add (del, timeout_auto_reconnect, serv);
	fe_server_event (serv, FE_SE_RECONDELAY, del);
}

static void
server_flush_queue (server *serv)
{


@@ 774,9 649,8 @@ server_connect_success (server *serv)
		   server_cleanup() */
		if ((err = _SSL_set_verify (serv->ctx, ssl_cb_verify)))
		{
			EMIT_SIGNAL (XP_TE_CONNFAIL, serv->server_session, err, NULL,
							 NULL, NULL, 0);
			server_cleanup (serv);	/* ->connecting = FALSE */
			serv->p_connfail (serv, err);
			return;
		}
		serv->ssl = _SSL_socket (serv->ctx, serv->sok);


@@ 800,7 674,6 @@ server_connect_success (server *serv)
static gboolean
server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
{
	session *sess = serv->server_session;
	char tbuf[128];
	char outbuf[512];
	char host[100];


@@ 812,9 685,9 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
	{
	case '0':	/* print some text */
		waitline2 (source, tbuf, sizeof tbuf);
		PrintText (serv->server_session, tbuf);
		serv->p_log (serv, tbuf);
		break;
	case '1':						  /* unknown host */
	case '1':	/* unknown host */
		server_stopconnecting (serv);
		closesocket (serv->sok4);
		if (serv->proxy_sok4 != -1)


@@ 823,12 696,9 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
			closesocket (serv->sok6);
		if (serv->proxy_sok6 != -1)
			closesocket (serv->proxy_sok6);
		EMIT_SIGNAL (XP_TE_UKNHOST, sess, NULL, NULL, NULL, NULL, 0);
		if (!servlist_cycle (serv))
			if (prefs.hex_net_auto_reconnectonfail)
				auto_reconnect (serv, FALSE, -1);
		serv->p_unknhost (serv);
		break;
	case '2':						  /* connection failed */
	case '2':	/* connection failed */
		waitline2 (source, tbuf, sizeof tbuf);
		server_stopconnecting (serv);
		closesocket (serv->sok4);


@@ 838,19 708,15 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
			closesocket (serv->sok6);
		if (serv->proxy_sok6 != -1)
			closesocket (serv->proxy_sok6);
		EMIT_SIGNAL (XP_TE_CONNFAIL, sess, errorstring (atoi (tbuf)), NULL,
						 NULL, NULL, 0);
		if (!servlist_cycle (serv))
			if (prefs.hex_net_auto_reconnectonfail)
				auto_reconnect (serv, FALSE, -1);
		serv->p_connfail (serv, errorstring (atoi (tbuf)));
		break;
	case '3':						  /* gethostbyname finished */
	case '3':	/* gethostbyname finished */
		waitline2 (source, host, sizeof host);
		waitline2 (source, ip, sizeof ip);
		waitline2 (source, outbuf, sizeof outbuf);
		EMIT_SIGNAL (XP_TE_CONNECT, sess, host, ip, outbuf, NULL, 0);
		serv->p_connecting (serv, host, ip, outbuf);
		break;
	case '4':						  /* success */
	case '4':	/* success */
		waitline2 (source, tbuf, sizeof (tbuf));
		serv->sok = atoi (tbuf);
		/* close the one we didn't end up using */


@@ 866,48 732,25 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
				closesocket (serv->proxy_sok4);
		}

		{
			struct sockaddr_storage addr;
			int addr_len = sizeof (addr);
			guint16 port;
			ircnet *net = serv->network;

			if (!getsockname (serv->sok, (struct sockaddr *)&addr, &addr_len))
			{
				if (addr.ss_family == AF_INET)
					port = ntohs(((struct sockaddr_in *)&addr)->sin_port);
				else
					port = ntohs(((struct sockaddr_in6 *)&addr)->sin6_port);

				g_snprintf (outbuf, sizeof (outbuf), "IDENTD %"G_GUINT16_FORMAT" ", port);
				if (net && net->user && !(net->flags & FLAG_USE_GLOBAL))
					g_strlcat (outbuf, net->user, sizeof (outbuf));
				else
					g_strlcat (outbuf, prefs.hex_irc_user_name, sizeof (outbuf));

				handle_command (serv->server_session, outbuf, FALSE);
			}
		}

		server_connect_success (serv);
		break;
	case '5':						  /* prefs ip discovered */
	case '5':	/* prefs ip discovered */
		waitline2 (source, tbuf, sizeof tbuf);
		prefs.local_ip = inet_addr (tbuf);
		break;
	case '7':						  /* gethostbyname (prefs.hex_net_bind_host) failed */
	case '7':	/* gethostbyname (prefs.hex_net_bind_host) failed */
		sprintf (outbuf,
					_("Cannot resolve hostname %s\nCheck your IP Settings!\n"),
					prefs.hex_net_bind_host);
		PrintText (sess, outbuf);
			 _("Cannot resolve hostname %s\nCheck your IP Settings!\n"),
			 prefs.hex_net_bind_host);
		serv->p_log (serv, outbuf);
		break;
	case '8':
		PrintText (sess, _("Proxy traversal failed.\n"));
		server_disconnect (sess, FALSE, -1);
		serv->p_log (serv, _("Proxy traversal failed.\n"));
		server_disconnect (serv, FALSE, -1);
		break;
	case '9':
		waitline2 (source, tbuf, sizeof tbuf);
		EMIT_SIGNAL (XP_TE_SERVERLOOKUP, sess, tbuf, NULL, NULL, NULL, 0);
		serv->p_serverlookup (serv, tbuf);
		break;
	}



@@ 962,7 805,6 @@ server_cleanup (server * serv)
		if (serv->proxy_sok)
			close_socket (serv->proxy_sok);
		serv->connected = FALSE;
		serv->end_of_motd = FALSE;
		return 2;
	}



@@ 977,53 819,34 @@ server_cleanup (server * serv)
	return 0;
}

static void
server_disconnect (session * sess, int sendquit, int err)
int
server_disconnect (server *serv, int sendquit, int err)
{
	server *serv = sess->server;
	GSList *list;
	char tbuf[64];
	gboolean shutup = FALSE;

	/* send our QUIT reason */
	if (sendquit && serv->connected)
	{
		server_sendquit (sess);
		serv->p_quit (serv);
	}

	fe_server_event (serv, FE_SE_DISCONNECT, 0);

	/* close all sockets & io tags */
	switch (server_cleanup (serv))
	{
	case 0:							  /* it wasn't even connected! */
		notc_msg (sess);
		return;
	case 1:							  /* it was in the process of connecting */
		sprintf (tbuf, "%d", sess->server->childpid);
		EMIT_SIGNAL (XP_TE_STOPCONNECT, sess, tbuf, NULL, NULL, NULL, 0);
		return;
	case 0:			/* it wasn't even connected! */
		return 1;
	case 1:			/* it was in the process of connecting */
		sprintf (tbuf, "%d", serv->childpid);
		serv->p_connstop (serv, tbuf);
		return 0;
	case 3:
		shutup = TRUE;	/* won't print "disconnected" in channels */
	}

	server_flush_queue (serv);

	list = sess_list;
	while (list)
	{
		sess = (struct session *) list->data;
		if (sess->server == serv)
		{
			if (!shutup || sess->type == SESS_SERVER)
				/* print "Disconnected" to each window using this server */
				EMIT_SIGNAL (XP_TE_DISCON, sess, errorstring (err), NULL, NULL, NULL, 0);

			if (!sess->channel[0] || sess->type == SESS_CHANNEL)
				clear_channel (sess);
		}
		list = list->next;
	}
	serv->p_disconnected (serv, shutup, err);

	serv->pos = 0;
	serv->motd_skipped = FALSE;


@@ 1032,6 855,8 @@ server_disconnect (session * sess, int sendquit, int err)
	serv->lag_sent = 0;

	notify_cleanup ();
	
	return 0;
}

/* send a "print text" command to the parent process - MUST END IN \n! */


@@ 1434,8 1259,8 @@ server_child (server * serv)
		}

		if (prefs.hex_net_proxy_host[0] &&
			   prefs.hex_net_proxy_type > 0 &&
			   prefs.hex_net_proxy_use != 2) /* proxy is NOT dcc-only */
		    prefs.hex_net_proxy_type > 0 &&
		    prefs.hex_net_proxy_use != 2) /* proxy is NOT dcc-only */
		{
			proxy_type = prefs.hex_net_proxy_type;
			proxy_host = g_strdup (prefs.hex_net_proxy_host);


@@ 1469,7 1294,7 @@ server_child (server * serv)
				write (serv->childwrite, "1\n", 2);
				goto xit;
			}
		} else						  /* otherwise we can just use the hostname */
		} else		/* otherwise we can just use the hostname */
			proxy_ip = g_strdup (hostname);
	} else
	{


@@ 1539,11 1364,10 @@ xit:
	/* cppcheck-suppress memleak */
}

static void
void
server_connect (server *serv, char *hostname, int port, int no_login)
{
	int pid, read_des[2];
	session *sess = serv->server_session;

#ifdef USE_OPENSSL
	if (!serv->ctx && serv->use_ssl)


@@ 1571,11 1395,9 @@ server_connect (server *serv, char *hostname, int port, int no_login)
	}

	if (serv->connected || serv->connecting || serv->recondelay_tag)
		server_disconnect (sess, TRUE, -1);

	fe_progressbar_start (sess);
		server_disconnect (serv, TRUE, -1);

	EMIT_SIGNAL (XP_TE_SERVERLOOKUP, sess, hostname, NULL, NULL, NULL, 0);
	serv->p_serverlookup (serv, hostname);

	safe_strcpy (serv->servername, hostname, sizeof (serv->servername));
	/* overlap illegal in strncpy */


@@ 1590,7 1412,7 @@ server_connect (server *serv, char *hostname, int port, int no_login)

		/* first try network specific cert/key */
		cert_file = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "certs" G_DIR_SEPARATOR_S "%s.pem",
					 get_xdir (), server_get_network (serv, TRUE));
					 get_xdir (), serv->p_get_network (serv, TRUE));
		if (SSL_CTX_use_certificate_file (serv->ctx, cert_file, SSL_FILETYPE_PEM) == 1)
		{
			if (SSL_CTX_use_PrivateKey_file (serv->ctx, cert_file, SSL_FILETYPE_PEM) == 1)


@@ 1673,11 1495,8 @@ server_connect (server *serv, char *hostname, int port, int no_login)
void
server_fill_her_up (server *serv)
{
	serv->connect = server_connect;
	serv->disconnect = server_disconnect;
	serv->cleanup = server_cleanup;
	serv->flush_queue = server_flush_queue;
	serv->auto_reconnect = auto_reconnect;

	proto_fill_her_up (serv);
}


@@ 1795,65 1614,14 @@ server_set_defaults (server *serv)
	serv->have_accnotify = FALSE;
	serv->have_extjoin = FALSE;
	serv->have_account_tag = FALSE;
	serv->have_echo_message = FALSE;
	serv->have_message_tags = FALSE;
	serv->have_server_time = FALSE;
	serv->have_sasl = FALSE;
	serv->have_except = FALSE;
	serv->have_invite = FALSE;
}

char *
server_get_network (server *serv, gboolean fallback)
{
	/* check the network list */
	if (serv->network)
		return ((ircnet *)serv->network)->name;

	/* check the network name given in 005 NETWORK=... */
	if (serv->server_session && *serv->server_session->channel)
		return serv->server_session->channel;

	if (fallback)
		return serv->servername;

	return NULL;
}

void
server_set_name (server *serv, char *name)
{
	GSList *list = sess_list;
	session *sess;

	if (name[0] == 0)
		name = serv->hostname;

	/* strncpy parameters must NOT overlap */
	if (name != serv->servername)
	{
		safe_strcpy (serv->servername, name, sizeof (serv->servername));
	}

	while (list)
	{
		sess = (session *) list->data;
		if (sess->server == serv)
			fe_set_title (sess);
		list = list->next;
	}

	if (serv->server_session->type == SESS_SERVER)
	{
		if (serv->network)
		{
			safe_strcpy (serv->server_session->channel, ((ircnet *)serv->network)->name, CHANLEN);
		} else
		{
			safe_strcpy (serv->server_session->channel, name, CHANLEN);
		}
		fe_set_channel (serv->server_session);
	}
}

struct away_msg *
server_away_find_message (server *serv, char *nick)
{

M src/common/server.h => src/common/server.h +5 -2
@@ 32,9 32,12 @@ int is_server (server *serv);
void server_fill_her_up (server *serv);
void server_set_encoding (server *serv, char *new_encoding);
void server_set_defaults (server *serv);
char *server_get_network (server *serv, gboolean fallback);
void server_set_name (server *serv, char *name);
void server_free (server *serv);
void server_connect (server *serv, char *hostname, int port, int no_login);
int server_disconnect (server *serv, int sendquit, int err);

char *ircserver_get_network (server *serv, gboolean fallback);
void ircserver_set_name (server *serv, char *name);

void server_away_save_message (server *serv, char *nick, char *msg);
struct away_msg *server_away_find_message (server *serv, char *nick);

M src/common/servlist.c => src/common/servlist.c +3 -3
@@ 433,15 433,15 @@ servlist_connect (session *sess, ircnet *net, gboolean join)
#ifdef USE_OPENSSL
			serv->use_ssl = TRUE;
#endif
			serv->connect (serv, ircserv->hostname, atoi (port + 2), FALSE);
			server_connect (serv, ircserv->hostname, atoi (port + 2), FALSE);
		} else
		{
			serv->connect (serv, ircserv->hostname, atoi (port + 1), FALSE);
			server_connect (serv, ircserv->hostname, atoi (port + 1), FALSE);
		}

		*port = '/';
	} else
		serv->connect (serv, ircserv->hostname, -1, FALSE);
		server_connect (serv, ircserv->hostname, -1, FALSE);

	server_set_encoding (serv, net->encoding);
}

M src/common/text.c => src/common/text.c +5 -5
@@ 76,7 76,7 @@ scrollback_get_filename (session *sess)
{
	char *net, *chan, *buf, *ret = NULL;

	net = server_get_network (sess->server, FALSE);
	net = ircserver_get_network (sess->server, FALSE);
	if (!net)
		return NULL;



@@ 607,11 607,11 @@ log_open (session *sess)

	log_close (sess);
	sess->logfd = log_open_file (sess->server->servername, sess->channel,
										  server_get_network (sess->server, FALSE));
				     ircserver_get_network (sess->server, FALSE));

	if (!log_error && sess->logfd == -1)
	{
		char *filename = log_create_pathname (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE));
		char *filename = log_create_pathname (sess->server->servername, sess->channel, ircserver_get_network (sess->server, FALSE));
		char *message = g_strdup_printf (_("* Can't open log file(s) for writing. Check the\npermissions on %s"), filename);

		g_free (filename);


@@ 696,7 696,7 @@ log_write (session *sess, char *text, time_t ts)
	}

	/* change to a different log file? */
	file = log_create_pathname (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE));
	file = log_create_pathname (sess->server->servername, sess->channel, ircserver_get_network (sess->server, FALSE));
	if (file)
	{
		if (g_access (file, F_OK) != 0)


@@ 706,7 706,7 @@ log_write (session *sess, char *text, time_t ts)
				close (sess->logfd);
			}

			sess->logfd = log_open_file (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE));
			sess->logfd = log_open_file (sess->server->servername, sess->channel, ircserver_get_network (sess->server, FALSE));
		}

		g_free (file);

M src/common/util.c => src/common/util.c +41 -0
@@ 47,6 47,7 @@
#include "hexchatc.h"
#include <ctype.h>
#include "util.h"
#include "cfgfiles.h"

#if defined (__FreeBSD__) || defined (__APPLE__)
#include <sys/sysctl.h>


@@ 1555,3 1556,43 @@ strftime_utf8 (char *dest, gsize destsize, const char *format, time_t time)
	g_date_free (date);
	return result;
}

char *
random_line (char *file_name)
{
	FILE *fh;
	char buf[512];
	int lines, ran;

	if (!file_name[0])
		goto nofile;

	fh = hexchat_fopen_file (file_name, "r", 0);
	if (!fh)
	{
	 nofile:
		/* reason is not a file, an actual reason! */
		return g_strdup (file_name);
	}

	/* count number of lines in file */
	lines = 0;
	while (fgets (buf, sizeof (buf), fh))
		lines++;

	if (lines < 1)
		goto nofile;

	/* go down a random number */
	rewind (fh);
	ran = RAND_INT (lines);
	do
	{
		fgets (buf, sizeof (buf), fh);
		lines--;
	}
	while (lines > ran);
	fclose (fh);
	return g_strdup (buf);
}


M src/common/util.h => src/common/util.h +1 -0
@@ 80,4 80,5 @@ char *encode_sasl_pass_plain (char *user, char *pass);
char *challengeauth_response (const char *username, const char *password, const char *challenge);
size_t strftime_validated (char *dest, size_t destsize, const char *format, const struct tm *time);
gsize strftime_utf8 (char *dest, gsize destsize, const char *format, time_t time);
char *random_line (char *file_name);
#endif

M src/fe-gtk/chanlist.c => src/fe-gtk/chanlist.c +1 -1
@@ 718,7 718,7 @@ chanlist_opengui (server *serv, int do_refresh)
	}

	g_snprintf (tbuf, sizeof tbuf, _("Channel List (%s) - %s"),
				 server_get_network (serv, TRUE), _(DISPLAY_NAME));
		    ircserver_get_network (serv, TRUE), _(DISPLAY_NAME));

	serv->gui->chanlist_pending_rows = NULL;
	serv->gui->chanlist_tag = 0;

M src/fe-gtk/joind.c => src/fe-gtk/joind.c +1 -1
@@ 160,7 160,7 @@ joind_show_dialog (server *serv)
	gtk_box_pack_start (GTK_BOX (hbox1), vbox2, TRUE, TRUE, 0);

	g_snprintf (buf2, sizeof (buf2), _("Connection to %s complete."),
				 server_get_network (serv, TRUE));
		    ircserver_get_network (serv, TRUE));
	g_snprintf (buf, sizeof (buf), "\n<b>%s</b>", buf2);
	label = gtk_label_new (buf);
	gtk_widget_show (label);

M src/fe-gtk/maingui.c => src/fe-gtk/maingui.c +18 -18
@@ 395,26 395,26 @@ fe_set_title (session *sess)
	{
	case SESS_DIALOG:
		g_snprintf (tbuf, sizeof (tbuf), "%s %s @ %s - %s",
					 _("Dialog with"), sess->channel, server_get_network (sess->server, TRUE),
					 _(DISPLAY_NAME));
			    _("Dialog with"), sess->channel, ircserver_get_network (sess->server, TRUE),
			    _(DISPLAY_NAME));
		break;
	case SESS_SERVER:
		g_snprintf (tbuf, sizeof (tbuf), "%s%s%s - %s",
					 prefs.hex_gui_win_nick ? sess->server->nick : "",
					 prefs.hex_gui_win_nick ? " @ " : "", server_get_network (sess->server, TRUE),
			    prefs.hex_gui_win_nick ? sess->server->nick : "",
			    prefs.hex_gui_win_nick ? " @ " : "", ircserver_get_network (sess->server, TRUE),
					 _(DISPLAY_NAME));
		break;
	case SESS_CHANNEL:
		/* don't display keys in the titlebar */
			g_snprintf (tbuf, sizeof (tbuf),
					 "%s%s%s / %s%s%s%s - %s",
					 prefs.hex_gui_win_nick ? sess->server->nick : "",
					 prefs.hex_gui_win_nick ? " @ " : "",
					 server_get_network (sess->server, TRUE), sess->channel,
					 prefs.hex_gui_win_modes && sess->current_modes ? " (" : "",
					 prefs.hex_gui_win_modes && sess->current_modes ? sess->current_modes : "",
					 prefs.hex_gui_win_modes && sess->current_modes ? ")" : "",
					 _(DISPLAY_NAME));
				    "%s%s%s / %s%s%s%s - %s",
				    prefs.hex_gui_win_nick ? sess->server->nick : "",
				    prefs.hex_gui_win_nick ? " @ " : "",
				    ircserver_get_network (sess->server, TRUE), sess->channel,
				    prefs.hex_gui_win_modes && sess->current_modes ? " (" : "",
				    prefs.hex_gui_win_modes && sess->current_modes ? sess->current_modes : "",
				    prefs.hex_gui_win_modes && sess->current_modes ? ")" : "",
				    _(DISPLAY_NAME));
		if (prefs.hex_gui_win_ucount)
		{
			g_snprintf (tbuf + strlen (tbuf), 9, " (%d)", sess->total);


@@ 423,9 423,9 @@ fe_set_title (session *sess)
	case SESS_NOTICES:
	case SESS_SNOTICES:
		g_snprintf (tbuf, sizeof (tbuf), "%s%s%s (notices) - %s",
					 prefs.hex_gui_win_nick ? sess->server->nick : "",
					 prefs.hex_gui_win_nick ? " @ " : "", server_get_network (sess->server, TRUE),
					 _(DISPLAY_NAME));
			    prefs.hex_gui_win_nick ? sess->server->nick : "",
			    prefs.hex_gui_win_nick ? " @ " : "", ircserver_get_network (sess->server, TRUE),
			    _(DISPLAY_NAME));
		break;
	default:
	def:


@@ 955,7 955,7 @@ mg_populate (session *sess)
	gtk_widget_set_sensitive (gui->menu_item[MENU_ID_AWAY], sess->server->connected);
	gtk_widget_set_sensitive (gui->menu_item[MENU_ID_JOIN], sess->server->end_of_motd);
	gtk_widget_set_sensitive (gui->menu_item[MENU_ID_DISCONNECT],
									  sess->server->connected || sess->server->recondelay_tag);
				  sess->server->connected || sess->server->recondelay_tag);

	mg_set_topic_tip (sess);



@@ 2129,8 2129,8 @@ mg_dialog_button_cb (GtkWidget *wid, char *cmd)
		host = topic + 1;

	auto_insert (buf, sizeof (buf), cmd, 0, 0, "", "", "",
					 server_get_network (current_sess->server, TRUE), host, "",
					 current_sess->channel, "");
		     ircserver_get_network (current_sess->server, TRUE), host, "",
		     current_sess->channel, "");

	handle_command (current_sess, buf, TRUE);


M src/fe-gtk/menu.c => src/fe-gtk/menu.c +2 -2
@@ 140,8 140,8 @@ nick_command_parse (session *sess, char *cmd, char *nick, char *allnick)
	buf = g_malloc (len);

	auto_insert (buf, len, cmd, 0, 0, allnick, sess->channel, "",
					 server_get_network (sess->server, TRUE), host,
					 sess->server->nick, nick, account);
		     ircserver_get_network (sess->server, TRUE), host,
		     sess->server->nick, nick, account);

	nick_command (sess, buf);


M src/fe-gtk/notifygui.c => src/fe-gtk/notifygui.c +1 -1
@@ 217,7 217,7 @@ notify_gui_update (void)
				{
					if (servcount > 0)
						name = "";
					server = server_get_network (servnot->server, TRUE);
					server = ircserver_get_network (servnot->server, TRUE);

					g_snprintf (agobuf, sizeof (agobuf), _("%d minutes ago"), (int)(time (0) - lastseen) / 60);
					seen = agobuf;