3efcee68bd
- copy and paste into msg windows caused html to be passed on to the icb-server. - implemented keepalive so that my connection doesn't drop when behind crapy firewalls that timeout idle tcp connections quickly. - fixed a crash in the auto reconnect code path where "group" is not in the hash table in icb_join_chat(). - implemented a defensive programming check in icb_send() to prevent other NULL fields from crashing pidgin. - fixed some amd64 warnings. Maintainer timeout
205 lines
6.3 KiB
Plaintext
205 lines
6.3 KiB
Plaintext
--- icb.c.orig 2007-05-05 12:39:23.000000000 -0400
|
|
+++ icb.c 2009-08-12 12:22:00.000000000 -0400
|
|
@@ -30,6 +30,12 @@
|
|
|
|
#include "icb.h"
|
|
|
|
+/*
|
|
+ * Keep alives will be sent after KEEPALIVE_TIMEOUT seconds of
|
|
+ * inactivity.
|
|
+ */
|
|
+#define KEEPALIVE_TIMEOUT 150
|
|
+
|
|
static char icb_input_buf[ICB_BUFSIZE+1];
|
|
static char *icb_input_pos = icb_input_buf;
|
|
static int icb_input_fill = 0;
|
|
@@ -96,8 +102,8 @@ icb_dump_packet(IcbPacket *packet)
|
|
purple_debug_info("icb", "length: %d\n", packet->length);
|
|
purple_debug_info("icb", "command: %c\n", packet->command);
|
|
for (i = 0; i < packet->nof; i++) {
|
|
- purple_debug_info("icb", "field %d: %d \"%s\"\n", i,
|
|
- strlen(packet->fields[i]), packet->fields[i]);
|
|
+ purple_debug_info("icb", "field %d: %ld \"%s\"\n", i,
|
|
+ (long)strlen(packet->fields[i]), packet->fields[i]);
|
|
}
|
|
|
|
purple_debug_info("icb", "<- icb_dump_packet\n");
|
|
@@ -143,14 +149,14 @@ IcbPacket *
|
|
icb_parse_buf()
|
|
{
|
|
char *separator, *tmpbuf;
|
|
- unsigned char *size;
|
|
+ unsigned char size;
|
|
IcbPacket *packet = NULL;
|
|
|
|
purple_debug_info("icb", "-> icb_parse_buf\n");
|
|
|
|
/* There has to be at least two chars in buffer: size and command */
|
|
if (icb_input_fill < 2) {
|
|
- purple_debug_info("icb", "Buffer is to short. Only %d char(s)\n", icb_input_buf);
|
|
+ purple_debug_info("icb", "Buffer is to short. Only %d char(s)\n", icb_input_fill);
|
|
return NULL;
|
|
}
|
|
|
|
@@ -172,12 +178,12 @@ icb_parse_buf()
|
|
return NULL;
|
|
}
|
|
|
|
- size = icb_input_pos; /* Size of the package */
|
|
+ size = *(unsigned char *)icb_input_pos; /* Size of the package */
|
|
tmpbuf = icb_input_pos+1; /* Command sent in packet */
|
|
|
|
packet->nof = 0;
|
|
packet->fields = (char **) calloc(1, ICB_MAX_NO_FIELDS*sizeof(char *));
|
|
- packet->length = *size;
|
|
+ packet->length = size;
|
|
packet->command = *tmpbuf++;
|
|
|
|
separator = tmpbuf;
|
|
@@ -220,6 +226,8 @@ icb_login_cb(gpointer data, gint source,
|
|
|
|
gc->inpa = purple_input_add(icb->fd, PURPLE_INPUT_READ, icb_input_cb, gc);
|
|
|
|
+ icb->sr_time = time(NULL);
|
|
+
|
|
purple_debug_info("icb", "<- icb_login_cb\n");
|
|
}
|
|
|
|
@@ -263,18 +271,21 @@ icb_send(IcbSession *icb, char command,
|
|
va_start(arg, params);
|
|
while (params-- > 0) {
|
|
field = va_arg(arg, const char *);
|
|
- fieldlen = strlen(field);
|
|
-
|
|
- // -1 to leave space for NUL at the end of buffer
|
|
- if (fieldlen + size > ICB_PACKET_SIZE -1) {
|
|
- purple_debug_info("icb", "<- icb_send: too much data to write");
|
|
- va_end(arg);
|
|
- return -1;
|
|
- }
|
|
+ if (field != NULL) {
|
|
+ fieldlen = strlen(field);
|
|
|
|
- // field data
|
|
- strncpy(&packet[size], field, fieldlen);
|
|
- size += fieldlen;
|
|
+ // -1 to leave space for NUL at the end of buffer
|
|
+ if (fieldlen + size > ICB_PACKET_SIZE -1) {
|
|
+ purple_debug_info("icb", "<- icb_send: too much data to write");
|
|
+ va_end(arg);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ // field data
|
|
+ strncpy(&packet[size], field, fieldlen);
|
|
+ size += fieldlen;
|
|
+ } else
|
|
+ purple_debug_info("icb", "Skipping NULL param");
|
|
|
|
// separator
|
|
if (params != 0) {
|
|
@@ -294,7 +305,8 @@ icb_send(IcbSession *icb, char command,
|
|
purple_debug_info("icb", "write(): %d, %s\n", errno, strerror(errno));
|
|
purple_connection_error(purple_account_get_connection(icb->account),
|
|
_("Server has disconnected"));
|
|
- }
|
|
+ } else
|
|
+ icb->sr_time = time(NULL);
|
|
|
|
purple_debug_info("icb", "<- icb_send %d byte(s)\n", ret);
|
|
|
|
@@ -403,7 +415,7 @@ icb_input_cb(gpointer data, gint source,
|
|
|
|
purple_debug_misc("icb", "-> icb_input_cb: fd=%d\n", icb->fd);
|
|
|
|
- purple_debug_misc("icb", "icb_input_pos - icb_input_buf=%d\n", icb_input_pos - icb_input_buf);
|
|
+ purple_debug_misc("icb", "icb_input_pos - icb_input_buf=%ld\n", icb_input_pos - icb_input_buf);
|
|
purple_debug_misc("icb", "icb_input_fill=%d\n", icb_input_fill);
|
|
|
|
if (icb->fd < 0) {
|
|
@@ -427,6 +439,7 @@ icb_input_cb(gpointer data, gint source,
|
|
purple_debug_info("icb", "Now buffer is filled with %d char(s)\n", icb_input_fill);
|
|
|
|
while (icb_input_fill > 0 && (packet = icb_parse_buf()) != NULL) {
|
|
+ icb->sr_time = time(NULL);
|
|
icb_dump_packet(packet);
|
|
switch (packet->command) {
|
|
case ICB_CMD_PROTO_VERSION:
|
|
@@ -826,6 +839,9 @@ moderator_just_left:
|
|
}
|
|
#endif
|
|
}
|
|
+ case ICB_CMD_PONG:
|
|
+ purple_debug_info("icb", "pong msg\n");
|
|
+ break;
|
|
default:
|
|
break;
|
|
}
|
|
@@ -879,7 +895,7 @@ icb_send_chat(PurpleConnection *gc, int
|
|
purple_debug_info("icb", "icb_send_chat\n");
|
|
purple_debug_info("icb", "id=%d, len=%d, msg=\"%s\"\n", id, len, message);
|
|
|
|
- tmp = purple_unescape_html(message);
|
|
+ tmp = purple_markup_strip_html(message);
|
|
|
|
/* Split <message> into smaller chunks, as packed size is limited to
|
|
* ICB_MAX_DATA_SIZE bytes.
|
|
@@ -918,7 +934,7 @@ icb_send_im(PurpleConnection *gc, const
|
|
purple_debug_info("icb", "icb_send_im\n");
|
|
purple_debug_info("icb", "who=\"%s\", len=%d, msg=\"%s\"\n", who, msglen, msg);
|
|
|
|
- tmp = purple_unescape_html(msg);
|
|
+ tmp = purple_markup_strip_html(msg);
|
|
|
|
/* max_msg_size is smaller than ICB_MAX_DATA_SIZE as IM packet looks like this:
|
|
* -gm,username message sent by user*
|
|
@@ -989,10 +1005,17 @@ icb_join_chat(PurpleConnection *gc, GHas
|
|
|
|
group = g_hash_table_lookup(data, "group");
|
|
|
|
- purple_debug_info("icb", "group %s\n", group);
|
|
-
|
|
- icb_send(icb, ICB_CMD_COMMAND, 2, "g", group);
|
|
+ /*
|
|
+ * auto-reconnect calls icb_join_chat when group is not in the hash
|
|
+ * table. ignore these calls gracefully instead of segfaulting in
|
|
+ * icb_send.
|
|
+ */
|
|
+ if (group != NULL) {
|
|
+ purple_debug_info("icb", "group %s\n", group);
|
|
|
|
+ icb_send(icb, ICB_CMD_COMMAND, 2, "g", group);
|
|
+ }
|
|
+
|
|
purple_debug_info("icb", "<- icb_join_chat\n");
|
|
}
|
|
|
|
@@ -1249,6 +1272,18 @@ icb_chat_info_defaults(PurpleConnection
|
|
return defaults;
|
|
}
|
|
|
|
+static void icb_keepalive(PurpleConnection *gc)
|
|
+{
|
|
+ IcbSession *icb = gc->proto_data;
|
|
+
|
|
+ purple_debug_misc("icb", "-> icb_keepalive\n");
|
|
+
|
|
+ if ((time(NULL) - icb->sr_time) >= KEEPALIVE_TIMEOUT)
|
|
+ icb_send(icb, ICB_CMD_PONG, 0);
|
|
+
|
|
+ purple_debug_misc("icb", "<- icb_keepalive\n");
|
|
+}
|
|
+
|
|
static PurplePlugin *icb_plugin = NULL;
|
|
|
|
static PurplePluginProtocolInfo prpl_info =
|
|
@@ -1290,7 +1325,7 @@ static PurplePluginProtocolInfo prpl_inf
|
|
icb_leave_chat, /* chat_leave */
|
|
NULL, /* chat_whisper */
|
|
icb_send_chat, /* chat_send */
|
|
- NULL, /* keepalive */
|
|
+ icb_keepalive, /* keepalive */
|
|
NULL, /* register_user */
|
|
NULL, /* get_cb_info */
|
|
NULL, /* get_cb_away */
|