From bc5d16c4fb6dc4442c1e1cac1c736d872ce2062d Mon Sep 17 00:00:00 2001 From: misdre Date: Fri, 5 Apr 2013 23:14:51 +0200 Subject: [PATCH 1/3] split long message on action and notice --- src/common/outbound.c | 139 ++++++++++++++++++++++++++++-------------- 1 file changed, 94 insertions(+), 45 deletions(-) diff --git a/src/common/outbound.c b/src/common/outbound.c index 082ba812..d933de32 100644 --- a/src/common/outbound.c +++ b/src/common/outbound.c @@ -2576,10 +2576,57 @@ cmd_load (struct session *sess, char *tbuf, char *word[], char *word_eol[]) return FALSE; } +char * +split_text(struct session *sess, char *text, int cmd_length, char *splitted_text) +{ + unsigned int max; + + /* maximum allowed text */ + /* :nickname!username@host.com cmd_length */ + max = 512; /* rfc 2812 */ + max -= 3; /* :, !, @ */ + max -= cmd_length; + max -= strlen (sess->server->nick); + max -= strlen (sess->channel); + if (sess->me && sess->me->hostname) + max -= strlen (sess->me->hostname); + else + { + max -= 9; /* username */ + max -= 65; /* max possible hostname and '@' */ + } + + if (strlen (text) > max) + { + unsigned int i = 0; + int size; + + /* traverse the utf8 string and find the nearest cut point that + doesn't split 1 char in half */ + while (1) + { + size = g_utf8_skip[((unsigned char *)text)[i]]; + if ((i + size) >= max) + break; + i += size; + } + max = i; + + splitted_text = g_strdup_printf ("%.*s", max, text); + + return splitted_text; + } + + return NULL; +} + static int cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[]) { char *act = word_eol[2]; + char *splitted_text = NULL; + int cmd_length = 22; /* " PRIVMSG ", " ", :, \001ACTION, " ", \001, \r, \n */ + int offset = 0; if (!(*act)) return FALSE; @@ -2601,9 +2648,21 @@ cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[]) /* DCC CHAT failed, try through server */ if (sess->server->connected) { - sess->server->p_action (sess->server, sess->channel, act); + while ((splitted_text = split_text (sess, act + offset, cmd_length, splitted_text))) + { + sess->server->p_action (sess->server, sess->channel, splitted_text); + /* print it to screen */ + inbound_action (sess, sess->channel, sess->server->nick, "", splitted_text, TRUE, FALSE); + + if (*splitted_text) + offset += strlen(splitted_text); + + g_free(splitted_text); + } + + sess->server->p_action (sess->server, sess->channel, act + offset); /* print it to screen */ - inbound_action (sess, sess->channel, sess->server->nick, "", act, TRUE, FALSE); + inbound_action (sess, sess->channel, sess->server->nick, "", act + offset, TRUE, FALSE); } else { notc_msg (sess); @@ -2769,10 +2828,27 @@ cmd_nick (struct session *sess, char *tbuf, char *word[], char *word_eol[]) static int cmd_notice (struct session *sess, char *tbuf, char *word[], char *word_eol[]) { + char *text = word_eol[3]; + char *splitted_text = NULL; + int cmd_length = 12; /* " NOTICE ", " ", :, \r, \n */ + int offset = 0; + if (*word[2] && *word_eol[3]) { - sess->server->p_notice (sess->server, word[2], word_eol[3]); - EMIT_SIGNAL (XP_TE_NOTICESEND, sess, word[2], word_eol[3], NULL, NULL, 0); + while ((splitted_text = split_text (sess, text + offset, cmd_length, splitted_text))) + { + sess->server->p_notice (sess->server, word[2], splitted_text); + EMIT_SIGNAL (XP_TE_NOTICESEND, sess, word[2], splitted_text, NULL, NULL, 0); + + if (*splitted_text) + offset += strlen(splitted_text); + + g_free(splitted_text); + } + + sess->server->p_notice (sess->server, word[2], text + offset); + EMIT_SIGNAL (XP_TE_NOTICESEND, sess, word[2], text + offset, NULL, NULL, 0); + return TRUE; } return FALSE; @@ -4257,52 +4333,25 @@ handle_say (session *sess, char *text, int check_spch) if (sess->server->connected) { - unsigned int max; - unsigned char t = 0; + char *splitted_text = NULL; + int cmd_length = 13; /* " PRIVMSG ", " ", :, \r, \n */ + int offset = 0; - /* maximum allowed message text */ - /* :nickname!username@host.com PRIVMSG #channel :text\r\n */ - max = 512; - max -= 16; /* :, !, @, " PRIVMSG ", " ", :, \r, \n */ - max -= strlen (sess->server->nick); - max -= strlen (sess->channel); - if (sess->me && sess->me->hostname) - max -= strlen (sess->me->hostname); - else + while ((splitted_text = split_text (sess, text + offset, cmd_length, splitted_text))) { - max -= 9; /* username */ - max -= 65; /* max possible hostname and '@' */ - } - - if (strlen (text) > max) - { - unsigned int i = 0; - int size; - - /* traverse the utf8 string and find the nearest cut point that - doesn't split 1 char in half */ - while (1) - { - size = g_utf8_skip[((unsigned char *)text)[i]]; - if ((i + size) >= max) - break; - i += size; - } - max = i; - t = text[max]; - text[max] = 0; /* insert a NULL terminator to shorten it */ + inbound_chanmsg (sess->server, sess, sess->channel, sess->server->nick, + splitted_text, TRUE, FALSE); + sess->server->p_message (sess->server, sess->channel, splitted_text); + + if (*splitted_text) + offset += strlen(splitted_text); + + g_free(splitted_text); } inbound_chanmsg (sess->server, sess, sess->channel, sess->server->nick, - text, TRUE, FALSE); - sess->server->p_message (sess->server, sess->channel, text); - - if (t) - { - text[max] = t; - handle_say (sess, text + max, FALSE); - } - + text + offset, TRUE, FALSE); + sess->server->p_message (sess->server, sess->channel, text + offset); } else { notc_msg (sess); From 5004f69b5e68afa19c67d90207fa8e2d57332606 Mon Sep 17 00:00:00 2001 From: misdre Date: Sat, 6 Apr 2013 00:11:45 +0200 Subject: [PATCH 2/3] 'splitted' is'nt a word --- src/common/outbound.c | 48 +++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/common/outbound.c b/src/common/outbound.c index d933de32..c167ec77 100644 --- a/src/common/outbound.c +++ b/src/common/outbound.c @@ -2577,7 +2577,7 @@ cmd_load (struct session *sess, char *tbuf, char *word[], char *word_eol[]) } char * -split_text(struct session *sess, char *text, int cmd_length, char *splitted_text) +split_up_text(struct session *sess, char *text, int cmd_length, char *split_text) { unsigned int max; @@ -2612,9 +2612,9 @@ split_text(struct session *sess, char *text, int cmd_length, char *splitted_text } max = i; - splitted_text = g_strdup_printf ("%.*s", max, text); + split_text = g_strdup_printf ("%.*s", max, text); - return splitted_text; + return split_text; } return NULL; @@ -2624,7 +2624,7 @@ static int cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[]) { char *act = word_eol[2]; - char *splitted_text = NULL; + char *split_text = NULL; int cmd_length = 22; /* " PRIVMSG ", " ", :, \001ACTION, " ", \001, \r, \n */ int offset = 0; @@ -2648,16 +2648,16 @@ cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[]) /* DCC CHAT failed, try through server */ if (sess->server->connected) { - while ((splitted_text = split_text (sess, act + offset, cmd_length, splitted_text))) + while ((split_text = split_up_text (sess, act + offset, cmd_length, split_text))) { - sess->server->p_action (sess->server, sess->channel, splitted_text); + sess->server->p_action (sess->server, sess->channel, split_text); /* print it to screen */ - inbound_action (sess, sess->channel, sess->server->nick, "", splitted_text, TRUE, FALSE); + inbound_action (sess, sess->channel, sess->server->nick, "", split_text, TRUE, FALSE); - if (*splitted_text) - offset += strlen(splitted_text); + if (*split_text) + offset += strlen(split_text); - g_free(splitted_text); + g_free(split_text); } sess->server->p_action (sess->server, sess->channel, act + offset); @@ -2829,21 +2829,21 @@ static int cmd_notice (struct session *sess, char *tbuf, char *word[], char *word_eol[]) { char *text = word_eol[3]; - char *splitted_text = NULL; + char *split_text = NULL; int cmd_length = 12; /* " NOTICE ", " ", :, \r, \n */ int offset = 0; if (*word[2] && *word_eol[3]) { - while ((splitted_text = split_text (sess, text + offset, cmd_length, splitted_text))) + while ((split_text = split_up_text (sess, text + offset, cmd_length, split_text))) { - sess->server->p_notice (sess->server, word[2], splitted_text); - EMIT_SIGNAL (XP_TE_NOTICESEND, sess, word[2], splitted_text, NULL, NULL, 0); + sess->server->p_notice (sess->server, word[2], split_text); + EMIT_SIGNAL (XP_TE_NOTICESEND, sess, word[2], split_text, NULL, NULL, 0); - if (*splitted_text) - offset += strlen(splitted_text); + if (*split_text) + offset += strlen(split_text); - g_free(splitted_text); + g_free(split_text); } sess->server->p_notice (sess->server, word[2], text + offset); @@ -4333,20 +4333,20 @@ handle_say (session *sess, char *text, int check_spch) if (sess->server->connected) { - char *splitted_text = NULL; + char *split_text = NULL; int cmd_length = 13; /* " PRIVMSG ", " ", :, \r, \n */ int offset = 0; - while ((splitted_text = split_text (sess, text + offset, cmd_length, splitted_text))) + while ((split_text = split_up_text (sess, text + offset, cmd_length, split_text))) { inbound_chanmsg (sess->server, sess, sess->channel, sess->server->nick, - splitted_text, TRUE, FALSE); - sess->server->p_message (sess->server, sess->channel, splitted_text); + split_text, TRUE, FALSE); + sess->server->p_message (sess->server, sess->channel, split_text); - if (*splitted_text) - offset += strlen(splitted_text); + if (*split_text) + offset += strlen(split_text); - g_free(splitted_text); + g_free(split_text); } inbound_chanmsg (sess->server, sess, sess->channel, sess->server->nick, From 08d948435d29f2e78633299876c130c4b8702c2d Mon Sep 17 00:00:00 2001 From: misdre Date: Sat, 6 Apr 2013 01:11:28 +0200 Subject: [PATCH 3/3] split cmd_msg too --- src/common/outbound.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/common/outbound.c b/src/common/outbound.c index c167ec77..d6ce1488 100644 --- a/src/common/outbound.c +++ b/src/common/outbound.c @@ -2723,6 +2723,10 @@ cmd_msg (struct session *sess, char *tbuf, char *word[], char *word_eol[]) char *msg = word_eol[3]; struct session *newsess; + char *split_text = NULL; + int cmd_length = 13; /* " PRIVMSG ", " ", :, \r, \n */ + int offset = 0; + if (*nick) { if (*msg) @@ -2751,14 +2755,37 @@ cmd_msg (struct session *sess, char *tbuf, char *word[], char *word_eol[]) notc_msg (sess); return TRUE; } - sess->server->p_message (sess->server, nick, msg); + + while ((split_text = split_up_text (sess, msg + offset, cmd_length, split_text))) + { + sess->server->p_message (sess->server, nick, split_text); + + if (*split_text) + offset += strlen(split_text); + + g_free(split_text); + } + sess->server->p_message (sess->server, nick, msg + offset); + offset = 0; } newsess = find_dialog (sess->server, nick); if (!newsess) newsess = find_channel (sess->server, nick); if (newsess) + { + while ((split_text = split_up_text (sess, msg + offset, cmd_length, split_text))) + { + inbound_chanmsg (newsess->server, NULL, newsess->channel, + newsess->server->nick, split_text, TRUE, FALSE); + + if (*split_text) + offset += strlen(split_text); + + g_free(split_text); + } inbound_chanmsg (newsess->server, NULL, newsess->channel, - newsess->server->nick, msg, TRUE, FALSE); + newsess->server->nick, msg + offset, TRUE, FALSE); + } else { /* mask out passwords */