diff options
author | SoniEx2 <endermoneymod@gmail.com> | 2021-05-27 20:39:07 -0300 |
---|---|---|
committer | SoniEx2 <endermoneymod@gmail.com> | 2021-05-27 20:39:07 -0300 |
commit | 5571d277b93b62c73568b78c652c85b2e8e95183 (patch) | |
tree | 0d97d65058e31ccdeab4006384442a8e378d5f06 /src/common | |
parent | f58165fd33919951e2ca594c6f19a785420fc4f9 (diff) | |
parent | 7f8b0a19cff46f7d27451fb9942eea5018f0c5b5 (diff) |
Merge upstream changes
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/chanopt.c | 2 | ||||
-rw-r--r-- | src/common/common.vcxproj | 2 | ||||
-rw-r--r-- | src/common/dcc.c | 8 | ||||
-rw-r--r-- | src/common/dcc.h | 2 | ||||
-rw-r--r-- | src/common/hexchat.c | 1 | ||||
-rw-r--r-- | src/common/hexchat.h | 14 | ||||
-rw-r--r-- | src/common/inbound.c | 36 | ||||
-rw-r--r-- | src/common/inbound.h | 2 | ||||
-rw-r--r-- | src/common/meson.build | 5 | ||||
-rw-r--r-- | src/common/modes.c | 4 | ||||
-rw-r--r-- | src/common/outbound.c | 2 | ||||
-rw-r--r-- | src/common/plugin.c | 119 | ||||
-rw-r--r-- | src/common/proto-irc.c | 65 | ||||
-rw-r--r-- | src/common/proto-irc.h | 6 | ||||
-rw-r--r-- | src/common/server.c | 56 | ||||
-rw-r--r-- | src/common/servlist.c | 61 | ||||
-rw-r--r-- | src/common/text.c | 7 | ||||
-rw-r--r-- | src/common/textevents.in | 6 | ||||
-rw-r--r-- | src/common/url.c | 2 | ||||
-rw-r--r-- | src/common/userlist.c | 17 |
20 files changed, 294 insertions, 123 deletions
diff --git a/src/common/chanopt.c b/src/common/chanopt.c index 1870c99c..67cb46cf 100644 --- a/src/common/chanopt.c +++ b/src/common/chanopt.c @@ -58,6 +58,7 @@ typedef struct static const channel_options chanopt[] = { + {"alert_balloon", NULL, S_F(alert_balloon)}, {"alert_beep", "BEEP", S_F(alert_beep)}, {"alert_taskbar", NULL, S_F(alert_taskbar)}, {"alert_tray", "TRAY", S_F(alert_tray)}, @@ -182,6 +183,7 @@ typedef struct { /* Per-Channel Alerts */ /* use a byte, because we need a pointer to each element */ + guint8 alert_balloon; guint8 alert_beep; guint8 alert_taskbar; guint8 alert_tray; diff --git a/src/common/common.vcxproj b/src/common/common.vcxproj index 33a883bf..bc191f43 100644 --- a/src/common/common.vcxproj +++ b/src/common/common.vcxproj @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v142</PlatformToolset> <ConfigurationType>StaticLibrary</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> diff --git a/src/common/dcc.c b/src/common/dcc.c index 51f6d661..df129e68 100644 --- a/src/common/dcc.c +++ b/src/common/dcc.c @@ -1618,13 +1618,13 @@ dcc_accept (GIOChannel *source, GIOCondition condition, struct DCC *dcc) } guint32 -dcc_get_my_address (void) /* the address we'll tell the other person */ +dcc_get_my_address (session *sess) /* the address we'll tell the other person */ { struct hostent *dns_query; guint32 addr = 0; - if (prefs.hex_dcc_ip_from_server && prefs.dcc_ip) - addr = prefs.dcc_ip; + if (prefs.hex_dcc_ip_from_server && sess->server->dcc_ip) + addr = sess->server->dcc_ip; else if (prefs.hex_dcc_ip[0]) { dns_query = gethostbyname ((const char *) prefs.hex_dcc_ip); @@ -1710,7 +1710,7 @@ dcc_listen_init (struct DCC *dcc, session *sess) /*if we have a dcc_ip, we use that, so the remote client can connect*/ /*else we try to take an address from hex_dcc_ip*/ /*if something goes wrong we tell the client to connect to our LAN ip*/ - dcc->addr = dcc_get_my_address (); + dcc->addr = dcc_get_my_address (sess); /*if nothing else worked we use the address we bound to*/ if (dcc->addr == 0) diff --git a/src/common/dcc.h b/src/common/dcc.h index 379385e6..74028205 100644 --- a/src/common/dcc.h +++ b/src/common/dcc.h @@ -124,7 +124,7 @@ void dcc_chat (session *sess, char *nick, int passive); void handle_dcc (session *sess, char *nick, char *word[], char *word_eol[], const message_tags_data *tags_data); void dcc_show_list (session *sess); -guint32 dcc_get_my_address (void); +guint32 dcc_get_my_address (session *sess); void dcc_get_with_destfile (struct DCC *dcc, char *utf8file); #endif diff --git a/src/common/hexchat.c b/src/common/hexchat.c index 347cf1ce..9be2e56d 100644 --- a/src/common/hexchat.c +++ b/src/common/hexchat.c @@ -493,6 +493,7 @@ session_new (server *serv, char *from, int type, int focus) sess->logfd = -1; sess->type = type; + sess->alert_balloon = SET_DEFAULT; sess->alert_beep = SET_DEFAULT; sess->alert_taskbar = SET_DEFAULT; sess->alert_tray = SET_DEFAULT; diff --git a/src/common/hexchat.h b/src/common/hexchat.h index 8c4a6a41..d8effa1f 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -75,7 +75,7 @@ #define DOMAINLEN 100 #define NICKLEN 64 /* including the NULL, so 63 really */ #define CHANLEN 300 -#define PDIWORDS 32 +#define PDIWORDS 32 #define USERNAMELEN 10 #define HIDDEN_CHAR 8 /* invisible character for xtext */ @@ -301,8 +301,8 @@ struct hexchatprefs char hex_irc_user_name[127]; char hex_net_bind_host[127]; char hex_net_proxy_host[64]; - char hex_net_proxy_pass[32]; - char hex_net_proxy_user[32]; + char hex_net_proxy_pass[256]; + char hex_net_proxy_user[256]; char hex_stamp_log_format[64]; char hex_stamp_text_format[64]; char hex_text_background[PATHLEN + 1]; @@ -313,7 +313,6 @@ struct hexchatprefs /* these are the private variables */ guint32 local_ip; - guint32 dcc_ip; unsigned int wait_on_exit; /* wait for logs to be flushed to disk IF we're connected */ @@ -364,6 +363,7 @@ typedef struct session { /* Per-Channel Alerts */ /* use a byte, because we need a pointer to each element */ + guint8 alert_balloon; guint8 alert_beep; guint8 alert_taskbar; guint8 alert_tray; @@ -482,6 +482,10 @@ typedef struct server int proxy_sok4; int proxy_sok6; int id; /* unique ID number (for plugin API) */ + + /* dcc_ip moved from hexchatprefs to make it per-server */ + guint32 dcc_ip; + #ifdef USE_OPENSSL SSL_CTX *ctx; SSL *ssl; @@ -566,6 +570,7 @@ typedef struct server unsigned int have_idmsg:1; /* freenode's IDENTIFY-MSG */ unsigned int have_accnotify:1; /* cap account-notify */ unsigned int have_extjoin:1; /* cap extended-join */ + unsigned int have_account_tag:1; /* cap account-tag */ unsigned int have_server_time:1; /* cap server-time */ unsigned int have_sasl:1; /* SASL capability */ unsigned int have_except:1; /* ban exemptions +e */ @@ -575,6 +580,7 @@ typedef struct server unsigned int sasl_mech; /* mechanism for sasl auth */ unsigned int sent_capend:1; /* have sent CAP END yet */ unsigned int waiting_on_cap:1; /* waiting on another line of CAP LS */ + unsigned int waiting_on_sasl:1; /* waiting on sasl */ #ifdef USE_OPENSSL unsigned int use_ssl:1; /* is server SSL capable? */ unsigned int accept_invalid_cert:1;/* ignore result of server's cert. verify */ diff --git a/src/common/inbound.c b/src/common/inbound.c index fb8eb511..7175b2ae 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -815,7 +815,9 @@ inbound_topictime (server *serv, char *chan, char *nick, time_t stamp, if (!sess) sess = serv->server_session; - tim[24] = 0; /* get rid of the \n */ + if (tim != NULL) + tim[24] = 0; /* get rid of the \n */ + EMIT_SIGNAL_TIMESTAMP (XP_TE_TOPICDATE, sess, chan, nick, tim, NULL, 0, tags_data->timestamp); } @@ -1420,7 +1422,7 @@ inbound_foundip (session *sess, char *ip, const message_tags_data *tags_data) HostAddr = gethostbyname (ip); if (HostAddr) { - prefs.dcc_ip = ((struct in_addr *) HostAddr->h_addr)->s_addr; + sess->server->dcc_ip = ((struct in_addr *) HostAddr->h_addr)->s_addr; EMIT_SIGNAL_TIMESTAMP (XP_TE_FOUNDIP, sess->server->server_session, inet_ntoa (*((struct in_addr *) HostAddr->h_addr)), NULL, NULL, NULL, 0, tags_data->timestamp); @@ -1489,7 +1491,7 @@ inbound_banlist (session *sess, time_t stamp, char *chan, char *mask, server *serv = sess->server; char *nl; - if (stamp <= 0) + if (stamp <= 0 || time_str == NULL) { time_str = ""; } @@ -1669,6 +1671,8 @@ inbound_toggle_caps (server *serv, const char *extensions_str, gboolean enable) serv->have_server_time = enable; else if (!strcmp (extension, "away-notify")) serv->have_awaynotify = enable; + else if (!strcmp (extension, "account-tag")) + serv->have_account_tag = enable; else if (!strcmp (extension, "sasl")) { serv->have_sasl = enable; @@ -1722,6 +1726,9 @@ static const char * const supported_caps[] = { "userhost-in-names", "cap-notify", "chghost", + "setname", + "invite-notify", + "account-tag", /* ZNC */ "znc.in/server-time-iso", @@ -1768,7 +1775,6 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str, { char buffer[500]; /* buffer for requesting capabilities and emitting the signal */ gboolean want_cap = FALSE; /* format the CAP REQ string based on previous capabilities being requested or not */ - gboolean want_sasl = FALSE; /* CAP END shouldn't be sent when SASL is requested, it needs further responses */ char **extensions; int i; @@ -1806,7 +1812,7 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str, /* if the SASL password is set AND auth mode is set to SASL, request SASL auth */ if (!g_strcmp0 (extension, "sasl") && ((serv->loginmethod == LOGIN_SASL && strlen (serv->password) != 0) - || (serv->loginmethod == LOGIN_SASLEXTERNAL && serv->have_cert))) + || serv->loginmethod == LOGIN_SASLEXTERNAL)) { if (value) { @@ -1816,7 +1822,7 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str, serv->sasl_mech = sasl_mech; } want_cap = TRUE; - want_sasl = TRUE; + serv->waiting_on_sasl = TRUE; g_strlcat (buffer, "sasl ", sizeof(buffer)); continue; } @@ -1842,7 +1848,7 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str, tags_data->timestamp); tcp_sendf (serv, "%s\r\n", g_strchomp (buffer)); } - if (!want_sasl && !serv->waiting_on_cap) + if (!serv->waiting_on_sasl && !serv->waiting_on_cap) { /* if we use SASL, CAP END is dealt via raw numerics */ serv->sent_capend = TRUE; @@ -1851,13 +1857,25 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str, } void -inbound_cap_nak (server *serv, const message_tags_data *tags_data) +inbound_cap_nak (server *serv, char *extensions_str, const message_tags_data *tags_data) { - if (!serv->waiting_on_cap && !serv->sent_capend) + char **extensions; + int i; + + extensions = g_strsplit (extensions_str, " ", 0); + for (i=0; extensions[i]; i++) + { + if (!g_strcmp0 (extensions[i], "sasl")) + serv->waiting_on_sasl = FALSE; + } + + if (!serv->waiting_on_cap && !serv->waiting_on_sasl && !serv->sent_capend) { serv->sent_capend = TRUE; tcp_send_len (serv, "CAP END\r\n", 9); } + + g_strfreev (extensions); } void diff --git a/src/common/inbound.h b/src/common/inbound.h index 83e78d5d..6e7c171f 100644 --- a/src/common/inbound.h +++ b/src/common/inbound.h @@ -92,7 +92,7 @@ void inbound_cap_ack (server *serv, char *nick, char *extensions, const message_tags_data *tags_data); void inbound_cap_ls (server *serv, char *nick, char *extensions, const message_tags_data *tags_data); -void inbound_cap_nak (server *serv, const message_tags_data *tags_data); +void inbound_cap_nak (server *serv, char *extensions, const message_tags_data *tags_data); void inbound_cap_list (server *serv, char *nick, char *extensions, const message_tags_data *tags_data); void inbound_cap_del (server *serv, char *nick, char *extensions, diff --git a/src/common/meson.build b/src/common/meson.build index a0d6ce2b..492227b2 100644 --- a/src/common/meson.build +++ b/src/common/meson.build @@ -93,10 +93,6 @@ endif if get_option('with-plugin') common_deps += libgmodule_dep - common_cflags += '-DHEXCHATLIBDIR="@0@"'.format(join_paths(get_option('prefix'), - get_option('libdir'), - 'hexchat/plugins')) - install_headers('hexchat-plugin.h') endif @@ -109,6 +105,7 @@ hexchat_common = static_library('hexchatcommon', ) hexchat_common_dep = declare_dependency( + sources: [textevents] + marshal, link_with: hexchat_common, include_directories: common_includes, compile_args: common_cflags, diff --git a/src/common/modes.c b/src/common/modes.c index c65bf279..3c0ac8ab 100644 --- a/src/common/modes.c +++ b/src/common/modes.c @@ -735,6 +735,8 @@ handle_mode (server * serv, char *word[], char *word_eol[], if (!(*word[i + offset])) break; num_args++; + if (word[i + offset][0] == ':') + break; } /* count the number of modes (without the -/+ chars */ @@ -765,7 +767,7 @@ handle_mode (server * serv, char *word[], char *word_eol[], if ((all_modes_have_args || mode_has_arg (serv, sign, *modes)) && arg < (num_args + 1)) { arg++; - argstr = word[arg + offset]; + argstr = STRIP_COLON(word, word_eol, arg+offset); } handle_single_mode (&mr, sign, *modes, nick, chan, argstr, numeric_324 || prefs.hex_irc_raw_modes, diff --git a/src/common/outbound.c b/src/common/outbound.c index 96fb7fe4..614aad38 100644 --- a/src/common/outbound.c +++ b/src/common/outbound.c @@ -3287,7 +3287,7 @@ cmd_send (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (!word[2][0]) return FALSE; - addr = dcc_get_my_address (); + addr = dcc_get_my_address (sess); if (addr == 0) { /* use the one from our connected server socket */ diff --git a/src/common/plugin.c b/src/common/plugin.c index 0aa8859d..d3f3b7ca 100644 --- a/src/common/plugin.c +++ b/src/common/plugin.c @@ -115,6 +115,34 @@ enum HOOK_DELETED = 1 << 7 /* marked for deletion */ }; +enum +{ + CHANNEL_FLAG_CONNECTED = 1 << 0, + CHANNEL_FLAG_CONNECING = 1 << 1, + CHANNEL_FLAG_AWAY = 1 << 2, + CHANNEL_FLAG_END_OF_MOTD = 1 << 3, + CHANNEL_FLAG_HAS_WHOX = 1 << 4, + CHANNEL_FLAG_HAS_IDMSG = 1 << 5, + CHANNEL_FLAG_HIDE_JOIN_PARTS = 1 << 6, + CHANNEL_FLAG_HIDE_JOIN_PARTS_UNSET = 1 << 7, + CHANNEL_FLAG_BEEP = 1 << 8, + CHANNEL_FLAG_BEEP_UNSET = 1 << 9, + CHANNEL_FLAG_UNUSED = 1 << 10, + CHANNEL_FLAG_LOGGING = 1 << 11, + CHANNEL_FLAG_LOGGING_UNSET = 1 << 12, + CHANNEL_FLAG_SCROLLBACK = 1 << 13, + CHANNEL_FLAG_SCROLLBACK_UNSET = 1 << 14, + CHANNEL_FLAG_STRIP_COLORS = 1 << 15, + CHANNEL_FLAG_STRIP_COLORS_UNSET = 1 << 16, + CHANNEL_FLAG_TRAY = 1 << 17, + CHANNEL_FLAG_TRAY_UNSET = 1 << 18, + CHANNEL_FLAG_TASKBAR = 1 << 19, + CHANNEL_FLAG_TASKBAR_UNSET = 1 << 20, + CHANNEL_FLAG_BALLOON = 1 << 21, + CHANNEL_FLAG_BALLOON_UNSET = 1 << 22, + CHANNEL_FLAG_COUNT = 23 +}; + GSList *plugin_list = NULL; /* export for plugingui.c */ static GSList *hook_list = NULL; @@ -355,7 +383,8 @@ plugin_kill_all (void) } } -#ifdef USE_PLUGIN +#if defined(USE_PLUGIN) || defined(WIN32) +/* used for loading plugins, and in fe-gtk/notifications/notification-windows.c */ GModule * module_load (char *filename) @@ -384,6 +413,10 @@ module_load (char *filename) return handle; } +#endif + +#ifdef USE_PLUGIN + /* load a plugin from a filename. Returns: NULL-success or an error string */ char * @@ -676,11 +709,11 @@ check_and_invalidate(void *plug_, void *killsess_) int plugin_emit_dummy_print (session *sess, char *name) { - char *word[32]; + char *word[PDIWORDS]; int i; word[0] = name; - for (i = 1; i < 32; i++) + for (i = 1; i < PDIWORDS; i++) word[i] = "\000"; i = plugin_hook_run (sess, name, word, NULL, NULL, HOOK_PRINT); @@ -1544,7 +1577,11 @@ hexchat_list_int (hexchat_plugin *ph, hexchat_list *xlist, const char *name) { guint32 hash = str_hash (name); gpointer data = ph->context; - int tmp = 0; + + int channel_flag; + int channel_flags[CHANNEL_FLAG_COUNT]; + int channel_flags_used = 0; + int type = LIST_CHANNELS; /* a NULL xlist is a shortcut to current "channels" context */ @@ -1605,48 +1642,38 @@ hexchat_list_int (hexchat_plugin *ph, hexchat_list *xlist, const char *name) case 0xd1b: /* id */ return ((struct session *)data)->server->id; case 0x5cfee87: /* flags */ - /* used if alert_taskbar is unset */ /* 20 */ - tmp <<= 1; - tmp |= ((struct session *)data)->alert_taskbar; /* 19 */ - tmp <<= 1; - /* used if alert_tray is unset */ /* 18 */ - tmp <<= 1; - tmp |= ((struct session *)data)->alert_tray; /* 17 */ - tmp <<= 1; - /* used if text_strip is unset */ /* 16 */ - tmp <<= 1; - tmp |= ((struct session *)data)->text_strip; /* 15 */ - tmp <<= 1; - /* used if text_scrollback is unset */ /* 14 */ - tmp <<= 1; - tmp |= ((struct session *)data)->text_scrollback; /* 13 */ - tmp <<= 1; - /* used if text_logging is unset */ /* 12 */ - tmp <<= 1; - tmp |= ((struct session *)data)->text_logging; /* 11 */ - tmp <<= 1; - /* unused for historical reasons */ /* 10 */ - tmp <<= 1; - /* used if alert_beep is unset */ /* 9 */ - tmp <<= 1; - tmp |= ((struct session *)data)->alert_beep; /* 8 */ - tmp <<= 1; - /* used if text_hidejoinpart is unset */ /* 7 */ - tmp <<= 1; - tmp |= ((struct session *)data)->text_hidejoinpart; /* 6 */ - tmp <<= 1; - tmp |= ((struct session *)data)->server->have_idmsg; /* 5 */ - tmp <<= 1; - tmp |= ((struct session *)data)->server->have_whox; /* 4 */ - tmp <<= 1; - tmp |= ((struct session *)data)->server->end_of_motd;/* 3 */ - tmp <<= 1; - tmp |= ((struct session *)data)->server->is_away; /* 2 */ - tmp <<= 1; - tmp |= ((struct session *)data)->server->connecting; /* 1 */ - tmp <<= 1; - tmp |= ((struct session *)data)->server->connected; /* 0 */ - return tmp; + channel_flags[0] = ((struct session *)data)->server->connected; + channel_flags[1] = ((struct session *)data)->server->connecting; + channel_flags[2] = ((struct session *)data)->server->is_away; + channel_flags[3] = ((struct session *)data)->server->end_of_motd; + channel_flags[4] = ((struct session *)data)->server->have_whox; + channel_flags[5] = ((struct session *)data)->server->have_idmsg; + channel_flags[6] = ((struct session *)data)->text_hidejoinpart; + channel_flags[7] = ((struct session *)data)->text_hidejoinpart == SET_DEFAULT; + channel_flags[8] = ((struct session *)data)->alert_beep; + channel_flags[9] = ((struct session *)data)->alert_beep == SET_DEFAULT; + channel_flags[10] = 0; /* unused for historical reasons */ + channel_flags[11] = ((struct session *)data)->text_logging; + channel_flags[12] = ((struct session *)data)->text_logging == SET_DEFAULT; + channel_flags[13] = ((struct session *)data)->text_scrollback; + channel_flags[14] = ((struct session *)data)->text_scrollback == SET_DEFAULT; + channel_flags[15] = ((struct session *)data)->text_strip; + channel_flags[16] = ((struct session *)data)->text_strip == SET_DEFAULT; + channel_flags[17] = ((struct session *)data)->alert_tray; + channel_flags[18] = ((struct session *)data)->alert_tray == SET_DEFAULT; + channel_flags[19] = ((struct session *)data)->alert_taskbar; + channel_flags[20] = ((struct session *)data)->alert_taskbar == SET_DEFAULT; + channel_flags[21] = ((struct session *)data)->alert_balloon; + channel_flags[22] = ((struct session *)data)->alert_balloon == SET_DEFAULT; + + /* Set flags */ + for (channel_flag = 0; channel_flag < CHANNEL_FLAG_COUNT; ++channel_flag) { + if (channel_flags[channel_flag]) { + channel_flags_used |= 1 << channel_flag; + } + } + + return channel_flags_used; case 0x1a192: /* lag */ return ((struct session *)data)->server->lag; case 0x1916144c: /* maxmodes */ diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index 776d1434..c8e44b62 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -60,8 +60,8 @@ irc_login (server *serv, char *user, char *realname) tcp_sendf (serv, "NICK %s\r\n" - "USER %s %s %s :%s\r\n", - serv->nick, user, user, serv->servername, realname); + "USER %s 0 * :%s\r\n", + serv->nick, user, realname); } static void @@ -454,7 +454,8 @@ channel_date (session *sess, char *chan, char *timestr, { time_t timestamp = (time_t) atol (timestr); char *tim = ctime (×tamp); - tim[24] = 0; /* get rid of the \n */ + if (tim != NULL) + tim[24] = 0; /* get rid of the \n */ EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANDATE, sess, chan, tim, NULL, NULL, 0, tags_data->timestamp); } @@ -602,7 +603,8 @@ process_numeric (session * sess, int n, else { tim = ctime (×tamp); - tim[19] = 0; /* get rid of the \n */ + if (tim != NULL) + tim[19] = 0; /* get rid of the \n */ EMIT_SIGNAL_TIMESTAMP (XP_TE_WHOIS4T, whois_sess, word[4], outbuf, tim, NULL, 0, tags_data->timestamp); } @@ -621,7 +623,7 @@ process_numeric (session * sess, int n, case 319: if (!serv->skip_next_whois) EMIT_SIGNAL_TIMESTAMP (XP_TE_WHOIS2, whois_sess, word[4], - word_eol[5] + 1, NULL, NULL, 0, + word_eol[5][0] == ':' ? word_eol[5] + 1 : word_eol[5], NULL, NULL, 0, tags_data->timestamp); break; @@ -714,7 +716,7 @@ process_numeric (session * sess, int n, break; case 333: - inbound_topictime (serv, word[4], word[5], atol (word[6]), tags_data); + inbound_topictime (serv, word[4], word[5], atol (STRIP_COLON(word, word_eol, 6)), tags_data); break; #if 0 @@ -726,7 +728,7 @@ process_numeric (session * sess, int n, #endif case 341: /* INVITE ACK */ - EMIT_SIGNAL_TIMESTAMP (XP_TE_UINVITE, sess, word[4], word[5], + EMIT_SIGNAL_TIMESTAMP (XP_TE_UINVITE, sess, word[4], STRIP_COLON(word, word_eol, 5), serv->servername, NULL, 0, tags_data->timestamp); break; @@ -957,6 +959,7 @@ process_numeric (session * sess, int n, EMIT_SIGNAL_TIMESTAMP (XP_TE_SASLRESPONSE, serv->server_session, word[1], word[2], word[3], ++word_eol[4], 0, tags_data->timestamp); + serv->waiting_on_sasl = FALSE; if (!serv->sent_capend) { serv->sent_capend = TRUE; @@ -1007,6 +1010,7 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[], const message_tags_data *tags_data) { server *serv = sess->server; + char *account; char ip[128], nick[NICKLEN]; char *text, *ex; int len = strlen (type); @@ -1025,6 +1029,14 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[], ex[0] = '!'; } + + /** Update the account for this message's source. */ + if (serv->have_account_tag) + { + account = tags_data->account && *tags_data->account ? tags_data->account : "*"; + inbound_account (serv, nick, account, tags_data); + } + if (len == 4) { guint32 t; @@ -1142,7 +1154,7 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[], { case WORDL('A','C','C','O'): - inbound_account (serv, nick, word[3], tags_data); + inbound_account (serv, nick, STRIP_COLON(word, word_eol, 3), tags_data); return; case WORDL('A', 'U', 'T', 'H'): @@ -1150,20 +1162,26 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[], return; case WORDL('C', 'H', 'G', 'H'): - inbound_user_info (sess, NULL, word[3], word[4], NULL, nick, NULL, + inbound_user_info (sess, NULL, word[3], STRIP_COLON(word, word_eol, 4), NULL, nick, NULL, + NULL, 0xff, tags_data); + return; + + case WORDL('S', 'E', 'T', 'N'): + inbound_user_info (sess, NULL, NULL, NULL, NULL, nick, STRIP_COLON(word, word_eol, 3), NULL, 0xff, tags_data); return; case WORDL('I','N','V','I'): if (ignore_check (word[1], IG_INVI)) return; - - if (word[4][0] == ':') - EMIT_SIGNAL_TIMESTAMP (XP_TE_INVITED, sess, word[4] + 1, nick, - serv->servername, NULL, 0, + + text = STRIP_COLON(word, word_eol, 4); + if (serv->p_cmp (word[3], serv->nick)) + EMIT_SIGNAL_TIMESTAMP (XP_TE_INVITEDOTHER, sess, text, nick, + word[3], serv->servername, 0, tags_data->timestamp); else - EMIT_SIGNAL_TIMESTAMP (XP_TE_INVITED, sess, word[4], nick, + EMIT_SIGNAL_TIMESTAMP (XP_TE_INVITED, sess, text, nick, serv->servername, NULL, 0, tags_data->timestamp); @@ -1241,10 +1259,13 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[], text++; } len = strlen (text); - if (text[0] == 1 && text[len - 1] == 1) /* ctcp */ + if (text[0] == 1) /* ctcp */ { char *new_pdibuf = NULL; - text[len - 1] = 0; + if (text[len - 1] == 1) + { + text[len - 1] = 0; + } text++; if (g_ascii_strncasecmp (text, "ACTION", 6) != 0) flood_check (nick, ip, serv, sess, 0); @@ -1330,7 +1351,7 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[], } else if (strncasecmp (word[4], "NAK", 3) == 0) { - inbound_cap_nak (serv, tags_data); + inbound_cap_nak (serv, word[5][0] == ':' ? word_eol[5] + 1 : word_eol[5], tags_data); } else if (strncasecmp (word[4], "LIST", 4) == 0) { @@ -1513,6 +1534,9 @@ handle_message_tags (server *serv, const char *tags_str, *value = '\0'; value++; + if (serv->have_account_tag && !strcmp (key, "account")) + tags_data->account = g_strdup (value); + if (serv->have_server_time && !strcmp (key, "time")) handle_message_tag_time (value, tags_data); } @@ -1610,10 +1634,17 @@ irc_inline (server *serv, char *buf, int len) } xit: + message_tags_data_free (&tags_data); g_free (pdibuf); } void +message_tags_data_free (message_tags_data *tags_data) +{ + g_clear_pointer (&tags_data->account, g_free); +} + +void proto_fill_her_up (server *serv) { serv->p_inline = irc_inline; diff --git a/src/common/proto-irc.h b/src/common/proto-irc.h index a7b4029c..0f72c644 100644 --- a/src/common/proto-irc.h +++ b/src/common/proto-irc.h @@ -25,18 +25,24 @@ #define MESSAGE_TAGS_DATA_INIT \ { \ + NULL, /* account name */ \ (time_t)0, /* timestamp */ \ } +#define STRIP_COLON(word, word_eol, idx) (word)[(idx)][0] == ':' ? (word_eol)[(idx)]+1 : (word)[(idx)] + /* Message tag information that might be passed along with a server message * * See http://ircv3.atheme.org/specification/capability-negotiation-3.1 */ typedef struct { + char *account; time_t timestamp; } message_tags_data; +void message_tags_data_free (message_tags_data *tags_data); + void proto_fill_her_up (server *serv); #endif diff --git a/src/common/server.c b/src/common/server.c index 3db0a963..5c645eb5 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -200,13 +200,35 @@ tcp_send_len (server *serv, char *buf, int len) } else { - /* WHO/MODE get the lowest priority */ - if (g_ascii_strncasecmp (dbuf + 1, "WHO ", 4) == 0 || - /* but only MODE queries, not changes */ - (g_ascii_strncasecmp (dbuf + 1, "MODE", 4) == 0 && - strchr (dbuf, '-') == NULL && - strchr (dbuf, '+') == NULL)) + /* WHO gets the lowest priority */ + if (g_ascii_strncasecmp (dbuf + 1, "WHO ", 4) == 0) dbuf[0] = 0; + /* as do MODE queries (but not changes) */ + else if (g_ascii_strncasecmp (dbuf + 1, "MODE ", 5) == 0) + { + char *mode_str, *mode_str_end, *loc; + /* skip spaces before channel/nickname */ + for (mode_str = dbuf + 5; *mode_str == ' '; ++mode_str); + /* skip over channel/nickname */ + mode_str = strchr (mode_str, ' '); + if (mode_str) + { + /* skip spaces before mode string */ + for (; *mode_str == ' '; ++mode_str); + /* find spaces after end of mode string */ + mode_str_end = strchr (mode_str, ' '); + /* look for +/- within the mode string */ + loc = strchr (mode_str, '-'); + if (loc && (!mode_str_end || loc < mode_str_end)) + goto keep_priority; + loc = strchr (mode_str, '+'); + if (loc && (!mode_str_end || loc < mode_str_end)) + goto keep_priority; + } + dbuf[0] = 0; +keep_priority: + ; + } } serv->outbound_queue = g_slist_append (serv->outbound_queue, dbuf); @@ -1094,6 +1116,7 @@ traverse_socks5 (int print_fd, int sok, char *serverAddr, int port) if (auth) { int len_u=0, len_p=0; + unsigned char *u_p_buf; /* authentication sub-negotiation (RFC1929) */ if (buf[1] != 2) /* UPA not supported by server */ @@ -1102,18 +1125,22 @@ traverse_socks5 (int print_fd, int sok, char *serverAddr, int port) return 1; } - memset (buf, 0, sizeof(buf)); - /* form the UPA request */ len_u = strlen (prefs.hex_net_proxy_user); len_p = strlen (prefs.hex_net_proxy_pass); - buf[0] = 1; - buf[1] = len_u; - memcpy (buf + 2, prefs.hex_net_proxy_user, len_u); - buf[2 + len_u] = len_p; - memcpy (buf + 3 + len_u, prefs.hex_net_proxy_pass, len_p); - send (sok, buf, 3 + len_u + len_p, 0); + packetlen = 2 + len_u + 1 + len_p; + u_p_buf = g_malloc0 (packetlen); + + u_p_buf[0] = 1; + u_p_buf[1] = len_u; + memcpy (u_p_buf + 2, prefs.hex_net_proxy_user, len_u); + u_p_buf[2 + len_u] = len_p; + memcpy (u_p_buf + 3 + len_u, prefs.hex_net_proxy_pass, len_p); + + send (sok, u_p_buf, packetlen, 0); + g_free(u_p_buf); + if ( recv (sok, buf, 2, 0) != 2 ) goto read_error; if ( buf[1] != 0 ) @@ -1757,6 +1784,7 @@ server_set_defaults (server *serv) serv->have_idmsg = FALSE; serv->have_accnotify = FALSE; serv->have_extjoin = FALSE; + serv->have_account_tag = FALSE; serv->have_server_time = FALSE; serv->have_sasl = FALSE; serv->have_except = FALSE; diff --git a/src/common/servlist.c b/src/common/servlist.c index 449f982b..79a5694b 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -54,15 +54,13 @@ static const struct defaultserver def[] = /* Invalid hostname in cert */ {0, "irc.2600.net"}, - {"2ch", 0, 0, "iso-2022-jp", 0, 0}, - {0, "irc.2ch.sc"}, - {0, "irc.nurs.or.jp"}, - {0, "irc.juggler.jp"}, - {"AccessIRC", 0}, /* Self signed */ {0, "irc.accessirc.net"}, + {"ACN", 0, 0, 0, LOGIN_SASL, 0, TRUE}, + {0, "global.acn.gr"}, + {"AfterNET", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.afternet.org"}, @@ -125,6 +123,13 @@ static const struct defaultserver def[] = {"DarkMyst", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.darkmyst.org"}, +#ifdef USE_OPENSSL + {"darkscience", 0, 0, 0, LOGIN_SASL, 0, TRUE}, + {0, "irc.darkscience.net"}, + {0, "irc.drk.sc"}, + {0, "irc.darkscience.ws"}, +#endif + {"Dark-Tou-Net", 0}, {0, "irc.d-t-net.de"}, @@ -166,9 +171,6 @@ static const struct defaultserver def[] = /* irc. points to chat. but many users and urls still reference it */ {0, "irc.freenode.net"}, - {"Furnet", 0, 0, 0, 0, 0, TRUE}, - {0, "irc.furnet.org"}, - {"GalaxyNet", 0}, {0, "irc.galaxynet.org"}, @@ -196,6 +198,12 @@ static const struct defaultserver def[] = #endif {0, "irc.globalgamers.net"}, +#ifdef USE_OPENSSL + {"hackint", 0, 0, 0, LOGIN_SASL, 0, TRUE}, + {0, "irc.hackint.org"}, + {0, "irc.eu.hackint.org"}, +#endif + {"Hashmark", 0}, {0, "irc.hashmark.net"}, @@ -231,10 +239,18 @@ static const struct defaultserver def[] = {"Krstarica", 0}, {0, "irc.krstarica.com"}, +#ifdef USE_OPENSSL + {"LibertaCasa", 0, 0, 0, LOGIN_SASL, 0, TRUE}, + {0, "irc.liberta.casa"}, +#endif + {"LibraIRC", 0}, /* Self signed */ {0, "irc.librairc.net"}, + {"Libera.Chat", 0, 0, 0, LOGIN_SASL, 0, TRUE}, + {0, "irc.libera.chat"}, + #ifdef USE_OPENSSL {"LinkNet", 0}, {0, "irc.link-net.org/+7000"}, @@ -246,9 +262,6 @@ static const struct defaultserver def[] = {"MIXXnet", 0}, {0, "irc.mixxnet.net"}, - {"Moznet", 0, 0, 0, 0, 0, TRUE}, - {0, "irc.mozilla.org"}, - {"ObsidianIRC", 0}, /* Self signed */ {0, "irc.obsidianirc.net"}, @@ -273,9 +286,12 @@ static const struct defaultserver def[] = {0, "irc.ponychat.net"}, {"PTNet.org", 0}, - /* Note that the network suggests ISO-8859-1 but most users ignore this */ + {0, "irc.ptnet.org"}, {0, "uevora.ptnet.org"}, - {0, "vianetworks.ptnet.org"}, + {0, "claranet.ptnet.org"}, + {0, "sonaquela.ptnet.org"}, + {0, "uc.ptnet.org"}, + {0, "ipg.ptnet.org"}, {"QuakeNet", 0, 0, 0, LOGIN_CHALLENGEAUTH}, {0, "irc.quakenet.org"}, @@ -299,6 +315,9 @@ static const struct defaultserver def[] = {"Serenity-IRC", 0}, {0, "irc.serenity-irc.net"}, + {"SimosNap", 0, 0, 0, LOGIN_SASL, 0, TRUE}, + {0, "irc.simosnap.com"}, + {"SlashNET", 0}, /* Self signed */ {0, "irc.slashnet.org"}, @@ -340,7 +359,18 @@ static const struct defaultserver def[] = {"Techtronix", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.techtronix.net"}, + + {"tilde.chat", 0, 0, 0, LOGIN_SASL, 0, TRUE}, + {0, "irc.tilde.chat"}, +#ifdef USE_OPENSSL + {"TripSit", 0, 0, 0, LOGIN_SASL, 0, TRUE}, + {0, "irc.tripsit.me"}, + {0, "newirc.tripsit.me"}, + {0, "coconut.tripsit.me"}, + {0, "innsbruck.tripsit.me"}, +#endif + {"TURLINet", 0, 0, 0, 0, 0, TRUE}, /* Other servers use CP1251 and invalid certs */ {0, "irc.servx.ru"}, @@ -358,6 +388,9 @@ static const struct defaultserver def[] = {"Xertion", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.xertion.org"}, + + {"DeltaPool", 0, 0, 0, LOGIN_SASL, 0, TRUE}, + {0, "irc.deltapool.net"}, {0,0} }; @@ -928,7 +961,7 @@ servlist_load_defaults (void) { int i = 0, j = 0; ircnet *net = NULL; - guint def_hash = g_str_hash ("freenode"); + guint def_hash = g_str_hash ("Libera.Chat"); while (1) { diff --git a/src/common/text.c b/src/common/text.c index 4a274f98..b0a90e03 100644 --- a/src/common/text.c +++ b/src/common/text.c @@ -1295,6 +1295,13 @@ static char * const pevt_invited_help[] = { N_("Server Name"), }; +static char * const pevt_invitedother_help[] = { + N_("Channel Name"), + N_("Nick of person who sent the invite"), + N_("Nick of person who was invited"), + N_("Server Name"), +}; + static char * const pevt_usersonchan_help[] = { N_("Channel Name"), N_("Users"), diff --git a/src/common/textevents.in b/src/common/textevents.in index 9790c18d..14bd4b06 100644 --- a/src/common/textevents.in +++ b/src/common/textevents.in @@ -496,6 +496,12 @@ pevt_invited_help %C24*%O$tYou have been invited to %C22$1%O by %C18$2%O (%C29$3%O) 3 +Invited Other +XP_TE_INVITEDOTHER +pevt_invitedother_help +%C24*%O$t%C26$3%C has been invited to %C22$1%O by %C18$2%O (%C29$4%O) +4 + Join XP_TE_JOIN pevt_join_help diff --git a/src/common/url.c b/src/common/url.c index a741fb04..6a1d09e8 100644 --- a/src/common/url.c +++ b/src/common/url.c @@ -518,6 +518,8 @@ struct { "pop", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH }, { "nfs", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH }, { "smb", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH }, + { "gopher", "/", URI_AUTHORITY | URI_PATH }, + { "gemini", "/", URI_AUTHORITY | URI_PATH }, { "ssh", "", URI_AUTHORITY | URI_OPT_USERINFO }, { "sip", "", URI_AUTHORITY | URI_USERINFO }, { "sips", "", URI_AUTHORITY | URI_USERINFO }, diff --git a/src/common/userlist.c b/src/common/userlist.c index 0f28a000..5f2d67f2 100644 --- a/src/common/userlist.c +++ b/src/common/userlist.c @@ -101,13 +101,15 @@ userlist_set_account (struct session *sess, char *nick, char *account) user = userlist_find (sess, nick); if (user) { - g_free (user->account); - if (strcmp (account, "*") == 0) - user->account = NULL; - else + { + g_clear_pointer (&user->account, g_free); + } else if (g_strcmp0 (user->account, account)) + { + g_free (user->account); user->account = g_strdup (account); - + } + /* gui doesnt currently reflect login status, maybe later fe_userlist_rehash (sess, user); */ } @@ -130,8 +132,11 @@ userlist_add_hostname (struct session *sess, char *nick, char *hostname, g_free (user->hostname); user->hostname = g_strdup (hostname); } - if (!user->realname && realname && *realname) + if (realname && *realname && g_strcmp0 (user->realname, realname) != 0) + { + g_free (user->realname); user->realname = g_strdup (realname); + } if (!user->servername && servername) user->servername = g_strdup (servername); if (!user->account && account && strcmp (account, "0") != 0) |