From bf788d753ac51adb7dae9b517b2a6a7190cc4d32 Mon Sep 17 00:00:00 2001 From: Aleteoryx Date: Sun, 27 Jul 2025 18:49:29 -0400 Subject: [PATCH] remove all mentions of struct session from server.c --- src/common/chanopt.c | 6 +- src/common/ctcp.c | 2 +- src/common/hexchat.c | 2 +- src/common/hexchat.h | 19 +- src/common/inbound.c | 2 +- src/common/notify.c | 6 +- src/common/outbound.c | 81 ++------- src/common/outbound.h | 1 - src/common/plugin.c | 6 +- src/common/proto-irc.c | 315 ++++++++++++++++++++++++++++++++- src/common/server.c | 388 +++++++++-------------------------------- src/common/server.h | 7 +- src/common/servlist.c | 6 +- src/common/text.c | 10 +- src/common/util.c | 41 +++++ src/common/util.h | 1 + src/fe-gtk/chanlist.c | 2 +- src/fe-gtk/joind.c | 2 +- src/fe-gtk/maingui.c | 36 ++-- src/fe-gtk/menu.c | 4 +- src/fe-gtk/notifygui.c | 2 +- 21 files changed, 510 insertions(+), 429 deletions(-) diff --git a/src/common/chanopt.c b/src/common/chanopt.c index 67cb46cf50ae331231b31d4bff67abd33bb34e6a..30b330a5351e49532749a632562663b97c875528 100644 --- a/src/common/chanopt.c +++ b/src/common/chanopt.c @@ -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) : _(""), + sess->server->network ? ircserver_get_network (sess->server, TRUE) : _(""), _("Channel"), sess->session_name[0] ? sess->session_name : _("")); @@ -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; diff --git a/src/common/ctcp.c b/src/common/ctcp.c index facc94d712bd7ed857c3f8710e030df55433b37c..61b22b9b921836697f1f4885b724caba7dbbd960 100644 --- a/src/common/ctcp.c +++ b/src/common/ctcp.c @@ -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); } diff --git a/src/common/hexchat.c b/src/common/hexchat.c index e482b008ccb58dc221b34b55d373bd7054bda715..8089cdd102db3480e7636ab8442bcaa4c836ce06 100644 --- a/src/common/hexchat.c +++ b/src/common/hexchat.c @@ -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 diff --git a/src/common/hexchat.h b/src/common/hexchat.h index de8958afebc68b5a16dae82a27f9d22f14c8c30b..38c5bb796ac094becbf3216da7cc65f87ecbca01 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -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 */ diff --git a/src/common/inbound.c b/src/common/inbound.c index 1c7cfe9361cee1ddfa8c69470b1b1d6fbd9fc054..3cb6b5e86eaa4fdd322b36c098a535aa74209f15 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -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 */ diff --git a/src/common/notify.c b/src/common/notify.c index 4f0b260b95ba658ce49d41c4983c799fc032e610..bf1ad825f59bccfbd62da9a8066237b54bb748af 100644 --- a/src/common/notify.c +++ b/src/common/notify.c @@ -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); diff --git a/src/common/outbound.c b/src/common/outbound.c index a52625f6a09c87f152ee09e308257691e9b3cc3c..ee620c874418bd341126603691309bb5140cf497 100644 --- a/src/common/outbound.c +++ b/src/common/outbound.c @@ -75,45 +75,6 @@ notc_msg (struct session *sess) PrintText (sess, _("Not connected. Try /server []\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) { @@ -129,26 +90,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, @@ -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")); diff --git a/src/common/outbound.h b/src/common/outbound.h index 490a58caba3caec29c04f0168ce1adeaf159772f..7f79a177452d4e2a33957544a775e0d74b3e9391 100644 --- a/src/common/outbound.h +++ b/src/common/outbound.h @@ -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); diff --git a/src/common/plugin.c b/src/common/plugin.c index 536f376d9a939fa8ae56d596b90f849afe83c5dd..5d9f16efb65d6d68aee4aaafbe0f03a6b7a44085 100644 --- a/src/common/plugin.c +++ b/src/common/plugin.c @@ -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 */ diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index 7d708c3090570118bf513f7caf7a26196220b9e0..6ae03d186d1e68abd2d59820bfac99b9df16aa0d 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -24,6 +24,10 @@ #include #include +#define WANTSOCKET +#define WANTARPA +#include "inet.h" + #ifndef WIN32 #include #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; diff --git a/src/common/server.c b/src/common/server.c index c78ce900395085a4b441711d086f6d5c341725be..e276c149ab9fc759345f86876c9b40c7c0ecfd16 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -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) { diff --git a/src/common/server.h b/src/common/server.h index ff8ef4047ee66ae2f9d535e7c3f5ed53a42889cd..88726cf394f2a547c905734077fceee6de53416d 100644 --- a/src/common/server.h +++ b/src/common/server.h @@ -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); diff --git a/src/common/servlist.c b/src/common/servlist.c index 1f29bb32d50a7a9b0d4f65a73cdfb87199f63b21..31cf50e889b9e75177842ebc57aecee8151d27ef 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -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); } diff --git a/src/common/text.c b/src/common/text.c index 460a0c49a3da4f28a09dcd478bd4deb12696cb0d..12b8ad1580d8869b99fa2ded6cd03a9b77851697 100644 --- a/src/common/text.c +++ b/src/common/text.c @@ -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); diff --git a/src/common/util.c b/src/common/util.c index bd920cae44d05d101846d895742b92cdabefe81e..41ab1d6fdc356575bfc42f171a3cd9594830b8e9 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -47,6 +47,7 @@ #include "hexchatc.h" #include #include "util.h" +#include "cfgfiles.h" #if defined (__FreeBSD__) || defined (__APPLE__) #include @@ -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); +} + diff --git a/src/common/util.h b/src/common/util.h index fcb238345ee7ee3677b447122fd813f020bd3911..f2be7771696e3d2d42b6fe43311e5e87fdb9cff0 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -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 diff --git a/src/fe-gtk/chanlist.c b/src/fe-gtk/chanlist.c index abf62843a0e981bff54a66564cd00ef369c88204..6538cf821049985caf3aa2a75ccfc7332db80c22 100644 --- a/src/fe-gtk/chanlist.c +++ b/src/fe-gtk/chanlist.c @@ -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; diff --git a/src/fe-gtk/joind.c b/src/fe-gtk/joind.c index ce3cbcaeca8f26a32ad0906a29c78d754ffb2cfd..7715197a93dc8b5220ec0285ffd26cba54bb088c 100644 --- a/src/fe-gtk/joind.c +++ b/src/fe-gtk/joind.c @@ -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%s", buf2); label = gtk_label_new (buf); gtk_widget_show (label); diff --git a/src/fe-gtk/maingui.c b/src/fe-gtk/maingui.c index 1c14b6aef69a3f64ae216880b98394ec6da649b1..1e76fa97c4410078393fc23b415dea509e8db80c 100644 --- a/src/fe-gtk/maingui.c +++ b/src/fe-gtk/maingui.c @@ -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); diff --git a/src/fe-gtk/menu.c b/src/fe-gtk/menu.c index 07183154d164eb2a8654d165b0107f00d1bf0c2a..04420562f9e64c1c6617778c6cd183922ee6037f 100644 --- a/src/fe-gtk/menu.c +++ b/src/fe-gtk/menu.c @@ -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); diff --git a/src/fe-gtk/notifygui.c b/src/fe-gtk/notifygui.c index 38b35eb9750601fc45e8a11c57e098c407747f36..790e1bde4d3ebfe243c11d40e6dc22fee7448a94 100644 --- a/src/fe-gtk/notifygui.c +++ b/src/fe-gtk/notifygui.c @@ -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;