📄 ops.c
字号:
/* silcpurple_ops.c Author: Pekka Riikonen <priikone@silcnet.org> Copyright (C) 2004 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.*/#include "silcincludes.h"#include "silcclient.h"#include "silcpurple.h"#include "imgstore.h"#include "wb.h"static voidsilc_channel_message(SilcClient client, SilcClientConnection conn, SilcClientEntry sender, SilcChannelEntry channel, SilcMessagePayload payload, SilcChannelPrivateKey key, SilcMessageFlags flags, const unsigned char *message, SilcUInt32 message_len);static voidsilc_private_message(SilcClient client, SilcClientConnection conn, SilcClientEntry sender, SilcMessagePayload payload, SilcMessageFlags flags, const unsigned char *message, SilcUInt32 message_len);/* Message sent to the application by library. `conn' associates the message to a specific connection. `conn', however, may be NULL. The `type' indicates the type of the message sent by the library. The application can for example filter the message according the type. */static voidsilc_say(SilcClient client, SilcClientConnection conn, SilcClientMessageType type, char *msg, ...){ /* Nothing */}#ifdef HAVE_SILCMIME_H/* Processes incoming MIME message. Can be private message or channel message. */static voidsilcpurple_mime_message(SilcClient client, SilcClientConnection conn, SilcClientEntry sender, SilcChannelEntry channel, SilcMessagePayload payload, SilcChannelPrivateKey key, SilcMessageFlags flags, SilcMime mime, gboolean recursive){ PurpleConnection *gc = client->application; SilcPurple sg = gc->proto_data; const char *type; const unsigned char *data; SilcUInt32 data_len; PurpleMessageFlags cflags = 0; PurpleConversation *convo = NULL; if (!mime) return; /* Check for fragmented MIME message */ if (silc_mime_is_partial(mime)) { if (!sg->mimeass) sg->mimeass = silc_mime_assembler_alloc(); /* Defragment */ mime = silc_mime_assemble(sg->mimeass, mime); if (!mime) /* More fragments to come */ return; /* Process the complete message */ silcpurple_mime_message(client, conn, sender, channel, payload, key, flags, mime, FALSE); return; } /* Check for multipart message */ if (silc_mime_is_multipart(mime)) { SilcMime p; const char *mtype; SilcDList parts = silc_mime_get_multiparts(mime, &mtype); /* Only "mixed" type supported */ if (strcmp(mtype, "mixed")) goto out; silc_dlist_start(parts); while ((p = silc_dlist_get(parts)) != SILC_LIST_END) { /* Recursively process parts */ silcpurple_mime_message(client, conn, sender, channel, payload, key, flags, p, TRUE); } goto out; } /* Get content type and MIME data */ type = silc_mime_get_field(mime, "Content-Type"); if (!type) goto out; data = silc_mime_get_data(mime, &data_len); if (!data) goto out; /* Process according to content type */ /* Plain text */ if (strstr(type, "text/plain")) { /* Default is UTF-8, don't check for other charsets */ if (!strstr(type, "utf-8")) goto out; if (channel) silc_channel_message(client, conn, sender, channel, payload, key, SILC_MESSAGE_FLAG_UTF8, data, data_len); else silc_private_message(client, conn, sender, payload, SILC_MESSAGE_FLAG_UTF8, data, data_len); goto out; } /* Image */ if (strstr(type, "image/png") || strstr(type, "image/jpeg") || strstr(type, "image/gif") || strstr(type, "image/tiff")) { char tmp[32]; int imgid; /* Get channel convo (if message is for channel) */ if (key && channel) { GList *l; SilcPurplePrvgrp prv; for (l = sg->grps; l; l = l->next) if (((SilcPurplePrvgrp)l->data)->key == key) { prv = l->data; convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, prv->channel, sg->account); break; } } if (channel && !convo) convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, channel->channel_name, sg->account); if (channel && !convo) goto out; imgid = purple_imgstore_add_with_id(g_memdup(data, data_len), data_len, ""); if (imgid) { cflags |= PURPLE_MESSAGE_IMAGES | PURPLE_MESSAGE_RECV; g_snprintf(tmp, sizeof(tmp), "<IMG ID=\"%d\">", imgid); if (channel) serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)), sender->nickname ? sender->nickname : "<unknown>", cflags, tmp, time(NULL)); else serv_got_im(gc, sender->nickname ? sender->nickname : "<unknown>", tmp, cflags, time(NULL)); purple_imgstore_unref_by_id(imgid); cflags = 0; } goto out; } /* Whiteboard message */ if (strstr(type, "application/x-wb") && !purple_account_get_bool(sg->account, "block-wb", FALSE)) { if (channel) silcpurple_wb_receive_ch(client, conn, sender, channel, payload, flags, data, data_len); else silcpurple_wb_receive(client, conn, sender, payload, flags, data, data_len); goto out; } out: if (!recursive) silc_mime_free(mime);}#endif /* HAVE_SILCMIME_H *//* Message for a channel. The `sender' is the sender of the message The `channel' is the channel. The `message' is the message. Note that `message' maybe NULL. The `flags' indicates message flags and it is used to determine how the message can be interpreted (like it may tell the message is multimedia message). */static voidsilc_channel_message(SilcClient client, SilcClientConnection conn, SilcClientEntry sender, SilcChannelEntry channel, SilcMessagePayload payload, SilcChannelPrivateKey key, SilcMessageFlags flags, const unsigned char *message, SilcUInt32 message_len){ PurpleConnection *gc = client->application; SilcPurple sg = gc->proto_data; PurpleConversation *convo = NULL; char *msg, *tmp; if (!message) return; if (key) { GList *l; SilcPurplePrvgrp prv; for (l = sg->grps; l; l = l->next) if (((SilcPurplePrvgrp)l->data)->key == key) { prv = l->data; convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, prv->channel, sg->account); break; } } if (!convo) convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, channel->channel_name, sg->account); if (!convo) return; if (flags & SILC_MESSAGE_FLAG_SIGNED && purple_account_get_bool(sg->account, "sign-verify", FALSE)) { /* XXX */ } if (flags & SILC_MESSAGE_FLAG_DATA) { /* Process MIME message */#ifdef HAVE_SILCMIME_H SilcMime mime; mime = silc_mime_decode(message, message_len); silcpurple_mime_message(client, conn, sender, channel, payload, key, flags, mime, FALSE);#else char type[128], enc[128]; unsigned char *data; SilcUInt32 data_len; memset(type, 0, sizeof(type)); memset(enc, 0, sizeof(enc)); if (!silc_mime_parse(message, message_len, NULL, 0, type, sizeof(type) - 1, enc, sizeof(enc) - 1, &data, &data_len)) return; if (!strcmp(type, "application/x-wb") && !strcmp(enc, "binary") && !purple_account_get_bool(sg->account, "block-wb", FALSE)) silcpurple_wb_receive_ch(client, conn, sender, channel, payload, flags, data, data_len);#endif return; } if (flags & SILC_MESSAGE_FLAG_ACTION) { msg = g_strdup_printf("/me %s", (const char *)message); if (!msg) return; tmp = g_markup_escape_text(msg, -1); /* Send to Purple */ serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)), sender->nickname ? sender->nickname : "<unknown>", 0, tmp, time(NULL)); g_free(tmp); g_free(msg); return; } if (flags & SILC_MESSAGE_FLAG_NOTICE) { msg = g_strdup_printf("(notice) <I>%s</I> %s", sender->nickname ? sender->nickname : "<unknown>", (const char *)message); if (!msg) return; /* Send to Purple */ purple_conversation_write(convo, NULL, (const char *)msg, PURPLE_MESSAGE_SYSTEM, time(NULL)); g_free(msg); return; } if (flags & SILC_MESSAGE_FLAG_UTF8) { tmp = g_markup_escape_text((const char *)message, -1); /* Send to Purple */ serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)), sender->nickname ? sender->nickname : "<unknown>", 0, tmp, time(NULL)); g_free(tmp); }}/* Private message to the client. The `sender' is the sender of the message. The message is `message'and maybe NULL. The `flags' indicates message flags and it is used to determine how the message can be interpreted (like it may tell the message is multimedia message). */static voidsilc_private_message(SilcClient client, SilcClientConnection conn, SilcClientEntry sender, SilcMessagePayload payload, SilcMessageFlags flags, const unsigned char *message, SilcUInt32 message_len){ PurpleConnection *gc = client->application; SilcPurple sg = gc->proto_data; PurpleConversation *convo = NULL; char *msg, *tmp; if (!message) return; if (sender->nickname) /* XXX - Should this be PURPLE_CONV_TYPE_IM? */ convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, sender->nickname, sg->account); if (flags & SILC_MESSAGE_FLAG_SIGNED && purple_account_get_bool(sg->account, "sign-verify", FALSE)) { /* XXX */ } if (flags & SILC_MESSAGE_FLAG_DATA) {#ifdef HAVE_SILCMIME_H /* Process MIME message */ SilcMime mime; mime = silc_mime_decode(message, message_len); silcpurple_mime_message(client, conn, sender, NULL, payload, NULL, flags, mime, FALSE);#else char type[128], enc[128]; unsigned char *data; SilcUInt32 data_len; memset(type, 0, sizeof(type)); memset(enc, 0, sizeof(enc)); if (!silc_mime_parse(message, message_len, NULL, 0, type, sizeof(type) - 1, enc, sizeof(enc) - 1, &data, &data_len)) return; if (!strcmp(type, "application/x-wb") && !strcmp(enc, "binary") && !purple_account_get_bool(sg->account, "block-wb", FALSE)) silcpurple_wb_receive(client, conn, sender, payload, flags, data, data_len);#endif return; } if (flags & SILC_MESSAGE_FLAG_ACTION && convo) { msg = g_strdup_printf("/me %s", (const char *)message); if (!msg) return; tmp = g_markup_escape_text(msg, -1); /* Send to Purple */ serv_got_im(gc, sender->nickname ? sender->nickname : "<unknown>", tmp, 0, time(NULL)); g_free(msg); g_free(tmp); return; } if (flags & SILC_MESSAGE_FLAG_NOTICE && convo) { msg = g_strdup_printf("(notice) <I>%s</I> %s", sender->nickname ? sender->nickname : "<unknown>", (const char *)message); if (!msg) return; /* Send to Purple */ purple_conversation_write(convo, NULL, (const char *)msg, PURPLE_MESSAGE_SYSTEM, time(NULL)); g_free(msg); return; } if (flags & SILC_MESSAGE_FLAG_UTF8) { tmp = g_markup_escape_text((const char *)message, -1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -