$NetBSD: patch-af,v 1.2 2010/08/10 20:26:36 sketch Exp $ --- src/core/icb-protocol.c (revision 5174) +++ src/core/icb-protocol.c (working copy) @@ -27,19 +27,19 @@ #include "icb-servers.h" static char *signal_names[] = { - "login", - "open", - "personal", - "status", - "error", - "important", - "exit", - "command", - "cmdout", - "protocol", - "beep", - "ping", - "pong" + "login", /* a */ + "open", /* b */ + "personal", /* c */ + "status", /* d */ + "error", /* e */ + "important", /* f */ + "exit", /* g */ + "command", /* h */ + "cmdout", /* i */ + "protocol", /* j */ + "beep", /* k */ + "ping", /* l */ + "pong" /* m */ }; #define SIGNAL_FIRST 'a' @@ -121,9 +121,93 @@ void icb_send_open_msg(ICB_SERVER_REC *server, const char *text) { - icb_send_cmd(server, 'b', text, NULL); + size_t remain; + + /* + * ICB has 255 byte line length limit, and public messages are sent + * out with our nickname, so split text accordingly. + * + * 250 = 255 - 'b' - 1 space after nick - ^A - nul - extra + * + * Taken from ircII's icb.c, thanks phone :-) + */ + remain = 250 - strlen(server->connrec->nick); + + while(*text) { + char buf[256], *sendbuf; + size_t len, copylen; + + len = strlen(text); + copylen = remain; + if (len > remain) { + int i; + + /* try to split on a word boundary */ + for (i = 1; i < 128 && i < len; i++) { + if (isspace(text[remain - i])) { + copylen -= i - 1; + break; + } + } + strncpy(buf, text, copylen); + buf[copylen] = 0; + sendbuf = buf; + } else { + sendbuf = (char *)text; + } + icb_send_cmd(server, 'b', sendbuf, NULL); + text += len > copylen ? copylen : len; + } } +void icb_send_private_msg(ICB_SERVER_REC *server, const char *target, + const char *text) +{ + size_t mylen, targlen, remain; + + /* + * ICB has 255 byte line length limit. Private messages are sent + * out with our nickname, but received with the target nickname, + * so deduct the larger of the two in addition to other parts. + * + * 248 = 255 - 'hm' - 1 space after nick - ^A's - nul - extra + * + * Taken from ircII's icb.c, thanks phone :-) + */ + mylen = strlen(server->connrec->nick); + targlen = strlen(target); + if (mylen > targlen) { + remain = 248 - mylen; + } else { + remain = 248 - targlen; + } + while(*text) { + char buf[256], *sendbuf; + size_t len, copylen; + + len = strlen(text); + copylen = remain; + if (len > remain) { + int i; + + /* try to split on a word boundary */ + for (i = 1; i < 128 && i < len; i++) { + if (isspace(text[remain - i])) { + copylen -= i - 1; + break; + } + } + strncpy(buf, text, copylen); + buf[copylen] = 0; + sendbuf = g_strconcat(target, " ", buf, NULL); + } else { + sendbuf = g_strconcat(target, " ", text, NULL); + } + icb_send_cmd(server, 'h', "m", sendbuf, NULL); + text += len > copylen ? copylen : len; + } +} + void icb_command(ICB_SERVER_REC *server, const char *cmd, const char *args, const char *id) { @@ -293,6 +377,20 @@ g_strfreev(args); } +static void event_status(ICB_SERVER_REC *server, const char *data) +{ + char **args, *event; + + args = g_strsplit(data, "\001", -1); + if (args[0] != NULL) { + event = g_strdup_printf("icb status %s", g_ascii_strdown(args[0], strlen(args[0]))); + if (!signal_emit(event, 2, server, args)) + signal_emit("default icb status", 2, server, args); + g_free(event); + } + g_strfreev(args); +} + void icb_protocol_init(void) { signal_add("server connected", (SIGNAL_FUNC) sig_server_connected); @@ -300,6 +398,7 @@ signal_add("icb event login", (SIGNAL_FUNC) event_login); signal_add("icb event ping", (SIGNAL_FUNC) event_ping); signal_add("icb event cmdout", (SIGNAL_FUNC) event_cmdout); + signal_add("icb event status", (SIGNAL_FUNC) event_status); } void icb_protocol_deinit(void) @@ -309,4 +408,5 @@ signal_remove("icb event login", (SIGNAL_FUNC) event_login); signal_remove("icb event ping", (SIGNAL_FUNC) event_ping); signal_remove("icb event cmdout", (SIGNAL_FUNC) event_cmdout); + signal_remove("icb event status", (SIGNAL_FUNC) event_status); }