+Sun Aug 24 23:35:19 CEST 2003 Jochen Eisinger <c0ffee@penguin-breeder.org>
+
+ * Provide a signal handler to send MIME encoded messages and emit
+ a signal when a MIME encoded message is received. Also document
+ the signals for usage with the perl interface.
+
+ A sample perl script will be supplied at a later point.
+
+ Affected files are irssi/docs/signals.txt,
+ irssi/src/silc/core/client_ops.[ch],
+ irssi/src/silc/core/silc-{channels,servers}.c
+
Sun Aug 24 12:58:30 CEST 2003 Jochen Eisinger <c0ffee@penguin-breeder.org>
* Use SILC_COMMAND_PING to estimate the round-trip time to the
gui-printtext.c:
"beep"
+
+SILC
+---
+
+silc-channels.c:
+ "mime", SERVER_REC, CHANNEL_REC, char *blob, char *enc, char *type, char *nick
+
+silc-servers.c:
+ "mime-send", SERVER_REC, WI_ITEM_REC, char *blob, char *enc, char *type
return ret;
}
+char * silc_unescape_data(const char *escaped_data, SilcUInt32 *length)
+{
+ SilcUInt32 ctr, dest=0;
+ char *data;
+
+ data = silc_calloc(strlen(escaped_data), sizeof(char));
+
+ for (ctr = 0; ctr < strlen(escaped_data); ctr++)
+ if (escaped_data[ctr] == 1)
+ data[dest++] = escaped_data[++ctr] - 1;
+ else
+ data[dest++] = escaped_data[ctr];
+
+ *length = dest;
+ return data;
+}
+
+char * silc_escape_data(const char *data, SilcUInt32 len)
+{
+ char *escaped_data;
+ SilcUInt32 ctr, zeros=0;
+
+ for (ctr = 0; ctr < len; ctr++)
+ if (data[ctr] == 0 || data[ctr] == 1)
+ zeros++;
+
+ escaped_data = silc_calloc(zeros + len, sizeof(char));
+
+ zeros=0;
+ for (ctr = 0; ctr < len; ctr++)
+ switch (data[ctr]) {
+ case 0:
+ escaped_data[zeros++] = 1;
+ escaped_data[zeros++] = 1;
+ break;
+
+ case 1:
+ escaped_data[zeros++] = 1;
+ escaped_data[zeros++] = 2;
+ break;
+
+ default:
+ escaped_data[zeros++] = data[ctr];
+ }
+
+ return escaped_data;
+}
+
+void silc_emit_mime_sig(SILC_SERVER_REC *server, SILC_CHANNEL_REC *channel,
+ const char *data, SilcUInt32 data_len,
+ const char *encoding, const char *type, const char *nick)
+{
+ char *escaped_data;
+
+ escaped_data = silc_escape_data(data, data_len);
+
+ signal_emit("mime", 6, server, channel, escaped_data, encoding, type, nick);
+
+ silc_free(escaped_data);
+}
+
+
/* Message for a channel. The `sender' is the nickname of the sender
received in the packet. The `channel_name' is the name of the channel. */
/* It is something textual, display it */
message = (const unsigned char *)data;
} else {
- printformat_module("fe-common/silc", server, channel->channel_name,
- MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA,
- nick == NULL ? "[<unknown>]" : nick->nick, type);
+ silc_emit_mime_sig(server, chanrec, data, data_len,
+ enc, type, nick == NULL ? NULL : nick->nick);
message = NULL;
}
}
/* It is something textual, display it */
message = (const unsigned char *)data;
} else {
- printformat_module("fe-common/silc", server, NULL,
- MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA,
- sender->nickname ? sender->nickname : "[<unknown>]",
- type);
+ silc_emit_mime_sig(server, NULL, data, data_len,
+ enc, type, sender->nickname);
message = NULL;
}
}
void
silc_detach(SilcClient client, SilcClientConnection conn,
const unsigned char *detach_data, SilcUInt32 detach_data_len);
+char *
+silc_unescape_data(const char *escaped_data, SilcUInt32 *length);
+char *
+silc_escape_data(const char *data, SilcUInt32 len);
#endif
#include "silc-commands.h"
+void sig_mime(SILC_SERVER_REC *server, SILC_CHANNEL_REC *channel,
+ const char *blob, const char *enc, const char *type,
+ const char *nick)
+{
+
+ if (!(IS_SILC_SERVER(server)))
+ return;
+
+ printformat_module("fe-common/silc", server,
+ channel == NULL ? NULL : channel->name,
+ MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA,
+ nick == NULL ? "[<unknown>]" : nick, type);
+
+}
+
SILC_CHANNEL_REC *silc_channel_create(SILC_SERVER_REC *server,
const char *name,
const char *visible_name,
signal_add("server connected", (SIGNAL_FUNC) sig_connected);
signal_add("server quit", (SIGNAL_FUNC) sig_server_quit);
signal_add("gui exit", (SIGNAL_FUNC) sig_gui_quit);
+ signal_add("mime", (SIGNAL_FUNC) sig_mime);
command_bind_silc("part", MODULE_NAME, (SIGNAL_FUNC) command_part);
command_bind_silc("me", MODULE_NAME, (SIGNAL_FUNC) command_me);
signal_remove("server connected", (SIGNAL_FUNC) sig_connected);
signal_remove("server quit", (SIGNAL_FUNC) sig_server_quit);
signal_remove("gui exit", (SIGNAL_FUNC) sig_gui_quit);
+ signal_remove("mime", (SIGNAL_FUNC) sig_mime);
command_unbind("part", (SIGNAL_FUNC) command_part);
command_unbind("me", (SIGNAL_FUNC) command_me);
}
void silc_send_mime(SILC_SERVER_REC *server, WI_ITEM_REC *to,
- const char *data, int data_len,
+ const char *data,
const char *enc, const char *type)
{
SILC_CHANNEL_REC *channel;
QUERY_REC *query;
+ char *unescaped_data;
+ int unescaped_data_len;
char *mime_data;
int mime_data_len;
(enc == NULL) || (type == NULL))
return;
+ unescaped_data = silc_unescape_data(data, &unescaped_data_len);
+
#define SILC_MIME_HEADER "MIME-Version: 1.0\r\nContent-Type: %s\r\nContent-Transfer-Encoding: %s\r\n\r\n"
- mime_data_len = data_len + strlen(SILC_MIME_HEADER) - 4
+ mime_data_len = unescaped_data_len + strlen(SILC_MIME_HEADER) - 4
+ strlen(enc) + strlen(type);
if (mime_data_len >= SILC_PACKET_MAX_LEN)
return;
mime_data = silc_calloc(mime_data_len, sizeof(*mime_data));
snprintf(mime_data, mime_data_len, SILC_MIME_HEADER, type, enc);
memmove(mime_data + strlen(SILC_MIME_HEADER) - 4 + strlen(enc) + strlen(type),
- data, data_len);
+ unescaped_data, unescaped_data_len);
#undef SILC_MIME_HEADER
}
silc_free(mime_data);
+ silc_free(unescaped_data);
}
static int isnickflag_func(char flag)