From bb7bafc93cb78dc185565d5750ac3ca5abff2fc8 Mon Sep 17 00:00:00 2001
From: Sebastian Thorarensen <sebth@naju.se>
Date: Tue, 17 Jun 2014 18:17:28 +0200
Subject: Split long IRC `ACTION' messages

Add line splitting logic to commands `/me' and `/action'.
---
 src/fe-common/irc/fe-irc-commands.c | 27 ++++++++++++++++++++-------
 src/irc/core/irc-servers.c          | 18 ++++++++++++++++++
 src/irc/core/irc-servers.h          |  5 ++++-
 3 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/src/fe-common/irc/fe-irc-commands.c b/src/fe-common/irc/fe-irc-commands.c
index f2b00590..765b5340 100644
--- a/src/fe-common/irc/fe-irc-commands.c
+++ b/src/fe-common/irc/fe-irc-commands.c
@@ -44,6 +44,9 @@
 static void cmd_me(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
 {
 	const char *target;
+	char *subdata;
+	char **splitdata;
+	int n = 0;
 
         CMD_IRC_SERVER(server);
 	if (!IS_IRC_ITEM(item))
@@ -53,10 +56,13 @@ static void cmd_me(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
 		cmd_return_error(CMDERR_NOT_CONNECTED);
 
 	target = window_item_get_target(item);
-	irc_server_send_action(server, target, data);
-
-	signal_emit("message irc own_action", 3, server, data,
-		    item->visible_name);
+	splitdata = irc_server_split_action(server, target, data);
+	while ((subdata = splitdata[n++])) {
+		irc_server_send_action(server, target, subdata);
+		signal_emit("message irc own_action", 3, server, subdata,
+			    item->visible_name);
+	}
+	g_strfreev(splitdata);
 }
 
 /* SYNTAX: ACTION [-<server tag>] <target> <message> */
@@ -64,6 +70,9 @@ static void cmd_action(const char *data, IRC_SERVER_REC *server)
 {
 	GHashTable *optlist;
 	const char *target, *text;
+	char *subtext;
+	char **splittexts;
+	int n = 0;
 	void *free_arg;
 
         CMD_IRC_SERVER(server);
@@ -79,10 +88,14 @@ static void cmd_action(const char *data, IRC_SERVER_REC *server)
 	if (server == NULL || !server->connected)
 		cmd_param_error(CMDERR_NOT_CONNECTED);
 
-	irc_server_send_action(server, target, text);
-
-	signal_emit("message irc own_action", 3, server, text, target);
+	splittexts = irc_server_split_action(server, target, text);
+	while ((subtext = splittexts[n++])) {
+		irc_server_send_action(server, target, subtext);
+		signal_emit("message irc own_action", 3, server, subtext,
+			    target);
+	}
 
+	g_strfreev(splittexts);
 	cmd_params_free(free_arg);
 }
 
diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c
index 872dbbfd..dc98e1c1 100644
--- a/src/irc/core/irc-servers.c
+++ b/src/irc/core/irc-servers.c
@@ -450,6 +450,24 @@ void irc_server_send_action(IRC_SERVER_REC *server, const char *target, const ch
 	g_free(recoded);
 }
 
+char **irc_server_split_action(IRC_SERVER_REC *server, const char *target,
+			       const char *data)
+{
+	/* See split_message() on how the maximum length is calculated. */
+	int userhostlen = 63 + 10 + 1;
+
+	g_return_val_if_fail(server != NULL, NULL);
+	g_return_val_if_fail(target != NULL, NULL);
+	g_return_val_if_fail(data != NULL, NULL);
+
+	if (server->userhost != NULL)
+		userhostlen = strlen(server->userhost);
+
+	return split_line(SERVER(server), data, target,
+			  510 - strlen(":! PRIVMSG  :\001ACTION \001") -
+			  strlen(server->nick) - userhostlen - strlen(target));
+}
+
 void irc_server_send_away(IRC_SERVER_REC *server, const char *reason)
 {
 	char *recoded = NULL;
diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h
index 8c9c1cd7..7e4eeabf 100644
--- a/src/irc/core/irc-servers.h
+++ b/src/irc/core/irc-servers.h
@@ -117,7 +117,10 @@ void irc_server_purge_output(IRC_SERVER_REC *server, const char *target);
 char *irc_server_get_channels(IRC_SERVER_REC *server);
 
 /* INTERNAL: */
-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 **irc_server_split_action(IRC_SERVER_REC *server, const char *target,
+			       const char *data);
 void irc_server_send_away(IRC_SERVER_REC *server, const char *reason);
 void irc_server_send_data(IRC_SERVER_REC *server, const char *data, int len);
 void irc_server_init_isupport(IRC_SERVER_REC *server);
-- 
cgit debian/1.2.3+git2.25.1-1-2-gaceb0