1
0
mirror of https://github.com/irssi/irssi.git synced 2024-10-27 05:20:20 -04:00

sending of tag messages and customisable maximum irc message length

This commit is contained in:
ailin-nemui 2019-08-12 23:41:18 +02:00
parent d418989f0c
commit da9adec47f
6 changed files with 69 additions and 18 deletions

View File

@ -142,7 +142,7 @@ static void irc_channels_join(IRC_SERVER_REC *server, const char *data,
/* don't try to send too long lines /* don't try to send too long lines
make sure it's not longer than 510 make sure it's not longer than 510
so 510 - strlen("JOIN ") = 505 */ so 510 - strlen("JOIN ") = 505 */
if (cmdlen < MAX_IRC_MESSAGE_LEN - 5 /* strlen("JOIN ") */) if (cmdlen < server->max_message_len - 5 /* strlen("JOIN ") */)
continue; continue;
} }
if (outchans->len > 0) { if (outchans->len > 0) {

View File

@ -202,7 +202,7 @@ static char **split_message(SERVER_REC *server, const char *target,
/* length calculation shamelessly stolen from splitlong_safe.pl */ /* length calculation shamelessly stolen from splitlong_safe.pl */
return split_line(SERVER(server), msg, target, return split_line(SERVER(server), msg, target,
MAX_IRC_MESSAGE_LEN - strlen(":! PRIVMSG :") - ircserver->max_message_len - strlen(":! PRIVMSG :") -
strlen(ircserver->nick) - MAX_USERHOST_LEN - strlen(ircserver->nick) - MAX_USERHOST_LEN -
strlen(target)); strlen(target));
} }
@ -233,6 +233,7 @@ static void server_init(IRC_SERVER_REC *server)
irc_cap_toggle(server, CAP_SASL, TRUE); irc_cap_toggle(server, CAP_SASL, TRUE);
} }
irc_cap_toggle(server, CAP_MAXLINE, TRUE);
irc_cap_toggle(server, CAP_MULTI_PREFIX, TRUE); irc_cap_toggle(server, CAP_MULTI_PREFIX, TRUE);
irc_cap_toggle(server, CAP_EXTENDED_JOIN, TRUE); irc_cap_toggle(server, CAP_EXTENDED_JOIN, TRUE);
irc_cap_toggle(server, CAP_SETNAME, TRUE); irc_cap_toggle(server, CAP_SETNAME, TRUE);
@ -314,6 +315,8 @@ SERVER_REC *irc_server_init_connect(SERVER_CONNECT_REC *conn)
server->connrec->use_tls ? 6697 : 6667; server->connrec->use_tls ? 6697 : 6667;
} }
server->max_message_len = MAX_IRC_MESSAGE_LEN;
server->cmd_queue_speed = ircconn->cmd_queue_speed > 0 ? server->cmd_queue_speed = ircconn->cmd_queue_speed > 0 ?
ircconn->cmd_queue_speed : settings_get_time("cmd_queue_speed"); ircconn->cmd_queue_speed : settings_get_time("cmd_queue_speed");
server->max_cmds_at_once = ircconn->max_cmds_at_once > 0 ? server->max_cmds_at_once = ircconn->max_cmds_at_once > 0 ?
@ -479,6 +482,14 @@ static void sig_server_quit(IRC_SERVER_REC *server, const char *msg)
g_free(recoded); g_free(recoded);
} }
static void cap_maxline(IRC_SERVER_REC *server)
{
int maxline = atoi(g_hash_table_lookup(server->cap_supported, CAP_MAXLINE));
if (maxline >= MAX_IRC_MESSAGE_LEN + 2 /* 2 bytes for CR+LF */) {
server->max_message_len = maxline - 2;
}
}
void irc_server_send_action(IRC_SERVER_REC *server, const char *target, const char *data) void irc_server_send_action(IRC_SERVER_REC *server, const char *target, const char *data)
{ {
char *recoded; char *recoded;
@ -496,7 +507,7 @@ char **irc_server_split_action(IRC_SERVER_REC *server, const char *target,
g_return_val_if_fail(data != NULL, NULL); g_return_val_if_fail(data != NULL, NULL);
return split_line(SERVER(server), data, target, return split_line(SERVER(server), data, target,
MAX_IRC_MESSAGE_LEN - strlen(":! PRIVMSG :\001ACTION \001") - server->max_message_len - strlen(":! PRIVMSG :\001ACTION \001") -
strlen(server->nick) - MAX_USERHOST_LEN - strlen(server->nick) - MAX_USERHOST_LEN -
strlen(target)); strlen(target));
} }
@ -1033,6 +1044,7 @@ void irc_servers_init(void)
signal_add_first("server connected", (SIGNAL_FUNC) sig_connected); signal_add_first("server connected", (SIGNAL_FUNC) sig_connected);
signal_add_last("server destroyed", (SIGNAL_FUNC) sig_destroyed); signal_add_last("server destroyed", (SIGNAL_FUNC) sig_destroyed);
signal_add_last("server quit", (SIGNAL_FUNC) sig_server_quit); signal_add_last("server quit", (SIGNAL_FUNC) sig_server_quit);
signal_add("server cap ack " CAP_MAXLINE, (SIGNAL_FUNC) cap_maxline);
signal_add("event 001", (SIGNAL_FUNC) event_connected); signal_add("event 001", (SIGNAL_FUNC) event_connected);
signal_add("event 004", (SIGNAL_FUNC) event_server_info); signal_add("event 004", (SIGNAL_FUNC) event_server_info);
signal_add("event 005", (SIGNAL_FUNC) event_isupport); signal_add("event 005", (SIGNAL_FUNC) event_isupport);
@ -1060,6 +1072,7 @@ void irc_servers_deinit(void)
signal_remove("server connected", (SIGNAL_FUNC) sig_connected); signal_remove("server connected", (SIGNAL_FUNC) sig_connected);
signal_remove("server destroyed", (SIGNAL_FUNC) sig_destroyed); signal_remove("server destroyed", (SIGNAL_FUNC) sig_destroyed);
signal_remove("server quit", (SIGNAL_FUNC) sig_server_quit); signal_remove("server quit", (SIGNAL_FUNC) sig_server_quit);
signal_remove("server cap ack " CAP_MAXLINE, (SIGNAL_FUNC) cap_maxline);
signal_remove("event 001", (SIGNAL_FUNC) event_connected); signal_remove("event 001", (SIGNAL_FUNC) event_connected);
signal_remove("event 004", (SIGNAL_FUNC) event_server_info); signal_remove("event 004", (SIGNAL_FUNC) event_server_info);
signal_remove("event 005", (SIGNAL_FUNC) event_isupport); signal_remove("event 005", (SIGNAL_FUNC) event_isupport);

View File

@ -15,6 +15,8 @@
#define MAX_IRC_USER_TAGS_LEN 4094 #define MAX_IRC_USER_TAGS_LEN 4094
#define CAP_LS_VERSION "302" #define CAP_LS_VERSION "302"
#define CAP_MAXLINE "oragono.io/maxline-2"
#define CAP_MESSAGE_TAGS "message-tags"
#define CAP_SASL "sasl" #define CAP_SASL "sasl"
#define CAP_MULTI_PREFIX "multi-prefix" #define CAP_MULTI_PREFIX "multi-prefix"
#define CAP_EXTENDED_JOIN "extended-join" #define CAP_EXTENDED_JOIN "extended-join"
@ -58,6 +60,8 @@ struct _IRC_SERVER_CONNECT_REC {
struct _IRC_SERVER_REC { struct _IRC_SERVER_REC {
#include <irssi/src/core/server-rec.h> #include <irssi/src/core/server-rec.h>
int max_message_len; /* Maximum message length, default = 510 = 512 - 2 (for CR+LF) */
/* For deciding if event should be redirected */ /* For deciding if event should be redirected */
GSList *redirects; GSList *redirects;
GSList *redirect_queue; /* should be updated from redirect_next each time cmdqueue is updated */ GSList *redirect_queue; /* should be updated from redirect_next each time cmdqueue is updated */

View File

@ -49,8 +49,9 @@ static void strip_params_colon(char *const);
void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd,
int send_now, int immediate, int raw) int send_now, int immediate, int raw)
{ {
char str[513]; GString *str;
int len; int len;
gboolean server_supports_tag;
g_return_if_fail(server != NULL); g_return_if_fail(server != NULL);
g_return_if_fail(cmd != NULL); g_return_if_fail(cmd != NULL);
@ -58,35 +59,66 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd,
if (server->connection_lost) if (server->connection_lost)
return; return;
len = strlen(cmd); str = g_string_sized_new(MAX_IRC_USER_TAGS_LEN + 2 /* `@'+SPACE */ +
server->max_message_len + 2 /* CR+LF */ + 1 /* `\0' */);
if (server->cmdcount == 0) if (server->cmdcount == 0)
irc_servers_start_cmd_timeout(); irc_servers_start_cmd_timeout();
server->cmdcount++; server->cmdcount++;
if (!raw) { if (!raw) {
const char *tmp = cmd;
server_supports_tag = server->cap_supported != NULL &&
g_hash_table_lookup_extended(server->cap_supported, CAP_MESSAGE_TAGS, NULL, NULL);
if (*cmd == '@' && server_supports_tag) {
const char *end;
while (*tmp != ' ' && *tmp != '\0')
tmp++;
end = tmp;
if (tmp - cmd > MAX_IRC_USER_TAGS_LEN) {
g_warning("irc_send_cmd_full(); tags too long(%ld)", tmp - cmd);
while (tmp - cmd > MAX_IRC_USER_TAGS_LEN && cmd != tmp - 1) tmp--;
while (*tmp != ',' && cmd != tmp - 1) tmp--;
}
if (cmd != tmp)
g_string_append_len(str, cmd, tmp - cmd);
tmp = end;
while (*tmp == ' ') tmp++;
if (*tmp != '\0' && str->len > 0)
g_string_append_c(str, ' ');
}
len = strlen(tmp);
/* check that we don't send any longer commands /* check that we don't send any longer commands
than 510 bytes (2 bytes for CR+LF) */ than 510 bytes (2 bytes for CR+LF) */
strncpy(str, cmd, 510); g_string_append_len(str, tmp, len > server->max_message_len ?
if (len > 510) len = 510; server->max_message_len : len);
str[len] = '\0'; } else {
cmd = str; g_string_append(str, cmd);
} }
if (send_now) { if (send_now) {
rawlog_output(server->rawlog, cmd); rawlog_output(server->rawlog, str->str);
server_redirect_command(server, cmd, server->redirect_next); server_redirect_command(server, str->str, server->redirect_next);
server->redirect_next = NULL; server->redirect_next = NULL;
} }
if (!raw) { if (!raw) {
/* Add CR+LF to command */ /* Add CR+LF to command */
str[len++] = 13; g_string_append_c(str, 13);
str[len++] = 10; g_string_append_c(str, 10);
str[len] = '\0';
} }
if (send_now) { if (send_now) {
irc_server_send_data(server, cmd, len); irc_server_send_data(server, str->str, str->len);
g_string_free(str, TRUE);
} else { } else {
/* add to queue */ /* add to queue */
@ -94,10 +126,10 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd,
server->cmdqueue = g_slist_prepend(server->cmdqueue, server->cmdqueue = g_slist_prepend(server->cmdqueue,
server->redirect_next); server->redirect_next);
server->cmdqueue = g_slist_prepend(server->cmdqueue, server->cmdqueue = g_slist_prepend(server->cmdqueue,
g_strdup(cmd)); g_string_free(str, FALSE));
} else { } else {
server->cmdqueue = g_slist_append(server->cmdqueue, server->cmdqueue = g_slist_append(server->cmdqueue,
g_strdup(cmd)); g_string_free(str, FALSE));
server->cmdqueue = g_slist_append(server->cmdqueue, server->cmdqueue = g_slist_append(server->cmdqueue,
server->redirect_next); server->redirect_next);
} }

View File

@ -131,7 +131,7 @@ static void notifylist_timeout_server(IRC_SERVER_REC *server)
len = strlen(nick); len = strlen(nick);
if (cmd->len+len+1 > MAX_IRC_MESSAGE_LEN) if (cmd->len+len+1 > server->max_message_len)
ison_send(server, cmd); ison_send(server, cmd);
g_string_append_printf(cmd, "%s ", nick); g_string_append_printf(cmd, "%s ", nick);

View File

@ -24,6 +24,8 @@ static void perl_irc_server_fill_hash(HV *hv, IRC_SERVER_REC *server)
(void) hv_store(hv, "usermode", 8, new_pv(server->usermode), 0); (void) hv_store(hv, "usermode", 8, new_pv(server->usermode), 0);
(void) hv_store(hv, "userhost", 8, new_pv(server->userhost), 0); (void) hv_store(hv, "userhost", 8, new_pv(server->userhost), 0);
(void) hv_store(hv, "max_message_len", 15, newSViv(server->max_message_len), 0);
(void) hv_store(hv, "max_cmds_at_once", 16, newSViv(server->max_cmds_at_once), 0); (void) hv_store(hv, "max_cmds_at_once", 16, newSViv(server->max_cmds_at_once), 0);
(void) hv_store(hv, "cmd_queue_speed", 15, newSViv(server->cmd_queue_speed), 0); (void) hv_store(hv, "cmd_queue_speed", 15, newSViv(server->cmd_queue_speed), 0);
(void) hv_store(hv, "max_query_chans", 15, newSViv(server->max_query_chans), 0); (void) hv_store(hv, "max_query_chans", 15, newSViv(server->max_query_chans), 0);