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 => +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;